On Wed, Oct 14, 2009 at 13:57, JMGross <[email protected]> wrote:
> I'd say it is not a compiler bug but a programmer bug.
>
> return (adc12ctl0_t) ADC12CTL0;
>
> should do better. And should be much faster. But fails due to the
> incompatible type of data (non-scalar struct and scalar word value). This is
> also the reason why the compiler does not use a word instruction for
> constructing the result: the target is not a scalar type. And it has been
> packed, so it cannot be assumed word-aligned at all. The compiler does not
> know that in this special case it could just transfer a source word to
> a target word-size structure. It just assembles the target, and it does so
> (unoptimized) field by field, using the source only byte-wise. even after
> optimisation, when the optimisation algorithm discovers that the bit-wise
> assembly is unnecessary, the byte-wise source access still remains, as the
> optimisation does not know that it could be put together again. It does not
> even know for sure whether the target is word-aligned. Only the
> linker can tell.
As John has said, something has changed recently to trigger this. With
a mspgcc build from 03/2008 the assembler looks fine:
mov &0x01A0, r15
But I agree on the alignment.The adc12ctl0_t in the mspgcc adc12.h
header file should be explicitly word aligned like this:
typedef struct {
volatile unsigned
adc12sc:1,
enc:1,
adc12tovie:1,
adc12ovie:1,
adc12on:1,
refon:1,
r2_5v:1,
msc:1,
sht0:4,
sht1:4;
volatile unsigned int : 0;
} __attribute__ ((packed)) adc12ctl0_t;
Independent from this, from the point of view of TinyOS, the access of
the ADC registers should be wrapped in the standard DEFINE_UNION_CAST
macro just like the timer and the usart drivers
#define DEFINE_UNION_CAST(func_name,to_type,from_type) \
to_type func_name(from_type x) @safe() { union {from_type f; to_type
t;} c = {f:x}; return c.t; }
i.e.
async command adc12ctl0_t HplAdc12.getCtl0(){
return *((adc12ctl0_t*) &ADC12CTL0);
}
should be converted to:
DEFINE_UNION_CAST(adc12ctl2int,uint16_t,adc12ctl0_t)
async command adc12ctl0_t HplAdc12.getCtl0(){
return adc12ctl2int(ADC12CTL0);
}
Vlado