Storing values ​​in the HI and LO MIPS register

I write certain code in MIPS, and I came to the conclusion that the requirement is to temporarily store the result in HI and LO special registers (both have a width of 4 bytes). These instructions are at my disposal:

 divu s,t lo <-- s div t ; hi <-- s mod t multu s,t hi / lo < -- s * t ; 

So, divu stores the result of division in LO and the remainder in HI , and multu stores the result of multiplication in LO (below 4 bytes) and HI (higher 4 bytes).

Later, to get the result from the HI and LO registers, I can:

 mfhi $v0 mflo $v1 

I already understood how to save the calculation result in LO :

 ori $v0,$0,1 # Store result from $a0 into LO divu $a0,$v0 
  • divu stores the division result in LO, so I just divide the result by 1 to get it there.

However, storing in HI more complicated. One way would be to force the multu command multu shift the value by 32 bits (4 bytes):

 multu $a0,0x80000000 # Shift $a0 by 32 bits and store into HI/LO 

But the result is that the value in HI is 1 bit to the right of where it should be (so if my value is 0100 1000 , then HI will contain 0010 0100 ).

Does anyone know how to store something in the HI register?

+4
source share
3 answers

I want to extend the Nils Pipenbrinck answer:

From the arsenal of MIPS32 for programmers

mthi

Format: MIPS32 (MIPS I)

  MTHI rs 

Purpose: To copy GPR to the special purpose HI register

 Description: HI ← rs 

The contents of the GPR rs are loaded into a special HI register.

Limitations:

A calculated result written to an HI / LO pair using DIV, DIVU, MULT or MULTU must be read by MFHI or MFLO before a new result can be written to HI or LO. If the MTHI instruction is executed on one of these arithmetic instructions, but before the MFLO or MFHI instructions, the contents of LO are impractical. The following example shows this illegal situation:

  MUL r2,r4 # start operation that will eventually write to HI,LO ... # code not containing mfhi or mflo MTHI r6 ... # code not containing mflo # this mflo would get an UNPREDICTABLE value MFLO r3 

Historical Information:

In MIPS I-III, if one of the two previous instructions is MFHI, the result of this MFHI is CONTINUOUS. The reading of the HI or LO special register should be separated from any subsequent instructions that are written to them by two or more instructions. In MIPS IV and later, including MIPS32 and MIPS64, this restriction does not exist.

mtlo

Format: MIPS32 (MIPS I)

  MTLO rs 

Purpose: To copy the GPR to the special register LO Description:

  LO ← rs 

The contents of the GPR rs are loaded into a special register LO.

Restrictions: A calculated result written to an HI / LO pair using DIV, DIVU, MULT or MULTU must be read by MFHI or MFLO before a new result can be written to HI or LO.

If the MTLO instruction is executed on one of these arithmetic instructions, but before the MFLO or MFHI instruction, the contents of the HI are CONTINUOUS. The following example shows this illegal situation:

  MUL r2,r4 # start operation that will eventually write to HI,LO ... # code not containing mfhi or mflo MTLO r6 ... # code not containing mfhi # this mfhi would get an UNPREDICTABLE value MFHI r3 

Historical Information:

In MIPS I-III, if one of the two previous instructions is MFHI, the result of this MFHI is CONTINUOUS. The reading of the HI or LO special register should be separated from any subsequent instructions that are written to them by two or more instructions. In MIPS IV and later, including MIPS32 and MIPS64, this restriction does not exist.

+7
source

The MIPS instruction set has an analogue MFLO / MFHI.

It is called MTLO / MTHI and does exactly what you want:

  mtlo $v0 # moves the contents of v0 into the lo-register mthi $v1 # moves the contents of v1 into the hi-register 

These instructions are rare and often not presented in generalized references to a set of instructions.

Btw: Be sure to check the processor manual for delays and dangers associated with the LO / HI registries. They are very special, and your code can have things like waiting for at least three cycles between writing and reading. Unfortunately, it depends on which processor you are running on.

How to make a mistake, this is a common mistake for beginning MIPS programmers :-)

+6
source

Think about what other extreme values ​​might produce interesting results when used as the second argument to multu / divu (I'm intentionally vague because it looks like a homework question).

+1
source

All Articles