Found in some versions such as the MSP430F1611
C compilers do not necessarily do a good job of using it. Below is an example using pure C vs the multiplier accumulator equivalent.
typedef unsigned short UINT16; ///< unsigned 16-bit
typedef unsigned long UINT32; ///< unsigned 32-bit
UINT32 u32Answer;
UINT16 uX,uY,uZ;
uX = 10;
uY = 2;
uZ = 40000;
The line below translates to lots of code (even with the "use multiplier"
option checked in the compiller):
u32Answer = (UINT32)uX*3 + (UINT32)uY*4 + (UINT32)uZ*5 + (UINT32)uX*6;
Efficientcy by using multiply accumulate:
*(INT32 *)RESLO_ = 0L; // Clear accumulator
MAC = 3;
OP2 = uX;
MAC = 4;
OP2 = uY;
MAC = 5;
OP2 = uZ;
MAC = 6;
OP2 = uX;
NOP();
u32Answer = *(INT32 *)RESLO_;
Code in CPU looks like:
94 *(INT32 *)RESLO_ = 0L;
\ 000072 82433a01 MOV.W #0x0, &0x13a
\ 000076 82433c01 MOV.W #0x0, &0x13c
95 MAC = 3;
\ 00007A B24003003401 MOV.W #0x3, &0x134
96 OP2 = uX;
\ 000080 824E3801 MOV.W R14, &0x138
97 MAC = 4;
\ 000084 A2423401 MOV.W #0x4, &0x134
98 OP2 = uY;
\ 000088 824C3801 MOV.W R12, &0x138
99 MAC = 5;
\ 00008C B24005003401 MOV.W #0x5, &0x134
100 OP2 = uZ;
\ 000092 824F3801 MOV.W R15, &0x138
101 MAC = 6;
\ 000096 B24006003401 MOV.W #0x6, &0x134
102 OP2 = uX;
\ 00009C 824E3801 MOV.W R14, &0x138
103 NOP();
\ 0000A0 0343 NOP
104 u32Answer = *(INT32 *)RESLO_;
\ 0000A2 92423A01.... MOV.W &0x13a, &u32Answer
\ 0000A8 92423C01.... MOV.W &0x13c, &u32Answer + 2
See also: