Shop OBEX P1 Docs P2 Docs Learn Events
flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler - Page 88 — Parallax Forums

flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler

18586889091116

Comments

  • Patreon has a version 6.0.0… Just sayin! :)

  • evanhevanh Posts: 15,126

    @TonyB_ said:

    @evanh said:
    On the other hand, if there is no branch and you execute off the end of lutRAM it will wrap back to cogRAM, albeit with the program counter ticking along above $400, because hubexec will only trigger on a branch.

    I think there might be something else apart from PC that wraps around from end of LUT RAM to start of cog RAM, from a discussion a few months ago.

    That was running off end of hubRAM I believe. Same story though. The program counter itself is 32-bit, therefore doesn't rollover at 1 MB, but not all bits are decoded so it still maps like it rolled over.

  • evanhevanh Posts: 15,126
    edited 2021-07-09 03:14

    @evanh said:
    Testing that it seems to be precisely scaled as longwords below $400 and bytes from $400 up. Which makes sense given that is the documented addressing. So a relative branch of $100 from $380 in lutRAM will land at $480 in hubRAM.

    Ha, just read the manual on these instructions, BRANCH ADDRESSING section. When in hubexec, they scale up the meaning of immediate relative encoding to longword steps. Which means that example there is at odds and will explain why I had previously thought there was something quirky at the lutRAM<->hubRAM boundary.

  • @evanh said:
    aaaw! didn't do lut<->hub ;)

    That crossing is kind of wonky due to the difference in the way the offsets are calculated. So I left the error in for that one.

  • evanhevanh Posts: 15,126

    Right. That fact sunk in for me a little later.

  • @evanh said:

    @TonyB_ said:

    @evanh said:
    On the other hand, if there is no branch and you execute off the end of lutRAM it will wrap back to cogRAM, albeit with the program counter ticking along above $400, because hubexec will only trigger on a branch.

    I think there might be something else apart from PC that wraps around from end of LUT RAM to start of cog RAM, from a discussion a few months ago.

    That was running off end of hubRAM I believe. Same story though. The program counter itself is 32-bit, therefore doesn't rollover at 1 MB, but not all bits are decoded so it still maps like it rolled over.

    Actually it was Fast Block Moves wrapping around to start of the same RAM (cog to cog or LUT to LUT), not LUT RAM to cog RAM.

  • @evanh said:

    @evanh said:
    Testing that it seems to be precisely scaled as longwords below $400 and bytes from $400 up. Which makes sense given that is the documented addressing. So a relative branch of $100 from $380 in lutRAM will land at $480 in hubRAM.

    Ha, just read the manual on these instructions, BRANCH ADDRESSING section. When in hubexec, they scale up the meaning of immediate relative encoding to longword steps. Which means that example there is at odds and will explain why I had previously thought there was something quirky at the lutRAM<->hubRAM boundary.

    It's not clear from the doc whether relative jumps from cog/LUT to hub are implemented in silicon. If they are, I guess that the hub address must be long-aligned.

  • evanhevanh Posts: 15,126
    edited 2021-07-09 11:01

    It is a little quirky but makes sense to me now. Relative branches from lut to hub are not scaled up in hubram space, ie: they're treated as if landing in lutram. But relative branches back from hub to lut are scaled up even in cog/lut space, ie: treated as if landing in hubram so multiplied by 4. Which means a negative branch from $404 by $100 will branch backwards by $400 and therefore will land at address 4 in cogram!

  • evanhevanh Posts: 15,126

    @TonyB_ said:
    Actually it was Fast Block Moves wrapping around to start of the same RAM (cog to cog or LUT to LUT), not LUT RAM to cog RAM.

    Somewhat of a different category not being instruction fetch. Don't remember seeing it either.

  • @ersmith Is there a way to tell FlexBASIC to hold-off on doing garbage collection? I occasionally find it tries to tidy-up the heap right when I’m about to enter a bit of time-critical code. Maybe something like _gc_pause() and _gc_resume() maybe?

  • @JRoark said:
    @ersmith Is there a way to tell FlexBASIC to hold-off on doing garbage collection? I occasionally find it tries to tidy-up the heap right when I’m about to enter a bit of time-critical code. Maybe something like _gc_pause() and _gc_resume() maybe?

    Automatic garbage collection only happens when the allocator would otherwise fail, so holding it off would mean failing allocation -- probably not what you want. The best ways to avoid garbage collection during time critical code are:

    (1) Avoid anything that requires memory allocation (string operations, mostly) inside the time critical code, or
    (2) Call _gc_collect explicitly right before the time critical code to force the collection when you want it done

  • JRoarkJRoark Posts: 1,214
    edited 2021-07-12 17:58

    @ersmith said:
    (2) Call _gc_collect explicitly right before the time critical code to force the collection when you want it done

    That works wonderfully! Actually, forcing a collection each time thru a slow loop seems to result in much faster, more predictable collection times. Winner!

  • evanhevanh Posts: 15,126
    edited 2021-07-18 05:25

    Eric,
    In C, I'm using _setclk() to adjust the sysclock frequency for testing purposes. It works, however, I still want to use printf() down the serial port. What options do I have for updating the baud on each clock change?

    PS: I've currently hacked in a _wxpin() for pins P62/P63. Doing the job.

  • @evanh Have you tried _setbaud(rate)?

  • evanhevanh Posts: 15,126
    edited 2021-07-18 13:49

    That's sounds like an option ... Yep, doing the job too.

  • Very interesting. I was just thinking about asking about this, but I was too shy.
    Could someone please summarize this in a single paragraph or two, ideally for the documentation.
    When can i do relative jumps, Registers, LutRam, HubRam.
    I guess that is two 3x3 matrix. One for C programs and one for Assembly programs.

    My suspicion is that one can do a lot more in assembly than one can in C.
    In particular, I suspect that in Assembly, I can move functions to Registers or LutRam, and do relative
    addressing on them, whereas I fear that C does not allow that.

    I also suspect that C does not support the skip function.
    Is there documentation somewhere on the differences between C and Assembly/Spin?

  • RaymanRayman Posts: 13,797

    @lozinski If you read the FlexProp main documentation, it says how to force code segments into Cog or LUT RAM.

  • evanhevanh Posts: 15,126
    edited 2021-07-18 18:58

    C, as a language generally, is intended to not be that architecture specific. On the other hand, what the compiler can generate most certainly is allowed to be architecture specific.

    That said, the __asm {} directives do provide a way to hand code Propeller specifics.

  • evanhevanh Posts: 15,126

    I've used asm {} to great effect here - https://forums.parallax.com/discussion/comment/1525977/#Comment_1525977
    muldiv65() makes use of the 64-bit result of a QMUL and 64-bit dividend of QDIV, but just as importantly it also incorporates round-to-nearest on the resulting 32-bit quotient.

  • @ersmith I noticed today that FlexBASIC has built-in facilities that allow you to start, query and get the ID of a cog, but there is no "cog stop" command. Would it be possible to round-out the cog control suite with a CPUSTOP() function? Presently I'm using the C function _cogstop(), but it seems odd there is no "native" equiv in FlexBASIC.

  • @JRoark said:
    @ersmith I noticed today that FlexBASIC has built-in facilities that allow you to start, query and get the ID of a cog, but there is no "cog stop" command. Would it be possible to round-out the cog control suite with a CPUSTOP() function? Presently I'm using the C function _cogstop(), but it seems odd there is no "native" equiv in FlexBASIC.

    Oh, I didn't realize there was no cpustop() in BASIC. I'll fix that, it really should be there. Thanks!

  • RaymanRayman Posts: 13,797
    edited 2021-07-24 21:40

    Seem to have an issue compiling mcufont (from github).

    Gives an error on line 397 (see image) when initializing a structure (in all the other font files too).
    Doesn't like the brackets inside brackets I guess.
    Error message: DejaVuSans12.c:397: error: Variable mf_rlefont_DejaVuSans12 is initialized twice

    The code claims to be ansi C...

    I've attached the source files. Build line is in build.bat.

    912 x 986 - 149K
  • @Rayman: thanks for the bug report. The initialization error is fixed in 5.5.2. Unfortunately there are still some other bugs that prevent your program from building. I'm not exactly sure what's going wrong, but it's probably something wrong with flexspin.

  • RaymanRayman Posts: 13,797

    @ersmith Thanks!
    Looking at the other issues now...
    Here's a strange one... It doesn't like the font structure reference in a complex line, but is OK when pulled out separately like this:

    MF_EXTERN void mf_character_whitespace(struct mf_font_s *font,
                                           mf_char character,
                                           uint8_t *left, uint8_t *top,
                                           uint8_t *right, uint8_t *bottom)
    {
        struct whitespace_state state = {255, 255, 0, 0};
        mf_render_character(font, 0, 0, character, whitespace_callback, &state);
    
    
    
        if (state.min_x == 255 && state.min_y == 255)
        {
            /* Character is whitespace */
            if (left) *left = font->width;
            if (top) *top = font->height;
            if (right) *right = 0;
            if (bottom) *bottom = 0;
        }
        else
        {
            int w = font->width;  //RJA making line below less complex
            int h = font->height;  //RJA
            if (left) *left = state.min_x;
            if (top) *top = state.min_y;
            //if (right) *right = font->width - state.max_x - 1;
            //if (bottom) *bottom = font->height - state.max_y - 1;
            if (right) *right = w - state.max_x - 1;
            if (bottom) *bottom = h - state.max_y - 1;
        }
    }
    
  • RaymanRayman Posts: 13,797

    @ersmith Got it to compile!
    The other strange error was that it doesn't like a structure element with name "state". Changed to "stated" and it works:

    struct renderstate_r
    {
        int16_t x_begin;
        int16_t x_end;
        int16_t x;
        int16_t y;
        int16_t y_end;
        mf_pixel_callback_t callback;
        //void *state
        void *stated;
    };
    
  • RaymanRayman Posts: 13,797
    edited 2021-07-31 21:58

    I'm adding some stuff to the above and get errors when partially initializing a structure.

    This line gives an error for apparently trying to initialize a structure with nothing:
    state_t state = {};

    This line gives an error for apparently trying to initialize a structure with just the first element:
    struct linelen_s current = { 0 };

    Update: I posted the full code in the mcufont thread, in case you need more info...

  • JRoarkJRoark Posts: 1,214
    edited 2021-07-31 20:58

    @ersmith Re: FlexBasic 5.5.2
    This code compiles without throwing an error.

    OPTION EXPLICIT
    CLASS tmpThing
        Widgets as single
        Widgets as ulong
        Widgets as byte
        Widgets as short
        Widgets as string
        Widgets as string
    END CLASS
    
    dim NewThing as tmpThing
    NewThing.Widgets = 10
    print "NewThing:Widgets="; NewThing.Widgets
    

    The above is an extreme example, but in the "real world" I found this while looking for a memory leak/corruptor where I had defined the same var in a CLASS twice. Correcting that duplication seems to have fixed the corruption issue, which is why I'm reporting it. :)

  • evanhevanh Posts: 15,126
    edited 2021-07-31 21:49

    Freshly pulled master nets me this error:
    make: *** No rule to make target 'backends/bytecode/bcbuffers.c', needed by 'build/bcbuffers.o'. Stop.

    Looking in backends/bytecode, there is no bcbuffers.c file.

    EDIT: Ah, and looking back at the git pull output I see this:

     backends/{bytecode => }/bcbuffers.c |   0
     backends/{bytecode => }/bcbuffers.h |   0
    
  • evanhevanh Posts: 15,126

    Grr, my GIT-foo is useless. The output from git pull shows what looks to be a moving of the two branches 'master' and 'release'. But my attempts at selecting the release branch go nowhere. eg: git branch only lists master.

  • @Rayman : thanks for the bug report. It may be a little while before I get to looking at that code.

    @JRoark : Hmmm, that is odd, there should have been some kind of warning. I'll try to figure it out.

Sign In or Register to comment.