# The SuperH-3, part 4: Basic arithmetic

Raymond

Okay, we’re ready to do some arithmetic. Due to the limited instruction encoding space, there isn’t room for any three-operand instructions.¹ All of the arithmetic instructions are two-operand, where the second source operand also acts as the destination.

```    ADD     Rm, Rn      ; Rn += Rm    , no effect on T
ADD     #imm, Rn    ; Rn += imm   , no effect on T
ADDC    Rm, Rn      ; Rn += Rm + T, T receives carry
ADDV    Rm, Rn      ; Rn += Rm    , T receives signed overflow
```

The `ADD` instructions add two values and put the result in the second register. You can add two registers together, or you can add a signed 8-bit immediate to the destination register.

The `ADDC` instruction treats the T flag as a carry flag: It is added to the sum, and it receives the carry of the result.

The `ADDV` instruction treats the T flag as an overflow flag: It reports whether a signed overflow occurred.

Okay, subtraction is going to look really similar now.

```    SUB     Rm, Rn      ; Rn -= Rm    , no effect on T
SUB     #imm, Rn    ; Rn -= imm   , no effect on T
SUBC    Rm, Rn      ; Rn -= Rm + T, T receives borrow
SUBV    Rm, Rn      ; Rn -= Rm    , T receives signed underflow
```

Basically the same as addition, except you’re now subtracting. The SH-3 treats T as a borrow flag in the case of `SUBC`, whereas for `SUBV` it reports whether a signed underflow occurred.

Arithmetic negation is up next.

```    NEG     Rm, Rn      ; Rn = -Rm    , no effect on T
NEGC    Rm, Rn      ; Rn = -Rm - T, T receives borrow
```

There is no `NEGV`, but overflow occurs only if the value is `0x80000000`, so I guess you could test for that value specifically.

There is a special instruction for for decrementing a register:

```    DT      Rn          ; Rn = Rn - 1, T  = (Rn == 0)
```

The decrement and test instruction decrements a register and compares the result against zero. This is presumably for counted loops.

Next come the comparison instructions.

```    CMP/EQ #imm, r0     ; T = (r0 == signed 8-bit immediate)
CMP/EQ Rm, Rn       ; T = (Rn == Rm)
CMP/HS Rm, Rn       ; T = (Rn ≥ Rm), unsigned comparison
CMP/GE Rm, Rn       ; T = (Rn ≥ Rm),   signed comparison
CMP/HI Rm, Rn       ; T = (Rn > Rm), unsigned comparison
CMP/GT Rm, Rn       ; T = (Rn > Rm),   signed comparison
CMP/PZ Rn           ; T = (Rn ≥ 0),    signed comparison
CMP/PL Rn           ; T = (Rn > 0),    signed comparison
CMP/STR Rm, Rn      ; T = 1 iff any corresponding bytes are equal
```

These instructions set the T flag according to a particular comparison. Note that the comparison is backward! For example, `CMP/GE r1, r2` does not check whether r1 ≥ r2; rather, it checks whether r2 ≥ r1. This takes a lot of getting used to.

You have the special ability to compare r0 for equality with a signed 8-bit immediate. Otherwise, you can compare two registers against each other, or a register against zero.

The special `CMP/STR` compares two registers to determine whether any of the four component bytes are equal. It’s clear from the mnemonic that the intended purpose is to search for a null terminator in a string. You set Rn to zero and then do a `CMP/STR` against every longword in the string until it says, “Hey, I found a zero byte!” and then you can study that longword to see where the zero byte is.

The processor documentation doesn’t explain why they chose the names for the mnemonics, but I can guess.

ConditionMeaning
`EQ`equal
`HS`high or same
`GE`greater or equal
`HI`high
`GT`greater than
`PZ`plus or zero
`PL`plus
`STR`string

It took me a while to come up with a plausible explanation for `HS`.

Exercise 1: Synthesize the `SETT` and `CLRT` instructions.

Exercise 2: Perform the opposite of the `MOVT` instruction: Set the T register to 0 if a register is zero, or 1 if the register is nonzero.

The last arithmetic instructions are the extension instructions.

```    EXTS.B Rm, Rn       ; sign extend byte in Rm to Rn
EXTS.W Rm, Rn       ; sign extend word in Rm to Rn
EXTU.B Rm, Rn       ; zero extend byte in Rm to Rn
EXTU.W Rm, Rn       ; zero extend word in Rm to Rn
```

That’s it for the basic arithmetic instructions. We’ll start looking at the more complicated arithmetic instructions next time, starting with multiplication.

¹ Well, okay, you can have three-operand instructions if some of them are hard-coded! But that’s not what I mean. I mean three-operand instructions where the programmer can choose all three of the operands.