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

13468911

Comments

  • Thank you Eric!
    Mike R.
  • Eric,
    I have started using spin2gui to write C programs for the P2ES. So far just compiling very simple programs (add 2 variables, set pins to input/output, high/low) to see what works and what the P2ASM looks like.

    I did try using #include propeller.h, but got an error message so just compiled the programs without any includes.

    What propeller features are supported? I saw that DIRA(int), OUTA(int) and INA are, but the SimpleTools versions (high, low, etc.) are not, although since I didn't know how to include Simpletools.h I'm not really sure.

    Could you please let us know a bit more about C through spin2gui?

    Thanks
    Tom
  • Eventually SimpleTools will be supported, but right now all that's supported is raw C (no libraries, basically; there are a few header files but they're very unfinished). There's a little bit of documentation in docs/c.md, although even that unfortunately has a typo: the "asm" keyword for inline assembly should read "__asm" (two underscores in front).

    There are some built in variables; basically all of the Propeller registers (INA, OUTA, DIRA, CNT, etc.) and at the moment the built in Spin functions like waitcnt(), cogid(), coginit(), and so on are also available from C. Soon (in the next release I hope) the C library will start to come together.

    I am puzzled that you had trouble with #include <propeller.h>. That should have worked, although the provided propeller.h is quite incomplete. Is there an include/propeller.h file in your spin2gui installation?

    Thanks for trying out fastspin and spin2gui. The more bugs we can shake out early the quicker we can get this working properly :)!
  • Eric: Have you added structs to your C compiler yet?
  • The version of fastspin in github now has some very preliminary struct support, but it's still incomplete (for example passing and returning structs by value does not work).
  • ersmith wrote: »

    I am puzzled that you had trouble with #include <propeller.h>. That should have worked, although the provided propeller.h is quite incomplete. Is there an include/propeller.h file in your spin2gui installation?
    Eric,
    Thanks for the info.
    I tried again & #include <propeller.h> worked. Not sure what I did wrong originally.
    Tom
  • ersmith wrote: »
    The version of fastspin in github now has some very preliminary struct support, but it's still incomplete (for example passing and returning structs by value does not work).
    That sounds good. I try not to pass structs by value anyway. Thanks!

  • David BetzDavid Betz Posts: 13,099
    edited 2018-12-12 - 03:01:50
    Okay, I cloned your GitHub repository and built fastspin. Do you have a sample C program?

    Edit: Never mind. I see there is some sample C code in the Test directory.
  • I should emphasize here that fastspin/C (aka "flexC") is not really usable yet -- I kind of got ahead of myself by announcing it as a feature. It can compile very simple benchmarks and bit banging programs, but anything beyond that is going to give it trouble. It is changing quickly, and I hope to get it into a state where it's useful soon. But it isn't quite there yet :(.
  • ersmith wrote: »
    I should emphasize here that fastspin/C (aka "flexC") is not really usable yet -- I kind of got ahead of myself by announcing it as a feature. It can compile very simple benchmarks and bit banging programs, but anything beyond that is going to give it trouble. It is changing quickly, and I hope to get it into a state where it's useful soon. But it isn't quite there yet :(.
    I assume it is at least a strict subset of C so anything that gets developed with it will also compile with a full ANSI C compiler? That is, of course, everything other than the extensions you've added to interface to Spin and BASIC code.
  • David Betz wrote: »
    ersmith wrote: »
    I should emphasize here that fastspin/C (aka "flexC") is not really usable yet -- I kind of got ahead of myself by announcing it as a feature. It can compile very simple benchmarks and bit banging programs, but anything beyond that is going to give it trouble. It is changing quickly, and I hope to get it into a state where it's useful soon. But it isn't quite there yet :(.
    I assume it is at least a strict subset of C so anything that gets developed with it will also compile with a full ANSI C compiler? That is, of course, everything other than the extensions you've added to interface to Spin and BASIC code.

    Eventually I hope for it to be a strict superset of ANSI C, that is for it to support everything in some version of ANSI C (probably C99) plus some extensions. As an example of extensions, it already supports binary notation (0b1111 == 0xf) and underscores inside numbers (so 115_200 == 115200). It'll almost certainly support some subset of C++ classes -- in fact the github version kind of does that now with the "struct __using" notation.

    At the moment it's a bit of a mish-mash, with many standard C features (like structs and the standard library) not working or only partially working. It should parse (almost) any legal C program, since I started with a C89 YACC file, but whether it'll produce valid output is another matter entirely! It's under very active development, so if you pull from github regularly you'll get new features and bug fixes every few days.
  • ersmith wrote: »
    David Betz wrote: »
    ersmith wrote: »
    I should emphasize here that fastspin/C (aka "flexC") is not really usable yet -- I kind of got ahead of myself by announcing it as a feature. It can compile very simple benchmarks and bit banging programs, but anything beyond that is going to give it trouble. It is changing quickly, and I hope to get it into a state where it's useful soon. But it isn't quite there yet :(.
    I assume it is at least a strict subset of C so anything that gets developed with it will also compile with a full ANSI C compiler? That is, of course, everything other than the extensions you've added to interface to Spin and BASIC code.

    Eventually I hope for it to be a strict superset of ANSI C, that is for it to support everything in some version of ANSI C (probably C99) plus some extensions. As an example of extensions, it already supports binary notation (0b1111 == 0xf) and underscores inside numbers (so 115_200 == 115200). It'll almost certainly support some subset of C++ classes -- in fact the github version kind of does that now with the "struct __using" notation.

    At the moment it's a bit of a mish-mash, with many standard C features (like structs and the standard library) not working or only partially working. It should parse (almost) any legal C program, since I started with a C89 YACC file, but whether it'll produce valid output is another matter entirely! It's under very active development, so if you pull from github regularly you'll get new features and bug fixes every few days.
    Thanks, Eric! Where is your standard library code? I see a "Lib" subdirectory in your repository but it only contains Spin code.
  • David Betz wrote: »
    Thanks, Eric! Where is your standard library code? I see a "Lib" subdirectory in your repository but it only contains Spin code.

    There isn't any yet, except for the small amount inside the include subdirectory. That's the next major thing I need to work on. (At present there's no mechanism for linking.)

  • ersmith wrote: »
    David Betz wrote: »
    Thanks, Eric! Where is your standard library code? I see a "Lib" subdirectory in your repository but it only contains Spin code.

    There isn't any yet, except for the small amount inside the include subdirectory. That's the next major thing I need to work on. (At present there's no mechanism for linking.)
    Okay, thanks. I thought maybe it was in a different GitHub project.

  • Do you need any help with this? I assume you have the compiler under control yourself but what about the library? Can't stuff be brought over from the PropGCC library? I guess it doesn't make much sense to modify the code to adhere to the subset of C that you currently support because that subset will grow as you complete the compiler but maybe some stuff doesn't use anything beyond what you already support.
  • David Betz wrote: »
    Do you need any help with this? I assume you have the compiler under control yourself but what about the library? Can't stuff be brought over from the PropGCC library?
    Yes, I could definitely use help, thanks! I do plan to re-use the PropGCC library, with #ifdefs as needed. I started looking at the #include files (as you can see I've moved a few over) to see what needs changing for another compiler. It's kind of too bad we didn't port that library to Catalina, it would have made porting it again much easier.

    On the topic of linking, I was thinking of starting off without a linker at all but with a directive in the header files to indicate what source file to include. That is, string.h would have definitions like:
    #ifdef __FLEXC__
    #define _IMPL(x) __fromfile(x) /* gives where to find the function */
    #else
    #define _IMPL(x) /* default */
    #endif
    
    char *strcpy(char *dest, const char *src) _IMPL("libc/string/strcpy.c");
    int strcmp(char *a, char *b) _IMPL("libc/string/strcmp.c");
    ...
    
    and so on. If the user provides a definition for one of these functions the _IMPL note is ignored. But if there is no definition, then the compiler knows it has to include the _IMPL file as if it were given on the command line.

    The advantage of this method is that the header file has all the info needed to compile -- there's no .a file -- and the compiler always sees all source code, so it can inline functions and perform similar optimizations. The disadvantage is that it's non-traditional, and perhaps a bit less efficient. I don't think efficiency is going to be a big issue; modern computers are literally thousands of times faster than the computers that C was first designed for, and P1 and P2 programs are not going to be excessively huge (they have to fit in 32K or 1M respectively).
  • David BetzDavid Betz Posts: 13,099
    edited 2018-12-12 - 13:21:23
    ersmith wrote: »
    On the topic of linking, I was thinking of starting off without a linker at all but with a directive in the header files to indicate what source file to include. That is, string.h would have definitions like:
    #ifdef __FLEXC__
    #define _IMPL(x) __fromfile(x) /* gives where to find the function */
    #else
    #define _IMPL(x) /* default */
    #endif
    
    char *strcpy(char *dest, const char *src) _IMPL("libc/string/strcpy.c");
    int strcmp(char *a, char *b) _IMPL("libc/string/strcmp.c");
    ...
    
    and so on. If the user provides a definition for one of these functions the _IMPL note is ignored. But if there is no definition, then the compiler knows it has to include the _IMPL file as if it were given on the command line.

    The advantage of this method is that the header file has all the info needed to compile -- there's no .a file -- and the compiler always sees all source code, so it can inline functions and perform similar optimizations. The disadvantage is that it's non-traditional, and perhaps a bit less efficient. I don't think efficiency is going to be a big issue; modern computers are literally thousands of times faster than the computers that C was first designed for, and P1 and P2 programs are not going to be excessively huge (they have to fit in 32K or 1M respectively).
    I assume you'll ignore the __fromfile(x) directives if the corresponding function isn't actually referenced in the user's program? Header files tend to define huge numbers of functions most of which are not used by any particular program. I suspect that you have dead code elimination so they wouldn't get included in the final executable but just parsing all of those files might be slow for programs that include a lot of the standard header files.

    Compiling a 32K executable should be fast enough but a 512K executable might take a while to build if it has to be compiled from scratch each time. Maybe still not a big deal though.

  • David BetzDavid Betz Posts: 13,099
    edited 2018-12-21 - 02:39:28
    It seems that my P2-ES board is on the way. I guess it's time to make sure I have a full set of tools to program it. I just updated my spin2cpp repository clone so I have its assembler and compilers but I'm wondering what else I need to program the P2. I assume I'll need loadp2. Where is the latest version of that located? Do I need anything else other than a text editor?

    Edit: I just found loadp2 as part of the zip file posted in the p2gcc thread. I guess I'm all set!
  • Does fastspin look at the file extension of the file it is compiling to determine whether to compile for P1 or P2? It seems like I have to specify -2 on the command line even though the file I'm compiling has a ".spin2" extension.
  • David Betz wrote: »
    Does fastspin look at the file extension of the file it is compiling to determine whether to compile for P1 or P2?
    No, fastspin uses the file extension only to determine what kind of *input* it has been given (Spin, BASIC, or C). The output is always determined by the command line flags. You'll have to give -2 on the command line to build for P2.
  • ersmith wrote: »
    David Betz wrote: »
    Does fastspin look at the file extension of the file it is compiling to determine whether to compile for P1 or P2?
    No, fastspin uses the file extension only to determine what kind of *input* it has been given (Spin, BASIC, or C). The output is always determined by the command line flags. You'll have to give -2 on the command line to build for P2.
    Thanks!

  • cheezuscheezus Posts: 108
    edited 2018-12-21 - 19:28:53
    I keep forgetting to post a bug report for Spin2GUI v1.2.3 on P1 source "error: fit 496 failed: pc is 624"

    The project is a mess and I'm guessing it has something to do with the DAT sections littered everywhere. Attached is a zip of the project.

    *edit
    I should mention I was trying to compile for P1.
  • One of the Spin objects that is used in almost all of my Spin projects is FullDuplexSerial (and its cousin FullDuplexserialPlus)... Of course that object has a dependency on its PASM code that includes several jmpret instructions. Building P2 projects with fastspin is chocking on those instructions...

    Is there a quick solution or should I just remove my Spin code projects dependencies on FDS? Seems that I'll need to replace FDS with a P2 equivalent, eventually, right?

    UPS tells me that my P2ES will be delivered today and I want to test a few of my existing projects.

    dgately
    Livermore, CA (50 miles SE of San Francisco)
  • I wonder if "simple_serial" would work... Looks like it might...
    Prop Info and Apps: http://www.rayslogic.com/
  • The ROM has a built-in serial driver without fifo. I've posted examples of how to use it. It doesn't do all that FDX does, but it will read a cr terminated string or single char too.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • cheezus wrote: »
    I keep forgetting to post a bug report for Spin2GUI v1.2.3 on P1 source "error: fit 496 failed: pc is 624"

    The project is a mess and I'm guessing it has something to do with the DAT sections littered everywhere. Attached is a zip of the project.
    I think rather than the DAT sections it's a very large number of constants (many of which are generated by references to large objects). fastspin uses COG RAM to store immediate values > 512 which it needs, and in this case it seems to need a lot of them :(. I'm going to have to look at how to reduce that, but it'll be a while before I can get to it.

    Thanks for the bug report!
  • ersmithersmith Posts: 2,712
    edited 2018-12-21 - 23:32:34
    dgately wrote: »
    One of the Spin objects that is used in almost all of my Spin projects is FullDuplexSerial (and its cousin FullDuplexserialPlus)... Of course that object has a dependency on its PASM code that includes several jmpret instructions. Building P2 projects with fastspin is chocking on those instructions...

    Is there a quick solution or should I just remove my Spin code projects dependencies on FDS? Seems that I'll need to replace FDS with a P2 equivalent, eventually, right?

    You'll certainly have to replace FDS (as you've noticed, it won't work on P2 anyway because of the PASM code not being compatible). I usually use some variant of SimpleSerial.spin, which is a dead simple half-duplex driver that'll work on P1, P2, and PC. I think it's in the fastspin Libs/ directory, but I've attached a copy here just in case.

    Edit: the original version I posted was missing P2 and PC support for rx. I've updated those, and added a demo program. There still seems to be a bug in the P2 rx, or perhaps in fastspin: I had to compile with -2 -O0 to get it to work right.
  • ersmith wrote: »
    dgately wrote: »
    One of the Spin objects that is used in almost all of my Spin projects is FullDuplexSerial (and its cousin FullDuplexserialPlus)... Of course that object has a dependency on its PASM code that includes several jmpret instructions. Building P2 projects with fastspin is chocking on those instructions...

    Is there a quick solution or should I just remove my Spin code projects dependencies on FDS? Seems that I'll need to replace FDS with a P2 equivalent, eventually, right?

    You'll certainly have to replace FDS (as you've noticed, it won't work on P2 anyway because of the PASM code not being compatible). I usually use some variant of SimpleSerial.spin, which is a dead simple half-duplex driver that'll work on P1, P2, and PC. I think it's in the fastspin Libs/ directory, but I've attached a copy here just in case.
    Nice and simple as advertised but I don't see how rx will work on a PC.
  • David Betz wrote: »
    ersmith wrote: »
    dgately wrote: »
    One of the Spin objects that is used in almost all of my Spin projects is FullDuplexSerial (and its cousin FullDuplexserialPlus)... Of course that object has a dependency on its PASM code that includes several jmpret instructions. Building P2 projects with fastspin is chocking on those instructions...

    Is there a quick solution or should I just remove my Spin code projects dependencies on FDS? Seems that I'll need to replace FDS with a P2 equivalent, eventually, right?

    You'll certainly have to replace FDS (as you've noticed, it won't work on P2 anyway because of the PASM code not being compatible). I usually use some variant of SimpleSerial.spin, which is a dead simple half-duplex driver that'll work on P1, P2, and PC. I think it's in the fastspin Libs/ directory, but I've attached a copy here just in case.
    Nice and simple as advertised but I don't see how rx will work on a PC.

    You're right, rx was a late addition and I forgot to put in an #ifdef PC to make it use getchar(). So at the moment SimpleSerial won't work on PC. It'd be easy enough to fix (just follow the template for tx).

    Actually it looks like rx is broken on P2 as well :(. I'll have to take a look at that.
  • ersmith wrote: »
    cheezus wrote: »
    I keep forgetting to post a bug report for Spin2GUI v1.2.3 on P1 source "error: fit 496 failed: pc is 624"

    The project is a mess and I'm guessing it has something to do with the DAT sections littered everywhere. Attached is a zip of the project.
    I think rather than the DAT sections it's a very large number of constants (many of which are generated by references to large objects). fastspin uses COG RAM to store immediate values > 512 which it needs, and in this case it seems to need a lot of them :(. I'm going to have to look at how to reduce that, but it'll be a while before I can get to it.

    Thanks for the bug report!

    That totally makes sense, I'll look at what I can do to optimize the code knowing this. Nice work btw!
Sign In or Register to comment.