47 #include "arch/arm/generated/decoder.hh" 56 MacroMemOp::MacroMemOp(
const char *mnem,
ExtMachInst machInst,
59 bool load, uint32_t reglist) :
62 uint32_t regs = reglist;
64 uint32_t mem_ops = ones;
68 bool copy_base = (
bits(reglist, rn) && load) || !ones;
69 bool force_user = user & !
bits(reglist, 15);
70 bool exception_ret = user &
bits(reglist, 15);
71 bool pc_temp = load && writeback &&
bits(reglist, 15);
77 + ((ones % 2 == 0 && exception_ret) ? 1 : 0)
90 addr = (ones << 2) - 4;
100 *uop++ =
new MicroAddiUop(machInst,
INTREG_UREG0, rn, 0);
103 while (mem_ops != 0) {
105 if (load && mem_ops >= 2 &&
113 while (!
bits(regs, reg)) reg++;
118 while (!
bits(regs, reg)) reg++;
127 *uop =
new MicroLdr2Uop(machInst, reg_idx1, reg_idx2,
130 if (!writeback && reg_idx2 ==
INTREG_PC) {
132 (*uop)->setFlag(StaticInst::IsControl);
133 (*uop)->setFlag(StaticInst::IsIndirectControl);
136 (*uop)->setFlag(StaticInst::IsCondControl);
138 (*uop)->setFlag(StaticInst::IsUncondControl);
148 while (!
bits(regs, reg)) reg++;
159 }
else if (reg_idx ==
INTREG_PC && exception_ret) {
161 *uop =
new MicroLdrRetUop(machInst, reg_idx,
165 *uop =
new MicroLdrUop(machInst, reg_idx,
170 if (!writeback && reg_idx ==
INTREG_PC) {
171 (*uop)->setFlag(StaticInst::IsControl);
172 (*uop)->setFlag(StaticInst::IsIndirectControl);
175 (*uop)->setFlag(StaticInst::IsCondControl);
177 (*uop)->setFlag(StaticInst::IsUncondControl);
180 *uop =
new MicroStrUop(machInst, reg_idx, rn, up, addr);
192 if (writeback && ones) {
195 *uop++ =
new MicroAddiUop(machInst, rn, rn, ones * 4);
197 *uop++ =
new MicroSubiUop(machInst, rn, rn, ones * 4);
202 *uop =
new MicroUopRegMovRet(machInst, 0,
INTREG_UREG1);
206 (*uop)->setFlag(StaticInst::IsControl);
207 (*uop)->setFlag(StaticInst::IsIndirectControl);
210 (*uop)->setFlag(StaticInst::IsCondControl);
212 (*uop)->setFlag(StaticInst::IsUncondControl);
215 (*uop)->setFlag(StaticInst::IsReturn);
223 microOps[0]->setFirstMicroop();
226 if ((*uop)->isControl())
227 setFlag(StaticInst::IsControl);
228 if ((*uop)->isCondCtrl())
229 setFlag(StaticInst::IsCondControl);
230 if ((*uop)->isUncondCtrl())
231 setFlag(StaticInst::IsUncondControl);
232 if ((*uop)->isIndirectCtrl())
233 setFlag(StaticInst::IsIndirectControl);
234 if ((*uop)->isReturn())
238 (*uop)->setDelayedCommit();
243 uint32_t size,
bool fp,
bool load,
bool noAlloc,
244 bool signExt,
bool exclusive,
bool acrel,
254 numMicroops = (post ? 0 : 1) + ((size + 4) / 8) + (writeback ? 1 : 0);
256 numMicroops = (post ? 0 : 1) + (size / 4) + (writeback ? 1 : 0);
265 *uop++ =
new MicroAddXiSpAlignUop(machInst,
INTREG_UREG0, rn,
272 *uop++ =
new MicroLdFp16Uop(machInst, rt,
273 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
274 *uop++ =
new MicroLdFp16Uop(machInst, rt2,
275 post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel);
277 *uop++ =
new MicroStrQBFpXImmUop(machInst, rt,
278 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
279 *uop++ =
new MicroStrQTFpXImmUop(machInst, rt,
280 post ? rn : INTREG_UREG0, 0, noAlloc, exclusive, acrel);
281 *uop++ =
new MicroStrQBFpXImmUop(machInst, rt2,
282 post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel);
283 *uop++ =
new MicroStrQTFpXImmUop(machInst, rt2,
284 post ? rn : INTREG_UREG0, 16, noAlloc, exclusive, acrel);
286 }
else if (size == 8) {
288 *uop++ =
new MicroLdPairFp8Uop(machInst, rt, rt2,
289 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
291 *uop++ =
new MicroStrFpXImmUop(machInst, rt,
292 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
293 *uop++ =
new MicroStrFpXImmUop(machInst, rt2,
294 post ? rn : INTREG_UREG0, 8, noAlloc, exclusive, acrel);
296 }
else if (size == 4) {
298 *uop++ =
new MicroLdrDFpXImmUop(machInst, rt, rt2,
299 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
301 *uop++ =
new MicroStrDFpXImmUop(machInst, rt, rt2,
302 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
308 *uop++ =
new MicroLdPairUop(machInst, rt, rt2,
309 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
311 *uop++ =
new MicroStrXImmUop(machInst, rt, post ? rn :
INTREG_UREG0,
312 0, noAlloc, exclusive, acrel);
313 *uop++ =
new MicroStrXImmUop(machInst, rt2, post ? rn : INTREG_UREG0,
314 size, noAlloc, exclusive, acrel);
316 }
else if (size == 4) {
319 *uop++ =
new MicroLdrDSXImmUop(machInst, rt, rt2,
320 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
322 *uop++ =
new MicroLdrDUXImmUop(machInst, rt, rt2,
323 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
326 *uop++ =
new MicroStrDXImmUop(machInst, rt, rt2,
327 post ? rn :
INTREG_UREG0, 0, noAlloc, exclusive, acrel);
333 *uop++ =
new MicroAddXiUop(machInst, rn, post ? rn :
INTREG_UREG0,
343 (*curUop)->setDelayedCommit();
358 *uop =
new MicroLdFp16Uop(machInst, dest, base, imm);
360 *uop =
new MicroStrQBFpXImmUop(machInst, dest, base, imm);
361 (*uop)->setDelayedCommit();
362 *++uop =
new MicroStrQTFpXImmUop(machInst, dest, base, imm);
364 (*uop)->setLastMicroop();
379 *uop++ =
new MicroLdFp16Uop(machInst, dest, base, 0);
381 *uop++=
new MicroStrQBFpXImmUop(machInst, dest, base, 0);
382 *uop++ =
new MicroStrQTFpXImmUop(machInst, dest, base, 0);
384 *uop =
new MicroAddXiUop(machInst, base, base, imm);
385 (*uop)->setLastMicroop();
390 (*curUop)->setDelayedCommit();
405 *uop++ =
new MicroLdFp16Uop(machInst, dest, base, imm);
407 *uop++ =
new MicroStrQBFpXImmUop(machInst, dest, base, imm);
408 *uop++ =
new MicroStrQTFpXImmUop(machInst, dest, base, imm);
410 *uop =
new MicroAddXiUop(machInst, base, base, imm);
411 (*uop)->setLastMicroop();
416 (*curUop)->setDelayedCommit();
432 *uop =
new MicroLdFp16RegUop(machInst, dest, base,
435 *uop =
new MicroStrQBFpXRegUop(machInst, dest, base,
437 (*uop)->setDelayedCommit();
438 *++uop =
new MicroStrQTFpXRegUop(machInst, dest, base,
442 (*uop)->setLastMicroop();
454 microOps[0] =
new MicroLdFp16LitUop(machInst, dest, imm);
464 assert(regs > 0 && regs <= 4);
465 assert(regs % elems == 0);
468 bool wb = (rm != 15);
469 bool deinterleave = (elems > 1);
482 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
484 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
488 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
490 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
494 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
498 microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
503 microOps[uopIdx++] =
new Unknown(machInst);
506 if (rm != 15 && rm != 13) {
508 new MicroAddUop(machInst, rn, rn, rm, 0,
ArmISA::LSL);
511 new MicroAddiUop(machInst, rn, rn, regs * 8);
518 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>(
519 size,
machInst, vd * 2, rMid, inc * 2);
523 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>(
524 size,
machInst, vd * 2, rMid, inc * 2);
527 assert(regs == 4 || regs == 2);
529 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
530 size,
machInst, vd * 2, rMid, inc * 2);
531 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
532 size,
machInst, vd * 2 + 2, rMid + 4, inc * 2);
534 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
535 size,
machInst, vd * 2, rMid, inc * 2);
555 OpClass __opClass,
bool all,
unsigned elems,
557 unsigned inc, uint32_t size, uint32_t
align,
561 assert(regs > 0 && regs <= 4);
562 assert(regs % elems == 0);
564 unsigned eBytes = (1 << size);
565 unsigned loadSize = eBytes * elems;
567 (loadSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
569 assert(loadRegs > 0 && loadRegs <= 4);
572 bool wb = (rm != 15);
583 microOps[uopIdx++] =
new MicroLdrNeon1Uop<uint8_t>(
588 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint16_t>(
591 microOps[uopIdx++] =
new MicroLdrNeon2Uop<uint8_t>(
596 microOps[uopIdx++] =
new MicroLdrNeon3Uop<uint8_t>(
602 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint8_t>(
606 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint16_t>(
610 microOps[uopIdx++] =
new MicroLdrNeon4Uop<uint32_t>(
616 microOps[uopIdx++] =
new MicroLdrNeon6Uop<uint16_t>(
622 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint16_t>(
626 microOps[uopIdx++] =
new MicroLdrNeon8Uop<uint32_t>(
632 microOps[uopIdx++] =
new MicroLdrNeon12Uop<uint32_t>(
636 microOps[uopIdx++] =
new MicroLdrNeon16Uop<uint32_t>(
644 if (rm != 15 && rm != 13) {
646 new MicroAddUop(machInst, rn, rn, rm, 0,
ArmISA::LSL);
649 new MicroAddiUop(machInst, rn, rn, loadSize);
658 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint8_t>(
661 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint8_t>(
662 machInst, vd * 2, ufp0, inc * 2, lane);
667 microOps[uopIdx++] =
new MicroUnpackAllNeon2to8Uop<uint16_t>(
670 microOps[uopIdx++] =
new MicroUnpackNeon2to8Uop<uint16_t>(
671 machInst, vd * 2, ufp0, inc * 2, lane);
676 microOps[uopIdx++] =
new MicroUnpackAllNeon4to8Uop<uint32_t>(
679 microOps[uopIdx++] =
new MicroUnpackNeon4to8Uop<uint32_t>(
680 machInst, vd * 2, ufp0, inc * 2, lane);
694 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint8_t>(
697 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint8_t>(
698 machInst, vd * 2, ufp0, inc * 2, lane);
703 microOps[uopIdx++] =
new MicroUnpackAllNeon2to6Uop<uint16_t>(
706 microOps[uopIdx++] =
new MicroUnpackNeon2to6Uop<uint16_t>(
707 machInst, vd * 2, ufp0, inc * 2, lane);
712 microOps[uopIdx++] =
new MicroUnpackAllNeon4to6Uop<uint32_t>(
715 microOps[uopIdx++] =
new MicroUnpackNeon4to6Uop<uint32_t>(
716 machInst, vd * 2, ufp0, inc * 2, lane);
727 assert(loadRegs <= 2);
731 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint8_t>(
734 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint8_t>(
735 machInst, vd * 2, ufp0, inc * 2, lane);
740 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint16_t>(
743 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint16_t>(
744 machInst, vd * 2, ufp0, inc * 2, lane);
749 microOps[uopIdx++] =
new MicroUnpackAllNeon2to4Uop<uint32_t>(
752 microOps[uopIdx++] =
new MicroUnpackNeon2to4Uop<uint32_t>(
753 machInst, vd * 2, ufp0, inc * 2, lane);
763 assert(regs == 1 || (all && regs == 2));
764 assert(loadRegs <= 2);
770 new MicroUnpackAllNeon2to2Uop<uint8_t>(
774 new MicroUnpackNeon2to2Uop<uint8_t>(
781 new MicroUnpackAllNeon2to2Uop<uint16_t>(
785 new MicroUnpackNeon2to2Uop<uint16_t>(
792 new MicroUnpackAllNeon2to2Uop<uint32_t>(
796 new MicroUnpackNeon2to2Uop<uint32_t>(
827 assert(regs > 0 && regs <= 4);
828 assert(regs % elems == 0);
831 bool wb = (rm != 15);
832 bool interleave = (elems > 1);
847 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>(
848 size,
machInst, rMid, vd * 2, inc * 2);
852 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>(
853 size,
machInst, rMid, vd * 2, inc * 2);
856 assert(regs == 4 || regs == 2);
858 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
859 size,
machInst, rMid, vd * 2, inc * 2);
860 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
861 size,
machInst, rMid + 4, vd * 2 + 2, inc * 2);
863 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
864 size,
machInst, rMid, vd * 2, inc * 2);
874 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
876 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
880 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
882 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
886 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
890 microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
895 microOps[uopIdx++] =
new Unknown(machInst);
898 if (rm != 15 && rm != 13) {
900 new MicroAddUop(machInst, rn, rn, rm, 0,
ArmISA::LSL);
903 new MicroAddiUop(machInst, rn, rn, regs * 8);
918 OpClass __opClass,
bool all,
unsigned elems,
920 unsigned inc, uint32_t size, uint32_t
align,
925 assert(regs > 0 && regs <= 4);
926 assert(regs % elems == 0);
928 unsigned eBytes = (1 << size);
929 unsigned storeSize = eBytes * elems;
931 (storeSize +
sizeof(uint32_t) - 1) /
sizeof(uint32_t);
933 assert(storeRegs > 0 && storeRegs <= 4);
936 bool wb = (rm != 15);
950 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint8_t>(
951 machInst, ufp0, vd * 2, inc * 2, lane);
954 microOps[uopIdx++] =
new MicroPackNeon8to2Uop<uint16_t>(
955 machInst, ufp0, vd * 2, inc * 2, lane);
958 microOps[uopIdx++] =
new MicroPackNeon8to4Uop<uint32_t>(
959 machInst, ufp0, vd * 2, inc * 2, lane);
971 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint8_t>(
972 machInst, ufp0, vd * 2, inc * 2, lane);
975 microOps[uopIdx++] =
new MicroPackNeon6to2Uop<uint16_t>(
976 machInst, ufp0, vd * 2, inc * 2, lane);
979 microOps[uopIdx++] =
new MicroPackNeon6to4Uop<uint32_t>(
980 machInst, ufp0, vd * 2, inc * 2, lane);
990 assert(storeRegs <= 2);
993 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint8_t>(
994 machInst, ufp0, vd * 2, inc * 2, lane);
997 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint16_t>(
998 machInst, ufp0, vd * 2, inc * 2, lane);
1001 microOps[uopIdx++] =
new MicroPackNeon4to2Uop<uint32_t>(
1002 machInst, ufp0, vd * 2, inc * 2, lane);
1011 assert(regs == 1 || (all && regs == 2));
1012 assert(storeRegs <= 2);
1016 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint8_t>(
1020 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint16_t>(
1024 microOps[uopIdx++] =
new MicroPackNeon2to2Uop<uint32_t>(
1038 switch (storeSize) {
1040 microOps[uopIdx++] =
new MicroStrNeon1Uop<uint8_t>(
1045 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint16_t>(
1048 microOps[uopIdx++] =
new MicroStrNeon2Uop<uint8_t>(
1053 microOps[uopIdx++] =
new MicroStrNeon3Uop<uint8_t>(
1059 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint8_t>(
1063 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint16_t>(
1067 microOps[uopIdx++] =
new MicroStrNeon4Uop<uint32_t>(
1073 microOps[uopIdx++] =
new MicroStrNeon6Uop<uint16_t>(
1079 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint16_t>(
1083 microOps[uopIdx++] =
new MicroStrNeon8Uop<uint32_t>(
1089 microOps[uopIdx++] =
new MicroStrNeon12Uop<uint32_t>(
1093 microOps[uopIdx++] =
new MicroStrNeon16Uop<uint32_t>(
1101 if (rm != 15 && rm != 13) {
1103 new MicroAddUop(machInst, rn, rn, rm, 0,
ArmISA::LSL);
1106 new MicroAddiUop(machInst, rn, rn, storeSize);
1122 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1123 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
1132 int totNumBytes = numRegs * dataSize / 8;
1133 assert(totNumBytes <= 64);
1137 int numMemMicroops = totNumBytes / 16;
1138 int residuum = totNumBytes % 16;
1143 int numMarshalMicroops = numRegs / 2 + (numRegs % 2 ? 1 : 0);
1147 unsigned uopIdx = 0;
1152 for (; i < numMemMicroops - 1; ++
i) {
1153 microOps[uopIdx++] =
new MicroNeonLoad64(
1154 machInst, vx + (
RegIndex) i, rnsp, 16 * i, memaccessFlags,
1155 baseIsSP, 16 , eSize);
1157 microOps[uopIdx++] =
new MicroNeonLoad64(
1158 machInst, vx + (
RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP,
1159 residuum ? residuum : 16 , eSize);
1166 microOps[uopIdx++] =
new MicroAddXERegUop(machInst, rnsp, rnsp, rm,
1169 microOps[uopIdx++] =
new MicroAddXiUop(machInst, rnsp, rnsp,
1174 for (
int i = 0; i < numMarshalMicroops; ++
i) {
1176 case 1:
microOps[uopIdx++] =
new MicroDeintNeon64_1Reg(
1177 machInst, vd + (
RegIndex) (2 * i), vx, eSize, dataSize,
1178 numStructElems, 1, i );
1180 case 2:
microOps[uopIdx++] =
new MicroDeintNeon64_2Reg(
1181 machInst, vd + (
RegIndex) (2 * i), vx, eSize, dataSize,
1182 numStructElems, 2, i );
1184 case 3:
microOps[uopIdx++] =
new MicroDeintNeon64_3Reg(
1185 machInst, vd + (
RegIndex) (2 * i), vx, eSize, dataSize,
1186 numStructElems, 3, i );
1188 case 4:
microOps[uopIdx++] =
new MicroDeintNeon64_4Reg(
1189 machInst, vd + (
RegIndex) (2 * i), vx, eSize, dataSize,
1190 numStructElems, 4, i );
1192 default:
panic(
"Invalid number of registers");
1217 int totNumBytes = numRegs * dataSize / 8;
1218 assert(totNumBytes <= 64);
1222 int numMemMicroops = totNumBytes / 16;
1223 int residuum = totNumBytes % 16;
1228 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1232 unsigned uopIdx = 0;
1234 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1236 case 1:
microOps[uopIdx++] =
new MicroIntNeon64_1Reg(
1237 machInst, vx + (
RegIndex) (2 *
i), vd, eSize, dataSize,
1238 numStructElems, 1,
i );
1240 case 2:
microOps[uopIdx++] =
new MicroIntNeon64_2Reg(
1241 machInst, vx + (
RegIndex) (2 *
i), vd, eSize, dataSize,
1242 numStructElems, 2,
i );
1244 case 3:
microOps[uopIdx++] =
new MicroIntNeon64_3Reg(
1245 machInst, vx + (
RegIndex) (2 *
i), vd, eSize, dataSize,
1246 numStructElems, 3,
i );
1248 case 4:
microOps[uopIdx++] =
new MicroIntNeon64_4Reg(
1249 machInst, vx + (
RegIndex) (2 *
i), vd, eSize, dataSize,
1250 numStructElems, 4,
i );
1252 default:
panic(
"Invalid number of registers");
1260 for (; i < numMemMicroops - 1; ++
i) {
1261 microOps[uopIdx++] =
new MicroNeonStore64(
1262 machInst, vx + (
RegIndex) i, rnsp, 16 * i, memaccessFlags,
1263 baseIsSP, 16 , eSize);
1265 microOps[uopIdx++] =
new MicroNeonStore64(
1266 machInst, vx + (
RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP,
1267 residuum ? residuum : 16 , eSize);
1274 microOps[uopIdx++] =
new MicroAddXERegUop(machInst, rnsp, rnsp, rm,
1277 microOps[uopIdx++] =
new MicroAddXiUop(machInst, rnsp, rnsp,
1296 eSize(0), dataSize(0), numStructElems(0), index(0),
1297 wb(false), replicate(false)
1306 int eSizeBytes = 1 <<
eSize;
1307 int totNumBytes = numStructElems * eSizeBytes;
1308 assert(totNumBytes <= 64);
1312 int numMemMicroops = totNumBytes / 16;
1313 int residuum = totNumBytes % 16;
1318 int numMarshalMicroops = numStructElems / 2 + (numStructElems % 2 ? 1 : 0);
1322 unsigned uopIdx = 0;
1328 for (; i < numMemMicroops - 1; ++
i) {
1329 microOps[uopIdx++] =
new MicroNeonLoad64(
1330 machInst, vx + (
RegIndex) i, rnsp, 16 * i, memaccessFlags,
1331 baseIsSP, 16 , eSize);
1333 microOps[uopIdx++] =
new MicroNeonLoad64(
1334 machInst, vx + (
RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP,
1335 residuum ? residuum : 16 , eSize);
1342 microOps[uopIdx++] =
new MicroAddXERegUop(machInst, rnsp, rnsp, rm,
1345 microOps[uopIdx++] =
new MicroAddXiUop(machInst, rnsp, rnsp,
1350 for (
int i = 0; i < numMarshalMicroops; ++
i) {
1351 microOps[uopIdx++] =
new MicroUnpackNeon64(
1352 machInst, vd + (
RegIndex) (2 * i), vx, eSize, dataSize,
1353 numStructElems, index, i , replicate);
1370 eSize(0), dataSize(0), numStructElems(0), index(0),
1371 wb(false), replicate(false)
1379 int eSizeBytes = 1 <<
eSize;
1380 int totNumBytes = numStructElems * eSizeBytes;
1381 assert(totNumBytes <= 64);
1385 int numMemMicroops = totNumBytes / 16;
1386 int residuum = totNumBytes % 16;
1391 int numMarshalMicroops = totNumBytes > 32 ? 2 : 1;
1395 unsigned uopIdx = 0;
1397 for (
int i = 0;
i < numMarshalMicroops; ++
i) {
1398 microOps[uopIdx++] =
new MicroPackNeon64(
1399 machInst, vx + (
RegIndex) (2 *
i), vd, eSize, dataSize,
1400 numStructElems, index,
i , replicate);
1407 for (; i < numMemMicroops - 1; ++
i) {
1408 microOps[uopIdx++] =
new MicroNeonStore64(
1409 machInst, vx + (
RegIndex) i, rnsp, 16 * i, memaccessFlags,
1410 baseIsSP, 16 , eSize);
1412 microOps[uopIdx++] =
new MicroNeonStore64(
1413 machInst, vx + (
RegIndex) i, rnsp, 16 * i, memaccessFlags, baseIsSP,
1414 residuum ? residuum : 16 , eSize);
1421 microOps[uopIdx++] =
new MicroAddXERegUop(machInst, rnsp, rnsp, rm,
1424 microOps[uopIdx++] =
new MicroAddXiUop(machInst, rnsp, rnsp,
1449 numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0);
1461 microOps[i++] =
new MicroLdrFpUop(machInst, vd++, rn,
1464 microOps[i++] =
new MicroLdrDBFpUop(machInst, vd++, rn,
1466 microOps[i++] =
new MicroLdrDTFpUop(machInst, vd++, rn, tempUp,
1467 addr + (up ? 4 : -4));
1471 microOps[i++] =
new MicroStrFpUop(machInst, vd++, rn,
1474 microOps[i++] =
new MicroStrDBFpUop(machInst, vd++, rn,
1476 microOps[i++] =
new MicroStrDTFpUop(machInst, vd++, rn, tempUp,
1477 addr + (up ? 4 : -4));
1481 addr -= (single ? 4 : 8);
1489 addr += (single ? 4 : 8);
1496 new MicroAddiUop(machInst, rn, rn, 4 * offset);
1499 new MicroSubiUop(machInst, rn, rn, 4 * offset);
1517 std::stringstream
ss;
1530 std::stringstream
ss;
1543 std::stringstream
ss;
1552 std::stringstream
ss;
1564 std::stringstream
ss;
1575 std::stringstream
ss;
1588 std::stringstream
ss;
1605 std::stringstream
ss;
#define panic(...)
This implements a cprintf based panic() function.
void ccprintf(cp::Print &print)
static IntRegIndex makeSP(IntRegIndex reg)
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
void printMnemonic(std::ostream &os, const std::string &suffix="", bool withPred=true, bool withCond64=false, ConditionCode cond64=COND_UC) const
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
BigFpMemPostOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, bool load, IntRegIndex dest, IntRegIndex base, int64_t imm)
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
void printExtendOperand(bool firstOperand, std::ostream &os, IntRegIndex rm, ArmExtendType type, int64_t shiftAmt) const
VldSingleOp64(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex rn, RegIndex vd, RegIndex rm, uint8_t eSize, uint8_t dataSize, uint8_t numStructElems, uint8_t index, bool wb, bool replicate=false)
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
VstSingleOp64(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex rn, RegIndex vd, RegIndex rm, uint8_t eSize, uint8_t dataSize, uint8_t numStructElems, uint8_t index, bool wb, bool replicate=false)
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
MacroVFPMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, IntRegIndex rn, RegIndex vd, bool single, bool up, bool writeback, bool load, uint32_t offset)
Overload hash function for BasicBlockRange type.
BigFpMemLitOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, IntRegIndex dest, int64_t imm)
BigFpMemPreOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, bool load, IntRegIndex dest, IntRegIndex base, int64_t imm)
VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, unsigned width, RegIndex rn, RegIndex vd, unsigned regs, unsigned inc, uint32_t size, uint32_t align, RegIndex rm)
VldMultOp64(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex rn, RegIndex vd, RegIndex rm, uint8_t eSize, uint8_t dataSize, uint8_t numStructElems, uint8_t numRegs, bool wb)
static unsigned int number_of_ones(int32_t val)
PairMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, uint32_t size, bool fp, bool load, bool noAlloc, bool signExt, bool exclusive, bool acrel, int64_t imm, AddrMode mode, IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2)
Utility functions and datatypes used by AArch64 NEON memory instructions.
BigFpMemImmOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, bool load, IntRegIndex dest, IntRegIndex base, int64_t imm)
const ExtMachInst machInst
The binary machine instruction.
void inc(scfx_mant &mant)
void align(const scfx_rep &lhs, const scfx_rep &rhs, int &new_wp, int &len_mant, scfx_mant_ref &lhs_mant, scfx_mant_ref &rhs_mant)
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
void printIntReg(std::ostream &os, RegIndex reg_idx, uint8_t opWidth=0) const
Print a register name for disassembly given the unique dependence tag number (FP or int)...
const int NumVecV8ArchRegs
VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, unsigned inc, uint32_t size, uint32_t align, RegIndex rm)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
VstMultOp64(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex rn, RegIndex vd, RegIndex rm, uint8_t eSize, uint8_t dataSize, uint8_t numStructElems, uint8_t numRegs, bool wb)
VldSingleOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, bool all, unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, unsigned inc, uint32_t size, uint32_t align, RegIndex rm, unsigned lane)
VstSingleOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, bool all, unsigned elems, RegIndex rn, RegIndex vd, unsigned regs, unsigned inc, uint32_t size, uint32_t align, RegIndex rm, unsigned lane)
Base class for predicated macro-operations.
Base class for Memory microops.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
TheISA::ExtMachInst ExtMachInst
Binary extended machine instruction type.
void printFloatReg(std::ostream &os, RegIndex reg_idx) const
BigFpMemRegOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, bool load, IntRegIndex dest, IntRegIndex base, IntRegIndex offset, ArmExtendType type, int64_t imm)
static bool isSP(IntRegIndex reg)
static const int NumArgumentRegs M5_VAR_USED
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
T * get() const
Directly access the pointer itself without taking a reference.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
static int intRegInMode(OperatingMode mode, int reg)
bool isLastMicroop() const
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.