Pseudoinstructions and Branches

Introduction

As you look through the branch instructions, you see beq and bne, but not bge (branch on greater than or equal), bgt (branch on greater than), ble (branch on less than or equal), blt (branch on less than). There are no branch instructions for relational operators!

Why not?

The answer lies in the way the MIPS folks designed the ISA. They decided that instructions could stay in the ISA if there was a noticeable improvement in the speed using benchmarks, otherwise, if it could be written using two or more instructions, without noticeable delay (because they weren't used too often), then those instructions weren't made part of the ISA.

This is a completely different strategy of designing ISAs compared to CISC ISAs. For CISC ISAs, the thinking was to add instructions to make it easier to write compilers. The thought of making the machine run faster was not the first one to come to mind. Only in the early 1980's did some researchers (notably, Hennessy and Patterson) begin to think that complex instructions were not better. Not surprisingly, this coincided with memory becoming cheaper and cheaper. When that happened, processors could be designed differently to take advantage of this economic fact. RISC owes as much of its success to the economics of memory as to any technological advantage it may have over CISC.

Assemblers allow programmers to use pseudo-instructions like blt, which it then translates to two or more instructions. Usually, the translations are simple. If you want sophisticated translations, you program in a high-level language.

slt, slti, sltu, sltiu

To translate these instructions, we'll primarily use slt (set on less than). However, there are three other related instructions. Here's a brief summary:

slt  $rd, $rs, $rt      # R[d] = R[s] < R[t] ? 030::1 : 032
sltu $rd, $rs, $rt      # R[d] = R[s] < R[t] ? 030::1 : 032
slt  $rt, $rs, immed    # R[d] = R[s] < immed ? 030::1 : 032
sltu $rt, $rs, immed    # R[d] = R[s] < immed ? 030::1 : 032
Notice I'm using the conditional expression (question-mark/colon operator) in C to explain the semantics.

Here are the differences between all the instructions.

As you might guess, slt and sltu are R-type instructions, while slti and sltiu are I-type instructions.

Translated Pseudoinstructions

Here's the table for translating pseudoinstructions.

Pseudoinstruction Translation
bge $rt, $rs, LABEL slt $t0, $rt, $rs
beq $t0, $zero, LABEL
bgt $rt, $rs, LABEL slt $t0, $rs, $rt
bne $t0, $zero, LABEL
ble $rt, $rs, LABEL slt $t0, $rs, $rt
beq $t0, $zero, LABEL
blt $rt, $rs, LABEL slt $t0, $rt, $rs
bne $t0, $zero, LABEL

where we assume $t0 is not $rs, nor $rt (if it is, pick another register that's being unused), and $zero is $r0.

Machine Code Representation

Instruction B31-26 B25-21 B20-16 B15-11 B10-6 B5-0
  opcode register s register t register d shift amount function
slt $rd, $rs, $rt 000 000 (SPECIAL) - - - 00000 101 010
sltu $rd, $rs, $rt 000 000 (SPECIAL) - - - 00000 101 011

The dashes are 5-bit encoding of the register number in UB. For example, $r7 is encoded as 00111.

Instruction B31-26 B25-21 B20-16                 B15-0                
  opcode register s register t immediate
slti $rt, $rs, <immed> 001 010 - - -
sltiu $rt, $rs, <immed> 001 011 - - -

Summary

It's useful to know how translate branches for relational operators because they aren't supported directly in the MIPS ISA. Instead, they are pseudo-instructions, which are translated to slt and a branch instruction.

Web Accessibility