Catch some more cases where we can represent a 16 bit immediate operand as
8 bit sign extended.
This commit is contained in:
parent
8d75d12d1b
commit
773f551c1d
|
@ -1,3 +1,18 @@
|
||||||
|
2000-02-26 Alan Modra <alan@spri.levels.unisa.edu.au>
|
||||||
|
|
||||||
|
* config/tc-i386.c (i386_immediate): Move constant operand sizing
|
||||||
|
from here..
|
||||||
|
(md_assemble): To here, before template operands are matched.
|
||||||
|
Also ensure a constant immediate is sign extended when we know the
|
||||||
|
size is at most 16 bits. This is to catch cases like "add
|
||||||
|
$0xffc0,%ax" where we don't know the size, and thus that the
|
||||||
|
immediate can be represented as Imm8S until after parsing the
|
||||||
|
register operand.
|
||||||
|
(i386_displacement): Similarly sign extend 16 bit constant
|
||||||
|
displacements.
|
||||||
|
(md_assemble): Relax 16-bit jump constant range check to suit sign
|
||||||
|
extended displacements.
|
||||||
|
|
||||||
2000-02-26 Andreas Jaeger <aj@suse.de>
|
2000-02-26 Andreas Jaeger <aj@suse.de>
|
||||||
|
|
||||||
* doc/c-mips.texi (MIPS Opts): Fix typo in last patch.
|
* doc/c-mips.texi (MIPS Opts): Fix typo in last patch.
|
||||||
|
|
|
@ -1305,6 +1305,61 @@ md_assemble (line)
|
||||||
i.seg[1] = temp_seg;
|
i.seg[1] = temp_seg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i.imm_operands)
|
||||||
|
{
|
||||||
|
/* Try to ensure constant immediates are represented in the smallest
|
||||||
|
opcode possible. */
|
||||||
|
char guess_suffix = 0;
|
||||||
|
int op;
|
||||||
|
|
||||||
|
if (i.suffix)
|
||||||
|
guess_suffix = i.suffix;
|
||||||
|
else if (i.reg_operands)
|
||||||
|
{
|
||||||
|
/* Figure out a suffix from the last register operand specified.
|
||||||
|
We can't do this properly yet, ie. excluding InOutPortReg,
|
||||||
|
but the following works for instructions with immediates.
|
||||||
|
In any case, we can't set i.suffix yet. */
|
||||||
|
for (op = i.operands; --op >= 0; )
|
||||||
|
if (i.types[op] & Reg)
|
||||||
|
{
|
||||||
|
if (i.types[op] & Reg8)
|
||||||
|
guess_suffix = BYTE_MNEM_SUFFIX;
|
||||||
|
else if (i.types[op] & Reg16)
|
||||||
|
guess_suffix = WORD_MNEM_SUFFIX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (op = i.operands; --op >= 0; )
|
||||||
|
if ((i.types[op] & Imm)
|
||||||
|
&& i.op[op].imms->X_op == O_constant)
|
||||||
|
{
|
||||||
|
/* If a suffix is given, this operand may be shortened. */
|
||||||
|
switch (guess_suffix)
|
||||||
|
{
|
||||||
|
case WORD_MNEM_SUFFIX:
|
||||||
|
i.types[op] |= Imm16;
|
||||||
|
break;
|
||||||
|
case BYTE_MNEM_SUFFIX:
|
||||||
|
i.types[op] |= Imm16 | Imm8 | Imm8S;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
i.types[op] |= smallest_imm_type ((long) i.op[op].imms->X_add_number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
overlap0 = 0;
|
overlap0 = 0;
|
||||||
overlap1 = 0;
|
overlap1 = 0;
|
||||||
overlap2 = 0;
|
overlap2 = 0;
|
||||||
|
@ -2200,7 +2255,9 @@ md_assemble (line)
|
||||||
{
|
{
|
||||||
long n = (long) i.op[1].imms->X_add_number;
|
long n = (long) i.op[1].imms->X_add_number;
|
||||||
|
|
||||||
if (size == 2 && !fits_in_unsigned_word (n))
|
if (size == 2
|
||||||
|
&& !fits_in_unsigned_word (n)
|
||||||
|
&& !fits_in_signed_word (n))
|
||||||
{
|
{
|
||||||
as_bad (_("16-bit jump out of range"));
|
as_bad (_("16-bit jump out of range"));
|
||||||
return;
|
return;
|
||||||
|
@ -2530,20 +2587,7 @@ i386_immediate (imm_start)
|
||||||
int bigimm = Imm32;
|
int bigimm = Imm32;
|
||||||
if (flag_16bit_code ^ (i.prefix[DATA_PREFIX] != 0))
|
if (flag_16bit_code ^ (i.prefix[DATA_PREFIX] != 0))
|
||||||
bigimm = Imm16;
|
bigimm = Imm16;
|
||||||
|
i.types[this_operand] |= bigimm;
|
||||||
i.types[this_operand] |=
|
|
||||||
(bigimm | smallest_imm_type ((long) exp->X_add_number));
|
|
||||||
|
|
||||||
/* If a suffix is given, this operand may be shortened. */
|
|
||||||
switch (i.suffix)
|
|
||||||
{
|
|
||||||
case WORD_MNEM_SUFFIX:
|
|
||||||
i.types[this_operand] |= Imm16;
|
|
||||||
break;
|
|
||||||
case BYTE_MNEM_SUFFIX:
|
|
||||||
i.types[this_operand] |= Imm16 | Imm8 | Imm8S;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
|
#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
|
||||||
else if (
|
else if (
|
||||||
|
@ -2784,6 +2828,14 @@ i386_displacement (disp_start, disp_end)
|
||||||
|
|
||||||
if (exp->X_op == O_constant)
|
if (exp->X_op == O_constant)
|
||||||
{
|
{
|
||||||
|
if (i.types[this_operand] & Disp16)
|
||||||
|
{
|
||||||
|
/* We know this operand is at most 16 bits, so convert to a
|
||||||
|
signed 16 bit number before trying to see whether it will
|
||||||
|
fit in an even smaller size. */
|
||||||
|
exp->X_add_number =
|
||||||
|
(((exp->X_add_number & 0xffff) ^ 0x8000) - 0x8000);
|
||||||
|
}
|
||||||
if (fits_in_signed_byte (exp->X_add_number))
|
if (fits_in_signed_byte (exp->X_add_number))
|
||||||
i.types[this_operand] |= Disp8;
|
i.types[this_operand] |= Disp8;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue