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 $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.
| 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.
| 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 | - | - | - |