From e05278afa3c5b5aa74f9694f7aac576f437c7e1b Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 28 Sep 2005 15:31:21 +0000 Subject: [PATCH] gas/ 2005-09-28 Jan Beulich * 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 * gas/i386/mixed-mode-reloc.s: Enable all insns. * gas/i386/mixed-mode-reloc32.d: Adjust. * gas/i386/mixed-mode-reloc64.d: Adjust. --- gas/ChangeLog | 7 ++++ gas/config/tc-i386.c | 41 +++++++++++++++++++-- gas/testsuite/ChangeLog | 6 +++ gas/testsuite/gas/i386/mixed-mode-reloc.s | 6 +-- gas/testsuite/gas/i386/mixed-mode-reloc32.d | 6 +-- gas/testsuite/gas/i386/mixed-mode-reloc64.d | 6 +-- 6 files changed, 59 insertions(+), 13 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 91d515f1004..8085e676e7d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2005-09-28 Jan Beulich + + * 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. + 2005-09-28 Jan Beulich * dw2gencfi.c (dot_cfi): Call ignore_rest_of_line when not fully diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 8f229cfb354..d6e11df8ac1 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]; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index dc7927a4c84..5416d284e71 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-09-28 Jan Beulich + + * gas/i386/mixed-mode-reloc.s: Enable all insns. + * gas/i386/mixed-mode-reloc32.d: Adjust. + * gas/i386/mixed-mode-reloc64.d: Adjust. + 2005-09-28 Jan Beulich * gas/i386/reloc64.s: Also test .slong. diff --git a/gas/testsuite/gas/i386/mixed-mode-reloc.s b/gas/testsuite/gas/i386/mixed-mode-reloc.s index 1b1a7fe25b1..3cc286197f7 100644 --- a/gas/testsuite/gas/i386/mixed-mode-reloc.s +++ b/gas/testsuite/gas/i386/mixed-mode-reloc.s @@ -2,12 +2,12 @@ .code16 _start16: -#FIXME movl xtrn@got(%ebx), %eax -#FIXME calll xtrn@plt + movl xtrn@got(%ebx), %eax + calll xtrn@plt .code32 _start32: -#FIXME movl xtrn@got(%ebx), %eax + movl xtrn@got(%ebx), %eax calll xtrn@plt .code64 diff --git a/gas/testsuite/gas/i386/mixed-mode-reloc32.d b/gas/testsuite/gas/i386/mixed-mode-reloc32.d index 2dba860eed9..6bc52f7959a 100644 --- a/gas/testsuite/gas/i386/mixed-mode-reloc32.d +++ b/gas/testsuite/gas/i386/mixed-mode-reloc32.d @@ -6,9 +6,9 @@ RELOCATION RECORDS FOR \[.text\]: OFFSET[ ]+TYPE[ ]+VALUE[ ]* -#[0-9a-f]+[ ]+R_386_GOT32[ ]+xtrn[ ]* -#[0-9a-f]+[ ]+R_386_PLT32[ ]+xtrn[ ]* -#[0-9a-f]+[ ]+R_386_GOT32[ ]+xtrn[ ]* +[0-9a-f]+[ ]+R_386_GOT32[ ]+xtrn[ ]* +[0-9a-f]+[ ]+R_386_PLT32[ ]+xtrn[ ]* +[0-9a-f]+[ ]+R_386_GOT32[ ]+xtrn[ ]* [0-9a-f]+[ ]+R_386_PLT32[ ]+xtrn[ ]* [0-9a-f]+[ ]+R_386_GOT32[ ]+xtrn[ ]* [0-9a-f]+[ ]+R_386_PLT32[ ]+xtrn[ ]* diff --git a/gas/testsuite/gas/i386/mixed-mode-reloc64.d b/gas/testsuite/gas/i386/mixed-mode-reloc64.d index 9c99eefaf57..dc50e43576b 100644 --- a/gas/testsuite/gas/i386/mixed-mode-reloc64.d +++ b/gas/testsuite/gas/i386/mixed-mode-reloc64.d @@ -6,9 +6,9 @@ RELOCATION RECORDS FOR \[.text\]: OFFSET[ ]+TYPE[ ]+VALUE[ ]* -#[0-9a-f]+[ ]+R_X86_64_GOT32[ ]+xtrn[ ]* -#[0-9a-f]+[ ]+R_X86_64_PLT32[ ]+xtrn\+0xf+c[ ]* -#[0-9a-f]+[ ]+R_X86_64_GOT32[ ]+xtrn[ ]* +[0-9a-f]+[ ]+R_X86_64_GOT32[ ]+xtrn[ ]* +[0-9a-f]+[ ]+R_X86_64_PLT32[ ]+xtrn\+0xf+c[ ]* +[0-9a-f]+[ ]+R_X86_64_GOT32[ ]+xtrn[ ]* [0-9a-f]+[ ]+R_X86_64_PLT32[ ]+xtrn\+0xf+c[ ]* [0-9a-f]+[ ]+R_X86_64_GOT32[ ]+xtrn[ ]* [0-9a-f]+[ ]+R_X86_64_PLT32[ ]+xtrn\+0xf+c[ ]*