CPU_PCLMUL_FLAGS },
{ ".fma", PROCESSOR_UNKNOWN,
CPU_FMA_FLAGS },
+ { ".fma4", PROCESSOR_UNKNOWN,
+ CPU_FMA4_FLAGS },
{ ".movbe", PROCESSOR_UNKNOWN,
CPU_MOVBE_FLAGS },
{ ".ept", PROCESSOR_UNKNOWN,
SKIP_WHITESPACE ();
- if (needs_align
+ if (needs_align
&& *input_line_pointer == ',')
{
align = parse_align (needs_align - 1);
-
+
if (align == (addressT) -1)
return NULL;
}
return match;
/* Check reverse. */
- assert (i.operands == 2);
+ gas_assert (i.operands == 2);
match = 1;
for (j = 0; j < 2; j++)
smallest_imm_type (offsetT num)
{
i386_operand_type t;
-
+
operand_type_set (&t, 0);
t.bitfield.imm64 = 1;
allow_naked_reg = (ask_naked_reg < 0);
expr_set_rank (O_full_ptr, syntax_flag ? 10 : 0);
-
+
identifier_chars['%'] = intel_syntax && allow_naked_reg ? '%' : 0;
identifier_chars['$'] = intel_syntax ? '$' : 0;
register_prefix = allow_naked_reg ? "" : "%";
i.op[xchg] = i.op[0];
i.op[0] = temp_op;
- assert (i.rm.mode == 3);
+ gas_assert (i.rm.mode == 3);
i.rex = REX_R;
xchg = i.rm.regmem;
AVX instructions also use this encoding, for some of
3 argument instructions. */
- assert (i.imm_operands == 0
- && (i.operands <= 2
- || (i.tm.opcode_modifier.vex
- && i.operands <= 4)));
+ gas_assert (i.imm_operands == 0
+ && (i.operands <= 2
+ || (i.tm.opcode_modifier.vex
+ && i.operands <= 4)));
exp = &im_expressions[i.imm_operands++];
i.op[i.operands].imms = exp;
there is no suffix, the default will be byte extension. */
if (i.reg_operands != 2
&& !i.suffix
- && intel_syntax)
+ && intel_syntax)
as_bad (_("ambiguous operand size for `%s'"), i.tm.name);
i.suffix = 0;
if (!process_suffix ())
return;
+ /* Update operand types. */
+ for (j = 0; j < i.operands; j++)
+ i.types[j] = operand_type_and (i.types[j], i.tm.operand_types[j]);
+
/* Make still unresolved immediate matches conform to size of immediate
given in i.suffix. */
if (!finalize_imm ())
if (i.types[0].bitfield.imm1)
i.imm_operands = 0; /* kludge for shift insns. */
- for (j = 0; j < 3; j++)
- if (i.types[j].bitfield.inoutportreg
- || i.types[j].bitfield.shiftcount
- || i.types[j].bitfield.acc
- || i.types[j].bitfield.floatacc)
- i.reg_operands--;
+ /* We only need to check those implicit registers for instructions
+ with 3 operands or less. */
+ if (i.operands <= 3)
+ for (j = 0; j < i.operands; j++)
+ if (i.types[j].bitfield.inoutportreg
+ || i.types[j].bitfield.shiftcount
+ || i.types[j].bitfield.acc
+ || i.types[j].bitfield.floatacc)
+ i.reg_operands--;
/* ImmExt should be processed after SSE2AVX. */
if (!i.tm.opcode_modifier.sse2avx
}
}
-if (i.rex != 0)
+ if (i.rex != 0)
add_prefix (REX_OPCODE | i.rex);
/* We are ready to output the insn. */
if (supported != CPU_FLAGS_PERFECT_MATCH)
{
as_bad (_("`%s' is not supported on `%s%s'"),
- current_templates->start->name,
+ current_templates->start->name,
cpu_arch_name ? cpu_arch_name : default_arch,
cpu_sub_arch_name ? cpu_sub_arch_name : "");
return NULL;
In any case, we can't set i.suffix yet. */
for (op = i.operands; --op >= 0;)
if (i.types[op].bitfield.reg8)
- {
+ {
guess_suffix = BYTE_MNEM_SUFFIX;
break;
}
else
{
unsigned int suffixes;
-
+
suffixes = !i.tm.opcode_modifier.no_bsuf;
if (!i.tm.opcode_modifier.no_wsuf)
suffixes |= 1 << 1;
static int
update_imm (unsigned int j)
{
- i386_operand_type overlap;
-
- overlap = operand_type_and (i.types[j], i.tm.operand_types[j]);
+ i386_operand_type overlap = i.types[j];
if ((overlap.bitfield.imm8
|| overlap.bitfield.imm8s
|| overlap.bitfield.imm16
i386_operand_type temp;
operand_type_set (&temp, 0);
- if (i.suffix == BYTE_MNEM_SUFFIX)
+ if (i.suffix == BYTE_MNEM_SUFFIX)
{
temp.bitfield.imm8 = overlap.bitfield.imm8;
temp.bitfield.imm8s = overlap.bitfield.imm8s;
static int
finalize_imm (void)
{
- unsigned int j;
+ unsigned int j, n;
- for (j = 0; j < 2; j++)
- if (update_imm (j) == 0)
- return 0;
+ /* Update the first 2 immediate operands. */
+ n = i.operands > 2 ? 2 : i.operands;
+ if (n)
+ {
+ for (j = 0; j < n; j++)
+ if (update_imm (j) == 0)
+ return 0;
- i.types[2] = operand_type_and (i.types[2], i.tm.operand_types[2]);
- assert (operand_type_check (i.types[2], imm) == 0);
+ /* The 3rd operand can't be immediate operand. */
+ gas_assert (operand_type_check (i.types[2], imm) == 0);
+ }
return 1;
}
unsigned int j;
/* The destination must be an xmm register. */
- assert (i.reg_operands
- && MAX_OPERANDS > dup
- && operand_type_equal (&i.types[dest], ®xmm));
+ gas_assert (i.reg_operands
+ && MAX_OPERANDS > dup
+ && operand_type_equal (&i.types[dest], ®xmm));
if (i.tm.opcode_modifier.firstxmm0)
{
/* The first operand is implicit and must be xmm0. */
- assert (operand_type_equal (&i.types[0], ®xmm));
+ gas_assert (operand_type_equal (&i.types[0], ®xmm));
if (i.op[0].regs->reg_num != 0)
return bad_implicit_operand (1);
}
}
else if (i.tm.opcode_modifier.implicit1stxmm0)
- {
- assert ((MAX_OPERANDS - 1) > dup
- && i.tm.opcode_modifier.vex3sources);
+ {
+ gas_assert ((MAX_OPERANDS - 1) > dup
+ && i.tm.opcode_modifier.vex3sources);
/* Add the implicit xmm0 for instructions with VEX prefix
and 3 sources. */
}
i.op[0].regs
= (const reg_entry *) hash_find (reg_hash, "xmm0");
- i.types[0] = regxmm;
+ i.types[0] = regxmm;
i.tm.operand_types[0] = regxmm;
i.operands += 2;
unsigned int j;
/* The first operand is implicit and must be xmm0/ymm0. */
- assert (i.reg_operands
- && (operand_type_equal (&i.types[0], ®xmm)
- || operand_type_equal (&i.types[0], ®ymm)));
+ gas_assert (i.reg_operands
+ && (operand_type_equal (&i.types[0], ®xmm)
+ || operand_type_equal (&i.types[0], ®ymm)));
if (i.op[0].regs->reg_num != 0)
return bad_implicit_operand (i.types[0].bitfield.regxmm);
else
first_reg_op = 1;
/* Pretend we saw the extra register operand. */
- assert (i.reg_operands == 1
- && i.op[first_reg_op + 1].regs == 0);
+ gas_assert (i.reg_operands == 1
+ && i.op[first_reg_op + 1].regs == 0);
i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
i.types[first_reg_op + 1] = i.types[first_reg_op];
i.operands++;
}
else
{
- /* The register or float register operand is in operand
+ /* The register or float register operand is in operand
0 or 1. */
unsigned int op;
-
- if (i.types[0].bitfield.floatreg
- || operand_type_check (i.types[0], reg))
- op = 0;
- else
- op = 1;
+
+ if (i.types[0].bitfield.floatreg
+ || operand_type_check (i.types[0], reg))
+ op = 0;
+ else
+ op = 1;
/* Register goes in low 3 bits of opcode. */
i.tm.base_opcode |= i.op[op].regs->reg_num;
if ((i.op[op].regs->reg_flags & RegRex) != 0)
{
const seg_entry *default_seg = 0;
unsigned int source, dest;
- int vex_3_sources;
+ int vex_3_sources;
/* The first operand of instructions with VEX prefix and 3 sources
must be VEX_Imm4. */
{
unsigned int nds, reg;
+ if (i.tm.opcode_modifier.veximmext
+ && i.tm.opcode_modifier.immext)
+ {
+ dest = i.operands - 2;
+ gas_assert (dest == 3);
+ }
+ else
dest = i.operands - 1;
nds = dest - 1;
- source = 1;
- reg = 0;
-
- /* This instruction must have 4 operands: 4 register operands
- or 3 register operands plus 1 memory operand. It must have
- VexNDS and VexImmExt. */
- assert (i.operands == 4
- && (i.reg_operands == 4
- || (i.reg_operands == 3 && i.mem_operands == 1))
- && i.tm.opcode_modifier.vexnds
- && i.tm.opcode_modifier.veximmext
- && (operand_type_equal (&i.tm.operand_types[dest],
- ®xmm)
- || operand_type_equal (&i.tm.operand_types[dest],
- ®ymm))
- && (operand_type_equal (&i.tm.operand_types[nds],
- ®xmm)
- || operand_type_equal (&i.tm.operand_types[nds],
- ®ymm))
- && (operand_type_equal (&i.tm.operand_types[reg],
- ®xmm)
- || operand_type_equal (&i.tm.operand_types[reg],
- ®ymm)));
+
+ /* This instruction must have 4 register operands
+ or 3 register operands plus 1 memory operand.
+ It must have VexNDS and VexImmExt. */
+ gas_assert ((i.reg_operands == 4
+ || (i.reg_operands == 3 && i.mem_operands == 1))
+ && i.tm.opcode_modifier.vexnds
+ && i.tm.opcode_modifier.veximmext
+ && (operand_type_equal (&i.tm.operand_types[dest], ®xmm)
+ || operand_type_equal (&i.tm.operand_types[dest], ®ymm)));
/* Generate an 8bit immediate operand to encode the register
operand. */
i.op[i.operands].imms = exp;
i.types[i.operands] = imm8;
i.operands++;
+ /* If VexW1 is set, the first operand is the source and
+ the second operand is encoded in the immediate operand. */
+ if (i.tm.opcode_modifier.vexw1)
+ {
+ source = 0;
+ reg = 1;
+ }
+ else
+ {
+ source = 1;
+ reg = 0;
+ }
+ /* FMA4 swaps REG and NDS. */
+ if (i.tm.cpu_flags.bitfield.cpufma4)
+ {
+ unsigned int tmp;
+ tmp = reg;
+ reg = nds;
+ nds = tmp;
+ }
+ gas_assert ((operand_type_equal (&i.tm.operand_types[reg], ®xmm)
+ || operand_type_equal (&i.tm.operand_types[reg],
+ ®ymm))
+ && (operand_type_equal (&i.tm.operand_types[nds], ®xmm)
+ || operand_type_equal (&i.tm.operand_types[nds],
+ ®ymm)));
exp->X_op = O_constant;
exp->X_add_number
- = ((i.op[0].regs->reg_num
- + ((i.op[0].regs->reg_flags & RegRex) ? 8 : 0)) << 4);
-
+ = ((i.op[reg].regs->reg_num
+ + ((i.op[reg].regs->reg_flags & RegRex) ? 8 : 0)) << 4);
i.vex.register_specifier = i.op[nds].regs;
}
else
instruction with VexNDD, the destination register is encoded
in VEX prefix. If there are 4 register operands, it must be
a instruction with VEX prefix and 3 sources. */
- if (i.mem_operands == 0
- && ((i.reg_operands == 2
- && !i.tm.opcode_modifier.vexndd)
- || (i.reg_operands == 3
- && i.tm.opcode_modifier.vexnds)
- || (i.reg_operands == 4 && vex_3_sources)))
+ if (i.mem_operands == 0
+ && ((i.reg_operands == 2
+ && !i.tm.opcode_modifier.vexndd)
+ || (i.reg_operands == 3
+ && i.tm.opcode_modifier.vexnds)
+ || (i.reg_operands == 4 && vex_3_sources)))
{
switch (i.operands)
{
which may be the first or the last operand. Otherwise,
the first operand must be shift count register (cl) or it
is an instruction with VexNDS. */
- assert (i.imm_operands == 1
- || (i.imm_operands == 0
- && (i.tm.opcode_modifier.vexnds
- || i.types[0].bitfield.shiftcount)));
+ gas_assert (i.imm_operands == 1
+ || (i.imm_operands == 0
+ && (i.tm.opcode_modifier.vexnds
+ || i.types[0].bitfield.shiftcount)));
if (operand_type_check (i.types[0], imm)
|| i.types[0].bitfield.shiftcount)
source = 1;
For instructions with VexNDS, if the first operand
an imm8, the source operand is the 2nd one. If the last
operand is imm8, the source operand is the first one. */
- assert ((i.imm_operands == 2
- && i.types[0].bitfield.imm8
- && i.types[1].bitfield.imm8)
- || (i.tm.opcode_modifier.vexnds
- && i.imm_operands == 1
- && (i.types[0].bitfield.imm8
- || i.types[i.operands - 1].bitfield.imm8)));
+ gas_assert ((i.imm_operands == 2
+ && i.types[0].bitfield.imm8
+ && i.types[1].bitfield.imm8)
+ || (i.tm.opcode_modifier.vexnds
+ && i.imm_operands == 1
+ && (i.types[0].bitfield.imm8
+ || i.types[i.operands - 1].bitfield.imm8)));
if (i.tm.opcode_modifier.vexnds)
{
if (i.types[0].bitfield.imm8)
unsigned int fake_zero_displacement = 0;
unsigned int op;
- for (op = 0; op < i.operands; op++)
- if (operand_type_check (i.types[op], anymem))
- break;
- assert (op < i.operands);
+ for (op = 0; op < i.operands; op++)
+ if (operand_type_check (i.types[op], anymem))
+ break;
+ gas_assert (op < i.operands);
default_seg = &ds;
holds the correct displacement size. */
expressionS *exp;
- assert (i.op[op].disps == 0);
+ gas_assert (i.op[op].disps == 0);
exp = &disp_expressions[i.disp_operands++];
i.op[op].disps = exp;
exp->X_op = O_constant;
if (i.reg_operands)
{
unsigned int op;
- unsigned int vex_reg = ~0;
-
- for (op = 0; op < i.operands; op++)
- if (i.types[op].bitfield.reg8
- || i.types[op].bitfield.reg16
- || i.types[op].bitfield.reg32
- || i.types[op].bitfield.reg64
- || i.types[op].bitfield.regmmx
- || i.types[op].bitfield.regxmm
- || i.types[op].bitfield.regymm
- || i.types[op].bitfield.sreg2
- || i.types[op].bitfield.sreg3
- || i.types[op].bitfield.control
- || i.types[op].bitfield.debug
- || i.types[op].bitfield.test)
- break;
+ unsigned int vex_reg = ~0;
+
+ for (op = 0; op < i.operands; op++)
+ if (i.types[op].bitfield.reg8
+ || i.types[op].bitfield.reg16
+ || i.types[op].bitfield.reg32
+ || i.types[op].bitfield.reg64
+ || i.types[op].bitfield.regmmx
+ || i.types[op].bitfield.regxmm
+ || i.types[op].bitfield.regymm
+ || i.types[op].bitfield.sreg2
+ || i.types[op].bitfield.sreg3
+ || i.types[op].bitfield.control
+ || i.types[op].bitfield.debug
+ || i.types[op].bitfield.test)
+ break;
- if (vex_3_sources)
- op = dest;
- else if (i.tm.opcode_modifier.vexnds)
- {
- /* For instructions with VexNDS, the register-only
- source operand is encoded in VEX prefix. */
- assert (mem != (unsigned int) ~0);
+ if (vex_3_sources)
+ op = dest;
+ else if (i.tm.opcode_modifier.vexnds)
+ {
+ /* For instructions with VexNDS, the register-only
+ source operand is encoded in VEX prefix. */
+ gas_assert (mem != (unsigned int) ~0);
- if (op > mem)
- {
- vex_reg = op++;
- assert (op < i.operands);
- }
- else
- {
- vex_reg = op + 1;
- assert (vex_reg < i.operands);
- }
- }
- else if (i.tm.opcode_modifier.vexndd)
+ if (op > mem)
{
- /* For instructions with VexNDD, there should be
- no memory operand and the register destination
- is encoded in VEX prefix. */
- assert (i.mem_operands == 0
- && (op + 2) == i.operands);
- vex_reg = op + 1;
+ vex_reg = op++;
+ gas_assert (op < i.operands);
}
else
- assert (op < i.operands);
-
- if (vex_reg != (unsigned int) ~0)
{
- assert (i.reg_operands == 2);
-
- if (!operand_type_equal (&i.tm.operand_types[vex_reg],
- & regxmm)
- && !operand_type_equal (&i.tm.operand_types[vex_reg],
- ®ymm))
- abort ();
- i.vex.register_specifier = i.op[vex_reg].regs;
+ vex_reg = op + 1;
+ gas_assert (vex_reg < i.operands);
}
+ }
+ else if (i.tm.opcode_modifier.vexndd)
+ {
+ /* For instructions with VexNDD, there should be
+ no memory operand and the register destination
+ is encoded in VEX prefix. */
+ gas_assert (i.mem_operands == 0
+ && (op + 2) == i.operands);
+ vex_reg = op + 1;
+ }
+ else
+ gas_assert (op < i.operands);
- /* If there is an extension opcode to put here, the
- register number must be put into the regmem field. */
- if (i.tm.extension_opcode != None)
- {
- i.rm.regmem = i.op[op].regs->reg_num;
- if ((i.op[op].regs->reg_flags & RegRex) != 0)
- i.rex |= REX_B;
- }
- else
- {
- i.rm.reg = i.op[op].regs->reg_num;
- if ((i.op[op].regs->reg_flags & RegRex) != 0)
- i.rex |= REX_R;
- }
+ if (vex_reg != (unsigned int) ~0)
+ {
+ gas_assert (i.reg_operands == 2);
+
+ if (!operand_type_equal (&i.tm.operand_types[vex_reg],
+ & regxmm)
+ && !operand_type_equal (&i.tm.operand_types[vex_reg],
+ ®ymm))
+ abort ();
+ i.vex.register_specifier = i.op[vex_reg].regs;
+ }
+
+ /* If there is an extension opcode to put here, the
+ register number must be put into the regmem field. */
+ if (i.tm.extension_opcode != None)
+ {
+ i.rm.regmem = i.op[op].regs->reg_num;
+ if ((i.op[op].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_B;
+ }
+ else
+ {
+ i.rm.reg = i.op[op].regs->reg_num;
+ if ((i.op[op].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_R;
+ }
/* Now, if no memory operand has set i.rm.mode = 0, 1, 2 we
must set it to 3 to indicate this is a register operand
int pcrel = (i.flags[n] & Operand_PCrel) != 0;
/* We can't have 8 bit displacement here. */
- assert (!i.types[n].bitfield.disp8);
+ gas_assert (!i.types[n].bitfield.disp8);
/* The PC relative address is computed relative
to the instruction boundary, so in case immediate
{
/* Only one immediate is allowed for PC
relative address. */
- assert (sz == 0);
+ gas_assert (sz == 0);
sz = imm_size (n1);
i.op[n].disps->X_add_number -= sz;
}
/* We should find the immediate. */
- assert (sz != 0);
+ gas_assert (sz != 0);
}
p = frag_more (size);
OPERAND_TYPE_NONE },
{ "DTPOFF", { BFD_RELOC_386_TLS_LDO_32,
BFD_RELOC_X86_64_DTPOFF32 },
-
+
OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
{ "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE,
0 },
: i386_regtab[j].reg_type.bitfield.reg16)
&& i386_regtab[j].reg_num == expected)
break;
- assert (j < i386_regtab_size);
+ gas_assert (j < i386_regtab_size);
as_warn (_("`%s' is not valid here (expected `%c%s%s%c')"),
operand_string,
intel_syntax ? '[' : '(',
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|| (IS_ELF
&& (S_IS_EXTERNAL (fragP->fr_symbol)
- || S_IS_WEAK (fragP->fr_symbol)))
+ || S_IS_WEAK (fragP->fr_symbol)
+ || ((symbol_get_bfdsym (fragP->fr_symbol)->flags
+ & BSF_GNU_INDIRECT_FUNCTION))))
#endif
#if defined (OBJ_COFF) && defined (TE_PE)
- || (OUTPUT_FLAVOR == bfd_target_coff_flavour
+ || (OUTPUT_FLAVOR == bfd_target_coff_flavour
&& S_IS_WEAK (fragP->fr_symbol))
#endif
)
if ((sym_seg == seg
|| (symbol_section_p (fixP->fx_addsy)
&& sym_seg != absolute_section))
- && !generic_force_reloc (fixP))
+ && !TC_FORCE_RELOCATION (fixP))
{
/* Yes, we add the values in twice. This is because
bfd_install_relocation subtracts them out again. I think
break;
case '[':
- assert (intel_syntax);
+ gas_assert (intel_syntax);
end = input_line_pointer++;
expression (e);
if (*input_line_pointer == ']')
mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, sse4,\n\
avx, vmx, smx, xsave, movbe, ept, aes, pclmul, fma,\n\
clflush, syscall, rdtscp, 3dnow, 3dnowa, sse4a,\n\
- svme, abm, padlock\n"));
+ svme, abm, padlock, fma4\n"));
fprintf (stream, _("\
-mtune=CPU optimize for CPU, CPU is one of:\n\
i8086, i186, i286, i386, i486, pentium, pentiumpro,\n\
#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
|| defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
- || defined (TE_PE) || defined (TE_PEP))
+ || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
/* Pick the target format to use. */
}
return flag_code == CODE_64BIT ? ELF_TARGET_FORMAT64 : ELF_TARGET_FORMAT;
}
+#endif
+#if defined (OBJ_MACH_O)
+ case bfd_target_mach_o_flavour:
+ return flag_code == CODE_64BIT ? "mach-o-x86-64" : "mach-o-i386";
#endif
default:
abort ();
bfd_get_reloc_code_name (code));
/* Set howto to a garbage value so that we can keep going. */
rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
- assert (rel->howto != NULL);
+ gas_assert (rel->howto != NULL);
}
return rel;
input_line_pointer = sp[flag_code >> 1];
tc_x86_parse_to_dw2regnum (&exp);
- assert (exp.X_op == O_constant);
+ gas_assert (exp.X_op == O_constant);
sp_regno[flag_code >> 1] = exp.X_add_number;
input_line_pointer = saved_input;
}