47 #include "arch/arm/generated/decoder.hh"
51 using namespace ArmISAInst;
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);
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>(
523 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>(
527 assert(regs == 4 || regs == 2);
529 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
531 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
534 microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
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;
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>(
852 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>(
856 assert(regs == 4 || regs == 2);
858 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
860 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
863 microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
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;
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");
1207 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1208 uint8_t numStructElems, uint8_t numRegs,
bool wb) :
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,
1292 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1293 uint8_t numStructElems, uint8_t
index,
bool wb,
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);
1366 RegIndex rm, uint8_t eSize, uint8_t dataSize,
1367 uint8_t numStructElems, uint8_t
index,
bool wb,
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,
1448 int count = (single ? offset : (offset / 2));
1450 warn_once(
"Bad offset field for VFP load/store multiple.\n");
1458 numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0);
1470 microOps[i++] =
new MicroLdrFpUop(machInst, vd++, rn,
1473 microOps[i++] =
new MicroLdrDBFpUop(machInst, vd++, rn,
1475 microOps[i++] =
new MicroLdrDTFpUop(machInst, vd++, rn, tempUp,
1476 addr + (up ? 4 : -4));
1480 microOps[i++] =
new MicroStrFpUop(machInst, vd++, rn,
1483 microOps[i++] =
new MicroStrDBFpUop(machInst, vd++, rn,
1485 microOps[i++] =
new MicroStrDTFpUop(machInst, vd++, rn, tempUp,
1486 addr + (up ? 4 : -4));
1490 addr -= (single ? 4 : 8);
1498 addr += (single ? 4 : 8);
1505 new MicroAddiUop(machInst, rn, rn, 4 * offset);
1508 new MicroSubiUop(machInst, rn, rn, 4 * offset);
1526 std::stringstream
ss;
1539 std::stringstream
ss;
1552 std::stringstream
ss;
1561 std::stringstream
ss;
1573 std::stringstream
ss;
1584 std::stringstream
ss;
1597 std::stringstream
ss;
1614 std::stringstream
ss;
void ccprintf(cp::Print &print)
static IntRegIndex makeSP(IntRegIndex reg)
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
BigFpMemPostOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, bool load, IntRegIndex dest, IntRegIndex base, int64_t imm)
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)
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)
void printMnemonic(std::ostream &os, const std::string &suffix="", bool withPred=true, bool withCond64=false, ConditionCode cond64=COND_UC) const
void printReg(std::ostream &os, int reg) const
Print a register name for disassembly given the unique dependence tag number (FP or int)...
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
T * get() const
Directly access the pointer itself without taking a reference.
MacroVFPMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass, IntRegIndex rn, RegIndex vd, bool single, bool up, bool writeback, bool load, uint32_t offset)
TheISA::RegIndex RegIndex
Logical register index 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.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
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.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
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.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
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)
static const int NumArgumentRegs M5_VAR_USED
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.
const int NumFloatV8ArchRegs
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
TheISA::ExtMachInst ExtMachInst
Binary extended machine instruction type.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
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)
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
bool isLastMicroop() const
static int intRegInMode(OperatingMode mode, int reg)
const int NumFloatV7ArchRegs