45 #include "arch/arm/generated/decoder.hh"
52 using namespace ArmISAInst;
58 OpClass __opClass, IntRegIndex
rn,
60 bool load, uint32_t reglist) :
63 uint32_t regs = reglist;
65 uint32_t mem_ops = ones;
69 bool copy_base = (
bits(reglist,
rn) && load) || !ones;
70 bool force_user = user & !
bits(reglist, 15);
71 bool exception_ret = user &
bits(reglist, 15);
78 + ((ones % 2 == 0 && exception_ret) ? 1 : 0)
91 addr = (ones << 2) - 4;
104 while (mem_ops != 0) {
106 if (load && mem_ops >= 2 &&
107 !(mem_ops == 2 &&
bits(regs,INTREG_PC) && exception_ret)) {
124 if (reg_idx2 == INTREG_PC && pc_temp)
125 reg_idx2 = INTREG_UREG1;
128 *uop =
new MicroLdr2Uop(
machInst, reg_idx1, reg_idx2,
131 if (!
writeback && reg_idx2 == INTREG_PC) {
133 (*uop)->setFlag(StaticInst::IsControl);
134 (*uop)->setFlag(StaticInst::IsIndirectControl);
137 (*uop)->setFlag(StaticInst::IsCondControl);
139 (*uop)->setFlag(StaticInst::IsUncondControl);
158 *uop =
new MicroLdrUop(
machInst, INTREG_UREG1,
160 }
else if (reg_idx == INTREG_PC && exception_ret) {
162 *uop =
new MicroLdrRetUop(
machInst, reg_idx,
166 *uop =
new MicroLdrUop(
machInst, reg_idx,
171 if (!
writeback && reg_idx == INTREG_PC) {
172 (*uop)->setFlag(StaticInst::IsControl);
173 (*uop)->setFlag(StaticInst::IsIndirectControl);
176 (*uop)->setFlag(StaticInst::IsCondControl);
178 (*uop)->setFlag(StaticInst::IsUncondControl);
203 *uop =
new MicroUopRegMovRet(
machInst, 0, INTREG_UREG1);
205 *uop =
new MicroUopRegMov(
machInst, INTREG_PC, INTREG_UREG1);
207 (*uop)->setFlag(StaticInst::IsControl);
208 (*uop)->setFlag(StaticInst::IsIndirectControl);
211 (*uop)->setFlag(StaticInst::IsCondControl);
213 (*uop)->setFlag(StaticInst::IsUncondControl);
216 (*uop)->setFlag(StaticInst::IsReturn);
227 if ((*uop)->isControl())
228 setFlag(StaticInst::IsControl);
229 if ((*uop)->isCondCtrl())
230 setFlag(StaticInst::IsCondControl);
231 if ((*uop)->isUncondCtrl())
232 setFlag(StaticInst::IsUncondControl);
233 if ((*uop)->isIndirectCtrl())
234 setFlag(StaticInst::IsIndirectControl);
235 if ((*uop)->isReturn())
239 (*uop)->setDelayedCommit();
244 uint32_t size,
bool fp,
bool load,
bool noAlloc,
245 bool signExt,
bool exclusive,
bool acrel,
247 IntRegIndex
rn, IntRegIndex
rt, IntRegIndex rt2) :
275 *uop++ =
new MicroLdFp16Uop(
machInst, rt2,
278 *uop++ =
new MicroStrQBFpXImmUop(
machInst,
rt,
280 *uop++ =
new MicroStrQTFpXImmUop(
machInst,
rt,
282 *uop++ =
new MicroStrQBFpXImmUop(
machInst, rt2,
284 *uop++ =
new MicroStrQTFpXImmUop(
machInst, rt2,
287 }
else if (size == 8) {
289 *uop++ =
new MicroLdPairFp8Uop(
machInst,
rt, rt2,
294 *uop++ =
new MicroStrFpXImmUop(
machInst, rt2,
297 }
else if (size == 4) {
299 *uop++ =
new MicroLdrDFpXImmUop(
machInst,
rt, rt2,
302 *uop++ =
new MicroStrDFpXImmUop(
machInst,
rt, rt2,
309 *uop++ =
new MicroLdPairUop(
machInst,
rt, rt2,
313 0, noAlloc, exclusive, acrel);
315 size, noAlloc, exclusive, acrel);
317 }
else if (size == 4) {
320 *uop++ =
new MicroLdrDSXImmUop(
machInst,
rt, rt2,
323 *uop++ =
new MicroLdrDUXImmUop(
machInst,
rt, rt2,
327 *uop++ =
new MicroStrDXImmUop(
machInst,
rt, rt2,
344 (*curUop)->setDelayedCommit();
349 OpClass __opClass,
bool load, IntRegIndex dest,
350 IntRegIndex
base, int64_t
imm) :
362 (*uop)->setDelayedCommit();
365 (*uop)->setLastMicroop();
370 OpClass __opClass,
bool load, IntRegIndex dest,
371 IntRegIndex
base, int64_t
imm) :
382 *uop++=
new MicroStrQBFpXImmUop(
machInst, dest,
base, 0);
383 *uop++ =
new MicroStrQTFpXImmUop(
machInst, dest,
base, 0);
386 (*uop)->setLastMicroop();
391 (*curUop)->setDelayedCommit();
396 OpClass __opClass,
bool load, IntRegIndex dest,
397 IntRegIndex
base, int64_t
imm) :
412 (*uop)->setLastMicroop();
417 (*curUop)->setDelayedCommit();
422 OpClass __opClass,
bool load, IntRegIndex dest,
438 (*uop)->setDelayedCommit();
443 (*uop)->setLastMicroop();
448 OpClass __opClass, IntRegIndex dest,
465 assert(regs > 0 && regs <= 4);
466 assert(regs % elems == 0);
469 bool wb = (
rm != 15);
470 bool deinterleave = (elems > 1);
478 uint32_t noAlign = 0;
483 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
485 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
489 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
491 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
495 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
499 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
507 if (
rm != 15 &&
rm != 13) {
519 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>(
524 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>(
528 assert(regs == 4 || regs == 2);
530 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
532 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
535 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
556 OpClass __opClass,
bool all,
unsigned elems,
558 unsigned inc, uint32_t size, uint32_t
align,
562 assert(regs > 0 && regs <= 4);
563 assert(regs % elems == 0);
565 unsigned eBytes = (1 << size);
566 unsigned loadSize = eBytes * elems;
567 [[maybe_unused]]
unsigned loadRegs =
568 (loadSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
570 assert(loadRegs > 0 && loadRegs <= 4);
573 bool wb = (
rm != 15);
584 microOps[uopIdx++] =
new MicroLdrNeon1Uop<uint8_t>(
589 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint16_t>(
592 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint8_t>(
597 microOps[uopIdx++] =
new MicroLdrNeon3Uop<uint8_t>(
603 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint8_t>(
607 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint16_t>(
611 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint32_t>(
617 microOps[uopIdx++] =
new MicroLdrNeon6Uop<uint16_t>(
623 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint16_t>(
627 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint32_t>(
633 microOps[uopIdx++] =
new MicroLdrNeon12Uop<uint32_t>(
637 microOps[uopIdx++] =
new MicroLdrNeon16Uop<uint32_t>(
645 if (
rm != 15 &&
rm != 13) {
659 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint8_t>(
662 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint8_t>(
668 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint16_t>(
671 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint16_t>(
677 microOps[uopIdx++] =
new MicroUnpackAllNeon4to8Uop<uint32_t>(
680 microOps[uopIdx++] =
new MicroUnpackNeon4to8Uop<uint32_t>(
695 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint8_t>(
698 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint8_t>(
704 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint16_t>(
707 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint16_t>(
713 microOps[uopIdx++] =
new MicroUnpackAllNeon4to6Uop<uint32_t>(
716 microOps[uopIdx++] =
new MicroUnpackNeon4to6Uop<uint32_t>(
728 assert(loadRegs <= 2);
732 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint8_t>(
735 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint8_t>(
741 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint16_t>(
744 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint16_t>(
750 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint32_t>(
753 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint32_t>(
764 assert(regs == 1 || (all && regs == 2));
765 assert(loadRegs <= 2);
771 new MicroUnpackAllNeon2to2Uop<uint8_t>(
775 new MicroUnpackNeon2to2Uop<uint8_t>(
782 new MicroUnpackAllNeon2to2Uop<uint16_t>(
786 new MicroUnpackNeon2to2Uop<uint16_t>(
793 new MicroUnpackAllNeon2to2Uop<uint32_t>(
797 new MicroUnpackNeon2to2Uop<uint32_t>(
828 assert(regs > 0 && regs <= 4);
829 assert(regs % elems == 0);
832 bool wb = (
rm != 15);
833 bool interleave = (elems > 1);
839 uint32_t noAlign = 0;
848 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>(
853 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>(
857 assert(regs == 4 || regs == 2);
859 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
861 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
864 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
875 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
877 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
881 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
883 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
887 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
891 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
899 if (
rm != 15 &&
rm != 13) {
919 OpClass __opClass,
bool all,
unsigned elems,
921 unsigned inc, uint32_t size, uint32_t
align,
926 assert(regs > 0 && regs <= 4);
927 assert(regs % elems == 0);
929 unsigned eBytes = (1 << size);
930 unsigned storeSize = eBytes * elems;
931 [[maybe_unused]]
unsigned storeRegs =
932 (storeSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
934 assert(storeRegs > 0 && storeRegs <= 4);
937 bool wb = (
rm != 15);
951 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint8_t>(
955 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint16_t>(
959 microOps[uopIdx++] =
new MicroPackNeon8to4Uop<uint32_t>(
972 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint8_t>(
976 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint16_t>(
980 microOps[uopIdx++] =
new MicroPackNeon6to4Uop<uint32_t>(
991 assert(storeRegs <= 2);
994 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint8_t>(
998 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint16_t>(
1002 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint32_t>(
1012 assert(regs == 1 || (all && regs == 2));
1013 assert(storeRegs <= 2);
1017 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint8_t>(
1021 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint16_t>(
1025 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint32_t>(
1039 switch (storeSize) {
1041 microOps[uopIdx++] =
new MicroStrNeon1Uop<uint8_t>(
1046 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint16_t>(
1049 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint8_t>(
1054 microOps[uopIdx++] =
new MicroStrNeon3Uop<uint8_t>(
1060 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint8_t>(
1064 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint16_t>(
1068 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint32_t>(
1074 microOps[uopIdx++] =
new MicroStrNeon6Uop<uint16_t>(
1080 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint16_t>(
1084 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint32_t>(
1090 microOps[uopIdx++] =
new MicroStrNeon12Uop<uint32_t>(
1094 microOps[uopIdx++] =
new MicroStrNeon16Uop<uint32_t>(
1102 if (
rm != 15 &&
rm != 13) {
1123 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1124 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
1129 bool baseIsSP =
isSP((IntRegIndex) rnsp);
1134 assert(totNumBytes <= 64);
1138 int numMemMicroops = totNumBytes / 16;
1139 int residuum = totNumBytes % 16;
1148 unsigned uopIdx = 0;
1152 for (;
i < numMemMicroops - 1; ++
i) {
1153 microOps[uopIdx++] =
new MicroNeonLoad64(
1155 baseIsSP, 16 ,
eSize);
1157 microOps[uopIdx++] =
new MicroNeonLoad64(
1159 residuum ? residuum : 16 ,
eSize);
1174 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1176 case 1:
microOps[uopIdx++] =
new MicroDeintNeon64_1Reg(
1180 case 2:
microOps[uopIdx++] =
new MicroDeintNeon64_2Reg(
1184 case 3:
microOps[uopIdx++] =
new MicroDeintNeon64_3Reg(
1188 case 4:
microOps[uopIdx++] =
new MicroDeintNeon64_4Reg(
1192 default:
panic(
"Invalid number of registers");
1208 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1209 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
1214 bool baseIsSP =
isSP((IntRegIndex) rnsp);
1219 assert(totNumBytes <= 64);
1223 int numMemMicroops = totNumBytes / 16;
1224 int residuum = totNumBytes % 16;
1229 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1233 unsigned uopIdx = 0;
1235 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1237 case 1:
microOps[uopIdx++] =
new MicroIntNeon64_1Reg(
1241 case 2:
microOps[uopIdx++] =
new MicroIntNeon64_2Reg(
1245 case 3:
microOps[uopIdx++] =
new MicroIntNeon64_3Reg(
1249 case 4:
microOps[uopIdx++] =
new MicroIntNeon64_4Reg(
1253 default:
panic(
"Invalid number of registers");
1260 for (;
i < numMemMicroops - 1; ++
i) {
1261 microOps[uopIdx++] =
new MicroNeonStore64(
1263 baseIsSP, 16 ,
eSize);
1265 microOps[uopIdx++] =
new MicroNeonStore64(
1267 residuum ? residuum : 16 ,
eSize);
1293 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1294 uint8_t numStructElems, uint8_t
index,
bool wb,
1297 eSize(0), dataSize(0), numStructElems(0),
index(0),
1298 wb(false), replicate(false)
1303 bool baseIsSP =
isSP((IntRegIndex) rnsp);
1307 int eSizeBytes = 1 <<
eSize;
1309 assert(totNumBytes <= 64);
1313 int numMemMicroops = totNumBytes / 16;
1314 int residuum = totNumBytes % 16;
1323 unsigned uopIdx = 0;
1328 for (;
i < numMemMicroops - 1; ++
i) {
1329 microOps[uopIdx++] =
new MicroNeonLoad64(
1331 baseIsSP, 16 ,
eSize);
1333 microOps[uopIdx++] =
new MicroNeonLoad64(
1335 residuum ? residuum : 16 ,
eSize);
1350 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1351 microOps[uopIdx++] =
new MicroUnpackNeon64(
1367 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1368 uint8_t numStructElems, uint8_t
index,
bool wb,
1371 eSize(0), dataSize(0), numStructElems(0),
index(0),
1372 wb(false), replicate(false)
1376 bool baseIsSP =
isSP((IntRegIndex) rnsp);
1380 int eSizeBytes = 1 <<
eSize;
1382 assert(totNumBytes <= 64);
1386 int numMemMicroops = totNumBytes / 16;
1387 int residuum = totNumBytes % 16;
1392 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1396 unsigned uopIdx = 0;
1398 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1399 microOps[uopIdx++] =
new MicroPackNeon64(
1407 for (;
i < numMemMicroops - 1; ++
i) {
1408 microOps[uopIdx++] =
new MicroNeonStore64(
1410 baseIsSP, 16 ,
eSize);
1412 microOps[uopIdx++] =
new MicroNeonStore64(
1414 residuum ? residuum : 16 ,
eSize);
1439 OpClass __opClass, IntRegIndex
rn,
1482 addr -= (single ? 4 : 8);
1490 addr += (single ? 4 : 8);
1520 std::stringstream
ss;
1534 std::stringstream
ss;
1548 std::stringstream
ss;
1558 std::stringstream
ss;
1571 std::stringstream
ss;
1583 std::stringstream
ss;
1597 std::stringstream
ss;
1615 std::stringstream
ss;