[AArch64] Fix +nofp16 handling

Feature flag handling was not perfect, +nofp16 disabled fp
instructions too.

New feature flag macros were added to check features with multiple
bits set (matters for FP_F16 and SIMD_F16 opcode feature tests).
The unused AARCH64_OPCODE_HAS_FEATURE was removed, all checks should
use one of the AARCH64_CPU_HAS_* macros.  AARCH64_CPU_HAS_FEATURE
now checks all feature bits.

The aarch64_features table now contains the dependencies as
a separate field (so when the feature is enabled all dependencies
are enabled and when it is disabled everything that depends on it
is disabled).

Note that armv8-a+foo+nofoo is not equivalent to armv8-a if
+foo turns on dependent features that nofoo does not turn off.

gas/
	* config/tc-aarch64.c (struct aarch64_option_cpu_value_table): Add
	require field.
	(aarch64_features): Initialize require fields.
	(aarch64_parse_features): Handle dependencies.
	(aarch64_feature_enable_set, aarch64_feature_disable_set): New.
	(md_assemble): Use AARCH64_CPU_HAS_ALL_FEATURES.
	* testsuite/gas/aarch64/illegal-nofp16.s: New.
	* testsuite/gas/aarch64/illegal-nofp16.l: New.
	* testsuite/gas/aarch64/illegal-nofp16.d: New.

include/
	* opcode/aarch64.h (AARCH64_CPU_HAS_ALL_FEATURES): New.
	(AARCH64_CPU_HAS_ANY_FEATURES): New.
	(AARCH64_CPU_HAS_FEATURE): Define as AARCH64_CPU_HAS_ALL_FEATURES.
	(AARCH64_OPCODE_HAS_FEATURE): Remove.
This commit is contained in:
Szabolcs Nagy 2016-07-01 16:20:50 +01:00
parent 2c5c2a3321
commit 93d8990cba
7 changed files with 105 additions and 21 deletions

View File

@ -1,3 +1,15 @@
2016-07-01 Szabolcs Nagy <szabolcs.nagy@arm.com>
* config/tc-aarch64.c (struct aarch64_option_cpu_value_table): Add
require field.
(aarch64_features): Initialize require fields.
(aarch64_parse_features): Handle dependencies.
(aarch64_feature_enable_set, aarch64_feature_disable_set): New.
(md_assemble): Use AARCH64_CPU_HAS_ALL_FEATURES.
* testsuite/gas/aarch64/illegal-nofp16.s: New.
* testsuite/gas/aarch64/illegal-nofp16.l: New.
* testsuite/gas/aarch64/illegal-nofp16.d: New.
2016-07-01 Nick Clifton <nickc@redhat.com>
* macro.c (macro_expand_body): Use a buffer big enough to hold an

View File

@ -6080,7 +6080,7 @@ md_assemble (char *str)
{
/* Check that this instruction is supported for this CPU. */
if (!opcode->avariant
|| !AARCH64_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant))
|| !AARCH64_CPU_HAS_ALL_FEATURES (cpu_variant, *opcode->avariant))
{
as_bad (_("selected processor does not support `%s'"), str);
return;
@ -7801,23 +7801,33 @@ struct aarch64_option_cpu_value_table
{
const char *name;
const aarch64_feature_set value;
const aarch64_feature_set require; /* Feature dependencies. */
};
static const struct aarch64_option_cpu_value_table aarch64_features[] = {
{"crc", AARCH64_FEATURE (AARCH64_FEATURE_CRC, 0)},
{"crypto", AARCH64_FEATURE (AARCH64_FEATURE_CRYPTO, 0)},
{"fp", AARCH64_FEATURE (AARCH64_FEATURE_FP, 0)},
{"lse", AARCH64_FEATURE (AARCH64_FEATURE_LSE, 0)},
{"simd", AARCH64_FEATURE (AARCH64_FEATURE_SIMD, 0)},
{"pan", AARCH64_FEATURE (AARCH64_FEATURE_PAN, 0)},
{"lor", AARCH64_FEATURE (AARCH64_FEATURE_LOR, 0)},
{"ras", AARCH64_FEATURE (AARCH64_FEATURE_RAS, 0)},
{"rdma", AARCH64_FEATURE (AARCH64_FEATURE_SIMD
| AARCH64_FEATURE_RDMA, 0)},
{"fp16", AARCH64_FEATURE (AARCH64_FEATURE_F16
| AARCH64_FEATURE_FP, 0)},
{"profile", AARCH64_FEATURE (AARCH64_FEATURE_PROFILE, 0)},
{NULL, AARCH64_ARCH_NONE}
{"crc", AARCH64_FEATURE (AARCH64_FEATURE_CRC, 0),
AARCH64_ARCH_NONE},
{"crypto", AARCH64_FEATURE (AARCH64_FEATURE_CRYPTO, 0),
AARCH64_ARCH_NONE},
{"fp", AARCH64_FEATURE (AARCH64_FEATURE_FP, 0),
AARCH64_ARCH_NONE},
{"lse", AARCH64_FEATURE (AARCH64_FEATURE_LSE, 0),
AARCH64_ARCH_NONE},
{"simd", AARCH64_FEATURE (AARCH64_FEATURE_SIMD, 0),
AARCH64_ARCH_NONE},
{"pan", AARCH64_FEATURE (AARCH64_FEATURE_PAN, 0),
AARCH64_ARCH_NONE},
{"lor", AARCH64_FEATURE (AARCH64_FEATURE_LOR, 0),
AARCH64_ARCH_NONE},
{"ras", AARCH64_FEATURE (AARCH64_FEATURE_RAS, 0),
AARCH64_ARCH_NONE},
{"rdma", AARCH64_FEATURE (AARCH64_FEATURE_RDMA, 0),
AARCH64_FEATURE (AARCH64_FEATURE_SIMD, 0)},
{"fp16", AARCH64_FEATURE (AARCH64_FEATURE_F16, 0),
AARCH64_FEATURE (AARCH64_FEATURE_FP, 0)},
{"profile", AARCH64_FEATURE (AARCH64_FEATURE_PROFILE, 0),
AARCH64_ARCH_NONE},
{NULL, AARCH64_ARCH_NONE, AARCH64_ARCH_NONE},
};
struct aarch64_long_option_table
@ -7828,6 +7838,38 @@ struct aarch64_long_option_table
char *deprecated; /* If non-null, print this message. */
};
/* Transitive closure of features depending on set. */
static aarch64_feature_set
aarch64_feature_disable_set (aarch64_feature_set set)
{
const struct aarch64_option_cpu_value_table *opt;
aarch64_feature_set prev = 0;
while (prev != set) {
prev = set;
for (opt = aarch64_features; opt->name != NULL; opt++)
if (AARCH64_CPU_HAS_ANY_FEATURES (opt->require, set))
AARCH64_MERGE_FEATURE_SETS (set, set, opt->value);
}
return set;
}
/* Transitive closure of dependencies of set. */
static aarch64_feature_set
aarch64_feature_enable_set (aarch64_feature_set set)
{
const struct aarch64_option_cpu_value_table *opt;
aarch64_feature_set prev = 0;
while (prev != set) {
prev = set;
for (opt = aarch64_features; opt->name != NULL; opt++)
if (AARCH64_CPU_HAS_FEATURE (set, opt->value))
AARCH64_MERGE_FEATURE_SETS (set, set, opt->require);
}
return set;
}
static int
aarch64_parse_features (const char *str, const aarch64_feature_set **opt_p,
bfd_boolean ext_only)
@ -7895,11 +7937,19 @@ aarch64_parse_features (const char *str, const aarch64_feature_set **opt_p,
for (opt = aarch64_features; opt->name != NULL; opt++)
if (strncmp (opt->name, str, optlen) == 0)
{
aarch64_feature_set set;
/* Add or remove the extension. */
if (adding_value)
AARCH64_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->value);
{
set = aarch64_feature_enable_set (opt->value);
AARCH64_MERGE_FEATURE_SETS (*ext_set, *ext_set, set);
}
else
AARCH64_CLEAR_FEATURE (*ext_set, *ext_set, opt->value);
{
set = aarch64_feature_disable_set (opt->value);
AARCH64_CLEAR_FEATURE (*ext_set, *ext_set, set);
}
break;
}

View File

@ -0,0 +1,2 @@
#as: -march=armv8.2-a+nofp16 -mno-verbose-error
#error-output: illegal-nofp16.l

View File

@ -0,0 +1,3 @@
[^:]*: Assembler messages:
^[^:]+:4: Error: selected processor does not support `fneg h0,h1'
^[^:]+:6: Error: selected processor does not support `fneg v0\.8h,v1\.8h'

View File

@ -0,0 +1,7 @@
// Test -march=armv8.2-a+nofp16 to only disable fp16, not fp.
.text
fneg s0, s1
fneg h0, h1
fneg v0.4s, v1.4s
fneg v0.8h, v1.8h
neg v0.16b, v1.16b

View File

@ -1,3 +1,10 @@
2016-07-01 Szabolcs Nagy <szabolcs.nagy@arm.com>
* opcode/aarch64.h (AARCH64_CPU_HAS_ALL_FEATURES): New.
(AARCH64_CPU_HAS_ANY_FEATURES): New.
(AARCH64_CPU_HAS_FEATURE): Define as AARCH64_CPU_HAS_ALL_FEATURES.
(AARCH64_OPCODE_HAS_FEATURE): Remove.
2016-06-30 Matthew Wahab <matthew.wahab@arm.com>
* opcode/arm.h (ARM_ARCH_V8_2a): Add FPU_NEON_EXT_RDMA to the set

View File

@ -84,9 +84,15 @@ typedef uint32_t aarch64_insn;
/* CPU-specific features. */
typedef unsigned long aarch64_feature_set;
#define AARCH64_CPU_HAS_FEATURE(CPU,FEAT) \
#define AARCH64_CPU_HAS_ALL_FEATURES(CPU,FEAT) \
((~(CPU) & (FEAT)) == 0)
#define AARCH64_CPU_HAS_ANY_FEATURES(CPU,FEAT) \
(((CPU) & (FEAT)) != 0)
#define AARCH64_CPU_HAS_FEATURE(CPU,FEAT) \
AARCH64_CPU_HAS_ALL_FEATURES (CPU,FEAT)
#define AARCH64_MERGE_FEATURE_SETS(TARG,F1,F2) \
do \
{ \
@ -103,9 +109,6 @@ typedef unsigned long aarch64_feature_set;
#define AARCH64_FEATURE(core,coproc) ((core) | (coproc))
#define AARCH64_OPCODE_HAS_FEATURE(OPC,FEAT) \
(((OPC) & (FEAT)) != 0)
enum aarch64_operand_class
{
AARCH64_OPND_CLASS_NIL,