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

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

19293959798103

Comments

  • pik33pik33 Posts: 1,809

    a << 1? Doesn't it have be a=a << 1?

  • ersmithersmith Posts: 5,513

    @JRoark said:
    @ersmith It looks like SHR, SHL, <<, and >> are broken in FlexBASIC Version 5.9.11.
    This code:

      option explicit
      dim a as ulong
      a = &h55555555
      a << 1
      print a
    

    throws this error:

    error: syntax error, unexpected shl, expecting $end or end of line or end or ':'
    

    SHL (and associated things) are operators, like "+" or "*". So you can't use them on their own, you have to do something like:

    a = a << 1
    
  • JRoarkJRoark Posts: 1,138

    Ok, now I feel like an idjit. 🙈

    But in my defense I recall the docs actually support this syntax. I’ll check and repost when I get home. In the mean time, I’ll wear the dunce cap. Lol

  • JRoarkJRoark Posts: 1,138

    Idjit-mode confirmed. Dunce hat applied.

    I will submit some mods for the FlexBASIC docs in due course to promote a bit more clarity in the way of correct copy/paste code examples.

  • evanhevanh Posts: 13,837
    edited 2022-06-12 23:46

    Eric,
    As per my latest mis-posting under Pnut topic - https://forums.parallax.com/discussion/comment/1539716/#Comment_1539716
    I've found that Flexspin supports the clkmode_ and clkfreq_ symbols at top level compile but not as objects.

    I'm keen to get feature parity on this. Including for struct __using() in C.

    PS: Here's a test program:

    CON
        _xtlfreq = 20_000_000
        _clkfreq = 80_000_000
        DOWNLOAD_BAUD = 230_400
        DEBUG_BAUD = DOWNLOAD_BAUD
        DIAGTXPIN = 62
        DIAGRXPIN = 63
    
    OBJ
        lib :"stdlib"
    
    
    PUB  do_test() | div, divisor
    
        send := @lib.putch
        waitms( 400 )
        lib.baudinit( DEBUG_BAUD )
        send( 10," Defaults: ",lib.dec(clkfreq),"  ",lib.hex(clkmode,8),13,10,10 )
    
        waitms( 400 )
        lib.pllset( 180_000_000 )
        lib.baudinit( DEBUG_BAUD )
        send( 10," Defaults: ",lib.dec(clkfreq),"  ",lib.hex(clkmode,8),13,10,10 )
    
  • ersmithersmith Posts: 5,513

    @evanh said:
    As per my latest mis-posting under Pnut topic - https://forums.parallax.com/discussion/comment/1539716/#Comment_1539716
    I've found that Flexspin supports the clkmode_ and clkfreq_ symbols at top level compile but not as objects.

    When you say not "as objects", do you mean "in objects"? That is, are you hoping to get the compile time definition of clkmode_ into a sub-object? if so, I'm very surprised that PNut would support this, since traditionally it compiles objects completely independently. Could it be that it's actually fetching the value at run time from the defined memory addresses?

  • evanhevanh Posts: 13,837
    edited 2022-06-13 01:28

    @ersmith said:
    When you say not "as objects", do you mean "in objects"? That is, are you hoping to get the compile time definition of clkmode_ into a sub-object?

    Yes.

    if so, I'm very surprised that PNut would support this, since traditionally it compiles objects completely independently. Could it be that it's actually fetching the value at run time from the defined memory addresses?

    I understand then to be constant symbols. Same as the prefixed underscore versions but are always defined. I use them to reference what the hardware crystal frequency and %CC mode bits are when adjusting the PLL. Certainly they don't adjust along with clkmode and clkfreq system variables.

    EDIT: They're documented in the Spin2 Language Documentation google doc under Clock Setup section:

    QUOTE:
    During compilation, two constant symbols are defined by the compiler, whose values reflect the compiled clock setup: ...

  • ersmithersmith Posts: 5,513

    Thank @evanh. It should be fixed now.

  • evanhevanh Posts: 13,837

    Perfect! My hero! It'd actually been a niggle for a year or two but I'd never looped back to making a formal posting about it till now. Back then, the testing was all done top-level so I didn't actually identify Flexspin was different to Pnut and got a tad confused, not unlike when posting in Pnut topic.

  • evanhevanh Posts: 13,837

    Eric,
    How many local (register) variables are automatically available with inline pasm, specifically with __asm volatile {}? I think I'm running out at eight of them.

  • All the variables are in registers to begin with (unlike Chip's interpreter, where they are on stack). If it runs out it won't compile ("fit failed" message).

  • evanhevanh Posts: 13,837
    edited 2022-06-14 23:48

    Something's weird. My code is crashing under unexplained conditions. The number of locals isn't it. I now think that just happened to coincide. I'm trying to use the streamer at the same time but that is reading from hubRAM so shouldn't be interfering. I've run out of time tonight ...

    EDIT: Oops, maybe it's the block copy to lutRAM for the CRC calc. Kind of forgot about that part. Seems a lot better now I've remove those two lines.

            setq2   #127
            rdlong  0, buf    // copy block (512 bytes) to lutRAM
    
  • evanhevanh Posts: 13,837
    edited 2022-06-16 12:57

    Lol, I can fix and trigger my crash with NOPs too. Hadn't been testing NOPs till now.

    EDIT: But not any longer. No more crashing from any of the combinations that used to do it ... I'm clueless as to why it happened, and why it's gone now. I still have the streamer actively using RDFAST in all tests and still exit the inline assembly on a WAITXFI.

    PS: It was still happening after removal of the lutRAM block write above and I can add that back in without problem.

    PPS: I never did try changing the compiler optimisation level.

  • evanhevanh Posts: 13,837
    edited 2022-06-16 12:45

    Eric,
    Got a result I didn't expect. When I add in some forced dead code:

        __asm volatile {
            getct   var1
            getct   var2
            getct   var3
            getct   var4
            getct   var5
            getct   var6
            add var1, var2
            add var1, var3
            add var1, var4
            add var1, var5
            add var1, var6
            ...
    

    This is the resulting code gen:

        org 0
        getct   result1
        getct   arg03
        getct   arg02
        getct   arg01
        getct   local06
        getct   local07
        add local08, arg03
        add local08, arg02
        add local08, arg01
        add local08, local06
        add local08, local07
        ...
    

    Of course it runs as expected because the var's are never used. So I gather the odd occurance of both result1 and local08 are just side effects of the compiler still attempting to eliminate dead code but getting stymied by the volatile.

  • ersmithersmith Posts: 5,513

    @evanh : I'd need to see the whole function in order to know exactly what's going on. But if the vars are never used then I think the code is valid as-is, right? This isn't actually a compiler bug?

  • That does seem slightly busted though. The first getct should be using local08, but it seems to think that it becomes dead and thus replaces it with another free register.

  • evanhevanh Posts: 13,837
    edited 2022-06-16 21:12

    @ersmith said:
    @evanh : I'd need to see the whole function in order to know exactly what's going on. But if the vars are never used then I think the code is valid as-is, right? This isn't actually a compiler bug?

    Here's the full source prior to adding the var's. (I'd undone the temporary dead code addition before going to bed.) It's my first experimenting code for testing out using the streamer and computing a CRC together - preparing for future 4-bit SD card writes.

    PS: I've been going around in circles trying to isolate why it had been crashing earlier. My first assumption had been that the WAITXFI event occurs early and the FIFO was losing a hubexec instruction to the streamer ... but I've not been able to prove that either. - https://forums.parallax.com/discussion/comment/1539747/#Comment_1539747

    c
    c
  • TonyB_TonyB_ Posts: 2,002

    Does Flexspin have a directive or something that makes assembling RFVAR/RFVARS addresses easier? In particular, convert a hub address to three RFVAR bytes automatically.

  • evanhevanh Posts: 13,837

    @TonyB_ said:
    Does Flexspin have a directive or something that makes assembling RFVAR/RFVARS addresses easier? In particular, convert a hub address to three RFVAR bytes automatically.

    I guess hubexec code could use RFVAR by embedding the constant assignments inline, so that they are pulled from the FIFO at the correct spacings to beat the cog's pipeline fetches. It would look weird as all hell reading the generated pasm.

  • TonyB_TonyB_ Posts: 2,002

    @evanh said:

    @TonyB_ said:
    Does Flexspin have a directive or something that makes assembling RFVAR/RFVARS addresses easier? In particular, convert a hub address to three RFVAR bytes automatically.

    I guess hubexec code could use RFVAR by embedding the constant assignments inline, so that they are pulled from the FIFO at the correct spacings to beat the cog's pipeline fetches. It would look weird as all hell reading the generated pasm.

    All I need is something that does RFVAR in reverse, without having to chop up the address and shift, mask and set msb's manually.

  • evanhevanh Posts: 13,837

    reverse? example please.

  • ersmithersmith Posts: 5,513

    Standard Spin2 has FVAR and FVARS for declaring unsigned and signed RFVAR data, and flexspin supports these.

  • evanhevanh Posts: 13,837
    edited 2022-06-16 22:47

    Oh, how is a BYTE FVAR any different from just a BYTE? I must admit, I've never seen the RFVAR instruction in use.

  • ersmithersmith Posts: 5,513

    FVAR compresses the data by using a scheme Chip devised (IIRC it stores 7 bits per byte, with the high bit indicating whether any more data is needed). It's useful for storing immediate constants in byte code -- the same bytecode can act on 8 bit, 16 bit, or 24 bit data, with the data itself indicating how many bytes are required. Here's a listing file showing how it works:

    00000                 | 
    00000                 | #line 1 "foo.spin2"
    00000                 | DAT
    00000                 | 
    00000 000             |     ORG 0
    00000 000 06 00 78 FC |     rdfast #0, dataptr
    00004 001 13 0E 60 FD |     rfvar  a
    00008 002 13 10 60 FD |     rfvar  b
    0000c 003 13 12 60 FD |     rfvar  c
    00010 004 13 14 60 FD |     rfvar  d
    00014 005             | 
    00014 005 36 02 64 FD |     DEBUG(uhex(a), uhex(b), uhex(c), uhex(d))
    00018 006             | 
    00018 006             | dataptr long           @data1
    00018 006 2C 00 00 00 
    0001c 007             | a   long   0
    0001c 007 00 00 00 00 
    00020 008             | b   long   0
    00020 008 00 00 00 00 
    00024 009             | c   long   0
    00024 009 00 00 00 00 
    00028 00a             | d   long   0
    00028 00a 00 00 00 00 
    0002c 00b             | 
    0002c                 |     ORGH
    0002c                 | data1
    0002c     12          |     long fvar $12
    0002d                 | data2
    0002d     B4 24       |     long fvar $1234
    0002f                 | data3
    0002f     AA B3 A2 04 |     long fvar $8899aa
    00033                 | data4
    00033     2C          |     long fvar @@@data1
    00034                 | 
    

    Note that "byte fvar", "word fvar", and "long fvar" all do the same thing (produce a sequence of bytes suitable for reading by RFVAR).

  • TonyB_TonyB_ Posts: 2,002

    @ersmith said:
    FVAR compresses the data by using a scheme Chip devised.

    Eric, thanks for adding this to Flexspin. It works a treat.

  • evanhevanh Posts: 13,837

    @ersmith said:
    FVAR compresses the data by using a scheme Chip devised (IIRC it stores 7 bits per byte, with the high bit indicating whether any more data is needed).

    Ah, that's like Unicode I think.

  • msrobotsmsrobots Posts: 3,611

    dataptr long @data1

    Does Proptool support this too?

    That is basically what @@@ did in Spin1 BST absolute Address in Dat Section instead of the need to write dataptr := @data1 somewhere in code not in DAT.

    curious,

    Mike

  • ersmithersmith Posts: 5,513

    @msrobots said:
    dataptr long @data1

    Does Proptool support this too?

    Only in pure PASM code. If any Spin code is mixed in the "@data1" will produce a relative address.

  • evanhevanh Posts: 13,837

    @ersmith said:
    If any Spin code is mixed in the "@data1" will produce a relative address.

    I was amused when inspecting a compiled .p2asm file and found a LOC instruction used to load a data value, into PA I think. The instruction encoding had it converted to be a PC-relative offset even though it wasn't a memory address. The value was something like 54 and the opcode located at higher address so the resulting encoded value was a fat negative number starting with $FFxxx.

  • RaymanRayman Posts: 12,920
    edited 2022-06-20 11:11

    @evanh said:
    Ah, that's like Unicode I think.

    I was thinking the same thing... It's essentially the same as UTF-8.

    Except this is limited to 24 bits? Why not allow 32-bits like UTF-8?

    Guess the Spin way saves a byte if 24-bit data is common. Guess depends on common usage...

Sign In or Register to comment.