aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2000-06-22 10:49:13 +0000
committerAlan Modra <amodra@gmail.com>2000-06-22 10:49:13 +0000
commit45288df104aeefbd6fb98ac40659b1aec6b6bb65 (patch)
tree6a800a943262a7267064b9f4a105cb087deb392e
parentf7778913340992e6e32bbf7b0739283535a6e891 (diff)
downloadgdb-45288df104aeefbd6fb98ac40659b1aec6b6bb65.zip
gdb-45288df104aeefbd6fb98ac40659b1aec6b6bb65.tar.gz
gdb-45288df104aeefbd6fb98ac40659b1aec6b6bb65.tar.bz2
Fix a problem with 32-bit displacements in .code16gcc mode.
-rw-r--r--gas/ChangeLog8
-rw-r--r--gas/config/tc-i386.c50
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);