Porting the Oberon Compiler (ORP) to the P2
in Propeller 2
I decided to start a new topic now that there is a starting point.
The code can be found here: https://github.com/raps500/Propberon. I decided to call it Propberon
, instead of AleOberon
.
For the time being produces RISC5 code but that will change soon.
It would be great if I could modularize the code generation
, then I don't have to drop support for RISC5 during development
.
The disassembler ignores a couple of flags for MOV, needs fixing.
The code can be found here: https://github.com/raps500/Propberon. I decided to call it Propberon
For the time being produces RISC5 code but that will change soon.
It would be great if I could modularize the code generation
The disassembler ignores a couple of flags for MOV, needs fixing.

Comments
Would a Searchable name make more sense ? - the 'opberon' there will not find on an Oberon Search, and it probably should be clear it is Prop2, not Prop ?
You may need to introduce segments, as VARs in COG will create much smaller and faster code than VAR in HUB.
ie This is very similar to DATA and XDATA on the 8051, with LUT being maybe similar to IDATA.
Then, some var overlay scheme with simple checking would help local vars in functions not waste COG memory. Because sometimes the tools cannot be certain one function does not call another indirectly, some means to disable this is needed for those rare cases.
Segments are accessed differently... lots of fun !
IMHO OberonAle would go down a lot better, and would be searchable ;-)
OberonP2
Looks like Oberon Ale is already a beer (which may indeed "go down a lot better")
http://mikesbrewreview.com/review-of-bells-oberon/
I think Propberon is fine, Ale, full steam ahead!...
I had presumed exactly that from the tone of Kwinn's post
Actually had no idea there was a brew by that name, just put Oberon and Ale together and thought it rolled off the tongue so well. Getting really hard to come up with a unique and memorable name for anything.
Of course I will have to see if I can find an Oberon Ale to sample now.
Hehe, and that winky, & 'go down a lot better', had me thinking you had one in your hand !
Wouldn't mind having one in hand to try but it's not available locally. Brewed in Kalamazoo Michigan which is a bit too far (624KM) to go for a beer, although I will keep it in mind if I am in the neighborhood.
If we're (I'm) going to ultimately run Project Oberon on the P2, I'D like to keep everything as similar as possible. (I did make some changes in ORG, numbers are kind of packed, I'm using full 32 bits for all numbers, except the separators and strings. I think, at a later stage, strings and separators should be modulo 4 aligned, too.
Register usage R0..R11 as R0..R11 (in COG RAM) PTRA as stack pointer PTRB as SB due to the lack of 16 bit range in indexed memory access, a combination of opcodes has to be implemented to achieve the same purpose: Proc Entry Code: 4EE9000C SUB SP, SP, C mov _SP, PTRA sub _SP, #12 ' or its augmented version if range too short This serves two purposes: if the arguments are outside the range of indexed mode the pseudo register _SP can be used instead Saving the link register is not needed because calla saves already the return address to the stack: Code: AFE00000 ST LNK, [SP + 0] Access to stack variable: Code: A0E00008 ST R0, [SP + 8] Code: 80E00004 LD R0, [SP + 4] The limited range of the index argument (31 for bytes or 124 for longs) means that the stack pointer has to be used indirectly, adding 2 or three extra opcodes per access: wrlong _R0,PTRA[2] ' 2 will be scaled because argument is long mov _TT, _SP add _TT, #508 rdlong _R0,_TT mov _TT, _SP augs #4096 ' really deep stack add _TT, #508 rdlong _R0,_TT Byte variables should be kept on lower addresses to use the shortest form. Opcode changes Some RISC5 opcodes can be directly be replaced by P2 opcodes but it has to be seen if the 3 register form is widely used or not, because the P2 only provides 2-operands opcodes: Code: 40080005 ADD R0, R0, 5 add _R0, #5 ' or ist augmented version if the operand is larger Exiting from a Procedure requires some house-keeping too: Code: 4EE8000C ADD SP, SP, C Code: C700000F BRA LNK add _SP, #12 mov PTRA, _SP add _SP, #4 ' re-adjust _SP to keep in sync with PTRA after reta reta And 2 RISC5 opcodes become 4 :(, if variables are used. Arguments are passed in registers for less stack usage, when they fit: Code: 40000006 MOV R0, R0, 6 Code: F7FFFFED BRAL FFFFED mov _R0, #6 ' or its augmented version calla _ProcGreat work on Oberon compiler for the Prop2. Have you managed to compile any code to the FPGA Verilog implementation you have, AProp?
As a solution I was thinking that a layer of abstraction could solve the problem:
ORP generates an instructions file, a target generator reads it and process it outputting the necessary P2 code with the adjusted offsets. The library files need also to be modified because the offsets written there are no longer valid (I have to look into this again, it's been a while...). A pretty mess
What do you think ?
Do you mean like an intermediate assembler file, that takes one RSIC5 opcode, and generates what could be multiple P2 opcodes, or in extreme cases a call to a Lib-stub, which starts to merge/morph into a RISC5 emulator ?
Oberon code is usually quite easy to read, another approach would be to try to modify the code generator to generate P2 code ?
A first step could be to recode using RISC 5 so you can still test it, but limit the R5 opcodes to 2 arguments ?
Code would get slightly larger, during this morph.
A P2/R5 switch could then output P2-ASM ?
Maybe that is the best approach, but I thought about something like: Do you mean like an intermediate assembler file but without the R5 opcodes only the "commands" with the offset adjustments, so everything can be re-calculated and re-targetted (I also wanted to target the RISC-V).
A direct ORP port is what I tried, that's why I was looking for an alternative. Maybe I have to look at the code generator again.
That could also work - I guess it depends on whether you prefer to work at MACRO-ASM or Code generator level, and which ASM levels tools you have too...
I did play with FASMG, which seems a very powerful, general assembler (no linker), but that's also another tool chain, and not likely to be P2 self-hosting.
I just tested that and yep it works as you say. I'd completely forgotten how the ALTx instructions work in detail. Here's my test code: (variables are in CogRAM) Terminal output is as follows:
I had to think about why "zero" had to be referenced like that and why the shorter ALTR D instruction wasn't used. I worked it out but wasn't happy I couldn't find a cheaper solution that didn't need an additional variable reference like that.
There's already a RISC-V emulator for both P1 and P2, so another solution would be just to output RISC-V binaries and then run those. The P2 version does a JIT compilation from RISC-V binaries to P2 binaries. Sources are found at
github.com/totalspectrum/riscvemu.git.
Eric
https://www.inf.ethz.ch/personal/wirth/FPGA-relatedWork/RISC-Arch.pdf
+