45 #include "arch/arm/generated/decoder.hh"
54 MacroMemOp::MacroMemOp(
const char *mnem,
ExtMachInst machInst,
57 bool load, uint32_t reglist) :
60 uint32_t regs = reglist;
62 uint32_t mem_ops = ones;
66 bool copy_base = (
bits(reglist,
rn) && load) || !ones;
67 bool force_user = user & !
bits(reglist, 15);
68 bool exception_ret = user &
bits(reglist, 15);
75 + ((ones % 2 == 0 && exception_ret) ? 1 : 0)
88 addr = (ones << 2) - 4;
101 while (mem_ops != 0) {
103 if (load && mem_ops >= 2 &&
125 *uop =
new MicroLdr2Uop(
machInst, reg_idx1, reg_idx2,
130 (*uop)->setFlag(StaticInst::IsControl);
131 (*uop)->setFlag(StaticInst::IsIndirectControl);
134 (*uop)->setFlag(StaticInst::IsCondControl);
136 (*uop)->setFlag(StaticInst::IsUncondControl);
157 }
else if (reg_idx ==
INTREG_PC && exception_ret) {
159 *uop =
new MicroLdrRetUop(
machInst, reg_idx,
163 *uop =
new MicroLdrUop(
machInst, reg_idx,
169 (*uop)->setFlag(StaticInst::IsControl);
170 (*uop)->setFlag(StaticInst::IsIndirectControl);
173 (*uop)->setFlag(StaticInst::IsCondControl);
175 (*uop)->setFlag(StaticInst::IsUncondControl);
204 (*uop)->setFlag(StaticInst::IsControl);
205 (*uop)->setFlag(StaticInst::IsIndirectControl);
208 (*uop)->setFlag(StaticInst::IsCondControl);
210 (*uop)->setFlag(StaticInst::IsUncondControl);
213 (*uop)->setFlag(StaticInst::IsReturn);
224 if ((*uop)->isControl())
225 setFlag(StaticInst::IsControl);
226 if ((*uop)->isCondCtrl())
227 setFlag(StaticInst::IsCondControl);
228 if ((*uop)->isUncondCtrl())
229 setFlag(StaticInst::IsUncondControl);
230 if ((*uop)->isIndirectCtrl())
231 setFlag(StaticInst::IsIndirectControl);
232 if ((*uop)->isReturn())
236 (*uop)->setDelayedCommit();
241 uint32_t size,
bool fp,
bool load,
bool noAlloc,
242 bool signExt,
bool exclusive,
bool acrel,
272 *uop++ =
new MicroLdFp16Uop(
machInst, rt2,
275 *uop++ =
new MicroStrQBFpXImmUop(
machInst,
rt,
277 *uop++ =
new MicroStrQTFpXImmUop(
machInst,
rt,
279 *uop++ =
new MicroStrQBFpXImmUop(
machInst, rt2,
281 *uop++ =
new MicroStrQTFpXImmUop(
machInst, rt2,
284 }
else if (size == 8) {
286 *uop++ =
new MicroLdPairFp8Uop(
machInst,
rt, rt2,
291 *uop++ =
new MicroStrFpXImmUop(
machInst, rt2,
294 }
else if (size == 4) {
296 *uop++ =
new MicroLdrDFpXImmUop(
machInst,
rt, rt2,
299 *uop++ =
new MicroStrDFpXImmUop(
machInst,
rt, rt2,
306 *uop++ =
new MicroLdPairUop(
machInst,
rt, rt2,
310 0, noAlloc, exclusive, acrel);
312 size, noAlloc, exclusive, acrel);
314 }
else if (size == 4) {
317 *uop++ =
new MicroLdrDSXImmUop(
machInst,
rt, rt2,
320 *uop++ =
new MicroLdrDUXImmUop(
machInst,
rt, rt2,
324 *uop++ =
new MicroStrDXImmUop(
machInst,
rt, rt2,
341 (*curUop)->setDelayedCommit();
359 (*uop)->setDelayedCommit();
362 (*uop)->setLastMicroop();
379 *uop++=
new MicroStrQBFpXImmUop(
machInst, dest,
base, 0);
380 *uop++ =
new MicroStrQTFpXImmUop(
machInst, dest,
base, 0);
383 (*uop)->setLastMicroop();
388 (*curUop)->setDelayedCommit();
409 (*uop)->setLastMicroop();
414 (*curUop)->setDelayedCommit();
435 (*uop)->setDelayedCommit();
440 (*uop)->setLastMicroop();
462 assert(regs > 0 && regs <= 4);
463 assert(regs % elems == 0);
466 bool wb = (
rm != 15);
467 bool deinterleave = (elems > 1);
475 uint32_t noAlign = 0;
480 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
482 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
486 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
488 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
492 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
496 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
504 if (
rm != 15 &&
rm != 13) {
516 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>(
521 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>(
525 assert(regs == 4 || regs == 2);
527 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
529 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
532 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
553 OpClass __opClass,
bool all,
unsigned elems,
555 unsigned inc, uint32_t size, uint32_t
align,
559 assert(regs > 0 && regs <= 4);
560 assert(regs % elems == 0);
562 unsigned eBytes = (1 << size);
563 unsigned loadSize = eBytes * elems;
564 unsigned loadRegs M5_VAR_USED =
565 (loadSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
567 assert(loadRegs > 0 && loadRegs <= 4);
570 bool wb = (
rm != 15);
581 microOps[uopIdx++] =
new MicroLdrNeon1Uop<uint8_t>(
586 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint16_t>(
589 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint8_t>(
594 microOps[uopIdx++] =
new MicroLdrNeon3Uop<uint8_t>(
600 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint8_t>(
604 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint16_t>(
608 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint32_t>(
614 microOps[uopIdx++] =
new MicroLdrNeon6Uop<uint16_t>(
620 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint16_t>(
624 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint32_t>(
630 microOps[uopIdx++] =
new MicroLdrNeon12Uop<uint32_t>(
634 microOps[uopIdx++] =
new MicroLdrNeon16Uop<uint32_t>(
642 if (
rm != 15 &&
rm != 13) {
656 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint8_t>(
659 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint8_t>(
665 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint16_t>(
668 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint16_t>(
674 microOps[uopIdx++] =
new MicroUnpackAllNeon4to8Uop<uint32_t>(
677 microOps[uopIdx++] =
new MicroUnpackNeon4to8Uop<uint32_t>(
692 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint8_t>(
695 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint8_t>(
701 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint16_t>(
704 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint16_t>(
710 microOps[uopIdx++] =
new MicroUnpackAllNeon4to6Uop<uint32_t>(
713 microOps[uopIdx++] =
new MicroUnpackNeon4to6Uop<uint32_t>(
725 assert(loadRegs <= 2);
729 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint8_t>(
732 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint8_t>(
738 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint16_t>(
741 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint16_t>(
747 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint32_t>(
750 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint32_t>(
761 assert(regs == 1 || (all && regs == 2));
762 assert(loadRegs <= 2);
768 new MicroUnpackAllNeon2to2Uop<uint8_t>(
772 new MicroUnpackNeon2to2Uop<uint8_t>(
779 new MicroUnpackAllNeon2to2Uop<uint16_t>(
783 new MicroUnpackNeon2to2Uop<uint16_t>(
790 new MicroUnpackAllNeon2to2Uop<uint32_t>(
794 new MicroUnpackNeon2to2Uop<uint32_t>(
825 assert(regs > 0 && regs <= 4);
826 assert(regs % elems == 0);
829 bool wb = (
rm != 15);
830 bool interleave = (elems > 1);
836 uint32_t noAlign = 0;
845 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>(
850 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>(
854 assert(regs == 4 || regs == 2);
856 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
858 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
861 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
872 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
874 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
878 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
880 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
884 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
888 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
896 if (
rm != 15 &&
rm != 13) {
916 OpClass __opClass,
bool all,
unsigned elems,
918 unsigned inc, uint32_t size, uint32_t
align,
923 assert(regs > 0 && regs <= 4);
924 assert(regs % elems == 0);
926 unsigned eBytes = (1 << size);
927 unsigned storeSize = eBytes * elems;
928 unsigned storeRegs M5_VAR_USED =
929 (storeSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
931 assert(storeRegs > 0 && storeRegs <= 4);
934 bool wb = (
rm != 15);
948 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint8_t>(
952 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint16_t>(
956 microOps[uopIdx++] =
new MicroPackNeon8to4Uop<uint32_t>(
969 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint8_t>(
973 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint16_t>(
977 microOps[uopIdx++] =
new MicroPackNeon6to4Uop<uint32_t>(
988 assert(storeRegs <= 2);
991 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint8_t>(
995 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint16_t>(
999 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint32_t>(
1009 assert(regs == 1 || (all && regs == 2));
1010 assert(storeRegs <= 2);
1014 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint8_t>(
1018 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint16_t>(
1022 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint32_t>(
1036 switch (storeSize) {
1038 microOps[uopIdx++] =
new MicroStrNeon1Uop<uint8_t>(
1043 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint16_t>(
1046 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint8_t>(
1051 microOps[uopIdx++] =
new MicroStrNeon3Uop<uint8_t>(
1057 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint8_t>(
1061 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint16_t>(
1065 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint32_t>(
1071 microOps[uopIdx++] =
new MicroStrNeon6Uop<uint16_t>(
1077 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint16_t>(
1081 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint32_t>(
1087 microOps[uopIdx++] =
new MicroStrNeon12Uop<uint32_t>(
1091 microOps[uopIdx++] =
new MicroStrNeon16Uop<uint32_t>(
1099 if (
rm != 15 &&
rm != 13) {
1120 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1121 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
1131 assert(totNumBytes <= 64);
1135 int numMemMicroops = totNumBytes / 16;
1136 int residuum = totNumBytes % 16;
1145 unsigned uopIdx = 0;
1149 for (;
i < numMemMicroops - 1; ++
i) {
1150 microOps[uopIdx++] =
new MicroNeonLoad64(
1152 baseIsSP, 16 ,
eSize);
1154 microOps[uopIdx++] =
new MicroNeonLoad64(
1156 residuum ? residuum : 16 ,
eSize);
1171 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1173 case 1:
microOps[uopIdx++] =
new MicroDeintNeon64_1Reg(
1177 case 2:
microOps[uopIdx++] =
new MicroDeintNeon64_2Reg(
1181 case 3:
microOps[uopIdx++] =
new MicroDeintNeon64_3Reg(
1185 case 4:
microOps[uopIdx++] =
new MicroDeintNeon64_4Reg(
1189 default:
panic(
"Invalid number of registers");
1205 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1206 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
1216 assert(totNumBytes <= 64);
1220 int numMemMicroops = totNumBytes / 16;
1221 int residuum = totNumBytes % 16;
1226 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1230 unsigned uopIdx = 0;
1232 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1234 case 1:
microOps[uopIdx++] =
new MicroIntNeon64_1Reg(
1238 case 2:
microOps[uopIdx++] =
new MicroIntNeon64_2Reg(
1242 case 3:
microOps[uopIdx++] =
new MicroIntNeon64_3Reg(
1246 case 4:
microOps[uopIdx++] =
new MicroIntNeon64_4Reg(
1250 default:
panic(
"Invalid number of registers");
1257 for (;
i < numMemMicroops - 1; ++
i) {
1258 microOps[uopIdx++] =
new MicroNeonStore64(
1260 baseIsSP, 16 ,
eSize);
1262 microOps[uopIdx++] =
new MicroNeonStore64(
1264 residuum ? residuum : 16 ,
eSize);
1290 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1291 uint8_t numStructElems, uint8_t
index,
bool wb,
1294 eSize(0), dataSize(0), numStructElems(0),
index(0),
1295 wb(false), replicate(false)
1304 int eSizeBytes = 1 <<
eSize;
1306 assert(totNumBytes <= 64);
1310 int numMemMicroops = totNumBytes / 16;
1311 int residuum = totNumBytes % 16;
1320 unsigned uopIdx = 0;
1325 for (;
i < numMemMicroops - 1; ++
i) {
1326 microOps[uopIdx++] =
new MicroNeonLoad64(
1328 baseIsSP, 16 ,
eSize);
1330 microOps[uopIdx++] =
new MicroNeonLoad64(
1332 residuum ? residuum : 16 ,
eSize);
1347 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1348 microOps[uopIdx++] =
new MicroUnpackNeon64(
1364 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1365 uint8_t numStructElems, uint8_t
index,
bool wb,
1368 eSize(0), dataSize(0), numStructElems(0),
index(0),
1369 wb(false), replicate(false)
1377 int eSizeBytes = 1 <<
eSize;
1379 assert(totNumBytes <= 64);
1383 int numMemMicroops = totNumBytes / 16;
1384 int residuum = totNumBytes % 16;
1389 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1393 unsigned uopIdx = 0;
1395 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1396 microOps[uopIdx++] =
new MicroPackNeon64(
1404 for (;
i < numMemMicroops - 1; ++
i) {
1405 microOps[uopIdx++] =
new MicroNeonStore64(
1407 baseIsSP, 16 ,
eSize);
1409 microOps[uopIdx++] =
new MicroNeonStore64(
1411 residuum ? residuum : 16 ,
eSize);
1479 addr -= (single ? 4 : 8);
1487 addr += (single ? 4 : 8);
1517 std::stringstream
ss;
1531 std::stringstream
ss;
1545 std::stringstream
ss;
1555 std::stringstream
ss;
1568 std::stringstream
ss;
1580 std::stringstream
ss;
1594 std::stringstream
ss;
1612 std::stringstream
ss;