/* tc-i386.c -- Assemble code for the Intel 80386
- Copyright (C) 1989-2020 Free Software Foundation, Inc.
+ Copyright (C) 1989-2021 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
static int
check_hle (void)
{
- switch (i.tm.opcode_modifier.hleprefixok)
+ switch (i.tm.opcode_modifier.prefixok)
{
default:
abort ();
- case HLEPrefixNone:
+ case PrefixLock:
+ case PrefixNone:
+ case PrefixNoTrack:
+ case PrefixRep:
as_bad (_("invalid instruction `%s' after `%s'"),
i.tm.name, i.hle_prefix);
return 0;
- case HLEPrefixLock:
+ case PrefixHLELock:
if (i.prefix[LOCK_PREFIX])
return 1;
as_bad (_("missing `lock' with `%s'"), i.hle_prefix);
return 0;
- case HLEPrefixAny:
+ case PrefixHLEAny:
return 1;
- case HLEPrefixRelease:
+ case PrefixHLERelease:
if (i.prefix[HLE_PREFIX] != XRELEASE_PREFIX_OPCODE)
{
as_bad (_("instruction `%s' after `xacquire' not allowed"),
return;
/* Check if REP prefix is OK. */
- if (i.rep_prefix && !i.tm.opcode_modifier.repprefixok)
+ if (i.rep_prefix && i.tm.opcode_modifier.prefixok != PrefixRep)
{
as_bad (_("invalid instruction `%s' after `%s'"),
i.tm.name, i.rep_prefix);
/* Check for lock without a lockable instruction. Destination operand
must be memory unless it is xchg (0x86). */
if (i.prefix[LOCK_PREFIX]
- && (!i.tm.opcode_modifier.islockable
+ && (i.tm.opcode_modifier.prefixok < PrefixLock
|| i.mem_operands == 0
|| (i.tm.base_opcode != 0x86
&& !(i.flags[i.operands - 1] & Operand_Mem))))
as_bad (_("expecting valid branch instruction after `bnd'"));
/* Check NOTRACK prefix. */
- if (i.notrack_prefix && !i.tm.opcode_modifier.notrackprefixok)
+ if (i.notrack_prefix && i.tm.opcode_modifier.prefixok != PrefixNoTrack)
as_bad (_("expecting indirect branch instruction after `notrack'"));
if (i.tm.cpu_flags.bitfield.cpumpx)
for (j = 0; j < i.operands; j++)
{
i.types[j] = operand_type_and (i.types[j], i.tm.operand_types[j]);
- switch (i.types[j].bitfield.class)
+ switch (i.tm.operand_types[j].bitfield.class)
{
default:
break;
i.xstate |= xstate_mask;
break;
case RegSIMD:
- if (i.types[j].bitfield.tmmword)
+ if (i.tm.operand_types[j].bitfield.tmmword)
i.xstate |= xstate_tmm;
- else if (i.types[j].bitfield.zmmword)
+ else if (i.tm.operand_types[j].bitfield.zmmword)
i.xstate |= xstate_zmm;
- else if (i.types[j].bitfield.ymmword)
+ else if (i.tm.operand_types[j].bitfield.ymmword)
i.xstate |= xstate_ymm;
- else if (i.types[j].bitfield.xmmword)
+ else if (i.tm.operand_types[j].bitfield.xmmword)
i.xstate |= xstate_xmm;
break;
}
break;
case 0:
- /* Select word/dword/qword operation with explict data sizing prefix
+ /* Select word/dword/qword operation with explicit data sizing prefix
when there are no suitable register operands. */
if (i.tm.opcode_modifier.w
&& (i.prefix[DATA_PREFIX] || (i.prefix[REX_PREFIX] & REX_W))
if (!object_64bit)
return FALSE;
+ if (s == NULL)
+ return FALSE;
+
/* Weak or undefined symbol need PLT32 relocation. */
if (S_IS_WEAK (s) || !S_IS_DEFINED (s))
return TRUE;
|| i.tm.cpu_flags.bitfield.cpuamx_tile)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_TMM;
- if (i.tm.cpu_flags.bitfield.cpusse3
- || i.tm.cpu_flags.bitfield.cpussse3
- || i.tm.cpu_flags.bitfield.cpusse4_1
- || i.tm.cpu_flags.bitfield.cpusse4_2
- || i.tm.cpu_flags.bitfield.cpucx16
- || i.tm.cpu_flags.bitfield.cpupopcnt
- /* LAHF-SAHF insns in 64-bit mode. */
- || (flag_code == CODE_64BIT
- && (i.tm.base_opcode | 1) == 0x9f))
- x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_V2;
- if (i.tm.cpu_flags.bitfield.cpuavx
- || i.tm.cpu_flags.bitfield.cpuavx2
- /* Any VEX encoded insns execpt for CpuAVX512F, CpuAVX512BW,
- CpuAVX512DQ, LPW, TBM and AMX. */
- || (i.tm.opcode_modifier.vex
- && !i.tm.cpu_flags.bitfield.cpuavx512f
- && !i.tm.cpu_flags.bitfield.cpuavx512bw
- && !i.tm.cpu_flags.bitfield.cpuavx512dq
- && !i.tm.cpu_flags.bitfield.cpulwp
- && !i.tm.cpu_flags.bitfield.cputbm
- && !(x86_feature_2_used & GNU_PROPERTY_X86_FEATURE_2_TMM))
- || i.tm.cpu_flags.bitfield.cpuf16c
- || i.tm.cpu_flags.bitfield.cpufma
- || i.tm.cpu_flags.bitfield.cpulzcnt
- || i.tm.cpu_flags.bitfield.cpumovbe
- || i.tm.cpu_flags.bitfield.cpuxsave
- || i.tm.cpu_flags.bitfield.cpuxsavec
- || i.tm.cpu_flags.bitfield.cpuxsaveopt
- || i.tm.cpu_flags.bitfield.cpuxsaves)
- x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_V3;
- if (i.tm.cpu_flags.bitfield.cpuavx512f
- || i.tm.cpu_flags.bitfield.cpuavx512bw
- || i.tm.cpu_flags.bitfield.cpuavx512dq
- || i.tm.cpu_flags.bitfield.cpuavx512vl
- /* Any EVEX encoded insns except for AVX512ER, AVX512PF and
- VNNIW. */
- || (i.tm.opcode_modifier.evex
- && !i.tm.cpu_flags.bitfield.cpuavx512er
- && !i.tm.cpu_flags.bitfield.cpuavx512pf
- && !i.tm.cpu_flags.bitfield.cpuavx512_4vnniw))
- x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_V4;
-
if (i.tm.cpu_flags.bitfield.cpu8087
|| i.tm.cpu_flags.bitfield.cpu287
|| i.tm.cpu_flags.bitfield.cpu387
|| i.tm.cpu_flags.bitfield.cpu687
|| i.tm.cpu_flags.bitfield.cpufisttp)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_X87;
+
if ((i.xstate & xstate_mmx)
|| i.tm.base_opcode == 0xf77 /* emms */
|| i.tm.base_opcode == 0xf0e /* femms */)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_MMX;
+
if (i.index_reg)
{
if (i.index_reg->reg_type.bitfield.zmmword)
else if (i.index_reg->reg_type.bitfield.xmmword)
i.xstate |= xstate_xmm;
}
+
+ /* vzeroall / vzeroupper */
+ if (i.tm.base_opcode == 0x77 && i.tm.cpu_flags.bitfield.cpuavx)
+ i.xstate |= xstate_ymm;
+
if ((i.xstate & xstate_xmm)
+ /* ldmxcsr / stmxcsr */
+ || (i.tm.base_opcode == 0xfae && i.tm.cpu_flags.bitfield.cpusse)
+ /* vldmxcsr / vstmxcsr */
+ || (i.tm.base_opcode == 0xae && i.tm.cpu_flags.bitfield.cpuavx)
|| i.tm.cpu_flags.bitfield.cpuwidekl
|| i.tm.cpu_flags.bitfield.cpukl)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_XMM;
+
if ((i.xstate & xstate_ymm) == xstate_ymm)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_YMM;
if ((i.xstate & xstate_zmm) == xstate_zmm)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT;
if (i.tm.cpu_flags.bitfield.cpuxsavec)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_XSAVEC;
+
+ if (x86_feature_2_used
+ || i.tm.cpu_flags.bitfield.cpucmov
+ || i.tm.cpu_flags.bitfield.cpusyscall
+ || (i.tm.base_opcode == 0xfc7
+ && i.tm.opcode_modifier.opcodeprefix == 0
+ && i.tm.extension_opcode == 1) /* cmpxchg8b */)
+ x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_BASELINE;
+ if (i.tm.cpu_flags.bitfield.cpusse3
+ || i.tm.cpu_flags.bitfield.cpussse3
+ || i.tm.cpu_flags.bitfield.cpusse4_1
+ || i.tm.cpu_flags.bitfield.cpusse4_2
+ || i.tm.cpu_flags.bitfield.cpucx16
+ || i.tm.cpu_flags.bitfield.cpupopcnt
+ /* LAHF-SAHF insns in 64-bit mode. */
+ || (flag_code == CODE_64BIT
+ && (i.tm.base_opcode | 1) == 0x9f))
+ x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_V2;
+ if (i.tm.cpu_flags.bitfield.cpuavx
+ || i.tm.cpu_flags.bitfield.cpuavx2
+ /* Any VEX encoded insns execpt for CpuAVX512F, CpuAVX512BW,
+ CpuAVX512DQ, LPW, TBM and AMX. */
+ || (i.tm.opcode_modifier.vex
+ && !i.tm.cpu_flags.bitfield.cpuavx512f
+ && !i.tm.cpu_flags.bitfield.cpuavx512bw
+ && !i.tm.cpu_flags.bitfield.cpuavx512dq
+ && !i.tm.cpu_flags.bitfield.cpulwp
+ && !i.tm.cpu_flags.bitfield.cputbm
+ && !(x86_feature_2_used & GNU_PROPERTY_X86_FEATURE_2_TMM))
+ || i.tm.cpu_flags.bitfield.cpuf16c
+ || i.tm.cpu_flags.bitfield.cpufma
+ || i.tm.cpu_flags.bitfield.cpulzcnt
+ || i.tm.cpu_flags.bitfield.cpumovbe
+ || i.tm.cpu_flags.bitfield.cpuxsaves
+ || (x86_feature_2_used
+ & (GNU_PROPERTY_X86_FEATURE_2_XSAVE
+ | GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT
+ | GNU_PROPERTY_X86_FEATURE_2_XSAVEC)) != 0)
+ x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_V3;
+ if (i.tm.cpu_flags.bitfield.cpuavx512f
+ || i.tm.cpu_flags.bitfield.cpuavx512bw
+ || i.tm.cpu_flags.bitfield.cpuavx512dq
+ || i.tm.cpu_flags.bitfield.cpuavx512vl
+ /* Any EVEX encoded insns except for AVX512ER, AVX512PF and
+ VNNIW. */
+ || (i.tm.opcode_modifier.evex
+ && !i.tm.cpu_flags.bitfield.cpuavx512er
+ && !i.tm.cpu_flags.bitfield.cpuavx512pf
+ && !i.tm.cpu_flags.bitfield.cpuavx512_4vnniw))
+ x86_isa_1_used |= GNU_PROPERTY_X86_ISA_1_V4;
}
#endif
int len;
const enum bfd_reloc_code_real rel[2];
const i386_operand_type types64;
+ bfd_boolean need_GOT_symbol;
} gotrel[] = {
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
{ STRING_COMMA_LEN ("SIZE"), { BFD_RELOC_SIZE32,
BFD_RELOC_SIZE32 },
- OPERAND_TYPE_IMM32_64 },
+ OPERAND_TYPE_IMM32_64, FALSE },
#endif
{ STRING_COMMA_LEN ("PLTOFF"), { _dummy_first_bfd_reloc_code_real,
BFD_RELOC_X86_64_PLTOFF64 },
- OPERAND_TYPE_IMM64 },
+ OPERAND_TYPE_IMM64, TRUE },
{ STRING_COMMA_LEN ("PLT"), { BFD_RELOC_386_PLT32,
BFD_RELOC_X86_64_PLT32 },
- OPERAND_TYPE_IMM32_32S_DISP32 },
+ OPERAND_TYPE_IMM32_32S_DISP32, FALSE },
{ STRING_COMMA_LEN ("GOTPLT"), { _dummy_first_bfd_reloc_code_real,
BFD_RELOC_X86_64_GOTPLT64 },
- OPERAND_TYPE_IMM64_DISP64 },
+ OPERAND_TYPE_IMM64_DISP64, TRUE },
{ STRING_COMMA_LEN ("GOTOFF"), { BFD_RELOC_386_GOTOFF,
BFD_RELOC_X86_64_GOTOFF64 },
- OPERAND_TYPE_IMM64_DISP64 },
+ OPERAND_TYPE_IMM64_DISP64, TRUE },
{ STRING_COMMA_LEN ("GOTPCREL"), { _dummy_first_bfd_reloc_code_real,
BFD_RELOC_X86_64_GOTPCREL },
- OPERAND_TYPE_IMM32_32S_DISP32 },
+ OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
{ STRING_COMMA_LEN ("TLSGD"), { BFD_RELOC_386_TLS_GD,
BFD_RELOC_X86_64_TLSGD },
- OPERAND_TYPE_IMM32_32S_DISP32 },
+ OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
{ STRING_COMMA_LEN ("TLSLDM"), { BFD_RELOC_386_TLS_LDM,
_dummy_first_bfd_reloc_code_real },
- OPERAND_TYPE_NONE },
+ OPERAND_TYPE_NONE, TRUE },
{ STRING_COMMA_LEN ("TLSLD"), { _dummy_first_bfd_reloc_code_real,
BFD_RELOC_X86_64_TLSLD },
- OPERAND_TYPE_IMM32_32S_DISP32 },
+ OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
{ STRING_COMMA_LEN ("GOTTPOFF"), { BFD_RELOC_386_TLS_IE_32,
BFD_RELOC_X86_64_GOTTPOFF },
- OPERAND_TYPE_IMM32_32S_DISP32 },
+ OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
{ STRING_COMMA_LEN ("TPOFF"), { BFD_RELOC_386_TLS_LE_32,
BFD_RELOC_X86_64_TPOFF32 },
- OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
+ OPERAND_TYPE_IMM32_32S_64_DISP32_64, TRUE },
{ STRING_COMMA_LEN ("NTPOFF"), { BFD_RELOC_386_TLS_LE,
_dummy_first_bfd_reloc_code_real },
- OPERAND_TYPE_NONE },
+ OPERAND_TYPE_NONE, TRUE },
{ STRING_COMMA_LEN ("DTPOFF"), { BFD_RELOC_386_TLS_LDO_32,
BFD_RELOC_X86_64_DTPOFF32 },
- OPERAND_TYPE_IMM32_32S_64_DISP32_64 },
+ OPERAND_TYPE_IMM32_32S_64_DISP32_64, TRUE },
{ STRING_COMMA_LEN ("GOTNTPOFF"),{ BFD_RELOC_386_TLS_GOTIE,
_dummy_first_bfd_reloc_code_real },
- OPERAND_TYPE_NONE },
+ OPERAND_TYPE_NONE, TRUE },
{ STRING_COMMA_LEN ("INDNTPOFF"),{ BFD_RELOC_386_TLS_IE,
_dummy_first_bfd_reloc_code_real },
- OPERAND_TYPE_NONE },
+ OPERAND_TYPE_NONE, TRUE },
{ STRING_COMMA_LEN ("GOT"), { BFD_RELOC_386_GOT32,
BFD_RELOC_X86_64_GOT32 },
- OPERAND_TYPE_IMM32_32S_64_DISP32 },
+ OPERAND_TYPE_IMM32_32S_64_DISP32, TRUE },
{ STRING_COMMA_LEN ("TLSDESC"), { BFD_RELOC_386_TLS_GOTDESC,
BFD_RELOC_X86_64_GOTPC32_TLSDESC },
- OPERAND_TYPE_IMM32_32S_DISP32 },
+ OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
{ STRING_COMMA_LEN ("TLSCALL"), { BFD_RELOC_386_TLS_DESC_CALL,
BFD_RELOC_X86_64_TLSDESC_CALL },
- OPERAND_TYPE_IMM32_32S_DISP32 },
+ OPERAND_TYPE_IMM32_32S_DISP32, TRUE },
};
char *cp;
unsigned int j;
*types = gotrel[j].types64;
}
- if (j != 0 && GOT_symbol == NULL)
+ if (gotrel[j].need_GOT_symbol && GOT_symbol == NULL)
GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
/* The length of the first part of our input line. */
kind = "string address";
- if (current_templates->start->opcode_modifier.repprefixok)
+ if (current_templates->start->opcode_modifier.prefixok == PrefixRep)
{
int es_op = current_templates->end[-1].opcode_modifier.isstring
- IS_STRING_ES_OP0;
list = bfd_target_list ();
for (l = list; *l != NULL; l++)
- if (CONST_STRNEQ (*l, "elf64-x86-64")
+ if (startswith (*l, "elf64-x86-64")
|| strcmp (*l, "coff-x86-64") == 0
|| strcmp (*l, "pe-x86-64") == 0
|| strcmp (*l, "pei-x86-64") == 0
list = bfd_target_list ();
for (l = list; *l != NULL; l++)
- if (CONST_STRNEQ (*l, "elf32-x86-64"))
+ if (startswith (*l, "elf32-x86-64"))
{
default_arch = "x86_64:32";
break;
bfd_vma
x86_64_section_word (char *str, size_t len)
{
- if (len == 5 && flag_code == CODE_64BIT && CONST_STRNEQ (str, "large"))
+ if (len == 5 && flag_code == CODE_64BIT && startswith (str, "large"))
return SHF_X86_64_LARGE;
return -1;