From bb050a6932c4b0ea86202fe62bed2d94999f77ad Mon Sep 17 00:00:00 2001 From: Claudiu Zissulescu Date: Thu, 17 Nov 2016 13:26:54 +0100 Subject: [PATCH] [ARC] Fix and extend features of .cpu directive. gas/ 2016-11-18 Claudiu Zissulescu * testsuite/gas/arc/cl-warn.s: New file. * testsuite/gas/arc/cpu-pseudop-1.d: Likewise. * testsuite/gas/arc/cpu-pseudop-1.s: Likewise. * testsuite/gas/arc/cpu-pseudop-2.d: Likewise. * testsuite/gas/arc/cpu-pseudop-2.s: Likewise. * testsuite/gas/arc/cpu-warn2.s: Likewise. * config/tc-arc.c (selected_cpu): Initialize. (feature_type): New struct. (feature_list): New variable. (arc_check_feature): New function. (arc_select_cpu): Check for .cpu duplicates. Don't overwrite the current cpu features. Check if a feature is available for a given cpu. (md_parse_option): Test if features are available for a given cpu. --- gas/ChangeLog | 17 ++++++ gas/config/tc-arc.c | 77 ++++++++++++++++++++------- gas/testsuite/gas/arc/cl-warn.s | 5 ++ gas/testsuite/gas/arc/cpu-pseudop-1.d | 12 +++++ gas/testsuite/gas/arc/cpu-pseudop-1.s | 6 +++ gas/testsuite/gas/arc/cpu-pseudop-2.d | 11 ++++ gas/testsuite/gas/arc/cpu-pseudop-2.s | 5 ++ gas/testsuite/gas/arc/cpu-warn2.s | 4 ++ 8 files changed, 119 insertions(+), 18 deletions(-) create mode 100644 gas/testsuite/gas/arc/cl-warn.s create mode 100644 gas/testsuite/gas/arc/cpu-pseudop-1.d create mode 100644 gas/testsuite/gas/arc/cpu-pseudop-1.s create mode 100644 gas/testsuite/gas/arc/cpu-pseudop-2.d create mode 100644 gas/testsuite/gas/arc/cpu-pseudop-2.s create mode 100644 gas/testsuite/gas/arc/cpu-warn2.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 2ade09ce41..c95decc6bf 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,20 @@ +2016-11-18 Claudiu Zissulescu + + * testsuite/gas/arc/cl-warn.s: New file. + * testsuite/gas/arc/cpu-pseudop-1.d: Likewise. + * testsuite/gas/arc/cpu-pseudop-1.s: Likewise. + * testsuite/gas/arc/cpu-pseudop-2.d: Likewise. + * testsuite/gas/arc/cpu-pseudop-2.s: Likewise. + * testsuite/gas/arc/cpu-warn2.s: Likewise. + * config/tc-arc.c (selected_cpu): Initialize. + (feature_type): New struct. + (feature_list): New variable. + (arc_check_feature): New function. + (arc_select_cpu): Check for .cpu duplicates. Don't overwrite the + current cpu features. Check if a feature is available for a given + cpu. + (md_parse_option): Test if features are available for a given cpu. + 2016-11-18 Szabolcs Nagy * config/tc-aarch64.c (parse_operands): Handle AARCH64_OPND_IMM_ROT*. diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c index 06aee48900..376ac4332f 100644 --- a/gas/config/tc-arc.c +++ b/gas/config/tc-arc.c @@ -451,7 +451,23 @@ static const struct cpu_type }; /* Information about the cpu/variant we're assembling for. */ -static struct cpu_type selected_cpu; +static struct cpu_type selected_cpu = { 0, 0, 0, 0, 0 }; + +/* A table with options. */ +static const struct feature_type +{ + unsigned feature; + unsigned cpus; + const char *name; +} + feature_list[] = +{ + { ARC_CD, ARC_OPCODE_ARCV2, "code-density" }, + { ARC_NPS400, ARC_OPCODE_ARC700, "nps400" }, + { ARC_SPFP, ARC_OPCODE_ARCFPX, "single-precision FPX" }, + { ARC_DPFP, ARC_OPCODE_ARCFPX, "double-precision FPX" }, + { ARC_FPUDA, ARC_OPCODE_ARCv2EM, "double assist FP" } +}; /* Used by the arc_reloc_op table. Order is important. */ #define O_gotoff O_md1 /* @gotoff relocation. */ @@ -775,6 +791,27 @@ md_number_to_chars_midend (char *buf, unsigned long long val, int n) } } +/* Check if a feature is allowed for a specific CPU. */ + +static void +arc_check_feature (void) +{ + unsigned i; + + if (!selected_cpu.features + || !selected_cpu.name) + return; + for (i = 0; (i < ARRAY_SIZE (feature_list)); i++) + { + if ((selected_cpu.features & feature_list[i].feature) + && !(selected_cpu.flags & feature_list[i].cpus)) + { + as_bad (_("invalid %s option for %s cpu"), feature_list[i].name, + selected_cpu.name); + } + } +} + /* Select an appropriate entry from CPU_TYPES based on ARG and initialise the relevant static global variables. Parameter SEL describes where this selection originated from. */ @@ -790,6 +827,10 @@ arc_select_cpu (const char *arg, enum mach_selection_type sel) gas_assert (sel != MACH_SELECTION_FROM_DEFAULT || mach_selection_mode == MACH_SELECTION_NONE); + if ((mach_selection_mode == MACH_SELECTION_FROM_CPU_DIRECTIVE) + && (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE)) + as_bad (_("Multiple .cpu directives found")); + /* Look for a matching entry in CPU_TYPES array. */ for (i = 0; cpu_types[i].name; ++i) { @@ -807,22 +848,25 @@ arc_select_cpu (const char *arg, enum mach_selection_type sel) && selected_cpu.mach != cpu_types[i].mach) { as_warn (_("Command-line value overrides \".cpu\" directive")); - return; } + return; } - /* Initialise static global data about selected machine type. */ - selected_cpu.flags = cpu_types[i].flags; - selected_cpu.name = cpu_types[i].name; - selected_cpu.features = cpu_types[i].features; - selected_cpu.mach = cpu_types[i].mach; - cpu_flags = cpu_types[i].eflags; + /* Initialise static global data about selected machine type. */ + selected_cpu.flags = cpu_types[i].flags; + selected_cpu.name = cpu_types[i].name; + selected_cpu.features |= cpu_types[i].features; + selected_cpu.mach = cpu_types[i].mach; + cpu_flags = cpu_types[i].eflags; break; } } if (!cpu_types[i].name) as_fatal (_("unknown architecture: %s\n"), arg); + + /* Check if set features are compatible with the chosen CPU. */ + arc_check_feature (); gas_assert (cpu_flags != 0); selected_cpu.eflags = (arc_initial_eflag & ~EF_ARC_MACH_MSK) | cpu_flags; mach_selection_mode = sel; @@ -3304,11 +3348,8 @@ md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED) break; case OPTION_CD: - /* This option has an effect only on ARC EM. */ - if (selected_cpu.flags & ARC_OPCODE_ARCv2EM) - selected_cpu.features |= ARC_CD; - else - as_warn (_("Code density option invalid for selected CPU")); + selected_cpu.features |= ARC_CD; + arc_check_feature (); break; case OPTION_RELAX: @@ -3317,22 +3358,22 @@ md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED) case OPTION_NPS400: selected_cpu.features |= ARC_NPS400; + arc_check_feature (); break; case OPTION_SPFP: selected_cpu.features |= ARC_SPFP; + arc_check_feature (); break; case OPTION_DPFP: selected_cpu.features |= ARC_DPFP; + arc_check_feature (); break; case OPTION_FPUDA: - /* This option has an effect only on ARC EM. */ - if (selected_cpu.flags & ARC_OPCODE_ARCv2EM) - selected_cpu.features |= ARC_FPUDA; - else - as_warn (_("FPUDA invalid for selected CPU")); + selected_cpu.features |= ARC_FPUDA; + arc_check_feature (); break; /* Dummy options are accepted but have no effect. */ diff --git a/gas/testsuite/gas/arc/cl-warn.s b/gas/testsuite/gas/arc/cl-warn.s new file mode 100644 index 0000000000..63199cfb77 --- /dev/null +++ b/gas/testsuite/gas/arc/cl-warn.s @@ -0,0 +1,5 @@ +; Test command line option compatibility checking. +; { dg-do assemble } +; { dg-options "--mcpu=archs -mdpfp" } +; { dg-error ".* invalid double-precision FPX option for archs cpu" "" { target arc*-*-* } 0 } + nop diff --git a/gas/testsuite/gas/arc/cpu-pseudop-1.d b/gas/testsuite/gas/arc/cpu-pseudop-1.d new file mode 100644 index 0000000000..09c47c9e2d --- /dev/null +++ b/gas/testsuite/gas/arc/cpu-pseudop-1.d @@ -0,0 +1,12 @@ +#as: -mcpu=arcem -mcode-density -mdpfp +#objdump: -dp -M dpfp + +.*: +file format .*arc.* +private flags = 0x305: -mcpu=ARCv2EM .* + + +Disassembly of section .text: + +00000000 <.text>: + 0: 4af7 sub_s r15,r2,r15 + 2: 3211 00c1 dsubh12 r1,r2,r3 diff --git a/gas/testsuite/gas/arc/cpu-pseudop-1.s b/gas/testsuite/gas/arc/cpu-pseudop-1.s new file mode 100644 index 0000000000..40217aae6e --- /dev/null +++ b/gas/testsuite/gas/arc/cpu-pseudop-1.s @@ -0,0 +1,6 @@ +;;; Check if user can use additional command line options. + .cpu EM + .section .text + + sub_s r15,r2,r15 ;code density instruction + dsubh12 r1,r2,r3 ;double-precision instruction diff --git a/gas/testsuite/gas/arc/cpu-pseudop-2.d b/gas/testsuite/gas/arc/cpu-pseudop-2.d new file mode 100644 index 0000000000..3bde329759 --- /dev/null +++ b/gas/testsuite/gas/arc/cpu-pseudop-2.d @@ -0,0 +1,11 @@ +#as: -mcpu=archs +#objdump: -dp + +.*: +file format .*arc.* +private flags = 0x306: -mcpu=ARCv2HS .* + + +Disassembly of section .text: + +00000000 <.text>: + 0: 4af7 sub_s r15,r2,r15 diff --git a/gas/testsuite/gas/arc/cpu-pseudop-2.s b/gas/testsuite/gas/arc/cpu-pseudop-2.s new file mode 100644 index 0000000000..def89d63cc --- /dev/null +++ b/gas/testsuite/gas/arc/cpu-pseudop-2.s @@ -0,0 +1,5 @@ +;;; Check if user can use additional command line options. + .cpu EM + .section .text + + sub_s r15,r2,r15 ;code density instruction diff --git a/gas/testsuite/gas/arc/cpu-warn2.s b/gas/testsuite/gas/arc/cpu-warn2.s new file mode 100644 index 0000000000..e9ee338a8e --- /dev/null +++ b/gas/testsuite/gas/arc/cpu-warn2.s @@ -0,0 +1,4 @@ +; Test warnings when multiple .cpu pseudo-ops are defined. +; { dg-do assemble } + .cpu EM + .cpu HS ;{ dg-error "Error: Multiple .cpu directives found" } -- 2.34.1