arm-elf-as truncates branch offsets w/o warning

Alan Modra alan@SPRI.Levels.UniSA.Edu.Au
Fri Mar 17 15:16:00 GMT 2000


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 */
}



More information about the Binutils mailing list