Loading an address in MIPS64

后端 未结 2 1607
不知归路
不知归路 2020-12-19 06:26

This is probably a simple, obvious thing I\'m just not seeing, but how do I load an address in a MIPS64 processor? In a MIPS32 processor the following assembler pseudo-inst

相关标签:
2条回答
  • 2020-12-19 07:02

    address so it leaves me convinced that I've overlooked something. What is it I've overlooked (if anything)?

    What you are missing is that even in Mips64 the instruction size stays 32bit (4bytes). In this 32bit machine code encoding system, The 'la' translated to 'lui' + 'ori' combination can handle a max of 32 bit value (address). There are not enough bits in the 4byte machine instruction to easily encode a 64bit address. To deal with 64bit address, more iterations of the same (lui+ori) is used along with shifts (dsll).

    Paxym

    0 讨论(0)
  • 2020-12-19 07:05

    I think if you need to load a lot of constants, you should put it in a constant pool (A.K.A "literal pool") near the current code and then load it by an ld instruction.

    For example: $s0 contains the pool's base address, and the constant you want to load is at offset 48, you can load it to $t1 by the instruction ld $t1, 48($s0)

    This technique is very common in ARM, where instructions could only load a 12-bit immediate (only later versions of ARM can load 16-bit immediates with some restrictions). And it is used in Java too.

    However somehow MIPS compilers still always generate multiple instructions to load a 64-bit immediate. For example to load 0xfedcba0987654321 on MIPS gcc uses

        li      $2,-9568256       # 0xffffffffff6e0000
        daddiu  $2,$2,23813
        dsll    $2,$2,17
        daddiu  $2,$2,-30875
        dsll    $2,$2,16
        daddiu  $2,$2,17185
    

    Many other RISC architectures have more efficient ways to load an immediate so they need less instructions, but still at least 4. Maybe the instruction cache cost is lower than data cache cost in those cases, or maybe someone just don't like that idea

    Here's an example of handwritten constant pool on MIPS

    # load pool base address
        dla $s0, pool
    foo:
    # just some placeholder
        addu $t0, $t0, $t1
    bar:
    # load from pool
        ld $a0, pool_foo($s0)
        ld $a1, pool_bar($s0)
    
    .section pool
    # macro helper to define a pool entry
    .macro ENTRY label
    pool_entry_\label\(): .quad \label
    .equ pool_\label\(), pool_entry_\label - pool
    .endm
    ENTRY foo
    ENTRY bar
    

    I failed to persuade any MIPS compilers to emit a literal pool but here's a compiler-generated example on ARM

    0 讨论(0)
提交回复
热议问题