Shop OBEX P1 Docs P2 Docs Learn Events
To ORGH or not to ORGH? - Page 4 — Parallax Forums

To ORGH or not to ORGH?

124»

Comments

  • cgraceycgracey Posts: 14,133
    LOC is really only useful in hub-exec code, unless you're just exploiting it to load 20-bit constants. That it assembles under ORG is there for the possibility, but it's not practical. LOC was intended only as a mechanism to allow hub code to get addresses of its internal data structures.
  • evanhevanh Posts: 15,126
    cgracey wrote: »
    Dave, the PC is known at runtime, so LOC can give you an absolute address when your code only knows the relative offset from the PC. By writing hub-exec code which uses relative branches and relative LOC's, you can have an entire PASM application which can sit at any byte offset in hub memory in which it fits, and it will execute without any external pointers being required. You only need to JMP to the start of the code.

    Emphasising the PA register content is always resolved to absolute:
    loc  pa, #label testing
    =========================
    Cogexec
       PC    Op-code  PA-data  Cog-dref Hub-dref
    0000000b fe9ffffc 00000008 0badf00d 00000000
    0000000f fe900100 00000110 ff000002 deadbeef
    00000011 fe8004a8 000004a8 00000000 cafef00d
    
    Hubexec
       PC    Op-code  PA-data  Cog-dref Hub-dref
    00000404 fe800008 00000008 0badf00d 00000000
    00000414 fe800110 00000110 ff000002 deadbeef
    0000041c fe900088 000004a8 00000000 cafef00d
    
  • evanhevanh Posts: 15,126
    edited 2019-04-12 15:59
    Note: The PC there is the address of the LOC opcode. The program counter value required for PC-relative calculation is at the subsequent longword.
  • OK, got it. LOC loads the absolute address independent of whether the address is encoded as absolute or relative.

    Chip, are you going to change PNut to match the changes in fastspin for the LOC instruction?
  • RaymanRayman Posts: 13,797
    I thought LOC was just there to save one instruction...
  • That intent was seen in Moto chips, 6809, 68k, and the instruction was LEA.

    Load Effective Address.

    For PC relative, you specified that address mode.

    LEA would deliver the effective address 9f any combination of addressing modes into a register.

    LEA PC, X

    Address = current PC at time of execute, plus X.

    Relocatable, reentrant code was straightforward to write. Drop it anywhere, run it, move it, everything just worked.

    P2 benefits from this thinking.
  • Now that I understand how LOC works I can see that it would be useful for position-independent-code. Unfortunately, it can only write to PA, PB, PTRA or PTRB. It would be nice if it could write to a larger range of cog memory, but that would have gobbled up a lot of instruction space. Maybe in the P3 there could be a LOC instruction with a smaller hub address range, and a larger range of destinations.

    p2gcc generates code that loads addresses into one of the 15 general purpose registers, such as "mov r3, ##variable". A C source file is compiled into an object file starting at address $400. It must then be relocated to another address by the linker. The linker doesn't have to worry about the calls and jumps since they use relative address, but it does have to adjust variable addresses. With LOC the variable addresses could be relative also.

    I would have to move the address from the LOC destination register to a general purpose register, so the generated code would look like this:
        loc pb, #variable
        mov r3, pb
    
    However, this would take the same number of instructions as I currently use with the with the long source value.
  • evanhevanh Posts: 15,126
    Dave Hein wrote: »
    Chip, are you going to change PNut to match the changes in fastspin for the LOC instruction?

    You can forge ahead on the two buggy cases as they were unusable for everyone.

    The one case that could be improved is hubexec referencing hubram data below $400. Currently, this is getting encoded as absolute when it could be encoded as PC-relative.
  • cgraceycgracey Posts: 14,133
    edited 2019-04-13 00:20
    evanh wrote: »
    Dave Hein wrote: »
    Chip, are you going to change PNut to match the changes in fastspin for the LOC instruction?

    You can forge ahead on the two buggy cases as they were unusable for everyone.

    The one case that could be improved is hubexec referencing hubram data below $400. Currently, this is getting encoded as absolute when it could be encoded as PC-relative.

    Yes, I agree.
  • evanhevanh Posts: 15,126
    edited 2019-04-13 04:33
    Looking at Fastspin, even though it resolves fine, there is more PC-relative cases than expected. And I think this carries over to branching instructions too.

    Amusingly, all cases could default to PC-relative and you wouldn't know they were unless examining the machine code.
     loc  pa, #label testing  (fastspin v3.9.25)
    =========================
     cogexec
       PC    Op-code  PA-data    Cog-dref Hub-dref LUT-dref
    0000000f fe9ffff8 00000008   11111111 00000000 fa00b7f6
    00000011 fe9000fe 00000110   fd60062a 22222222 00000000
    00000013 fe800434 00000434   00000000 33333333 f607ee0a
    00000015 fe90038a 000003a0   2e202e20 00000000 44444444
    
     hubexec
       PC    Op-code  PA-data    Cog-dref Hub-dref LUT-dref
    00000410 fe800008 00000008   11111111 00000000 fa00b7f6
    00000418 fe800110 00000110   fd60062a 22222222 00000000
    00000420 fe900010 00000434   00000000 33333333 f607ee0a
    00000428 fe8003a0 000003a0   2e202e20 00000000 44444444
    
     lutexec
       PC    Op-code  PA-data    Cog-dref Hub-dref LUT-dref
    00000280 fe9ffd87 00000008   11111111 00000000 fa00b7f6
    00000282 fe9ffe8d 00000110   fd60062a 22222222 00000000
    00000284 fe800434 00000434   00000000 33333333 f607ee0a
    00000286 fe900119 000003a0   2e202e20 00000000 44444444
    

    EDIT: Updated with easier to read memory data.
  • I added the fix to p2asm for LOC relative addresses in the cog mode.
  • evanhevanh Posts: 15,126
    edited 2019-04-13 03:08
    https://github.com/davehein/p2gcc

    Yep, that matches fastspin result.
     loc  pa, #label testing  (p2asm v0.015)
    =========================
     cogexec
       PC    Op-code  PA-data    Cog-dref Hub-dref LUT-dref
    0000000f fe9ffff8 00000008   11111111 00000000 fa00b7f6
    00000011 fe9000fe 00000110   fd60062a 22222222 00000000
    00000013 fe800434 00000434   00000000 33333333 f607ee0a
    00000015 fe90038a 000003a0   2e202e20 00000000 44444444
    
     hubexec
       PC    Op-code  PA-data    Cog-dref Hub-dref LUT-dref
    00000410 fe800008 00000008   11111111 00000000 fa00b7f6
    00000418 fe800110 00000110   fd60062a 22222222 00000000
    00000420 fe900010 00000434   00000000 33333333 f607ee0a
    00000428 fe8003a0 000003a0   2e202e20 00000000 44444444
    
     lutexec
       PC    Op-code  PA-data    Cog-dref Hub-dref LUT-dref
    00000280 fe9ffd87 00000008   11111111 00000000 fa00b7f6
    00000282 fe9ffe8d 00000110   fd60062a 22222222 00000000
    00000284 fe800434 00000434   00000000 33333333 f607ee0a
    00000286 fe900119 000003a0   2e202e20 00000000 44444444
    
  • evanhevanh Posts: 15,126
    edited 2019-04-13 03:09
    Here's pnut:
     loc  pa, #label testing  (pnut v32i)
    =========================
     cogexec
       PC    Op-code  PA-data    Cog-dref Hub-dref LUT-dref
    0000000f fe9fffe0 000ffff0   47ee18aa 00000000 2884fd76
    00000011 fe9003f8 0000040a   fdb008fc 024afe80 f100b25b
    00000013 fe800434 00000434   00000000 33333333 f607ee0a
    00000015 fe900e28 00000e3e   00000000 1d1594ee c607ee31
    
     hubexec
       PC    Op-code  PA-data    Cog-dref Hub-dref LUT-dref
    00000410 fe800008 00000008   11111111 00000000 fa00b7f6
    00000418 fe800110 00000110   fd60062a 22222222 00000000
    00000420 fe900010 00000434   00000000 33333333 f607ee0a
    00000428 fe8003a0 000003a0   2e202e20 00000000 44444444
    
     lutexec
       PC    Op-code  PA-data    Cog-dref Hub-dref LUT-dref
    00000280 fe9ff61c 000ff89d   00000000 59545544 00000000
    00000282 fe9ffa34 000ffcb7   00000000 223a81d7 00000000
    00000284 fe800434 00000434   00000000 33333333 f607ee0a
    00000286 fe900464 000006eb   00000000 3d20736e 00000000
    
  • jmgjmg Posts: 15,140
    evanh wrote: »
    Yep, that matches fastspin result.
    ...
    Here's pnut:

    So that means p2asm and fastspin are now considered 'correct' and pnut is still to be fixed ?

  • evanhevanh Posts: 15,126
    edited 2019-04-13 05:32
    Yes, in terms of LOC now works in all cases.

    Although I think LOC and all branch long-immediates could all be encoded to PC-relative in all #label and #@label cases. Absolute encoding of those instructions doesn't seem to have a specific purpose. Ah, absolute does have a purpose when an actual piece of PIC wants a hard coded specific address. Won't be common I don't think.
  • evanh wrote: »
    Although I think LOC and all branch long-immediates could all be encoded to PC-relative in all #label and #@label cases.
    LOC probably could, in theory, be encoded relative in all cases. But branches are handled differently from LOC and if I recall correctly doing a relative branch that crosses HUB/COG/LUT domains is forbidden by the hardware. (There's internal state about how PCs are handled in relative branches, and I wouldn't want to mess with that.)

  • Cluso99Cluso99 Posts: 18,066
    There are times when LOC should be absolute and not relative. Examples are using hub tables, and we will probably have some fixed areas for mailboxes.
    I would rather always declare absolute or relative. The programmer should have the right to use what they require.
  • evanhevanh Posts: 15,126
    ersmith wrote: »
    evanh wrote: »
    Although I think LOC and all branch long-immediates could all be encoded to PC-relative in all #label and #@label cases.
    LOC probably could, in theory, be encoded relative in all cases. But branches are handled differently from LOC and if I recall correctly doing a relative branch that crosses HUB/COG/LUT domains is forbidden by the hardware. (There's internal state about how PCs are handled in relative branches, and I wouldn't want to mess with that.)
    Challenge accepted and met! :) I replaced
    		jmp	#loctesthub
    
    at the end of my cogram code, cogram address $17, with
    		long	$fd900fa0
    
    This successfully jumps to hub address $400 ($1000 at byte scale) and runs the second part of the LOC test code placed there. Calculated as offset = $400 * 4 - ($17 + 1) * 4

    It has some peculiar effect on the effective memory map. Still have to get my head around the implication ...
  • evanhevanh Posts: 15,126
    edited 2019-04-13 13:26
    Or you could write it as offset = ($400 - $17 - 1) * 4

    EDIT: New version
     		long	$fd900000 + (($400-$-1)*4)&$fffff
    

    EDIT: And to relative jump to cogexec from hubexec
    		long	$fd900000 + (9-$-4)&$fffff
    
    Cog address 9 is start of my LOC testing code.
  • evanhevanh Posts: 15,126
    Cluso99 wrote: »
    I would rather always declare absolute or relative. The programmer should have the right to use what they require.
    #\ is always there for forcing absolute.
Sign In or Register to comment.