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.
This commit is contained in:
Richard Sandiford 2021-12-02 15:00:56 +00:00
parent f96093c1f5
commit b3e59f8873
2 changed files with 27 additions and 33 deletions

View File

@ -1290,15 +1290,13 @@ struct aarch64_operand_error
dependencies for both assembler and disassembler. */
struct aarch64_instr_sequence
{
/* The instruction that caused this sequence to be opened. */
/* The instructions in the sequence, starting with the one that
caused it to be opened. */
aarch64_inst *instr;
/* The number of instructions the above instruction allows one to be kept in the
sequence before an automatic close is done. */
int num_insns;
/* The instructions currently added to the sequence. */
aarch64_inst **current_insns;
/* The number of instructions already in the sequence. */
int next_insn;
int num_added_insns;
/* The number of instructions allocated to the sequence. */
int num_allocated_insns;
};
/* Encoding entrypoint. */

View File

@ -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;