* gas/config/tc-i386.c: Fix for immediates and displacements in 16-bit

mode when no insn suffix present, eg. push $0x12345678.  Fix some
compiler warnings.  Disallow immediate jump absolute.
This commit is contained in:
Alan Modra
1999-07-16 11:09:15 +00:00
parent 318da145ed
commit b4cac588ae
2 changed files with 66 additions and 48 deletions

@ -1,3 +1,13 @@
1999-07-16 Alan Modra <alan@spri.levels.unisa.edu.au>
* config/tc-i386.c (intel_float_operand): Add prototype, make static.
(md_assemble): Localize *exp variable to if (fake_zero_displacement)
block. Print a warning if an 8-bit or 16-bit constant
displacement or immediate is truncated on output.
(i386_immediate): Ensure Imm16 is always legal for a 16-bit mode
immediate.
(i386_operand): Disallow immediate jump absolute operand.
1999-07-15 Ian Lance Taylor <ian@zembu.com> 1999-07-15 Ian Lance Taylor <ian@zembu.com>
* configure.in: Bump version number to 2.9.5. * configure.in: Bump version number to 2.9.5.

@ -949,7 +949,10 @@ tc_i386_fix_adjustable(fixP)
#define BFD_RELOC_386_GOTOFF 0 #define BFD_RELOC_386_GOTOFF 0
#endif #endif
int static int
intel_float_operand PARAMS ((char *mnemonic));
static int
intel_float_operand (mnemonic) intel_float_operand (mnemonic)
char *mnemonic; char *mnemonic;
{ {
@ -1245,7 +1248,6 @@ md_assemble (line)
{ {
register unsigned int overlap0, overlap1; register unsigned int overlap0, overlap1;
expressionS *exp;
unsigned int overlap2; unsigned int overlap2;
unsigned int found_reverse_match; unsigned int found_reverse_match;
int suffix_check; int suffix_check;
@ -1969,6 +1971,8 @@ md_assemble (line)
{ {
/* Fakes a zero displacement assuming that i.types[op] /* Fakes a zero displacement assuming that i.types[op]
holds the correct displacement size. */ holds the correct displacement size. */
expressionS *exp;
exp = &disp_expressions[i.disp_operands++]; exp = &disp_expressions[i.disp_operands++];
i.disps[op] = exp; i.disps[op] = exp;
exp->X_op = O_constant; exp->X_op = O_constant;
@ -2359,30 +2363,28 @@ md_assemble (line)
{ {
if (i.disps[n]->X_op == O_constant) if (i.disps[n]->X_op == O_constant)
{ {
if (i.types[n] & Disp8) int size = 4;
long val = (long) i.disps[n]->X_add_number;
if (i.types[n] & (Disp8 | Disp16))
{ {
insn_size += 1; long mask;
p = frag_more (1);
md_number_to_chars (p, size = 2;
(valueT) i.disps[n]->X_add_number, mask = ~ (long) 0xffff;
1); if (i.types[n] & Disp8)
} {
else if (i.types[n] & Disp16) size = 1;
{ mask = ~ (long) 0xff;
insn_size += 2; }
p = frag_more (2);
md_number_to_chars (p, if ((val & mask) != 0 && (val & mask) != mask)
(valueT) i.disps[n]->X_add_number, as_warn (_("%ld shortened to %ld"),
2); val, val & ~mask);
}
else
{ /* Disp32 */
insn_size += 4;
p = frag_more (4);
md_number_to_chars (p,
(valueT) i.disps[n]->X_add_number,
4);
} }
insn_size += size;
p = frag_more (size);
md_number_to_chars (p, (valueT) val, size);
} }
else if (i.types[n] & Disp32) else if (i.types[n] & Disp32)
{ {
@ -2415,30 +2417,27 @@ md_assemble (line)
{ {
if (i.imms[n]->X_op == O_constant) if (i.imms[n]->X_op == O_constant)
{ {
if (i.types[n] & (Imm8 | Imm8S)) int size = 4;
long val = (long) i.imms[n]->X_add_number;
if (i.types[n] & (Imm8 | Imm8S | Imm16))
{ {
insn_size += 1; long mask;
p = frag_more (1);
md_number_to_chars (p, size = 2;
(valueT) i.imms[n]->X_add_number, mask = ~ (long) 0xffff;
1); if (i.types[n] & (Imm8 | Imm8S))
} {
else if (i.types[n] & Imm16) size = 1;
{ mask = ~ (long) 0xff;
insn_size += 2; }
p = frag_more (2); if ((val & mask) != 0 && (val & mask) != mask)
md_number_to_chars (p, as_warn (_("%ld shortened to %ld"),
(valueT) i.imms[n]->X_add_number, val, val & ~mask);
2);
}
else
{
insn_size += 4;
p = frag_more (4);
md_number_to_chars (p,
(valueT) i.imms[n]->X_add_number,
4);
} }
insn_size += size;
p = frag_more (size);
md_number_to_chars (p, (valueT) val, size);
} }
else else
{ /* not absolute_section */ { /* not absolute_section */
@ -2613,9 +2612,13 @@ i386_immediate (imm_start)
} }
else if (exp->X_op == O_constant) else if (exp->X_op == O_constant)
{ {
int bigimm = Imm32;
if (flag_16bit_code ^ (i.prefix[DATA_PREFIX] != 0))
bigimm = Imm16;
i.types[this_operand] |= i.types[this_operand] |=
smallest_imm_type ((long) exp->X_add_number); (bigimm | smallest_imm_type ((long) exp->X_add_number));
/* If a suffix is given, this operand may be shortended. */ /* If a suffix is given, this operand may be shortended. */
switch (i.suffix) switch (i.suffix)
{ {
@ -3450,6 +3453,11 @@ i386_operand (operand_string)
else if (*op_string == IMMEDIATE_PREFIX) else if (*op_string == IMMEDIATE_PREFIX)
{ /* ... or an immediate */ { /* ... or an immediate */
++op_string; ++op_string;
if (i.types[this_operand] & JumpAbsolute)
{
as_bad (_("Immediate operand illegal with absolute jump"));
return 0;
}
if (!i386_immediate (op_string)) if (!i386_immediate (op_string))
return 0; return 0;
} }