- BLR, BLRR, BLRS, BR, BRR, BRS, BX.
- RET, RETR, RETS.
Disassembly note: RET with capability is always disassembled with the
register name even if it is the default register, i.e. C30. This is
to make it visually simpler to differentiate between the A64 and
Morello RET instructions.
gas/ChangeLog:
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* config/tc-aarch64.c (process_omitted_operand): Identify Can.
(parse_operands): Add CST_REG, Cam_SP
and A64C_IMMV4.
* testsuite/gas/aarch64/morello_insn.s: Add tests.
* testsuite/gas/aarch64/morello_insn.d: Likewise.
* testsuite/gas/aarch64/morello_insn-c64.d: Likewise.
include/ChangeLog:
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* opcode/aarch64.h (aarch64_opnd): Add CST_REG, Cam_SP
and A64C_IMMV4.
(aarch64_insn_class): Add br_sealed.
opcodes/ChangeLog:
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* aarch64-dis.c (aarch64_ext_a64c_immv): New function.
(aarch64_ext_regno): Set PRESENT flag for A64 RET.
* aarch64-dis.h (aarch64_ext_a64c_immv): New function.
* aarch64-opc.c (operand_general_constraint_met_p): Add
A64C_IMMV4. Remove ATTRIBUTE_UNUSED. Reject A64 RET without
operand when in C64.
(aarch64_match_operands_constraint): Remove ATTRIBUTE_UNUSED.
(aarch64_print_operand): Add A64C_IMMV4, Cam_SP and CST_REG.
* aarch64-tbl.h (QL1_A64C_CA, QL3_A64C_CA_CA_CA): New macros.
(aarch64_opcode_table): New instructions.
(AARCH64_OPERANDS): New operands.
* aarch64-asm-2.c: Regenerate.
* aarch64-dis-2.c: Regenerate.
* aarch64-opc-2.c: Regenerate.
+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
+ * config/tc-aarch64.c (process_omitted_operand): Identify Can.
+ (parse_operands): Add CST_REG, Cam_SP
+ and A64C_IMMV4.
+ * testsuite/gas/aarch64/morello_insn.s: Add tests.
+ * testsuite/gas/aarch64/morello_insn.d: Likewise.
+ * testsuite/gas/aarch64/morello_insn-c64.d: Likewise.
+
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* config/tc-aarch64.c (parse_operands): Add A64C_IMM8.
switch (type)
{
+ case AARCH64_OPND_Can:
case AARCH64_OPND_Rd:
case AARCH64_OPND_Rn:
case AARCH64_OPND_Rm:
info->qualifier = AARCH64_OPND_QLF_CA;
break;
+ case AARCH64_OPND_A64C_CST_REG:
+ po_reg_or_fail (REG_TYPE_CA_N);
+ if (val != 29
+ && (opcode->iclass == br_sealed))
+ {
+ set_fatal_syntax_error
+ (_(N_ ("Capability register c29 expected")));
+ goto failure;
+ }
+ info->reg.regno = val;
+ info->qualifier = AARCH64_OPND_QLF_CA;
+ break;
+
+ case AARCH64_OPND_Cam_SP:
case AARCH64_OPND_Can_SP:
case AARCH64_OPND_Cad_SP:
po_reg_or_fail (REG_TYPE_CA_N_SP);
info->imm.value = val;
break;
+ case AARCH64_OPND_A64C_IMMV4:
+ po_imm_nc_or_fail ();
+ if (val != 4)
+ {
+ set_fatal_syntax_error (_("immediate #4 expected"));
+ goto failure;
+ }
+ info->imm.value = 4;
+ break;
+
case AARCH64_OPND_IMM0:
po_imm_nc_or_fail ();
if (val != 0)
Disassembly of section \.text:
.* <.text>:
+.*: c2c273e0 bx #4
+.*: c2c253c0 ret c30
+.*: c2c23280 blr c20
+.*: c2c23283 blrr c20
+.*: c2c23282 blrs c20
+.*: c2c21280 br c20
+.*: c2c21283 brr c20
+.*: c2c21282 brs c20
+.*: c2c25280 ret c20
+.*: c2c25283 retr c20
+.*: c2c25282 rets c20
.*: c2c1d26b mov c11, c19
.*: c2c1d26b mov c11, c19
.*: c2c1d3eb mov c11, csp
.*: c2d92be7 bicflgs c7, csp, x25
.*: c2d928df bicflgs csp, c6, x25
.*: c2d92bff bicflgs csp, csp, x25
+.*: c2c4a440 blrs c29, c2, c4
+.*: c2c48440 brs c29, c2, c4
+.*: c2c4c440 rets c29, c2, c4
.*: c2a4e131 add c17, c9, x4, sxtx
.*: c2a4f131 add c17, c9, x4, sxtx #4
.*: c2a4d131 add c17, c9, w4, sxtw #4
Disassembly of section \.text:
.* <.text>:
+.*: c2c273e0 bx #4
+.*: d65f03c0 ret
+.*: c2c23280 blr c20
+.*: c2c23283 blrr c20
+.*: c2c23282 blrs c20
+.*: c2c21280 br c20
+.*: c2c21283 brr c20
+.*: c2c21282 brs c20
+.*: c2c25280 ret c20
+.*: c2c25283 retr c20
+.*: c2c25282 rets c20
.*: c2c1d26b mov c11, c19
.*: c2c1d26b mov c11, c19
.*: c2c1d3eb mov c11, csp
.*: c2d92be7 bicflgs c7, csp, x25
.*: c2d928df bicflgs csp, c6, x25
.*: c2d92bff bicflgs csp, csp, x25
+.*: c2c4a440 blrs c29, c2, c4
+.*: c2c48440 brs c29, c2, c4
+.*: c2c4c440 rets c29, c2, c4
.*: c2a4e131 add c17, c9, x4, sxtx
.*: c2a4f131 add c17, c9, x4, sxtx #4
.*: c2a4d131 add c17, c9, w4, sxtw #4
+// Zero/one operands
+
+bx #4
+ret
+
+// Single operand (n)
+
+ .macro morello_jump cn
+ .irp op, blr, blrr, blrs, br, brr, brs, ret, retr, rets
+ \op \cn
+ .endr
+ .endm
+morello_jump c20
+
// Two operands (dn).
.macro morello_cspcsp cdsp, cnsp
morello_cspcspx csp, c6, x25
morello_cspcspx csp, csp, x25
+ .macro morello_jump_sealed cn, cm
+ .irp op, blrs, brs, rets
+ \op c29, \cn, \cm
+ .endr
+ .endm
+morello_jump_sealed c2, c4
+
// Four operands (dnmi)
.macro morello_add_scalar cspd, cspn, rm
+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
+ * opcode/aarch64.h (aarch64_opnd): Add CST_REG, Cam_SP
+ and A64C_IMMV4.
+ (aarch64_insn_class): Add br_sealed.
+
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* opcode/aarch64.h (aarch64_opnd): Add A64C_IMM8.
AARCH64_OPND_Cad_SP, /* Capability register or Cap SP as
destination. */
AARCH64_OPND_Can_SP, /* Capability register or Cap SP as source. */
+ AARCH64_OPND_Cam_SP, /* Capability register or Cap SP as source. */
AARCH64_OPND_A64C_Rm_EXT, /* Integer Xm extended. */
+ AARCH64_OPND_A64C_IMMV4, /* Immediate value #4 for BX. */
+ AARCH64_OPND_A64C_CST_REG, /* Constant capability register c29 for
+ BRS/BLRS. */
AARCH64_OPND_A64C_AIMM, /* Add immediate for A64C ADD/SUB. */
AARCH64_OPND_A64C_IMM8, /* IMM8 for BICFLGS. */
};
dotproduct,
bfloat16,
a64c,
+ br_sealed,
};
/* Opcode enumerators. */
+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
+ * aarch64-dis.c (aarch64_ext_a64c_immv): New function.
+ (aarch64_ext_regno): Set PRESENT flag for A64 RET.
+ * aarch64-dis.h (aarch64_ext_a64c_immv): New function.
+ * aarch64-opc.c (operand_general_constraint_met_p): Add
+ A64C_IMMV4. Remove ATTRIBUTE_UNUSED. Reject A64 RET without
+ operand when in C64.
+ (aarch64_match_operands_constraint): Remove ATTRIBUTE_UNUSED.
+ (aarch64_print_operand): Add A64C_IMMV4, Cam_SP and CST_REG.
+ * aarch64-tbl.h (QL1_A64C_CA, QL3_A64C_CA_CA_CA): New macros.
+ (aarch64_opcode_table): New instructions.
+ (AARCH64_OPERANDS): New operands.
+ * aarch64-asm-2.c: Regenerate.
+ * aarch64-dis-2.c: Regenerate.
+ * aarch64-opc-2.c: Regenerate.
+
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* aarch64-opc.c (fields): Add a64c_imm8.
if (aarch64_get_operand_class (info->type) == AARCH64_OPND_CLASS_CAP_REG)
info->qualifier = AARCH64_OPND_QLF_CA;
+ /* Allow disassembly of A64 RET when encountered in C64 code. */
+ if (inst->opcode->iclass == branch_reg)
+ info->present = 1;
+
return true;
}
return true;
}
+/* Set immediate value #4 when decoding for e.g. BX. */
+bool
+aarch64_ext_a64c_immv (const aarch64_operand *self ATTRIBUTE_UNUSED,
+ aarch64_opnd_info *info,
+ const aarch64_insn code ATTRIBUTE_UNUSED,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED,
+ aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+ if (info->type == AARCH64_OPND_A64C_IMMV4)
+ {
+ info->imm.value = 4;
+ return true;
+ }
+ if (info->type == AARCH64_OPND_A64C_CST_REG
+ && (inst->opcode->iclass == br_sealed))
+ {
+ info->reg.regno = 29;
+ return true;
+ }
+
+ return false;
+}
+
/* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
bool
aarch64_ext_imm_half (const aarch64_operand *self, aarch64_opnd_info *info,
AARCH64_DECL_OPD_EXTRACTOR (ext_imm_rotate2);
AARCH64_DECL_OPD_EXTRACTOR (ext_x0_to_x30);
AARCH64_DECL_OPD_EXTRACTOR (ext_a64c_aimm);
+AARCH64_DECL_OPD_EXTRACTOR (ext_a64c_immv);
#undef AARCH64_DECL_OPD_EXTRACTOR
represent an error. */
static int
-operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
+operand_general_constraint_met_p (aarch64_feature_set features,
+ const aarch64_opnd_info *opnds, int idx,
enum aarch64_opnd type,
const aarch64_opcode *opcode,
aarch64_operand_error *mismatch_detail)
default:
break;
}
+ /* Reject A64 RET with default operand when in C64 mode. */
+ if (opcode->iclass == branch_reg
+ && AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_C64)
+ && !opnd->present)
+ {
+ set_other_error (mismatch_detail, idx,
+ _("capability register expected"));
+ return 0;
+ }
break;
case AARCH64_OPND_CLASS_SVE_REG:
}
break;
+ case AARCH64_OPND_A64C_IMMV4:
+ if (opnd->imm.value != 4)
+ {
+ set_other_error (mismatch_detail, idx,
+ _("immediate #4 expected"));
+ return 0;
+ }
+ break;
+
case AARCH64_OPND_IMM0:
case AARCH64_OPND_FPIMM0:
if (opnd->imm.value != 0)
Un-determined operand qualifiers may get established during the process. */
int
-aarch64_match_operands_constraint (aarch64_feature_set features
- ATTRIBUTE_UNUSED, aarch64_inst *inst,
+aarch64_match_operands_constraint (aarch64_feature_set features,
+ aarch64_inst *inst,
aarch64_operand_error *mismatch_detail)
{
int i;
DEBUG_TRACE ("skip the incomplete operand %d", i);
continue;
}
- if (operand_general_constraint_met_p (inst->operands, i, type,
+ if (operand_general_constraint_met_p (features, inst->operands, i, type,
inst->opcode,
mismatch_detail) == 0)
{
snprintf (buf, size, "C%" PRIi64, opnd->imm.value);
break;
+ case AARCH64_OPND_A64C_IMMV4:
case AARCH64_OPND_A64C_IMM8:
case AARCH64_OPND_IDX:
case AARCH64_OPND_MASK:
case AARCH64_OPND_Cad_SP:
case AARCH64_OPND_Can_SP:
+ case AARCH64_OPND_Cam_SP:
snprintf (buf, size, "%s", get_cap_reg_name (opnd->reg.regno, 1));
break;
+ case AARCH64_OPND_A64C_CST_REG:
case AARCH64_OPND_Cat:
case AARCH64_OPND_Cat2:
case AARCH64_OPND_Can:
QLF3(V_4S, V_8H, S_H), \
}
+#define QL1_A64C_CA \
+{ \
+ QLF1(CA), \
+}
+
#define QL2_A64C_CA_CA \
{ \
QLF2(CA, CA), \
QLF3(CA, CA, X), \
}
+#define QL3_A64C_CA_CA_CA \
+{ \
+ QLF3(CA, CA, CA), \
+}
\f
/* Opcode table. */
A64C_INSN ("sub", 0x02800000, 0xff800000, a64c, 0, OP3 (Cad_SP, Can_SP, A64C_AIMM), QL3_A64C_CA_CA_NIL, 0),
A64C_INSN ("bicflgs", 0xc2e00000, 0xffe01c00, a64c, 0, OP3 (Cad_SP, Can_SP, A64C_IMM8), QL3_A64C_CA_CA_NIL, 0),
A64C_INSN ("bicflgs", 0xc2c02800, 0xffe0fc00, a64c, 0, OP3 (Cad_SP, Can_SP, Rm), QL3_A64C_CA_CA_X, 0),
+ A64C_INSN ("blr", 0xc2c23000, 0xfffffc1f, a64c, 0, OP1 (Can), QL1_A64C_CA, 0),
+ A64C_INSN ("blrr", 0xc2c23003, 0xfffffc1f, a64c, 0, OP1 (Can), QL1_A64C_CA, 0),
+ A64C_INSN ("blrs", 0xc2c23002, 0xfffffc1f, a64c, 0, OP1 (Can), QL1_A64C_CA, 0),
+ A64C_INSN ("blrs", 0xc2c0a400, 0xffe0fc1f, br_sealed, 0, OP3 (A64C_CST_REG, Can, Cam), QL3_A64C_CA_CA_CA, 0),
+ A64C_INSN ("br", 0xc2c21000, 0xfffffc1f, a64c, 0, OP1 (Can), QL1_A64C_CA, 0),
+ A64C_INSN ("brr", 0xc2c21003, 0xfffffc1f, a64c, 0, OP1 (Can), QL1_A64C_CA, 0),
+ A64C_INSN ("brs", 0xc2c21002, 0xfffffc1f, a64c, 0, OP1 (Can), QL1_A64C_CA, 0),
+ A64C_INSN ("brs", 0xc2c08400, 0xffe0fc1f, br_sealed, 0, OP3 (A64C_CST_REG, Can, Cam), QL3_A64C_CA_CA_CA, 0),
+ A64C_INSN ("bx", 0xc2c273e0, 0xffffffff, a64c, 0, OP1 (A64C_IMMV4), {}, 0),
+ A64C_INSN ("ret", 0xc2c25000, 0xfffffc1f, a64c, 0, OP1 (Can), QL1_A64C_CA, F_OPD0_OPT | F_DEFAULT (30)),
+ A64C_INSN ("retr", 0xc2c25003, 0xfffffc1f, a64c, 0, OP1 (Can), QL1_A64C_CA, 0),
+ A64C_INSN ("rets", 0xc2c25002, 0xfffffc1f, a64c, 0, OP1 (Can), QL1_A64C_CA, 0),
+ A64C_INSN ("rets", 0xc2c0c400, 0xffe0fc1f, br_sealed, 0, OP3 (A64C_CST_REG, Can, Cam), QL3_A64C_CA_CA_CA, 0),
/* TME Instructions. */
_TME_INSN ("tstart", 0xd5233060, 0xffffffe0, 0, 0, OP1 (Rd), QL_I1X, 0),
_TME_INSN ("tcommit", 0xd503307f, 0xffffffff, 0, 0, OP0 (), {}, 0),
"a Capability register or a capability stack pointer register") \
Y(CAP_REG, regno, "Can_SP", OPD_F_MAYBE_CSP, F(FLD_Can), \
"a Capability register or a capability stack pointer register") \
+ Y(CAP_REG, regno, "Cam_SP", OPD_F_MAYBE_CSP, F(FLD_Cam), \
+ "a Capability register or a capability stack pointer register") \
Y(MODIFIED_REG, reg_extended, "A64C_Rm_EXT", 0, F(), \
"an integer register with extension") \
+ X(IMMEDIATE, 0, ext_a64c_immv, "A64C_IMMV4", 0, F(), "4") \
+ X(CAP_REG, 0, ext_a64c_immv, "A64C_CST_REG", 0, F(), \
+ "capability register c29") \
X(IMMEDIATE, ins_aimm, ext_a64c_aimm, "A64C_AIMM", 0, \
F(FLD_a64c_shift_ai,FLD_imm12), \
"a 12-bit unsigned immediate with optional left shift of 12 bits")\