diff options
author | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2019-04-15 12:07:20 +0100 |
---|---|---|
committer | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2019-04-15 12:32:01 +0100 |
commit | 4b5a202f107b5393da30fd0b488c3eff2bc758a5 (patch) | |
tree | 0064af5b36c2d2ef8aeaebd63c882327adad6b4e /opcodes | |
parent | 60f993ce170b91876ad41e8f7339c24afd63fac2 (diff) | |
download | gdb-4b5a202f107b5393da30fd0b488c3eff2bc758a5.zip gdb-4b5a202f107b5393da30fd0b488c3eff2bc758a5.tar.gz gdb-4b5a202f107b5393da30fd0b488c3eff2bc758a5.tar.bz2 |
[binutils, ARM, 13/16] Add support for CLRM
Given the similarity between LDM/STM and CLRM register lists, most of the changes in this patch aim at sharing code between those two sets of instruction. Sharing is achieved both in parsing and encoding of those instructions.
In terms of parsing, parse_reg_list () is extended to take a type that describe what type of instruction is being parsed. The reg_list_els used for parse_vfp_reg_list () is reused for the type and that function is added an assert for the new REGLIST_CLRM and REGLIST_RN enumerators.
parse_reg_list () is then taught to accept APSR and reject SP and PC when parsing for a CLRM instruction. At last, caller of parse_reg_list () is updated accordingly and logic is added for the new OP_CLRMLST operand.
Encoding-wise, encode_thumb2_ldmstm () is reused to encode the variable bits of CLRM and is thus renamed encode_thumb2_multi (). A new do_io parameter is added to distinguish between LDM/STM and CLRM which guard all the LDM/STM specific code of the function.
Finally objdump is told how to disassemble CLRM, again reusing the logic to print the LDM/STM register list (format specifier 'm'). Tests are also added in the form of negative tests to check parsing and encoding/disassembling tests.
ChangeLog entries are as follows:
*** gas/ChangeLog ***
2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
* config/tc-arm.c (enum reg_list_els): Define earlier and add
REGLIST_RN and REGLIST_CLRM enumerators.
(parse_reg_list): Add etype parameter to distinguish between regular
core register list and CLRM register list. Add logic to
recognize CLRM register list.
(parse_vfp_reg_list): Assert type is not for core register list.
(s_arm_unwind_save_core): Update call to parse_reg_list to new
prototype.
(enum operand_parse_code): Declare OP_CLRMLST enumerator.
(parse_operands): Update call to parse_reg_list to new prototype. Add
logic for OP_CLRMLST.
(encode_thumb2_ldmstm): Rename into ...
(encode_thumb2_multi): This. Add do_io parameter. Add logic to
encode CLRM and guard LDM/STM only code by do_io.
(do_t_ldmstm): Adapt to use encode_thumb2_multi.
(do_t_push_pop): Likewise.
(do_t_clrm): New function.
(insns): Define CLRM.
* testsuite/gas/arm/archv8m_1m-cmse-main-bad.d: New file.
* testsuite/gas/arm/archv8m_1m-cmse-main-bad.l: Likewise.
* testsuite/gas/arm/archv8m_1m-cmse-main-bad.s: Likewise.
* testsuite/gas/arm/archv8m_1m-cmse-main.d: Likewise.
* testsuite/gas/arm/archv8m_1m-cmse-main.s: Likewise.
*** opcodes/ChangeLog ***
2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
* arm-dis.c (thumb_opcodes): Document %n control code. Add entry for
CLRM.
(print_insn_thumb32): Add logic to print %n CLRM register list.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 6 | ||||
-rw-r--r-- | opcodes/arm-dis.c | 17 |
2 files changed, 21 insertions, 2 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 7f86025..a01e494 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com> + + * arm-dis.c (thumb_opcodes): Document %n control code. Add entry for + CLRM. + (print_insn_thumb32): Add logic to print %n CLRM register list. + 2019-04-15 Sudakshina Das <sudi.das@arm.com> * arm-dis.c (print_insn_thumb32): Updated to accept new %P diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 4a0f76a..e70641c 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -2710,6 +2710,7 @@ static const struct opcode16 thumb_opcodes[] = %a print the address of a plain load/store %w print the width and signedness of a core load/store %m print register mask for ldm/stm + %n print register mask for clrm %E print the lsb and width fields of a bfc/bfi instruction %F print the lsb and width fields of a sbfx/ubfx instruction @@ -2751,7 +2752,8 @@ static const struct opcode16 thumb_opcodes[] = makes heavy use of special-case bit patterns. */ static const struct opcode32 thumb32_opcodes[] = { - /* Armv8.1-M Mainline instructions. */ + /* Armv8.1-M Mainline and Armv8.1-M Mainline Security Extensions + instructions. */ {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN), 0xf040c001, 0xfff0f001, "wls\tlr, %16-19S, %Q"}, {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN), @@ -2772,6 +2774,8 @@ static const struct opcode32 thumb32_opcodes[] = {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN), 0xf000e001, 0xf840f001, "bfcsel\t%G, %Z, %18-21c"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN), + 0xe89f0000, 0xffff2000, "clrm%c\t%n"}, /* ARMv8-M and ARMv8-M Security Extensions instructions. */ {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M), 0xe97fe97f, 0xffffffff, "sg"}, @@ -5556,6 +5560,7 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) for (insn = thumb32_opcodes; insn->assembler; insn++) if ((given & insn->mask) == insn->value) { + bfd_boolean is_clrm = FALSE; bfd_boolean is_unpredictable = FALSE; signed long value_in_comment = 0; const char *c = insn->assembler; @@ -5851,6 +5856,9 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) } break; + case 'n': + is_clrm = TRUE; + /* Fall through. */ case 'm': { int started = 0; @@ -5863,7 +5871,12 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) if (started) func (stream, ", "); started = 1; - func (stream, "%s", arm_regnames[reg]); + if (is_clrm && reg == 13) + func (stream, "(invalid: %s)", arm_regnames[reg]); + else if (is_clrm && reg == 15) + func (stream, "%s", "APSR"); + else + func (stream, "%s", arm_regnames[reg]); } func (stream, "}"); } |