aboutsummaryrefslogtreecommitdiff
path: root/opcodes/aarch64-dis.c
diff options
context:
space:
mode:
authorTamar Christina <tamar.christina@arm.com>2018-10-03 18:51:11 +0100
committerTamar Christina <tamar.christina@arm.com>2018-10-03 18:51:58 +0100
commitbde90be2cddc06371ee80a258bf6855d0f346324 (patch)
tree21c071ccc885044550b711ab68eec36041193365 /opcodes/aarch64-dis.c
parent4f5d2536289c0aedc3234f1bff6e9f4284f267c5 (diff)
downloadgdb-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.c66
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 ();