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

Reply via email to