diff options
author | Alan Modra <amodra@gmail.com> | 2000-06-22 10:49:13 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2000-06-22 10:49:13 +0000 |
commit | 45288df104aeefbd6fb98ac40659b1aec6b6bb65 (patch) | |
tree | 6a800a943262a7267064b9f4a105cb087deb392e | |
parent | f7778913340992e6e32bbf7b0739283535a6e891 (diff) | |
download | gdb-45288df104aeefbd6fb98ac40659b1aec6b6bb65.zip gdb-45288df104aeefbd6fb98ac40659b1aec6b6bb65.tar.gz gdb-45288df104aeefbd6fb98ac40659b1aec6b6bb65.tar.bz2 |
Fix a problem with 32-bit displacements in .code16gcc mode.
-rw-r--r-- | gas/ChangeLog | 8 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 50 |
2 files changed, 39 insertions, 19 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 35854d9..f5c06d7 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2000-06-22 Alan Modra <alan@linuxcare.com.au> + + * config/tc-i386.c (i386_displacement): Don't assume a constant + displacement is necessarily 16 bits when in 16 bit code mode. + (md_assemble): Instead size the displacement here after we know + for sure that a .code16gcc operand hasn't automatically added + operand size prefixes. + 2000-06-21 H.J. Lu <hjl@gnu.org> * Makefile.am: Rebuild dependency. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 2c32e74..6ab93c5 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1461,6 +1461,31 @@ md_assemble (line) } } + if (i.disp_operands) + { + /* Try to use the smallest displacement type too. */ + int op; + + for (op = i.operands; --op >= 0; ) + if ((i.types[op] & Disp) + && i.op[op].imms->X_op == O_constant) + { + offsetT disp = i.op[op].disps->X_add_number; + + if (i.types[op] & 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. */ + + disp = (((disp & 0xffff) ^ 0x8000) - 0x8000); + } + if (fits_in_signed_byte (disp)) + i.types[op] |= Disp8; + } + } + overlap0 = 0; overlap1 = 0; overlap2 = 0; @@ -2920,28 +2945,15 @@ i386_displacement (disp_start, disp_end) exp->X_op_symbol = (symbolS *) 0; } - 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)) - i.types[this_operand] |= Disp8; - } #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT)) - else if ( + if (exp->X_op != O_constant #ifdef BFD_ASSEMBLER - OUTPUT_FLAVOR == bfd_target_aout_flavour && + && OUTPUT_FLAVOR == bfd_target_aout_flavour #endif - exp_seg != text_section - && exp_seg != data_section - && exp_seg != bss_section - && exp_seg != undefined_section) + && exp_seg != text_section + && exp_seg != data_section + && exp_seg != bss_section + && exp_seg != undefined_section) { #ifdef BFD_ASSEMBLER as_bad (_("unimplemented segment %s in operand"), exp_seg->name); |