Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In MIPS, when to use a signed-extend, when to use a zero-extend?

I am designing a MIPS processor as my individual project, by now I met a very confused question. I just can not summarize when to use signed-extend and when to use zero-extend in MIPS.

I have searched lots of resources, mostly said:

1) ADDI, ADDIU are both use signed-extend.
2) ANDI, ORI, XORI both use zero-extend.

However, In those two instruction, I am start getting confused:

SLTIU/SLTI

In the Imagination's "MIPS Architecture for Programmers Volume II-A: The MIPS instruction set Manual" page 368 says: Picture 1

It clearly mentioned the 16-bit immediate is signed-extend.But I don't understand the following statement:

[0, 32767] or maximum [max_unsigned-32767, max_unsigned] end of the unsigned range.

and some other people say the 16-bit immediate is zero-extend, like this:

http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/pseudojump.html

Well, can some one explain what exactly differences between the signed instruction and unsigned instruction in MIPS?

like image 861
Shuaiyu Jiang Avatar asked Mar 26 '15 16:03

Shuaiyu Jiang


2 Answers

I'm not sure if the two descriptions that you are showing behave exactly the same. They seem to be different implementations.

The implementation of Imagination's MIPS as it appears in their document is as follows (in SystemVerilog syntax, assuming GPR regsiters are 32 bits):

if ({1'b0 , GPR[rs]} < {1'b0 , sign_extend(immediate)} 
   GPR[rd] = 32'h00000001;
else
   GPR[rd] = 32'h00000000;

Notice that this is a 33 bit comparison where the 33rd bit is 0, hence an unsigned comparison.

Also, notice that:

sign_extend(immediate) returns: { {16{immediate[15]}}, immediate }

This means immediate is first treated as a signed number, i.e., a 15 bit value and the 16th bit is the sign. Therefore:

If immediate >=0, then sign_extend(immediate) is in [0,32767]. 

On the other hand if immediate is a negative number, we will have:

sign_extend(immediate)  = { {16{1'b1}}, 1'b1, immediate[15:0] }, which is in [32'hFFFFFFFF-32767, 32'hFFFFFFFF]

where 32'hFFFFFFFF is called max_unsigned.

Basically this instruction enables you to perform an unsigned comparison between GPR[rs] and an unsigned number either in [0,32767] or [32'hFFFFFFFF-32767, 32'hFFFFFFFF].

The second implementation performs an unsigned comparison between GPR[rs] and [0,65535].

EDIT:

Note that in SLTI and SLTIU the immediate value is sign extended but with different intentions. In SLTIU, the two numbers being compared are forced to be unsinged (by adding the 33rd bit). So the sign extension of immediate enabled a different range of comparison: the 32767 smallest and the 32767 largest unsigned values as opposed to just 0 to 65535. The sign extension was not done for the purposes of signed comparison as one might be confused.

In SLTI however, the sign extension of immediate is done for a different purpose: to compare a negative value to a positive value (signed comparison).

like image 172
Ari Avatar answered Nov 16 '22 23:11

Ari


The docs imply that the instruction first sign-extends the 16-bit immediate, but then performs a 32-bit unsigned comparison. In verilog this should amount to:

if (gpr[rs] < { {16{imm[15]}}, imm })
  gpr[rt] = 1;
else
  gpr[rt] = 0;
like image 21
Guy Avatar answered Nov 16 '22 23:11

Guy