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
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.
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???
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 @REG
ABS call CALL call_ CALL_ call_ CALL_ call CALL
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
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 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! InstructionSet_20131217a.spin
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.
@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???
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 and manipulating them easily with GETWORD and SETWORD
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.
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.
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.