diff options
author | Jan Beulich <jbeulich@novell.com> | 2005-09-28 15:31:21 +0000 |
---|---|---|
committer | Jan Beulich <jbeulich@novell.com> | 2005-09-28 15:31:21 +0000 |
commit | e05278afa3c5b5aa74f9694f7aac576f437c7e1b (patch) | |
tree | e37ee201918565103f23244f3ca1239acb5e8d0c /gas/config | |
parent | dd86362472ff29dd0a3972e35b20ab0e7b1ba161 (diff) | |
download | gdb-e05278afa3c5b5aa74f9694f7aac576f437c7e1b.zip gdb-e05278afa3c5b5aa74f9694f7aac576f437c7e1b.tar.gz gdb-e05278afa3c5b5aa74f9694f7aac576f437c7e1b.tar.bz2 |
gas/
2005-09-28 Jan Beulich <jbeulich@novell.com>
* config/tc-i386.c (reloc): Disable signedness check for 4-byte
relocations in 16- and 32-bit modes.
(i386_displacement): Make pc-relative branch handling dependent
upon operand (rather than address) size.
gas/testsuite/
2005-09-28 Jan Beulich <jbeulich@novell.com>
* gas/i386/mixed-mode-reloc.s: Enable all insns.
* gas/i386/mixed-mode-reloc32.d: Adjust.
* gas/i386/mixed-mode-reloc64.d: Adjust.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-i386.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 8f229cf..d6e11df 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1237,6 +1237,11 @@ reloc (unsigned int size, default: break; } + + /* Sign-checking 4-byte relocations in 16-/32-bit code is pointless. */ + if (size == 4 && flag_code != CODE_64BIT) + sign = -1; + reloc = bfd_reloc_type_lookup (stdoutput, other); if (!reloc) as_bad (_("unknown relocation (%u)"), other); @@ -4111,16 +4116,44 @@ i386_displacement (disp_start, disp_end) segT exp_seg = 0; char *save_input_line_pointer; char *gotfree_input_line; - int bigdisp = Disp32; + int bigdisp, override; unsigned int types = Disp; + if ((i.types[this_operand] & JumpAbsolute) + || !(current_templates->start->opcode_modifier & (Jump | JumpDword))) + { + bigdisp = Disp32; + override = (i.prefix[ADDR_PREFIX] != 0); + } + else + { + /* For PC-relative branches, the width of the displacement + is dependent upon data size, not address size. */ + bigdisp = 0; + override = (i.prefix[DATA_PREFIX] != 0); + } if (flag_code == CODE_64BIT) { - if (i.prefix[ADDR_PREFIX] == 0) + if (!bigdisp) + bigdisp = (override || i.suffix == WORD_MNEM_SUFFIX) + ? Disp16 + : Disp32S | Disp32; + else if (!override) bigdisp = Disp64 | Disp32S | Disp32; } - else if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0)) - bigdisp = Disp16; + else + { + if (!bigdisp) + { + if (!override) + override = (i.suffix == (flag_code != CODE_16BIT + ? WORD_MNEM_SUFFIX + : LONG_MNEM_SUFFIX)); + bigdisp = Disp32; + } + if ((flag_code == CODE_16BIT) ^ override) + bigdisp = Disp16; + } i.types[this_operand] |= bigdisp; exp = &disp_expressions[i.disp_operands]; |