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

Comments

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.

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 !

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

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 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.

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.

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.

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.

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:

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).

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:

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.

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.

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.

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.

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.

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.

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.

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.

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.

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!