This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: .code16gcc and "lea <32bit>(%eax),%edx"
- To: Etienne Lorrain <etienne_lorrain at yahoo dot fr>
- Subject: Re: .code16gcc and "lea <32bit>(%eax),%edx"
- From: Alan Modra <alan at linuxcare dot com dot au>
- Date: Thu, 22 Jun 2000 21:00:06 +1000 (EST)
- cc: binutils at sourceware dot cygnus dot com
On Thu, 22 Jun 2000, [iso-8859-1] Etienne Lorrain wrote:
> 3 .code16gcc
> 4 0006 67668D78 leal 4194428(%eax),%edi
> 4 7C
I squinted at this code when I made a similar fix for immediates on
2000-04-03, at the time deciding that displacements wouldn't be a problem
because the size is only affected by the mode and prefixes, which we've
already seen. Forgot that i386_index_check might magically add a prefix
in...
Ah well. Following patch installed.
--
Linuxcare. Support for the Revolution.
gas/ChangeLog
* 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.
Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.55
diff -u -p -r1.55 tc-i386.c
--- tc-i386.c 2000/06/21 02:18:17 1.55
+++ tc-i386.c 2000/06/22 10:44:38
@@ -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);