aboutsummaryrefslogtreecommitdiff
path: root/opcodes/arm-dis.c
diff options
context:
space:
mode:
authorAndre Vieira <andre.simoesdiasvieira@arm.com>2019-04-15 12:07:20 +0100
committerAndre Vieira <andre.simoesdiasvieira@arm.com>2019-04-15 12:32:01 +0100
commit4b5a202f107b5393da30fd0b488c3eff2bc758a5 (patch)
tree0064af5b36c2d2ef8aeaebd63c882327adad6b4e /opcodes/arm-dis.c
parent60f993ce170b91876ad41e8f7339c24afd63fac2 (diff)
downloadgdb-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/arm-dis.c')
-rw-r--r--opcodes/arm-dis.c17
1 files changed, 15 insertions, 2 deletions
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, "}");
}