diff options
author | Tamar Christina <tamar.christina@arm.com> | 2018-10-03 18:51:11 +0100 |
---|---|---|
committer | Tamar Christina <tamar.christina@arm.com> | 2018-10-03 18:51:58 +0100 |
commit | bde90be2cddc06371ee80a258bf6855d0f346324 (patch) | |
tree | 21c071ccc885044550b711ab68eec36041193365 /opcodes/aarch64-dis.c | |
parent | 4f5d2536289c0aedc3234f1bff6e9f4284f267c5 (diff) | |
download | gdb-bde90be2cddc06371ee80a258bf6855d0f346324.zip gdb-bde90be2cddc06371ee80a258bf6855d0f346324.tar.gz gdb-bde90be2cddc06371ee80a258bf6855d0f346324.tar.bz2 |
AArch64: Constraint disassembler and assembler changes.
This patch wires in the new constraint verifiers into the assembler and
disassembler. Because of this the MOVPRFX tests have to be split out from the
generic SVE tests into their own tests so warnings can be ignored.
These tests are only intended to test the encoding correctness and not the
constraints.
gas/
* testsuite/gas/aarch64/sve-movprfx.d: New test.
* testsuite/gas/aarch64/sve-movprfx.s: New test.
* testsuite/gas/aarch64/sve.d: Refactor.
* testsuite/gas/aarch64/sve.s: Refactor.
* testsuite/gas/aarch64/sysreg-diagnostic.d: Update.
opcodes/
* aarch64-asm.c (aarch64_opcode_encode): Apply constraint verifier.
* aarch64-dis.c (print_operands): Refactor to take notes.
(print_verifier_notes): New.
(print_aarch64_insn): Apply constraint verifier.
(print_insn_aarch64_word): Update call to print_aarch64_insn.
* aarch64-opc.c (aarch64_print_operand): Remove attribute, update notes format.
Diffstat (limited to 'opcodes/aarch64-dis.c')
-rw-r--r-- | opcodes/aarch64-dis.c | 66 |
1 files changed, 59 insertions, 7 deletions
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 373ddae..c9bd4ae 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -45,7 +45,7 @@ static int no_aliases = 0; /* If set disassemble as most general inst. */ output as comments. */ /* Currently active instruction sequence. */ -static aarch64_instr_sequence insn_sequence ATTRIBUTE_UNUSED; +static aarch64_instr_sequence insn_sequence; static void set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED) @@ -2983,10 +2983,11 @@ aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst, static void print_operands (bfd_vma pc, const aarch64_opcode *opcode, - const aarch64_opnd_info *opnds, struct disassemble_info *info) + const aarch64_opnd_info *opnds, struct disassemble_info *info, + bfd_boolean *has_notes) { - int i, pcrel_p, num_printed; char *notes = NULL; + int i, pcrel_p, num_printed; for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i) { char str[128]; @@ -3016,7 +3017,10 @@ print_operands (bfd_vma pc, const aarch64_opcode *opcode, } if (notes && !no_notes) - (*info->fprintf_func) (info->stream, "\t; note: %s", notes); + { + *has_notes = TRUE; + (*info->fprintf_func) (info->stream, " // note: %s", notes); + } } /* Set NAME to a copy of INST's mnemonic with the "." suffix removed. */ @@ -3074,15 +3078,63 @@ print_comment (const aarch64_inst *inst, struct disassemble_info *info) } } +/* Build notes from verifiers into a string for printing. */ + +static void +print_verifier_notes (aarch64_operand_error *detail, + struct disassemble_info *info) +{ + if (no_notes) + return; + + /* The output of the verifier cannot be a fatal error, otherwise the assembly + would not have succeeded. We can safely ignore these. */ + assert (detail->non_fatal); + assert (detail->error); + + /* If there are multiple verifier messages, concat them up to 1k. */ + (*info->fprintf_func) (info->stream, " // note: %s", detail->error); + if (detail->index >= 0) + (*info->fprintf_func) (info->stream, " at operand %d", detail->index + 1); +} + /* Print the instruction according to *INST. */ static void print_aarch64_insn (bfd_vma pc, const aarch64_inst *inst, - struct disassemble_info *info) + const aarch64_insn code, + struct disassemble_info *info, + aarch64_operand_error *mismatch_details) { + bfd_boolean has_notes = FALSE; + print_mnemonic_name (inst, info); - print_operands (pc, inst->opcode, inst->operands, info); + print_operands (pc, inst->opcode, inst->operands, info, &has_notes); print_comment (inst, info); + + /* We've already printed a note, not enough space to print more so exit. + Usually notes shouldn't overlap so it shouldn't happen that we have a note + from a register and instruction at the same time. */ + if (has_notes) + return; + + /* Always run constraint verifiers, this is needed because constraints need to + maintain a global state regardless of whether the instruction has the flag + set or not. */ + enum err_type result = verify_constraints (inst, code, pc, FALSE, + mismatch_details, &insn_sequence); + switch (result) + { + case ERR_UND: + case ERR_UNP: + case ERR_NYI: + assert (0); + case ERR_VFI: + print_verifier_notes (mismatch_details, info); + break; + default: + break; + } } /* Entry-point of the instruction disassembler and printer. */ @@ -3139,7 +3191,7 @@ print_insn_aarch64_word (bfd_vma pc, break; case ERR_OK: user_friendly_fixup (&inst); - print_aarch64_insn (pc, &inst, info); + print_aarch64_insn (pc, &inst, word, info, errors); break; default: abort (); |