Part Number: MSP430-GCC-OPENSOURCE
Hi,
some register constraints do not work as documented at https://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html
Consider the following example:
static uint16_t swapvals[8];
uint8_t some_function(int index, uint8_t value)
{
__asm__ __volatile__
(
"mov.b %[val], 1(%[dst])\n"
"swpb 0(%[dst])\n"
"mov.b 1(%[dst]), %[val]\n"
: [val] "+g" (value), [dst] "+o" (swapvals[index])
);
return value;
}
This function is supposed to implement an interrupt-safe method to read and change an 8 bit value atomically. First, Parameter "value" is written to the high byte of swapvals[index], afterwards the swap is performed on the memory Operand. The new value is now in effect in the low byte, while the old remains stored in the high Byte and can be retrieved.
This is why I chose "+o" as Output Operand constraint which according to GCC doc is:
‘o’ A memory operand is allowed, but only if the address is offsettable. This means that adding a small integer (actually, the width in bytes of the Operand, as determined by its machine mode) may be added to the address and the result is also a valid memory address. For example, an address which is constant is offsettable; so is an address that is the sum of a Register and a constant (as long as a slightly larger constant is also within the range of address-offsets supported by the machine); but an autoincrement or autodecrement address is not offsettable. More complicated indirect/indexed addresses may or may not be offsettable depending on the other addressing modes that the machine supports.
However, on -O0 this generates the following (Code by which gcc loads R13 with the value of &swapvals[index] has been omitted):
mov.b R12, 1(@R13) swpb 0(@R13) mov.b 1(@R13), R12
On -O3 it gets even weirder:
mov.b R12, 1(swapvals(R13)) swpb 0(swapvals(R13)) mov.b 1(swapvals(R13)), R12
wth??
@ addressing mode is clearly not offsettable, not mentioning the fact that a Destination operand does not support @ addressing mode anyway.
But what I wanted was:
mov.b R12, 1(R13) swpb 0(R13) mov.b 1(R13), R12
Now I realize, the Definition for 'o' constraint would also allow for & addressing mode.. had I used swapvals[0] as Input Operand, it would have generated this:
mov.b R12, 1(&swapvals) swpb 0(&swapvals) mov.b 1(&swapvals), R12
So currently, the only way to achieve what I want is using a pointer as pure Input Operand with These constraints:
: [val] "+g" (value) : [dst] "r" (&swapvals[index])
However, gcc does not notice then that swapvals[index] is clobbered and having to add a "memory" clobber seems excessive to me.
Is there any reason, why we cannot introduce machine-specific constraint characters so one has direct control over the addressing mode that is used for each Input Operand?