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

1555658606168

Comments

  • On macOS, version 4.2.4-beta-8bb44ef7 of fastspin results in an illegal hardware instruction, when exec'd with "-l" (i.e. lowercase L) option... Using that option is the default in flexgui's Configure Commands window.
    "%D/bin/fastspin" -2 -l -D_BAUD=%r %O %I "%S"
                          ^
    
    from flexgui's usage: [ -l ] output DAT as a listing file
    ./fastspin -2b -l ../samples/blink1.spin 
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.2.4-beta-8bb44ef7 Compiled on: Jun 28 2020
    blink1.spin
    blink1.p2asm
    zsh: illegal hardware instruction  ./fastspin -2b -l ../samples/blink1.spin
    
    ./fastspin -2b ../samples/blink1.spin 
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.2.4-beta-8bb44ef7 Compiled on: Jun 28 2020
    blink1.spin
    blink1.p2asm
    Done.
    Program size is 1340 bytes
    

    dgately
  • @dgately: I can't reproduce that problem on my Mac-Mini. I tried both building the 4.2.4-beta-8bb44ef7 on the Mac, and also running the fastspin.mac from the flexgui.zip file, and both produced listing files from samples/blink1.spin. The Linux and Windows versions also seem to work OK.

    Could you try rebuilding after a "make clean"? If it still doesn't work, is there any way for you to get a stack trace? At this point I kind of suspect a bug in your installed version of Xcode, but I did make changes to the listing file output and maybe there's some subtle problem that doesn't trigger on older Xcode (and Linux gcc).

    Thanks,
    Eric
  • dgatelydgately Posts: 1,304
    edited 2020-06-28 - 15:15:08
    Eric, This was from a "make clean" & "make install" after exec'ing "git pull". I'll try fastspin.mac from your zip file and report results!

    My XCode has not been updated recently. I am running macOS 10.15.5, which is the latest OS.

    EDIT: Is this version of clang different than your version?
    % clang --version
    Apple clang version 11.0.3 (clang-1103.0.32.62)
    Target: x86_64-apple-darwin19.5.0
    Thread model: posix
    InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
    


    dgately
  • Oh it's definitely different, I have a very old macOS:
    Mac-mini:~ ersmith$ clang --version
    Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
    Target: x86_64-apple-darwin17.5.0
    Thread model: posix
    

    The binaries in flexgui.zip were actually built on Linux using a cross compiler, the version of which is even older I'm afraid:
    clang version 3.8.1-24 (tags/RELEASE_381/final)
    Target: x86_64-apple-darwin14
    Thread model: posix
    InstalledDir: /usr/bin
    
  • dgatelydgately Posts: 1,304
    edited 2020-06-28 - 16:26:39
    Even on my much older iMac OS (running 10.11.6), with clang version LLVM version 8.0.0, get's an error when using the "-l" option. That's the iMac running as David Zemon's TeamCity server. This was with a completely clean "git clone --recursive" from github.
    ~/flexgui]$ clang --version
    Apple LLVM version 8.0.0 (clang-800.0.42.1)
    Target: x86_64-apple-darwin15.6.0
    Thread model: posix
    InstalledDir: /Library/Developer/CommandLineTools/usr/bin
    

    From flegui's Computer Output:
    "/Users/myUserName/flexgui/bin/fastspin" -2 -l -D_BAUD=230400 -O1 -I "/Users/dgate/flexgui/include"  "/Users/dgate/flexgui/samples/blink1.spin"
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.2.3 Compiled on: Jun 28 2020
    blink1.spin
    blink1.p2asm
    child killed: SIGABRT
    Finished at Sun Jun 28 08:37:58 2020
    

    flexgui without "-l":
    "/Users/myUserName/flexgui/bin/fastspin" -2b -D_BAUD=230400 -O1 -I "/Users/dgate/flexgui/include"  "/Users/dgate/flexgui/samples/blink1.spin"
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.2.3 Compiled on: Jun 28 2020
    blink1.spin
    blink1.p2asm
    Done.
    Program size is 1340 bytes
    Finished at Sun Jun 28 08:46:38 2020
    

    Command line exec:
    ~/flexgui/bin]$ ./fastspin -2b -l ~/flexgui/samples/blink1.spin 
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.2.3 Compiled on: Jun 28 2020
    blink1.spin
    blink1.p2asm
    Abort trap: 6
    

    EDIT: Error reports is attached!

    EDIT2: lldb session dump attached!
  • @dgately: the crash dump showed the problem: in newer clang's Apple added a check for overlapping strcpy. I had forgotten that this is undefined behavior (the straightforward implementation of strcpy(a, b) works fine if a < b, but it's technically not required for the library to support this case).

    Thanks for finding this, and I've checked in a fix.
  • Tested... works on my 10.15.5 system.
    Tested and working on the Team City server Mac, too.

    THx!
  • Eric,

    Today I have been struggling to make a piece of code work exactly the same in Chips interpreter and FastSpin...
    It turns out that the "encod" operator behaves differently between the compilers. FastSpins version behaves like the PASM instruction while the interpreter offsets the value by one.

    FastSpin says that "encod 1 == 1" while the interpreter says that "encod 1 == 0"... Who is right? I kind of think that it makes more sense that the PASM instruction and the operator works the same.
    Is it a bug in the interpreter? Chip?

    /Johannes
  • This is probably a bug in fastspin: the ENCOD instruction doesn't do what the equivalent operator did in Spin1. I'll try to fix it soon.

    (I think the Spin2 ENCOD operator is actually doing what the assembly instruction does; it's just not what I expected.)

    Thanks,
    Eric
  • Yep, prop2 ENCOD instruction will make a 1 into a 0.
    2 or 3 => 1
    4/5/6/7 => 2
    8/9/10/11/12/13/14/15 => 3
    ...
  • After running the following code in FastSpin...
    repeat i from 0 to 20
        if i == 10
          r := i
          quit
    

    i == 10
    r == undefined

    It will yield the right result if I compile with "-O1".

    /Johannes

  • Thanks for the bug report, Jesse. There was a problem with one of the -O2 loop optimizations. It's fixed in github now.
  • @ersmith Running FlexBASIC V4.2.3 on P2-EVAL R2 on Win 10:

    It appears the PINSET() function isn't being recognized by the compiler. This code:
    OPTION EXPLICIT
    CONST X_PIN = 28
    CONST HIGH = 1
    
    	pinset(X_PIN, HIGH)
    
    produces this: "error: Undefined symbol pinset".
  • @JRoark: thanks for the bug report. A typo crept in to the BASIC code when I was re-arranging some of the functions to match the Spin2 names. I'll fix that soon!
  • Hi Eric,

    great presentation, BTW! I watched it but wasn't able to contribute much. First, I couldn't find my camera and my microphone didn't work. Second, I had been rock climbing the whole day, it was late at night (23 PM CEST) and I could hardly keep my eyes open. I haven't learned anything new but I hope that many others have discovered the potential of FastSpin and it helps you gain some more users and patreons.

    Now, one more question: Is it possible to assign a Spin function to a function pointer variable in C? I tried this:
    static struct __using("Sc3_IncEnc.spin2")	enc;
    
    typedef int32_t (*PositionGetter) ();
    
    PositionGetter GetPact;	// pointer to actual position getter function
    
    void SetPActSource (PositionGetter getPos, int ppr)
    // Sets actual position source (encoder or resolver)
    {
      GetPact= getPos;
      ResetPosition ();
    }
    
    ...
    void main 
    {
      SetPActSource (enc.GetPosition, ppr)
    ...
    
    But I get an error message "Unable to dereference symbol GetPosition in Sc3_IncEnc_spin2". Is this a general problem of the compiler or have I done something wrong? I never can remember where to put the "*" in function pointer definitions...
    It would be nice if this worked because I have many different encoder drivers and I'd like to call the position getter via a function variable instead of many ugly switch/case statements.
  • It's certainly possible to assign a Spin function to a C function pointer. I think you need to explicitly put an address of operator (&) before any methods inside classes, though. Here's a sample program that does work:
    // simple demo for function pointers
    static struct __using("spin/SmartSerial.spin") ser;
    
    typedef int (*TxFunc)(int);
    
    void putstr(TxFunc f, const char *str)
    {
        while (*str) {
            f(*str++);
        }
    }
    
    void main()
    {
        ser.start(63, 62, 0, 230400);
        putstr(&ser.tx, "hello, world!\n");
    }
    
  • Eric, I have to say that your integration of C, Spin, Basic and Pasm is truly amazing. Excellent work!
  • Thanks Eric! With the "&" before the function argument it worked immediately. AsI said I often mix up the uses of "*" and "&" in C and I'm a bit spoiled by the error messages of GCC. In this case it would say something like "incompatible types for argument 1 of GetPActSource(), expected *PositionGetter aka int (*) (void)".
    Dave Hein wrote: »
    Eric, I have to say that your integration of C, Spin, Basic and Pasm is truly amazing. Excellent work!

    +1
  • Dave Hein wrote: »
    Eric, I have to say that your integration of C, Spin, Basic and Pasm is truly amazing. Excellent work!

    Thanks Dave! And thank you for what you did with loadp2 -- it's really been an incredibly useful program!
  • ManAtWork wrote: »
    Thanks Eric! With the "&" before the function argument it worked immediately. AsI said I often mix up the uses of "*" and "&" in C and I'm a bit spoiled by the error messages of GCC. In this case it would say something like "incompatible types for argument 1 of GetPActSource(), expected *PositionGetter aka int (*) (void)".
    Well, the root problem for fastspin was that without the "&" it thought that the method was never used and removed it. Which probably wasn't quite the correct behavior, but that's why you got the error message you did. I will try to improve this in the next release.
  • A new version of fastspin/spin2cpp is available from github. It has a lot of bug fixes (including the issues discussed here in the forums) and improvements to Spin2 compatibility.
  • I think we had this one before in C, now it's in Spin2.
    PRI Spi_RdByte (): b
    ' read 8 bits
      ORG
    	wypin	#16,#spi_ck		'start 16 clock transitions
    	mov	b,#0
    	waitx	#2			' 1..4 works for me
    	rep	#.loop,#8
    	testp   #spi_do wc
    	rcl	b,#1
    .loop
      END
    
    The above works but the following doesn't
    	rep	#2,#8
    	testp   #spi_do wc
    	rcl	b,#1
      END
    
    Should be the same, I think (repeat the next 2 instructions 8 times). If I read the docs correctly D for REP is always relative, so either .loop (without #) or #2 should be correct. But both result in an error of the compiler or assembler.
  • Use "rep @.loop,#8" rather than "rep #.loop,#8". The first form means "use the difference up to .loop as the repeat count", the second one means "use the value of the label .loop as the repeat count".

    I agree that "rep #2,#8" should work, I'll try to fix that.
  • Isn't their a difference between how to use REP in inline vs. regular assembly?

    Seem to recall that #.loop is correct for inline...
  • #.loop works in inline (not in regular) but it's not optimal. @.loop is the correct form. There are some older versions of fastspin that don't support the @.loop form, but if you have one of those you should upgrade :).
  • Ok, I'm glad that got changed then! Was very confusing...
  • Eric,
    I was trying out fastspin compiling P1 ZiCog version (previously compiled with homespun and bst) and noticed that the #warn used in homespun/bst is not supported. Not a problem for me - just reporting a difference.
    #ifdef CPU_Z80
    #elseifdef CPU_8080
    #else
    #warn No CPU type defined
    #endif
    
  • Huh, there was a typo in the code for #warn that caused it not to work (it was supposed to, and I thought it did at one time). That'll be fixed in the next release. In the meantime #error does work.
  • @ersmith FlexBASIC V4.2.4 under Win10:

    This is a trivial one, but here it is. Consider these two declarations:
    dim PRO as class using "d:\Flex2Gui\flexgui\P2 Libs\PropellerLibP2.bas"
    dim PRO as class using "\Flex2Gui\flexgui\P2 Libs\PropellerLibP2.bas"
    

    Neither of these forms cause any *compiler* errors and both create the same, functional code. But within the IDE, if the user clicks on the link created by the first form (with the drive letter) the IDE complains with a message box saying "D is not found". This error does not occur when clicking on the second form.

    Not critical. Just inconsistent. :)
  • The #warn problem and link issue in the GUI are both fixed in 4.2.5. I've published a beta version of the binary for this to my Patreon page. It's patron-only for now, but in 3 days it'll become available to everyone. (Or, you can always build from the github source.)

    The other major new feature coming in 4.2.5 is a flag, -Wall, to enable additional warnings. The most interesting of these are warnings about using fastspin language extensions. This should make porting code to PNut easier (fastspin -2 -Wall will let you know at least some of the changes you'll have to make to your fastspin code to make it work with PNut).
Sign In or Register to comment.