45 #include "arch/arm/generated/decoder.hh"
53 MacroMemOp::MacroMemOp(
const char *mnem,
ExtMachInst machInst,
56 bool load, uint32_t reglist) :
59 uint32_t regs = reglist;
61 uint32_t mem_ops = ones;
65 bool copy_base = (
bits(reglist,
rn) && load) || !ones;
66 bool force_user = user & !
bits(reglist, 15);
67 bool exception_ret = user &
bits(reglist, 15);
74 + ((ones % 2 == 0 && exception_ret) ? 1 : 0)
87 addr = (ones << 2) - 4;
100 while (mem_ops != 0) {
102 if (load && mem_ops >= 2 &&
124 *uop =
new MicroLdr2Uop(
machInst, reg_idx1, reg_idx2,
129 (*uop)->setFlag(StaticInst::IsControl);
130 (*uop)->setFlag(StaticInst::IsIndirectControl);
133 (*uop)->setFlag(StaticInst::IsCondControl);
135 (*uop)->setFlag(StaticInst::IsUncondControl);
156 }
else if (reg_idx ==
INTREG_PC && exception_ret) {
158 *uop =
new MicroLdrRetUop(
machInst, reg_idx,
162 *uop =
new MicroLdrUop(
machInst, reg_idx,
168 (*uop)->setFlag(StaticInst::IsControl);
169 (*uop)->setFlag(StaticInst::IsIndirectControl);
172 (*uop)->setFlag(StaticInst::IsCondControl);
174 (*uop)->setFlag(StaticInst::IsUncondControl);
203 (*uop)->setFlag(StaticInst::IsControl);
204 (*uop)->setFlag(StaticInst::IsIndirectControl);
207 (*uop)->setFlag(StaticInst::IsCondControl);
209 (*uop)->setFlag(StaticInst::IsUncondControl);
212 (*uop)->setFlag(StaticInst::IsReturn);
223 if ((*uop)->isControl())
224 setFlag(StaticInst::IsControl);
225 if ((*uop)->isCondCtrl())
226 setFlag(StaticInst::IsCondControl);
227 if ((*uop)->isUncondCtrl())
228 setFlag(StaticInst::IsUncondControl);
229 if ((*uop)->isIndirectCtrl())
230 setFlag(StaticInst::IsIndirectControl);
231 if ((*uop)->isReturn())
235 (*uop)->setDelayedCommit();
240 uint32_t size,
bool fp,
bool load,
bool noAlloc,
241 bool signExt,
bool exclusive,
bool acrel,
271 *uop++ =
new MicroLdFp16Uop(
machInst, rt2,
274 *uop++ =
new MicroStrQBFpXImmUop(
machInst,
rt,
276 *uop++ =
new MicroStrQTFpXImmUop(
machInst,
rt,
278 *uop++ =
new MicroStrQBFpXImmUop(
machInst, rt2,
280 *uop++ =
new MicroStrQTFpXImmUop(
machInst, rt2,
283 }
else if (size == 8) {
285 *uop++ =
new MicroLdPairFp8Uop(
machInst,
rt, rt2,
290 *uop++ =
new MicroStrFpXImmUop(
machInst, rt2,
293 }
else if (size == 4) {
295 *uop++ =
new MicroLdrDFpXImmUop(
machInst,
rt, rt2,
298 *uop++ =
new MicroStrDFpXImmUop(
machInst,
rt, rt2,
305 *uop++ =
new MicroLdPairUop(
machInst,
rt, rt2,
309 0, noAlloc, exclusive, acrel);
311 size, noAlloc, exclusive, acrel);
313 }
else if (size == 4) {
316 *uop++ =
new MicroLdrDSXImmUop(
machInst,
rt, rt2,
319 *uop++ =
new MicroLdrDUXImmUop(
machInst,
rt, rt2,
323 *uop++ =
new MicroStrDXImmUop(
machInst,
rt, rt2,
340 (*curUop)->setDelayedCommit();
358 (*uop)->setDelayedCommit();
361 (*uop)->setLastMicroop();
378 *uop++=
new MicroStrQBFpXImmUop(
machInst, dest,
base, 0);
379 *uop++ =
new MicroStrQTFpXImmUop(
machInst, dest,
base, 0);
382 (*uop)->setLastMicroop();
387 (*curUop)->setDelayedCommit();
408 (*uop)->setLastMicroop();
413 (*curUop)->setDelayedCommit();
434 (*uop)->setDelayedCommit();
439 (*uop)->setLastMicroop();
461 assert(regs > 0 && regs <= 4);
462 assert(regs % elems == 0);
465 bool wb = (
rm != 15);
466 bool deinterleave = (elems > 1);
474 uint32_t noAlign = 0;
479 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
481 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
485 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
487 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
491 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
495 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
503 if (
rm != 15 &&
rm != 13) {
515 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>(
520 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>(
524 assert(regs == 4 || regs == 2);
526 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
528 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
531 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
552 OpClass __opClass,
bool all,
unsigned elems,
554 unsigned inc, uint32_t size, uint32_t
align,
558 assert(regs > 0 && regs <= 4);
559 assert(regs % elems == 0);
561 unsigned eBytes = (1 << size);
562 unsigned loadSize = eBytes * elems;
563 M5_VAR_USED
unsigned loadRegs =
564 (loadSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
566 assert(loadRegs > 0 && loadRegs <= 4);
569 bool wb = (
rm != 15);
580 microOps[uopIdx++] =
new MicroLdrNeon1Uop<uint8_t>(
585 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint16_t>(
588 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint8_t>(
593 microOps[uopIdx++] =
new MicroLdrNeon3Uop<uint8_t>(
599 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint8_t>(
603 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint16_t>(
607 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint32_t>(
613 microOps[uopIdx++] =
new MicroLdrNeon6Uop<uint16_t>(
619 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint16_t>(
623 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint32_t>(
629 microOps[uopIdx++] =
new MicroLdrNeon12Uop<uint32_t>(
633 microOps[uopIdx++] =
new MicroLdrNeon16Uop<uint32_t>(
641 if (
rm != 15 &&
rm != 13) {
655 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint8_t>(
658 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint8_t>(
664 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint16_t>(
667 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint16_t>(
673 microOps[uopIdx++] =
new MicroUnpackAllNeon4to8Uop<uint32_t>(
676 microOps[uopIdx++] =
new MicroUnpackNeon4to8Uop<uint32_t>(
691 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint8_t>(
694 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint8_t>(
700 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint16_t>(
703 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint16_t>(
709 microOps[uopIdx++] =
new MicroUnpackAllNeon4to6Uop<uint32_t>(
712 microOps[uopIdx++] =
new MicroUnpackNeon4to6Uop<uint32_t>(
724 assert(loadRegs <= 2);
728 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint8_t>(
731 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint8_t>(
737 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint16_t>(
740 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint16_t>(
746 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint32_t>(
749 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint32_t>(
760 assert(regs == 1 || (all && regs == 2));
761 assert(loadRegs <= 2);
767 new MicroUnpackAllNeon2to2Uop<uint8_t>(
771 new MicroUnpackNeon2to2Uop<uint8_t>(
778 new MicroUnpackAllNeon2to2Uop<uint16_t>(
782 new MicroUnpackNeon2to2Uop<uint16_t>(
789 new MicroUnpackAllNeon2to2Uop<uint32_t>(
793 new MicroUnpackNeon2to2Uop<uint32_t>(
824 assert(regs > 0 && regs <= 4);
825 assert(regs % elems == 0);
828 bool wb = (
rm != 15);
829 bool interleave = (elems > 1);
835 uint32_t noAlign = 0;
844 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>(
849 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>(
853 assert(regs == 4 || regs == 2);
855 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
857 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
860 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
871 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
873 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
877 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
879 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
883 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
887 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
895 if (
rm != 15 &&
rm != 13) {
915 OpClass __opClass,
bool all,
unsigned elems,
917 unsigned inc, uint32_t size, uint32_t
align,
922 assert(regs > 0 && regs <= 4);
923 assert(regs % elems == 0);
925 unsigned eBytes = (1 << size);
926 unsigned storeSize = eBytes * elems;
927 M5_VAR_USED
unsigned storeRegs =
928 (storeSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
930 assert(storeRegs > 0 && storeRegs <= 4);
933 bool wb = (
rm != 15);
947 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint8_t>(
951 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint16_t>(
955 microOps[uopIdx++] =
new MicroPackNeon8to4Uop<uint32_t>(
968 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint8_t>(
972 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint16_t>(
976 microOps[uopIdx++] =
new MicroPackNeon6to4Uop<uint32_t>(
987 assert(storeRegs <= 2);
990 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint8_t>(
994 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint16_t>(
998 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint32_t>(
1008 assert(regs == 1 || (all && regs == 2));
1009 assert(storeRegs <= 2);
1013 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint8_t>(
1017 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint16_t>(
1021 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint32_t>(
1035 switch (storeSize) {
1037 microOps[uopIdx++] =
new MicroStrNeon1Uop<uint8_t>(
1042 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint16_t>(
1045 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint8_t>(
1050 microOps[uopIdx++] =
new MicroStrNeon3Uop<uint8_t>(
1056 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint8_t>(
1060 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint16_t>(
1064 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint32_t>(
1070 microOps[uopIdx++] =
new MicroStrNeon6Uop<uint16_t>(
1076 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint16_t>(
1080 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint32_t>(
1086 microOps[uopIdx++] =
new MicroStrNeon12Uop<uint32_t>(
1090 microOps[uopIdx++] =
new MicroStrNeon16Uop<uint32_t>(
1098 if (
rm != 15 &&
rm != 13) {
1119 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1120 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
1130 assert(totNumBytes <= 64);
1134 int numMemMicroops = totNumBytes / 16;
1135 int residuum = totNumBytes % 16;
1144 unsigned uopIdx = 0;
1148 for (;
i < numMemMicroops - 1; ++
i) {
1149 microOps[uopIdx++] =
new MicroNeonLoad64(
1151 baseIsSP, 16 ,
eSize);
1153 microOps[uopIdx++] =
new MicroNeonLoad64(
1155 residuum ? residuum : 16 ,
eSize);
1170 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1172 case 1:
microOps[uopIdx++] =
new MicroDeintNeon64_1Reg(
1176 case 2:
microOps[uopIdx++] =
new MicroDeintNeon64_2Reg(
1180 case 3:
microOps[uopIdx++] =
new MicroDeintNeon64_3Reg(
1184 case 4:
microOps[uopIdx++] =
new MicroDeintNeon64_4Reg(
1188 default:
panic(
"Invalid number of registers");
1204 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1205 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
1215 assert(totNumBytes <= 64);
1219 int numMemMicroops = totNumBytes / 16;
1220 int residuum = totNumBytes % 16;
1225 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1229 unsigned uopIdx = 0;
1231 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1233 case 1:
microOps[uopIdx++] =
new MicroIntNeon64_1Reg(
1237 case 2:
microOps[uopIdx++] =
new MicroIntNeon64_2Reg(
1241 case 3:
microOps[uopIdx++] =
new MicroIntNeon64_3Reg(
1245 case 4:
microOps[uopIdx++] =
new MicroIntNeon64_4Reg(
1249 default:
panic(
"Invalid number of registers");
1256 for (;
i < numMemMicroops - 1; ++
i) {
1257 microOps[uopIdx++] =
new MicroNeonStore64(
1259 baseIsSP, 16 ,
eSize);
1261 microOps[uopIdx++] =
new MicroNeonStore64(
1263 residuum ? residuum : 16 ,
eSize);
1289 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1290 uint8_t numStructElems, uint8_t
index,
bool wb,
1293 eSize(0), dataSize(0), numStructElems(0),
index(0),
1294 wb(false), replicate(false)
1303 int eSizeBytes = 1 <<
eSize;
1305 assert(totNumBytes <= 64);
1309 int numMemMicroops = totNumBytes / 16;
1310 int residuum = totNumBytes % 16;
1319 unsigned uopIdx = 0;
1324 for (;
i < numMemMicroops - 1; ++
i) {
1325 microOps[uopIdx++] =
new MicroNeonLoad64(
1327 baseIsSP, 16 ,
eSize);
1329 microOps[uopIdx++] =
new MicroNeonLoad64(
1331 residuum ? residuum : 16 ,
eSize);
1346 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1347 microOps[uopIdx++] =
new MicroUnpackNeon64(
1363 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1364 uint8_t numStructElems, uint8_t
index,
bool wb,
1367 eSize(0), dataSize(0), numStructElems(0),
index(0),
1368 wb(false), replicate(false)
1376 int eSizeBytes = 1 <<
eSize;
1378 assert(totNumBytes <= 64);
1382 int numMemMicroops = totNumBytes / 16;
1383 int residuum = totNumBytes % 16;
1388 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1392 unsigned uopIdx = 0;
1394 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1395 microOps[uopIdx++] =
new MicroPackNeon64(
1403 for (;
i < numMemMicroops - 1; ++
i) {
1404 microOps[uopIdx++] =
new MicroNeonStore64(
1406 baseIsSP, 16 ,
eSize);
1408 microOps[uopIdx++] =
new MicroNeonStore64(
1410 residuum ? residuum : 16 ,
eSize);
1478 addr -= (single ? 4 : 8);
1486 addr += (single ? 4 : 8);
1516 std::stringstream
ss;
1530 std::stringstream
ss;
1544 std::stringstream
ss;
1554 std::stringstream
ss;
1567 std::stringstream
ss;
1579 std::stringstream
ss;
1593 std::stringstream
ss;
1611 std::stringstream
ss;