X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-i386.c;h=12b3032a0d04d180621bef5fb4d84eb7618adfe8;hb=33eaf5de31b248f84ae108cf0cf4e1664db9ee51;hp=d74e870e8bb81fe266d8c68d8f54116bf2ee4a8b;hpb=56ceb5b5405af23eddd12e12d8ba849010120324;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index d74e870e8b..12b3032a0d 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1,5 +1,5 @@ /* tc-i386.c -- Assemble code for the Intel 80386 - Copyright (C) 1989-2015 Free Software Foundation, Inc. + Copyright (C) 1989-2017 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -133,10 +133,18 @@ typedef struct enum processor_type type; /* arch type */ i386_cpu_flags flags; /* cpu feature flags */ unsigned int skip; /* show_arch should skip this. */ - unsigned int negated; /* turn off indicated flags. */ } arch_entry; +/* Used to turn off indicated flags. */ +typedef struct +{ + const char *name; /* arch name */ + unsigned int len; /* arch string length */ + i386_cpu_flags flags; /* cpu feature flags */ +} +noarch_entry; + static void update_code_flag (int, int); static void set_code_flag (int); static void set_16bit_gcc_code_flag (int); @@ -165,7 +173,7 @@ static void swap_operands (void); static void swap_2_operands (int, int); static void optimize_imm (void); static void optimize_disp (void); -static const insn_template *match_template (void); +static const insn_template *match_template (char); static int check_string (void); static int process_suffix (void); static int check_byte_reg (void); @@ -318,6 +326,9 @@ struct _i386_insn explicit segment overrides are given. */ const seg_entry *seg[2]; + /* Copied first memory operand string, for re-checking. */ + char *memop1_string; + /* PREFIX holds all the given prefix opcodes (usually null). PREFIXES is the number of prefix opcodes. */ unsigned int prefixes; @@ -527,6 +538,10 @@ static int shared = 0; 0 if att syntax. */ static int intel_syntax = 0; +/* 1 for Intel64 ISA, + 0 if AMD64 ISA. */ +static int intel64; + /* 1 for intel mnemonic, 0 if att mnemonic. */ static int intel_mnemonic = !SYSV386_COMPAT; @@ -540,7 +555,7 @@ static int allow_pseudo_reg = 0; /* 1 if register prefix % not required. */ static int allow_naked_reg = 0; -/* 1 if the assembler should add BND prefix for all control-tranferring +/* 1 if the assembler should add BND prefix for all control-transferring instructions supporting it, even if this prefix wasn't specified explicitly. */ static int add_bnd_prefix = 0; @@ -552,6 +567,15 @@ static int allow_index_reg = 0; specified explicitly. */ static int omit_lock_prefix = 0; +/* 1 if the assembler should encode lfence, mfence, and sfence as + "lock addl $0, (%{re}sp)". */ +static int avoid_fence = 0; + +/* 1 if the assembler should generate relax relocations. */ + +static int generate_relax_relocations + = DEFAULT_GENERATE_X86_RELAX_RELOCATIONS; + static enum check_kind { check_none = 0, @@ -721,235 +745,269 @@ static const arch_entry cpu_arch[] = /* Do not replace the first two entries - i386_target_format() relies on them being there in this order. */ { STRING_COMMA_LEN ("generic32"), PROCESSOR_GENERIC32, - CPU_GENERIC32_FLAGS, 0, 0 }, + CPU_GENERIC32_FLAGS, 0 }, { STRING_COMMA_LEN ("generic64"), PROCESSOR_GENERIC64, - CPU_GENERIC64_FLAGS, 0, 0 }, + CPU_GENERIC64_FLAGS, 0 }, { STRING_COMMA_LEN ("i8086"), PROCESSOR_UNKNOWN, - CPU_NONE_FLAGS, 0, 0 }, + CPU_NONE_FLAGS, 0 }, { STRING_COMMA_LEN ("i186"), PROCESSOR_UNKNOWN, - CPU_I186_FLAGS, 0, 0 }, + CPU_I186_FLAGS, 0 }, { STRING_COMMA_LEN ("i286"), PROCESSOR_UNKNOWN, - CPU_I286_FLAGS, 0, 0 }, + CPU_I286_FLAGS, 0 }, { STRING_COMMA_LEN ("i386"), PROCESSOR_I386, - CPU_I386_FLAGS, 0, 0 }, + CPU_I386_FLAGS, 0 }, { STRING_COMMA_LEN ("i486"), PROCESSOR_I486, - CPU_I486_FLAGS, 0, 0 }, + CPU_I486_FLAGS, 0 }, { STRING_COMMA_LEN ("i586"), PROCESSOR_PENTIUM, - CPU_I586_FLAGS, 0, 0 }, + CPU_I586_FLAGS, 0 }, { STRING_COMMA_LEN ("i686"), PROCESSOR_PENTIUMPRO, - CPU_I686_FLAGS, 0, 0 }, + CPU_I686_FLAGS, 0 }, { STRING_COMMA_LEN ("pentium"), PROCESSOR_PENTIUM, - CPU_I586_FLAGS, 0, 0 }, + CPU_I586_FLAGS, 0 }, { STRING_COMMA_LEN ("pentiumpro"), PROCESSOR_PENTIUMPRO, - CPU_PENTIUMPRO_FLAGS, 0, 0 }, + CPU_PENTIUMPRO_FLAGS, 0 }, { STRING_COMMA_LEN ("pentiumii"), PROCESSOR_PENTIUMPRO, - CPU_P2_FLAGS, 0, 0 }, + CPU_P2_FLAGS, 0 }, { STRING_COMMA_LEN ("pentiumiii"),PROCESSOR_PENTIUMPRO, - CPU_P3_FLAGS, 0, 0 }, + CPU_P3_FLAGS, 0 }, { STRING_COMMA_LEN ("pentium4"), PROCESSOR_PENTIUM4, - CPU_P4_FLAGS, 0, 0 }, + CPU_P4_FLAGS, 0 }, { STRING_COMMA_LEN ("prescott"), PROCESSOR_NOCONA, - CPU_CORE_FLAGS, 0, 0 }, + CPU_CORE_FLAGS, 0 }, { STRING_COMMA_LEN ("nocona"), PROCESSOR_NOCONA, - CPU_NOCONA_FLAGS, 0, 0 }, + CPU_NOCONA_FLAGS, 0 }, { STRING_COMMA_LEN ("yonah"), PROCESSOR_CORE, - CPU_CORE_FLAGS, 1, 0 }, + CPU_CORE_FLAGS, 1 }, { STRING_COMMA_LEN ("core"), PROCESSOR_CORE, - CPU_CORE_FLAGS, 0, 0 }, + CPU_CORE_FLAGS, 0 }, { STRING_COMMA_LEN ("merom"), PROCESSOR_CORE2, - CPU_CORE2_FLAGS, 1, 0 }, + CPU_CORE2_FLAGS, 1 }, { STRING_COMMA_LEN ("core2"), PROCESSOR_CORE2, - CPU_CORE2_FLAGS, 0, 0 }, + CPU_CORE2_FLAGS, 0 }, { STRING_COMMA_LEN ("corei7"), PROCESSOR_COREI7, - CPU_COREI7_FLAGS, 0, 0 }, + CPU_COREI7_FLAGS, 0 }, { STRING_COMMA_LEN ("l1om"), PROCESSOR_L1OM, - CPU_L1OM_FLAGS, 0, 0 }, + CPU_L1OM_FLAGS, 0 }, { STRING_COMMA_LEN ("k1om"), PROCESSOR_K1OM, - CPU_K1OM_FLAGS, 0, 0 }, + CPU_K1OM_FLAGS, 0 }, { STRING_COMMA_LEN ("iamcu"), PROCESSOR_IAMCU, - CPU_IAMCU_FLAGS, 0, 0 }, + CPU_IAMCU_FLAGS, 0 }, { STRING_COMMA_LEN ("k6"), PROCESSOR_K6, - CPU_K6_FLAGS, 0, 0 }, + CPU_K6_FLAGS, 0 }, { STRING_COMMA_LEN ("k6_2"), PROCESSOR_K6, - CPU_K6_2_FLAGS, 0, 0 }, + CPU_K6_2_FLAGS, 0 }, { STRING_COMMA_LEN ("athlon"), PROCESSOR_ATHLON, - CPU_ATHLON_FLAGS, 0, 0 }, + CPU_ATHLON_FLAGS, 0 }, { STRING_COMMA_LEN ("sledgehammer"), PROCESSOR_K8, - CPU_K8_FLAGS, 1, 0 }, + CPU_K8_FLAGS, 1 }, { STRING_COMMA_LEN ("opteron"), PROCESSOR_K8, - CPU_K8_FLAGS, 0, 0 }, + CPU_K8_FLAGS, 0 }, { STRING_COMMA_LEN ("k8"), PROCESSOR_K8, - CPU_K8_FLAGS, 0, 0 }, + CPU_K8_FLAGS, 0 }, { STRING_COMMA_LEN ("amdfam10"), PROCESSOR_AMDFAM10, - CPU_AMDFAM10_FLAGS, 0, 0 }, + CPU_AMDFAM10_FLAGS, 0 }, { STRING_COMMA_LEN ("bdver1"), PROCESSOR_BD, - CPU_BDVER1_FLAGS, 0, 0 }, + CPU_BDVER1_FLAGS, 0 }, { STRING_COMMA_LEN ("bdver2"), PROCESSOR_BD, - CPU_BDVER2_FLAGS, 0, 0 }, + CPU_BDVER2_FLAGS, 0 }, { STRING_COMMA_LEN ("bdver3"), PROCESSOR_BD, - CPU_BDVER3_FLAGS, 0, 0 }, + CPU_BDVER3_FLAGS, 0 }, { STRING_COMMA_LEN ("bdver4"), PROCESSOR_BD, - CPU_BDVER4_FLAGS, 0, 0 }, + CPU_BDVER4_FLAGS, 0 }, { STRING_COMMA_LEN ("znver1"), PROCESSOR_ZNVER, - CPU_ZNVER1_FLAGS, 0, 0 }, + CPU_ZNVER1_FLAGS, 0 }, { STRING_COMMA_LEN ("btver1"), PROCESSOR_BT, - CPU_BTVER1_FLAGS, 0, 0 }, + CPU_BTVER1_FLAGS, 0 }, { STRING_COMMA_LEN ("btver2"), PROCESSOR_BT, - CPU_BTVER2_FLAGS, 0, 0 }, + CPU_BTVER2_FLAGS, 0 }, { STRING_COMMA_LEN (".8087"), PROCESSOR_UNKNOWN, - CPU_8087_FLAGS, 0, 0 }, + CPU_8087_FLAGS, 0 }, { STRING_COMMA_LEN (".287"), PROCESSOR_UNKNOWN, - CPU_287_FLAGS, 0, 0 }, + CPU_287_FLAGS, 0 }, { STRING_COMMA_LEN (".387"), PROCESSOR_UNKNOWN, - CPU_387_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".no87"), PROCESSOR_UNKNOWN, - CPU_ANY87_FLAGS, 0, 1 }, + CPU_387_FLAGS, 0 }, + { STRING_COMMA_LEN (".687"), PROCESSOR_UNKNOWN, + CPU_687_FLAGS, 0 }, { STRING_COMMA_LEN (".mmx"), PROCESSOR_UNKNOWN, - CPU_MMX_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".nommx"), PROCESSOR_UNKNOWN, - CPU_3DNOWA_FLAGS, 0, 1 }, + CPU_MMX_FLAGS, 0 }, { STRING_COMMA_LEN (".sse"), PROCESSOR_UNKNOWN, - CPU_SSE_FLAGS, 0, 0 }, + CPU_SSE_FLAGS, 0 }, { STRING_COMMA_LEN (".sse2"), PROCESSOR_UNKNOWN, - CPU_SSE2_FLAGS, 0, 0 }, + CPU_SSE2_FLAGS, 0 }, { STRING_COMMA_LEN (".sse3"), PROCESSOR_UNKNOWN, - CPU_SSE3_FLAGS, 0, 0 }, + CPU_SSE3_FLAGS, 0 }, { STRING_COMMA_LEN (".ssse3"), PROCESSOR_UNKNOWN, - CPU_SSSE3_FLAGS, 0, 0 }, + CPU_SSSE3_FLAGS, 0 }, { STRING_COMMA_LEN (".sse4.1"), PROCESSOR_UNKNOWN, - CPU_SSE4_1_FLAGS, 0, 0 }, + CPU_SSE4_1_FLAGS, 0 }, { STRING_COMMA_LEN (".sse4.2"), PROCESSOR_UNKNOWN, - CPU_SSE4_2_FLAGS, 0, 0 }, + CPU_SSE4_2_FLAGS, 0 }, { STRING_COMMA_LEN (".sse4"), PROCESSOR_UNKNOWN, - CPU_SSE4_2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".nosse"), PROCESSOR_UNKNOWN, - CPU_ANY_SSE_FLAGS, 0, 1 }, + CPU_SSE4_2_FLAGS, 0 }, { STRING_COMMA_LEN (".avx"), PROCESSOR_UNKNOWN, - CPU_AVX_FLAGS, 0, 0 }, + CPU_AVX_FLAGS, 0 }, { STRING_COMMA_LEN (".avx2"), PROCESSOR_UNKNOWN, - CPU_AVX2_FLAGS, 0, 0 }, + CPU_AVX2_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512f"), PROCESSOR_UNKNOWN, - CPU_AVX512F_FLAGS, 0, 0 }, + CPU_AVX512F_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512cd"), PROCESSOR_UNKNOWN, - CPU_AVX512CD_FLAGS, 0, 0 }, + CPU_AVX512CD_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512er"), PROCESSOR_UNKNOWN, - CPU_AVX512ER_FLAGS, 0, 0 }, + CPU_AVX512ER_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512pf"), PROCESSOR_UNKNOWN, - CPU_AVX512PF_FLAGS, 0, 0 }, + CPU_AVX512PF_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512dq"), PROCESSOR_UNKNOWN, - CPU_AVX512DQ_FLAGS, 0, 0 }, + CPU_AVX512DQ_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512bw"), PROCESSOR_UNKNOWN, - CPU_AVX512BW_FLAGS, 0, 0 }, + CPU_AVX512BW_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512vl"), PROCESSOR_UNKNOWN, - CPU_AVX512VL_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".noavx"), PROCESSOR_UNKNOWN, - CPU_ANY_AVX_FLAGS, 0, 1 }, + CPU_AVX512VL_FLAGS, 0 }, { STRING_COMMA_LEN (".vmx"), PROCESSOR_UNKNOWN, - CPU_VMX_FLAGS, 0, 0 }, + CPU_VMX_FLAGS, 0 }, { STRING_COMMA_LEN (".vmfunc"), PROCESSOR_UNKNOWN, - CPU_VMFUNC_FLAGS, 0, 0 }, + CPU_VMFUNC_FLAGS, 0 }, { STRING_COMMA_LEN (".smx"), PROCESSOR_UNKNOWN, - CPU_SMX_FLAGS, 0, 0 }, + CPU_SMX_FLAGS, 0 }, { STRING_COMMA_LEN (".xsave"), PROCESSOR_UNKNOWN, - CPU_XSAVE_FLAGS, 0, 0 }, + CPU_XSAVE_FLAGS, 0 }, { STRING_COMMA_LEN (".xsaveopt"), PROCESSOR_UNKNOWN, - CPU_XSAVEOPT_FLAGS, 0, 0 }, + CPU_XSAVEOPT_FLAGS, 0 }, { STRING_COMMA_LEN (".xsavec"), PROCESSOR_UNKNOWN, - CPU_XSAVEC_FLAGS, 0, 0 }, + CPU_XSAVEC_FLAGS, 0 }, { STRING_COMMA_LEN (".xsaves"), PROCESSOR_UNKNOWN, - CPU_XSAVES_FLAGS, 0, 0 }, + CPU_XSAVES_FLAGS, 0 }, { STRING_COMMA_LEN (".aes"), PROCESSOR_UNKNOWN, - CPU_AES_FLAGS, 0, 0 }, + CPU_AES_FLAGS, 0 }, { STRING_COMMA_LEN (".pclmul"), PROCESSOR_UNKNOWN, - CPU_PCLMUL_FLAGS, 0, 0 }, + CPU_PCLMUL_FLAGS, 0 }, { STRING_COMMA_LEN (".clmul"), PROCESSOR_UNKNOWN, - CPU_PCLMUL_FLAGS, 1, 0 }, + CPU_PCLMUL_FLAGS, 1 }, { STRING_COMMA_LEN (".fsgsbase"), PROCESSOR_UNKNOWN, - CPU_FSGSBASE_FLAGS, 0, 0 }, + CPU_FSGSBASE_FLAGS, 0 }, { STRING_COMMA_LEN (".rdrnd"), PROCESSOR_UNKNOWN, - CPU_RDRND_FLAGS, 0, 0 }, + CPU_RDRND_FLAGS, 0 }, { STRING_COMMA_LEN (".f16c"), PROCESSOR_UNKNOWN, - CPU_F16C_FLAGS, 0, 0 }, + CPU_F16C_FLAGS, 0 }, { STRING_COMMA_LEN (".bmi2"), PROCESSOR_UNKNOWN, - CPU_BMI2_FLAGS, 0, 0 }, + CPU_BMI2_FLAGS, 0 }, { STRING_COMMA_LEN (".fma"), PROCESSOR_UNKNOWN, - CPU_FMA_FLAGS, 0, 0 }, + CPU_FMA_FLAGS, 0 }, { STRING_COMMA_LEN (".fma4"), PROCESSOR_UNKNOWN, - CPU_FMA4_FLAGS, 0, 0 }, + CPU_FMA4_FLAGS, 0 }, { STRING_COMMA_LEN (".xop"), PROCESSOR_UNKNOWN, - CPU_XOP_FLAGS, 0, 0 }, + CPU_XOP_FLAGS, 0 }, { STRING_COMMA_LEN (".lwp"), PROCESSOR_UNKNOWN, - CPU_LWP_FLAGS, 0, 0 }, + CPU_LWP_FLAGS, 0 }, { STRING_COMMA_LEN (".movbe"), PROCESSOR_UNKNOWN, - CPU_MOVBE_FLAGS, 0, 0 }, + CPU_MOVBE_FLAGS, 0 }, { STRING_COMMA_LEN (".cx16"), PROCESSOR_UNKNOWN, - CPU_CX16_FLAGS, 0, 0 }, + CPU_CX16_FLAGS, 0 }, { STRING_COMMA_LEN (".ept"), PROCESSOR_UNKNOWN, - CPU_EPT_FLAGS, 0, 0 }, + CPU_EPT_FLAGS, 0 }, { STRING_COMMA_LEN (".lzcnt"), PROCESSOR_UNKNOWN, - CPU_LZCNT_FLAGS, 0, 0 }, + CPU_LZCNT_FLAGS, 0 }, { STRING_COMMA_LEN (".hle"), PROCESSOR_UNKNOWN, - CPU_HLE_FLAGS, 0, 0 }, + CPU_HLE_FLAGS, 0 }, { STRING_COMMA_LEN (".rtm"), PROCESSOR_UNKNOWN, - CPU_RTM_FLAGS, 0, 0 }, + CPU_RTM_FLAGS, 0 }, { STRING_COMMA_LEN (".invpcid"), PROCESSOR_UNKNOWN, - CPU_INVPCID_FLAGS, 0, 0 }, + CPU_INVPCID_FLAGS, 0 }, { STRING_COMMA_LEN (".clflush"), PROCESSOR_UNKNOWN, - CPU_CLFLUSH_FLAGS, 0, 0 }, + CPU_CLFLUSH_FLAGS, 0 }, { STRING_COMMA_LEN (".nop"), PROCESSOR_UNKNOWN, - CPU_NOP_FLAGS, 0, 0 }, + CPU_NOP_FLAGS, 0 }, { STRING_COMMA_LEN (".syscall"), PROCESSOR_UNKNOWN, - CPU_SYSCALL_FLAGS, 0, 0 }, + CPU_SYSCALL_FLAGS, 0 }, { STRING_COMMA_LEN (".rdtscp"), PROCESSOR_UNKNOWN, - CPU_RDTSCP_FLAGS, 0, 0 }, + CPU_RDTSCP_FLAGS, 0 }, { STRING_COMMA_LEN (".3dnow"), PROCESSOR_UNKNOWN, - CPU_3DNOW_FLAGS, 0, 0 }, + CPU_3DNOW_FLAGS, 0 }, { STRING_COMMA_LEN (".3dnowa"), PROCESSOR_UNKNOWN, - CPU_3DNOWA_FLAGS, 0, 0 }, + CPU_3DNOWA_FLAGS, 0 }, { STRING_COMMA_LEN (".padlock"), PROCESSOR_UNKNOWN, - CPU_PADLOCK_FLAGS, 0, 0 }, + CPU_PADLOCK_FLAGS, 0 }, { STRING_COMMA_LEN (".pacifica"), PROCESSOR_UNKNOWN, - CPU_SVME_FLAGS, 1, 0 }, + CPU_SVME_FLAGS, 1 }, { STRING_COMMA_LEN (".svme"), PROCESSOR_UNKNOWN, - CPU_SVME_FLAGS, 0, 0 }, + CPU_SVME_FLAGS, 0 }, { STRING_COMMA_LEN (".sse4a"), PROCESSOR_UNKNOWN, - CPU_SSE4A_FLAGS, 0, 0 }, + CPU_SSE4A_FLAGS, 0 }, { STRING_COMMA_LEN (".abm"), PROCESSOR_UNKNOWN, - CPU_ABM_FLAGS, 0, 0 }, + CPU_ABM_FLAGS, 0 }, { STRING_COMMA_LEN (".bmi"), PROCESSOR_UNKNOWN, - CPU_BMI_FLAGS, 0, 0 }, + CPU_BMI_FLAGS, 0 }, { STRING_COMMA_LEN (".tbm"), PROCESSOR_UNKNOWN, - CPU_TBM_FLAGS, 0, 0 }, + CPU_TBM_FLAGS, 0 }, { STRING_COMMA_LEN (".adx"), PROCESSOR_UNKNOWN, - CPU_ADX_FLAGS, 0, 0 }, + CPU_ADX_FLAGS, 0 }, { STRING_COMMA_LEN (".rdseed"), PROCESSOR_UNKNOWN, - CPU_RDSEED_FLAGS, 0, 0 }, + CPU_RDSEED_FLAGS, 0 }, { STRING_COMMA_LEN (".prfchw"), PROCESSOR_UNKNOWN, - CPU_PRFCHW_FLAGS, 0, 0 }, + CPU_PRFCHW_FLAGS, 0 }, { STRING_COMMA_LEN (".smap"), PROCESSOR_UNKNOWN, - CPU_SMAP_FLAGS, 0, 0 }, + CPU_SMAP_FLAGS, 0 }, { STRING_COMMA_LEN (".mpx"), PROCESSOR_UNKNOWN, - CPU_MPX_FLAGS, 0, 0 }, + CPU_MPX_FLAGS, 0 }, { STRING_COMMA_LEN (".sha"), PROCESSOR_UNKNOWN, - CPU_SHA_FLAGS, 0, 0 }, + CPU_SHA_FLAGS, 0 }, { STRING_COMMA_LEN (".clflushopt"), PROCESSOR_UNKNOWN, - CPU_CLFLUSHOPT_FLAGS, 0, 0 }, + CPU_CLFLUSHOPT_FLAGS, 0 }, { STRING_COMMA_LEN (".prefetchwt1"), PROCESSOR_UNKNOWN, - CPU_PREFETCHWT1_FLAGS, 0, 0 }, + CPU_PREFETCHWT1_FLAGS, 0 }, { STRING_COMMA_LEN (".se1"), PROCESSOR_UNKNOWN, - CPU_SE1_FLAGS, 0, 0 }, + CPU_SE1_FLAGS, 0 }, { STRING_COMMA_LEN (".clwb"), PROCESSOR_UNKNOWN, - CPU_CLWB_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".pcommit"), PROCESSOR_UNKNOWN, - CPU_PCOMMIT_FLAGS, 0, 0 }, + CPU_CLWB_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512ifma"), PROCESSOR_UNKNOWN, - CPU_AVX512IFMA_FLAGS, 0, 0 }, + CPU_AVX512IFMA_FLAGS, 0 }, { STRING_COMMA_LEN (".avx512vbmi"), PROCESSOR_UNKNOWN, - CPU_AVX512VBMI_FLAGS, 0, 0 }, + CPU_AVX512VBMI_FLAGS, 0 }, + { STRING_COMMA_LEN (".avx512_4fmaps"), PROCESSOR_UNKNOWN, + CPU_AVX512_4FMAPS_FLAGS, 0 }, + { STRING_COMMA_LEN (".avx512_4vnniw"), PROCESSOR_UNKNOWN, + CPU_AVX512_4VNNIW_FLAGS, 0 }, + { STRING_COMMA_LEN (".avx512_vpopcntdq"), PROCESSOR_UNKNOWN, + CPU_AVX512_VPOPCNTDQ_FLAGS, 0 }, { STRING_COMMA_LEN (".clzero"), PROCESSOR_UNKNOWN, - CPU_CLZERO_FLAGS, 0, 0 }, + CPU_CLZERO_FLAGS, 0 }, { STRING_COMMA_LEN (".mwaitx"), PROCESSOR_UNKNOWN, - CPU_MWAITX_FLAGS, 0, 0 }, + CPU_MWAITX_FLAGS, 0 }, + { STRING_COMMA_LEN (".ospke"), PROCESSOR_UNKNOWN, + CPU_OSPKE_FLAGS, 0 }, + { STRING_COMMA_LEN (".rdpid"), PROCESSOR_UNKNOWN, + CPU_RDPID_FLAGS, 0 }, + { STRING_COMMA_LEN (".ptwrite"), PROCESSOR_UNKNOWN, + CPU_PTWRITE_FLAGS, 0 }, +}; + +static const noarch_entry cpu_noarch[] = +{ + { STRING_COMMA_LEN ("no87"), CPU_ANY_X87_FLAGS }, + { STRING_COMMA_LEN ("no287"), CPU_ANY_287_FLAGS }, + { STRING_COMMA_LEN ("no387"), CPU_ANY_387_FLAGS }, + { STRING_COMMA_LEN ("no687"), CPU_ANY_687_FLAGS }, + { STRING_COMMA_LEN ("nommx"), CPU_ANY_MMX_FLAGS }, + { STRING_COMMA_LEN ("nosse"), CPU_ANY_SSE_FLAGS }, + { STRING_COMMA_LEN ("nosse2"), CPU_ANY_SSE2_FLAGS }, + { STRING_COMMA_LEN ("nosse3"), CPU_ANY_SSE3_FLAGS }, + { STRING_COMMA_LEN ("nossse3"), CPU_ANY_SSSE3_FLAGS }, + { STRING_COMMA_LEN ("nosse4.1"), CPU_ANY_SSE4_1_FLAGS }, + { STRING_COMMA_LEN ("nosse4.2"), CPU_ANY_SSE4_2_FLAGS }, + { STRING_COMMA_LEN ("nosse4"), CPU_ANY_SSE4_1_FLAGS }, + { STRING_COMMA_LEN ("noavx"), CPU_ANY_AVX_FLAGS }, + { STRING_COMMA_LEN ("noavx2"), CPU_ANY_AVX2_FLAGS }, + { STRING_COMMA_LEN ("noavx512f"), CPU_ANY_AVX512F_FLAGS }, + { STRING_COMMA_LEN ("noavx512cd"), CPU_ANY_AVX512CD_FLAGS }, + { STRING_COMMA_LEN ("noavx512er"), CPU_ANY_AVX512ER_FLAGS }, + { STRING_COMMA_LEN ("noavx512pf"), CPU_ANY_AVX512PF_FLAGS }, + { STRING_COMMA_LEN ("noavx512dq"), CPU_ANY_AVX512DQ_FLAGS }, + { STRING_COMMA_LEN ("noavx512bw"), CPU_ANY_AVX512BW_FLAGS }, + { STRING_COMMA_LEN ("noavx512vl"), CPU_ANY_AVX512VL_FLAGS }, + { STRING_COMMA_LEN ("noavx512ifma"), CPU_ANY_AVX512IFMA_FLAGS }, + { STRING_COMMA_LEN ("noavx512vbmi"), CPU_ANY_AVX512VBMI_FLAGS }, + { STRING_COMMA_LEN ("noavx512_4fmaps"), CPU_ANY_AVX512_4FMAPS_FLAGS }, + { STRING_COMMA_LEN ("noavx512_4vnniw"), CPU_ANY_AVX512_4VNNIW_FLAGS }, + { STRING_COMMA_LEN ("noavx512_vpopcntdq"), CPU_ANY_AVX512_VPOPCNTDQ_FLAGS }, }; #ifdef I386COFF @@ -1054,95 +1112,95 @@ i386_align_code (fragS *fragP, int count) /* Various efficient no-op patterns for aligning code labels. Note: Don't try to assemble the instructions in the comments. 0L and 0w are not legal. */ - static const char f32_1[] = + static const unsigned char f32_1[] = {0x90}; /* nop */ - static const char f32_2[] = + static const unsigned char f32_2[] = {0x66,0x90}; /* xchg %ax,%ax */ - static const char f32_3[] = + static const unsigned char f32_3[] = {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */ - static const char f32_4[] = + static const unsigned char f32_4[] = {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ - static const char f32_5[] = + static const unsigned char f32_5[] = {0x90, /* nop */ 0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ - static const char f32_6[] = + static const unsigned char f32_6[] = {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */ - static const char f32_7[] = + static const unsigned char f32_7[] = {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ - static const char f32_8[] = + static const unsigned char f32_8[] = {0x90, /* nop */ 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ - static const char f32_9[] = + static const unsigned char f32_9[] = {0x89,0xf6, /* movl %esi,%esi */ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f32_10[] = + static const unsigned char f32_10[] = {0x8d,0x76,0x00, /* leal 0(%esi),%esi */ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f32_11[] = + static const unsigned char f32_11[] = {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f32_12[] = + static const unsigned char f32_12[] = {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ 0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */ - static const char f32_13[] = + static const unsigned char f32_13[] = {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f32_14[] = + static const unsigned char f32_14[] = {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f16_3[] = + static const unsigned char f16_3[] = {0x8d,0x74,0x00}; /* lea 0(%esi),%esi */ - static const char f16_4[] = + static const unsigned char f16_4[] = {0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */ - static const char f16_5[] = + static const unsigned char f16_5[] = {0x90, /* nop */ 0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */ - static const char f16_6[] = + static const unsigned char f16_6[] = {0x89,0xf6, /* mov %si,%si */ 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */ - static const char f16_7[] = + static const unsigned char f16_7[] = {0x8d,0x74,0x00, /* lea 0(%si),%si */ 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */ - static const char f16_8[] = + static const unsigned char f16_8[] = {0x8d,0xb4,0x00,0x00, /* lea 0w(%si),%si */ 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */ - static const char jump_31[] = + static const unsigned char jump_31[] = {0xeb,0x1d,0x90,0x90,0x90,0x90,0x90, /* jmp .+31; lotsa nops */ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; - static const char *const f32_patt[] = { + static const unsigned char *const f32_patt[] = { f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8, f32_9, f32_10, f32_11, f32_12, f32_13, f32_14 }; - static const char *const f16_patt[] = { + static const unsigned char *const f16_patt[] = { f32_1, f32_2, f16_3, f16_4, f16_5, f16_6, f16_7, f16_8 }; /* nopl (%[re]ax) */ - static const char alt_3[] = + static const unsigned char alt_3[] = {0x0f,0x1f,0x00}; /* nopl 0(%[re]ax) */ - static const char alt_4[] = + static const unsigned char alt_4[] = {0x0f,0x1f,0x40,0x00}; /* nopl 0(%[re]ax,%[re]ax,1) */ - static const char alt_5[] = + static const unsigned char alt_5[] = {0x0f,0x1f,0x44,0x00,0x00}; /* nopw 0(%[re]ax,%[re]ax,1) */ - static const char alt_6[] = + static const unsigned char alt_6[] = {0x66,0x0f,0x1f,0x44,0x00,0x00}; /* nopl 0L(%[re]ax) */ - static const char alt_7[] = + static const unsigned char alt_7[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; /* nopl 0L(%[re]ax,%[re]ax,1) */ - static const char alt_8[] = + static const unsigned char alt_8[] = {0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; /* nopw 0L(%[re]ax,%[re]ax,1) */ - static const char alt_9[] = + static const unsigned char alt_9[] = {0x66,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; /* nopw %cs:0L(%[re]ax,%[re]ax,1) */ - static const char alt_10[] = + static const unsigned char alt_10[] = {0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - static const char *const alt_patt[] = { + static const unsigned char *const alt_patt[] = { f32_1, f32_2, alt_3, alt_4, alt_5, alt_6, alt_7, alt_8, alt_9, alt_10 }; @@ -1180,7 +1238,7 @@ i386_align_code (fragS *fragP, int count) } else { - const char *const *patt = NULL; + const unsigned char *const *patt = NULL; if (fragP->tc_frag_data.isa == PROCESSOR_UNKNOWN) { @@ -1323,9 +1381,11 @@ operand_type_all_zero (const union i386_operand_type *x) case 3: if (x->array[2]) return 0; + /* Fall through. */ case 2: if (x->array[1]) return 0; + /* Fall through. */ case 1: return !x->array[0]; default: @@ -1340,10 +1400,13 @@ operand_type_set (union i386_operand_type *x, unsigned int v) { case 3: x->array[2] = v; + /* Fall through. */ case 2: x->array[1] = v; + /* Fall through. */ case 1: x->array[0] = v; + /* Fall through. */ break; default: abort (); @@ -1359,9 +1422,11 @@ operand_type_equal (const union i386_operand_type *x, case 3: if (x->array[2] != y->array[2]) return 0; + /* Fall through. */ case 2: if (x->array[1] != y->array[1]) return 0; + /* Fall through. */ case 1: return x->array[0] == y->array[0]; break; @@ -1378,9 +1443,11 @@ cpu_flags_all_zero (const union i386_cpu_flags *x) case 3: if (x->array[2]) return 0; + /* Fall through. */ case 2: if (x->array[1]) return 0; + /* Fall through. */ case 1: return !x->array[0]; default: @@ -1397,9 +1464,11 @@ cpu_flags_equal (const union i386_cpu_flags *x, case 3: if (x->array[2] != y->array[2]) return 0; + /* Fall through. */ case 2: if (x->array[1] != y->array[1]) return 0; + /* Fall through. */ case 1: return x->array[0] == y->array[0]; break; @@ -1422,8 +1491,10 @@ cpu_flags_and (i386_cpu_flags x, i386_cpu_flags y) { case 3: x.array [2] &= y.array [2]; + /* Fall through. */ case 2: x.array [1] &= y.array [1]; + /* Fall through. */ case 1: x.array [0] &= y.array [0]; break; @@ -1440,8 +1511,10 @@ cpu_flags_or (i386_cpu_flags x, i386_cpu_flags y) { case 3: x.array [2] |= y.array [2]; + /* Fall through. */ case 2: x.array [1] |= y.array [1]; + /* Fall through. */ case 1: x.array [0] |= y.array [0]; break; @@ -1458,8 +1531,10 @@ cpu_flags_and_not (i386_cpu_flags x, i386_cpu_flags y) { case 3: x.array [2] &= ~y.array [2]; + /* Fall through. */ case 2: x.array [1] &= ~y.array [1]; + /* Fall through. */ case 1: x.array [0] &= ~y.array [0]; break; @@ -1469,20 +1544,6 @@ cpu_flags_and_not (i386_cpu_flags x, i386_cpu_flags y) return x; } -static int -valid_iamcu_cpu_flags (const i386_cpu_flags *flags) -{ - if (cpu_arch_isa == PROCESSOR_IAMCU) - { - static const i386_cpu_flags iamcu_flags = CPU_IAMCU_COMPAT_FLAGS; - i386_cpu_flags compat_flags; - compat_flags = cpu_flags_and_not (*flags, iamcu_flags); - return cpu_flags_all_zero (&compat_flags); - } - else - return 1; -} - #define CPU_FLAGS_ARCH_MATCH 0x1 #define CPU_FLAGS_64BIT_MATCH 0x2 #define CPU_FLAGS_AES_MATCH 0x4 @@ -1516,8 +1577,6 @@ cpu_flags_match (const insn_template *t) /* This instruction is available only on some archs. */ i386_cpu_flags cpu = cpu_arch_flags; - cpu.bitfield.cpu64 = 0; - cpu.bitfield.cpuno64 = 0; cpu = cpu_flags_and (x, cpu); if (!cpu_flags_all_zero (&cpu)) { @@ -1543,6 +1602,21 @@ cpu_flags_match (const insn_template *t) else match |= CPU_FLAGS_ARCH_MATCH; } + else if (x.bitfield.cpuavx512vl) + { + /* Match AVX512VL. */ + if (cpu.bitfield.cpuavx512vl) + { + /* Need another match. */ + cpu.bitfield.cpuavx512vl = 0; + if (!cpu_flags_all_zero (&cpu)) + match |= CPU_FLAGS_32BIT_MATCH; + else + match |= CPU_FLAGS_ARCH_MATCH; + } + else + match |= CPU_FLAGS_ARCH_MATCH; + } else match |= CPU_FLAGS_32BIT_MATCH; } @@ -1557,8 +1631,10 @@ operand_type_and (i386_operand_type x, i386_operand_type y) { case 3: x.array [2] &= y.array [2]; + /* Fall through. */ case 2: x.array [1] &= y.array [1]; + /* Fall through. */ case 1: x.array [0] &= y.array [0]; break; @@ -1575,8 +1651,10 @@ operand_type_or (i386_operand_type x, i386_operand_type y) { case 3: x.array [2] |= y.array [2]; + /* Fall through. */ case 2: x.array [1] |= y.array [1]; + /* Fall through. */ case 1: x.array [0] |= y.array [0]; break; @@ -1593,8 +1671,10 @@ operand_type_xor (i386_operand_type x, i386_operand_type y) { case 3: x.array [2] ^= y.array [2]; + /* Fall through. */ case 2: x.array [1] ^= y.array [1]; + /* Fall through. */ case 1: x.array [0] ^= y.array [0]; break; @@ -1869,6 +1949,9 @@ register_number (const reg_entry *r) if (r->reg_flags & RegRex) nr += 8; + if (r->reg_flags & RegVRex) + nr += 16; + return nr; } @@ -2354,17 +2437,10 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED) break; } - if (!cpu_arch[j].negated) - flags = cpu_flags_or (cpu_arch_flags, - cpu_arch[j].flags); - else - flags = cpu_flags_and_not (cpu_arch_flags, - cpu_arch[j].flags); + flags = cpu_flags_or (cpu_arch_flags, + cpu_arch[j].flags); - if (!valid_iamcu_cpu_flags (&flags)) - as_fatal (_("`%s' isn't valid for Intel MCU"), - cpu_arch[j].name); - else if (!cpu_flags_equal (&flags, &cpu_arch_flags)) + if (!cpu_flags_equal (&flags, &cpu_arch_flags)) { if (cpu_sub_arch_name) { @@ -2384,6 +2460,37 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED) return; } } + + if (*string == '.' && j >= ARRAY_SIZE (cpu_arch)) + { + /* Disable an ISA extension. */ + for (j = 0; j < ARRAY_SIZE (cpu_noarch); j++) + if (strcmp (string + 1, cpu_noarch [j].name) == 0) + { + flags = cpu_flags_and_not (cpu_arch_flags, + cpu_noarch[j].flags); + if (!cpu_flags_equal (&flags, &cpu_arch_flags)) + { + if (cpu_sub_arch_name) + { + char *name = cpu_sub_arch_name; + cpu_sub_arch_name = concat (name, string, + (const char *) NULL); + free (name); + } + else + cpu_sub_arch_name = xstrdup (string); + cpu_arch_flags = flags; + cpu_arch_isa_flags = flags; + } + (void) restore_line_pointer (e); + demand_empty_rest_of_line (); + return; + } + + j = ARRAY_SIZE (cpu_arch); + } + if (j >= ARRAY_SIZE (cpu_arch)) as_bad (_("no such architecture: `%s'"), string); @@ -2497,7 +2604,7 @@ md_begin (void) /* Setup for loop. */ optab = i386_optab; - core_optab = (templates *) xmalloc (sizeof (templates)); + core_optab = XNEW (templates); core_optab->start = optab; while (1) @@ -2520,7 +2627,7 @@ md_begin (void) } if (optab->name == NULL) break; - core_optab = (templates *) xmalloc (sizeof (templates)); + core_optab = XNEW (templates); core_optab->start = optab; } } @@ -3033,7 +3140,7 @@ build_vex_prefix (const insn_template *t) else register_specifier = 0xf; - /* Use 2-byte VEX prefix by swappping destination and source + /* Use 2-byte VEX prefix by swapping destination and source operand. */ if (!i.swap_operand && i.operands == i.reg_operands @@ -3445,7 +3552,7 @@ void md_assemble (char *line) { unsigned int j; - char mnemonic[MAX_MNEM_SIZE]; + char mnemonic[MAX_MNEM_SIZE], mnem_suffix; const insn_template *t; /* Initialize globals. */ @@ -3463,9 +3570,12 @@ md_assemble (char *line) line = parse_insn (line, mnemonic); if (line == NULL) return; + mnem_suffix = i.suffix; line = parse_operands (line, mnemonic); this_operand = -1; + xfree (i.memop1_string); + i.memop1_string = NULL; if (line == NULL) return; @@ -3506,7 +3616,7 @@ md_assemble (char *line) making sure the overlap of the given operands types is consistent with the template operand types. */ - if (!(t = match_template ())) + if (!(t = match_template (mnem_suffix))) return; if (sse_check != check_none @@ -3571,10 +3681,15 @@ md_assemble (char *line) if (i.bnd_prefix && !i.tm.opcode_modifier.bndprefixok) as_bad (_("expecting valid branch instruction after `bnd'")); - if (i.tm.cpu_flags.bitfield.cpumpx - && flag_code == CODE_64BIT - && i.prefix[ADDR_PREFIX]) - as_bad (_("32-bit address isn't allowed in 64-bit MPX instructions.")); + if (i.tm.cpu_flags.bitfield.cpumpx) + { + if (flag_code == CODE_64BIT && i.prefix[ADDR_PREFIX]) + as_bad (_("32-bit address isn't allowed in 64-bit MPX instructions.")); + else if (flag_code != CODE_16BIT + ? i.prefix[ADDR_PREFIX] + : i.mem_operands && !i.prefix[ADDR_PREFIX]) + as_bad (_("16-bit address isn't allowed in MPX instructions")); + } /* Insert BND prefix. */ if (add_bnd_prefix @@ -3843,6 +3958,7 @@ check_suffix: if (intel_syntax && (intel_float_operand (mnemonic) & 2)) i.suffix = SHORT_MNEM_SUFFIX; else + /* Fall through. */ case BYTE_MNEM_SUFFIX: case QWORD_MNEM_SUFFIX: i.suffix = mnem_p[-1]; @@ -4020,13 +4136,13 @@ parse_operands (char *l, const char *mnemonic) { /* Yes, we've read in another operand. */ unsigned int operand_ok; this_operand = i.operands++; - i.types[this_operand].bitfield.unspecified = 1; if (i.operands > MAX_OPERANDS) { as_bad (_("spurious operands; (%d operands/instruction max)"), MAX_OPERANDS); return NULL; } + i.types[this_operand].bitfield.unspecified = 1; /* Now parse operand adding info to 'i' as we go along. */ END_STRING_AND_SAVE (l); @@ -4118,6 +4234,7 @@ swap_operands (void) case 5: case 4: swap_2_operands (1, i.operands - 2); + /* Fall through. */ case 3: case 2: swap_2_operands (0, i.operands - 1); @@ -4216,6 +4333,8 @@ optimize_imm (void) i.op[op].imms->X_add_number = (((i.op[op].imms->X_add_number & 0xffff) ^ 0x8000) - 0x8000); } +#ifdef BFD64 + /* Store 32-bit immediate in 64-bit for 64-bit BFD. */ if ((i.types[op].bitfield.imm32) && ((i.op[op].imms->X_add_number & ~(((offsetT) 2 << 31) - 1)) == 0)) @@ -4224,6 +4343,7 @@ optimize_imm (void) ^ ((offsetT) 1 << 31)) - ((offsetT) 1 << 31)); } +#endif i.types[op] = operand_type_or (i.types[op], smallest_imm_type (i.op[op].imms->X_add_number)); @@ -4304,6 +4424,8 @@ optimize_disp (void) op_disp = (((op_disp & 0xffff) ^ 0x8000) - 0x8000); i.types[op].bitfield.disp64 = 0; } +#ifdef BFD64 + /* Optimize 64-bit displacement to 32-bit for 64-bit BFD. */ if (i.types[op].bitfield.disp32 && (op_disp & ~(((offsetT) 2 << 31) - 1)) == 0) { @@ -4314,6 +4436,7 @@ optimize_disp (void) op_disp = (op_disp ^ ((offsetT) 1 << 31)) - ((addressT) 1 << 31); i.types[op].bitfield.disp64 = 0; } +#endif if (!op_disp && i.types[op].bitfield.baseindex) { i.types[op].bitfield.disp8 = 0; @@ -4555,7 +4678,9 @@ check_VecOperands (const insn_template *t) && i.op[op].disps->X_op == O_constant) { offsetT value = i.op[op].disps->X_add_number; - int vec_disp8_ok = fits_in_vec_disp8 (value); + int vec_disp8_ok + = (i.disp_encoding != disp_encoding_32bit + && fits_in_vec_disp8 (value)); if (t->operand_types [op].bitfield.vec_disp8) { if (vec_disp8_ok) @@ -4622,14 +4747,14 @@ VEX_check_operands (const insn_template *t) } static const insn_template * -match_template (void) +match_template (char mnem_suffix) { /* Points to template once we've found it. */ const insn_template *t; i386_operand_type overlap0, overlap1, overlap2, overlap3; i386_operand_type overlap4; unsigned int found_reverse_match; - i386_opcode_modifier suffix_check; + i386_opcode_modifier suffix_check, mnemsuf_check; i386_operand_type operand_types [MAX_OPERANDS]; int addr_prefix_disp; unsigned int j; @@ -4658,6 +4783,19 @@ match_template (void) else if (i.suffix == LONG_DOUBLE_MNEM_SUFFIX) suffix_check.no_ldsuf = 1; + memset (&mnemsuf_check, 0, sizeof (mnemsuf_check)); + if (intel_syntax) + { + switch (mnem_suffix) + { + case BYTE_MNEM_SUFFIX: mnemsuf_check.no_bsuf = 1; break; + case WORD_MNEM_SUFFIX: mnemsuf_check.no_wsuf = 1; break; + case SHORT_MNEM_SUFFIX: mnemsuf_check.no_ssuf = 1; break; + case LONG_MNEM_SUFFIX: mnemsuf_check.no_lsuf = 1; break; + case QWORD_MNEM_SUFFIX: mnemsuf_check.no_qsuf = 1; break; + } + } + /* Must have right number of operands. */ i.error = number_of_operands_mismatch; @@ -4685,10 +4823,12 @@ match_template (void) if (intel_mnemonic && t->opcode_modifier.attmnemonic) continue; - /* Check AT&T/Intel syntax. */ + /* Check AT&T/Intel syntax and Intel64/AMD64 ISA. */ i.error = unsupported_syntax; if ((intel_syntax && t->opcode_modifier.attsyntax) - || (!intel_syntax && t->opcode_modifier.intelsyntax)) + || (!intel_syntax && t->opcode_modifier.intelsyntax) + || (intel64 && t->opcode_modifier.amd64) + || (!intel64 && t->opcode_modifier.intel64)) continue; /* Check the suffix, except for some instructions in intel mode. */ @@ -4701,6 +4841,14 @@ match_template (void) || (t->opcode_modifier.no_qsuf && suffix_check.no_qsuf) || (t->opcode_modifier.no_ldsuf && suffix_check.no_ldsuf))) continue; + /* In Intel mode all mnemonic suffixes must be explicitly allowed. */ + if ((t->opcode_modifier.no_bsuf && mnemsuf_check.no_bsuf) + || (t->opcode_modifier.no_wsuf && mnemsuf_check.no_wsuf) + || (t->opcode_modifier.no_lsuf && mnemsuf_check.no_lsuf) + || (t->opcode_modifier.no_ssuf && mnemsuf_check.no_ssuf) + || (t->opcode_modifier.no_qsuf && mnemsuf_check.no_qsuf) + || (t->opcode_modifier.no_ldsuf && mnemsuf_check.no_ldsuf)) + continue; if (!operand_size_match (t)) continue; @@ -4808,7 +4956,7 @@ match_template (void) continue; break; case 2: - /* xchg %eax, %eax is a special case. It is an aliase for nop + /* xchg %eax, %eax is a special case. It is an alias for nop only in 32bit mode and we can use opcode 0x90. In 64bit mode, we can't use 0x90 for xchg %eax, %eax since it should zero-extend %eax to %rax. */ @@ -4826,11 +4974,13 @@ match_template (void) else if (t->opcode_modifier.d) goto check_reverse; } + /* Fall through. */ case 3: /* If we swap operand in encoding, we match the next one. */ if (i.swap_operand && t->opcode_modifier.s) continue; + /* Fall through. */ case 4: case 5: overlap1 = operand_type_and (i.types[1], operand_types[1]); @@ -4882,9 +5032,11 @@ check_reverse: case 5: overlap4 = operand_type_and (i.types[4], operand_types[4]); + /* Fall through. */ case 4: overlap3 = operand_type_and (i.types[3], operand_types[3]); + /* Fall through. */ case 3: overlap2 = operand_type_and (i.types[2], operand_types[2]); @@ -4902,6 +5054,7 @@ check_reverse: i.types[4], operand_types[4])) continue; + /* Fall through. */ case 4: if (!operand_type_match (overlap3, i.types[3]) || (check_register @@ -4912,6 +5065,7 @@ check_reverse: i.types[3], operand_types[3]))) continue; + /* Fall through. */ case 3: /* Here we make use of the fact that there are no reverse match 3 operand instructions, and all 3 @@ -5254,6 +5408,7 @@ process_suffix (void) i.suffix = QWORD_MNEM_SUFFIX; break; } + /* Fall through. */ case CODE_32BIT: if (!i.tm.opcode_modifier.no_lsuf) i.suffix = LONG_MNEM_SUFFIX; @@ -5539,7 +5694,7 @@ check_qword_reg (void) /* Warn if the r prefix on a general reg is missing. */ else if ((i.types[op].bitfield.reg16 || i.types[op].bitfield.reg32) - && (i.tm.operand_types[op].bitfield.reg32 + && (i.tm.operand_types[op].bitfield.reg64 || i.tm.operand_types[op].bitfield.acc)) { /* Prohibit these changes in the 64bit mode, since the @@ -5820,6 +5975,25 @@ duplicate: i.reg_operands--; i.tm.operands--; } + else if (i.tm.opcode_modifier.implicitquadgroup) + { + /* The second operand must be {x,y,z}mmN, where N is a multiple of 4. */ + gas_assert (i.operands >= 2 + && (operand_type_equal (&i.types[1], ®xmm) + || operand_type_equal (&i.types[1], ®ymm) + || operand_type_equal (&i.types[1], ®zmm))); + unsigned int regnum = register_number (i.op[1].regs); + unsigned int first_reg_in_group = regnum & ~3; + unsigned int last_reg_in_group = first_reg_in_group + 3; + if (regnum != first_reg_in_group) { + as_warn (_("the second source register `%s%s' implicitly denotes" + " `%s%.3s%d' to `%s%.3s%d' source group in `%s'"), + register_prefix, i.op[1].regs->reg_name, + register_prefix, i.op[1].regs->reg_name, first_reg_in_group, + register_prefix, i.op[1].regs->reg_name, last_reg_in_group, + i.tm.name); + } + } else if (i.tm.opcode_modifier.regkludge) { /* The imul $imm, %reg instruction is converted into @@ -6035,7 +6209,7 @@ build_modrm_byte (void) if (i.tm.opcode_modifier.immext) { - /* When ImmExt is set, the immdiate byte is the last + /* When ImmExt is set, the immediate byte is the last operand. */ imm_slot = i.operands - 1; source--; @@ -6837,6 +7011,7 @@ output_jump (void) { case 2: *p++ = i.tm.base_opcode >> 8; + /* Fall through. */ case 1: *p++ = i.tm.base_opcode; break; @@ -6948,6 +7123,22 @@ output_insn (void) unsigned int j; unsigned int prefix; + if (avoid_fence + && i.tm.base_opcode == 0xfae + && i.operands == 1 + && i.imm_operands == 1 + && (i.op[0].imms->X_add_number == 0xe8 + || i.op[0].imms->X_add_number == 0xf0 + || i.op[0].imms->X_add_number == 0xf8)) + { + /* Encode lfence, mfence, and sfence as + f0 83 04 24 00 lock addl $0x0, (%{re}sp). */ + offsetT val = 0x240483f0ULL; + p = frag_more (5); + md_number_to_chars (p, val, 5); + return; + } + /* Some processors fail on LOCK prefix. This options makes assembler ignore LOCK prefix and serves as a workaround. */ if (omit_lock_prefix) @@ -7239,9 +7430,14 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_off) /* Check for "call/jmp *mem", "mov mem, %reg", "test %reg, mem" and "binop mem, %reg" where binop is one of adc, add, and, cmp, or, sbb, sub, xor - instructions. */ - if ((i.rm.mode == 2 - || (i.rm.mode == 0 && i.rm.regmem == 5)) + instructions. Always generate R_386_GOT32X for + "sym*GOT" operand in 32-bit mode. */ + if ((generate_relax_relocations + || (!object_64bit + && i.rm.mode == 0 + && i.rm.regmem == 5)) + && (i.rm.mode == 2 + || (i.rm.mode == 0 && i.rm.regmem == 5)) && ((i.operands == 1 && i.tm.base_opcode == 0xff && (i.rm.reg == 2 || i.rm.reg == 4)) @@ -7562,7 +7758,7 @@ lex_got (enum bfd_reloc_code_real *rel, /* Allocate and copy string. The trailing NUL shouldn't be necessary, but be safe. */ - tmpbuf = (char *) xmalloc (first + second + 2); + tmpbuf = XNEWVEC (char, first + second + 2); memcpy (tmpbuf, input_line_pointer, first); if (second != 0 && *past_reloc != ' ') /* Replace the relocation token with ' ', so that @@ -7670,7 +7866,7 @@ lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED, /* Allocate and copy string. The trailing NUL shouldn't be necessary, but be safe. */ - tmpbuf = (char *) xmalloc (first + second + 2); + tmpbuf = XNEWVEC (char, first + second + 2); memcpy (tmpbuf, input_line_pointer, first); if (second != 0 && *past_reloc != ' ') /* Replace the relocation token with ' ', so that @@ -8390,7 +8586,7 @@ i386_index_check (const char *operand_string) kind = "string address"; - if (current_templates->start->opcode_modifier.w) + if (current_templates->start->opcode_modifier.repprefixok) { i386_operand_type type = current_templates->end[-1].operand_types[0]; @@ -8460,6 +8656,23 @@ bad_address: || i.index_reg->reg_num == RegEiz)) || !i.index_reg->reg_type.bitfield.baseindex))) goto bad_address; + + /* bndmk, bndldx, and bndstx have special restrictions. */ + if (current_templates->start->base_opcode == 0xf30f1b + || (current_templates->start->base_opcode & ~1) == 0x0f1a) + { + /* They cannot use RIP-relative addressing. */ + if (i.base_reg && i.base_reg->reg_num == RegRip) + { + as_bad (_("`%s' cannot be used here"), operand_string); + return 0; + } + + /* bndldx and bndstx ignore their scale factor. */ + if (current_templates->start->base_opcode != 0xf30f1b + && i.log2_scale_factor) + as_warn (_("register scaling is being ignored here")); + } } else { @@ -8541,6 +8754,49 @@ RC_SAE_immediate (const char *imm_start) return 1; } +/* Only string instructions can have a second memory operand, so + reduce current_templates to just those if it contains any. */ +static int +maybe_adjust_templates (void) +{ + const insn_template *t; + + gas_assert (i.mem_operands == 1); + + for (t = current_templates->start; t < current_templates->end; ++t) + if (t->opcode_modifier.isstring) + break; + + if (t < current_templates->end) + { + static templates aux_templates; + bfd_boolean recheck; + + aux_templates.start = t; + for (; t < current_templates->end; ++t) + if (!t->opcode_modifier.isstring) + break; + aux_templates.end = t; + + /* Determine whether to re-check the first memory operand. */ + recheck = (aux_templates.start != current_templates->start + || t != current_templates->end); + + current_templates = &aux_templates; + + if (recheck) + { + i.mem_operands = 0; + if (i.memop1_string != NULL + && i386_index_check (i.memop1_string) == 0) + return 0; + i.mem_operands = 1; + } + } + + return 1; +} + /* Parse OPERAND_STRING into the i386_insn structure I. Returns zero on error. */ @@ -8680,6 +8936,8 @@ i386_att_operand (char *operand_string) char *vop_start; do_memory_reference: + if (i.mem_operands == 1 && !maybe_adjust_templates ()) + return 0; if ((i.mem_operands == 1 && !current_templates->start->opcode_modifier.isstring) || i.mem_operands == 2) @@ -8857,6 +9115,8 @@ i386_att_operand (char *operand_string) if (i386_index_check (operand_string) == 0) return 0; i.types[this_operand].bitfield.mem = 1; + if (i.mem_operands == 0) + i.memop1_string = xstrdup (operand_string); i.mem_operands++; } else @@ -8905,7 +9165,7 @@ elf_symbol_resolved_in_segment_p (symbolS *fr_symbol, offsetT fr_var) { case BFD_RELOC_386_PLT32: case BFD_RELOC_X86_64_PLT32: - /* Symbol with PLT relocatin may be preempted. */ + /* Symbol with PLT relocation may be preempted. */ return 0; default: abort (); @@ -9296,11 +9556,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) fixP->fx_done = 0; return; - case BFD_RELOC_386_GOT32: - case BFD_RELOC_X86_64_GOT32: - value = 0; /* Fully resolved at runtime. No addend. */ - break; - case BFD_RELOC_VTABLE_INHERIT: case BFD_RELOC_VTABLE_ENTRY: fixP->fx_done = 0; @@ -9337,7 +9592,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) md_number_to_chars (p, value, fixP->fx_size); } -char * +const char * md_atof (int type, char *litP, int *sizeP) { /* This outputs the LITTLENUMs in REVERSE order; @@ -9443,17 +9698,20 @@ parse_real_register (char *reg_string, char **end_op) && !cpu_arch_flags.bitfield.cpu387) return (const reg_entry *) NULL; - if (r->reg_type.bitfield.regmmx && !cpu_arch_flags.bitfield.cpummx) + if (r->reg_type.bitfield.regmmx && !cpu_arch_flags.bitfield.cpuregmmx) return (const reg_entry *) NULL; - if (r->reg_type.bitfield.regxmm && !cpu_arch_flags.bitfield.cpusse) + if (r->reg_type.bitfield.regxmm && !cpu_arch_flags.bitfield.cpuregxmm) return (const reg_entry *) NULL; - if (r->reg_type.bitfield.regymm && !cpu_arch_flags.bitfield.cpuavx) + if (r->reg_type.bitfield.regymm && !cpu_arch_flags.bitfield.cpuregymm) return (const reg_entry *) NULL; - if ((r->reg_type.bitfield.regzmm || r->reg_type.bitfield.regmask) - && !cpu_arch_flags.bitfield.cpuavx512f) + if (r->reg_type.bitfield.regzmm && !cpu_arch_flags.bitfield.cpuregzmm) + return (const reg_entry *) NULL; + + if (r->reg_type.bitfield.regmask + && !cpu_arch_flags.bitfield.cpuregmask) return (const reg_entry *) NULL; /* Don't allow fake index register unless allow_index_reg isn't 0. */ @@ -9609,11 +9867,13 @@ const char *md_shortopts = "qn"; #define OPTION_MEVEXLIG (OPTION_MD_BASE + 16) #define OPTION_MEVEXWIG (OPTION_MD_BASE + 17) #define OPTION_MBIG_OBJ (OPTION_MD_BASE + 18) -#define OPTION_OMIT_LOCK_PREFIX (OPTION_MD_BASE + 19) +#define OPTION_MOMIT_LOCK_PREFIX (OPTION_MD_BASE + 19) #define OPTION_MEVEXRCIG (OPTION_MD_BASE + 20) #define OPTION_MSHARED (OPTION_MD_BASE + 21) #define OPTION_MAMD64 (OPTION_MD_BASE + 22) #define OPTION_MINTEL64 (OPTION_MD_BASE + 23) +#define OPTION_MFENCE_AS_LOCK_ADD (OPTION_MD_BASE + 24) +#define OPTION_MRELAX_RELOCATIONS (OPTION_MD_BASE + 25) struct option md_longopts[] = { @@ -9644,7 +9904,9 @@ struct option md_longopts[] = # if defined (TE_PE) || defined (TE_PEP) {"mbig-obj", no_argument, NULL, OPTION_MBIG_OBJ}, #endif - {"momit-lock-prefix", required_argument, NULL, OPTION_OMIT_LOCK_PREFIX}, + {"momit-lock-prefix", required_argument, NULL, OPTION_MOMIT_LOCK_PREFIX}, + {"mfence-as-lock-add", required_argument, NULL, OPTION_MFENCE_AS_LOCK_ADD}, + {"mrelax-relocations", required_argument, NULL, OPTION_MRELAX_RELOCATIONS}, {"mevexrcig", required_argument, NULL, OPTION_MEVEXRCIG}, {"mamd64", no_argument, NULL, OPTION_MAMD64}, {"mintel64", no_argument, NULL, OPTION_MINTEL64}, @@ -9653,10 +9915,10 @@ struct option md_longopts[] = size_t md_longopts_size = sizeof (md_longopts); int -md_parse_option (int c, char *arg) +md_parse_option (int c, const char *arg) { unsigned int j; - char *arch, *next; + char *arch, *next, *saved; switch (c) { @@ -9748,7 +10010,7 @@ md_parse_option (int c, char *arg) char *n, *t; const char *s; - n = (char *) xmalloc (strlen (i386_comment_chars) + 1); + n = XNEWVEC (char, strlen (i386_comment_chars) + 1); t = n; for (s = i386_comment_chars; *s != '\0'; s++) if (*s != '/') @@ -9760,7 +10022,11 @@ md_parse_option (int c, char *arg) break; case OPTION_MARCH: - arch = xstrdup (arg); + saved = xstrdup (arg); + arch = saved; + /* Allow -march=+nosse. */ + if (*arch == '+') + arch++; do { if (*arch == '.') @@ -9791,19 +10057,13 @@ md_parse_option (int c, char *arg) else if (*cpu_arch [j].name == '.' && strcmp (arch, cpu_arch [j].name + 1) == 0) { - /* ISA entension. */ + /* ISA extension. */ i386_cpu_flags flags; - if (!cpu_arch[j].negated) - flags = cpu_flags_or (cpu_arch_flags, - cpu_arch[j].flags); - else - flags = cpu_flags_and_not (cpu_arch_flags, - cpu_arch[j].flags); + flags = cpu_flags_or (cpu_arch_flags, + cpu_arch[j].flags); - if (!valid_iamcu_cpu_flags (&flags)) - as_fatal (_("`%s' isn't valid for Intel MCU"), arch); - else if (!cpu_flags_equal (&flags, &cpu_arch_flags)) + if (!cpu_flags_equal (&flags, &cpu_arch_flags)) { if (cpu_sub_arch_name) { @@ -9822,12 +10082,44 @@ md_parse_option (int c, char *arg) } } + if (j >= ARRAY_SIZE (cpu_arch)) + { + /* Disable an ISA extension. */ + for (j = 0; j < ARRAY_SIZE (cpu_noarch); j++) + if (strcmp (arch, cpu_noarch [j].name) == 0) + { + i386_cpu_flags flags; + + flags = cpu_flags_and_not (cpu_arch_flags, + cpu_noarch[j].flags); + if (!cpu_flags_equal (&flags, &cpu_arch_flags)) + { + if (cpu_sub_arch_name) + { + char *name = cpu_sub_arch_name; + cpu_sub_arch_name = concat (arch, + (const char *) NULL); + free (name); + } + else + cpu_sub_arch_name = xstrdup (arch); + cpu_arch_flags = flags; + cpu_arch_isa_flags = flags; + } + break; + } + + if (j >= ARRAY_SIZE (cpu_noarch)) + j = ARRAY_SIZE (cpu_arch); + } + if (j >= ARRAY_SIZE (cpu_arch)) as_fatal (_("invalid -march= option: `%s'"), arg); arch = next; } - while (next != NULL ); + while (next != NULL); + free (saved); break; case OPTION_MTUNE: @@ -9955,7 +10247,7 @@ md_parse_option (int c, char *arg) break; #endif - case OPTION_OMIT_LOCK_PREFIX: + case OPTION_MOMIT_LOCK_PREFIX: if (strcasecmp (arg, "yes") == 0) omit_lock_prefix = 1; else if (strcasecmp (arg, "no") == 0) @@ -9964,18 +10256,30 @@ md_parse_option (int c, char *arg) as_fatal (_("invalid -momit-lock-prefix= option: `%s'"), arg); break; + case OPTION_MFENCE_AS_LOCK_ADD: + if (strcasecmp (arg, "yes") == 0) + avoid_fence = 1; + else if (strcasecmp (arg, "no") == 0) + avoid_fence = 0; + else + as_fatal (_("invalid -mfence-as-lock-add= option: `%s'"), arg); + break; + + case OPTION_MRELAX_RELOCATIONS: + if (strcasecmp (arg, "yes") == 0) + generate_relax_relocations = 1; + else if (strcasecmp (arg, "no") == 0) + generate_relax_relocations = 0; + else + as_fatal (_("invalid -mrelax-relocations= option: `%s'"), arg); + break; + case OPTION_MAMD64: - cpu_arch_flags.bitfield.cpuamd64 = 1; - cpu_arch_flags.bitfield.cpuintel64 = 0; - cpu_arch_isa_flags.bitfield.cpuamd64 = 1; - cpu_arch_isa_flags.bitfield.cpuintel64 = 0; + intel64 = 0; break; case OPTION_MINTEL64: - cpu_arch_flags.bitfield.cpuamd64 = 0; - cpu_arch_flags.bitfield.cpuintel64 = 1; - cpu_arch_isa_flags.bitfield.cpuamd64 = 0; - cpu_arch_isa_flags.bitfield.cpuintel64 = 1; + intel64 = 1; break; default: @@ -9987,6 +10291,44 @@ md_parse_option (int c, char *arg) #define MESSAGE_TEMPLATE \ " " +static char * +output_message (FILE *stream, char *p, char *message, char *start, + int *left_p, const char *name, int len) +{ + int size = sizeof (MESSAGE_TEMPLATE); + int left = *left_p; + + /* Reserve 2 spaces for ", " or ",\0" */ + left -= len + 2; + + /* Check if there is any room. */ + if (left >= 0) + { + if (p != start) + { + *p++ = ','; + *p++ = ' '; + } + p = mempcpy (p, name, len); + } + else + { + /* Output the current message now and start a new one. */ + *p++ = ','; + *p = '\0'; + fprintf (stream, "%s\n", message); + p = start; + left = size - (start - message) - len - 2; + + gas_assert (left >= 0); + + p = mempcpy (p, name, len); + } + + *left_p = left; + return p; +} + static void show_arch (FILE *stream, int ext, int check) { @@ -10031,34 +10373,19 @@ show_arch (FILE *stream, int ext, int check) continue; } - /* Reserve 2 spaces for ", " or ",\0" */ - left -= len + 2; - - /* Check if there is any room. */ - if (left >= 0) - { - if (p != start) - { - *p++ = ','; - *p++ = ' '; - } - p = mempcpy (p, name, len); - } - else - { - /* Output the current message now and start a new one. */ - *p++ = ','; - *p = '\0'; - fprintf (stream, "%s\n", message); - p = start; - left = size - (start - message) - len - 2; - - gas_assert (left >= 0); - - p = mempcpy (p, name, len); - } + p = output_message (stream, p, message, start, &left, name, len); } + /* Display disabled extensions. */ + if (ext) + for (j = 0; j < ARRAY_SIZE (cpu_noarch); j++) + { + name = cpu_noarch [j].name; + len = cpu_noarch [j].len; + p = output_message (stream, p, message, start, &left, name, + len); + } + *p = '\0'; fprintf (stream, "%s\n", message); } @@ -10144,6 +10471,13 @@ md_show_usage (FILE *stream) -momit-lock-prefix=[no|yes]\n\ strip all lock prefixes\n")); fprintf (stream, _("\ + -mfence-as-lock-add=[no|yes]\n\ + encode lfence, mfence and sfence as\n\ + lock addl $0x0, (%%{re}sp)\n")); + fprintf (stream, _("\ + -mrelax-relocations=[no|yes]\n\ + generate relax relocations\n")); + fprintf (stream, _("\ -mamd64 accept only AMD64 ISA\n")); fprintf (stream, _("\ -mintel64 accept only Intel64 ISA\n")); @@ -10185,7 +10519,7 @@ i386_target_format (void) cpu_arch_tune_flags = cpu_arch_isa_flags; } } - else + else if (cpu_arch_isa != PROCESSOR_IAMCU) as_fatal (_("Intel MCU doesn't support `%s' architecture"), cpu_arch_name); } @@ -10317,7 +10651,7 @@ md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) int align; align = bfd_get_section_alignment (stdoutput, segment); - size = ((size + (1 << align) - 1) & ((valueT) -1 << align)); + size = ((size + (1 << align) - 1) & (-((valueT) 1 << align))); } #endif @@ -10419,6 +10753,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) return NULL; } #endif + /* Fall through. */ case BFD_RELOC_X86_64_PLT32: case BFD_RELOC_X86_64_GOT32: @@ -10471,6 +10806,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) code = fixp->fx_r_type; break; } + /* Fall through. */ default: if (fixp->fx_pcrel) { @@ -10529,8 +10865,8 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) code = BFD_RELOC_X86_64_GOTPC64; } - rel = (arelent *) xmalloc (sizeof (arelent)); - rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + rel = XNEW (arelent); + rel->sym_ptr_ptr = XNEW (asymbol *); *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); rel->address = fixp->fx_frag->fr_address + fixp->fx_where; @@ -10711,7 +11047,7 @@ tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size) /* For ELF on x86-64, add support for SHF_X86_64_LARGE. */ bfd_vma -x86_64_section_letter (int letter, char **ptr_msg) +x86_64_section_letter (int letter, const char **ptr_msg) { if (flag_code == CODE_64BIT) {