This is the mail archive of the crossgcc@sourceware.cygnus.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more infromation.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: arm-coff-gcc function prologue w/ unsigned short parameter


> 
> We've got both gcc 2.95.2 and egcs 2.91.57 compiling for an arm-coff target,
> and both are exhibiting an identical strange behavior in some cases with
> unsigned short parameters to functions and unsigned short local variables.
> Unfortunately, I can only find one brief code snippet that clearly
> exhibits the problem (others are long and complicated), and it uses inline
> assembly.  But I'll post it anyway, hoping that the inline assembly is
> straightforward enough.  It crops up other places that are pure ANSI C, so
> I don't think the use of assembly is causing the problem.
> 
> pcx09> cat testus2.c
> #include <stdio.h>
> 
> 
> static unsigned short
> swabw(unsigned short x)
> {
>     __asm__("orr %0, %0, %0, lsl #16 ; mov %0, %0, lsr #8" : "+r" (x) );
>     return x & 0xffff;
> }
> 
> 
> void
> testus2(unsigned short x)
> {
>     printf("x = 0x%04x, swabbed = 0x%04x\r\n", x, swabw(x));
> }
> 
> pcx09> 
> 
> 
> The swabw function swaps bytes within a short.  Normally we inline that
> function, but when we don't, we get this output from runs through the
> testus2() function...
> 
> x = 0x1234, swabbed = 0x3412
> x = 0x789a, swabbed = 0x9a78
> x = 0x89ab, swabbed = 0xff89
> 
> In general, the failure mode is that whenever bit 15 is set in the input
> to swabw, the output comes out with bits 15-8 all set regardless of what
> bits 7-0 of the input were.
> 

By declaring x as "unsigned short", you are saying that only the bottom 16 
bits contain meaningful data; but you then try to use all 32 (assuming 
that the top 16 are zero).

What you really need to write for swabw is

static unsigned short
swabw(unsigned short x)
{
    unsigned y = x;
    __asm__("orr %0, %0, %0, lsl #16 ; mov %0, %0, lsr #8" : "+r" (y) );
    return y & 0xffff;
}

This will then ensure that the top bits of 'y' are all zero.

Richard.



------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]