diff options
author | obrien <obrien@FreeBSD.org> | 2002-07-05 20:36:17 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-07-05 20:36:17 +0000 |
commit | e23e2669ca686ba67321c5135f24d2fe0c72a440 (patch) | |
tree | 6548a3e224cb49ff509058effcd34c3a38b8b01d /contrib/binutils | |
parent | 69e1a1e0d41099d0485eddacd2997659a21a97f8 (diff) | |
download | FreeBSD-src-e23e2669ca686ba67321c5135f24d2fe0c72a440.zip FreeBSD-src-e23e2669ca686ba67321c5135f24d2fe0c72a440.tar.gz |
Bring the binutils_2_12_20020622 snap version of this to the HEAD branch.
Diffstat (limited to 'contrib/binutils')
-rw-r--r-- | contrib/binutils/gas/config/tc-i386.c | 114 |
1 files changed, 63 insertions, 51 deletions
diff --git a/contrib/binutils/gas/config/tc-i386.c b/contrib/binutils/gas/config/tc-i386.c index 8dc0f5e..a4a6e61 100644 --- a/contrib/binutils/gas/config/tc-i386.c +++ b/contrib/binutils/gas/config/tc-i386.c @@ -186,9 +186,9 @@ typedef struct _i386_insn i386_insn; /* List of chars besides those in app.c:symbol_chars that can start an operand. Used to prevent the scrubber eating vital white-space. */ #ifdef LEX_AT -const char extra_symbol_chars[] = "*%-(@"; +const char extra_symbol_chars[] = "*%-(@["; #else -const char extra_symbol_chars[] = "*%-("; +const char extra_symbol_chars[] = "*%-(["; #endif #if (defined (TE_I386AIX) \ @@ -2212,15 +2212,15 @@ process_suffix () /* For movzx and movsx, need to check the register type. */ if (intel_syntax - && (i.tm.base_opcode == 0xfb6 || i.tm.base_opcode == 0xfbe)) - if (i.suffix && i.suffix == BYTE_MNEM_SUFFIX) - { - unsigned int prefix = DATA_PREFIX_OPCODE; + && (i.tm.base_opcode == 0xfb6 || i.tm.base_opcode == 0xfbe) + && i.suffix == BYTE_MNEM_SUFFIX) + { + unsigned int prefix = DATA_PREFIX_OPCODE; - if ((i.op[1].regs->reg_type & Reg16) != 0) - if (!add_prefix (prefix)) - return 0; - } + if ((i.op[1].regs->reg_type & Reg16) != 0) + if (!add_prefix (prefix)) + return 0; + } if (i.suffix && i.suffix != BYTE_MNEM_SUFFIX) { @@ -2232,6 +2232,7 @@ process_suffix () else i.tm.base_opcode |= 1; } + /* Now select between word & dword operations via the operand size prefix, except for instructions that will ignore this prefix anyway. */ @@ -2313,7 +2314,7 @@ check_byte_reg () if (flag_code == CODE_64BIT && (i.tm.operand_types[op] & InOutPortReg) == 0) { - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2372,7 +2373,7 @@ check_long_reg () lowering is more complicated. */ if (flag_code == CODE_64BIT) { - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2389,7 +2390,7 @@ check_long_reg () else if ((i.types[op] & Reg64) != 0 && (i.tm.operand_types[op] & (Reg32 | Acc)) != 0) { - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2421,7 +2422,7 @@ check_qword_reg () { /* Prohibit these changes in the 64bit mode, since the lowering is more complicated. */ - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2454,7 +2455,7 @@ check_word_reg () lowering is more complicated. */ if (flag_code == CODE_64BIT) { - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2984,7 +2985,6 @@ output_jump () { char *p; int size; - fixS *fixP; if (i.tm.opcode_modifier & JumpByte) { @@ -3035,9 +3035,8 @@ output_jump () p = frag_more (1 + size); *p++ = i.tm.base_opcode; - fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0])); - fixP->fx_pcrel_adjust = size; + fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0])); } static void @@ -3230,7 +3229,6 @@ output_disp () int size = 4; int sign = 0; int pcrel = (i.flags[n] & Operand_PCrel) != 0; - fixS *fixP; /* The PC relative address is computed relative to the instruction boundary, so in case immediate @@ -3270,11 +3268,9 @@ output_disp () } p = frag_more (size); - fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[n].disps, pcrel, - reloc (size, pcrel, sign, i.reloc[n])); - if (pcrel) - fixP->fx_pcrel_adjust = size; + fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.op[n].disps, pcrel, + reloc (size, pcrel, sign, i.reloc[n])); } } } @@ -4219,7 +4215,6 @@ md_estimate_size_before_relax (fragP, segment) RELOC_ENUM reloc_type; unsigned char *opcode; int old_fr_fix; - fixS *fixP; if (fragP->fr_var != NO_RELOC) reloc_type = fragP->fr_var; @@ -4237,18 +4232,15 @@ md_estimate_size_before_relax (fragP, segment) /* Make jmp (0xeb) a (d)word displacement jump. */ opcode[0] = 0xe9; fragP->fr_fix += size; - fixP = fix_new (fragP, old_fr_fix, size, - fragP->fr_symbol, - fragP->fr_offset, 1, - reloc_type); - fixP->fx_pcrel_adjust = size; + fix_new (fragP, old_fr_fix, size, + fragP->fr_symbol, + fragP->fr_offset, 1, + reloc_type); break; case COND_JUMP86: - if (no_cond_jump_promotion) - goto relax_guess; - - if (size == 2) + if (size == 2 + && (!no_cond_jump_promotion || fragP->fr_var != NO_RELOC)) { /* Negate the condition, and branch past an unconditional jump. */ @@ -4259,18 +4251,24 @@ md_estimate_size_before_relax (fragP, segment) /* We added two extra opcode bytes, and have a two byte offset. */ fragP->fr_fix += 2 + 2; - fixP = fix_new (fragP, old_fr_fix + 2, 2, - fragP->fr_symbol, - fragP->fr_offset, 1, - reloc_type); - fixP->fx_pcrel_adjust = size; + fix_new (fragP, old_fr_fix + 2, 2, + fragP->fr_symbol, + fragP->fr_offset, 1, + reloc_type); break; } /* Fall through. */ case COND_JUMP: - if (no_cond_jump_promotion) - goto relax_guess; + if (no_cond_jump_promotion && fragP->fr_var == NO_RELOC) + { + fragP->fr_fix += 1; + fix_new (fragP, old_fr_fix, 1, + fragP->fr_symbol, + fragP->fr_offset, 1, + BFD_RELOC_8_PCREL); + break; + } /* This changes the byte-displacement jump 0x7N to the (d)word-displacement jump 0x0f,0x8N. */ @@ -4278,11 +4276,10 @@ md_estimate_size_before_relax (fragP, segment) opcode[0] = TWO_BYTE_OPCODE_ESCAPE; /* We've added an opcode byte. */ fragP->fr_fix += 1 + size; - fixP = fix_new (fragP, old_fr_fix + 1, size, - fragP->fr_symbol, - fragP->fr_offset, 1, - reloc_type); - fixP->fx_pcrel_adjust = size; + fix_new (fragP, old_fr_fix + 1, size, + fragP->fr_symbol, + fragP->fr_offset, 1, + reloc_type); break; default: @@ -4293,7 +4290,6 @@ md_estimate_size_before_relax (fragP, segment) return fragP->fr_fix - old_fr_fix; } - relax_guess: /* Guess size depending on current relax state. Initially the relax state will correspond to a short jump and we return 1, because the variable part of the frag (the branch offset) is one byte @@ -4611,6 +4607,8 @@ md_apply_fix3 (fixP, valP, seg) else if (use_rela_relocations) { fixP->fx_no_overflow = 1; + /* Remember value for tc_gen_reloc. */ + fixP->fx_addnumber = value; value = 0; } #endif @@ -5124,9 +5122,23 @@ tc_gen_reloc (section, fixp) /* Use the rela in 64bit mode. */ else { - rel->addend = fixp->fx_offset; - if (fixp->fx_pcrel) - rel->addend -= fixp->fx_pcrel_adjust; + if (!fixp->fx_pcrel) + rel->addend = fixp->fx_offset; + else + switch (code) + { + case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_GOT32: + case BFD_RELOC_X86_64_GOTPCREL: + rel->addend = fixp->fx_offset - fixp->fx_size; + break; + default: + rel->addend = (section->vma + - fixp->fx_size + + fixp->fx_addnumber + + md_pcrel_from (fixp)); + break; + } } rel->howto = bfd_reloc_type_lookup (stdoutput, code); |