Inline assembly is a restricted subset of the full assembly language, and one of the restrictions is that only the conditions used by the compiler (like if_z, if_lt, etc.) are accepted in inline assembly. The implementation of inline assembly is completely different from that in the "main" assembler (top level __pasm blocks, for example).
Ever notice how spin2 just changes the P2 into an 8-bit instruction, 32-bit data Harvard architecture?
You mean PNut, I presume. The Spin2 language has two different implementations, PNut (Chip's compiler) and fastspin (my compiler). fastspin compiles everything into native P2 machine code.
Yes. Of course. Where I was heading with my comment was there seems to be a 1:1 relationship between spin2 operators and the underlying assembly language instructions. But that PNut is running bytecode instructions as if it was an 8 bit virtual CPU. Kind of a contradiction.
Inline assembly is a restricted subset of the full assembly language, and one of the restrictions is that only the conditions used by the compiler (like if_z, if_lt, etc.) are accepted in inline assembly. The implementation of inline assembly is completely different from that in the "main" assembler (top level __pasm blocks, for example).
Yes, I've alredy noticed. Inline assembly is passed as plain text to the p2asm file. Top level pasm is parsed and output as hex codes. I wonder why the conditions are restricted in inline assembly. If it is passed through to the p2asm file the compiler doesn't need to interpret it. If it was the other way round (translation to hex codes necessary) I'd understand it.
So the restrictions are there because the missing condition prefixes are simply not implemented? Or is there a more complicated reason like the optimizations wouldn't work?
BYTEMOVE() (and I guess also word-and longmove) works a bit different on PNUT and Fastspin.
Spin1 and Spin2 copy the bytes either upwards or downwards, depending on the source and destination addresses, fastspin does it always upwards.
This matters if you use bytemove() i.e. for string manipulation:
_clkfreq = 160_000_000
OBJ
ser : "spin/SmartSerial"
DAT
astr byte "test text ",0
PUB go()
ser.start(63,62,0,115200)
ser.printf("\nOriginal: %s",@astr)
bytemove(@astr,@astr+1,9) 'delete first char
ser.printf("\nDeleted: %s",@astr)
bytemove(@astr+1,@astr,9) 'insert another char
astr[0] := "b"
ser.printf("\nInserted: %s",@astr)
repeat
Output:
]
Fastspin:
Original: test text
Deleted: est text
Inserted: beeeeeeeee
PNUT:
Original: test text
Deleted: est text
Inserted: best text
Yes. Of course. Where I was heading with my comment was there seems to be a 1:1 relationship between spin2 operators and the underlying assembly language instructions. But that PNut is running bytecode instructions as if it was an 8 bit virtual CPU. Kind of a contradiction.
It's done for an aggressive trade off between size and speed. Small size, with hardware assist to perform much better than an intrepeter would otherwise, and where one needs speed, or can use concurrency, there is inline assembly and or the COGS.
We are going to be spoiled in a way. Anyone wanting a compile to machine code can get it as well as the spiffy byte code scenario.
Note that string1 and string2 are created by an automatic skip pattern generator program and are in an include file. Concatenator would have to remove any % (or $) after first char or replace with underscore.
EDIT:
This is for pure PASM2, not any variant of Spin.
Note that string1 and string2 are created by an automatic skip pattern generator program and are in an include file. Concatenator would have to remove any % (or $) after first char or replace with underscore.
EDIT:
This is for pure PASM2, not any variant of Spin.
An alternative is to or/add string1 with string2 shifted left by bit width of string1 (which could contain underscores).
Values and widths of strings are not known to the programmer because that is the whole point of using an automatic skip pattern generator.
BYTEMOVE() (and I guess also word-and longmove) works a bit different on PNUT and Fastspin.
Spin1 and Spin2 copy the bytes either upwards or downwards, depending on the source and destination addresses, fastspin does it always upwards.
Ah, interesting, I hadn't checked overlapping moves. Thanks for catching this! It's fixed in github now.
Note that string1 and string2 are created by an automatic skip pattern generator program and are in an include file. Concatenator would have to remove any % (or $) after first char or replace with underscore.
EDIT:
This is for pure PASM2, not any variant of Spin.
No, and that syntax would be ambiguous I'm afraid. It might be possible to modify the preprocessor to do a sort of string concatenation similar to the C ## preprocessor directive. I'm not sure how broadly useful it would be, though.
My skip pattern generator program (which I posted but nobody appears to have tried) writes constants to an include file. However, the bit width of these constants is not known until after they have been created, so fixed left shifts won't work.
If bwidth were a bit width function, then the code could look like:
bvalue3 long bvalue2 << bwidth(bvalue1) | bvalue1
bvalue1 could be skip bit pattern that selects source & destination data, while bvalue2 performs an operation on the data. This could be much simpler than combining both data selection and operation in a single pattern.
My skip pattern generator program (which I posted but nobody appears to have tried) writes constants to an include file. However, the bit width of these constants is not known until after they have been created, so fixed left shifts won't work.
If bwidth were a bit width function, then the code could look like:
bvalue3 long bvalue2 << bwidth(bvalue1) | bvalue1
bvalue1 could be skip bit pattern that selects source & destination data, while bvalue2 performs an operation on the data. This could be much simpler than combining both data selection and operation in a single pattern.
It might be better to say "bit length" instead of "bit width". The number of actual 0s and 1s in bvalue1 is the critical thing, not the number of bits needed to store that value. Leading 0s must not be removed.
I just found that it doesn't seem like the operator +>= compiles in Fastspin 4.1.9, and gives an error about not liking the equals sign, but using +> compiles for unsigned comparisons. Is this feature intended to work at some point? ie. an unsigned greater than or equal to check.
I just found that it doesn't seem like the operator +>= compiles in Fastspin 4.1.9, and gives an error about not liking the equals sign, but using +> compiles for unsigned comparisons. Is this feature intended to work at some point? ie. an unsigned greater than or equal to check.
When I invented the unsigned comparison operators it was in the context of Spin1, so unsigned greater than or equal to is written "+=<". When Chip took them over into Spin2 he changed it to "+<=". I didn't realize that, I'll add an alias for them in Spin2. Meanwhile you can write code that works in both compilers by using the fact that "a +<= b" is equivalent to "NOT (b +> a)".
@ersmith, what is the plan for handling => vs >= between PNut and Fastspin?
In Spin1 mode (the filename ends in ".spin") a >= b is treated as it is in Spin1, namely assignment a := a > b. In Spin2 mode (the filename ends in ".spin2") it is treated as "a greater than or equal to b".
In all cases a => b is treated as "a greater than or equal to b".
@ersmith, what is the plan for handling => vs >= between PNut and Fastspin?
In Spin1 mode (the filename ends in ".spin") a >= b is treated as it is in Spin1, namely assignment a := a > b. In Spin2 mode (the filename ends in ".spin2") it is treated as "a greater than or equal to b".
In all cases a => b is treated as "a greater than or equal to b".
Is there a command line option to force either Spin1 or Spin2 support regardless of the file extension? I don't need this but it occurs to me that some might just want to call their files "*.spin" but still process them as Spin2 files.
Is there a command line option to force either Spin1 or Spin2 support regardless of the file extension? I don't need this but it occurs to me that some might just want to call their files "*.spin" but still process them as Spin2 files.
No. It's like .c vs .cpp; if you want C++, you have to give a C++ extension to the file name. The reason is that multiple files may be given both on the command line and in OBJ declarations, and having a global mode that affects all of them is probably not going to work very often.
Note too that "Spin2 mode" means "Spin2 language" mode, and is independent of whether the processor is P1 or P2.
Like I said, in all cases "a => b" is treated as "a greater than or equal to b". Does Chip treat this differently? I had assumed it would give a syntax error in PNut and so it's safe to have this as a fastspin extension.
Is there a command line option to force either Spin1 or Spin2 support regardless of the file extension? I don't need this but it occurs to me that some might just want to call their files "*.spin" but still process them as Spin2 files.
No. It's like .c vs .cpp; if you want C++, you have to give a C++ extension to the file name. The reason is that multiple files may be given both on the command line and in OBJ declarations, and having a global mode that affects all of them is probably not going to work very often.
That makes sense. Having an option to force language selection probably wouldn't be that useful anyway and might be confusing.
Note too that "Spin2 mode" means "Spin2 language" mode, and is independent of whether the processor is P1 or P2.
Yes, I'm well aware of that. That is one of the big advantages of fastspin. You can use the new syntax even when targeting the P1 or you can compile Spin-only P1 Spin code for the P2. Very nice!
Is there a command line option to force either Spin1 or Spin2 support regardless of the file extension? I don't need this but it occurs to me that some might just want to call their files "*.spin" but still process them as Spin2 files.
No. It's like .c vs .cpp; if you want C++, you have to give a C++ extension to the file name. The reason is that multiple files may be given both on the command line and in OBJ declarations, and having a global mode that affects all of them is probably not going to work very often.
Note too that "Spin2 mode" means "Spin2 language" mode, and is independent of whether the processor is P1 or P2.
Like I said, in all cases "a => b" is treated as "a greater than or equal to b". Does Chip treat this differently? I had assumed it would give a syntax error in PNut and so it's safe to have this as a fastspin extension.
pnut errors on => and =< unless there is a legit case.
What you’ve done makes sense. I used to call my P2 programs .spin so that I could edit with PropTool P1 and get the highlighting.
Now I’ve moved on all P2 is .spin2 and I edit with VSCode which highlights the operators and indentation nicely. I now find it preferable to editing in PropTool for both P1 and P2. VSCode is open source and cross platform and I have .spin and .spin2 highlighting. Works nicely in dark mode (black background). It’s now my go to editor that I use every day in my python programming for work.
Comments
It seems that Fastspin does not support Spin2's ONES operator.
This may not be used often, but it's handy to calculate a parity bit.
Andy
Thanks Andy, I overlooked that one.
You mean PNut, I presume. The Spin2 language has two different implementations, PNut (Chip's compiler) and fastspin (my compiler). fastspin compiles everything into native P2 machine code.
Yes, I've alredy noticed. Inline assembly is passed as plain text to the p2asm file. Top level pasm is parsed and output as hex codes. I wonder why the conditions are restricted in inline assembly. If it is passed through to the p2asm file the compiler doesn't need to interpret it. If it was the other way round (translation to hex codes necessary) I'd understand it.
So the restrictions are there because the missing condition prefixes are simply not implemented? Or is there a more complicated reason like the optimizations wouldn't work?
BYTEMOVE() (and I guess also word-and longmove) works a bit different on PNUT and Fastspin.
Spin1 and Spin2 copy the bytes either upwards or downwards, depending on the source and destination addresses, fastspin does it always upwards.
This matters if you use bytemove() i.e. for string manipulation: Output:
] Andy
It's done for an aggressive trade off between size and speed. Small size, with hardware assist to perform much better than an intrepeter would otherwise, and where one needs speed, or can use concurrency, there is inline assembly and or the COGS.
We are going to be spoiled in a way. Anyone wanting a compile to machine code can get it as well as the spiffy byte code scenario.
I'm interested mainly in concatenating binary constants, which would make complex skip patterns easier. A simple example: Note that string1 and string2 are created by an automatic skip pattern generator program and are in an include file. Concatenator would have to remove any % (or $) after first char or replace with underscore.
EDIT:
This is for pure PASM2, not any variant of Spin.
An alternative is to or/add string1 with string2 shifted left by bit width of string1 (which could contain underscores).
Values and widths of strings are not known to the programmer because that is the whole point of using an automatic skip pattern generator.
I've done that with constant integers rather than strings. eg:
Then in the code section I can do this:
No, and that syntax would be ambiguous I'm afraid. It might be possible to modify the preprocessor to do a sort of string concatenation similar to the C ## preprocessor directive. I'm not sure how broadly useful it would be, though.
If bwidth were a bit width function, then the code could look like:
bvalue1 could be skip bit pattern that selects source & destination data, while bvalue2 performs an operation on the data. This could be much simpler than combining both data selection and operation in a single pattern.
It might be better to say "bit length" instead of "bit width". The number of actual 0s and 1s in bvalue1 is the critical thing, not the number of bits needed to store that value. Leading 0s must not be removed.
PS; I've not even tried to get my head around what skipping does let alone figuring having a need for it. I suspect I'm not the only one.
More info here:
https://forums.parallax.com/discussion/comment/1496768/#Comment_1496768
Just discovered COGCHK is missing.
Not a problem tho'.
When I invented the unsigned comparison operators it was in the context of Spin1, so unsigned greater than or equal to is written "+=<". When Chip took them over into Spin2 he changed it to "+<=". I didn't realize that, I'll add an alias for them in Spin2. Meanwhile you can write code that works in both compilers by using the fact that "a +<= b" is equivalent to "NOT (b +> a)".
Huh, I thought that was in there. Thanks, I'll add it.
In Spin1 mode (the filename ends in ".spin") a >= b is treated as it is in Spin1, namely assignment a := a > b. In Spin2 mode (the filename ends in ".spin2") it is treated as "a greater than or equal to b".
In all cases a => b is treated as "a greater than or equal to b".
No. It's like .c vs .cpp; if you want C++, you have to give a C++ extension to the file name. The reason is that multiple files may be given both on the command line and in OBJ declarations, and having a global mode that affects all of them is probably not going to work very often.
Note too that "Spin2 mode" means "Spin2 language" mode, and is independent of whether the processor is P1 or P2.
Like I said, in all cases "a => b" is treated as "a greater than or equal to b". Does Chip treat this differently? I had assumed it would give a syntax error in PNut and so it's safe to have this as a fastspin extension.
What you’ve done makes sense. I used to call my P2 programs .spin so that I could edit with PropTool P1 and get the highlighting.
Now I’ve moved on all P2 is .spin2 and I edit with VSCode which highlights the operators and indentation nicely. I now find it preferable to editing in PropTool for both P1 and P2. VSCode is open source and cross platform and I have .spin and .spin2 highlighting. Works nicely in dark mode (black background). It’s now my go to editor that I use every day in my python programming for work.