AArch64: Wire through instr_sequence
This patch introduces aarch64_instr_sequence which is a structure similar to IT blocks on Arm in order to track instructions that introduce a constraint or dependency on instruction 1..N positions away from the instruction that opened the block. The struct is also wired through to the locations that require it. gas/ * config/tc-aarch64.c (now_instr_sequence): (*insn_sequence, now_instr_sequence): New. (output_operand_error_record, do_encode): Add insn_sequence. (md_assemble): Update insn_sequence. (try_to_encode_as_unscaled_ldst, fix_mov_imm_insn, fix_insn): Pass insn_sequence. * config/tc-aarch64.h (struct aarch64_segment_info_type): Add insn_sequence. include/ * opcode/aarch64.h (struct aarch64_instr_sequence): New. (aarch64_opcode_encode): Use it. opcodes/ * aarch64-asm.c (aarch64_opcode_encode): Add insn_sequence. * aarch64-dis.c (insn_sequence): New.
This commit is contained in:
parent
eae424aef0
commit
7e84b55d8f
@ -1,3 +1,14 @@
|
||||
2018-10-03 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
* config/tc-aarch64.c (now_instr_sequence):
|
||||
(*insn_sequence, now_instr_sequence): New.
|
||||
(output_operand_error_record, do_encode): Add insn_sequence.
|
||||
(md_assemble): Update insn_sequence.
|
||||
(try_to_encode_as_unscaled_ldst, fix_mov_imm_insn, fix_insn):
|
||||
Pass insn_sequence.
|
||||
* config/tc-aarch64.h (struct aarch64_segment_info_type):
|
||||
Add insn_sequence.
|
||||
|
||||
2018-10-02 Palmer Dabbelt <palmer@sifive.com>
|
||||
|
||||
* testsuite/gas/riscv/fence-tso.d: New file.
|
||||
|
@ -55,6 +55,9 @@ static const aarch64_feature_set *march_cpu_opt = NULL;
|
||||
/* Constants for known architecture features. */
|
||||
static const aarch64_feature_set cpu_default = CPU_DEFAULT;
|
||||
|
||||
/* Currently active instruction sequence. */
|
||||
static aarch64_instr_sequence *insn_sequence = NULL;
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
|
||||
static symbolS *GOT_symbol;
|
||||
@ -146,6 +149,13 @@ static aarch64_instruction inst;
|
||||
static bfd_boolean parse_operands (char *, const aarch64_opcode *);
|
||||
static bfd_boolean programmer_friendly_fixup (aarch64_instruction *);
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
# define now_instr_sequence seg_info \
|
||||
(now_seg)->tc_segment_info_data.insn_sequence
|
||||
#else
|
||||
static struct aarch64_instr_sequence now_instr_sequence;
|
||||
#endif
|
||||
|
||||
/* Diagnostics inline function utilities.
|
||||
|
||||
These are lightweight utilities which should only be called by parse_operands
|
||||
@ -4661,7 +4671,7 @@ output_operand_error_record (const operand_error_record *record, char *str)
|
||||
&& programmer_friendly_fixup (&inst);
|
||||
gas_assert (result);
|
||||
result = aarch64_opcode_encode (opcode, inst_base, &inst_base->value,
|
||||
NULL, NULL);
|
||||
NULL, NULL, insn_sequence);
|
||||
gas_assert (!result);
|
||||
|
||||
/* Find the most matched qualifier sequence. */
|
||||
@ -6738,7 +6748,7 @@ do_encode (const aarch64_opcode *opcode, aarch64_inst *instr,
|
||||
aarch64_operand_error error_info;
|
||||
memset (&error_info, '\0', sizeof (error_info));
|
||||
error_info.kind = AARCH64_OPDE_NIL;
|
||||
if (aarch64_opcode_encode (opcode, instr, code, NULL, &error_info)
|
||||
if (aarch64_opcode_encode (opcode, instr, code, NULL, &error_info, insn_sequence)
|
||||
&& !error_info.non_fatal)
|
||||
return TRUE;
|
||||
|
||||
@ -6784,6 +6794,9 @@ md_assemble (char *str)
|
||||
S_SET_SEGMENT (last_label_seen, now_seg);
|
||||
}
|
||||
|
||||
/* Update the current insn_sequence from the segment. */
|
||||
insn_sequence = &seg_info (now_seg)->tc_segment_info_data.insn_sequence;
|
||||
|
||||
inst.reloc.type = BFD_RELOC_UNUSED;
|
||||
|
||||
DEBUG_TRACE ("\n\n");
|
||||
@ -7376,7 +7389,8 @@ try_to_encode_as_unscaled_ldst (aarch64_inst *instr)
|
||||
|
||||
DEBUG_TRACE ("Found LDURB entry to encode programmer-friendly LDRB");
|
||||
|
||||
if (!aarch64_opcode_encode (instr->opcode, instr, &instr->value, NULL, NULL))
|
||||
if (!aarch64_opcode_encode (instr->opcode, instr, &instr->value, NULL, NULL,
|
||||
insn_sequence))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
@ -7410,7 +7424,7 @@ fix_mov_imm_insn (fixS *fixP, char *buf, aarch64_inst *instr, offsetT value)
|
||||
opcode = aarch64_get_opcode (OP_MOV_IMM_WIDE);
|
||||
aarch64_replace_opcode (instr, opcode);
|
||||
if (aarch64_opcode_encode (instr->opcode, instr,
|
||||
&instr->value, NULL, NULL))
|
||||
&instr->value, NULL, NULL, insn_sequence))
|
||||
{
|
||||
put_aarch64_insn (buf, instr->value);
|
||||
return;
|
||||
@ -7419,7 +7433,7 @@ fix_mov_imm_insn (fixS *fixP, char *buf, aarch64_inst *instr, offsetT value)
|
||||
opcode = aarch64_get_opcode (OP_MOV_IMM_WIDEN);
|
||||
aarch64_replace_opcode (instr, opcode);
|
||||
if (aarch64_opcode_encode (instr->opcode, instr,
|
||||
&instr->value, NULL, NULL))
|
||||
&instr->value, NULL, NULL, insn_sequence))
|
||||
{
|
||||
put_aarch64_insn (buf, instr->value);
|
||||
return;
|
||||
@ -7432,7 +7446,7 @@ fix_mov_imm_insn (fixS *fixP, char *buf, aarch64_inst *instr, offsetT value)
|
||||
opcode = aarch64_get_opcode (OP_MOV_IMM_LOG);
|
||||
aarch64_replace_opcode (instr, opcode);
|
||||
if (aarch64_opcode_encode (instr->opcode, instr,
|
||||
&instr->value, NULL, NULL))
|
||||
&instr->value, NULL, NULL, insn_sequence))
|
||||
{
|
||||
put_aarch64_insn (buf, instr->value);
|
||||
return;
|
||||
@ -7543,7 +7557,7 @@ fix_insn (fixS *fixP, uint32_t flags, offsetT value)
|
||||
idx = aarch64_operand_index (new_inst->opcode->operands, opnd);
|
||||
new_inst->operands[idx].imm.value = value;
|
||||
if (aarch64_opcode_encode (new_inst->opcode, new_inst,
|
||||
&new_inst->value, NULL, NULL))
|
||||
&new_inst->value, NULL, NULL, insn_sequence))
|
||||
put_aarch64_insn (buf, new_inst->value);
|
||||
else
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
@ -7597,7 +7611,7 @@ fix_insn (fixS *fixP, uint32_t flags, offsetT value)
|
||||
|
||||
/* Encode/fix-up. */
|
||||
if (aarch64_opcode_encode (new_inst->opcode, new_inst,
|
||||
&new_inst->value, NULL, NULL))
|
||||
&new_inst->value, NULL, NULL, insn_sequence))
|
||||
{
|
||||
put_aarch64_insn (buf, new_inst->value);
|
||||
break;
|
||||
|
@ -183,6 +183,7 @@ struct aarch64_segment_info_type
|
||||
{
|
||||
enum mstate mapstate;
|
||||
unsigned int marked_pr_dependency;
|
||||
aarch64_instr_sequence insn_sequence;
|
||||
};
|
||||
|
||||
/* We want .cfi_* pseudo-ops for generating unwind info. */
|
||||
|
@ -1,3 +1,8 @@
|
||||
2018-10-03 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
* opcode/aarch64.h (struct aarch64_instr_sequence): New.
|
||||
(aarch64_opcode_encode): Use it.
|
||||
|
||||
2018-10-03 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
* opcode/aarch64.h (struct aarch64_opcode): Add constraints,
|
||||
|
@ -662,6 +662,13 @@ empty_qualifier_sequence_p (const aarch64_opnd_qualifier_t *qualifiers)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Forward declare error reporting type. */
|
||||
typedef struct aarch64_operand_error aarch64_operand_error;
|
||||
/* Forward declare instruction sequence type. */
|
||||
typedef struct aarch64_instr_sequence aarch64_instr_sequence;
|
||||
/* Forward declare instruction definition. */
|
||||
typedef struct aarch64_inst aarch64_inst;
|
||||
|
||||
/* This structure holds information for a particular opcode. */
|
||||
|
||||
struct aarch64_opcode
|
||||
@ -1124,14 +1131,27 @@ struct aarch64_operand_error
|
||||
bfd_boolean non_fatal;
|
||||
};
|
||||
|
||||
typedef struct aarch64_operand_error aarch64_operand_error;
|
||||
/* AArch64 sequence structure used to track instructions with F_SCAN
|
||||
dependencies for both assembler and disassembler. */
|
||||
struct aarch64_instr_sequence
|
||||
{
|
||||
/* The instruction that caused this sequence to be opened. */
|
||||
aarch64_inst *instr;
|
||||
/* The number of instructions the above instruction allows 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;
|
||||
};
|
||||
|
||||
/* Encoding entrypoint. */
|
||||
|
||||
extern int
|
||||
aarch64_opcode_encode (const aarch64_opcode *, const aarch64_inst *,
|
||||
aarch64_insn *, aarch64_opnd_qualifier_t *,
|
||||
aarch64_operand_error *);
|
||||
aarch64_operand_error *, aarch64_instr_sequence *);
|
||||
|
||||
extern const aarch64_opcode *
|
||||
aarch64_replace_opcode (struct aarch64_inst *,
|
||||
|
@ -1,3 +1,8 @@
|
||||
2018-10-03 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
* aarch64-asm.c (aarch64_opcode_encode): Add insn_sequence.
|
||||
* aarch64-dis.c (insn_sequence): New.
|
||||
|
||||
2018-10-03 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
* aarch64-tbl.h (CORE_INSN, __FP_INSN, SIMD_INSN, CRYP_INSN, _CRC_INSN,
|
||||
|
@ -1948,7 +1948,8 @@ bfd_boolean
|
||||
aarch64_opcode_encode (const aarch64_opcode *opcode,
|
||||
const aarch64_inst *inst_ori, aarch64_insn *code,
|
||||
aarch64_opnd_qualifier_t *qlf_seq,
|
||||
aarch64_operand_error *mismatch_detail)
|
||||
aarch64_operand_error *mismatch_detail,
|
||||
aarch64_instr_sequence* insn_sequence ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int i;
|
||||
const aarch64_opcode *aliased;
|
||||
|
@ -49,6 +49,9 @@ static int no_aliases = 0; /* If set disassemble as most general inst. */
|
||||
static int no_notes = 1; /* If set do not print disassemble notes in the
|
||||
output as comments. */
|
||||
|
||||
/* Currently active instruction sequence. */
|
||||
static aarch64_instr_sequence insn_sequence ATTRIBUTE_UNUSED;
|
||||
|
||||
static void
|
||||
set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user