sign extension break sleb128 tests on m68k

Alan Modra amodra@bigpond.net.au
Mon Mar 7 23:52:00 GMT 2005


On Mon, Mar 07, 2005 at 11:01:07AM -0800, James E Wilson wrote:
> On Mon, 2005-02-28 at 20:25, Alan Modra wrote:
> > When building with a 64-bit bfd, sleb128 and quad tests fail on m68k
> > targets, because something like
> >  .sleb128 0x80000000
> > has the constant sign extendend due to a peculiarity of m68k gas (grep
> > for TARGET_WORD_SIZE) as if you'd written
> >  .sleb128 0xffffffff80000000

[snip]
> One of the problems is that the h8300 gas port uses internal masks like
> 0xffffff00 which is intended to be -256.  That works fine on a 32-bit
> host, but not on a 64-bit host, where this is a large positive number
> instead of a small negative one.
> 
> The other related problem is that the testsuite contains similar
> numbers.  See for instance the file h8sx_mov_insn.s in the
> gas/testsuite/gas/h8300 directory.  It contains
>         mov.b   #foo,@0xffff8000
> which is supposed to be assembled into a 16-bit immediate field, but on
> a 64-bit host that is a large positive number which requires a 32-bit
> immediate field.  This causes the test to fail.

Which indicates another problem in the h8300 gas code.  I think this
constant ought to be assembled the same regardless of the host.  Take a
look at what tc-i386.c does for similar situations:

	    /* If this operand is at most 16 bits, convert it
	       to a signed 16 bit number before trying to see
	       whether it will fit in an even smaller size.
	       This allows a 16-bit operand such as $0xffe0 to
	       be recognised as within Imm8S range.  */
	    if ((i.types[op] & Imm16)
		&& (i.op[op].imms->X_add_number & ~(offsetT) 0xffff) == 0)
	      {
		i.op[op].imms->X_add_number =
		  (((i.op[op].imms->X_add_number & 0xffff) ^ 0x8000) - 0x8000);
	      }
	    if ((i.types[op] & Imm32)
		&& ((i.op[op].imms->X_add_number & ~(((offsetT) 2 << 31) - 1))
		    == 0))
	      {
		i.op[op].imms->X_add_number = ((i.op[op].imms->X_add_number
						^ ((offsetT) 1 << 31))
					       - ((offsetT) 1 << 31));
	      }
	    i.types[op] |= smallest_imm_type (i.op[op].imms->X_add_number);


> Perhaps something similar happened with the m68k port.  The problem
[snip example]

Thanks for bringing this to light.  I've opened a bugzilla report.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list