This patch similarly to the AArch64 one enables Dot Product support by default for the Cortex-A55 and Cortex-A75 which have hardware support for these instructions.

gas	* config/tc-arm.c (arm_cpus):
	Change FPU_ARCH_CRYPTO_NEON_VFP_ARMV8
	into FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD.

include	* opcode/arm.h (FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD):
	New macro.
This commit is contained in:
Tamar Christina 2017-11-07 10:17:21 +00:00 committed by Nick Clifton
parent db84fff3f8
commit 0198d5e6fc
4 changed files with 118 additions and 85 deletions

View file

@ -1,3 +1,9 @@
2017-11-07 Tamar Christina <tamar.christina@arm.com>
* config/tc-arm.c (arm_cpus):
Change FPU_ARCH_CRYPTO_NEON_VFP_ARMV8
into FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD.
2017-11-07 Alan Modra <amodra@gmail.com> 2017-11-07 Alan Modra <amodra@gmail.com>
* read.c (assemble_one, s_bundle_unlock): Formatting. * read.c (assemble_one, s_bundle_unlock): Formatting.

View file

@ -977,11 +977,11 @@ skip_past_char (char ** str, char c)
/* Return TRUE if anything in the expression is a bignum. */ /* Return TRUE if anything in the expression is a bignum. */
static int static bfd_boolean
walk_no_bignums (symbolS * sp) walk_no_bignums (symbolS * sp)
{ {
if (symbol_get_value_expression (sp)->X_op == O_big) if (symbol_get_value_expression (sp)->X_op == O_big)
return 1; return TRUE;
if (symbol_get_value_expression (sp)->X_add_symbol) if (symbol_get_value_expression (sp)->X_add_symbol)
{ {
@ -990,10 +990,10 @@ walk_no_bignums (symbolS * sp)
&& walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol))); && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
} }
return 0; return FALSE;
} }
static int in_my_get_expression = 0; static bfd_boolean in_my_get_expression = FALSE;
/* Third argument to my_get_expression. */ /* Third argument to my_get_expression. */
#define GE_NO_PREFIX 0 #define GE_NO_PREFIX 0
@ -1030,16 +1030,17 @@ my_get_expression (expressionS * ep, char ** str, int prefix_mode)
if (is_immediate_prefix (**str)) if (is_immediate_prefix (**str))
(*str)++; (*str)++;
break; break;
default: abort (); default:
abort ();
} }
memset (ep, 0, sizeof (expressionS)); memset (ep, 0, sizeof (expressionS));
save_in = input_line_pointer; save_in = input_line_pointer;
input_line_pointer = *str; input_line_pointer = *str;
in_my_get_expression = 1; in_my_get_expression = TRUE;
seg = expression (ep); seg = expression (ep);
in_my_get_expression = 0; in_my_get_expression = FALSE;
if (ep->X_op == O_illegal || ep->X_op == O_absent) if (ep->X_op == O_illegal || ep->X_op == O_absent)
{ {
@ -1086,7 +1087,7 @@ my_get_expression (expressionS * ep, char ** str, int prefix_mode)
*str = input_line_pointer; *str = input_line_pointer;
input_line_pointer = save_in; input_line_pointer = save_in;
return 0; return SUCCESS;
} }
/* Turn a string in input_line_pointer into a floating point constant /* Turn a string in input_line_pointer into a floating point constant
@ -1181,6 +1182,7 @@ md_atof (int type, char * litP, int * sizeP)
/* We handle all bad expressions here, so that we can report the faulty /* We handle all bad expressions here, so that we can report the faulty
instruction in the error message. */ instruction in the error message. */
void void
md_operand (expressionS * exp) md_operand (expressionS * exp)
{ {
@ -1190,10 +1192,11 @@ md_operand (expressionS * exp)
/* Immediate values. */ /* Immediate values. */
#ifdef OBJ_ELF
/* Generic immediate-value read function for use in directives. /* Generic immediate-value read function for use in directives.
Accepts anything that 'expression' can fold to a constant. Accepts anything that 'expression' can fold to a constant.
*val receives the number. */ *val receives the number. */
#ifdef OBJ_ELF
static int static int
immediate_for_directive (int *val) immediate_for_directive (int *val)
{ {
@ -4771,6 +4774,7 @@ parse_immediate (char **str, int *val, int min, int max,
bfd_boolean prefix_opt) bfd_boolean prefix_opt)
{ {
expressionS exp; expressionS exp;
my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX); my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
if (exp.X_op != O_constant) if (exp.X_op != O_constant)
{ {
@ -5618,6 +5622,7 @@ parse_address_main (char **str, int i, int group_relocations,
else else
{ {
char *q = p; char *q = p;
if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX)) if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
return PARSE_OPERAND_FAIL; return PARSE_OPERAND_FAIL;
/* If the offset is 0, find out if it's a +0 or -0. */ /* If the offset is 0, find out if it's a +0 or -0. */
@ -5708,6 +5713,7 @@ parse_address_main (char **str, int i, int group_relocations,
else else
{ {
char *q = p; char *q = p;
if (inst.operands[i].negative) if (inst.operands[i].negative)
{ {
inst.operands[i].negative = 0; inst.operands[i].negative = 0;
@ -18001,7 +18007,7 @@ opcode_lookup (char **str)
case OT_cinfix3_deprecated: case OT_cinfix3_deprecated:
case OT_odd_infix_unc: case OT_odd_infix_unc:
if (!unified_syntax) if (!unified_syntax)
return 0; return NULL;
/* Fall through. */ /* Fall through. */
case OT_csuffix: case OT_csuffix:
@ -22167,6 +22173,7 @@ add_unwind_adjustsp (offsetT offset)
} }
/* Finish the list of unwind opcodes for this function. */ /* Finish the list of unwind opcodes for this function. */
static void static void
finish_unwind_opcodes (void) finish_unwind_opcodes (void)
{ {
@ -22453,7 +22460,7 @@ tc_arm_regname_to_dw2regnum (char *regname)
if (reg != FAIL) if (reg != FAIL)
return reg + 256; return reg + 256;
return -1; return FAIL;
} }
#ifdef TE_PE #ifdef TE_PE
@ -22883,6 +22890,7 @@ thumb32_negate_data_op (offsetT *instruction, unsigned int value)
} }
/* Read a 32-bit thumb instruction from buf. */ /* Read a 32-bit thumb instruction from buf. */
static unsigned long static unsigned long
get_thumb32_insn (char * buf) get_thumb32_insn (char * buf)
{ {
@ -22893,7 +22901,6 @@ get_thumb32_insn (char * buf)
return insn; return insn;
} }
/* We usually want to set the low bit on the address of thumb function /* We usually want to set the low bit on the address of thumb function
symbols. In particular .word foo - . should have the low bit set. symbols. In particular .word foo - . should have the low bit set.
Generic code tries to fold the difference of two symbols to Generic code tries to fold the difference of two symbols to
@ -25404,7 +25411,6 @@ struct option md_longopts[] =
{NULL, no_argument, NULL, 0} {NULL, no_argument, NULL, 0}
}; };
size_t md_longopts_size = sizeof (md_longopts); size_t md_longopts_size = sizeof (md_longopts);
struct arm_option_table struct arm_option_table
@ -25582,6 +25588,7 @@ struct arm_cpu_option_table
/* This list should, at a minimum, contain all the cpu names /* This list should, at a minimum, contain all the cpu names
recognized by GCC. */ recognized by GCC. */
#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN } #define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
static const struct arm_cpu_option_table arm_cpus[] = static const struct arm_cpu_option_table arm_cpus[] =
{ {
ARM_CPU_OPT ("all", NULL, ARM_ANY, ARM_CPU_OPT ("all", NULL, ARM_ANY,
@ -25865,7 +25872,7 @@ static const struct arm_cpu_option_table arm_cpus[] =
FPU_ARCH_CRYPTO_NEON_VFP_ARMV8), FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A, ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
FPU_ARCH_CRYPTO_NEON_VFP_ARMV8), FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A, ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
ARM_FEATURE_COPROC (CRC_EXT_ARMV8), ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
FPU_ARCH_CRYPTO_NEON_VFP_ARMV8), FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
@ -25877,7 +25884,7 @@ static const struct arm_cpu_option_table arm_cpus[] =
FPU_ARCH_CRYPTO_NEON_VFP_ARMV8), FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A, ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST), ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
FPU_ARCH_CRYPTO_NEON_VFP_ARMV8), FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R, ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
ARM_ARCH_NONE, ARM_ARCH_NONE,
FPU_NONE), FPU_NONE),
@ -25940,7 +25947,7 @@ static const struct arm_cpu_option_table arm_cpus[] =
ARM_ARCH_NONE, ARM_ARCH_NONE,
FPU_ARCH_VFP_V2), FPU_ARCH_VFP_V2),
/* Maverick */ /* Maverick. */
ARM_CPU_OPT ("ep9312", "ARM920T", ARM_CPU_OPT ("ep9312", "ARM920T",
ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK), ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
ARM_ARCH_NONE, FPU_ARCH_MAVERICK), ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
@ -25976,6 +25983,7 @@ struct arm_arch_option_table
/* This list should, at a minimum, contain all the architecture names /* This list should, at a minimum, contain all the architecture names
recognized by GCC. */ recognized by GCC. */
#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF } #define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF }
static const struct arm_arch_option_table arm_archs[] = static const struct arm_arch_option_table arm_archs[] =
{ {
ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA), ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
@ -26038,6 +26046,7 @@ static const struct arm_arch_option_table arm_archs[] =
#undef ARM_ARCH_OPT #undef ARM_ARCH_OPT
/* ISA extensions in the co-processor and main instruction set space. */ /* ISA extensions in the co-processor and main instruction set space. */
struct arm_option_extension_value_table struct arm_option_extension_value_table
{ {
const char * name; const char * name;
@ -26050,10 +26059,11 @@ struct arm_option_extension_value_table
const arm_feature_set allowed_archs[2]; const arm_feature_set allowed_archs[2];
}; };
/* The following table must be in alphabetical order with a NULL last entry. /* The following table must be in alphabetical order with a NULL last entry. */
*/
#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } } #define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} } #define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
static const struct arm_option_extension_value_table arm_extensions[] = static const struct arm_option_extension_value_table arm_extensions[] =
{ {
ARM_EXT_OPT ("crc", ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8), ARM_EXT_OPT ("crc", ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
@ -26663,8 +26673,8 @@ md_show_usage (FILE * fp)
--fix-v4bx Allow BX in ARMv4 code\n")); --fix-v4bx Allow BX in ARMv4 code\n"));
} }
#ifdef OBJ_ELF #ifdef OBJ_ELF
typedef struct typedef struct
{ {
int val; int val;
@ -26730,6 +26740,7 @@ static const cpu_arch_ver_table cpu_arch_ver[] =
}; };
/* Set an attribute if it has not already been set by the user. */ /* Set an attribute if it has not already been set by the user. */
static void static void
aeabi_set_attribute_int (int tag, int value) aeabi_set_attribute_int (int tag, int value)
{ {
@ -26750,6 +26761,7 @@ aeabi_set_attribute_string (int tag, const char *value)
/* Return whether features in the *NEEDED feature set are available via /* Return whether features in the *NEEDED feature set are available via
extensions for the architecture whose feature set is *ARCH_FSET. */ extensions for the architecture whose feature set is *ARCH_FSET. */
static bfd_boolean static bfd_boolean
have_ext_for_needed_feat_p (const arm_feature_set *arch_fset, have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
const arm_feature_set *needed) const arm_feature_set *needed)
@ -26793,6 +26805,7 @@ have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
For -march/-mcpu=all the build attribute value of the most featureful For -march/-mcpu=all the build attribute value of the most featureful
architecture is returned. Tag_CPU_arch_profile result is returned in architecture is returned. Tag_CPU_arch_profile result is returned in
PROFILE. */ PROFILE. */
static int static int
get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset, get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
const arm_feature_set *ext_fset, const arm_feature_set *ext_fset,
@ -26895,6 +26908,7 @@ found:
} }
/* Set the public EABI object attributes. */ /* Set the public EABI object attributes. */
static void static void
aeabi_set_public_attributes (void) aeabi_set_public_attributes (void)
{ {
@ -27096,6 +27110,7 @@ aeabi_set_public_attributes (void)
/* Post relaxation hook. Recompute ARM attributes now that relaxation is /* Post relaxation hook. Recompute ARM attributes now that relaxation is
finished and free extension feature bits which will not be used anymore. */ finished and free extension feature bits which will not be used anymore. */
void void
arm_md_post_relax (void) arm_md_post_relax (void)
{ {
@ -27107,6 +27122,7 @@ arm_md_post_relax (void)
} }
/* Add the default contents for the .ARM.attributes section. */ /* Add the default contents for the .ARM.attributes section. */
void void
arm_md_end (void) arm_md_end (void)
{ {
@ -27117,7 +27133,6 @@ arm_md_end (void)
} }
#endif /* OBJ_ELF */ #endif /* OBJ_ELF */
/* Parse a .cpu directive. */ /* Parse a .cpu directive. */
static void static void
@ -27164,7 +27179,6 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
ignore_rest_of_line (); ignore_rest_of_line ();
} }
/* Parse a .arch directive. */ /* Parse a .arch directive. */
static void static void
@ -27200,7 +27214,6 @@ s_arm_arch (int ignored ATTRIBUTE_UNUSED)
ignore_rest_of_line (); ignore_rest_of_line ();
} }
/* Parse a .object_arch directive. */ /* Parse a .object_arch directive. */
static void static void
@ -27422,10 +27435,10 @@ arm_convert_symbolic_attribute (const char *name)
return -1; return -1;
} }
/* Apply sym value for relocations only in the case that they are for /* Apply sym value for relocations only in the case that they are for
local symbols in the same segment as the fixup and you have the local symbols in the same segment as the fixup and you have the
respective architectural feature for blx and simple switches. */ respective architectural feature for blx and simple switches. */
int int
arm_apply_sym_value (struct fix * fixP, segT this_seg) arm_apply_sym_value (struct fix * fixP, segT this_seg)
{ {

View file

@ -1,3 +1,8 @@
2017-11-07 Tamar Christina <tamar.christina@arm.com>
* opcode/arm.h (FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD):
New macro.
2017-11-02 Siddhesh Poyarekar <siddhesh@sourceware.org> 2017-11-02 Siddhesh Poyarekar <siddhesh@sourceware.org>
* include/opcode/aarch64.h (AARCH64_ARCH_V8_2): Drop * include/opcode/aarch64.h (AARCH64_ARCH_V8_2): Drop

View file

@ -227,6 +227,9 @@
| FPU_VFP_ARMV8) | FPU_VFP_ARMV8)
#define FPU_ARCH_CRYPTO_NEON_VFP_ARMV8 \ #define FPU_ARCH_CRYPTO_NEON_VFP_ARMV8 \
ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8 | FPU_NEON_ARMV8 | FPU_VFP_ARMV8) ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8 | FPU_NEON_ARMV8 | FPU_VFP_ARMV8)
#define FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD \
ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8 | FPU_NEON_ARMV8 | FPU_VFP_ARMV8 | \
FPU_NEON_EXT_DOTPROD)
#define ARCH_CRC_ARMV8 ARM_FEATURE_COPROC (CRC_EXT_ARMV8) #define ARCH_CRC_ARMV8 ARM_FEATURE_COPROC (CRC_EXT_ARMV8)
#define FPU_ARCH_NEON_VFP_ARMV8_1 \ #define FPU_ARCH_NEON_VFP_ARMV8_1 \
ARM_FEATURE_COPROC (FPU_NEON_ARMV8 \ ARM_FEATURE_COPROC (FPU_NEON_ARMV8 \
@ -363,25 +366,31 @@ typedef struct
&& (CPU).core[1] == ((arm_feature_set)ARM_ANY).core[1]) && (CPU).core[1] == ((arm_feature_set)ARM_ANY).core[1])
#define ARM_MERGE_FEATURE_SETS(TARG,F1,F2) \ #define ARM_MERGE_FEATURE_SETS(TARG,F1,F2) \
do { \ do \
{ \
(TARG).core[0] = (F1).core[0] | (F2).core[0]; \ (TARG).core[0] = (F1).core[0] | (F2).core[0]; \
(TARG).core[1] = (F1).core[1] | (F2).core[1]; \ (TARG).core[1] = (F1).core[1] | (F2).core[1]; \
(TARG).coproc = (F1).coproc | (F2).coproc; \ (TARG).coproc = (F1).coproc | (F2).coproc; \
} while (0) } \
while (0)
#define ARM_CLEAR_FEATURE(TARG,F1,F2) \ #define ARM_CLEAR_FEATURE(TARG,F1,F2) \
do { \ do \
{ \
(TARG).core[0] = (F1).core[0] &~ (F2).core[0]; \ (TARG).core[0] = (F1).core[0] &~ (F2).core[0]; \
(TARG).core[1] = (F1).core[1] &~ (F2).core[1]; \ (TARG).core[1] = (F1).core[1] &~ (F2).core[1]; \
(TARG).coproc = (F1).coproc &~ (F2).coproc; \ (TARG).coproc = (F1).coproc &~ (F2).coproc; \
} while (0) } \
while (0)
#define ARM_FEATURE_COPY(F1, F2) \ #define ARM_FEATURE_COPY(F1, F2) \
do { \ do \
{ \
(F1).core[0] = (F2).core[0]; \ (F1).core[0] = (F2).core[0]; \
(F1).core[1] = (F2).core[1]; \ (F1).core[1] = (F2).core[1]; \
(F1).coproc = (F2).coproc; \ (F1).coproc = (F2).coproc; \
} while (0) } \
while (0)
#define ARM_FEATURE_EQUAL(T1,T2) \ #define ARM_FEATURE_EQUAL(T1,T2) \
( (T1).core[0] == (T2).core[0] \ ( (T1).core[0] == (T2).core[0] \