Instruction Op Codes: Q's to Chip & others
Cluso99
Posts: 18,069
I have been going over the Op Code summary and I have a few thoughts and questions, in case another tweek of the P2 occurs before the February shuttle run...
JMPRET & JMPRETD
1. Could instruction codes for JMPRET & JMPRETD be swaped? Reason: Maintain P1 opcode compatibility where possible. Alternately, they could share the same "010111" opcode utilising the carry bit C=1=JMPRETD, freeing up an op code inthe process (see 6. below)
CMPSUB & SUBR
2. Could instruction codes for CMPSUB & SUBR be swapped? Reason: Maintain P1 opcode compatibility for CMPSUB (although R=0 is now used for additional instructions). Alternately, they could share the same op code "111000" utilising R=1=CMPSUB and R=0=SUBR. (also see below).
CMPSUB, SUBR, INCMOD, DECMOD & SETINDx, FIXINDx, CFGPINS, WAITVID
3. SETINDx, FIXINDx, CFGPINS & WAITVID could possibly all be combined into a 1/2 instruction with R=0 or 1 instruction with R=0/1, and utilising Z & C bits to decode. Reason: This would permit CMPSUB, SUBR, INCMOD & DECMOD to utilise the NR bits (as for most instructions). (see below to find a new op code)
Other possibilities could be...
3A. CMPSUB & SUBR could share the opcode "111000" with R=1 for CMPSUB and R=0 for SUBR (i.e. NR not possible with these instructions)
3B. INCMOD & DECMOD could share the opcode "111001" with R=1 for INCMOD and R=0 for DECMOD (i.e. NR not possible with these instructions)
IJZ, IJZD, IJNZ, IJNZD & DJZ, DJZD, DJNZ, DJNZD
4. These instructions all have the NR option but no WZ or WZ option. Would WZ be more useful than NR for these instructions ??? (It's a question because I am not sure - perhaps both would be nice and therefore utilise extra op codes that could be freed up below)
JP, JPD, JNP, JND
5. If these were able to have a separate op code, then could R be repurposed to provide a [#]D option too (as in the #n option used in op code "000011" instructions)? Would this therefore be possible... JP #D,#S ???
Possible instruction combinations to free up some op codes...
JMPRET, JMPRETD
6. (See 1. above.) Share op code "010111" utilising C=1=JMPRETD (Note: The D versions of IJxx, DJxx, TJxx & JxPx already utlise the C bit for the Delayed versions of these instructions - this change would provide consistency).
MOVS, MOVD, MOVI
7. In P1 these instructions have C undefined. "C" could therefore be used to combine two of these instructions into 1 opcode. I cannot really see much for the "R" bit so it could be repurposed as another decode bit, permitting all 3 instructions to share the one op code and leaves the possibility of a later instruction such as perhaps MOVC (moves the 4 CCCC bits) or MOVO (moves 14 bits b31:b18) or similar.
CMPS, CMPSX
8. In P1 the "R" bit is always =0. Therefore "R" could be utilised permitting these instructions to share an op code.
ENC
9. This instruction may be able to share another op code as Z/C/R are possibly useless. Perhaps CFGPINS or WAITVID ???
I think that almost all of these are simple verilog changes. Of course I could be completely wrong.
Possible new instruction...
10. Previously I asked if it would be possible to add an instruction to shift right 9 places from b26, leaving b31-b27 untouched, and b26-b18 set to 0. I use this in fast vector decoding (in my faster spin interpreter, and heater uses it in ZiCog) by having 3 cog instruction vectors and 5 top bits for various flags. It would be useful to also have the Z flag set according to the result of the bits b26-b0. Could this instuction be a subset of SHR where S or #S =%xxx100000. Currently, only the last 5 bits are tested and would/should? result in no shifting. By utilising a setting of >>32 an extra special instruction could be added. This is what I am trying to replace in P1 instructions...
MOV t1,Vector 'make copy
AND Vector,hF8000000 'extract top 5 bits for later
SHR t1,#9
AND t1,h3FFFF WZ 'leaves D & S bits, sets Z flag
OR Vector,t1 'add back in D & S bits
JMPRET & JMPRETD
1. Could instruction codes for JMPRET & JMPRETD be swaped? Reason: Maintain P1 opcode compatibility where possible. Alternately, they could share the same "010111" opcode utilising the carry bit C=1=JMPRETD, freeing up an op code inthe process (see 6. below)
CMPSUB & SUBR
2. Could instruction codes for CMPSUB & SUBR be swapped? Reason: Maintain P1 opcode compatibility for CMPSUB (although R=0 is now used for additional instructions). Alternately, they could share the same op code "111000" utilising R=1=CMPSUB and R=0=SUBR. (also see below).
CMPSUB, SUBR, INCMOD, DECMOD & SETINDx, FIXINDx, CFGPINS, WAITVID
3. SETINDx, FIXINDx, CFGPINS & WAITVID could possibly all be combined into a 1/2 instruction with R=0 or 1 instruction with R=0/1, and utilising Z & C bits to decode. Reason: This would permit CMPSUB, SUBR, INCMOD & DECMOD to utilise the NR bits (as for most instructions). (see below to find a new op code)
Other possibilities could be...
3A. CMPSUB & SUBR could share the opcode "111000" with R=1 for CMPSUB and R=0 for SUBR (i.e. NR not possible with these instructions)
3B. INCMOD & DECMOD could share the opcode "111001" with R=1 for INCMOD and R=0 for DECMOD (i.e. NR not possible with these instructions)
IJZ, IJZD, IJNZ, IJNZD & DJZ, DJZD, DJNZ, DJNZD
4. These instructions all have the NR option but no WZ or WZ option. Would WZ be more useful than NR for these instructions ??? (It's a question because I am not sure - perhaps both would be nice and therefore utilise extra op codes that could be freed up below)
JP, JPD, JNP, JND
5. If these were able to have a separate op code, then could R be repurposed to provide a [#]D option too (as in the #n option used in op code "000011" instructions)? Would this therefore be possible... JP #D,#S ???
Possible instruction combinations to free up some op codes...
JMPRET, JMPRETD
6. (See 1. above.) Share op code "010111" utilising C=1=JMPRETD (Note: The D versions of IJxx, DJxx, TJxx & JxPx already utlise the C bit for the Delayed versions of these instructions - this change would provide consistency).
MOVS, MOVD, MOVI
7. In P1 these instructions have C undefined. "C" could therefore be used to combine two of these instructions into 1 opcode. I cannot really see much for the "R" bit so it could be repurposed as another decode bit, permitting all 3 instructions to share the one op code and leaves the possibility of a later instruction such as perhaps MOVC (moves the 4 CCCC bits) or MOVO (moves 14 bits b31:b18) or similar.
CMPS, CMPSX
8. In P1 the "R" bit is always =0. Therefore "R" could be utilised permitting these instructions to share an op code.
ENC
9. This instruction may be able to share another op code as Z/C/R are possibly useless. Perhaps CFGPINS or WAITVID ???
I think that almost all of these are simple verilog changes. Of course I could be completely wrong.
Possible new instruction...
10. Previously I asked if it would be possible to add an instruction to shift right 9 places from b26, leaving b31-b27 untouched, and b26-b18 set to 0. I use this in fast vector decoding (in my faster spin interpreter, and heater uses it in ZiCog) by having 3 cog instruction vectors and 5 top bits for various flags. It would be useful to also have the Z flag set according to the result of the bits b26-b0. Could this instuction be a subset of SHR where S or #S =%xxx100000. Currently, only the last 5 bits are tested and would/should? result in no shifting. By utilising a setting of >>32 an extra special instruction could be added. This is what I am trying to replace in P1 instructions...
MOV t1,Vector 'make copy
AND Vector,hF8000000 'extract top 5 bits for later
SHR t1,#9
AND t1,h3FFFF WZ 'leaves D & S bits, sets Z flag
OR Vector,t1 'add back in D & S bits
Comments
You get an implied zero or non-zero from those instructions in the fact that they take the jump or not. You could code something to "read/store" that if really needed. You get actual functionality from the NR option (that I wouldn't want to lose). I think they should stay as they are.
Also, in general, I don't think it's all that valuable to remain binary opcode compatible with the P1. I think the PASM source instructions should be compatible as much as is reasonable, but at the bit level, I dunno. The shear number of new instructions and the number that are "overlapping" each other in the binary space is making the assembler (DAT section compiler in spin.exe) slightly more complex, but it's not that bad. Make a few cases be more P1 binary compatible isn't going to do much of real use... or am i missing something?
Roy
-Phil
1. All instructions from "001000" ROR to "110111" SUBSX (with/without a few exceptions) are the same as P1 other than they now execute in 1 clock instead of 4.
By swapping JMPRET & JMPRETD and CMPSUB & SUBR this becomes "001000" ROR to "111000" CMPSUB with the only current exception being CMPSUB which no longer has a usable NR bit. This is the majority of P1 instructions
The only P1 instructions then not the same would be DJNZ, TJNZ, TJZ, the RDxxxx/WRxxxx instructions, the hub instructions HUBOP, CLKSET, COGxxxx, LOCKxxxx, and the WAITxxx instructions.
DJNZ, TJNZ, TJZ:
TJNZ & TJZ previously had separate op codes on P1. They now share a new op code where WZ, WC and NR are re-purposed. WZ is used to share the op codes. WC is used to add the "delayed" versions. R is used to share the new JPx/JNPx instructions, since R=0 was implied in TJNZ/TJZ.
DJNZ now uses a new op code with WZ and WC re-purposed. WZ adds DJZ instructions and WC adds "delayed versions" to this opcode (DJNZx/DJZx)
IJZx/IJNZx has been added using a new op code (operates similar to the new DJZx/DJNZx)
RDxxxx/WRxxxx are basically the same with the addition that in RDxxxx, WC is used for the cached reads.
HUBOPs are changed considerably and were not used regularly anyway.
2. We use self-modifying code. At least if the majority of P1 instructions remain the same op codes, there will be little in the way of masks to change.
This is definately not a show-stopper, but if it is simple enough, then it is preferable.
Roy: re the WZ bit in the IJxxx/DJxxx/TJxxx scenarios. I often enter a routine with the C or Z or both indicating from where it came. I thought this could perhaps be more useful than the NR bit. I cannot see a valid use of the C bit here. Of course, my preference is to have both WZ & NR, but isn't that always the case
Phil: The compiler should restrict the use of the re-purposed flags. I agree the WC was not a good choice for the INA/INB and WAITPXX instructions. FOrtunately for us we never had to deal with this since the P1B never eventuated. However, the re-purposing of the ZCRI bits in insructions that do not require them seems an excellent way to extend the instruction set. This will all be hidden by the compiler, just like TEST was hidden from the AND instruction effectively using NR.
potatohead: No binary is going to run without recompiling at least. But the less changes the better. I think it is more a matter of making out the case that the P2 is a souped up extended version of P1. I think this makes it simpler for us P1 people to shift easily to P2.
-Phil
Binary compatibility really only matters when people are dealing with a lot of object code with the intent of running it directly, or with a very minimal modification. That's just not typical in the Propeller world. Self modify code is largely used for indexing / indirection, both of which are now hardware supported with additional instructions and registers for those purposes. That leaves the odd case of a self-modifying program that writes instructions for some purposes. I'm not sure we have cases worth such a change and where that might be true, it's only of limited value given code targeted to both CPU's remains confined to the subset of binary compatible instructions. Just don't see that as being a significant use case.
"the less changes the better"
Why? If we aren't really considering executable code, assembly language compatability and above is all that really matters. Where it's really at issue, some software can very easily assist with that, presenting things in ways that people understand easily. We do very little at the machine code level, mostly assembly and above and that's not really going to change, but for some niche cases patching things with the monitor, etc... and there isn't similar functionality on P1 and the resources required for one make it an educational thing at best.
Adding an instruction to address a clear and high value use case makes sense to me, but only when it's very significant, and we've not demonstrated that there aren't better means / methods open to us. By all means, make your case for either. I just can't support the instruction shuffling on the basis of binary compatibility because I don't see where it's high enough value to warrant the cost / risk of doing so.
I second Phil's comment about conditionals carrying through a few instructions.
Finally, the more I work with the P2 emulation, the more I realize they are very different chips that share the same design ideology. The P2 isn't really an increment of the P1, like where we see binary compatabity pay off, it's changed enough to warrant it's own arrangement of instructions.
These instructions can still execute conditionally based on the CCCC condition. They just cannot set the Z or C flags.
In other cases, the cccc bits are re-purposed. All this means is that these instructions do not have conditional execution capability - they will always execute. e.g. SETINDx
Perhaps this helps.
-Phil
These are the same P1 instructions, with exceptions noted...
WRxxxx/RDxxxx (WC repurposed)
ROR "001000" to SUBSX "110111" by combining JMPRET/JMPRETD into "010111" by repurposing WC. (also frees up "000111")
CMPSUB "111000" by moving CMPSUB/FIXINDx (NR repurposed)
DJNZ, TJNZ & TJZ "111001", "111010" & "111011" by reorganising IJxxx, DJxxx, TJxxx & JxPx plus "111100" (WC repurposed for "Delayed" variants)
The instructions...
HUBOPS (CLKSET, COGxxxx, LOCKxxxx) would be incompatible.
WAITxxxx would be incompatible.
So, providing the HUBOPS and WAITxxxx instructions were not used, or specifically catered for, the same PASM binary should run on both the P1 and P2. The caveat here is that self-modifying code require an extra instruction inserted for the P2, so this would be needed to be inserted in P1 binaries too.
Don^t forget that all instructions that use INDA or INDB in the destination or source field can no longer be conditional. The conition bits are used to specify the addressing mode for the indirect access in this case.
Andy
As long as the basic ideas are the same. : ]
I'm sure there is some underpinning logic as to why the instruction set is laid out the way it is on the PropII.
- anything less, and you are only merely discussing degrees of binary incompatibility.
Do you have an example ? In most cases I have seen, Self modifying uses a seed opcode and then replaces the Address fields.
The biggest gotcha would be the requirement that any self modifying code now needs 2 instructions between the change and execution (up from 1). Things like mov *,#0 wz,nr to clear the z flag and similar will still work because those instruction opcodes have thankfully not changed.
I have thought about (but cannot recall seeing) the changing of JMPRET from jmp to call and back again. Certainly I have seen the RET instruction modified, but again think there would be no compatibility problems.