Multiplication and division
The 68000 has instructions to multiply and divide numbers. They are slow, so you should try to avoid them as much as possible (especially division), but if the usual optimizations don't work and they aren't done too often, you may be fine using them.
Multiplication
There are two multiply instructions on the 68000:
muls.w
(signed multiplication)mulu.w
(unsigned multiplication)
Multiplication is a bit unintuitive: the two operands are 16-bit, but the result is 32-bit. However, this means the result will always fit no matter how large it is.
The destination operand has to be one of d0-d7
. On
the other hand, the source operand can be just about anything except
a0-a7
(e.g. can be also one of d0-d7
, or can
be a immediate number like #123
, or it can come from memory).
All of these are valid:
muls.w d1, d0
muls.w #123, d0
muls.w (MyVar), d0
muls.w (a0)+, d0
Division
As with multiplication, there are two division instructions on the 68000:
divs.w
(signed division)divu.w
(unsigned division)
Division is trickier to use:
- The destination operand is 32-bit
- The source operand is 16-bit
- The quotient is stored in the lower word of the destination
- The remainder is stored in the upper word of the destination
Again, destination has to be d0-d7
, while source can be
just about anything except a0-a7
.
Division often results in a result that isn't integer (i.e. has a fractional part), in this case the quotient is "truncated" (the fractional part is thrown away). Since when this happens the result always gets closer to zero we call it "rounding towards zero".
Dividing by zero will raise an exception, so don't do it. Since the quotient is 16-bit and the result may not fit, you can check if the result is valid by looking at the overflow flag:
divs.w d1, d0
bvs @Error
Or if you want to be sure and avoid the risk of dividing by 0:
tst.w d1
beq @Error
divs.w d1, d0
bvs @Error
Performance
Multiplication and division are slow.
Multiplication can take between 38 and 70 cycles, depending on the source operand. As a tip, how long it takes depends on how many bits are set in the source, so you can stick to smaller numbers to keep the speed of multiplications in check.
Division always takes around 140 cycles (unless the result doesn't fit). There isn't much you can do about this except trying to avoid divisions as much as possible.