45 #include "arch/arm/generated/decoder.hh"
52 using namespace ArmISAInst;
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;
101 *uop++ =
new MicroAddiUop(
machInst, int_reg::Ureg0,
rn, 0);
104 while (mem_ops != 0) {
106 if (load && mem_ops >= 2 &&
107 !(mem_ops == 2 &&
bits(regs, int_reg::Pc) && exception_ret)) {
124 if (reg_idx2 == int_reg::Pc && pc_temp)
125 reg_idx2 = int_reg::Ureg1;
128 *uop =
new MicroLdr2Uop(
machInst, reg_idx1, reg_idx2,
129 copy_base ? int_reg::Ureg0 :
rn,
up,
addr);
131 if (!
writeback && reg_idx2 == int_reg::Pc) {
133 (*uop)->setFlag(StaticInst::IsControl);
134 (*uop)->setFlag(StaticInst::IsIndirectControl);
137 (*uop)->setFlag(StaticInst::IsCondControl);
139 (*uop)->setFlag(StaticInst::IsUncondControl);
154 if (
writeback && reg_idx == int_reg::Pc) {
158 *uop =
new MicroLdrUop(
machInst, int_reg::Ureg1,
159 copy_base ? int_reg::Ureg0 :
rn,
up,
addr);
160 }
else if (reg_idx == int_reg::Pc && exception_ret) {
162 *uop =
new MicroLdrRetUop(
machInst, reg_idx,
163 copy_base ? int_reg::Ureg0 :
rn,
up,
addr);
166 *uop =
new MicroLdrUop(
machInst, reg_idx,
167 copy_base ? int_reg::Ureg0 :
rn,
up,
addr);
171 if (!
writeback && reg_idx == int_reg::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, int_reg::Ureg1);
205 *uop =
new MicroUopRegMov(
206 machInst, int_reg::Pc, int_reg::Ureg1);
208 (*uop)->setFlag(StaticInst::IsControl);
209 (*uop)->setFlag(StaticInst::IsIndirectControl);
212 (*uop)->setFlag(StaticInst::IsCondControl);
214 (*uop)->setFlag(StaticInst::IsUncondControl);
216 if (
rn == int_reg::Sp)
217 (*uop)->setFlag(StaticInst::IsReturn);
228 if ((*uop)->isControl())
229 setFlag(StaticInst::IsControl);
230 if ((*uop)->isCondCtrl())
231 setFlag(StaticInst::IsCondControl);
232 if ((*uop)->isUncondCtrl())
233 setFlag(StaticInst::IsUncondControl);
234 if ((*uop)->isIndirectCtrl())
235 setFlag(StaticInst::IsIndirectControl);
236 if ((*uop)->isReturn())
240 (*uop)->setDelayedCommit();
245 uint32_t size,
bool fp,
bool load,
bool noAlloc,
246 bool signExt,
bool exclusive,
bool acrel,
267 *uop++ =
new MicroAddXiSpAlignUop(
machInst, int_reg::Ureg0,
rn,
275 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
277 *uop++ =
new MicroLdFp16Uop(
machInst, rt2,
278 post ?
rn : int_reg::Ureg0, 16, noAlloc, exclusive,
281 *uop++ =
new MicroStrQBFpXImmUop(
machInst,
rt,
282 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
284 *uop++ =
new MicroStrQTFpXImmUop(
machInst,
rt,
285 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
287 *uop++ =
new MicroStrQBFpXImmUop(
machInst, rt2,
288 post ?
rn : int_reg::Ureg0, 16, noAlloc, exclusive,
290 *uop++ =
new MicroStrQTFpXImmUop(
machInst, rt2,
291 post ?
rn : int_reg::Ureg0, 16, noAlloc, exclusive,
294 }
else if (size == 8) {
296 *uop++ =
new MicroLdPairFp8Uop(
machInst,
rt, rt2,
297 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
301 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
303 *uop++ =
new MicroStrFpXImmUop(
machInst, rt2,
304 post ?
rn : int_reg::Ureg0, 8, noAlloc, exclusive,
307 }
else if (size == 4) {
309 *uop++ =
new MicroLdrDFpXImmUop(
machInst,
rt, rt2,
310 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
313 *uop++ =
new MicroStrDFpXImmUop(
machInst,
rt, rt2,
314 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
321 *uop++ =
new MicroLdPairUop(
machInst,
rt, rt2,
322 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
326 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
328 *uop++ =
new MicroStrXImmUop(
machInst, rt2,
329 post ?
rn : int_reg::Ureg0, size, noAlloc, exclusive,
332 }
else if (size == 4) {
335 *uop++ =
new MicroLdrDSXImmUop(
machInst,
rt, rt2,
336 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
339 *uop++ =
new MicroLdrDUXImmUop(
machInst,
rt, rt2,
340 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
344 *uop++ =
new MicroStrDXImmUop(
machInst,
rt, rt2,
345 post ?
rn : int_reg::Ureg0, 0, noAlloc, exclusive,
352 *uop++ =
new MicroAddXiUop(
machInst,
rn, post ?
rn : int_reg::Ureg0,
362 (*curUop)->setDelayedCommit();
367 OpClass __opClass,
bool load,
RegIndex dest,
380 (*uop)->setDelayedCommit();
383 (*uop)->setLastMicroop();
388 OpClass __opClass,
bool load,
RegIndex dest,
400 *uop++=
new MicroStrQBFpXImmUop(
machInst, dest,
base, 0);
401 *uop++ =
new MicroStrQTFpXImmUop(
machInst, dest,
base, 0);
404 (*uop)->setLastMicroop();
409 (*curUop)->setDelayedCommit();
414 OpClass __opClass,
bool load,
RegIndex dest,
430 (*uop)->setLastMicroop();
435 (*curUop)->setDelayedCommit();
440 OpClass __opClass,
bool load,
RegIndex dest,
456 (*uop)->setDelayedCommit();
461 (*uop)->setLastMicroop();
483 assert(regs > 0 && regs <= 4);
484 assert(regs % elems == 0);
487 bool wb = (
rm != 15);
488 bool deinterleave = (elems > 1);
496 uint32_t noAlign = 0;
501 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
503 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
507 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
509 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
513 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
517 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
525 if (
rm != 15 &&
rm != 13) {
537 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>(
542 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>(
546 assert(regs == 4 || regs == 2);
548 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
550 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
553 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
574 OpClass __opClass,
bool all,
unsigned elems,
576 unsigned inc, uint32_t size, uint32_t
align,
580 assert(regs > 0 && regs <= 4);
581 assert(regs % elems == 0);
583 unsigned eBytes = (1 << size);
584 unsigned loadSize = eBytes * elems;
585 [[maybe_unused]]
unsigned loadRegs =
586 (loadSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
588 assert(loadRegs > 0 && loadRegs <= 4);
591 bool wb = (
rm != 15);
602 microOps[uopIdx++] =
new MicroLdrNeon1Uop<uint8_t>(
607 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint16_t>(
610 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint8_t>(
615 microOps[uopIdx++] =
new MicroLdrNeon3Uop<uint8_t>(
621 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint8_t>(
625 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint16_t>(
629 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint32_t>(
635 microOps[uopIdx++] =
new MicroLdrNeon6Uop<uint16_t>(
641 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint16_t>(
645 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint32_t>(
651 microOps[uopIdx++] =
new MicroLdrNeon12Uop<uint32_t>(
655 microOps[uopIdx++] =
new MicroLdrNeon16Uop<uint32_t>(
663 if (
rm != 15 &&
rm != 13) {
677 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint8_t>(
680 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint8_t>(
686 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint16_t>(
689 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint16_t>(
695 microOps[uopIdx++] =
new MicroUnpackAllNeon4to8Uop<uint32_t>(
698 microOps[uopIdx++] =
new MicroUnpackNeon4to8Uop<uint32_t>(
713 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint8_t>(
716 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint8_t>(
722 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint16_t>(
725 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint16_t>(
731 microOps[uopIdx++] =
new MicroUnpackAllNeon4to6Uop<uint32_t>(
734 microOps[uopIdx++] =
new MicroUnpackNeon4to6Uop<uint32_t>(
746 assert(loadRegs <= 2);
750 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint8_t>(
753 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint8_t>(
759 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint16_t>(
762 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint16_t>(
768 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint32_t>(
771 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint32_t>(
782 assert(regs == 1 || (all && regs == 2));
783 assert(loadRegs <= 2);
789 new MicroUnpackAllNeon2to2Uop<uint8_t>(
793 new MicroUnpackNeon2to2Uop<uint8_t>(
800 new MicroUnpackAllNeon2to2Uop<uint16_t>(
804 new MicroUnpackNeon2to2Uop<uint16_t>(
811 new MicroUnpackAllNeon2to2Uop<uint32_t>(
815 new MicroUnpackNeon2to2Uop<uint32_t>(
846 assert(regs > 0 && regs <= 4);
847 assert(regs % elems == 0);
850 bool wb = (
rm != 15);
851 bool interleave = (elems > 1);
857 uint32_t noAlign = 0;
866 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>(
871 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>(
875 assert(regs == 4 || regs == 2);
877 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
879 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
882 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
893 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
895 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
899 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
901 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
905 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
909 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
917 if (
rm != 15 &&
rm != 13) {
937 OpClass __opClass,
bool all,
unsigned elems,
939 unsigned inc, uint32_t size, uint32_t
align,
944 assert(regs > 0 && regs <= 4);
945 assert(regs % elems == 0);
947 unsigned eBytes = (1 << size);
948 unsigned storeSize = eBytes * elems;
949 [[maybe_unused]]
unsigned storeRegs =
950 (storeSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
952 assert(storeRegs > 0 && storeRegs <= 4);
955 bool wb = (
rm != 15);
969 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint8_t>(
973 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint16_t>(
977 microOps[uopIdx++] =
new MicroPackNeon8to4Uop<uint32_t>(
990 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint8_t>(
994 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint16_t>(
998 microOps[uopIdx++] =
new MicroPackNeon6to4Uop<uint32_t>(
1009 assert(storeRegs <= 2);
1012 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint8_t>(
1016 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint16_t>(
1020 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint32_t>(
1030 assert(regs == 1 || (all && regs == 2));
1031 assert(storeRegs <= 2);
1035 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint8_t>(
1039 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint16_t>(
1043 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint32_t>(
1057 switch (storeSize) {
1059 microOps[uopIdx++] =
new MicroStrNeon1Uop<uint8_t>(
1064 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint16_t>(
1067 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint8_t>(
1072 microOps[uopIdx++] =
new MicroStrNeon3Uop<uint8_t>(
1078 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint8_t>(
1082 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint16_t>(
1086 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint32_t>(
1092 microOps[uopIdx++] =
new MicroStrNeon6Uop<uint16_t>(
1098 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint16_t>(
1102 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint32_t>(
1108 microOps[uopIdx++] =
new MicroStrNeon12Uop<uint32_t>(
1112 microOps[uopIdx++] =
new MicroStrNeon16Uop<uint32_t>(
1120 if (
rm != 15 &&
rm != 13) {
1141 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1142 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
1152 assert(totNumBytes <= 64);
1156 int numMemMicroops = totNumBytes / 16;
1157 int residuum = totNumBytes % 16;
1166 unsigned uopIdx = 0;
1170 for (;
i < numMemMicroops - 1; ++
i) {
1171 microOps[uopIdx++] =
new MicroNeonLoad64(
1173 baseIsSP, 16 ,
eSize);
1175 microOps[uopIdx++] =
new MicroNeonLoad64(
1177 residuum ? residuum : 16 ,
eSize);
1183 if (
rm != int_reg::X31) {
1192 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1194 case 1:
microOps[uopIdx++] =
new MicroDeintNeon64_1Reg(
1198 case 2:
microOps[uopIdx++] =
new MicroDeintNeon64_2Reg(
1202 case 3:
microOps[uopIdx++] =
new MicroDeintNeon64_3Reg(
1206 case 4:
microOps[uopIdx++] =
new MicroDeintNeon64_4Reg(
1210 default:
panic(
"Invalid number of registers");
1226 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1227 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
1237 assert(totNumBytes <= 64);
1241 int numMemMicroops = totNumBytes / 16;
1242 int residuum = totNumBytes % 16;
1247 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1251 unsigned uopIdx = 0;
1253 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1255 case 1:
microOps[uopIdx++] =
new MicroIntNeon64_1Reg(
1259 case 2:
microOps[uopIdx++] =
new MicroIntNeon64_2Reg(
1263 case 3:
microOps[uopIdx++] =
new MicroIntNeon64_3Reg(
1267 case 4:
microOps[uopIdx++] =
new MicroIntNeon64_4Reg(
1271 default:
panic(
"Invalid number of registers");
1278 for (;
i < numMemMicroops - 1; ++
i) {
1279 microOps[uopIdx++] =
new MicroNeonStore64(
1281 baseIsSP, 16 ,
eSize);
1283 microOps[uopIdx++] =
new MicroNeonStore64(
1285 residuum ? residuum : 16 ,
eSize);
1291 if (
rm != int_reg::X31) {
1311 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1312 uint8_t numStructElems, uint8_t
index,
bool wb,
1315 eSize(0), dataSize(0), numStructElems(0),
index(0),
1316 wb(false), replicate(false)
1325 int eSizeBytes = 1 <<
eSize;
1327 assert(totNumBytes <= 64);
1331 int numMemMicroops = totNumBytes / 16;
1332 int residuum = totNumBytes % 16;
1341 unsigned uopIdx = 0;
1346 for (;
i < numMemMicroops - 1; ++
i) {
1347 microOps[uopIdx++] =
new MicroNeonLoad64(
1349 baseIsSP, 16 ,
eSize);
1351 microOps[uopIdx++] =
new MicroNeonLoad64(
1353 residuum ? residuum : 16 ,
eSize);
1359 if (
rm != int_reg::X31) {
1368 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1369 microOps[uopIdx++] =
new MicroUnpackNeon64(
1385 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1386 uint8_t numStructElems, uint8_t
index,
bool wb,
1389 eSize(0), dataSize(0), numStructElems(0),
index(0),
1390 wb(false), replicate(false)
1398 int eSizeBytes = 1 <<
eSize;
1400 assert(totNumBytes <= 64);
1404 int numMemMicroops = totNumBytes / 16;
1405 int residuum = totNumBytes % 16;
1410 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1414 unsigned uopIdx = 0;
1416 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1417 microOps[uopIdx++] =
new MicroPackNeon64(
1425 for (;
i < numMemMicroops - 1; ++
i) {
1426 microOps[uopIdx++] =
new MicroNeonStore64(
1428 baseIsSP, 16 ,
eSize);
1430 microOps[uopIdx++] =
new MicroNeonStore64(
1432 residuum ? residuum : 16 ,
eSize);
1438 if (
rm != int_reg::X31) {
1500 addr -= (single ? 4 : 8);
1508 addr += (single ? 4 : 8);
1538 std::stringstream
ss;
1552 std::stringstream
ss;
1566 std::stringstream
ss;
1576 std::stringstream
ss;
1589 std::stringstream
ss;
1601 std::stringstream
ss;
1615 std::stringstream
ss;
1633 std::stringstream
ss;