+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
+ * config/tc-aarch64.c (parse_operands, fix_insn): Add
+ A64C_AIMM and A64C_Rm_EXT.
+ * testsuite/gas/aarch64/morello_insn.d: Add tests.
+ * testsuite/gas/aarch64/morello_insn-c64.d: Add tests.
+ * testsuite/gas/aarch64/morello_insn.s: Likewise.
+
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* config/tc-aarch64.c (parse_operands): Add capability
po_int_reg_or_fail (REG_TYPE_R_SP);
break;
+ case AARCH64_OPND_A64C_Rm_EXT:
case AARCH64_OPND_Rm_EXT:
case AARCH64_OPND_Rm_SFT:
po_misc_or_fail (parse_shifter_operand
- (&str, info, (operands[i] == AARCH64_OPND_Rm_EXT
- ? SHIFTED_ARITH_IMM
- : SHIFTED_LOGIC_IMM)));
+ (&str, info, (operands[i] == AARCH64_OPND_Rm_SFT
+ ? SHIFTED_LOGIC_IMM
+ : SHIFTED_ARITH_IMM)));
if (!info->shifter.operator_present)
{
/* Default to LSL if not present. Libopcodes prefers shifter
break;
case AARCH64_OPND_AIMM:
- if (opcode->op == OP_ADD)
+ case AARCH64_OPND_A64C_AIMM:
+ if (opcode->op == OP_ADD || opcode->op == OP_A64C_ADD)
/* ADD may have relocation types. */
po_misc_or_fail (parse_shifter_operand_reloc (&str, info,
SHIFTED_ARITH_IMM));
break;
case AARCH64_OPND_AIMM:
+ case AARCH64_OPND_A64C_AIMM:
/* ADD or SUB with immediate.
NOTE this assumes we come here with a add/sub shifted reg encoding
3 322|2222|2 2 2 21111 111111
.*: c2c1d3ff mov csp, csp
.*: c2c1d3ff mov csp, csp
.*: aa1f03e0 mov x0, xzr
+.*: 023fc135 add c21, c9, #0xff0
+.*: 023ffd35 add c21, c9, #0xfff
+.*: 0247f935 add c21, c9, #0x1fe, lsl #12
+.*: 02000d35 add c21, c9, #0x3
+.*: 02400135 add c21, c9, #0x0, lsl #12
+.*: 02bfc135 sub c21, c9, #0xff0
+.*: 02bffd35 sub c21, c9, #0xfff
+.*: 02c7f935 sub c21, c9, #0x1fe, lsl #12
+.*: 02800d35 sub c21, c9, #0x3
+.*: 02c00135 sub c21, c9, #0x0, lsl #12
+.*: 023fc13f add csp, c9, #0xff0
+.*: 023ffd3f add csp, c9, #0xfff
+.*: 0247f93f add csp, c9, #0x1fe, lsl #12
+.*: 02000d3f add csp, c9, #0x3
+.*: 0240013f add csp, c9, #0x0, lsl #12
+.*: 02bfc13f sub csp, c9, #0xff0
+.*: 02bffd3f sub csp, c9, #0xfff
+.*: 02c7f93f sub csp, c9, #0x1fe, lsl #12
+.*: 02800d3f sub csp, c9, #0x3
+.*: 02c0013f sub csp, c9, #0x0, lsl #12
+.*: 023fc3ff add csp, csp, #0xff0
+.*: 023fffff add csp, csp, #0xfff
+.*: 0247fbff add csp, csp, #0x1fe, lsl #12
+.*: 02000fff add csp, csp, #0x3
+.*: 024003ff add csp, csp, #0x0, lsl #12
+.*: 02bfc3ff sub csp, csp, #0xff0
+.*: 02bfffff sub csp, csp, #0xfff
+.*: 02c7fbff sub csp, csp, #0x1fe, lsl #12
+.*: 02800fff sub csp, csp, #0x3
+.*: 02c003ff sub csp, csp, #0x0, lsl #12
+.*: 023fc3f5 add c21, csp, #0xff0
+.*: 023ffff5 add c21, csp, #0xfff
+.*: 0247fbf5 add c21, csp, #0x1fe, lsl #12
+.*: 02000ff5 add c21, csp, #0x3
+.*: 024003f5 add c21, csp, #0x0, lsl #12
+.*: 02bfc3f5 sub c21, csp, #0xff0
+.*: 02bffff5 sub c21, csp, #0xfff
+.*: 02c7fbf5 sub c21, csp, #0x1fe, lsl #12
+.*: 02800ff5 sub c21, csp, #0x3
+.*: 02c003f5 sub c21, csp, #0x0, lsl #12
+.*: c2a4e131 add c17, c9, x4, sxtx
+.*: c2a4f131 add c17, c9, x4, sxtx #4
+.*: c2a4d131 add c17, c9, w4, sxtw #4
+.*: c2a46131 add c17, c9, x4, uxtx
+.*: c2a47131 add c17, c9, x4, uxtx #4
+.*: c2a4e13f add csp, c9, x4, sxtx
+.*: c2a4f13f add csp, c9, x4, sxtx #4
+.*: c2a4d13f add csp, c9, w4, sxtw #4
+.*: c2a4613f add csp, c9, x4, uxtx
+.*: c2a4713f add csp, c9, x4, uxtx #4
+.*: c2a4e3f1 add c17, csp, x4, sxtx
+.*: c2a4f3f1 add c17, csp, x4, sxtx #4
+.*: c2a4d3f1 add c17, csp, w4, sxtw #4
+.*: c2a463f1 add c17, csp, x4, uxtx
+.*: c2a473f1 add c17, csp, x4, uxtx #4
+.*: c2a4e3ff add csp, csp, x4, sxtx
+.*: c2a4f3ff add csp, csp, x4, sxtx #4
+.*: c2a4d3ff add csp, csp, w4, sxtw #4
+.*: c2a463ff add csp, csp, x4, uxtx
+.*: c2a473ff add csp, csp, x4, uxtx #4
.*: c2c1d3ff mov csp, csp
.*: c2c1d3ff mov csp, csp
.*: aa1f03e0 mov x0, xzr
+.*: 023fc135 add c21, c9, #0xff0
+.*: 023ffd35 add c21, c9, #0xfff
+.*: 0247f935 add c21, c9, #0x1fe, lsl #12
+.*: 02000d35 add c21, c9, #0x3
+.*: 02400135 add c21, c9, #0x0, lsl #12
+.*: 02bfc135 sub c21, c9, #0xff0
+.*: 02bffd35 sub c21, c9, #0xfff
+.*: 02c7f935 sub c21, c9, #0x1fe, lsl #12
+.*: 02800d35 sub c21, c9, #0x3
+.*: 02c00135 sub c21, c9, #0x0, lsl #12
+.*: 023fc13f add csp, c9, #0xff0
+.*: 023ffd3f add csp, c9, #0xfff
+.*: 0247f93f add csp, c9, #0x1fe, lsl #12
+.*: 02000d3f add csp, c9, #0x3
+.*: 0240013f add csp, c9, #0x0, lsl #12
+.*: 02bfc13f sub csp, c9, #0xff0
+.*: 02bffd3f sub csp, c9, #0xfff
+.*: 02c7f93f sub csp, c9, #0x1fe, lsl #12
+.*: 02800d3f sub csp, c9, #0x3
+.*: 02c0013f sub csp, c9, #0x0, lsl #12
+.*: 023fc3ff add csp, csp, #0xff0
+.*: 023fffff add csp, csp, #0xfff
+.*: 0247fbff add csp, csp, #0x1fe, lsl #12
+.*: 02000fff add csp, csp, #0x3
+.*: 024003ff add csp, csp, #0x0, lsl #12
+.*: 02bfc3ff sub csp, csp, #0xff0
+.*: 02bfffff sub csp, csp, #0xfff
+.*: 02c7fbff sub csp, csp, #0x1fe, lsl #12
+.*: 02800fff sub csp, csp, #0x3
+.*: 02c003ff sub csp, csp, #0x0, lsl #12
+.*: 023fc3f5 add c21, csp, #0xff0
+.*: 023ffff5 add c21, csp, #0xfff
+.*: 0247fbf5 add c21, csp, #0x1fe, lsl #12
+.*: 02000ff5 add c21, csp, #0x3
+.*: 024003f5 add c21, csp, #0x0, lsl #12
+.*: 02bfc3f5 sub c21, csp, #0xff0
+.*: 02bffff5 sub c21, csp, #0xfff
+.*: 02c7fbf5 sub c21, csp, #0x1fe, lsl #12
+.*: 02800ff5 sub c21, csp, #0x3
+.*: 02c003f5 sub c21, csp, #0x0, lsl #12
+.*: c2a4e131 add c17, c9, x4, sxtx
+.*: c2a4f131 add c17, c9, x4, sxtx #4
+.*: c2a4d131 add c17, c9, w4, sxtw #4
+.*: c2a46131 add c17, c9, x4, uxtx
+.*: c2a47131 add c17, c9, x4, uxtx #4
+.*: c2a4e13f add csp, c9, x4, sxtx
+.*: c2a4f13f add csp, c9, x4, sxtx #4
+.*: c2a4d13f add csp, c9, w4, sxtw #4
+.*: c2a4613f add csp, c9, x4, uxtx
+.*: c2a4713f add csp, c9, x4, uxtx #4
+.*: c2a4e3f1 add c17, csp, x4, sxtx
+.*: c2a4f3f1 add c17, csp, x4, sxtx #4
+.*: c2a4d3f1 add c17, csp, w4, sxtw #4
+.*: c2a463f1 add c17, csp, x4, uxtx
+.*: c2a473f1 add c17, csp, x4, uxtx #4
+.*: c2a4e3ff add csp, csp, x4, sxtx
+.*: c2a4f3ff add csp, csp, x4, sxtx #4
+.*: c2a4d3ff add csp, csp, w4, sxtw #4
+.*: c2a463ff add csp, csp, x4, uxtx
+.*: c2a473ff add csp, csp, x4, uxtx #4
morello_cspcsp csp, csp
mov c0, czr
+
+// Three operands (dni)
+
+ .macro morello_addsub_imm cdsp, cnsp
+ .irp op, add, sub
+ \op \cdsp, \cnsp, #0xff0
+ \op \cdsp, \cnsp, #0xfff, lsl #0
+ \op \cdsp, \cnsp, #0x1fe, lsl #12
+ \op \cdsp, \cnsp, #0x3, lsl #0
+ \op \cdsp, \cnsp, #0x0, lsl #12
+ .endr
+ .endm
+morello_addsub_imm c21, c9
+morello_addsub_imm csp, c9
+morello_addsub_imm csp, csp
+morello_addsub_imm c21, csp
+
+// Four operands (dnmi)
+
+ .macro morello_add_scalar cspd, cspn, rm
+ .irp op, add
+ \op \cspd, \cspn, x\rm, sxtx #0
+ \op \cspd, \cspn, x\rm, sxtx #4
+ \op \cspd, \cspn, w\rm, sxtw #4
+ \op \cspd, \cspn, x\rm
+ \op \cspd, \cspn, x\rm, lsl #4
+ .endr
+ .endm
+morello_add_scalar c17, c9, 4
+morello_add_scalar csp, c9, 4
+morello_add_scalar c17, csp, 4
+morello_add_scalar csp, csp, 4
+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
+ * opcode/aarch64 (aarch64_opnd): Add A64C_AIMM and
+ A64C_Rm_EXT.
+ (aarch64_op): Add OP_A64C_ADD.
+
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* opcode/aarch64.h (aarch64_opnd): New capability operands.
AARCH64_OPND_Cad_SP, /* Capability register or Cap SP as
destination. */
AARCH64_OPND_Can_SP, /* Capability register or Cap SP as source. */
+ AARCH64_OPND_A64C_Rm_EXT, /* Integer Xm extended. */
+ AARCH64_OPND_A64C_AIMM, /* Add immediate for A64C ADD/SUB. */
};
/* Qualifier constrains an operand. It either specifies a variant of an
OP_ADD,
OP_B,
OP_BL,
+ OP_A64C_ADD,
OP_MOVN,
OP_MOVZ,
+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
+ * aarch64-dis.c (aarch64_ext_regno, aarch64_ext_reg_extended):
+ Identify capability register class.
+ (do_ext_aimm): New function.
+ (arch64_ext_aimm): Call it.
+ (aarch64_ext_a64c_aimm): New function.
+ * aarch64-dis.h (ext_a64c_aimm): New function.
+ * aarch64-opc.c (fields): Add a64c_shift_ai field.
+ (operand_general_constraint_met_p, aarch64_print_operand): Add
+ A64C_AIMM and A64C_Rm_EXT.
+ * aarch64-opc.h (aarch64_field_kind): Add a64c_shift_ai.
+ * aarch64-tbl.h (QL3_A64C_CA_CA_NIL, QL3_A64C_CA_CA_R): New
+ macro.
+ (aarch64_opcode_table): New instructions.
+ (AARCH64_OPERANDS): Add 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-asm.c (do_special_encoding): Recognise capability
aarch64_operand_error *errors ATTRIBUTE_UNUSED)
{
info->reg.regno = extract_field (self->fields[0], code, 0);
+ /* For capability registers, set the qualifier. */
+ if (aarch64_get_operand_class (info->type) == AARCH64_OPND_CLASS_CAP_REG)
+ info->qualifier = AARCH64_OPND_QLF_CA;
+
return true;
}
return true;
}
-/* Decode arithmetic immediate for e.g.
- SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
-bool
-aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
+static bool
+do_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
aarch64_opnd_info *info, const aarch64_insn code,
const aarch64_inst *inst ATTRIBUTE_UNUSED,
- aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+ aarch64_operand_error *errors ATTRIBUTE_UNUSED,
+ int shift_amount, enum aarch64_field_kind imm,
+ enum aarch64_field_kind shift)
{
aarch64_insn value;
info->shifter.kind = AARCH64_MOD_LSL;
/* shift */
- value = extract_field (FLD_shift, code, 0);
+ value = extract_field (shift, code, 0);
if (value >= 2)
return false;
- info->shifter.amount = value ? 12 : 0;
- /* imm12 (unsigned) */
- info->imm.value = extract_field (FLD_imm12, code, 0);
+ info->shifter.amount = value ? shift_amount : 0;
+ info->imm.value = extract_field (imm, code, 0);
return true;
}
+/* Decode arithmetic immediate for e.g.
+ SUBS <Cd>, <Cn|CSP>, #<imm> {, <shift>}. */
+bool
+aarch64_ext_a64c_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
+ aarch64_opnd_info *info, const aarch64_insn code,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED,
+ aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+ return do_ext_aimm (self, info, code, inst, errors, 12, FLD_imm12,
+ FLD_a64c_shift_ai);
+}
+
+/* Decode arithmetic immediate for e.g.
+ SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
+bool
+aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
+ aarch64_opnd_info *info, const aarch64_insn code,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED,
+ aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+ return do_ext_aimm (self, info, code, inst, errors, 12, FLD_imm12,
+ FLD_shift);
+}
+
/* Return true if VALUE is a valid logical immediate encoding, storing the
decoded value in *RESULT if so. ESIZE is the number of bytes in the
decoded immediate. */
/* Assume inst->operands[0].qualifier has been resolved. */
assert (inst->operands[0].qualifier != AARCH64_OPND_QLF_NIL);
info->qualifier = AARCH64_OPND_QLF_W;
- if (inst->operands[0].qualifier == AARCH64_OPND_QLF_X
+ if ((inst->operands[0].qualifier == AARCH64_OPND_QLF_CA
+ || inst->operands[0].qualifier == AARCH64_OPND_QLF_X)
&& (info->shifter.kind == AARCH64_MOD_UXTX
|| info->shifter.kind == AARCH64_MOD_SXTX))
info->qualifier = AARCH64_OPND_QLF_X;
AARCH64_DECL_OPD_EXTRACTOR (ext_imm_rotate1);
AARCH64_DECL_OPD_EXTRACTOR (ext_imm_rotate2);
AARCH64_DECL_OPD_EXTRACTOR (ext_x0_to_x30);
+AARCH64_DECL_OPD_EXTRACTOR (ext_a64c_aimm);
#undef AARCH64_DECL_OPD_EXTRACTOR
instructions. */
{ 10, 5 }, /* Cat2, Capability register in destination for load store pair
type instructions. */
+ { 22, 1 }, /* a64c_shift_ai: Shift bit in immediate ADD/SUB. */
};
enum aarch64_operand_class
switch (type)
{
case AARCH64_OPND_AIMM:
+ case AARCH64_OPND_A64C_AIMM:
if (opnd->shifter.kind != AARCH64_MOD_LSL)
{
set_other_error (mismatch_detail, idx,
assert (idx == 1 || idx == 2);
switch (type)
{
+ case AARCH64_OPND_A64C_Rm_EXT:
case AARCH64_OPND_Rm_EXT:
if (!aarch64_extend_operator_p (opnd->shifter.kind)
&& opnd->shifter.kind != AARCH64_MOD_LSL)
(i.e. SP), in which case it defaults to LSL. The LSL alias is
only valid when "Rd" or "Rn" is '11111', and is preferred in that
case. */
- if (!aarch64_stack_pointer_p (opnds + 0)
+ if (type == AARCH64_OPND_Rm_EXT
+ && !aarch64_stack_pointer_p (opnds + 0)
&& (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
{
if (!opnd->shifter.operator_present)
get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
break;
+ case AARCH64_OPND_A64C_Rm_EXT:
case AARCH64_OPND_Rm_EXT:
kind = opnd->shifter.kind;
assert (idx == 1 || idx == 2);
snprintf (buf, size, "#0.0");
break;
+ case AARCH64_OPND_A64C_AIMM:
case AARCH64_OPND_LIMM:
case AARCH64_OPND_AIMM:
case AARCH64_OPND_HALF:
FLD_Cas,
FLD_Cat,
FLD_Cat2,
+ FLD_a64c_shift_ai,
};
/* Field description. */
{ \
QLF2(CA, CA), \
}
+
+#define QL3_A64C_CA_CA_NIL \
+{ \
+ QLF3(CA, CA, NIL), \
+}
+
+/* e.g. ADD <Cd|CSP>, <Cn|CSP>, <Xm>{, <extend> {#<amount>}}. */
+#define QL3_A64C_CA_CA_R \
+{ \
+ QLF3(CA, CA, X), \
+ QLF3(CA, CA, W), \
+}
+
\f
/* Opcode table. */
A64C_INSN ("cpy", 0xc2c1d000, 0xfffffc00, a64c, 0, OP2 (Cad_SP, Can_SP), QL2_A64C_CA_CA, F_HAS_ALIAS),
A64C_INSN ("mov", 0xc2c1d000, 0xfffffc00, a64c, 0, OP2 (Cad_SP, Can_SP), QL2_A64C_CA_CA, F_ALIAS | F_P1),
A64C_INSN ("mov", 0x2a1f03e0, 0x7fffffe0, a64c, OP_MOV_C_ZR, OP2 (Cad, Can), QL2_A64C_CA_CA, F_ALIAS | F_SF | F_P1),
+ A64C_INSN ("add", 0x02000000, 0xff800000, a64c, OP_A64C_ADD, OP3 (Cad_SP, Can_SP, AIMM), QL3_A64C_CA_CA_NIL, 0),
+ A64C_INSN ("add", 0xc2a00000, 0xffe00000, a64c, 0, OP3 (Cad_SP, Can_SP, A64C_Rm_EXT), QL3_A64C_CA_CA_R, 0),
+ A64C_INSN ("sub", 0x02800000, 0xff800000, a64c, 0, OP3 (Cad_SP, Can_SP, A64C_AIMM), QL3_A64C_CA_CA_NIL, 0),
/* TME Instructions. */
_TME_INSN ("tstart", 0xd5233060, 0xffffffe0, 0, 0, OP1 (Rd), QL_I1X, 0),
_TME_INSN ("tcommit", 0xd503307f, 0xffffffff, 0, 0, OP0 (), {}, 0),
Y(CAP_REG, regno, "Cad_SP", OPD_F_MAYBE_CSP, F(FLD_Cad), \
"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")
+ "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, 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")