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.
+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.
2018-10-02 Palmer Dabbelt <palmer@sifive.com>
* testsuite/gas/riscv/fence-tso.d: New file.
/* Constants for known architecture features. */
static const aarch64_feature_set cpu_default = CPU_DEFAULT;
/* 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;
#ifdef OBJ_ELF
/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
static symbolS *GOT_symbol;
static bfd_boolean parse_operands (char *, const aarch64_opcode *);
static bfd_boolean programmer_friendly_fixup (aarch64_instruction *);
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
/* Diagnostics inline function utilities.
These are lightweight utilities which should only be called by parse_operands
&& programmer_friendly_fixup (&inst);
gas_assert (result);
result = aarch64_opcode_encode (opcode, inst_base, &inst_base->value,
&& programmer_friendly_fixup (&inst);
gas_assert (result);
result = aarch64_opcode_encode (opcode, inst_base, &inst_base->value,
+ NULL, NULL, insn_sequence);
gas_assert (!result);
/* Find the most matched qualifier sequence. */
gas_assert (!result);
/* Find the most matched qualifier sequence. */
aarch64_operand_error error_info;
memset (&error_info, '\0', sizeof (error_info));
error_info.kind = AARCH64_OPDE_NIL;
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;
&& !error_info.non_fatal)
return TRUE;
S_SET_SEGMENT (last_label_seen, now_seg);
}
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");
inst.reloc.type = BFD_RELOC_UNUSED;
DEBUG_TRACE ("\n\n");
DEBUG_TRACE ("Found LDURB entry to encode programmer-friendly LDRB");
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;
return FALSE;
return TRUE;
opcode = aarch64_get_opcode (OP_MOV_IMM_WIDE);
aarch64_replace_opcode (instr, opcode);
if (aarch64_opcode_encode (instr->opcode, instr,
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;
{
put_aarch64_insn (buf, instr->value);
return;
opcode = aarch64_get_opcode (OP_MOV_IMM_WIDEN);
aarch64_replace_opcode (instr, opcode);
if (aarch64_opcode_encode (instr->opcode, instr,
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;
{
put_aarch64_insn (buf, instr->value);
return;
opcode = aarch64_get_opcode (OP_MOV_IMM_LOG);
aarch64_replace_opcode (instr, opcode);
if (aarch64_opcode_encode (instr->opcode, instr,
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;
{
put_aarch64_insn (buf, instr->value);
return;
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,
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,
put_aarch64_insn (buf, new_inst->value);
else
as_bad_where (fixP->fx_file, fixP->fx_line,
/* Encode/fix-up. */
if (aarch64_opcode_encode (new_inst->opcode, new_inst,
/* 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;
{
put_aarch64_insn (buf, new_inst->value);
break;
{
enum mstate mapstate;
unsigned int marked_pr_dependency;
{
enum mstate mapstate;
unsigned int marked_pr_dependency;
+ aarch64_instr_sequence insn_sequence;
};
/* We want .cfi_* pseudo-ops for generating unwind info. */
};
/* We want .cfi_* pseudo-ops for generating unwind info. */
2018-10-03 Tamar Christina <tamar.christina@arm.com>
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,
extend flags field size.
(F_SCAN, C_SCAN_MOVPRFX, C_MAX_ELEM): New.
* opcode/aarch64.h (struct aarch64_opcode): Add constraints,
extend flags field size.
(F_SCAN, C_SCAN_MOVPRFX, C_MAX_ELEM): New.
+/* 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
/* This structure holds information for a particular opcode. */
struct aarch64_opcode
bfd_boolean non_fatal;
};
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 *,
/* 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 *,
extern const aarch64_opcode *
aarch64_replace_opcode (struct aarch64_inst *,
2018-10-03 Tamar Christina <tamar.christina@arm.com>
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,
_LSE_INSN, _LOR_INSN, RDMA_INSN, FF16_INSN, SF16_INSN, V8_2_INSN,
_SVE_INSN, V8_3_INSN, CNUM_INSN, RCPC_INSN, SHA2_INSN, AES_INSN,
* aarch64-tbl.h (CORE_INSN, __FP_INSN, SIMD_INSN, CRYP_INSN, _CRC_INSN,
_LSE_INSN, _LOR_INSN, RDMA_INSN, FF16_INSN, SF16_INSN, V8_2_INSN,
_SVE_INSN, V8_3_INSN, CNUM_INSN, RCPC_INSN, SHA2_INSN, AES_INSN,
aarch64_opcode_encode (const aarch64_opcode *opcode,
const aarch64_inst *inst_ori, aarch64_insn *code,
aarch64_opnd_qualifier_t *qlf_seq,
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;
{
int i;
const aarch64_opcode *aliased;
\fstatic int no_notes = 1; /* If set do not print disassemble notes in the
output as comments. */
\fstatic 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)
{
static void
set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
{