X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-i386.c;h=ca26127f562f1622bb058451c1285a6f1dcfd76c;hb=7766fd10024dc0587838fbc4608f3f8e30e17a26;hp=610bc2b1fc73b2636530f367d5834da68320e3e5;hpb=bad6e36d96dcfe09dc4bec0fcda12bf4a1bc1b28;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 610bc2b1fc..ca26127f56 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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; @@ -730,237 +745,266 @@ 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 (".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, 0 }, + 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 }, }; #ifdef I386COFF @@ -1334,9 +1378,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: @@ -1351,10 +1397,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 (); @@ -1370,9 +1419,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; @@ -1389,9 +1440,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: @@ -1408,9 +1461,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; @@ -1433,8 +1488,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; @@ -1451,8 +1508,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; @@ -1469,8 +1528,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; @@ -1480,20 +1541,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 @@ -1527,8 +1574,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)) { @@ -1554,6 +1599,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; } @@ -1568,8 +1628,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; @@ -1586,8 +1648,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; @@ -1604,8 +1668,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; @@ -2368,17 +2434,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) { @@ -2398,6 +2457,37 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED) return; } } + + if (*string == '.' && j >= ARRAY_SIZE (cpu_arch)) + { + /* Disable an ISA entension. */ + 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); @@ -2511,7 +2601,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) @@ -2534,7 +2624,7 @@ md_begin (void) } if (optab->name == NULL) break; - core_optab = (templates *) xmalloc (sizeof (templates)); + core_optab = XNEW (templates); core_optab->start = optab; } } @@ -3459,7 +3549,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. */ @@ -3477,9 +3567,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; @@ -3520,7 +3613,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 @@ -3585,10 +3678,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 @@ -3857,6 +3955,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]; @@ -4132,6 +4231,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); @@ -4575,7 +4675,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) @@ -4642,14 +4744,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; @@ -4678,6 +4780,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; @@ -4705,10 +4820,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. */ @@ -4721,6 +4838,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; @@ -4846,11 +4971,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]); @@ -4902,9 +5029,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]); @@ -4922,6 +5051,7 @@ check_reverse: i.types[4], operand_types[4])) continue; + /* Fall through. */ case 4: if (!operand_type_match (overlap3, i.types[3]) || (check_register @@ -4932,6 +5062,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 @@ -5274,6 +5405,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; @@ -5559,7 +5691,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 @@ -5840,6 +5972,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 @@ -6857,6 +7008,7 @@ output_jump (void) { case 2: *p++ = i.tm.base_opcode >> 8; + /* Fall through. */ case 1: *p++ = i.tm.base_opcode; break; @@ -7603,7 +7755,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 @@ -7711,7 +7863,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 @@ -8431,7 +8583,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]; @@ -8501,6 +8653,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 { @@ -8582,6 +8751,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. */ @@ -8721,6 +8933,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) @@ -8898,6 +9112,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 @@ -9337,11 +9553,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; @@ -9378,7 +9589,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; @@ -9484,17 +9695,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.cpuregxmm) return (const reg_entry *) NULL; - if (r->reg_type.bitfield.regxmm && !cpu_arch_flags.bitfield.cpusse) + if (r->reg_type.bitfield.regymm && !cpu_arch_flags.bitfield.cpuregymm) return (const reg_entry *) NULL; - if (r->reg_type.bitfield.regymm && !cpu_arch_flags.bitfield.cpuavx) + if (r->reg_type.bitfield.regzmm && !cpu_arch_flags.bitfield.cpuregzmm) 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.regmask + && !cpu_arch_flags.bitfield.cpuregmask) return (const reg_entry *) NULL; /* Don't allow fake index register unless allow_index_reg isn't 0. */ @@ -9698,10 +9912,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) { @@ -9793,7 +10007,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 != '/') @@ -9805,7 +10019,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 == '.') @@ -9839,16 +10057,10 @@ md_parse_option (int c, char *arg) /* ISA entension. */ 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) { @@ -9867,12 +10079,44 @@ md_parse_option (int c, char *arg) } } + if (j >= ARRAY_SIZE (cpu_arch)) + { + /* Disable an ISA entension. */ + 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: @@ -10028,17 +10272,11 @@ md_parse_option (int c, char *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: @@ -10050,6 +10288,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) { @@ -10094,34 +10370,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); } @@ -10255,7 +10516,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); } @@ -10489,6 +10750,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: @@ -10541,6 +10803,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) code = fixp->fx_r_type; break; } + /* Fall through. */ default: if (fixp->fx_pcrel) { @@ -10599,8 +10862,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; @@ -10781,7 +11044,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) {