Shop OBEX P1 Docs P2 Docs Learn Events
RFBYTE/WORD/LONG work in hub exec mode — Parallax Forums

RFBYTE/WORD/LONG work in hub exec mode

TonyB_TonyB_ Posts: 2,232
edited 2025-12-19 15:26 in Propeller 2

I have tested RFBYTE/WORD/LONG in hub exec mode and they work, contrary to what the documentation says. They remove the byte/word/long after the next instruction from the FIFO. Possible uses for this are (a) to read data embedded within hub exec code, maybe put there by another cog and (b) to skip an instruction without any time penalty.

An example of (a):

rflong x
<instr2>
long $x_data
rflong y
<instr4>
long $y_data

The main advantage of using RFxxxx is that takes only two cycles, much faster than the 9...26 cycles (+1 if long crossing) for RDxxxx in hub exec mode. Note that if you wait sufficient time after a hub exec branch for FIFO filling to finish, RDxxxx can take the same as in cog exec, 9...16 cycles (+1 if long crossing).

An example of (b):

if_nz rflong temp
      <instr1>
_ret_ <instr2>
'return if z, continue if nz

Using RFLONG to skip instructions is equivalent to SKIPF with fixed skip pattern of %10. Hub exec doesn't support SKIPF itself. RFLONG removes the skipped instruction from the FIFO before it enters the instruction pipeline so it wastes no cycles, unlike SKIP.

RFVAR{S} did not work in hub exec mode in my tests. Consecutive RFBYTE/WORD/LONG also did not work. However, all RFxxxx can be used in cog exec after a routine in hub RAM returns. The data that RFxxxx reads start four bytes after the routine because the long directly after it has been read already as part of instruction pipelining. Note that a RDFAST is not needed before RFxxxx in this case because the former was done during the branch from cog to hub exec.

EDIT:
Added RFxxxx vs. RDxxxx time comparison.

Comments

  • evanhevanh Posts: 16,997

    Thieving data makes sense. And I'd come to the conclusion the FIFO doesn't terminate. It just stops being used.

  • TonyB_TonyB_ Posts: 2,232
    edited 2025-12-19 23:34

    @evanh said:
    Thieving data makes sense. And I'd come to the conclusion the FIFO doesn't terminate. It just stops being used.

    Yes and the good thing is that RFxxxx doesn't interfere with an instruction fetch in hub exec. I might test RFVAR{S} again as the other RFxxxx work.

    It's perfectly possible to do the following:
    From cog/LUT exec, call a routine in hub RAM then after it returns do RFxxxx's to read data starting four bytes after the end of the routine, without ever needing a RDFAST.

  • RaymanRayman Posts: 15,895

    Hmm... I was also under the impression that one can't touch the fifo in hubexec mode...

  • evanhevanh Posts: 16,997

    @Rayman said:
    Hmm... I was also under the impression that one can't touch the fifo in hubexec mode...

    It will crash your program if not carefully crafted.

  • @evanh said:

    @Rayman said:
    Hmm... I was also under the impression that one can't touch the fifo in hubexec mode...

    It will crash your program if not carefully crafted.

    For some instructions the docs are 'guidelines' more than rules. I thought RFxxxx in hub exec was worth trying and what I've described above does actually work. Care is needed to match RFxxxx with the size of data being removed from the FIFO, e.g.

    rfbyte x
    <instr2>
    byte $x_data
    rflong y
    <instr4>
    long $y_data
    

    but otherwise coding is straightforward.

  • roglohrogloh Posts: 6,209
    edited 2025-12-20 03:39

    This looks potentially useful for some future things. Perhaps it could pass a fixed 32 bit argument to some common cogexec routine called via different hubexec codepaths saving a couple of cycles, or for a parameter / return address? to an execf code block in cog RAM from hubexec code. That could allow a nice way to "return" back to hubexec from conditionally called execf code sprinkled throughout your hubexec code. Eg to return back to your hubexec code you could do:

    in hubRAM:

    rflong retaddr  ' read return address before conditionally branching into cogexec code
    if_z execf cogsvc ' conditionally do cog service
    long $+4 ' address of next long in hub
    <next_instr> ' next hubexec instruction after cogexec mode completes continues here
    

    in cogRAM:

    cogsvc  long  #%101001110 << 10 + cogexecsvc ' skipf pattern
    retaddr long 0 ' place to store return address
    
    cogexecsvc <svc_instr1>
    <svc_instr2>
    ...
    jmp retaddr ' continue with hub exec from where it was called
    

    This probably does incur a penalty however when returning due to hub fifo refill. But if your COG RAM is full and you can't break apart the service routines and can conveniently pack them together with execf it could still be helpful.

Sign In or Register to comment.