Shop OBEX P1 Docs P2 Docs Learn Events
Propeller II update - BLOG - Page 145 — Parallax Forums

Propeller II update - BLOG

1142143145147148223

Comments

  • David BetzDavid Betz Posts: 14,511
    edited 2013-12-19 20:20
    cgracey wrote: »
    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.
    I thought the 9 bit constants in DJNZ instructions were going to be treated as relative addresses? In that case they just stay in the mode they're currently in.
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 20:24
    I updated my previous post with this table of variants
             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 cannot see any reason for:
    COG-HUB and HUB-COG Relative instructions, either #Immediate or @Register
    I see little use to have:
    COG-COG @Register Relative
    HUB-HUB @Register Relative

    This would reduce to:
             COG-COG      COG-HUB      HUB-COG     HUB-HUB
    ABS     #IMM @REG   #IMM  @REG   #IMM  @REG   #IMM @REG
    REL     #IMM ????   ????  ????   ????  ????   #IMM ????
    
  • AribaAriba Posts: 2,682
    edited 2013-12-19 20:25
    The advantage of the toggling/non toggling JUMP versions is that you can execute the same binary code in HUB mode and in Cog mode.
    The Cog code is anyway generated as an image in Hub-Memory before it is loaded into the cog. It may be useful to be able to execute the code in the image also in hub mode.

    With JMP and HJMP you will need to change all the jumps in a code snippet if you decide to execute it in the other mode.
    If the compiler generates two different instructions from the same mnemonic depending on the Hub or cog mode it's a bit simpler, but you can not execute the same binary code in both modes. This is only possible with toggling the mode on CPU level.

    Andy
  • SapiehaSapieha Posts: 2,964
    edited 2013-12-19 20:29
    Hi Chip.

    As 'JMP/CALL label' need both Relative and Absolute modes --->
    How You will separate that?

    And 'JMP/CALL @register' have usage as Relative and Absolute modes ---> In calculated JUMP tables
    How You will separate that?
    cgracey wrote: »
    '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.
  • David BetzDavid Betz Posts: 14,511
    edited 2013-12-19 20:29
    cgracey wrote: »
    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.
    Actually, treating the 17th bit (the one you currently use to distinguish JMP from JMP_) as an extra address bit would solve your problem of code working in both cog and hub mode because the assembler symbol table would know which memory space a symbol was in and set the bit appropriately. If you move the code to the other space (hub to cog for instance), then the address space of the labels would also change and the code would continue to work. Your scheme with toggle breaks down if you move code from one space to the other but don't also move all of the labels it references as well. Say for example your code is in COG space and contains a JMP_ to a location in hub space. If you move that instruction to hub space then JMP_ will toggle to COG space and reference the wrong address. This is fixed by using that extra bit as a COG vs. hub selector.
  • David BetzDavid Betz Posts: 14,511
    edited 2013-12-19 20:31
    Ariba wrote: »
    The advantage of the toggling/non toggling JUMP versions is that you can execute the same binary code in HUB mode and in Cog mode.
    The Cog code is anyway generated as an image in Hub-Memory before it is loaded into the cog. It may be useful to be able to execute the code in the image also in hub mode.

    With JMP and HJMP you will need to change all the jumps in a code snippet if you decide to execute it in the other mode.
    If the compiler generates two different instructions from the same mnemonic depending on the Hub or cog mode it's a bit simpler, but you can not execute the same binary code in both modes. This is only possible with toggling the mode on CPU level.

    Andy
    I think there are other problems with executing code from both hub and COG mode as I mentioned in my earlier post. Also, it doesn't seem like it would be useful enough to justify the awkward toggle semantics.
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 20:36
    Ariba wrote: »
    The advantage of the toggling/non toggling JUMP versions is that you can execute the same binary code in HUB mode and in Cog mode.
    The Cog code is anyway generated as an image in Hub-Memory before it is loaded into the cog. It may be useful to be able to execute the code in the image also in hub mode.

    With JMP and HJMP you will need to change all the jumps in a code snippet if you decide to execute it in the other mode.
    If the compiler generates two different instructions from the same mnemonic depending on the Hub or cog mode it's a bit simpler, but you can not execute the same binary code in both modes. This is only possible with toggling the mode on CPU level.

    Andy
    Andy,
    Sorry, I think with the restrictions and caveats, running code compiled for cog and running it in hub or visa versa is just asking for some unseen trouble.
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 20:45
    Toggling vs Direct:
    The instruction bit just gets used instead of a "toggle" bit it is used as a set/reset bit. The flipflop in the ALU/Pipeline just gets set/reset instead of toggled.

    The DJNZ etc instructions just use the bit in the ALU/Pipeline as is, and no change.

    The instructions JMP/CALL become goto/stayin COG mode, and JMP_/CALL_ become goto/stayin HUB mode (could be called HJMP/HCALL if required, but as I said, the compiler can take care of this automatically).

    This just seems so much cleaner to me, and currently I cannot see any reason in favour of the toggle. Chip, am I really missing something here??? I definitely don't want to see anyone thinking they can run compiled code from either cog or hub as I really think that is a certain recipe for disaster.
  • SapiehaSapieha Posts: 2,964
    edited 2013-12-19 20:54
    Hi Chip.

    As Cluso said.

    It is BAD idea to have code that are COG/HUB runnable.

    As if anyone write Program code for HUB it will be mostly BIGGER programs that COG can handle.
  • cgraceycgracey Posts: 14,133
    edited 2013-12-19 20:55
    David Betz wrote: »
    Actually, treating the 17th bit (the one you currently use to distinguish JMP from JMP_) as an extra address bit would solve your problem of code working in both cog and hub mode because the assembler symbol table would know which memory space a symbol was in and set the bit appropriately. If you move the code to the other space (hub to cog for instance), then the address space of the labels would also change and the code would continue to work. Your scheme with toggle breaks down if you move code from one space to the other but don't also move all of the labels it references as well. Say for example your code is in COG space and contains a JMP_ to a location in hub space. If you move that instruction to hub space then JMP_ will toggle to COG space and reference the wrong address. This is fixed by using that extra bit as a COG vs. hub selector.


    If relative addressing is used, code will work in both places.

    I think that absolute addressing has to be something explicit, maybe indicated with #, as it is at the moment. Relative branches are using @, but it would be neat to make that implied.
  • cgraceycgracey Posts: 14,133
    edited 2013-12-19 20:58
    Cluso99 wrote: »
    Toggling vs Direct:
    The instruction bit just gets used instead of a "toggle" bit it is used as a set/reset bit. The flipflop in the ALU/Pipeline just gets set/reset instead of toggled.

    The DJNZ etc instructions just use the bit in the ALU/Pipeline as is, and no change.

    The instructions JMP/CALL become goto/stayin COG mode, and JMP_/CALL_ become goto/stayin HUB mode (could be called HJMP/HCALL if required, but as I said, the compiler can take care of this automatically).

    This just seems so much cleaner to me, and currently I cannot see any reason in favour of the toggle. Chip, am I really missing something here??? I definitely don't want to see anyone thinking they can run compiled code from either cog or hub as I really think that is a certain recipe for disaster.

    Generally speaking, that would be disastrous, but I could see writing a block of code that could be called in the hub, or moved into the cog for really fast execution.

    This whole thing is a little tricky to think about because there are syntax issues involved, too.
  • David BetzDavid Betz Posts: 14,511
    edited 2013-12-19 21:01
    cgracey wrote: »
    Generally speaking, that would be disastrous, but I could see writing a block of code that could be called in the hub, or moved into the cog for really fast execution.

    This whole thing is a little tricky to think about because there are syntax issues involved, too.
    I'm signing off for the evening. I suppose this will all have been decided by the time I wake up again. Good luck in sorting this out! And I'll make one final plea for explicit selection of the target address space rather than toggling between address spaces. Good night....
  • cgraceycgracey Posts: 14,133
    edited 2013-12-19 21:11
    David Betz wrote: »
    I'm signing off for the evening. I suppose this will all have been decided by the time I wake up again. Good luck in sorting this out! And I'll make one final plea for explicit selection of the target address space rather than toggling between address spaces. Good night....

    I started out thinking the same thing, but as I got to considering the mnemonic names I realized that it was going to be a pain to write one kind of code with JMP and another kind with HJMP. I wanted to make the differences go away to keep code simple. Still more to think about....
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 21:23
    cgracey wrote: »
    ...
    I think that absolute addressing has to be something explicit, maybe indicated with #, as it is at the moment. Relative branches are using @, but it would be neat to make that implied.
    Chip,
    This goes against common usage, where @ is used to denote indirection.
    Here seems to be the current combination/requirement???
             COG-COG      COG-HUB      HUB-COG     HUB-HUB
    ABS     #IMM @REG   #IMM  @REG   #IMM  @REG   #IMM @REG
    REL     #IMM ????   ????  ????   ????  ????   #IMM ????
    
    @reg uses a register for Absolute and Indirection
    #Imm could be used for Immediate Absolute (as we do in the P1, but I causes a lot of confusion)
    label could be used for Immediate Relative (new - but in most cases if the # is left out, this will still work - unless self-modifying code is used)
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 21:33
    cgracey wrote: »
    I started out thinking the same thing, but as I got to considering the mnemonic names I realized that it was going to be a pain to write one kind of code with JMP and another kind with HJMP. I wanted to make the differences go away to keep code simple. Still more to think about....
    If HJMP or whatever makes your pnut task simpler, do that. Op names can be changed simply later on when there is more time or the open compiler is made to run on P2.
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 21:47
    Chip,
    For HUB code, I would even be happy to just compile it as if it were cog code (like I do with LMM now) and hand code a long for the appropriate JMP/CALLs.
    May just need something like

    CON
    HJMP EQU %1111101_100_0000_xx_0000000000000000
    _IF_Z_OR_C EQU %xxxx << 18

    DAT
    ORG 0
    ORGH $4000

    ...code here...
    LONG _IF_Z_OR_C I HJMP | ~label ' if_z_or_c hjmp #label
    [code]
    where ~label would be some char and the label would be the hub or cog address - hopefully you could add this feature to pnut as a temp thing???

    Postedit: Maybe
    LONG _IF_Z_OR_C | HJMP | @label
    or @@label
    would already work???
  • AribaAriba Posts: 2,682
    edited 2013-12-19 21:48
    I wonder a bit what you all find so dangerous or complicated with toggling jumps.
    I find it not more complicated to read in a code than having two times the same mnemonic which generates different binary code depending of the mode.
    I can't really estimate how difficult or useful the toggling version will be, but it allows definitly more tricks, and simplifies the Assembler a bit (no directives for Hub / Cog mode).

    If we have separate hub and cog jumps then the 16 bit immediate addresses in the cog-jumps make not much sense. We may just waste these bits or Chip has to change the whole instruction set again.

    I don't vote for one or the other version, I just don't see a big problem with toggling. I will take what I get...

    Andy
  • potatoheadpotatohead Posts: 10,254
    edited 2013-12-19 21:53
    I don't either.

    Defintely prefer the existing P1 "#" sign for immediate. It is confusing, but it's also consistent with a lot of other uses. Seems a PITA to change it now.
  • cgraceycgracey Posts: 14,133
    edited 2013-12-19 21:57
    I just realized that since all hub-to-cog and cog-to-hub constant jumps must be absolute (since relative addresses make no sense), there is a already an obvious way of discriminating where you are going:

    Absolute addresses $000..$1FF are valid cog addresses, but are ROM in hub memory, so not practically called as hub addresses. These would obviously be cog addresses.
    Absolute addresses $200..$FFFF are obviously hub addresses, as they are outside the range of cog memory.

    So, that takes care of all constant absolute JMPs and CALLs within and between cog and hub memory.

    What's left is the register-based JMPs and CALLs, which are always absolute. Their ranges could be discriminated at execution time to determine where they were headed.

    This just leaves constant relative branches, which don't ever change modes, and therefore require no special consideration.

    All this means that we don't need the JMP_/CALL_ instructions, at all, but we can let the hardware figure out at execution time what the deal is.

    Does anyone see any problems with this?

    (Perhaps it's providence that the ROM starts at $00000 and is >= $200 longs!)
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 22:10
    This works!!
    CON
      _clkmode = xinput
      _xinfreq = 80_000_000
      _HJMP    = %1111101_100_0000_00_0000000000000000
      _if_nc   = %0011 << 18
      
    DAT
            orgh    $00E00                          ' start of hub ram
            org   0
    entry   jmp   #entry
    cog     nop
            long  _hjmp | cog
            long  _if_nc | _hjmp | @cog
    {
    compiles to
    00E00- 00 E8 7F A8 00 00 00 00 01 00 00 FB 04 0E 0C FB   ................
    } 
    
    
  • msrobotsmsrobots Posts: 3,704
    edited 2013-12-19 22:12
    I guess this Is what David was asking a while ago, since It may simplify things In GCC.

    I think it is a beautiful solution.

    edit: - and if you add ever add more cog ram to a P3xx then you may have more space for rom too...

    Enjoy!

    Mike
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 22:17
    cgracey wrote: »
    I just realized that since all hub-to-cog and cog-to-hub constant jumps must be absolute (since relative addresses make no sense), there is a already an obvious way of discriminating where you are going:

    Absolute addresses $000..$1FF are valid cog addresses, but are ROM in hub memory, so not practically called as hub addresses. These would obviously be cog addresses.
    Absolute addresses $200..$FFFF are obviously hub addresses, as they are outside the range of cog memory.

    So, that takes care of all constant absolute JMPs and CALLs within and between cog and hub memory.

    What's left is the register-based JMPs and CALLs, which are always absolute. Their ranges could be discriminated at execution time to determine where they were headed.

    This just leaves constant relative branches, which don't ever change modes, and therefore require no special consideration.

    All this means that we don't need the JMP_/CALL_ instructions, at all, but we can let the hardware figure out at execution time what the deal is.

    Does anyone see any problems with this?

    (Perhaps it's providence that the ROM starts at $00000 and is >= $200 longs!)
    Nice Job!

    Postedit: The more I think about it, the more elegant it becomes! Frees up instruction space, no toggling instructions, and simpler for the compiler too!

    BTW It's $200 << 2 = $800, but that's still fine as ROM < $E00 :)

    Yes, I use the fact that cog <$200 in my P2 Debugger when the user enters an address. I just let them enter $2_0000_0000 to address the ROM (now will be $8_0000_0000).
  • YanomaniYanomani Posts: 1,524
    edited 2013-12-19 22:18
    cgracey wrote: »
    I just realized that since all hub-to-cog and cog-to-hub constant jumps must be absolute (since relative addresses make no sense), there is a already an obvious way of discriminating where you are going:

    Absolute addresses $000..$1FF are valid cog addresses, but are ROM in hub memory, so not practically called as hub addresses. These would obviously be cog addresses.
    Absolute addresses $200..$FFFF are obviously hub addresses, as they are outside the range of cog memory.

    So, that takes care of all constant absolute JMPs and CALLs within and between cog and hub memory.

    What's left is the register-based JMPs and CALLs, which are always absolute. Their ranges could be discriminated at execution time to determine where they were headed.

    This just leaves constant relative branches, which don't ever change modes, and therefore require no special consideration.

    All this means that we don't need the JMP_/CALL_ instructions, at all, but we can let the hardware figure out at execution time what the deal is.

    Does anyone see any problems with this?

    (Perhaps it's providence that the ROM starts at $00000 and is >= $200 longs!)

    Chip

    Perhaps I'm loosing something, due to sleeplessness, but anyway....:smile:
    How could then we craft a CALL or JUMP, to take advantage of any HUB ROM resident routine, whose addresses are in the range &00000 - $001FF?

    Yanomani
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 22:27
    Chip,
    While you are changing the instructions for these simpler JMP/CALLs,
    Might it be worthwhile to move the REPD instruction down to S=%010iiiiii (or %100iiiiii, or even share the REPS instruction for the loss of a bit on the REPS instruction), and move the instructions from %01xxxxxxx onwards into the space freed up by moving REPD down? Just a thought.
  • cgraceycgracey Posts: 14,133
    edited 2013-12-19 22:33
    Yanomani wrote: »
    Chip

    Perhaps I'm loosing something, due to sleeplessness, but anyway....:smile:
    How could then we craft a CALL or JUMP, to take advantage of any HUB ROM resident routine, whose addresses are in the range &00000 - $001FF?

    Yanomani


    You couldn't. But what's there are cog programs that run in cogs, so they're not callable. However, it might be good to swap locations of the ROM SHA256 and ROM MONITOR so that the SHA256 could be hub-callable routines, instead of a cog program. It would just have to start above $00800 ($200 long address). That way, you could call it from the cog that needs it, rather than keeping it a stand-along program that needs a whole cog to run. The ROM MONITOR, on the other hand, is a complete program that must run in a cog. If it turns out to have any useful routines, they could be put into ROM and made callable, so that others could use them, too.

    Edit: We could have entry points at $200+ (long address) which could do relative jumps backwards into the lower area, without causing things to switch to cog mode.
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-12-19 22:34
    Yanomani wrote: »
    Chip

    Perhaps I'm loosing something, due to sleeplessness, but anyway....:smile:
    How could then we craft a CALL or JUMP, to take advantage of any HUB ROM resident routine, whose addresses are in the range &00000 - $001FF?

    Yanomani
    Sorry, we don't. But it's a small price to pay for such an elegant and simple solution. (and its $00000-$007FF)
  • cgraceycgracey Posts: 14,133
    edited 2013-12-19 22:37
    Cluso99 wrote: »
    Chip,
    While you are changing the instructions for these simpler JMP/CALLs,
    Might it be worthwhile to move the REPD instruction down to S=%010iiiiii (or %100iiiiii, or even share the REPS instruction for the loss of a bit on the REPS instruction), and move the instructions from %01xxxxxxx onwards into the space freed up by moving REPD down? Just a thought.


    I'll look at that tonight and see.
  • jmgjmg Posts: 15,148
    edited 2013-12-19 22:47
    cgracey wrote:
    I just realized that since all hub-to-cog and cog-to-hub constant jumps must be absolute (since relative addresses make no sense), there is a already an obvious way of discriminating where you are going:

    Absolute addresses $000..$1FF are valid cog addresses, but are ROM in hub memory, so not practically called as hub addresses. These would obviously be cog addresses.
    Absolute addresses $200..$FFFF are obviously hub addresses, as they are outside the range of cog memory.

    Sounds good, and common with how other micros manage things, so should be easy for new users to follow.
    cgracey wrote: »
    Edit: We could have entry points at $200+ (long address) which could do relative jumps backwards into the lower area, without causing things to switch to cog mode.

    How large is the ROM now ? The useful stuff could go above $200, and the less useful / larger chunks could go < $200, which would reduce (or eliminate?) the number of double-hop calls to lower ROM ? (each one does cost RAM )
  • YanomaniYanomani Posts: 1,524
    edited 2013-12-19 22:55
    cgracey wrote: »
    You couldn't. But what's there are cog programs that run in cogs, so they're not callable. However, it might be good to swap locations of the ROM SHA256 and ROM MONITOR so that the SHA256 could be hub-callable routines, instead of a cog program. It would just have to start above $00800 ($200 long address). That way, you could call it from the cog that needs it, rather than keeping it a stand-along program that needs a whole cog to run. The ROM MONITOR, on the other hand, is a complete program that must run in a cog. If it turns out to have any useful routines, they could be put into ROM and made callable, so that others could use them, too.

    Edit: We could have entry points at $200+ (long address) which could do relative jumps backwards into the lower area, without causing things to switch to cog mode.
    Cluso99 wrote: »
    Sorry, we don't. But it's a small price to pay for such an elegant and simple solution. (and its $00000-$007FF)

    Chip, Cluso99

    Thanks for the prompt reply! At least I didn't got things confused, inside my brain!
    There are a lot of lambs here, just waiting to skip some fences, and be accounted for. There are also a sheepdog, waiting to be called, to start its day journey.:smile:
    As long as I don't start mixing things, lambs x cogs, skips x jumps, and calling sheepdogs, without waiting for their return, it's not yet the right time, to make an appointment with the family doctor.:lol:
    Then there are those fences, lots of fences.... hhuuummm
    Time to have a shower and a deep dive, towards bed!

    Yanomani
  • cgraceycgracey Posts: 14,133
    edited 2013-12-19 23:17
    jmg wrote: »
    Sounds good, and common with how other micros manage things, so should be easy for new users to follow.



    How large is the ROM now ? The useful stuff could go above $200, and the less useful / larger chunks could go < $200, which would reduce (or eliminate?) the number of double-hop calls to lower ROM ? (each one does cost RAM )


    The ROM goes to byte address $00DFF, so it is $E00 bytes long, or $380 longs long. That's 1.75 cog RAM's worth of data.
Sign In or Register to comment.