aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorTamar Christina <tamar.christina@arm.com>2018-10-03 18:27:52 +0100
committerTamar Christina <tamar.christina@arm.com>2018-10-03 18:33:33 +0100
commit7e84b55d8f973b011f55f604a76c2d1d989d0b6b (patch)
tree1d860bb0c911056c9fed87fc0b3e46ec30723c91 /gas/config
parenteae424aef0b14e1765602088ac866b95d14d4a22 (diff)
downloadbinutils-7e84b55d8f973b011f55f604a76c2d1d989d0b6b.zip
binutils-7e84b55d8f973b011f55f604a76c2d1d989d0b6b.tar.gz
binutils-7e84b55d8f973b011f55f604a76c2d1d989d0b6b.tar.bz2
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.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-aarch64.c30
-rw-r--r--gas/config/tc-aarch64.h1
2 files changed, 23 insertions, 8 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index c77de21..206019b 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/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h
index dd92521..cdf9883 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. */