aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2021-12-02 15:00:56 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2021-12-02 15:00:56 +0000
commitb3e59f8873b9f07e84b19a19d40810f9a61b6d62 (patch)
tree50f74009c8830755ab4abcd476faad6584b49cd1 /opcodes
parentf96093c1f53bf4a930073f6ae862910583d79866 (diff)
downloadbinutils-b3e59f8873b9f07e84b19a19d40810f9a61b6d62.zip
binutils-b3e59f8873b9f07e84b19a19d40810f9a61b6d62.tar.gz
binutils-b3e59f8873b9f07e84b19a19d40810f9a61b6d62.tar.bz2
aarch64: Tweak insn sequence code
libopcodes has some code to check constraints across sequences of consecutive instructions. It was added to support MOVPRFX sequences but is going to be useful for the Armv8.8-A MOPS feature as well. Currently the structure has one field to record the instruction that started a sequence and another to record the remaining instructions in the sequence. It's more convenient for the MOPS code if we put the instructions into a single array instead. No functional change intended. include/ * opcode/aarch64.h (aarch64_instr_sequence): Replace num_insns and current_insns with num_added_insns and num_allocated_insns. opcodes/ * aarch64-opc.c (add_insn_to_sequence): New function. (init_insn_sequence): Update for new aarch64_instr_sequence layout. Add the first instruction to the inst array. (verify_constraints): Update for new aarch64_instr_sequence layout. Don't add the last instruction to the array.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/aarch64-opc.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index b7076cd..289df9e 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -5403,6 +5403,15 @@ verify_elem_sd (const struct aarch64_inst *inst, const aarch64_insn insn,
return ERR_OK;
}
+/* Add INST to the end of INSN_SEQUENCE. */
+
+static void
+add_insn_to_sequence (const struct aarch64_inst *inst,
+ aarch64_instr_sequence *insn_sequence)
+{
+ insn_sequence->instr[insn_sequence->num_added_insns++] = *inst;
+}
+
/* Initialize an instruction sequence insn_sequence with the instruction INST.
If INST is NULL the given insn_sequence is cleared and the sequence is left
uninitialized. */
@@ -5412,16 +5421,11 @@ init_insn_sequence (const struct aarch64_inst *inst,
aarch64_instr_sequence *insn_sequence)
{
int num_req_entries = 0;
- insn_sequence->next_insn = 0;
- insn_sequence->num_insns = num_req_entries;
- if (insn_sequence->instr)
- XDELETE (insn_sequence->instr);
- insn_sequence->instr = NULL;
- if (inst)
+ if (insn_sequence->instr)
{
- insn_sequence->instr = XNEW (aarch64_inst);
- memcpy (insn_sequence->instr, inst, sizeof (aarch64_inst));
+ XDELETE (insn_sequence->instr);
+ insn_sequence->instr = NULL;
}
/* Handle all the cases here. May need to think of something smarter than
@@ -5430,16 +5434,13 @@ init_insn_sequence (const struct aarch64_inst *inst,
if (inst && inst->opcode->constraints & C_SCAN_MOVPRFX)
num_req_entries = 1;
- if (insn_sequence->current_insns)
- XDELETEVEC (insn_sequence->current_insns);
- insn_sequence->current_insns = NULL;
+ insn_sequence->num_added_insns = 0;
+ insn_sequence->num_allocated_insns = num_req_entries;
if (num_req_entries != 0)
{
- size_t size = num_req_entries * sizeof (aarch64_inst);
- insn_sequence->current_insns
- = (aarch64_inst**) XNEWVEC (aarch64_inst, num_req_entries);
- memset (insn_sequence->current_insns, 0, size);
+ insn_sequence->instr = XCNEWVEC (aarch64_inst, num_req_entries);
+ add_insn_to_sequence (inst, insn_sequence);
}
}
@@ -5715,17 +5716,12 @@ verify_constraints (const struct aarch64_inst *inst,
}
done:
- /* Add the new instruction to the sequence. */
- memcpy (insn_sequence->current_insns + insn_sequence->next_insn++,
- inst, sizeof (aarch64_inst));
-
- /* Check if sequence is now full. */
- if (insn_sequence->next_insn >= insn_sequence->num_insns)
- {
- /* Sequence is full, but we don't have anything special to do for now,
- so clear and reset it. */
- init_insn_sequence (NULL, insn_sequence);
- }
+ if (insn_sequence->num_added_insns == insn_sequence->num_allocated_insns)
+ /* We've checked the last instruction in the sequence and so
+ don't need the sequence any more. */
+ init_insn_sequence (NULL, insn_sequence);
+ else
+ add_insn_to_sequence (inst, insn_sequence);
}
return res;