This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: arm-elf-as truncates branch offsets w/o warning
- To: Nick Clifton <nickc at cygnus dot com>
- Subject: Re: arm-elf-as truncates branch offsets w/o warning
- From: Alan Modra <alan at SPRI dot Levels dot UniSA dot Edu dot Au>
- Date: Sat, 18 Mar 2000 09:49:33 +1030 (CST)
- cc: grante at visi dot com, scottb at netwinder dot org, binutils at sourceware dot cygnus dot com
On Fri, 17 Mar 2000, Nick Clifton wrote:
> : > + /* Sign-extend a 24-bit number. */
> : > + #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
> : > +
> : That looks wrong. Don't you mean
> : #define SEXT24(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000)
>
> No, the plus and the inversion are right.
You're right, of course. My faulty inbuilt APU said ~0x7fffff == 0x800000.
Here's an interesting bit of gcc trivia I discovered recently. All of
the following functions are logically equivalent (Nick's sign extension
scheme is f2, mine is f1). Current x86 gcc -O2 recognises f1, f2, and f4,
and generates a single instruction "movswl" for the expression, but f3
misses the optimisation.
int f1(int n)
{
return ((n & 0xffff) ^ 0x8000) - 0x8000;
}
int f2(int n)
{
return ((n & 0xffff) ^ -0x8000) + 0x8000;
}
int f3(int n)
{
return ((n & 0xffff) - 0x8000) ^ -0x8000;
}
int f4(int n)
{
return n << 16 >> 16; /* works only if you know "int" to be 32 bits */
}