From: H.J. Lu Date: Mon, 11 May 2015 18:11:19 +0000 (-0700) Subject: Add Intel MCU support to gas X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=814860358c2e4194d372018dd1ae78b5c95a44d0;p=binutils-gdb.git Add Intel MCU support to gas -march=iamcu must be passed to i386 assembler to generate Intel MCU object file. gas/ * config/tc-i386.c (cpu_arch): Add iamcu. (i386_align_code): Handle PROCESSOR_IAMCU. (i386_arch): Likewise. (i386_mach): Likewise. (i386_target_format): Likewise. (valid_iamcu_cpu_flags): New function. (check_cpu_arch_compatible): Only allow Intel MCU instructions when targeting Intel MCU. (set_cpu_arch): Call valid_iamcu_cpu_flags to check if CPU flags are valid for Intel MCU. (md_parse_option): Likewise. * tc-i386.h (ELF_TARGET_IAMCU_FORMAT): New. (processor_type): Add PROCESSOR_IAMCU. * doc/c-i386.texi: Document iamcu. gas/testsuite/ * gas/i386/i386.exp: Run iamcu-1, iamcu-2, iamcu-3, iamcu-inval-1, iamcu-inval-2 and iamcu-inval-3. * gas/i386/iamcu-1.d: New file. * gas/i386/iamcu-1.s: Likewise. * gas/i386/iamcu-2.d: Likewise. * gas/i386/iamcu-2.s: Likewise. * gas/i386/iamcu-3.d: Likewise. * gas/i386/iamcu-3.s: Likewise. * gas/i386/iamcu-inval-1.l: Likewise. * gas/i386/iamcu-inval-1.s: Likewise. * gas/i386/iamcu-inval-2.l: Likewise. * gas/i386/iamcu-inval-2.s: Likewise. * gas/i386/iamcu-inval-3.l: Likewise. * gas/i386/iamcu-inval-3.s: Likewise. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 19bdb164334..ce9c7338c28 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,20 @@ +2015-05-11 H.J. Lu + + * config/tc-i386.c (cpu_arch): Add iamcu. + (i386_align_code): Handle PROCESSOR_IAMCU. + (i386_arch): Likewise. + (i386_mach): Likewise. + (i386_target_format): Likewise. + (valid_iamcu_cpu_flags): New function. + (check_cpu_arch_compatible): Only allow Intel MCU instructions + when targeting Intel MCU. + (set_cpu_arch): Call valid_iamcu_cpu_flags to check if CPU flags + are valid for Intel MCU. + (md_parse_option): Likewise. + * tc-i386.h (ELF_TARGET_IAMCU_FORMAT): New. + (processor_type): Add PROCESSOR_IAMCU. + * doc/c-i386.texi: Document iamcu. + 2015-05-08 Nick Clifton PR gas/18347 diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index bbc0969da18..8a6da64b03a 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -772,6 +772,8 @@ static const arch_entry cpu_arch[] = CPU_L1OM_FLAGS, 0, 0 }, { STRING_COMMA_LEN ("k1om"), PROCESSOR_K1OM, CPU_K1OM_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("iamcu"), PROCESSOR_IAMCU, + CPU_IAMCU_FLAGS, 0, 0 }, { STRING_COMMA_LEN ("k6"), PROCESSOR_K6, CPU_K6_FLAGS, 0, 0 }, { STRING_COMMA_LEN ("k6_2"), PROCESSOR_K6, @@ -1218,6 +1220,7 @@ i386_align_code (fragS *fragP, int count) case PROCESSOR_I486: case PROCESSOR_PENTIUM: case PROCESSOR_PENTIUMPRO: + case PROCESSOR_IAMCU: case PROCESSOR_GENERIC32: patt = f32_patt; break; @@ -1236,6 +1239,7 @@ i386_align_code (fragS *fragP, int count) case PROCESSOR_I386: case PROCESSOR_I486: case PROCESSOR_PENTIUM: + case PROCESSOR_IAMCU: case PROCESSOR_K6: case PROCESSOR_ATHLON: case PROCESSOR_K8: @@ -1469,6 +1473,20 @@ 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 @@ -2278,6 +2296,11 @@ check_cpu_arch_compatible (const char *name ATTRIBUTE_UNUSED, arch = default_arch; } + /* If we are targeting Intel MCU, we must enable it. */ + if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_IAMCU + || new_flag.bitfield.cpuiamcu) + return; + /* If we are targeting Intel L1OM, we must enable it. */ if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_L1OM || new_flag.bitfield.cpul1om) @@ -2341,7 +2364,11 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED) else flags = cpu_flags_and_not (cpu_arch_flags, cpu_arch[j].flags); - if (!cpu_flags_equal (&flags, &cpu_arch_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_sub_arch_name) { @@ -2406,6 +2433,13 @@ i386_arch (void) as_fatal (_("Intel K1OM is 64bit ELF only")); return bfd_arch_k1om; } + else if (cpu_arch_isa == PROCESSOR_IAMCU) + { + if (OUTPUT_FLAVOR != bfd_target_elf_flavour + || flag_code == CODE_64BIT) + as_fatal (_("Intel MCU is 32bit ELF only")); + return bfd_arch_iamcu; + } else return bfd_arch_i386; } @@ -2435,7 +2469,16 @@ i386_mach (void) return bfd_mach_x64_32; } else if (!strcmp (default_arch, "i386")) - return bfd_mach_i386_i386; + { + if (cpu_arch_isa == PROCESSOR_IAMCU) + { + if (OUTPUT_FLAVOR != bfd_target_elf_flavour) + as_fatal (_("Intel MCU is 32bit ELF only")); + return bfd_mach_i386_iamcu; + } + else + return bfd_mach_i386_i386; + } else as_fatal (_("unknown architecture")); } @@ -9678,7 +9721,10 @@ md_parse_option (int c, char *arg) else flags = cpu_flags_and_not (cpu_arch_flags, cpu_arch[j].flags); - if (!cpu_flags_equal (&flags, &cpu_arch_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_sub_arch_name) { @@ -10088,6 +10134,12 @@ i386_target_format (void) as_fatal (_("Intel K1OM is 64bit only")); return ELF_TARGET_K1OM_FORMAT; } + else if (cpu_arch_isa == PROCESSOR_IAMCU) + { + if (x86_elf_abi != I386_ABI) + as_fatal (_("Intel MCU is 32bit only")); + return ELF_TARGET_IAMCU_FORMAT; + } else return format; } diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index deea9c28b67..40483a12e54 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -90,6 +90,10 @@ extern unsigned long i386_mach (void); #define ELF_TARGET_K1OM_FORMAT "elf64-k1om" #endif +#ifndef ELF_TARGET_IAMCU_FORMAT +#define ELF_TARGET_IAMCU_FORMAT "elf32-iamcu" +#endif + #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \ || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O)) @@ -233,6 +237,7 @@ enum processor_type PROCESSOR_COREI7, PROCESSOR_L1OM, PROCESSOR_K1OM, + PROCESSOR_IAMCU, PROCESSOR_K6, PROCESSOR_ATHLON, PROCESSOR_K8, diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index eb6790cf80b..47bcbbb1337 100644 --- a/gas/doc/c-i386.texi +++ b/gas/doc/c-i386.texi @@ -110,6 +110,7 @@ processor names are recognized: @code{corei7}, @code{l1om}, @code{k1om}, +@code{iamcu}, @code{k6}, @code{k6_2}, @code{athlon}, @@ -1082,7 +1083,7 @@ supported on the CPU specified. The choices for @var{cpu_type} are: @item @samp{i486} @tab @samp{i586} @tab @samp{i686} @tab @samp{pentium} @item @samp{pentiumpro} @tab @samp{pentiumii} @tab @samp{pentiumiii} @tab @samp{pentium4} @item @samp{prescott} @tab @samp{nocona} @tab @samp{core} @tab @samp{core2} -@item @samp{corei7} @tab @samp{l1om} @tab @samp{k1om} +@item @samp{corei7} @tab @samp{l1om} @tab @samp{k1om} @samp{iamcu} @item @samp{k6} @tab @samp{k6_2} @tab @samp{athlon} @tab @samp{k8} @item @samp{amdfam10} @tab @samp{bdver1} @tab @samp{bdver2} @tab @samp{bdver3} @item @samp{bdver4} @tab @samp{znver1} @tab @samp{btver1} @tab @samp{btver2} diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index b3efb8fd3cd..da97ddcbb4a 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,20 @@ +2015-05-11 H.J. Lu + + * gas/i386/i386.exp: Run iamcu-1, iamcu-2, iamcu-3, iamcu-inval-1, + iamcu-inval-2 and iamcu-inval-3. + * gas/i386/iamcu-1.d: New file. + * gas/i386/iamcu-1.s: Likewise. + * gas/i386/iamcu-2.d: Likewise. + * gas/i386/iamcu-2.s: Likewise. + * gas/i386/iamcu-3.d: Likewise. + * gas/i386/iamcu-3.s: Likewise. + * gas/i386/iamcu-inval-1.l: Likewise. + * gas/i386/iamcu-inval-1.s: Likewise. + * gas/i386/iamcu-inval-2.l: Likewise. + * gas/i386/iamcu-inval-2.s: Likewise. + * gas/i386/iamcu-inval-3.l: Likewise. + * gas/i386/iamcu-inval-3.s: Likewise. + 2015-05-08 Nick Clifton PR gas/18347 diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 9492e80e5ff..c66dbc56d45 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -397,6 +397,15 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_dump_test "relax-3" run_dump_test "relax-4" + + if {![istarget "*-*-nacl*"]} then { + run_dump_test "iamcu-1" + run_dump_test "iamcu-2" + run_dump_test "iamcu-3" + run_list_test "iamcu-inval-1" "-march=iamcu -al" + run_list_test "iamcu-inval-2" "-march=iamcu -al" + run_list_test "iamcu-inval-3" "-march=iamcu+sse4 -al" + } } # This is a PE specific test. @@ -414,8 +423,10 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] # Common tests if [expr [istarget "i*86-*-*"] || [istarget "x86_64-*-*"]] then { - run_dump_test "intel-expr" - run_dump_test "string-ok" + if {![istarget "i*86-*-elfiamcu"]} then { + run_dump_test "intel-expr" + run_dump_test "string-ok" + } run_list_test "string-bad" "" run_list_test "reg-bad" "" run_list_test "space1" "-al" diff --git a/gas/testsuite/gas/i386/iamcu-1.d b/gas/testsuite/gas/i386/iamcu-1.d new file mode 100644 index 00000000000..c4d22bf00d9 --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-1.d @@ -0,0 +1,52 @@ +#as: -J -march=iamcu +#objdump: -dw +#not-target: *-*-nacl* + +.*: +file format elf32-iamcu.* + +Disassembly of section .text: + +0+ <.text>: +[ ]*[a-f0-9]+: 66 0f be f0 movsbw %al,%si +[ ]*[a-f0-9]+: 0f be f0 movsbl %al,%esi +[ ]*[a-f0-9]+: 0f bf f0 movswl %ax,%esi +[ ]*[a-f0-9]+: 0f be 10 movsbl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f be 10 movsbw \(%eax\),%dx +[ ]*[a-f0-9]+: 66 0f be 10 movsbw \(%eax\),%dx +[ ]*[a-f0-9]+: 0f be 10 movsbl \(%eax\),%edx +[ ]*[a-f0-9]+: 0f bf 10 movswl \(%eax\),%edx +[ ]*[a-f0-9]+: 0f be 10 movsbl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f be 10 movsbw \(%eax\),%dx +[ ]*[a-f0-9]+: 0f bf 10 movswl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f b6 f0 movzbw %al,%si +[ ]*[a-f0-9]+: 0f b6 f0 movzbl %al,%esi +[ ]*[a-f0-9]+: 0f b7 f0 movzwl %ax,%esi +[ ]*[a-f0-9]+: 0f b6 10 movzbl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f b6 10 movzbw \(%eax\),%dx +[ ]*[a-f0-9]+: 66 0f b6 10 movzbw \(%eax\),%dx +[ ]*[a-f0-9]+: 0f b6 10 movzbl \(%eax\),%edx +[ ]*[a-f0-9]+: 0f b7 10 movzwl \(%eax\),%edx +[ ]*[a-f0-9]+: 0f b6 10 movzbl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f b6 10 movzbw \(%eax\),%dx +[ ]*[a-f0-9]+: 0f b6 10 movzbl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f b6 10 movzbw \(%eax\),%dx +[ ]*[a-f0-9]+: 0f b7 10 movzwl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f be f0 movsbw %al,%si +[ ]*[a-f0-9]+: 0f be f0 movsbl %al,%esi +[ ]*[a-f0-9]+: 0f bf f0 movswl %ax,%esi +[ ]*[a-f0-9]+: 0f be 10 movsbl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f be 10 movsbw \(%eax\),%dx +[ ]*[a-f0-9]+: 0f bf 10 movswl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f b6 f0 movzbw %al,%si +[ ]*[a-f0-9]+: 0f b6 f0 movzbl %al,%esi +[ ]*[a-f0-9]+: 0f b7 f0 movzwl %ax,%esi +[ ]*[a-f0-9]+: 0f b6 10 movzbl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f b6 10 movzbw \(%eax\),%dx +[ ]*[a-f0-9]+: 0f b7 10 movzwl \(%eax\),%edx +[ ]*[a-f0-9]+: 66 0f be 00 movsbw \(%eax\),%ax +[ ]*[a-f0-9]+: 0f be 00 movsbl \(%eax\),%eax +[ ]*[a-f0-9]+: 0f bf 00 movswl \(%eax\),%eax +[ ]*[a-f0-9]+: 66 0f b6 00 movzbw \(%eax\),%ax +[ ]*[a-f0-9]+: 0f b6 00 movzbl \(%eax\),%eax +[ ]*[a-f0-9]+: 0f b7 00 movzwl \(%eax\),%eax +#pass diff --git a/gas/testsuite/gas/i386/iamcu-1.s b/gas/testsuite/gas/i386/iamcu-1.s new file mode 100644 index 00000000000..b631dfa17ef --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-1.s @@ -0,0 +1,51 @@ +# IAMCU instructions + .text + + movsx %al, %si + movsx %al, %esi + movsx %ax, %esi + movsx (%eax), %edx + movsx (%eax), %dx + movsxb (%eax), %dx + movsxb (%eax), %edx + movsxw (%eax), %edx + movsbl (%eax), %edx + movsbw (%eax), %dx + movswl (%eax), %edx + + movzx %al, %si + movzx %al, %esi + movzx %ax, %esi + movzx (%eax), %edx + movzx (%eax), %dx + movzxb (%eax), %dx + movzxb (%eax), %edx + movzxw (%eax), %edx + movzb (%eax), %edx + movzb (%eax), %dx + movzbl (%eax), %edx + movzbw (%eax), %dx + movzwl (%eax), %edx + + .intel_syntax noprefix + + movsx si,al + movsx esi,al + movsx esi,ax + movsx edx,BYTE PTR [eax] + movsx dx,BYTE PTR [eax] + movsx edx,WORD PTR [eax] + + movzx si,al + movzx esi,al + movzx esi,ax + movzx edx,BYTE PTR [eax] + movzx dx,BYTE PTR [eax] + movzx edx,WORD PTR [eax] + + movsx ax, byte ptr [eax] + movsx eax, byte ptr [eax] + movsx eax, word ptr [eax] + movzx ax, byte ptr [eax] + movzx eax, byte ptr [eax] + movzx eax, word ptr [eax] diff --git a/gas/testsuite/gas/i386/iamcu-2.d b/gas/testsuite/gas/i386/iamcu-2.d new file mode 100644 index 00000000000..f3f3bfdb8c9 --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-2.d @@ -0,0 +1,11 @@ +#as: -J -march=iamcu +#objdump: -dw +#not-target: *-*-nacl* + +.*: +file format elf32-iamcu.* + +Disassembly of section .text: + +0+ <.text>: +[ ]*[a-f0-9]+: 66 0f 1f 00 nopw \(%eax\) +#pass diff --git a/gas/testsuite/gas/i386/iamcu-2.s b/gas/testsuite/gas/i386/iamcu-2.s new file mode 100644 index 00000000000..05232776940 --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-2.s @@ -0,0 +1,4 @@ + .text + .arch .nop + + nopw (%eax) diff --git a/gas/testsuite/gas/i386/iamcu-3.d b/gas/testsuite/gas/i386/iamcu-3.d new file mode 100644 index 00000000000..291f6016a04 --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-3.d @@ -0,0 +1,11 @@ +#as: -J -march=iamcu+nop +#objdump: -dw +#not-target: *-*-nacl* + +.*: +file format elf32-iamcu.* + +Disassembly of section .text: + +0+ <.text>: +[ ]*[a-f0-9]+: 66 0f 1f 00 nopw \(%eax\) +#pass diff --git a/gas/testsuite/gas/i386/iamcu-3.s b/gas/testsuite/gas/i386/iamcu-3.s new file mode 100644 index 00000000000..fac63cab09d --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-3.s @@ -0,0 +1,2 @@ + .text + nopw (%eax) diff --git a/gas/testsuite/gas/i386/iamcu-inval-1.l b/gas/testsuite/gas/i386/iamcu-inval-1.l new file mode 100644 index 00000000000..7bbbc2daf9a --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-inval-1.l @@ -0,0 +1,21 @@ +.*: Assembler messages: +.*:4: Error: .* +.*:5: Error: .* +.*:7: Error: .* +.*:8: Error: .* +.*:10: Error: .* +.*:11: Error: .* +GAS LISTING .* + + +[ ]*1[ ]+\# Invalid Intel MCU instructions +[ ]*2[ ]+\.text +[ ]*3[ ]+ +[ ]*4[ ]+fnstsw +[ ]*5[ ]+fstsw %ax +[ ]*6[ ]+ +[ ]*7[ ]+cmove %eax,%ebx +[ ]*8[ ]+nopw \(%eax\) +[ ]*9[ ]+ +[ ]*10[ ]+movq %xmm1, \(%eax\) +[ ]*11[ ]+movnti %eax, \(%eax\) diff --git a/gas/testsuite/gas/i386/iamcu-inval-1.s b/gas/testsuite/gas/i386/iamcu-inval-1.s new file mode 100644 index 00000000000..4e2588037f9 --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-inval-1.s @@ -0,0 +1,11 @@ +# Invalid Intel MCU instructions + .text + + fnstsw + fstsw %ax + + cmove %eax,%ebx + nopw (%eax) + + movq %xmm1, (%eax) + movnti %eax, (%eax) diff --git a/gas/testsuite/gas/i386/iamcu-inval-2.l b/gas/testsuite/gas/i386/iamcu-inval-2.l new file mode 100644 index 00000000000..e62e29d4a6b --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-inval-2.l @@ -0,0 +1,2 @@ +.*: Assembler messages: +.*:2: Fatal error: `.sse4.1' isn't valid for Intel MCU diff --git a/gas/testsuite/gas/i386/iamcu-inval-2.s b/gas/testsuite/gas/i386/iamcu-inval-2.s new file mode 100644 index 00000000000..46ef3ffbb21 --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-inval-2.s @@ -0,0 +1,2 @@ +# Invalid .arch for Intel MCU + .arch .sse4.1 diff --git a/gas/testsuite/gas/i386/iamcu-inval-3.l b/gas/testsuite/gas/i386/iamcu-inval-3.l new file mode 100644 index 00000000000..a9762a50292 --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-inval-3.l @@ -0,0 +1,2 @@ +Assembler messages: +Fatal error: `sse4' isn't valid for Intel MCU diff --git a/gas/testsuite/gas/i386/iamcu-inval-3.s b/gas/testsuite/gas/i386/iamcu-inval-3.s new file mode 100644 index 00000000000..1c255e29318 --- /dev/null +++ b/gas/testsuite/gas/i386/iamcu-inval-3.s @@ -0,0 +1 @@ +.include "iamcu-1.s"