|mspgcc: A port of the GNU tools to the Texas Instruments MSP430 microcontrollers|
|<<< Previous||An introduction to the TI MSP430 low-power microcontrollers||Next >>>|
Some MSP430 processors have, as a memory-mapped peripheral, a hardware 16x16->32 multiply/accumulate unit. This is accessed via eight 16-bit registers from 0x0130 to 0x013F.
Writing the first operand specifies the operation type depending on the address used:
0x0130 - MPY unsigned multiply.
0x0132 - MPYS signed multiply.
0x0134 - MAC unsigned multiply-accumulate.
0x0136 - MACS signed multiply-accumulate.
Writing the second operand to 0x0138 starts the operation. The product is available in 0x013A(SumLo), 0x013C(SumHi) and 0x013E(SumExt) with only 2 cycles of latency. Thus, you can fetch the result with the next instruction if it's an indexed or absolute addressing mode.
If you use a register indirect or post-increment mode, you need to insert a nop (or something) between writing the second operand and reading the results.
The accumulator (SumLo and SumHi) is only 32 bits. SumExt is set to the carry (0 or 1) of the 32+32-bit sum in a MAC operation, but the old value of SumExt is not used.
In MPYS and MACS, SumExt is just the sign-extension of SumHi (0 or -1), which is not tremendously useful.
While all registers can be read back, the operation specified by the first operand's address is not recoverable by an interrupt handler. Thus, it is not possible to context-switch the multiplier unless you add some sort of wrapper software (locking or shadow registers) around it.
All registers are read/write except:
The first four are actually aliases for one register, so they always read the same value.
SumExt is not writable.
The multiplier is one 16-bit peripheral where a byte write might make sense. A byte write is zero-extended to 16 bits, which allows 8-bit unsigned operands to be used naturally.
Then x can be written to the first operand register just once.
a + b*x + c*x^2 + d*x^3 = (((d * x + c) * x) + b) * x + a