summaryrefslogtreecommitdiffstats
path: root/contrib/binutils/gas/config/tc-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/binutils/gas/config/tc-i386.c')
-rw-r--r--contrib/binutils/gas/config/tc-i386.c114
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 1d874af..f681014 100644
--- a/contrib/binutils/gas/config/tc-i386.c
+++ b/contrib/binutils/gas/config/tc-i386.c
@@ -182,9 +182,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) \
@@ -2208,15 +2208,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)
{
@@ -2228,6 +2228,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. */
@@ -2309,7 +2310,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;
@@ -2368,7 +2369,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;
@@ -2385,7 +2386,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;
@@ -2417,7 +2418,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;
@@ -2450,7 +2451,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;
@@ -2980,7 +2981,6 @@ output_jump ()
{
char *p;
int size;
- fixS *fixP;
if (i.tm.opcode_modifier & JumpByte)
{
@@ -3031,9 +3031,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
@@ -3226,7 +3225,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
@@ -3266,11 +3264,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]));
}
}
}
@@ -4215,7 +4211,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;
@@ -4233,18 +4228,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. */
@@ -4255,18 +4247,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. */
@@ -4274,11 +4272,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:
@@ -4289,7 +4286,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
@@ -4607,6 +4603,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
@@ -5120,9 +5118,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);
OpenPOWER on IntegriCloud