1
votes

I've been reading into the MIPS instruction set lately when I came across two unusual instructions that I've not seen in other instruction sets.

I've looked around to find a decent explanation of what exactly the instructions do, but all I've been able to figure out is that they're somehow related unaligned memory access.

For example, Wikipedia says:

MIPS I requires all memory accesses to be aligned to their natural word boundaries, otherwise an exception is signaled. To support efficient unaligned memory accesses, there are load/store word instructions suffixed by "left" or "right".

But does not elaborate further on what this actually means.

The closest I've been able to find to a proper explanation is from Dr John Lumis's website:

Unaligned words and doublewords can be loaded or stored in just two instructions by using a pair of special instructions. For loads a LWL instruction is paired with a LWR instruction. The load instructions read the left-side or right-side bytes (left or right side of register) from an aligned word and merge them into the correct bytes of the destination register.

But this still seems like only half the story to me and I'm having a hard time figuring out the exact details. I.e. I'm struggling to understand which bytes from which addresses would be moved where.

So what exactly do these instructions do?

1

1 Answers

3
votes

The explanation should be available in any MIPS manual: LWR will load the right portion (least significant part) of the value and LWL will load the left part

Basically for an address A LWL will load 4 - A % 4 bytes to the left of the register and LWR will load the remaining A % 4 bytes to the right of it. For example if A = 1 like in the below table

        ├ A             ┤
... ┃ 0 ┆ 1 ┆ 2 ┆ 3 ┃ 4 ┆ 5 ┆ 6 ┆ 7 ┃ ...

then the first word contains 3 bytes of the value we need, thus LWL will load 3 bytes at address { 1, 2, 3 } to the register and then the remaining byte will be loaded with LWR

In fact the first result on Google for the search term "MIPS LWL LWR" gives me the below demonstration

  • lwr $4, 2($0) # this is a dummy instruction that starts a byte 2 wants to read the 32-bit word starting at that location.

                Memory                                Register 4
                byte 0, byte 1, byte 2, byte 3        byte 0, byte 1, byte 2, byte 3
    address 4:  4       5       6       7             A       B       C       D       before 
    address 0:  0       1       2       3             A       0       1       2       after
    
  • lwl $4, 2($0) # this is a dummy instruction that starts a byte 2 wants to read the 32-bit word starting at that location.

                Memory                                Register 4
                byte 0, byte 1, byte 2, byte 3        byte 0, byte 1, byte 2, byte 3
    address 4:  4       5       6       7             A       B       C       D       before 
    address 0:  0       1       2       3             2       3       C       D       after
    

http://db.cs.duke.edu/courses/fall02/cps104/homework/lwswlr.html


Put it simply:

You give the “load word left” instruction the effective address of the most significant byte of the unaligned word you want to load, and it picks out the correct bytes from the enclosing word and merges them into the upper bytes of the destination register.

The “load word right” works analogously: You give it the effective address of the least significant byte of the unaligned word you want to load, and it picks out the correct bytes from the enclosing word and merges them into the lower bytes of the destination register.

The MIPS R4000, part 6: Memory access (unaligned)


Here's the details in the MIPS32 instruction set manual

LWL

LWR


Another illustration from MIPS IV ISA

LWL and LWR

See also

From MIPS Release 6 and up loads and stores are required to support unaligned access, so LWL/LWR/SWL/SWR were removed