From 1e6f4800fc01c7957d0688158385aba3bf5ce8de Mon Sep 17 00:00:00 2001 From: Matthew Wahab Date: Fri, 11 Dec 2015 10:22:40 +0000 Subject: [PATCH] [AArch64][Patch 5/5] Add instruction PSB CSYNC The Statistical Profile Extension adds the instruction PSB CSYNC as an alias for the HINT #17 instruction. This patch adds the instruction to binutils as a HINT alias that takes an operand. A new operand type, AARCH64_OPND_BARRIER_PSB, is added to represent the operand to PSB. A parser for the operand type is added to the assembler and a printer to the disassembler. The operand name "csync" is added to the list of HINT options with HINT number #17. Encoding and decoding of the operand is handled by the ins_hint/ext_hint functions added in the preceding patches. gas/ 2015-12-11 Matthew Wahab * config/tc-aarch64.c (aarch64_hint_opt_hsh): New. (parse_barrier_psb): New. (parse_operands): Add case for AARCH64_OPND_BARRIER_PSB. (md_begin): Set up aarch64_hint_opt_hsh. gas/testsuite/ 2015-12-11 Matthew Wahab * gas/aarch64/system-2.d: Enable the statistical profiling extension. Update the expected output. * gas/aarch64/system-2.s: Add tests for PSB CSYNC. * gas/aarch64/system.d: Update the expected output. include/opcode/ 2015-12-11 Matthew Wahab * aarch64.h (aarch64_opnd): Add AARCH64_OPND_BARRIER_PSB. * aarch64-asm-2.c: Regenerate. * aarch64-dis-2.c: Regenerate. * aarch64-opc-2.c: Regenerate. * aarch64-opc.c (aarch64_hint_options): Add "csync". (aarch64_print_operands): Handle AARCH64_OPND_BARRIER_PSB. * aarch64-tbl.h (aarch64_feature_stat_profile): New. (STAT_PROFILE): New. (aarch64_opcode_table): Add "psb". (AARCH64_OPERANDS): Add "BARRIER_PSB". Change-Id: I5ffb672d26a8b15b48785478d359350a9b70ca09 --- gas/ChangeLog | 7 ++++ gas/config/tc-aarch64.c | 56 +++++++++++++++++++++++++++- gas/testsuite/ChangeLog | 7 ++++ gas/testsuite/gas/aarch64/system-2.d | 4 +- gas/testsuite/gas/aarch64/system-2.s | 4 ++ gas/testsuite/gas/aarch64/system.d | 2 +- include/opcode/ChangeLog | 13 +++++++ include/opcode/aarch64.h | 1 + opcodes/aarch64-asm-2.c | 15 +++++--- opcodes/aarch64-dis-2.c | 39 ++++++++++--------- opcodes/aarch64-opc-2.c | 1 + opcodes/aarch64-opc.c | 5 +++ opcodes/aarch64-tbl.h | 9 ++++- 13 files changed, 135 insertions(+), 28 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 2fcad8e667..f69d006975 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2015-12-11 Matthew Wahab + + * config/tc-aarch64.c (aarch64_hint_opt_hsh): New. + (parse_barrier_psb): New. + (parse_operands): Add case for AARCH64_OPND_BARRIER_PSB. + (md_begin): Set up aarch64_hint_opt_hsh. + 2015-12-11 Matthew Wahab * config/tc-aarch64.c (aarch64_features): Add "profile". diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 2f115ec023..2685ae8ea9 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -406,6 +406,7 @@ static struct hash_control *aarch64_reg_hsh; static struct hash_control *aarch64_barrier_opt_hsh; static struct hash_control *aarch64_nzcv_hsh; static struct hash_control *aarch64_pldop_hsh; +static struct hash_control *aarch64_hint_opt_hsh; /* Stuff needed to resolve the label ambiguity As: @@ -3604,6 +3605,41 @@ parse_barrier (char **str) return o->value; } +/* Parse an operand for a PSB barrier. Set *HINT_OPT to the hint-option record + return 0 if successful. Otherwise return PARSE_FAIL. */ + +static int +parse_barrier_psb (char **str, + const struct aarch64_name_value_pair ** hint_opt) +{ + char *p, *q; + const struct aarch64_name_value_pair *o; + + p = q = *str; + while (ISALPHA (*q)) + q++; + + o = hash_find_n (aarch64_hint_opt_hsh, p, q - p); + if (!o) + { + set_fatal_syntax_error + ( _("unknown or missing option to PSB")); + return PARSE_FAIL; + } + + if (o->value != 0x11) + { + /* PSB only accepts option name 'CSYNC'. */ + set_syntax_error + (_("the specified option is not accepted for PSB")); + return PARSE_FAIL; + } + + *str = q; + *hint_opt = o; + return 0; +} + /* Parse a system register or a PSTATE field name for an MSR/MRS instruction. Returns the encoding for the option, or PARSE_FAIL. @@ -5643,6 +5679,12 @@ sys_reg_ins: inst.base.operands[i].prfop = aarch64_prfops + val; break; + case AARCH64_OPND_BARRIER_PSB: + val = parse_barrier_psb (&str, &(info->hint_option)); + if (val == PARSE_FAIL) + goto failure; + break; + default: as_fatal (_("unhandled operand code %d"), operands[i]); } @@ -7506,7 +7548,8 @@ md_begin (void) || (aarch64_reg_hsh = hash_new ()) == NULL || (aarch64_barrier_opt_hsh = hash_new ()) == NULL || (aarch64_nzcv_hsh = hash_new ()) == NULL - || (aarch64_pldop_hsh = hash_new ()) == NULL) + || (aarch64_pldop_hsh = hash_new ()) == NULL + || (aarch64_hint_opt_hsh = hash_new ()) == NULL) as_fatal (_("virtual memory exhausted")); fill_instruction_hash_table (); @@ -7602,6 +7645,17 @@ md_begin (void) (void *) (aarch64_prfops + i)); } + for (i = 0; aarch64_hint_options[i].name != NULL; i++) + { + const char* name = aarch64_hint_options[i].name; + + checked_hash_insert (aarch64_hint_opt_hsh, name, + (void *) (aarch64_hint_options + i)); + /* Also hash the name in the upper case. */ + checked_hash_insert (aarch64_pldop_hsh, get_upper_str (name), + (void *) (aarch64_hint_options + i)); + } + /* Set the cpu variant based on the command-line options. */ if (!mcpu_cpu_opt) mcpu_cpu_opt = march_cpu_opt; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index dafa360a3f..cd81f93591 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-12-11 Matthew Wahab + + * gas/aarch64/system-2.d: Enable the statistical profiling + extension. Update the expected output. + * gas/aarch64/system-2.s: Add tests for PSB CSYNC. + * gas/aarch64/system.d: Update the expected output. + 2015-12-11 Matthew Wahab * gas/aarch64/sysreg-2.s: Add tests for the statistical profiling diff --git a/gas/testsuite/gas/aarch64/system-2.d b/gas/testsuite/gas/aarch64/system-2.d index 9b379cf3cd..f999348f43 100644 --- a/gas/testsuite/gas/aarch64/system-2.d +++ b/gas/testsuite/gas/aarch64/system-2.d @@ -1,4 +1,4 @@ -#as: -march=armv8.2-a +#as: -march=armv8.2-a+profile #objdump: -dr .*: file format .* @@ -8,3 +8,5 @@ Disassembly of section \.text: 0000000000000000 <.*>: 0: d503221f esb 4: d503221f esb + 8: d503223f psb csync + c: d503223f psb csync diff --git a/gas/testsuite/gas/aarch64/system-2.s b/gas/testsuite/gas/aarch64/system-2.s index 9b7f216cc1..3402e7622d 100644 --- a/gas/testsuite/gas/aarch64/system-2.s +++ b/gas/testsuite/gas/aarch64/system-2.s @@ -4,3 +4,7 @@ /* RAS Extension. */ esb hint #0x10 + + /* Statistical profiling. */ + psb csync + hint #0x11 diff --git a/gas/testsuite/gas/aarch64/system.d b/gas/testsuite/gas/aarch64/system.d index d4dcf86aa3..2da13eea9e 100644 --- a/gas/testsuite/gas/aarch64/system.d +++ b/gas/testsuite/gas/aarch64/system.d @@ -29,7 +29,7 @@ Disassembly of section \.text: 54: d50321df hint #0xe 58: d50321ff hint #0xf 5c: d503221f (hint #0x10|esb) - 60: d503223f hint #0x11 + 60: d503223f (hint #0x11|psb csync) 64: d503225f hint #0x12 68: d503227f hint #0x13 6c: d503229f hint #0x14 diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 603bdb99bf..f307a2aa76 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,16 @@ +2015-12-11 Matthew Wahab + + * aarch64.h (aarch64_opnd): Add AARCH64_OPND_BARRIER_PSB. + * aarch64-asm-2.c: Regenerate. + * aarch64-dis-2.c: Regenerate. + * aarch64-opc-2.c: Regenerate. + * aarch64-opc.c (aarch64_hint_options): Add "csync". + (aarch64_print_operands): Handle AARCH64_OPND_BARRIER_PSB. + * aarch64-tbl.h (aarch64_feature_stat_profile): New. + (STAT_PROFILE): New. + (aarch64_opcode_table): Add "psb". + (AARCH64_OPERANDS): Add "BARRIER_PSB". + 2015-12-11 Matthew Wahab * aarch64.h (aarch64_hint_options): Declare. diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index 70486c9d36..b8a2c0142a 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -237,6 +237,7 @@ enum aarch64_opnd AARCH64_OPND_BARRIER, /* Barrier operand. */ AARCH64_OPND_BARRIER_ISB, /* Barrier operand for ISB. */ AARCH64_OPND_PRFOP, /* Prefetch operation. */ + AARCH64_OPND_BARRIER_PSB, /* Barrier operand for PSB. */ }; /* Qualifier constrains an operand. It either specifies a variant of an diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c index 2d1a22b752..8644c056a6 100644 --- a/opcodes/aarch64-asm-2.c +++ b/opcodes/aarch64-asm-2.c @@ -422,6 +422,7 @@ aarch64_find_real_opcode (const aarch64_opcode *opcode) case 1004: /* movz */ value = 1004; /* --> movz. */ break; + case 1018: /* psb */ case 1017: /* esb */ case 1016: /* sevl */ case 1015: /* sev */ @@ -432,12 +433,12 @@ aarch64_find_real_opcode (const aarch64_opcode *opcode) case 1010: /* hint */ value = 1010; /* --> hint. */ break; - case 1026: /* tlbi */ - case 1025: /* ic */ - case 1024: /* dc */ - case 1023: /* at */ - case 1022: /* sys */ - value = 1022; /* --> sys. */ + case 1027: /* tlbi */ + case 1026: /* ic */ + case 1025: /* dc */ + case 1024: /* at */ + case 1023: /* sys */ + value = 1023; /* --> sys. */ break; default: return NULL; } @@ -562,6 +563,8 @@ aarch64_insert_operand (const aarch64_operand *self, return aarch64_ins_barrier (self, info, code, inst); case 87: return aarch64_ins_prfop (self, info, code, inst); + case 88: + return aarch64_ins_hint (self, info, code, inst); default: assert (0); abort (); } } diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c index 6139af36cf..96b0287714 100644 --- a/opcodes/aarch64-dis-2.c +++ b/opcodes/aarch64-dis-2.c @@ -3319,7 +3319,7 @@ aarch64_opcode_lookup_1 (uint32_t word) 10987654321098765432109876543210 xxxxxxxxxxxxxxxxxxxxx1xx1x10x01x sysl. */ - return 1028; + return 1029; } } } @@ -3342,7 +3342,7 @@ aarch64_opcode_lookup_1 (uint32_t word) 10987654321098765432109876543210 xxxxxxxxxxxxxxxxxxxxxxxx0110x1xx tbz. */ - return 1030; + return 1031; } } else @@ -3361,7 +3361,7 @@ aarch64_opcode_lookup_1 (uint32_t word) 10987654321098765432109876543210 xxxxxxxxxxxxxxxxxxxxxxxx1110x1xx tbnz. */ - return 1031; + return 1032; } } } @@ -8857,15 +8857,15 @@ aarch64_find_next_opcode (const aarch64_opcode *opcode) case 794: value = 798; break; /* ldnp --> ldp. */ case 798: return NULL; /* ldp --> NULL. */ case 1009: value = 1010; break; /* msr --> hint. */ - case 1010: value = 1018; break; /* hint --> clrex. */ - case 1018: value = 1019; break; /* clrex --> dsb. */ - case 1019: value = 1020; break; /* dsb --> dmb. */ - case 1020: value = 1021; break; /* dmb --> isb. */ - case 1021: value = 1022; break; /* isb --> sys. */ - case 1022: value = 1027; break; /* sys --> msr. */ - case 1027: return NULL; /* msr --> NULL. */ - case 1028: value = 1029; break; /* sysl --> mrs. */ - case 1029: return NULL; /* mrs --> NULL. */ + case 1010: value = 1019; break; /* hint --> clrex. */ + case 1019: value = 1020; break; /* clrex --> dsb. */ + case 1020: value = 1021; break; /* dsb --> dmb. */ + case 1021: value = 1022; break; /* dmb --> isb. */ + case 1022: value = 1023; break; /* isb --> sys. */ + case 1023: value = 1028; break; /* sys --> msr. */ + case 1028: return NULL; /* msr --> NULL. */ + case 1029: value = 1030; break; /* sysl --> mrs. */ + case 1030: return NULL; /* mrs --> NULL. */ case 361: value = 362; break; /* st4 --> st1. */ case 362: value = 363; break; /* st1 --> st2. */ case 363: value = 364; break; /* st2 --> st3. */ @@ -9145,8 +9145,8 @@ aarch64_find_alias_opcode (const aarch64_opcode *opcode) case 952: value = 1001; break; /* lduminl --> stuminl. */ case 1002: value = 1003; break; /* movn --> mov. */ case 1004: value = 1005; break; /* movz --> mov. */ - case 1010: value = 1017; break; /* hint --> esb. */ - case 1022: value = 1026; break; /* sys --> tlbi. */ + case 1010: value = 1018; break; /* hint --> psb. */ + case 1023: value = 1027; break; /* sys --> tlbi. */ default: return NULL; } @@ -9271,6 +9271,7 @@ aarch64_find_next_alias_opcode (const aarch64_opcode *opcode) case 1001: value = 952; break; /* stuminl --> lduminl. */ case 1003: value = 1002; break; /* mov --> movn. */ case 1005: value = 1004; break; /* mov --> movz. */ + case 1018: value = 1017; break; /* psb --> esb. */ case 1017: value = 1016; break; /* esb --> sevl. */ case 1016: value = 1015; break; /* sevl --> sev. */ case 1015: value = 1014; break; /* sev --> wfi. */ @@ -9278,10 +9279,10 @@ aarch64_find_next_alias_opcode (const aarch64_opcode *opcode) case 1013: value = 1012; break; /* wfe --> yield. */ case 1012: value = 1011; break; /* yield --> nop. */ case 1011: value = 1010; break; /* nop --> hint. */ - case 1026: value = 1025; break; /* tlbi --> ic. */ - case 1025: value = 1024; break; /* ic --> dc. */ - case 1024: value = 1023; break; /* dc --> at. */ - case 1023: value = 1022; break; /* at --> sys. */ + case 1027: value = 1026; break; /* tlbi --> ic. */ + case 1026: value = 1025; break; /* ic --> dc. */ + case 1025: value = 1024; break; /* dc --> at. */ + case 1024: value = 1023; break; /* at --> sys. */ default: return NULL; } @@ -9411,6 +9412,8 @@ aarch64_extract_operand (const aarch64_operand *self, return aarch64_ext_barrier (self, info, code, inst); case 87: return aarch64_ext_prfop (self, info, code, inst); + case 88: + return aarch64_ext_hint (self, info, code, inst); default: assert (0); abort (); } } diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c index ef7e0a4403..01f9302064 100644 --- a/opcodes/aarch64-opc-2.c +++ b/opcodes/aarch64-opc-2.c @@ -112,6 +112,7 @@ const struct aarch64_operand aarch64_operands[] = {AARCH64_OPND_CLASS_SYSTEM, "BARRIER", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a barrier option name"}, {AARCH64_OPND_CLASS_SYSTEM, "BARRIER_ISB", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the ISB option name SY or an optional 4-bit unsigned immediate"}, {AARCH64_OPND_CLASS_SYSTEM, "PRFOP", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a prefetch operation specifier"}, + {AARCH64_OPND_CLASS_SYSTEM, "BARRIER_PSB", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the PSB option name CSYNC"}, {AARCH64_OPND_CLASS_NIL, "", 0, {0}, "DUMMY"}, }; diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index 5f65f8ce7d..1557582d0a 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -344,6 +344,7 @@ const struct aarch64_name_value_pair aarch64_barrier_options[16] = const struct aarch64_name_value_pair aarch64_hint_options[] = { + { "csync", 0x11 }, /* PSB CSYNC. */ { NULL, 0x0 }, }; @@ -2731,6 +2732,10 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, snprintf (buf, size, "#0x%02x", opnd->prfop->value); break; + case AARCH64_OPND_BARRIER_PSB: + snprintf (buf, size, "%s", opnd->hint_option->name); + break; + default: assert (0); } diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index 9e743db6b4..35f950f560 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -1303,6 +1303,8 @@ static const aarch64_feature_set aarch64_feature_v8_2 = AARCH64_FEATURE (AARCH64_FEATURE_V8_2, 0); static const aarch64_feature_set aarch64_feature_fp_f16 = AARCH64_FEATURE (AARCH64_FEATURE_F16 | AARCH64_FEATURE_FP, 0); +static const aarch64_feature_set aarch64_feature_stat_profile = + AARCH64_FEATURE (AARCH64_FEATURE_PROFILE, 0); #define CORE &aarch64_feature_v8 #define FP &aarch64_feature_fp @@ -1314,6 +1316,7 @@ static const aarch64_feature_set aarch64_feature_fp_f16 = #define RDMA &aarch64_feature_rdma #define FP_F16 &aarch64_feature_fp_f16 #define RAS &aarch64_feature_ras +#define STAT_PROFILE &aarch64_feature_stat_profile #define ARMV8_2 &aarch64_feature_v8_2 struct aarch64_opcode aarch64_opcode_table[] = @@ -2460,6 +2463,8 @@ struct aarch64_opcode aarch64_opcode_table[] = {"sev", 0xd503209f, 0xffffffff, ic_system, 0, CORE, OP0 (), {}, F_ALIAS}, {"sevl", 0xd50320bf, 0xffffffff, ic_system, 0, CORE, OP0 (), {}, F_ALIAS}, {"esb", 0xd503221f, 0xffffffff, ic_system, 0, RAS, OP0 (), {}, F_ALIAS}, + {"psb", 0xd503223f, 0xffffffff, ic_system, 0, STAT_PROFILE, + OP1 (BARRIER_PSB), {}, F_ALIAS }, {"clrex", 0xd503305f, 0xfffff0ff, ic_system, 0, CORE, OP1 (UIMM4), {}, F_OPD0_OPT | F_DEFAULT (0xF)}, {"dsb", 0xd503309f, 0xfffff0ff, ic_system, 0, CORE, OP1 (BARRIER), {}, 0}, {"dmb", 0xd50330bf, 0xfffff0ff, ic_system, 0, CORE, OP1 (BARRIER), {}, 0}, @@ -2662,4 +2667,6 @@ struct aarch64_opcode aarch64_opcode_table[] = Y(SYSTEM, barrier, "BARRIER_ISB", 0, F(), \ "the ISB option name SY or an optional 4-bit unsigned immediate") \ Y(SYSTEM, prfop, "PRFOP", 0, F(), \ - "a prefetch operation specifier") + "a prefetch operation specifier") \ + Y (SYSTEM, hint, "BARRIER_PSB", 0, F (), \ + "the PSB option name CSYNC") -- 2.34.1