Assembler / Large Memory Models
![hippy](https://forums.parallax.com/uploads/userpics/339/nR1DFKQUWXIHE.jpg)
Am I correct that the following instruction codes are not used by the COG processors ... ?
If so, then for a Large Memory Model, where code pages to execute are loaded from Hub under COG control, if one were prepared to sacrifice loading speed for code density in the Hub, those instructions could be used as 'macro instructions', identified and expanded when they are loaded to be JMPRET calls to a micro-kernel already in the COG with the original macro instruction following them.
The micro-kernel when entered would have enough information to locate and act upon the macro instruction and continue real instruction execution when complete.
From an Assembler programmer's point of view ( with the right assembler tool ), they would have access to new instructions which would be emulated/interpreted when encountered within the executing COG.
I see little difference in end result whether something like FJMP ( to jump between COG code pages ) were expanded to multiple instructions in Hub by the assembler or a single macro instruction expanded to the same when loaded.
There are arguments for and against each mechanism. This is really a half-way house between pure native instruction execution and full COG interpretation of a virtual machine instruction set, a little further towards interpretation than previous Large Memory Model discussions seem to have been.
It is an idea which I can see being useful in what I am planning where fastest execution isn't the primary goal, so I thought I would share.
Added :
One way to keep loading as fast as possible for code pages, would be a marker, to indicate if any macro codes were used in that page, and then fix the code up post-loading. That would likely involve shuffling the code block loaded in memory to insert JMPRET's so could be time consuming.
Post Edited (hippy) : 8/13/2007 1:26:42 PM GMT
0001 00-- ---- ---- ---- ---- ---- ---- 0001 01-- ---- ---- ---- ---- ---- ---- 0001 10-- ---- ---- ---- ---- ---- ---- 0001 11-- ---- ---- ---- ---- ---- ----
If so, then for a Large Memory Model, where code pages to execute are loaded from Hub under COG control, if one were prepared to sacrifice loading speed for code density in the Hub, those instructions could be used as 'macro instructions', identified and expanded when they are loaded to be JMPRET calls to a micro-kernel already in the COG with the original macro instruction following them.
The micro-kernel when entered would have enough information to locate and act upon the macro instruction and continue real instruction execution when complete.
From an Assembler programmer's point of view ( with the right assembler tool ), they would have access to new instructions which would be emulated/interpreted when encountered within the executing COG.
I see little difference in end result whether something like FJMP ( to jump between COG code pages ) were expanded to multiple instructions in Hub by the assembler or a single macro instruction expanded to the same when loaded.
There are arguments for and against each mechanism. This is really a half-way house between pure native instruction execution and full COG interpretation of a virtual machine instruction set, a little further towards interpretation than previous Large Memory Model discussions seem to have been.
It is an idea which I can see being useful in what I am planning where fastest execution isn't the primary goal, so I thought I would share.
Added :
One way to keep loading as fast as possible for code pages, would be a marker, to indicate if any macro codes were used in that page, and then fix the code up post-loading. That would likely involve shuffling the code block loaded in memory to insert JMPRET's so could be time consuming.
Post Edited (hippy) : 8/13/2007 1:26:42 PM GMT
Comments
The main difficulty with your idea is that the addresses in all the instructions in the code page would need to reflect the addresses before "compression". The assembler would need to do the actual assembly, then compress each code page substituting special opcodes for those compressed. The LMM kernel would then uncompress the code pages as they're copied.
Hippy: There are other hidden possibilities: cmps and cmpsx only exist with the R effect off, so they do not write result. HUB instructions also exist with or without R effect but not both, djnz, tjnz and tjz also. I do not know what can happen if you _happen_ to use the "other" version
I face this problem with the bcd routines I´m writing. Not all of them fit in 2 kbytes, so I thought that special, not so often used can be loaded from HUB mem, and the basic ones are always present. sadly, a jump table and constants take quite a bit of space... :-(
Fall-back for Propeller Mk II is to other instructions which are not used or can be replaced with something equivalent freeing one instruction of the two up for macro use, or using IF_NEVER tagged instructions - potential problems there with self modifying code, but a trade-off which would likely be acceptable.
Even if there is only one instruction that can be used to indicate 'macro instruction coming' the concept will still work. It may mean macro instructions need more than one long, but providing that is less than the code otherwise needed it is still an overall saving.
I do not see a problem with an assembler keeping track of addresses as they would be after loading. The assembler would build a post-expanded image, then compact the code page image by removing the to-be-inserted-on-loading JMPRET's but leaving addresses and all else unaffected. The addresses within Hub would not reflect the address offsets from start of code page while in the Hub but would once expanded into COG memory.
Elsewhere, deSilva noted that "ADDC dst,#0" is the same as "IF_C ADD dst,#1" and I'm sure there are other combinations which can be found. An assembler could easily force one to be the other providing the ability to self-modify those particular instructions were excluded.
Adding a micro-kernel or macro instruction handling without reducing available COG space for other instruction use is always going to be a tricky balance.
@ MIke : Although the available opcodes of the Propeller get taken in Propeller MkII there's no reason not to switch the MkII opcodes to macro instructions in the assembler and emulate those in the COG to make things easier and consistent all round. That would work well providing the new opcodes are rarely used.
If multiple block transfers are to be added, I guess that also means new opcodes which do not yet exist ... until we have a finalised specification it is going to be hard to design a system guaranteed to work for MkI and MkII.
If my ideas only work for the MkI I am presently happy to go with that constraint. The key seems to be designing a framework which can work with any particular micro-kernel so that can be easily changed and re-assembly brings everything back into shape.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
With only 13 bits needed to access the entire 8K x 32-longs which could be held in Hub, and 9-bits for any COG address, that gives plenty left over for macro-opcode and expansion for a MkII.
However, as you will need a special assambler (or at least a post procesing), you can very easily detect such "unauthorized " use.
You are looking for an "escape" code - abstractly speaking. But is is rarely understood that you can use ANYTHING as escape code, as long as you have a provision to decode the excape code when used in its original meaning. The best known examples are the C back slash when doubled, or the " as used in CSV-files..