From 33593eafc92b6376a71bef49f5cebd6e09abd283 Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Thu, 7 Nov 2019 16:53:40 +0000 Subject: [PATCH] [Patch][binutils][arm] Create a new generic coprocessor array [3/10] Hi, This patch is part of a series that adds support for Armv8.6-A (Matrix Multiply and BFloat16 extensions) to binutils. Some generic instructions match a large range of encoding space (e.g. stc, mcr, mrc). Currently these instructions are in the coprocessor_opcodes array, which means they are checked before many other instructions when disassembling arm and thumb32 codes. This patch moves the generic instructions into a separate array to be checked later on. This is done in order to avoid instruction conflict between the generic instructions and newer ones -- this has already been seen with MVE, and is also a problem with BFloat16. One way to avoid the conflict could be to swap the search order between coprocessor_opcodes and neon_opcodes. We avoid this since it's a larger change that may introduce extra bugs (that aren't caught by the testsuite). We have decided against searching the generic array after searching the arm specific and thumb32 specific arrays with a similar reasoning about keeping the change small. Regression tested with arm-none-linux-gnueabihf. Committed on behalf of Mihail Ionescu. opcodes/ChangeLog: 2019-10-29 Mihail Ionescu 2019-10-29 Matthew Malcomson * arm-dis.c (print_insn_coprocessor, print_insn_generic_coprocessor): Create wrapper functions around the implementation of the print_insn_coprocessor control codes. (print_insn_coprocessor_1): Original print_insn_coprocessor function that now takes which array to look at as an argument. (print_insn_arm): Use both print_insn_coprocessor and print_insn_generic_coprocessor. (print_insn_thumb32): As above. Is it ok for trunk? Regards, Mihail --- opcodes/ChangeLog | 12 ++++ opcodes/arm-dis.c | 137 +++++++++++++++++++++++++++++----------------- 2 files changed, 98 insertions(+), 51 deletions(-) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index ef6ecf5e0bb..3919c260e19 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,15 @@ +2019-11-07 Mihail Ionescu +2019-11-07 Matthew Malcomson + + * arm-dis.c (print_insn_coprocessor, + print_insn_generic_coprocessor): Create wrapper functions around + the implementation of the print_insn_coprocessor control codes. + (print_insn_coprocessor_1): Original print_insn_coprocessor + function that now takes which array to look at as an argument. + (print_insn_arm): Use both print_insn_coprocessor and + print_insn_generic_coprocessor. + (print_insn_thumb32): As above. + 2019-11-07 Mihail Ionescu 2019-11-07 Matthew Malcomson diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 8ff86bf4d62..85c573034ea 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -1184,38 +1184,7 @@ static const struct sopcode32 coprocessor_opcodes[] = {ANY, ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8), 0xfeb80b40, 0xffbc0fd0, "vrint%16-17?mpna%u.f64\t%z1, %z0"}, - /* Generic coprocessor instructions. */ {ANY, ARM_FEATURE_CORE_LOW (0), SENTINEL_GENERIC_START, 0, "" }, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5E), - 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5E), - 0x0c500000, 0x0ff00000, - "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), - 0x0e000000, 0x0f000010, - "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), - 0x0e10f010, 0x0f10f010, - "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), - 0x0e100010, 0x0f100010, - "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), - 0x0e000010, 0x0f100010, - "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), - 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), - 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"}, - - /* V6 coprocessor instructions. */ - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V6), - 0xfc500000, 0xfff00000, - "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V6), - 0xfc400000, 0xfff00000, - "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"}, - /* ARMv8.3 AdvSIMD instructions in the space of coprocessor 8. */ {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A), 0xfc800800, 0xfeb00f10, "vcadd%c.f16\t%12-15,22V, %16-19,7V, %0-3,5V, #%24?29%24'70"}, @@ -1262,21 +1231,6 @@ static const struct sopcode32 coprocessor_opcodes[] = {ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST | ARM_EXT2_V8_2A), 0xfe100850, 0xffb00f50, "vfmsl.f16\t%12-15,22Q, d%16-19,7d, d%0-2d[%3,5d]"}, - /* V5 coprocessor instructions. */ - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), - 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), - 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), - 0xfe000000, 0xff000010, - "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), - 0xfe000010, 0xff100010, - "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"}, - {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), - 0xfe100010, 0xff100010, - "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, - /* ARMv8.2 half-precision Floating point coprocessor 9 (VFP) instructions. cp_num: bit <11:8> == 0b1001. cond: bit <31:28> == 0b1110, otherwise, it's UNPREDICTABLE. */ @@ -1358,6 +1312,60 @@ static const struct sopcode32 coprocessor_opcodes[] = {ANY, ARM_FEATURE_CORE_LOW (0), 0, 0, 0} }; +/* Generic coprocessor instructions. These are only matched if a more specific + SIMD or co-processor instruction does not match first. */ + +static const struct sopcode32 generic_coprocessor_opcodes[] = +{ + /* Generic coprocessor instructions. */ + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5E), + 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5E), + 0x0c500000, 0x0ff00000, + "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), + 0x0e000000, 0x0f000010, + "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), + 0x0e10f010, 0x0f10f010, + "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), + 0x0e100010, 0x0f100010, + "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), + 0x0e000010, 0x0f100010, + "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), + 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V2), + 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"}, + + /* V6 coprocessor instructions. */ + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V6), + 0xfc500000, 0xfff00000, + "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V6), + 0xfc400000, 0xfff00000, + "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"}, + + /* V5 coprocessor instructions. */ + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), + 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), + 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), + 0xfe000000, 0xff000010, + "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), + 0xfe000010, 0xff100010, + "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"}, + {ANY, ARM_FEATURE_CORE_LOW (ARM_EXT_V5), + 0xfe100010, 0xff100010, + "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + + {ANY, ARM_FEATURE_CORE_LOW (0), 0, 0, 0} +}; + /* Neon opcode table: This does not encode the top byte -- that is checked by the print_insn_neon routine, as it depends on whether we are doing thumb32 or arm32 disassembly. */ @@ -7887,10 +7895,11 @@ print_vec_condition (struct disassemble_info *info, long given, recognised coprocessor instruction. */ static bfd_boolean -print_insn_coprocessor (bfd_vma pc, - struct disassemble_info *info, - long given, - bfd_boolean thumb) +print_insn_coprocessor_1 (const struct sopcode32 *opcodes, + bfd_vma pc, + struct disassemble_info *info, + long given, + bfd_boolean thumb) { const struct sopcode32 *insn; void *stream = info->stream; @@ -7906,7 +7915,7 @@ print_insn_coprocessor (bfd_vma pc, allowed_arches = private_data->features; - for (insn = coprocessor_opcodes; insn->assembler; insn++) + for (insn = opcodes; insn->assembler; insn++) { unsigned long u_reg = 16; bfd_boolean is_unpredictable = FALSE; @@ -8622,6 +8631,26 @@ print_insn_coprocessor (bfd_vma pc, return FALSE; } +static bfd_boolean +print_insn_coprocessor (bfd_vma pc, + struct disassemble_info *info, + long given, + bfd_boolean thumb) +{ + return print_insn_coprocessor_1 (coprocessor_opcodes, + pc, info, given, thumb); +} + +static bfd_boolean +print_insn_generic_coprocessor (bfd_vma pc, + struct disassemble_info *info, + long given, + bfd_boolean thumb) +{ + return print_insn_coprocessor_1 (generic_coprocessor_opcodes, + pc, info, given, thumb); +} + /* Decodes and prints ARM addressing modes. Returns the offset used in the address, if any, if it is worthwhile printing the offset as a hexadecimal value in a comment at the end of the @@ -9652,6 +9681,9 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) if (print_insn_neon (info, given, FALSE)) return; + if (print_insn_generic_coprocessor (pc, info, given, FALSE)) + return; + for (insn = arm_opcodes; insn->assembler; insn++) { if ((given & insn->mask) != insn->value) @@ -10489,6 +10521,9 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) if (is_mve && print_insn_mve (info, given)) return; + if (print_insn_generic_coprocessor (pc, info, given, TRUE)) + return; + for (insn = thumb32_opcodes; insn->assembler; insn++) if ((given & insn->mask) == insn->value) { -- 2.30.2