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:
parent
01a4d08220
commit
3dd032c5fb
@ -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 =
|
||||
|
3
gas/testsuite/gas/aarch64/sme-8-illegal.d
Normal file
3
gas/testsuite/gas/aarch64/sme-8-illegal.d
Normal file
@ -0,0 +1,3 @@
|
||||
#as: -march=armv8-a+sme
|
||||
#source: sme-8-illegal.s
|
||||
#error_output: sme-8-illegal.l
|
7
gas/testsuite/gas/aarch64/sme-8-illegal.l
Normal file
7
gas/testsuite/gas/aarch64/sme-8-illegal.l
Normal 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'
|
9
gas/testsuite/gas/aarch64/sme-8-illegal.s
Normal file
9
gas/testsuite/gas/aarch64/sme-8-illegal.s
Normal file
@ -0,0 +1,9 @@
|
||||
/* Scalable Matrix Extension (SME). */
|
||||
|
||||
smstart x0
|
||||
smstart sa
|
||||
smstart zm
|
||||
|
||||
smstop x0
|
||||
smstop sa
|
||||
smstop zm
|
27
gas/testsuite/gas/aarch64/sme-8.d
Normal file
27
gas/testsuite/gas/aarch64/sme-8.d
Normal 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
|
28
gas/testsuite/gas/aarch64/sme-8.s
Normal file
28
gas/testsuite/gas/aarch64/sme-8.s
Normal 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
|
@ -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,
|
||||
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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 },
|
||||
};
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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), \
|
||||
|
Loading…
x
Reference in New Issue
Block a user