This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 2/8][Binutils][AArch64] Wire through instr_sequence
- From: Tamar Christina <tamar dot christina at arm dot com>
- To: binutils at sourceware dot org
- Cc: nd at arm dot com, Richard dot Earnshaw at arm dot com, marcus dot shawcroft at arm dot com
- Date: Mon, 24 Sep 2018 18:20:20 +0100
- Subject: [PATCH 2/8][Binutils][AArch64] Wire through instr_sequence
Hi All,
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.
build on native hardware and regtested on
aarch64-none-elf, aarch64-none-elf (32 bit host),
aarch64-none-linux-gnu
Cross-compiled and regtested on
aarch64-none-linux-gnu, aarch64_be-none-linux-gnu
and no issues.
Ok for master?
Thanks,
Tamar
gas/
2018-09-24 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.
include/
2018-09-24 Tamar Christina <tamar.christina@arm.com>
* opcode/aarch64.h (struct aarch64_instr_sequence): New.
(aarch64_opcode_encode): Use it.
opcodes/
2018-09-24 Tamar Christina <tamar.christina@arm.com>
* aarch64-asm.c (aarch64_opcode_encode): Add insn_sequence.
* aarch64-dis.c (insn_sequence): New.
--
diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h
index dd92521e68c3272d1fabaccda10db8d171d667f5..cdf988376d9761479dcb61913652486d167157dc 100644
--- a/gas/config/tc-aarch64.h
+++ b/gas/config/tc-aarch64.h
@@ -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. */
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index c77de21d19dc1cc73df05f17c0e985152f3992ed..206019b382b58f0929ea045e098f7dfd8d14e41f 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -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;
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index c7d9008c857ba5e6d79a3d6acddb52729c77e213..10bf097ff39c56ca305141cde4ae2471fe129283 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -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 *,
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
index 06d428bf193d0720770f6324bfc92c54416321ee..35704cde1feaa61be39e4b702d689a51a1884272 100644
--- a/opcodes/aarch64-asm.c
+++ b/opcodes/aarch64-asm.c
@@ -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;
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index f7092b061f39cf5c9d999673593c001b2af6a5d7..599727e00bd2c70ae0133a8451fcfb0b365cc3ef 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -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)
{