Chip, why don't you just use an 8 bit byte for the LRU.
When you load a cache line, shift the byte right, put the 2 bit line ID in the upper 2 bits. When you load the next line, you just pull the 2 bit ID off the bottom of the byte and use that to determine what the next cache line is.
Init LRU to 11100100 at startup
First load grabs 00, shifts right, pushes 00 to the top: 00111001
Next load, so on.
When the cogs start running instructions through the cache, the efficiency of the code will mix up the order, creating LRU instead of round-robin, but at start it will simply be round-robin.
Also, I don't see how all tasks could want data at once, since they are staggered through the 4 stages of the pipeline. Sure, it takes 3-8 clocks to load, but the tasks will stall anyway. So, yes you can have a pile-up, and RDLONG should have priority over HUBEX, which will cause further stalls.
This is all a better reason not to support HUBEX for more than task 0. You will have totally non-deterministic execution with 4 HUBEX tasks, because of issue order of the HUBEX loads and overriding priority for RDXXXX instructions. That means if the first instruction of a HUBEX is RDXXXX, it will stall the next HUBEX load, then if it's multiple RDXXXX instructions in a row, those other HUBEX tasks will stall indefinitely.
If you only make 1 task HUBEX and have a 4 line cache, that will give best possible performance.
pre-caching can make hub execution fast, but you must allow explicit memory ops to interrupt pending pre-cache requests.
Don't you also need to keep a 13 bit tag for each line to remember what hub address it corresponds to and compare each instruction fetch address with all four of those simultaneously to determine if you have a hit on an already loaded line? And then if you do have a hit you need to delete the 2 bit tag for that line from the byte and add it to the front of the list to maintain the LRU ordering.
Would it be too disruptive to get rid of the #address requirement for constant branches and then use @register to denote register?
These:
JMP #label
JMP register
Would become:
JMP label
JMP @register
What do you think?
It would get rid of a lot of #'s in source code and introduce an occasional @. This is more like what newcomers would expect, but it differs from Prop1.
Would it be too disruptive to get rid of the #address requirement for constant branches and then use @register to denote register?
These:
JMP #label
JMP register
Would become:
JMP label
JMP @register
What do you think?
It would get rid of a lot of #'s in source code and introduce an occasional @. This is more like what newcomers would expect, but it differs from Prop1.
Then how would relative branches be specified?
@n for absolute
@+n for jump relative positive offset
@-n for jump relative negative offset
would work.
Or do you mean get rid of absolute jmp's?
It's actually looking to me like absolute jumps are kind of worthless. You don't need them in the cog. And in the hub, is it realistic to know the absolute address of something that's not you? I think a register would better hold a value for such a purpose What do you think?
It's actually looking to me like absolute jumps are kind of worthless. You don't need them in the cog. And in the hub, is it realistic to know the absolute address of something that's not you? I think a register would better hold a value for such a purpose What do you think?
It's actually looking to me like absolute jumps are kind of worthless. You don't need them in the cog. And in the hub, is it realistic to know the absolute address of something that's not you? I think a register would better hold a value for such a purpose What do you think?
Most other CPUs out there use relative addressing, works great for short or intermediate length jumps/calls.
In a 32bit address space with a 32 bit instruction, you don't have many options, unless you want to give up 1/2 of the instruction set range to handle absolute jumps.
In the case where you need an absolute jump, the mechanism is to generate a 32 bit constant, load it into a register, then branch to the register.
Without absolute jumps, how will hubexec code call cog subroutines or jump to them?
You're right. Wait...
Any branch that ends in underscore is cog/hub-mode toggling. Those jumps cannot be relative, because there's no sensible relationship between cog and hub execution address. I could just have those encoded as absolutes in the assembler and have the cog hardware handle them as absolutes. That would let us consolidate with one constant address syntax, so we could get rid of #. What do you think?
Would it be too disruptive to get rid of the #address requirement for constant branches and then use @register to denote register?
These:
JMP #label
JMP register
Would become:
JMP label
JMP @register
What do you think?
It would get rid of a lot of #'s in source code and introduce an occasional @. This is more like what newcomers would expect, but it differs from Prop1.
I would much prefer the @ case because it basically means indirect.
However, compatibility is to some extent a problem. Maybe later the compilers could have a compatibility bit to switch back to the P1 style modes.
As for relative vs absolute, this is more of a compiler issue isn't it?
eg
JMP label
would be created as a relative or absolute immediate instruction by the compiler.
But,
JMP @register
would the contents of the register be absolute or relative???
Would it be too disruptive to get rid of the #address requirement for constant branches and then use @register to denote register?
These:
JMP #label
JMP register
Would become:
JMP label
JMP @register
What do you think?
It would get rid of a lot of #'s in source code and introduce an occasional @. This is more like what newcomers would expect, but it differs from Prop1.
If this was only for branches, it would be unnecessarily inconsistent. If it was for everything, add @a, @b would be a headache. I like the Prop 1 method way better, even though I forget #'s all the time. How about keep it the Prop 1 way but make a compiler warning if you say jmp label, where label is initially a command and not a res or long? Maybe whether or not the compiler should emit this warning could be user configurable.
Any branch that ends in underscore is cog/hub-mode toggling. Those jumps cannot be relative, because there's no sensible relationship between cog and hub execution address. I could just have those encoded as absolutes in the assembler and have the cog hardware handle them as absolutes. That would let us consolidate with one constant address syntax, so we could get rid of #. What do you think?
There are certainly a lot of JMP/CALL instructions.
I am not sure why toggling is required though???
IMHO there are 2 basic cases
JMP/CALL to Hub
JMP/CALL to Cog
These two cover the cases of:
Hub JMP/CALL to Hub
Hub JMP/CALL to Cog
Cog JMP/CALL to Hub
Cog JMP/CALL to Cog
The compiler will know whether it is in hub or cog mode, and whether the call will be to hub or cog.
So I cannot see why we need a toggle JMP/CALL.
Am I missing something here???
Next, there are D (delayed versions).
And lastly, we need to see which hub and cog modes require..
Immediate Absolute
Immediate Relative
Indirect Absolute (register)
Indirect Relative (register)
To me, it makes sense for the Indirect JMP/CALL to use "@register".
Many, including myself, often forget the "#" for the immediate absolute. I would rather ditch it or have an option to include/warn in the compiler - I usually check my code with bst as it gives a warning - there are only 4 cases in the whole ZiCog code that actually use a register.
I agree that jumps between modes have to be absolute, as relative addresses do not make sense there. So you can save some instruction encodings there.
I have niggling feeling that we would regred not having both absolute and relative within the same mode.
I think what would work best:
cog-cog absolute and relative addressing
hub-hub absolute and relative addressing
cog-hub absolute addressing only
hub-cog absolute addressing only
Agreed, I cannot see the use of relative addressing for cog-hub or hub-cog mode switching. If anything is relative, then the sw would have to add the base to it, because there is not reference for the hw at runtime. Relative is only consistent within cog-cog and hub-hub.
On the P1 we don't have relative for cog-cog, but it would be nice. At some time, it may make expanding cog beyond 512 longs possible (with some simple caveats). I would love to access AUX as extended Cog ram.
Relative makes a lot more sense with hub mode although Chip has found 16bits of (immediate) address for absolute/relative.
Relative facilitates relocatable code, beyond the base.
Relative addressing can be computed by the compiler. This makes the code relocatable. These relative addresses would be held within the JMP/CALL instructions (17 typo16 bits). I cannot see a need to have Relative addressing held in registers - can you???
But the original call to the module would need to be done by an Absolute JMP/CALL.
Most likely, the Absolute address would need to be held in a register because you don't want to plug absolute addresses into instructions within hub.
However, we will also require the JMP/CALL from hub to cog to contain the absolute cog address within the instruction, and also cog to hub.
So it makes sense for JMP/CALLs to Hub or Cog to have absolute addresses contained within the instruction, as well as in a register.
'JMP/CALL @register' would be absolute.
'JMP_/CALL_ @register' would be absolute.
'JMP/CALL label' would be relative
'JMP_/CALL_ label' would be absolute
So, all would be absolute except non-toggling constant branches. They would be relative.
cog-cog absolute and relative addressing - I think we need both. Relative for relocatable snippets, and absolute for calling subroutine libraries, or jumping to known fixed entry points
hub-hub absolute and relative addressing - I think we need both. Relative for relocatable snippets, and absolute for calling subroutine libraries, or jumping to known fixed entry points
cog-hub absolute addressing only, as relative does not make sense.
hub-cog absolute addressing only, as relative does not make sense
I like using @absoluteaddr convention for labels, and @$1234 works for fixed absolute numbers.
I am concerned with using 'jmp label' to indicate relative jumps, as that would normally indicate jump to content of register.
Perhaps
jmp/call @addr indicates a relative jmp/call to the label addr (valid for cog-cog, hub-hub)
jmp/call #addr indicates an absolute jmp/call (consistent with P1) (valid for cog-cog, hub-hub, cog-hub, hub-cog)
jmp/call reg indicates an indirect jmp/call to the contents of reg (valid for cog-cog, hub-hub, cog-hub, hub-cog)
The more I think of it, the more certain I become that we should keep absolute calls/jumps for all modes.
Relative addressing can be computed by the compiler. This makes the code relocatable. These relative addresses would be held within the JMP/CALL instructions (17 bits). I cannot see a need to have Relative addressing held in registers - can you???
Agreed, no need to have relative-indirect. Only 16 bits needed, as all hub instructions must be long aligned.
This would also allow storing CAR/CDR in one long for CONS and manipulating them easily with GETWORD and SETWORD
But the original call to the module would need to be done by an Absolute JMP/CALL.
Most likely, the Absolute address would need to be held in a register because you don't want to plug absolute addresses into instructions within hub.
However, we will also require the JMP/CALL from hub to cog to contain the absolute cog address within the instruction, and also cog to hub.
So it makes sense for JMP/CALLs to Hub or Cog to have absolute addresses contained within the instruction, as well as in a register.
Does this make sense???
See my previous post (right before this one) I think I have all the usage cases, please let me know if I missed something... or if something should be added.
There are certainly a lot of JMP/CALL instructions.
I am not sure why toggling is required though???
IMHO there are 2 basic cases
JMP/CALL to Hub
JMP/CALL to Cog
These two cover the cases of:
Hub JMP/CALL to Hub
Hub JMP/CALL to Cog
Cog JMP/CALL to Hub
Cog JMP/CALL to Cog
The compiler will know whether it is in hub or cog mode, and whether the call will be to hub or cog.
So I cannot see why we need a toggle JMP/CALL.
Am I missing something here???
Next, there are D (delayed versions).
And lastly, we need to see which hub and cog modes require..
Immediate Absolute
Immediate Relative
Indirect Absolute (register)
Indirect Relative (register)
To me, it makes sense for the Indirect JMP/CALL to use "@register".
Many, including myself, often forget the "#" for the immediate absolute. I would rather ditch it or have an option to include/warn in the compiler - I usually check my code with bst as it gives a warning - there are only 4 cases in the whole ZiCog code that actually use a register.
jmp/call @addr indicates a relative jmp/call to the label addr (valid for cog-cog, hub-hub)
jmp/call #addr indicates an absolute jmp/call (consistent with P1) (valid for cog-cog, hub-hub, cog-hub, hub-cog)
jmp/call reg indicates an indirect jmp/call to the contents of reg (valid for cog-cog, hub-hub, cog-hub, hub-cog)
This is exactly how it's set up at the moment.
I was thinking if we could come up with some set rules for constants in different circumstances, we could adopt very simple syntax.
By having toggling jumps and calls, you cut the number of instructions in half.
While in hub mode, you'll want to call to both hub and cog code. When in cog mode, you'll want to call both hub and cog code.
I still don't see why you couldn't have a separate hub and cog version of each jmp and call. It would be the same number of instructions as having a non-mode-changing instruction and a mode-changing-instruction.
Instead of:
JMP
JMP_
You have:
JMP
HJMP
Where JMP means "jump to a COG address" and HJMP means "jump to a hub address". Seems more intuitive to me.
I feel as soon as any of the current capability (except for inter-modal call/jmp) is removed, we would get bitten by the lack.
Having subroutines at fixed location is very useful for libraries, system calls etc.
Indirect jumps/calls are very useful for function pointers and jump tables.
Relative jumps/calls are very useful for relocatable code.
I think we are asking for trouble if we try to eliminate any of these (except when switching modes, relative inter-modal adresses do not make any sense)
'JMP/CALL @register' would be absolute.
'JMP_/CALL_ @register' would be absolute.
'JMP/CALL label' would be relative
'JMP_/CALL_ label' would be absolute
So, all would be absolute except non-toggling constant branches. They would be relative.
Chip,
I cannot see the requirement for the toggling mode, although the hardware needs to know where the instruction pc is going. But in sw, the user doesn't want to know about this.
dat
COGMODE
org0
doloop ...
...
CALLX subr' call cog routine
...
CALLY hubloop ' call hub routine
...
subr ...
RETX ' return to caller (cog or hub)
HUBMODE
orgh $4000
hubloop ...
...
CALLX subr' call cog routine
...
CALLY hubsub ' call hub routine
...
RETY ' return to caller (cog or hub)
hubsub ...
RETY ' return to caller (cog or hub)
In the above cases, the compiler would use the correct JMP/CALL instruction. But I don't see a toggle case, but rather the specific case of the compiler inserting either a hub or cog CALL.
It doesn't actually save anything, but from a user perspective it sounds simpler (to me anyway). So the CALL & CALL_ become a COG CALL and a HUB CALL instead of a same cog/hub CALL and a toggle cog/hub CALL. This way, the specific CALL (say CALL (for cog) & CALLH) reset/set the hubexec mode bit in the ALU.
I cannot see the requirement for the toggling mode, although the hardware needs to know where the instruction pc is going. But in sw, the user doesn't want to know about this.
dat
COGMODE
org0
doloop ...
...
CALLX subr' call cog routine
...
CALLY hubloop ' call hub routine
...
subr ...
RETX ' return to caller (cog or hub)
HUBMODE
orgh $4000
hubloop ...
...
CALLX subr' call cog routine
...
CALLY hubsub ' call hub routine
...
RETY ' return to caller (cog or hub)
hubsub ...
RETY ' return to caller (cog or hub)
In the above cases, the compiler would use the correct JMP/CALL instruction. But I don't see a toggle case, but rather the specific case of the compiler inserting either a hub or cog CALL.
It doesn't actually save anything, but from a user perspective it sounds simpler (to me anyway). So the CALL & CALL_ become a COG CALL and a HUB CALL instead of a same cog/hub CALL and a toggle cog/hub CALL. This way, the specific CALL (say CALL (for cog) & CALLH) reset/set the hubexec mode bit in the ALU.
Does this make sense???
I tried to suggest this a while back. I think you're saying to use that extra bit to select hub or COG addresses in the CALL and JMP instructions. The other option is what I mentioned in the post just before yours, that we just use two different opcodes. Both result in the same binary being generated where the bit that Chip is currently using to distinguish the XXX and XXX_ instructions gets used to select hub vs. COG. That seems a lot simpler to me than the toggle although there might be some hardware reason that Chip prefers the toggle.
cog-cog absolute and relative addressing - I think we need both. Relative for relocatable snippets, and absolute for calling subroutine libraries, or jumping to known fixed entry points
hub-hub absolute and relative addressing - I think we need both. Relative for relocatable snippets, and absolute for calling subroutine libraries, or jumping to known fixed entry points
cog-hub absolute addressing only, as relative does not make sense.
hub-cog absolute addressing only, as relative does not make sense
There are more cases to these... where the addresses are stored in registers or as an immediate value (in the 16 bits - was a typo before) I will put the cases in a table shortly.
COG-COG COG-HUB HUB-COG HUB-HUB
ABS #IMM @REG #IMM @REG #IMM @REG #IMM @REG
REL #IMM @REG ???? ???? ???? ???? #IMM @REGABScallCALL call_ CALL_ call_ CALL_ callCALL
REL call na call_ na call_ na call na
I like using @absoluteaddr convention for labels, and @$1234 works for fixed absolute numbers.
I am concerned with using 'jmp label' to indicate relative jumps, as that would normally indicate jump to content of register.
Perhaps
jmp/call @addr indicates a relative jmp/call to the label addr (valid for cog-cog, hub-hub)
jmp/call #addr indicates an absolute jmp/call (consistent with P1) (valid for cog-cog, hub-hub, cog-hub, hub-cog)
jmp/call reg indicates an indirect jmp/call to the contents of reg (valid for cog-cog, hub-hub, cog-hub, hub-cog)
I strongly disagree here...
@ should be used for indirection (ie the address is stored in a register - complication is, is it relative or absolute?)
# could be optional (for P1 compatibility) but would indicate the address is stored within the instruction (ie immediate - same complication, is it relative or absolute?)
Some other micros use BRA for relative jumps but this does not solve the CALL problem.
The more I think of it, the more certain I become that we should keep absolute calls/jumps for all modes.
I tried to suggest this a while back. I think you're saying to use that extra bit to select hub or COG addresses in the CALL and JMP instructions. The other option is what I mentioned in the post just before yours, that we just use two different opcodes. Both result in the same binary being generated where the bit that Chip is currently using to distinguish the XXX and XXX_ instructions gets used to select hub vs. COG. That seems a lot simpler to me than the toggle although there might be some hardware reason that Chip prefers the toggle.
David
IMHO, you're right. Chip's thoughts seems to be driven by implicit hardware reasons.
Perhaps it's due to the fact, that a toggle bit is already there, selecting from where pipeline's first stage is to be loaded, Cog or Hub.
It must also exists, to enable the LRU caching mechanism.
So, it's an almost free differentiator bit, that must be there anyway.
I tried to suggest this a while back. I think you're saying to use that extra bit to select hub or COG addresses in the CALL and JMP instructions. The other option is what I mentioned in the post just before yours, that we just use two different opcodes. Both result in the same binary being generated where the bit that Chip is currently using to distinguish the XXX and XXX_ instructions gets used to select hub vs. COG. That seems a lot simpler to me than the toggle although there might be some hardware reason that Chip prefers the toggle.
This is exactly my thoughts too. Currently I cannot see any advantage to toggling and it just seems safer to explicitly select the correct mode rather than toggling.
It is just that the compiler will see it differently.
BTW I updated my earlier post with a table of instructions for all the modes.
I cannot see the requirement for the toggling mode, although the hardware needs to know where the instruction pc is going. But in sw, the user doesn't want to know about this.
dat
COGMODE
org0
doloop ...
...
CALLX subr' call cog routine
...
CALLY hubloop ' call hub routine
...
subr ...
RETX ' return to caller (cog or hub)
HUBMODE
orgh $4000
hubloop ...
...
CALLX subr' call cog routine
...
CALLY hubsub ' call hub routine
...
RETY ' return to caller (cog or hub)
hubsub ...
RETY ' return to caller (cog or hub)
In the above cases, the compiler would use the correct JMP/CALL instruction. But I don't see a toggle case, but rather the specific case of the compiler inserting either a hub or cog CALL.
It doesn't actually save anything, but from a user perspective it sounds simpler (to me anyway). So the CALL & CALL_ become a COG CA7gLL and a HUB CALL instead of a same cog/hub CALL and a toggle cog/hub CALL. This way, the specific CALL (say CALL (for cog) & CALLH) reset/set the hubexec mode bit in the ALU.
Does this make sense???
You're right that for constant jumps and calls the assembler can know if it's going to hub from cog, to cog from hub, or staying in the cog or hub. This could get rid of the "_" versions of branches.
We could have either toggling and non-toggling branches, or fixed cog and fixed hub branches. The latter seems simpler, but will inhibit code from working in both cog and hub. There's also the issue of the 9-bit constant branches (DJNZ, etc.) needing to work in both cog and hub. For these reasons, I think a toggling system is better, regardless of the syntax.
Comments
Postedit: Reduce screen magnification (Ctl + Scrollwheel) to view this table better!
ZCxS Opcode ZC I Cond Dest Source Instr/00 01 10 11 Operand(s) Flags -------------------------------------------------------------------------------------------------------------------------------- ZCWS 00000ff ZC I CCCC DDDDDDDDD SSSSSSSSS RDBYTE RDBYTEC RDWORD RDWORDC D,S/PTRA/PTRB [WZ],[WC] ZCWS 00001ff ZC I CCCC DDDDDDDDD SSSSSSSSS RDLONG RDLONGC RDAUX RDAUXR D,S/PTRA/PTRB || D,S/#0..$FF/PTRX/PTRY [WZ],[WC] ZCMS 00010ff ZC I CCCC DDDDDDDDD SSSSSSSSS ISOB NOTB CLRB SETB D,S/# [WZ],[WC] ZCMS 00011ff ZC I CCCC DDDDDDDDD SSSSSSSSS SETBC SETBNC SETBZ SETBNZ D,S/# [WZ],[WC] ZCMS 00100ff ZC I CCCC DDDDDDDDD SSSSSSSSS ANDN AND OR XOR D,S/# [WZ],[WC] ZCMS 00101ff ZC I CCCC DDDDDDDDD SSSSSSSSS MUXC MUXNC MUXZ MUXNZ D,S/# [WZ],[WC] ZCMS 00110ff ZC I CCCC DDDDDDDDD SSSSSSSSS ROR ROL SHR SHL D,S/# [WZ],[WC] ZCMS 00111ff ZC I CCCC DDDDDDDDD SSSSSSSSS RCR RCL SAR REV D,S/# [WZ],[WC] ZCWS 01000ff ZC I CCCC DDDDDDDDD SSSSSSSSS MOV NOT ABS NEG D,S/# [WZ],[WC] ZCWS 01001ff ZC I CCCC DDDDDDDDD SSSSSSSSS NEGC NEGNC NEGZ NEGNZ D,S/# [WZ],[WC] ZCMS 01010ff ZC I CCCC DDDDDDDDD SSSSSSSSS ADD SUB ADDX SUBX D,S/# [WZ],[WC] ZCMS 01011ff ZC I CCCC DDDDDDDDD SSSSSSSSS ADDS SUBS ADDSX SUBSX D,S/# [WZ],[WC] ZCMS 01100ff ZC I CCCC DDDDDDDDD SSSSSSSSS SUMC SUMNC SUMZ SUMNZ D,S/# [WZ],[WC] ZCMS 01101ff ZC I CCCC DDDDDDDDD SSSSSSSSS MIN MAX MINS MAXS D,S/# [WZ],[WC] ZCMS 01110ff ZC I CCCC DDDDDDDDD SSSSSSSSS ADDABS SUBABS INCMOD DECMOD D,S/# [WZ],[WC] ZCMS 01111ff ZC I CCCC DDDDDDDDD SSSSSSSSS CMPSUB SUBR MUL SCL D,S/# [WZ],[WC] ZCWS 10000ff ZC I CCCC DDDDDDDDD SSSSSSSSS DECOD2 DECOD3 DECOD4 DECOD5 D,S/# [WZ],[WC] Z-WS 100010f Zf I CCCC DDDDDDDDD SSSSSSSSS ENCOD BLMASK ONECNT ZERCNT D,S/# [WZ] -CWS 1000110 fC I CCCC DDDDDDDDD SSSSSSSSS INCPAT DECPAT D,S/# [WC] --WS 1000111 ff I CCCC DDDDDDDDD SSSSSSSSS SPLITB MERGEB SPLITW MERGEW D,S/# --MS 10010nn nf I CCCC DDDDDDDDD SSSSSSSSS GETNIB SETNIB D,S/#,#0..7 --MS 1001100 nf I CCCC DDDDDDDDD SSSSSSSSS GETWORD SETWORD D,S/#,#0..1 --MS 1001101 ff I CCCC DDDDDDDDD SSSSSSSSS STWORDS ROLNIB ROLBYTE ROLWORD D,S/# --MS 1001110 ff I CCCC DDDDDDDDD SSSSSSSSS SETS SETD SETX SETI D,S/# -CMS 1001111 fC I CCCC DDDDDDDDD SSSSSSSSS COGNEW WAITCNT D,S/# [WC] --MS 101000n nf I CCCC DDDDDDDDD SSSSSSSSS GETBYTE SETBYTE D,S/#,#0..3 --WS 1010010 ff I CCCC DDDDDDDDD SSSSSSSSS STBYTES SWBYTES PACKRGB UNPKRGB D,S/# --MS 1010011 ff I CCCC DDDDDDDDD SSSSSSSSS ADDPIX MULPIX BLNPIX MIXPIX D,S/# ZCMS 101010f ZC I CCCC DDDDDDDDD SSSSSSSSS JMPSW JMPSWD D,S/# [WZ],[WC] --MS 1010110 ff I CCCC DDDDDDDDD SSSSSSSSS IJZ IJZD IJNZ IJNZD D,S/# --MS 1010111 ff I CCCC DDDDDDDDD SSSSSSSSS DJZ DJZD DJNZ DJNZD D,S/# ZCRS 10110ff ZC I CCCC DDDDDDDDD SSSSSSSSS TESTB TESTN TEST CMP D,S/# [WZ],[WC] ZCRS 10111ff ZC I CCCC DDDDDDDDD SSSSSSSSS CMPX CMPS CMPSX CMPR D,S/# [WZ],[WC] --RS 11000nn nf I CCCC DDDDDDDDD SSSSSSSSS COGINIT WAITVID WAITVID D,S/#,#0..7 | #0..$DFF,S/# || D,S/# -CRS 11001fn nC I CCCC DDDDDDDDD SSSSSSSSS WAITPEQ WAITPNE D,S/#,#0..3 [WC] --LS 110100f fL I CCCC DDDDDDDDD SSSSSSSSS WRBYTE WRWORD WRLONG FRAC D/#,S/PTRA/PTRB ||| D/#,S/# --LS 110101f fL I CCCC DDDDDDDDD SSSSSSSSS WRAUX WRAUXR SETACCA SETACCB D/#,S/#0..$FF/PTRX/PTRY || D/#,S/# --LS 110110f fL I CCCC DDDDDDDDD SSSSSSSSS MACA MACB MUL32 MUL32U D/#,S/# --LS 110111f fL I CCCC DDDDDDDDD SSSSSSSSS DIV32 DIV32U DIV64 DIV64U D/#,S/# --LS 111000f fL I CCCC DDDDDDDDD SSSSSSSSS SQRT64 QSINCOS QARCTAN QROTATE D/#,S/# --LS 111001f fL I CCCC DDDDDDDDD SSSSSSSSS SETSERA SETSERB SETCTRS SETWAVS D/#,S/# --LS 111010f fL I CCCC DDDDDDDDD SSSSSSSSS SETFRQS SETPHSS ADDPHSS SUBPHSS D/#,S/# --LS 111011f fL I CCCC DDDDDDDDD SSSSSSSSS JP JPD JNP JNPD D/#,S/# --LS 111100n nL I CCCC DDDDDDDDD SSSSSSSSS CFGPINS JMPTASK D/#,S/#,#0..2 | D/#,S/# --LS 111101f fL I CCCC DDDDDDDDD SSSSSSSSS SETXFR SETMIX <empty> <empty> D/#,S/# --RS 1111100 ff I CCCC DDDDDDDDD SSSSSSSSS JZ JZD JNZ JNZD D,S/# -------------------------------------------------------------------------------------------------------------------------------- ---- 1111101 ff n nnnn nnnnnnnnn nnnnnnnnn AUGI #23bits ---- 1111101 01 0 nnnn nnnnnnnnn nnniiiiii REPS #1..$10000,#1..64 ---- 1111101 01 1 BBAA ddddddddd sssssssss xxxINDx FIXINDx #d,#s | SETINDx #s | #d | #d,# ---- 1111101 10 0 CCCC ffnnnnnnn nnnnnnnnn JMP JMP_ JMP JMP_ #abs | #abs | @rel | @rel ---- 1111101 10 1 CCCC ffnnnnnnn nnnnnnnnn JMPD JMPD_ JMPD JMPD_ #abs | #abs | @rel | @rel ---- 1111101 11 0 CCCC ffnnnnnnn nnnnnnnnn CALL CALL_ CALL CALL_ #abs | #abs | @rel | @rel ---- 1111101 11 1 CCCC ffnnnnnnn nnnnnnnnn CALLD CALLD_ CALLD CALLD_ #abs | #abs | @rel | @rel ---- 1111110 00 0 CCCC ffnnnnnnn nnnnnnnnn CALLA CALLA_ CALLA CALLA_ #abs | #abs | @rel | @rel ---- 1111110 00 1 CCCC ffnnnnnnn nnnnnnnnn CALLAD CALLAD_ CALLAD CALLAD_ #abs | #abs | @rel | @rel ---- 1111110 01 0 CCCC ffnnnnnnn nnnnnnnnn CALLB CALLB_ CALLB CALLB_ #abs | #abs | @rel | @rel ---- 1111110 01 1 CCCC ffnnnnnnn nnnnnnnnn CALLBD CALLBD_ CALLBD CALLBD_ #abs | #abs | @rel | @rel ---- 1111110 10 0 CCCC ffnnnnnnn nnnnnnnnn CALLX CALLX_ CALLX CALLX_ #abs | #abs | @rel | @rel ---- 1111110 10 1 CCCC ffnnnnnnn nnnnnnnnn CALLXD CALLXD_ CALLXD CALLXD_ #abs | #abs | @rel | @rel ---- 1111110 11 0 CCCC ffnnnnnnn nnnnnnnnn CALLY CALLY_ CALLY CALLY_ #abs | #abs | @rel | @rel ---- 1111110 11 1 CCCC ffnnnnnnn nnnnnnnnn CALLYD CALLYD_ CALLYD CALLYD_ #abs | #abs | @rel | @rel -------------------------------------------------------------------------------------------------------------------------------- ZCW- 1111111 ZC 0 CCCC DDDDDDDDD 0000000ff COGID LOCKNEW GETPC GETLFSR D [WZ],[WC] ZCW- 1111111 ZC 0 CCCC DDDDDDDDD 0000001ff GETCNT GETCNTX GETACAL GETACAH D [WZ],[WC] ZCW- 1111111 ZC 0 CCCC DDDDDDDDD 0000010ff GETACBL GETACBH GETPTRA GETPTRB D [WZ],[WC] ZCW- 1111111 ZC 0 CCCC DDDDDDDDD 0000011ff GETPTRX GETPTRY SERINA SERINB D [WZ],[WC] ZCW- 1111111 ZC 0 CCCC DDDDDDDDD 0000100ff GETMULL GETMULH GETDIVQ GETDIVR D [WZ],[WC] ZCW- 1111111 ZC 0 CCCC DDDDDDDDD 0000101ff GETSQRT GETQX GETQY GETQZ D [WZ],[WC] ZCW- 1111111 ZC 0 CCCC DDDDDDDDD 0000110ff GETPHSA GETPHZA GETCOSA GETSINA D [WZ],[WC] ZCW- 1111111 ZC 0 CCCC DDDDDDDDD 0000111ff GETPHSB GETPHZB GETCOSB GETSINB D [WZ],[WC] ZCM- 1111111 ZC 0 CCCC DDDDDDDDD 0001000ff PUSHZC POPZC SUBCNT GETPIX D [WZ],[WC] ZCM- 1111111 ZC 0 CCCC DDDDDDDDD 0001001ff BINBCD BCDBIN BINGRY GRYBIN D [WZ],[WC] ZCM- 1111111 ZC 0 CCCC DDDDDDDDD 0001010ff ESWAP4 ESWAP8 SEUSSF SEUSSR D [WZ],[WC] Z-M- 1111111 ZC 0 CCCC DDDDDDDDD 0001011ff INCD DECD INCDS DECDS D [WZ],[WC] ZCW- 1111111 ZC 0 CCCC DDDDDDDDD 000110000 POP D [WZ],[WC] --L- 1111111 00 L CCCC DDDDDDDDD 001iiiiii REPD D/#1..512,#1..64 --L- 1111111 00 L CCCC DDDDDDDDD 0100000ff CLKSET COGSTOP LOCKSET LOCKCLR D/# --L- 1111111 00 L CCCC DDDDDDDDD 0100001ff LOCKRET RDWIDEC RDWIDE WRWIDE D/# | D/PTRA/PTRB ZCL- 1111111 ZC L CCCC DDDDDDDDD 0100010ff GETP GETNP SEROUTA SEROUTB D/# [WZ],[WC] -CL- 1111111 0C L CCCC DDDDDDDDD 0100011ff CMPCNT WAITPX WAITPR WAITPF D/# [WC] ZCL- 1111111 ZC L CCCC DDDDDDDDD 0100100ff SETZC SETMAP SETXCH SETTASK D/# [WZ],[WC] --L- 1111111 00 L CCCC DDDDDDDDD 0100101ff SETRACE SARACCA SARACCB SARACCS D/# --L- 1111111 00 L CCCC DDDDDDDDD 0100110ff SETPTRA SETPTRB ADDPTRA ADDPTRB D/# --L- 1111111 00 L CCCC DDDDDDDDD 0100111ff SUBPTRA SUBPTRB SETWIDE SETWIDZ D/# --L- 1111111 00 L CCCC DDDDDDDDD 0101000ff SETPTRX SETPTRY ADDPTRX ADDPTRY D/# --L- 1111111 00 L CCCC DDDDDDDDD 0101001ff SUBPTRX SUBPTRY PASSCNT WAIT D/# --L- 1111111 00 L CCCC DDDDDDDDD 0101010ff OFFP NOTP CLRP SETP D/# --L- 1111111 00 L CCCC DDDDDDDDD 0101011ff SETPC SETPNC SETPZ SETPNZ D/# --L- 1111111 00 L CCCC DDDDDDDDD 0101100ff DIV64D SQRT32 QLOG QEXP D/# --L- 1111111 00 L CCCC DDDDDDDDD 0101101ff SETQI SETQZ CFGDACS SETDACS D/# --L- 1111111 00 L CCCC DDDDDDDDD 0101110ff CFGDAC0 CFGDAC1 CFGDAC2 CFGDAC3 D/# --L- 1111111 00 L CCCC DDDDDDDDD 0101111ff SETDAC0 SETDAC1 SETDAC2 SETDAC3 D/# --L- 1111111 00 L CCCC DDDDDDDDD 0110000ff SETCTRA SETWAVA SETFRQA SETPHSA D/# --L- 1111111 00 L CCCC DDDDDDDDD 0110001ff ADDPHSA SUBPHSA SETVID SETVIDY D/# --L- 1111111 00 L CCCC DDDDDDDDD 0110010ff SETCTRB SETWAVB SETFRQB SETPHSB D/# --L- 1111111 00 L CCCC DDDDDDDDD 0110011ff ADDPHSB SUBPHSB SETVIDI SETVIDQ D/# --L- 1111111 00 L CCCC DDDDDDDDD 0110100ff SETPIX SETPIXZ SETPIXU SETPIXV D/# --L- 1111111 00 L CCCC DDDDDDDDD 0110101ff SETPIXA SETPIXR SETPIXG SETPIXB D/# --L- 1111111 00 L CCCC DDDDDDDDD 0110110ff SETPORA SETPORB SETPORC SETPORD D/# --L- 1111111 00 L CCCC DDDDDDDDD 0110111ff PUSH <empty> JMPREL JMPRELD D/# | D/# | D | D --R- 1111111 00 0 CCCC DDDDDDDDD 0111010ff JMP JMP_ JMPD JMPD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111011ff CALL CALL_ CALLD CALLD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111100ff CALLA CALLA_ CALLAD CALLAD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111101ff CALLB CALLB_ CALLBD CALLBD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111110ff CALLX CALLX_ CALLXD CALLXD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111111ff CALLY CALLY_ CALLYD CALLYD_ D ZC-- 1111111 ZC x CCCC xxxxxxxxx 1000000ff RETA RETAD RETB RETBD [WZ],[WC] ZC-- 1111111 ZC x CCCC xxxxxxxxx 1000001ff RETX RETXD RETY RETYD [WZ],[WC] ZC-- 1111111 ZC x CCCC xxxxxxxxx 1000010ff RET RETD POLCTRA POLCTRB [WZ],[WC] ZC-- 1111111 ZC x CCCC xxxxxxxxx 1000011ff POLVID CAPCTRA CAPCTRB CAPCTRS [WZ],[WC] ---- 1111111 00 x CCCC xxxxxxxxx 1000100ff CACHEX CLRACCA CLRACCB CLRACCS ZC-- 1111111 ZC x CCCC xxxxxxxxx 1000101ff CHKPTRX CHKPTRY SYNCTRA SYNCTRB [WZ],[WC] ---- 1111111 00 x CCCC xxxxxxxxx 1000110ff SETPIXW <empty> <empty> <empty> --------------------------------------------------------------------------------------------------------------------------------
InstructionSet_20131217a.spinWould it be too disruptive to get rid of the #address requirement for constant branches and then use @register to denote register?
These:
JMP #label
JMP register
Would become:
JMP label
JMP @register
What do you think?
It would get rid of a lot of #'s in source code and introduce an occasional @. This is more like what newcomers would expect, but it differs from Prop1.
@n for absolute
@+n for jump relative positive offset
@-n for jump relative negative offset
would work.
Or do you mean get rid of absolute jmp's?
It's actually looking to me like absolute jumps are kind of worthless. You don't need them in the cog. And in the hub, is it realistic to know the absolute address of something that's not you? I think a register would better hold a value for such a purpose What do you think?
Without absolute jumps, how will hubexec code call cog subroutines or jump to them?
In a 32bit address space with a 32 bit instruction, you don't have many options, unless you want to give up 1/2 of the instruction set range to handle absolute jumps.
In the case where you need an absolute jump, the mechanism is to generate a 32 bit constant, load it into a register, then branch to the register.
You're right. Wait...
Any branch that ends in underscore is cog/hub-mode toggling. Those jumps cannot be relative, because there's no sensible relationship between cog and hub execution address. I could just have those encoded as absolutes in the assembler and have the cog hardware handle them as absolutes. That would let us consolidate with one constant address syntax, so we could get rid of #. What do you think?
However, compatibility is to some extent a problem. Maybe later the compilers could have a compatibility bit to switch back to the P1 style modes.
As for relative vs absolute, this is more of a compiler issue isn't it?
eg
JMP label
would be created as a relative or absolute immediate instruction by the compiler.
But,
JMP @register
would the contents of the register be absolute or relative???
ZCxS Opcode ZC I Cond Dest Source Instr/00 01 10 11 Operand(s) Flags -------------------------------------------------------------------------------------------------------------------------------- ZCMS 101010f ZC I CCCC DDDDDDDDD SSSSSSSSS JMPSW JMPSWD D,S/# [WZ],[WC] --MS 1010110 ff I CCCC DDDDDDDDD SSSSSSSSS IJZ IJZD IJNZ IJNZD D,S/# --MS 1010111 ff I CCCC DDDDDDDDD SSSSSSSSS DJZ DJZD DJNZ DJNZD D,S/# --LS 111011f fL I CCCC DDDDDDDDD SSSSSSSSS JP JPD JNP JNPD D/#,S/# --LS 111100n nL I CCCC DDDDDDDDD SSSSSSSSS CFGPINS JMPTASK D/#,S/#,#0..2 | D/#,S/# --RS 1111100 ff I CCCC DDDDDDDDD SSSSSSSSS JZ JZD JNZ JNZD D,S/# -------------------------------------------------------------------------------------------------------------------------------- ---- 1111101 ff n nnnn nnnnnnnnn nnnnnnnnn AUGI #23bits ---- 1111101 10 0 CCCC ffnnnnnnn nnnnnnnnn JMP JMP_ JMP JMP_ #abs | #abs | @rel | @rel ---- 1111101 10 1 CCCC ffnnnnnnn nnnnnnnnn JMPD JMPD_ JMPD JMPD_ #abs | #abs | @rel | @rel ---- 1111101 11 0 CCCC ffnnnnnnn nnnnnnnnn CALL CALL_ CALL CALL_ #abs | #abs | @rel | @rel ---- 1111101 11 1 CCCC ffnnnnnnn nnnnnnnnn CALLD CALLD_ CALLD CALLD_ #abs | #abs | @rel | @rel ---- 1111110 00 0 CCCC ffnnnnnnn nnnnnnnnn CALLA CALLA_ CALLA CALLA_ #abs | #abs | @rel | @rel ---- 1111110 00 1 CCCC ffnnnnnnn nnnnnnnnn CALLAD CALLAD_ CALLAD CALLAD_ #abs | #abs | @rel | @rel ---- 1111110 01 0 CCCC ffnnnnnnn nnnnnnnnn CALLB CALLB_ CALLB CALLB_ #abs | #abs | @rel | @rel ---- 1111110 01 1 CCCC ffnnnnnnn nnnnnnnnn CALLBD CALLBD_ CALLBD CALLBD_ #abs | #abs | @rel | @rel ---- 1111110 10 0 CCCC ffnnnnnnn nnnnnnnnn CALLX CALLX_ CALLX CALLX_ #abs | #abs | @rel | @rel ---- 1111110 10 1 CCCC ffnnnnnnn nnnnnnnnn CALLXD CALLXD_ CALLXD CALLXD_ #abs | #abs | @rel | @rel ---- 1111110 11 0 CCCC ffnnnnnnn nnnnnnnnn CALLY CALLY_ CALLY CALLY_ #abs | #abs | @rel | @rel ---- 1111110 11 1 CCCC ffnnnnnnn nnnnnnnnn CALLYD CALLYD_ CALLYD CALLYD_ #abs | #abs | @rel | @rel -------------------------------------------------------------------------------------------------------------------------------- --L- 1111111 00 L CCCC DDDDDDDDD 0110111ff PUSH <empty> JMPREL JMPRELD D/# | D/# | D | D --R- 1111111 00 0 CCCC DDDDDDDDD 0111010ff JMP JMP_ JMPD JMPD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111011ff CALL CALL_ CALLD CALLD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111100ff CALLA CALLA_ CALLAD CALLAD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111101ff CALLB CALLB_ CALLBD CALLBD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111110ff CALLX CALLX_ CALLXD CALLXD_ D --R- 1111111 00 0 CCCC DDDDDDDDD 0111111ff CALLY CALLY_ CALLYD CALLYD_ D ZC-- 1111111 ZC x CCCC xxxxxxxxx 1000000ff RETA RETAD RETB RETBD [WZ],[WC] ZC-- 1111111 ZC x CCCC xxxxxxxxx 1000001ff RETX RETXD RETY RETYD [WZ],[WC] ZC-- 1111111 ZC x CCCC xxxxxxxxx 1000010ff RET RETD POLCTRA POLCTRB [WZ],[WC] --------------------------------------------------------------------------------------------------------------------------------
If this was only for branches, it would be unnecessarily inconsistent. If it was for everything, add @a, @b would be a headache. I like the Prop 1 method way better, even though I forget #'s all the time. How about keep it the Prop 1 way but make a compiler warning if you say jmp label, where label is initially a command and not a res or long? Maybe whether or not the compiler should emit this warning could be user configurable.
electrodude
I agree that jumps between modes have to be absolute, as relative addresses do not make sense there. So you can save some instruction encodings there.
I have niggling feeling that we would regred not having both absolute and relative within the same mode.
I think what would work best:
cog-cog absolute and relative addressing
hub-hub absolute and relative addressing
cog-hub absolute addressing only
hub-cog absolute addressing only
I am not sure why toggling is required though???
IMHO there are 2 basic cases
JMP/CALL to Hub
JMP/CALL to Cog
These two cover the cases of:
Hub JMP/CALL to Hub
Hub JMP/CALL to Cog
Cog JMP/CALL to Hub
Cog JMP/CALL to Cog
The compiler will know whether it is in hub or cog mode, and whether the call will be to hub or cog.
So I cannot see why we need a toggle JMP/CALL.
Am I missing something here???
Next, there are D (delayed versions).
And lastly, we need to see which hub and cog modes require..
Immediate Absolute
Immediate Relative
Indirect Absolute (register)
Indirect Relative (register)
To me, it makes sense for the Indirect JMP/CALL to use "@register".
Many, including myself, often forget the "#" for the immediate absolute. I would rather ditch it or have an option to include/warn in the compiler - I usually check my code with bst as it gives a warning - there are only 4 cases in the whole ZiCog code that actually use a register.
Agreed, I cannot see the use of relative addressing for cog-hub or hub-cog mode switching. If anything is relative, then the sw would have to add the base to it, because there is not reference for the hw at runtime. Relative is only consistent within cog-cog and hub-hub.
On the P1 we don't have relative for cog-cog, but it would be nice. At some time, it may make expanding cog beyond 512 longs possible (with some simple caveats). I would love to access AUX as extended Cog ram.
Relative makes a lot more sense with hub mode although Chip has found 16bits of (immediate) address for absolute/relative.
Relative facilitates relocatable code, beyond the base.
'JMP/CALL @register' would be absolute.
'JMP_/CALL_ @register' would be absolute.
'JMP/CALL label' would be relative
'JMP_/CALL_ label' would be absolute
So, all would be absolute except non-toggling constant branches. They would be relative.
Thinking further...
In hub mode...
Relative addressing can be computed by the compiler. This makes the code relocatable. These relative addresses would be held within the JMP/CALL instructions (17 typo 16 bits). I cannot see a need to have Relative addressing held in registers - can you???
But the original call to the module would need to be done by an Absolute JMP/CALL.
Most likely, the Absolute address would need to be held in a register because you don't want to plug absolute addresses into instructions within hub.
However, we will also require the JMP/CALL from hub to cog to contain the absolute cog address within the instruction, and also cog to hub.
So it makes sense for JMP/CALLs to Hub or Cog to have absolute addresses contained within the instruction, as well as in a register.
Does this make sense???
cog-cog absolute and relative addressing - I think we need both. Relative for relocatable snippets, and absolute for calling subroutine libraries, or jumping to known fixed entry points
hub-hub absolute and relative addressing - I think we need both. Relative for relocatable snippets, and absolute for calling subroutine libraries, or jumping to known fixed entry points
cog-hub absolute addressing only, as relative does not make sense.
hub-cog absolute addressing only, as relative does not make sense
I like using @absoluteaddr convention for labels, and @$1234 works for fixed absolute numbers.
I am concerned with using 'jmp label' to indicate relative jumps, as that would normally indicate jump to content of register.
Perhaps
jmp/call @addr indicates a relative jmp/call to the label addr (valid for cog-cog, hub-hub)
jmp/call #addr indicates an absolute jmp/call (consistent with P1) (valid for cog-cog, hub-hub, cog-hub, hub-cog)
jmp/call reg indicates an indirect jmp/call to the contents of reg (valid for cog-cog, hub-hub, cog-hub, hub-cog)
The more I think of it, the more certain I become that we should keep absolute calls/jumps for all modes.
Agreed, no need to have relative-indirect. Only 16 bits needed, as all hub instructions must be long aligned.
This would also allow storing CAR/CDR in one long for CONS
See my previous post (right before this one) I think I have all the usage cases, please let me know if I missed something... or if something should be added.
While in hub mode, you'll want to call to both hub and cog code. When in cog mode, you'll want to call both hub and cog code.
This is exactly how it's set up at the moment.
I was thinking if we could come up with some set rules for constants in different circumstances, we could adopt very simple syntax.
Instead of:
JMP
JMP_
You have:
JMP
HJMP
Where JMP means "jump to a COG address" and HJMP means "jump to a hub address". Seems more intuitive to me.
I think that what we have is the simplest.
I feel as soon as any of the current capability (except for inter-modal call/jmp) is removed, we would get bitten by the lack.
Having subroutines at fixed location is very useful for libraries, system calls etc.
Indirect jumps/calls are very useful for function pointers and jump tables.
Relative jumps/calls are very useful for relocatable code.
I think we are asking for trouble if we try to eliminate any of these (except when switching modes, relative inter-modal adresses do not make any sense)
Chip,
I cannot see the requirement for the toggling mode, although the hardware needs to know where the instruction pc is going. But in sw, the user doesn't want to know about this.
dat COGMODE org 0 doloop ... ... CALLX subr ' call cog routine ... CALLY hubloop ' call hub routine ... subr ... RETX ' return to caller (cog or hub) HUBMODE orgh $4000 hubloop ... ... CALLX subr ' call cog routine ... CALLY hubsub ' call hub routine ... RETY ' return to caller (cog or hub) hubsub ... RETY ' return to caller (cog or hub)
In the above cases, the compiler would use the correct JMP/CALL instruction. But I don't see a toggle case, but rather the specific case of the compiler inserting either a hub or cog CALL.
It doesn't actually save anything, but from a user perspective it sounds simpler (to me anyway). So the CALL & CALL_ become a COG CALL and a HUB CALL instead of a same cog/hub CALL and a toggle cog/hub CALL. This way, the specific CALL (say CALL (for cog) & CALLH) reset/set the hubexec mode bit in the ALU.
Does this make sense???
There are more cases to these... where the addresses are stored in registers or as an immediate value (in the 16 bits - was a typo before)
I will put the cases in a table shortly.
COG-COG COG-HUB HUB-COG HUB-HUB ABS #IMM @REG #IMM @REG #IMM @REG #IMM @REG REL #IMM @REG ???? ???? ???? ???? #IMM @REG ABS call CALL call_ CALL_ call_ CALL_ call CALL REL call na call_ na call_ na call na
I strongly disagree here...@ should be used for indirection (ie the address is stored in a register - complication is, is it relative or absolute?)
# could be optional (for P1 compatibility) but would indicate the address is stored within the instruction (ie immediate - same complication, is it relative or absolute?)
Some other micros use BRA for relative jumps but this does not solve the CALL problem.
David
IMHO, you're right. Chip's thoughts seems to be driven by implicit hardware reasons.
Perhaps it's due to the fact, that a toggle bit is already there, selecting from where pipeline's first stage is to be loaded, Cog or Hub.
It must also exists, to enable the LRU caching mechanism.
So, it's an almost free differentiator bit, that must be there anyway.
Yanomani
It is just that the compiler will see it differently.
BTW I updated my earlier post with a table of instructions for all the modes.
You're right that for constant jumps and calls the assembler can know if it's going to hub from cog, to cog from hub, or staying in the cog or hub. This could get rid of the "_" versions of branches.
We could have either toggling and non-toggling branches, or fixed cog and fixed hub branches. The latter seems simpler, but will inhibit code from working in both cog and hub. There's also the issue of the 9-bit constant branches (DJNZ, etc.) needing to work in both cog and hub. For these reasons, I think a toggling system is better, regardless of the syntax.