aarch64: [SME] Add SME mode selection and state access instructions

This patch is adding new SME mode selection and state access instructions:
* Add SMSTART and SMSTOP instructions.
* Add SVCR system register.

gas/ChangeLog:

	* config/tc-aarch64.c (parse_sme_sm_za): New parser.
	(parse_operands): New parser.
	* testsuite/gas/aarch64/sme-8-illegal.d: New test.
	* testsuite/gas/aarch64/sme-8-illegal.l: New test.
	* testsuite/gas/aarch64/sme-8-illegal.s: New test.
	* testsuite/gas/aarch64/sme-8.d: New test.
	* testsuite/gas/aarch64/sme-8.s: New test.

include/ChangeLog:

	* opcode/aarch64.h (enum aarch64_opnd): New operand
	AARCH64_OPND_SME_SM_ZA.
	(enum aarch64_insn_class): New instruction classes
	sme_start and sme_stop.

opcodes/ChangeLog:

	* aarch64-asm.c (aarch64_ins_pstatefield): New inserter.
	(aarch64_ins_sme_sm_za): New inserter.
	* aarch64-dis.c (aarch64_ext_imm): New extractor.
	(aarch64_ext_pstatefield): New extractor.
	(aarch64_ext_sme_sm_za): New extractor.
	* aarch64-opc.c (operand_general_constraint_met_p):
	New pstatefield value for SME instructions.
	(aarch64_print_operand): Printout for OPND_SME_SM_ZA.
	(SR_SME): New register SVCR.
	* aarch64-opc.h (F_REG_IN_CRM): New register endcoding.
	* aarch64-opc.h (F_IMM_IN_CRM): New immediate endcoding.
	(PSTATE_ENCODE_CRM): Encode CRm field.
	(PSTATE_DECODE_CRM): Decode CRm field.
	(PSTATE_ENCODE_CRM_IMM): Encode CRm immediate field.
	(PSTATE_DECODE_CRM_IMM): Decode CRm immediate field.
	(PSTATE_ENCODE_CRM_AND_IMM): Encode CRm and immediate
	field.
	* aarch64-tbl.h (struct aarch64_opcode): New SMSTART
	and SMSTOP instructions.
	aarch64-asm-2.c: Regenerate.
	aarch64-dis-2.c: Regenerate.
	aarch64-opc-2.c: Regenerate.
This commit is contained in:
Przemyslaw Wirkus 2021-11-17 20:15:13 +00:00
parent 01a4d08220
commit 3dd032c5fb
17 changed files with 1775 additions and 1531 deletions

View File

@ -4629,6 +4629,32 @@ parse_sme_za_array (char **str, int *imm)
return regno;
}
/* Parse streaming mode operand for SMSTART and SMSTOP.
{SM | ZA}
Function returns 's' if SM or 'z' if ZM is parsed. Otherwise PARSE_FAIL.
*/
static int
parse_sme_sm_za (char **str)
{
char *p, *q;
p = q = *str;
while (ISALPHA (*q))
q++;
if ((q - p != 2)
|| (strncasecmp ("sm", p, 2) != 0 && strncasecmp ("za", p, 2) != 0))
{
set_syntax_error (_("expected SM or ZA operand"));
return PARSE_FAIL;
}
*str = q;
return TOLOWER (p[0]);
}
/* Parse a system register or a PSTATE field name for an MSR/MRS instruction.
Returns the encoding for the option, or PARSE_FAIL.
@ -7032,6 +7058,16 @@ parse_operands (char *str, const aarch64_opcode *opcode)
/* No qualifier. */
break;
case AARCH64_OPND_SME_SM_ZA:
/* { SM | ZA } */
if ((val = parse_sme_sm_za (&str)) == PARSE_FAIL)
{
set_syntax_error (_("unknown or missing PSTATE field name"));
goto failure;
}
info->reg.regno = val;
break;
case AARCH64_OPND_SVE_ADDR_RI_S4x16:
case AARCH64_OPND_SVE_ADDR_RI_S4x32:
case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
@ -7221,14 +7257,18 @@ parse_operands (char *str, const aarch64_opcode *opcode)
}
case AARCH64_OPND_PSTATEFIELD:
if ((val = parse_sys_reg (&str, aarch64_pstatefield_hsh, 0, 1, NULL))
== PARSE_FAIL)
{
set_syntax_error (_("unknown or missing PSTATE field name"));
goto failure;
}
inst.base.operands[i].pstatefield = val;
break;
{
uint32_t sysreg_flags;
if ((val = parse_sys_reg (&str, aarch64_pstatefield_hsh, 0, 1,
&sysreg_flags)) == PARSE_FAIL)
{
set_syntax_error (_("unknown or missing PSTATE field name"));
goto failure;
}
inst.base.operands[i].pstatefield = val;
inst.base.operands[i].sysreg.flags = sysreg_flags;
break;
}
case AARCH64_OPND_SYSREG_IC:
inst.base.operands[i].sysins_op =

View File

@ -0,0 +1,3 @@
#as: -march=armv8-a+sme
#source: sme-8-illegal.s
#error_output: sme-8-illegal.l

View File

@ -0,0 +1,7 @@
[^:]*: Assembler messages:
[^:]*:[0-9]+: Error: unexpected characters following instruction -- `smstart x0'
[^:]*:[0-9]+: Error: unexpected characters following instruction -- `smstart sa'
[^:]*:[0-9]+: Error: unexpected characters following instruction -- `smstart zm'
[^:]*:[0-9]+: Error: unexpected characters following instruction -- `smstop x0'
[^:]*:[0-9]+: Error: unexpected characters following instruction -- `smstop sa'
[^:]*:[0-9]+: Error: unexpected characters following instruction -- `smstop zm'

View File

@ -0,0 +1,9 @@
/* Scalable Matrix Extension (SME). */
smstart x0
smstart sa
smstart zm
smstop x0
smstop sa
smstop zm

View File

@ -0,0 +1,27 @@
#name: SME mode selection and state access instructions
#as: -march=armv8-a+sme
#objdump: -dr
.*: file format .*
Disassembly of section \.text:
0+ <.*>:
0: d53b4240 mrs x0, svcr
4: d51b4240 msr svcr, x0
8: d503427f smstop sm
c: d503447f smstop za
10: d503467f smstop
14: d503437f smstart sm
18: d503457f smstart za
1c: d503477f smstart
20: d503477f smstart
24: d503437f smstart sm
28: d503457f smstart za
2c: d503437f smstart sm
30: d503457f smstart za
34: d503467f smstop
38: d503427f smstop sm
3c: d503447f smstop za
40: d503427f smstop sm
44: d503447f smstop za

View File

@ -0,0 +1,28 @@
/* SME mode selection and state access instructions. */
/* SVCR system register access. */
mrs x0, svcr
msr svcr, x0
/* MSR SVCR Immediate access. */
msr svcrsm, #0
msr svcrza, #0
msr svcrsmza, #0
msr svcrsm, #1
msr svcrza, #1
msr svcrsmza, #1
/* SMSTART. */
smstart
smstart sm
smstart za
smstart SM
smstart ZA
/* SMSTOP. */
smstop
smstop sm
smstop za
smstop SM
smstop ZA

View File

@ -454,6 +454,7 @@ enum aarch64_opnd
AARCH64_OPND_SME_ZA_HV_idx_ldstr, /* SME destination ZA tile vector. */
AARCH64_OPND_SME_ZA_array, /* SME ZA[<Wv>{, #<imm>}]. */
AARCH64_OPND_SME_ADDR_RI_U4xVL, /* SME [<Xn|SP>{, #<imm>, MUL VL}]. */
AARCH64_OPND_SME_SM_ZA, /* SME {SM | ZA}. */
AARCH64_OPND_TME_UIMM16, /* TME unsigned 16-bit immediate. */
AARCH64_OPND_SM3_IMM2, /* SM3 encodes lane in bits [13, 14]. */
};
@ -621,6 +622,8 @@ enum aarch64_insn_class
sme_misc,
sme_ldr,
sme_str,
sme_start,
sme_stop,
sve_cpy,
sve_index,
sve_limm,

View File

@ -426,176 +426,176 @@ aarch64_find_real_opcode (const aarch64_opcode *opcode)
case 1188: /* movz */
value = 1188; /* --> movz. */
break;
case 1246: /* autibsp */
case 1245: /* autibz */
case 1244: /* autiasp */
case 1243: /* autiaz */
case 1242: /* pacibsp */
case 1241: /* pacibz */
case 1240: /* paciasp */
case 1239: /* paciaz */
case 1215: /* tsb */
case 1214: /* psb */
case 1213: /* esb */
case 1212: /* autib1716 */
case 1211: /* autia1716 */
case 1210: /* pacib1716 */
case 1209: /* pacia1716 */
case 1208: /* xpaclri */
case 1206: /* sevl */
case 1205: /* sev */
case 1204: /* wfi */
case 1203: /* wfe */
case 1202: /* yield */
case 1201: /* bti */
case 1200: /* csdb */
case 1199: /* nop */
case 1198: /* hint */
value = 1198; /* --> hint. */
case 1250: /* autibsp */
case 1249: /* autibz */
case 1248: /* autiasp */
case 1247: /* autiaz */
case 1246: /* pacibsp */
case 1245: /* pacibz */
case 1244: /* paciasp */
case 1243: /* paciaz */
case 1219: /* tsb */
case 1218: /* psb */
case 1217: /* esb */
case 1216: /* autib1716 */
case 1215: /* autia1716 */
case 1214: /* pacib1716 */
case 1213: /* pacia1716 */
case 1212: /* xpaclri */
case 1210: /* sevl */
case 1209: /* sev */
case 1208: /* wfi */
case 1207: /* wfe */
case 1206: /* yield */
case 1205: /* bti */
case 1204: /* csdb */
case 1203: /* nop */
case 1202: /* hint */
value = 1202; /* --> hint. */
break;
case 1221: /* pssbb */
case 1220: /* ssbb */
case 1219: /* dfb */
case 1217: /* dsb */
value = 1217; /* --> dsb. */
case 1225: /* pssbb */
case 1224: /* ssbb */
case 1223: /* dfb */
case 1221: /* dsb */
value = 1221; /* --> dsb. */
break;
case 1218: /* dsb */
value = 1218; /* --> dsb. */
case 1222: /* dsb */
value = 1222; /* --> dsb. */
break;
case 1234: /* cpp */
case 1233: /* dvp */
case 1232: /* cfp */
case 1229: /* tlbi */
case 1228: /* ic */
case 1227: /* dc */
case 1226: /* at */
case 1225: /* sys */
value = 1225; /* --> sys. */
case 1238: /* cpp */
case 1237: /* dvp */
case 1236: /* cfp */
case 1233: /* tlbi */
case 1232: /* ic */
case 1231: /* dc */
case 1230: /* at */
case 1229: /* sys */
value = 1229; /* --> sys. */
break;
case 1230: /* wfet */
value = 1230; /* --> wfet. */
case 1234: /* wfet */
value = 1234; /* --> wfet. */
break;
case 1231: /* wfit */
value = 1231; /* --> wfit. */
case 1235: /* wfit */
value = 1235; /* --> wfit. */
break;
case 2044: /* bic */
case 1294: /* and */
value = 1294; /* --> and. */
case 2048: /* bic */
case 1298: /* and */
value = 1298; /* --> and. */
break;
case 1277: /* mov */
case 1296: /* and */
value = 1296; /* --> and. */
case 1281: /* mov */
case 1300: /* and */
value = 1300; /* --> and. */
break;
case 1281: /* movs */
case 1297: /* ands */
value = 1297; /* --> ands. */
case 1285: /* movs */
case 1301: /* ands */
value = 1301; /* --> ands. */
break;
case 2045: /* cmple */
case 1332: /* cmpge */
value = 1332; /* --> cmpge. */
case 2049: /* cmple */
case 1336: /* cmpge */
value = 1336; /* --> cmpge. */
break;
case 2048: /* cmplt */
case 1335: /* cmpgt */
value = 1335; /* --> cmpgt. */
case 2052: /* cmplt */
case 1339: /* cmpgt */
value = 1339; /* --> cmpgt. */
break;
case 2046: /* cmplo */
case 1337: /* cmphi */
value = 1337; /* --> cmphi. */
case 2050: /* cmplo */
case 1341: /* cmphi */
value = 1341; /* --> cmphi. */
break;
case 2047: /* cmpls */
case 1340: /* cmphs */
value = 1340; /* --> cmphs. */
break;
case 1274: /* mov */
case 1362: /* cpy */
value = 1362; /* --> cpy. */
break;
case 1276: /* mov */
case 1363: /* cpy */
value = 1363; /* --> cpy. */
break;
case 2055: /* fmov */
case 1279: /* mov */
case 1364: /* cpy */
value = 1364; /* --> cpy. */
break;
case 1269: /* mov */
case 1376: /* dup */
value = 1376; /* --> dup. */
break;
case 1271: /* mov */
case 1268: /* mov */
case 1377: /* dup */
value = 1377; /* --> dup. */
break;
case 2054: /* fmov */
case 1273: /* mov */
case 1378: /* dup */
value = 1378; /* --> dup. */
break;
case 1272: /* mov */
case 1379: /* dupm */
value = 1379; /* --> dupm. */
break;
case 2049: /* eon */
case 1381: /* eor */
value = 1381; /* --> eor. */
break;
case 1282: /* not */
case 1383: /* eor */
value = 1383; /* --> eor. */
break;
case 1283: /* nots */
case 1384: /* eors */
value = 1384; /* --> eors. */
break;
case 2050: /* facle */
case 1389: /* facge */
value = 1389; /* --> facge. */
break;
case 2051: /* faclt */
case 1390: /* facgt */
value = 1390; /* --> facgt. */
break;
case 2052: /* fcmle */
case 1403: /* fcmge */
value = 1403; /* --> fcmge. */
break;
case 2053: /* fcmlt */
case 1405: /* fcmgt */
value = 1405; /* --> fcmgt. */
break;
case 1266: /* fmov */
case 1411: /* fcpy */
value = 1411; /* --> fcpy. */
break;
case 1265: /* fmov */
case 1434: /* fdup */
value = 1434; /* --> fdup. */
break;
case 1267: /* mov */
case 1765: /* orr */
value = 1765; /* --> orr. */
break;
case 2056: /* orn */
case 1766: /* orr */
value = 1766; /* --> orr. */
break;
case 1270: /* mov */
case 1768: /* orr */
value = 1768; /* --> orr. */
break;
case 1280: /* movs */
case 1769: /* orrs */
value = 1769; /* --> orrs. */
break;
case 1275: /* mov */
case 1831: /* sel */
value = 1831; /* --> sel. */
case 2051: /* cmpls */
case 1344: /* cmphs */
value = 1344; /* --> cmphs. */
break;
case 1278: /* mov */
case 1832: /* sel */
value = 1832; /* --> sel. */
case 1366: /* cpy */
value = 1366; /* --> cpy. */
break;
case 1280: /* mov */
case 1367: /* cpy */
value = 1367; /* --> cpy. */
break;
case 2059: /* fmov */
case 1283: /* mov */
case 1368: /* cpy */
value = 1368; /* --> cpy. */
break;
case 1273: /* mov */
case 1380: /* dup */
value = 1380; /* --> dup. */
break;
case 1275: /* mov */
case 1272: /* mov */
case 1381: /* dup */
value = 1381; /* --> dup. */
break;
case 2058: /* fmov */
case 1277: /* mov */
case 1382: /* dup */
value = 1382; /* --> dup. */
break;
case 1276: /* mov */
case 1383: /* dupm */
value = 1383; /* --> dupm. */
break;
case 2053: /* eon */
case 1385: /* eor */
value = 1385; /* --> eor. */
break;
case 1286: /* not */
case 1387: /* eor */
value = 1387; /* --> eor. */
break;
case 1287: /* nots */
case 1388: /* eors */
value = 1388; /* --> eors. */
break;
case 2054: /* facle */
case 1393: /* facge */
value = 1393; /* --> facge. */
break;
case 2055: /* faclt */
case 1394: /* facgt */
value = 1394; /* --> facgt. */
break;
case 2056: /* fcmle */
case 1407: /* fcmge */
value = 1407; /* --> fcmge. */
break;
case 2057: /* fcmlt */
case 1409: /* fcmgt */
value = 1409; /* --> fcmgt. */
break;
case 1270: /* fmov */
case 1415: /* fcpy */
value = 1415; /* --> fcpy. */
break;
case 1269: /* fmov */
case 1438: /* fdup */
value = 1438; /* --> fdup. */
break;
case 1271: /* mov */
case 1769: /* orr */
value = 1769; /* --> orr. */
break;
case 2060: /* orn */
case 1770: /* orr */
value = 1770; /* --> orr. */
break;
case 1274: /* mov */
case 1772: /* orr */
value = 1772; /* --> orr. */
break;
case 1284: /* movs */
case 1773: /* orrs */
value = 1773; /* --> orrs. */
break;
case 1279: /* mov */
case 1835: /* sel */
value = 1835; /* --> sel. */
break;
case 1282: /* mov */
case 1836: /* sel */
value = 1836; /* --> sel. */
break;
default: return NULL;
}
@ -675,7 +675,7 @@ aarch64_insert_operand (const aarch64_operand *self,
case 33:
case 34:
case 35:
case 220:
case 221:
return aarch64_ins_reglane (self, info, code, inst, errors);
case 36:
return aarch64_ins_reglist (self, info, code, inst, errors);
@ -721,7 +721,7 @@ aarch64_insert_operand (const aarch64_operand *self,
case 189:
case 190:
case 215:
case 219:
case 220:
return aarch64_ins_imm (self, info, code, inst, errors);
case 44:
case 45:
@ -889,6 +889,8 @@ aarch64_insert_operand (const aarch64_operand *self,
return aarch64_ins_sme_za_array (self, info, code, inst, errors);
case 218:
return aarch64_ins_sme_addr_ri_u4xvl (self, info, code, inst, errors);
case 219:
return aarch64_ins_sme_sm_za (self, info, code, inst, errors);
default: assert (0); abort ();
}
}

View File

@ -848,6 +848,10 @@ aarch64_ins_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
/* op1:op2 */
insert_fields (code, info->pstatefield, inst->opcode->mask, 2,
FLD_op2, FLD_op1);
/* Extra CRm mask. */
if (info->sysreg.flags | F_REG_IN_CRM)
insert_field (FLD_CRm, code, PSTATE_DECODE_CRM (info->sysreg.flags), 0);
return true;
}
@ -1427,6 +1431,27 @@ aarch64_ins_sme_addr_ri_u4xvl (const aarch64_operand *self,
return true;
}
/* Encode in SMSTART and SMSTOP {SM | ZA } mode. */
bool
aarch64_ins_sme_sm_za (const aarch64_operand *self,
const aarch64_opnd_info *info,
aarch64_insn *code,
const aarch64_inst *inst ATTRIBUTE_UNUSED,
aarch64_operand_error *errors ATTRIBUTE_UNUSED)
{
aarch64_insn fld_crm;
/* Set CRm[3:1] bits. */
if (info->reg.regno == 's')
fld_crm = 0x02 ; /* SVCRSM. */
else if (info->reg.regno == 'z')
fld_crm = 0x04; /* SVCRZA. */
else
assert (0);
insert_field (self->fields[0], code, fld_crm, 0);
return true;
}
/* Miscellaneous encoding functions. */
/* Encode size[0], i.e. bit 22, for

View File

@ -102,6 +102,7 @@ AARCH64_DECL_OPD_INSERTER (ins_sme_za_hv_tiles);
AARCH64_DECL_OPD_INSERTER (ins_sme_za_list);
AARCH64_DECL_OPD_INSERTER (ins_sme_za_array);
AARCH64_DECL_OPD_INSERTER (ins_sme_addr_ri_u4xvl);
AARCH64_DECL_OPD_INSERTER (ins_sme_sm_za);
AARCH64_DECL_OPD_INSERTER (ins_imm_rotate1);
AARCH64_DECL_OPD_INSERTER (ins_imm_rotate2);

File diff suppressed because it is too large Load Diff

View File

@ -664,7 +664,7 @@ aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED,
bool
aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
const aarch64_insn code,
const aarch64_inst *inst ATTRIBUTE_UNUSED,
const aarch64_inst *inst,
aarch64_operand_error *errors ATTRIBUTE_UNUSED)
{
uint64_t imm;
@ -682,6 +682,10 @@ aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
if (info->type == AARCH64_OPND_ADDR_ADRP)
imm <<= 12;
if (inst->operands[0].type == AARCH64_OPND_PSTATEFIELD
&& inst->operands[0].sysreg.flags & F_IMM_IN_CRM)
imm &= PSTATE_DECODE_CRM_IMM (inst->operands[0].sysreg.flags);
info->imm.value = imm;
return true;
}
@ -1226,11 +1230,20 @@ aarch64_ext_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
aarch64_operand_error *errors ATTRIBUTE_UNUSED)
{
int i;
aarch64_insn fld_crm = extract_field (FLD_CRm, code, 0);
/* op1:op2 */
info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2);
for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield)
return true;
{
/* PSTATEFIELD name can be encoded partially in CRm[3:1]. */
uint32_t flags = aarch64_pstatefields[i].flags;
if ((flags & F_REG_IN_CRM)
&& ((fld_crm & 0xe) != PSTATE_DECODE_CRM (flags)))
continue;
info->sysreg.flags = flags;
return true;
}
/* Reserved value in <pstatefield>. */
return false;
}
@ -1856,6 +1869,27 @@ aarch64_ext_sme_addr_ri_u4xvl (const aarch64_operand *self,
return true;
}
/* Decode {SM|ZA} filed for SMSTART and SMSTOP instructions. */
bool
aarch64_ext_sme_sm_za (const aarch64_operand *self,
aarch64_opnd_info *info, aarch64_insn code,
const aarch64_inst *inst ATTRIBUTE_UNUSED,
aarch64_operand_error *errors ATTRIBUTE_UNUSED)
{
info->pstatefield = 0x1b;
aarch64_insn fld_crm = extract_field (self->fields[0], code, 0);
fld_crm >>= 1; /* CRm[3:1]. */
if (fld_crm == 0x1)
info->reg.regno = 's';
else if (fld_crm == 0x2)
info->reg.regno = 'z';
else
assert (0);
return true;
}
/* Decode Zn[MM], where MM has a 7-bit triangular encoding. The fields
array specifies which field to use for Zn. MM is encoded in the
concatenation of imm5 and SVE_tszh, with imm5 being the less

View File

@ -126,6 +126,7 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_sme_za_hv_tiles);
AARCH64_DECL_OPD_EXTRACTOR (ext_sme_za_list);
AARCH64_DECL_OPD_EXTRACTOR (ext_sme_za_array);
AARCH64_DECL_OPD_EXTRACTOR (ext_sme_addr_ri_u4xvl);
AARCH64_DECL_OPD_EXTRACTOR (ext_sme_sm_za);
AARCH64_DECL_OPD_EXTRACTOR (ext_imm_rotate1);
AARCH64_DECL_OPD_EXTRACTOR (ext_imm_rotate2);

View File

@ -243,6 +243,7 @@ const struct aarch64_operand aarch64_operands[] =
{AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_HV_idx_ldstr", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_index2,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2}, "an SME horizontal or vertical vector access register"},
{AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_array", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_Rv,FLD_imm4_2}, "ZA array"},
{AARCH64_OPND_CLASS_ADDRESS, "SME_ADDR_RI_U4xVL", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn,FLD_imm4_2}, "memory offset"},
{AARCH64_OPND_CLASS_ADDRESS, "SME_SM_ZA", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_CRm}, "streaming mode"},
{AARCH64_OPND_CLASS_IMMEDIATE, "TME_UIMM16", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_imm16}, "a 16-bit unsigned immediate for TME tcancel"},
{AARCH64_OPND_CLASS_SIMD_ELEMENT, "SM3_IMM2", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SM3_imm2}, "an indexed SM3 vector immediate"},
{AARCH64_OPND_CLASS_NIL, "", 0, {0}, "DUMMY"},
@ -322,17 +323,17 @@ static const unsigned op_enum_table [] =
391,
413,
415,
1270,
1275,
1268,
1267,
1274,
1279,
1272,
1271,
1278,
1280,
1281,
1277,
1283,
1275,
1282,
1284,
1285,
1281,
1287,
1286,
131,
};

View File

@ -1520,7 +1520,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
if (!aarch64_stack_pointer_p (opnd))
{
set_other_error (mismatch_detail, idx,
_("stack pointer register expected"));
_("stack pointer register expected"));
return 0;
}
break;
@ -2592,11 +2592,15 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
/* MSR UAO, #uimm4
MSR PAN, #uimm4
MSR SSBS,#uimm4
MSR SVCRSM, #uimm4
MSR SVCRZA, #uimm4
MSR SVCRSMZA, #uimm4
The immediate must be #0 or #1. */
if ((opnd->pstatefield == 0x03 /* UAO. */
|| opnd->pstatefield == 0x04 /* PAN. */
|| opnd->pstatefield == 0x19 /* SSBS. */
|| opnd->pstatefield == 0x1a) /* DIT. */
|| opnd->pstatefield == 0x1a /* DIT. */
|| opnd->pstatefield == 0x1b) /* SVCRSM, SVCRZA or SVCRSMZA. */
&& opnds[1].imm.value > 1)
{
set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
@ -3465,6 +3469,10 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
opnd->za_tile_vector.index.imm);
break;
case AARCH64_OPND_SME_SM_ZA:
snprintf (buf, size, "%s", opnd->reg.regno == 's' ? "sm" : "za");
break;
case AARCH64_OPND_CRn:
case AARCH64_OPND_CRm:
snprintf (buf, size, "C%" PRIi64, opnd->imm.value);
@ -3861,8 +3869,17 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_PSTATEFIELD:
for (i = 0; aarch64_pstatefields[i].name; ++i)
if (aarch64_pstatefields[i].value == opnd->pstatefield)
break;
if (aarch64_pstatefields[i].value == opnd->pstatefield)
{
/* PSTATEFIELD name is encoded partially in CRm[3:1] for SVCRSM,
SVCRZA and SVCRSMZA. */
uint32_t flags = aarch64_pstatefields[i].flags;
if (flags & F_REG_IN_CRM
&& (PSTATE_DECODE_CRM (opnd->sysreg.flags)
!= PSTATE_DECODE_CRM (flags)))
continue;
break;
}
assert (aarch64_pstatefields[i].name);
snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
break;
@ -3958,6 +3975,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
#define SR_V8_4(n,e,f) SR_FEAT (n,e,f,V8_4)
#define SR_PAN(n,e,f) SR_FEAT (n,e,f,PAN)
#define SR_RAS(n,e,f) SR_FEAT (n,e,f,RAS)
#define SR_SME(n,e,f) SR_FEAT (n,e,f,SME)
#define SR_SSBS(n,e,f) SR_FEAT (n,e,f,SSBS)
#define SR_SVE(n,e,f) SR_FEAT (n,e,f,SVE)
#define SR_ID_PFR2(n,e,f) SR_FEAT (n,e,f,ID_PFR2)
@ -4808,6 +4826,8 @@ const aarch64_sys_reg aarch64_sys_regs [] =
SR_CORE ("gpccr_el3", CPENC (3,6,C2,C1,6), 0),
SR_CORE ("gptbr_el3", CPENC (3,6,C2,C1,4), 0),
SR_SME ("svcr", CPENC (3,3,C4,C2,2), 0),
{ 0, CPENC (0,0,0,0,0), 0, 0 }
};
@ -4834,6 +4854,9 @@ const aarch64_sys_reg aarch64_pstatefields [] =
SR_SSBS ("ssbs", 0x19, 0),
SR_V8_4 ("dit", 0x1a, 0),
SR_MEMTAG ("tco", 0x1c, 0),
SR_SME ("svcrsm", 0x1b, PSTATE_ENCODE_CRM_AND_IMM(0x2,0x1)),
SR_SME ("svcrza", 0x1b, PSTATE_ENCODE_CRM_AND_IMM(0x4,0x1)),
SR_SME ("svcrsmza", 0x1b, PSTATE_ENCODE_CRM_AND_IMM(0x6,0x1)),
{ 0, CPENC (0,0,0,0,0), 0, 0 },
};

View File

@ -243,6 +243,32 @@ verify_constraints (const struct aarch64_inst *, const aarch64_insn, bfd_vma,
#define F_REG_WRITE (1 << 4) /* Register can only be written to but not
read from. */
#undef F_REG_IN_CRM
#define F_REG_IN_CRM (1 << 5) /* Register extra encoding in CRm. */
/* PSTATE field name for the MSR instruction this is encoded in "op1:op2:CRm".
Part of CRm can be used to encode <pstatefield>. E.g. CRm[3:1] for SME.
In order to set/get full PSTATE field name use flag F_REG_IN_CRM and below
macros to encode and decode CRm encoding.
*/
#define PSTATE_ENCODE_CRM(val) (val << 6)
#define PSTATE_DECODE_CRM(flags) ((flags >> 6) & 0x0f)
#undef F_IMM_IN_CRM
#define F_IMM_IN_CRM (1 << 10) /* Immediate extra encoding in CRm. */
/* Also CRm may contain, in addition to <pstatefield> immediate.
E.g. CRm[0] <imm1> at bit 0 for SME. Use below macros to encode and decode
immediate mask.
*/
#define PSTATE_ENCODE_CRM_IMM(mask) (mask << 11)
#define PSTATE_DECODE_CRM_IMM(mask) ((mask >> 11) & 0x0f)
/* Helper macro to ENCODE CRm and its immediate. */
#define PSTATE_ENCODE_CRM_AND_IMM(CVAL,IMASK) \
(F_REG_IN_CRM | PSTATE_ENCODE_CRM(CVAL) \
| F_IMM_IN_CRM | PSTATE_ENCODE_CRM_IMM(IMASK))
/* HINT operand flags. */
#define HINT_OPD_F_NOPRINT (1 << 0) /* Should not be printed. */

View File

@ -3933,6 +3933,11 @@ const struct aarch64_opcode aarch64_opcode_table[] =
_TME_INSN ("tcommit", 0xd503307f, 0xffffffff, 0, 0, OP0 (), {}, 0),
_TME_INSN ("ttest", 0xd5233160, 0xffffffe0, 0, 0, OP1 (Rd), QL_I1X, 0),
_TME_INSN ("tcancel", 0xd4600000, 0xffe0001f, 0, 0, OP1 (TME_UIMM16), QL_IMM_NIL, 0),
/* SME instructions (aliases for MSR <sysreg> operations. */
SME_INSN ("smstart", 0xd503477f, 0xffffffff, sme_start, 0, OP0 (), {}, F_SYS_WRITE, 0),
SME_INSN ("smstop", 0xd503467f, 0xffffffff, sme_stop, 0, OP0 (), {}, F_SYS_WRITE, 0),
SME_INSN ("smstart", 0xd503417f, 0xfffff1ff, sme_start, 0, OP1 (SME_SM_ZA), {}, F_SYS_WRITE, 0),
SME_INSN ("smstop", 0xd503407f, 0xfffff1ff, sme_stop, 0, OP1 (SME_SM_ZA), {}, F_SYS_WRITE, 0),
/* System. */
CORE_INSN ("msr", 0xd500401f, 0xfff8f01f, ic_system, 0, OP2 (PSTATEFIELD, UIMM4), {}, F_SYS_WRITE),
CORE_INSN ("hint",0xd503201f, 0xfffff01f, ic_system, 0, OP1 (UIMM7), {}, F_HAS_ALIAS),
@ -5765,6 +5770,9 @@ const struct aarch64_opcode aarch64_opcode_table[] =
Y(ADDRESS, sme_addr_ri_u4xvl, "SME_ADDR_RI_U4xVL", 0 << OPD_F_OD_LSB, \
F(FLD_Rn,FLD_imm4_2), \
"memory offset") \
Y(ADDRESS, sme_sm_za, "SME_SM_ZA", 0, \
F(FLD_CRm), \
"streaming mode") \
Y(IMMEDIATE, imm, "TME_UIMM16", 0, F(FLD_imm16), \
"a 16-bit unsigned immediate for TME tcancel") \
Y(SIMD_ELEMENT, reglane, "SM3_IMM2", 0, F(FLD_SM3_imm2), \