@ersmith: the latest 5.1.1-beta release is some good stuff. The only thing I can find to report on the FlexBASIC side of the house is that the STRING$() command is missing from the docs.
I've published the final 5.1.1 release of the compiler on github. Because the new bytecode back end by @Wuerfel_21 is so interesting (even though it's unfinished) I've put up a binary release of spin2cpp and flexptools, for those who are interested in playing with the bytecode. This code is in FlexProp too, of course, but it's not exposed in the GUI yet since it's still unfinished. The full FlexProp binary release will be on github soon (it's on Patreon now if you're impatient ).
As an example of the size reduction possible, this little BASIC program:
var hello$ = "hello there: "
print hello$
for i = asc("A") to asc("Z")
hello$ = hello$ + chr$(i)
print hello$
next i
is exactly 10000 bytes when compiled with flexspin's default command line for the P1 (it pulls in a lot of libraries). It's only 2228 bytes when compiled with flexspin --interp=rom to produce P1 bytecode.
@evanh said:
Anyone want to venture to giving a name to the prop1's bytecode? That'll help with clarifying its status as not-an-interpreter.
Actually it is interpreted -- it's using the ROM bytecode interpreter. I don't know what the official language of that bytecode is. Maybe PNut bytecode? But the P1 version, not the P2 one (not yet, anyway).
@evanh said:
Anyone want to venture to giving a name to the prop1's bytecode? That'll help with clarifying its status as not-an-interpreter.
Actually it is interpreted -- it's using the ROM bytecode interpreter. I don't know what the official language of that bytecode is. Maybe PNut bytecode? But the P1 version, not the P2 one (not yet, anyway).
Maybe it should be called 'Prop1 ROM bytecode' then ?
@evanh said:
For me, interpreted means direct tokenised language statements. Bytecode is an intermediate, an emulation.
That's mainly semantics. Interpreted is non-native-binary-opcodes tokens, that need to pass thru the ROM Interpreter (which runs using use native-binary-opcodes)
So you get your smaller-but-slower trade off.
P1VM or PVM-some-version-and-chip-suffix?
...well... (V)irtual yes, but there is no simulated (M)achine. All its hardware really is Propeller stuff. But maybe VM is near enough and probably widely understood even by readers coming from outside the PropellerVerse.
P1BC?
ByteCode versus LMM would hint to the code density differences, but while being more exact, it wouldn't be understandable without a lot of additional information.
P1Thumb?
With increasing ARM presence in our daily lives, "thumb" for a compressed code subset gets more common, but in the ARMverse this would not be interpreted. This may hint to the right ideas in case of code density but doesn't hint at being interpreted.
So far, I'd prefer P1VM, P2VM, P#VM plus some suffix for modified interpreters and so on. PVM plus suffix hinting to the Propeller chip variant and interpreter flavour might be nice too and the other PVM (Parallel Virtual Machine), some already might know, is far away from the microcontroller universe not to cause confusion with this one. In the end, PVM like JVM might not be sooooo strange at all.
Whatever might get selected, I hope it will not be a funny PropellerVerse insider term which needs a long story to really get understood by the average reader.
It's always been called "the Spin Interpreter". The P1 manual calls it that, too.
Using "Interpreter" to mean instruction-by-instruction execution of non-native programs is very common. Many emulation programs offer a dichotomy of "Recompiler" vs "Interpreter" for their CPU emulation. (Pictured: Dolphin emulator)
I discovered what I believe is a bug in flexspin 5.4.0
I'm using Wuerfel_21's FAT32 driver she uploaded here in the forum a while ago. I attached it in a mildly patched version.
In it you will find a comment ERROR: This needs to be commented in which marks the problem. It is in the listSize-method of the object. Without the debug("result < 0:", posx) line in the code the result of the method is reliably $7fffffff, not the actual file-size.
The debug line is not even hit, but it must be there.
@ersmith said:
Have you tried flexspin 5.5.1? It has quite a few bug fixes over 5.4.0, some of them contributed by @Wuerfel_21 herself.
I upgraded to Version 5.5.1-HEAD-v5.5.1 Compiled on: Jun 26 2021 and that did not change the behavior.
I looked a bit deeper and found that the problem is not to do with debug or not, it just needs to be any code at all.
PUB listSize() : result | h
bytemove(@result, @directoryEntryCache[28], 4)
if(result < 0)
' ERROR: This needs to be commented in
' to produces the actual file size?
'debug("result < 0:", posx)
h := 2
h *= 10
result := posx
The h-based computation is obviously nonsense, but needed to produce the actual result.
I found that using -l I can look at the generated assembly. Now my P2 ASM fu is weak and I'm for the first time looking into the output generated by flexspin, but this is how it looks:
In the first, after doing the memmove, we see a comparison (as it would be expected given the if(result < 0), but that's missing from the non-working second one.
@deets said:
In the first, after doing the memmove, we see a comparison (as it would be expected given the if(result < 0), but that's missing from the non-working second one.
If there's nothing done in the "if" statement then the comparison is optimized away. So on its own that isn't surprising. But thanks for the small example, I think I can reproduce your original problem now (the original code you posted was interesting, but wasn't stand-alone and I couldn't build it). The root cause is that the bytemove at the beginning of the function is confusing something in the optimizer. In the meantime, @Wuerfel_21's revised code is more efficient and avoids the bug, so for now I'd go with that.
I'm trying out some C coding and bumped into first hurdle already. I'm wanting to busy wait on the carry flag returned from RDPIN data,pin WC. Not seeing any way for _rdpin() to do this ... so looked at inline assembly but even that has me worried as modifying condition codes inline could make bugs. So, now I'm looking for how to do this correctly. Maybe build function from assembly? I don't see much documentation in this area. Suggestions welcomed.
Thanks. Now ... how to do labels and looping inline? The compiler complains about the colon in the label.
EDIT: Ah, maybe use __pasm instead of __asm ...
EDIT2: Hmm, stuck on that too. It needs to be defined like a function, not inline. Not finding how to do that either.
Comments
@ersmith: the latest 5.1.1-beta release is some good stuff. The only thing I can find to report on the FlexBASIC side of the house is that the STRING$() command is missing from the docs.
I've published the final 5.1.1 release of the compiler on github. Because the new bytecode back end by @Wuerfel_21 is so interesting (even though it's unfinished) I've put up a binary release of spin2cpp and flexptools, for those who are interested in playing with the bytecode. This code is in FlexProp too, of course, but it's not exposed in the GUI yet since it's still unfinished. The full FlexProp binary release will be on github soon (it's on Patreon now if you're impatient ).
As an example of the size reduction possible, this little BASIC program:
is exactly 10000 bytes when compiled with flexspin's default command line for the P1 (it pulls in a lot of libraries). It's only 2228 bytes when compiled with
flexspin --interp=rom
to produce P1 bytecode.Anyone want to venture to giving a name to the prop1's bytecode? That'll help with clarifying its status as not-an-interpreter.
EDIT: PS: I suppose just calling it "Prop1 Bytecode" would do. :shrug:
Actually it is interpreted -- it's using the ROM bytecode interpreter. I don't know what the official language of that bytecode is. Maybe PNut bytecode? But the P1 version, not the P2 one (not yet, anyway).
For me, interpreted means direct tokenised language statements. Bytecode is an intermediate, an emulation.
Maybe it should be called 'Prop1 ROM bytecode' then ?
That's mainly semantics. Interpreted is non-native-binary-opcodes tokens, that need to pass thru the ROM Interpreter (which runs using use native-binary-opcodes)
So you get your smaller-but-slower trade off.
P1VM or PVM-some-version-and-chip-suffix?
...well... (V)irtual yes, but there is no simulated (M)achine. All its hardware really is Propeller stuff. But maybe VM is near enough and probably widely understood even by readers coming from outside the PropellerVerse.
P1BC?
ByteCode versus LMM would hint to the code density differences, but while being more exact, it wouldn't be understandable without a lot of additional information.
P1Thumb?
With increasing ARM presence in our daily lives, "thumb" for a compressed code subset gets more common, but in the ARMverse this would not be interpreted. This may hint to the right ideas in case of code density but doesn't hint at being interpreted.
So far, I'd prefer P1VM, P2VM, P#VM plus some suffix for modified interpreters and so on. PVM plus suffix hinting to the Propeller chip variant and interpreter flavour might be nice too and the other PVM (Parallel Virtual Machine), some already might know, is far away from the microcontroller universe not to cause confusion with this one. In the end, PVM like JVM might not be sooooo strange at all.
Whatever might get selected, I hope it will not be a funny PropellerVerse insider term which needs a long story to really get understood by the average reader.
Okay, I already regret asking the question.
Okay, I already regret reading your comment. :-P
It's always been called "the Spin Interpreter". The P1 manual calls it that, too.
Using "Interpreter" to mean instruction-by-instruction execution of non-native programs is very common. Many emulation programs offer a dichotomy of "Recompiler" vs "Interpreter" for their CPU emulation. (Pictured: Dolphin emulator)
Did that ever make sense?
That reads as if the bytecode were named "Spin"!
Java bytecode is called just that, I don't see a problem
The bytecode mnemonics and the assembler that I wrote for spinix were called Spasm, which is a shortened form of "Spin Assembly".
I discovered what I believe is a bug in flexspin 5.4.0
I'm using Wuerfel_21's FAT32 driver she uploaded here in the forum a while ago. I attached it in a mildly patched version.
In it you will find a comment
ERROR: This needs to be commented in
which marks the problem. It is in the listSize-method of the object. Without thedebug("result < 0:", posx)
line in the code the result of the method is reliably $7fffffff, not the actual file-size.The debug line is not even hit, but it must be there.
I've had that sort of behaviour in my assembly when missing a # in front of a label reference.
I don't see the attachment.
Have you tried flexspin 5.5.1? It has quite a few bug fixes over 5.4.0, some of them contributed by @Wuerfel_21 herself.
Sorry, whatever went wrong there. I attached it now.
Not yet, will give that a spin (pun intended) and report back if it's gone.
I upgraded to
Version 5.5.1-HEAD-v5.5.1 Compiled on: Jun 26 2021
and that did not change the behavior.I looked a bit deeper and found that the problem is not to do with debug or not, it just needs to be any code at all.
The h-based computation is obviously nonsense, but needed to produce the actual result.
Is there a way to look at the generated code?
Yes, just check the .pasm file that is generated.
Unrelatedly, try replacing that method with this significantly less stupidly written version
I found that using
-l
I can look at the generated assembly. Now my P2 ASM fu is weak and I'm for the first time looking into the output generated by flexspin, but this is how it looks:In the first, after doing the memmove, we see a comparison (as it would be expected given the
if(result < 0)
, but that's missing from the non-working second one.@Wuerfel_21
Saw your post after my last. Yes, your variant works. And the resulting code looks better (I presume _var02 is posx in the originial source)
No,
_var02
is the data read fromdirectoryEntryCache
, the posx is generated by thebmask result1, #30
If there's nothing done in the "if" statement then the comparison is optimized away. So on its own that isn't surprising. But thanks for the small example, I think I can reproduce your original problem now (the original code you posted was interesting, but wasn't stand-alone and I couldn't build it). The root cause is that the bytemove at the beginning of the function is confusing something in the optimizer. In the meantime, @Wuerfel_21's revised code is more efficient and avoids the bug, so for now I'd go with that.
Thanks,
I'm trying out some C coding and bumped into first hurdle already. I'm wanting to busy wait on the carry flag returned from RDPIN data,pin WC. Not seeing any way for _rdpin() to do this ... so looked at inline assembly but even that has me worried as modifying condition codes inline could make bugs. So, now I'm looking for how to do this correctly. Maybe build function from assembly? I don't see much documentation in this area. Suggestions welcomed.
Conditions in inline ASM are totally fine.
Thanks. Now ... how to do labels and looping inline? The compiler complains about the colon in the label.
EDIT: Ah, maybe use __pasm instead of __asm ...
EDIT2: Hmm, stuck on that too. It needs to be defined like a function, not inline. Not finding how to do that either.
on P2 the label needs to have a dot, not a colon
Grr, tried but failed to avoid looping in the assembly:
Gets
error: Variable x must be placed in memory (probably due to an @ expression) and hence cannot be accessed in inline assembly
Doh! Arr! I had a suffixed colon. That's not even part of Pasm. I'm losing it.