| OLD | NEW |
| 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// | 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 assert(Inst->getSrcSize() == 2); | 178 assert(Inst->getSrcSize() == 2); |
| 179 Str << "\t" << Opcode << getVecWidthString(Inst->getDest()->getType()) | 179 Str << "\t" << Opcode << getVecWidthString(Inst->getDest()->getType()) |
| 180 << "\t"; | 180 << "\t"; |
| 181 Inst->getDest()->emit(Func); | 181 Inst->getDest()->emit(Func); |
| 182 Str << ", "; | 182 Str << ", "; |
| 183 Inst->getSrc(0)->emit(Func); | 183 Inst->getSrc(0)->emit(Func); |
| 184 Str << ", "; | 184 Str << ", "; |
| 185 Inst->getSrc(1)->emit(Func); | 185 Inst->getSrc(1)->emit(Func); |
| 186 } | 186 } |
| 187 | 187 |
| 188 void InstARM32::emitFourAddrFP(const char *Opcode, const InstARM32 *Inst, |
| 189 const Cfg *Func) { |
| 190 if (!BuildDefs::dump()) |
| 191 return; |
| 192 Ostream &Str = Func->getContext()->getStrEmit(); |
| 193 assert(Inst->getSrcSize() == 3); |
| 194 assert(Inst->getSrc(0) == Inst->getDest()); |
| 195 Str << "\t" << Opcode << getVecWidthString(Inst->getDest()->getType()) |
| 196 << "\t"; |
| 197 Inst->getDest()->emit(Func); |
| 198 Str << ", "; |
| 199 Inst->getSrc(1)->emit(Func); |
| 200 Str << ", "; |
| 201 Inst->getSrc(2)->emit(Func); |
| 202 } |
| 203 |
| 188 void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, | 204 void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, |
| 189 const Cfg *Func) { | 205 const Cfg *Func) { |
| 190 if (!BuildDefs::dump()) | 206 if (!BuildDefs::dump()) |
| 191 return; | 207 return; |
| 192 Ostream &Str = Func->getContext()->getStrEmit(); | 208 Ostream &Str = Func->getContext()->getStrEmit(); |
| 193 assert(Inst->getSrcSize() == 3); | 209 assert(Inst->getSrcSize() == 3); |
| 194 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; | 210 Str << "\t" << Opcode << Inst->getPredicate() << "\t"; |
| 195 Inst->getDest()->emit(Func); | 211 Inst->getDest()->emit(Func); |
| 196 Str << ", "; | 212 Str << ", "; |
| 197 Inst->getSrc(0)->emit(Func); | 213 Inst->getSrc(0)->emit(Func); |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 } | 580 } |
| 565 | 581 |
| 566 InstARM32Label::InstARM32Label(Cfg *Func, TargetARM32 *Target) | 582 InstARM32Label::InstARM32Label(Cfg *Func, TargetARM32 *Target) |
| 567 : InstARM32(Func, InstARM32::Label, 0, nullptr), | 583 : InstARM32(Func, InstARM32::Label, 0, nullptr), |
| 568 Number(Target->makeNextLabelNumber()) {} | 584 Number(Target->makeNextLabelNumber()) {} |
| 569 | 585 |
| 570 IceString InstARM32Label::getName(const Cfg *Func) const { | 586 IceString InstARM32Label::getName(const Cfg *Func) const { |
| 571 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); | 587 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); |
| 572 } | 588 } |
| 573 | 589 |
| 590 namespace { |
| 591 // Requirements for Push/Pop: |
| 592 // 1) All the Variables have the same type; |
| 593 // 2) All the variables have registers assigned to them. |
| 594 void validatePushOrPopRegisterListOrDie(const VarList &RegList) { |
| 595 Type PreviousTy = IceType_void; |
| 596 for (Variable *Reg : RegList) { |
| 597 if (PreviousTy != IceType_void && Reg->getType() != PreviousTy) { |
| 598 llvm::report_fatal_error("Type mismatch when popping/pushing " |
| 599 "registers."); |
| 600 } |
| 601 |
| 602 if (!Reg->hasReg()) { |
| 603 llvm::report_fatal_error("Push/pop operand does not have a register " |
| 604 "assigned to it."); |
| 605 } |
| 606 |
| 607 PreviousTy = Reg->getType(); |
| 608 } |
| 609 } |
| 610 } // end of anonymous namespace |
| 611 |
| 574 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) | 612 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) |
| 575 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { | 613 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { |
| 576 // Track modifications to Dests separately via FakeDefs. Also, a pop | 614 // Track modifications to Dests separately via FakeDefs. Also, a pop |
| 577 // instruction affects the stack pointer and so it should not be allowed to | 615 // instruction affects the stack pointer and so it should not be allowed to |
| 578 // be automatically dead-code eliminated. This is automatic since we leave | 616 // be automatically dead-code eliminated. This is automatic since we leave |
| 579 // the Dest as nullptr. | 617 // the Dest as nullptr. |
| 618 validatePushOrPopRegisterListOrDie(Dests); |
| 580 } | 619 } |
| 581 | 620 |
| 582 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) | 621 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) |
| 583 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { | 622 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { |
| 584 for (Variable *Source : Srcs) | 623 validatePushOrPopRegisterListOrDie(Srcs); |
| 624 for (Variable *Source : Srcs) { |
| 585 addSource(Source); | 625 addSource(Source); |
| 626 } |
| 586 } | 627 } |
| 587 | 628 |
| 588 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) | 629 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) |
| 589 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { | 630 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { |
| 590 addSource(LR); | 631 addSource(LR); |
| 591 if (Source) | 632 if (Source) |
| 592 addSource(Source); | 633 addSource(Source); |
| 593 } | 634 } |
| 594 | 635 |
| 595 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, | 636 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 template <> const char *InstARM32Orr::Opcode = "orr"; | 770 template <> const char *InstARM32Orr::Opcode = "orr"; |
| 730 template <> const char *InstARM32Rsb::Opcode = "rsb"; | 771 template <> const char *InstARM32Rsb::Opcode = "rsb"; |
| 731 template <> const char *InstARM32Rsc::Opcode = "rsc"; | 772 template <> const char *InstARM32Rsc::Opcode = "rsc"; |
| 732 template <> const char *InstARM32Sbc::Opcode = "sbc"; | 773 template <> const char *InstARM32Sbc::Opcode = "sbc"; |
| 733 template <> const char *InstARM32Sdiv::Opcode = "sdiv"; | 774 template <> const char *InstARM32Sdiv::Opcode = "sdiv"; |
| 734 template <> const char *InstARM32Sub::Opcode = "sub"; | 775 template <> const char *InstARM32Sub::Opcode = "sub"; |
| 735 template <> const char *InstARM32Udiv::Opcode = "udiv"; | 776 template <> const char *InstARM32Udiv::Opcode = "udiv"; |
| 736 // FP | 777 // FP |
| 737 template <> const char *InstARM32Vadd::Opcode = "vadd"; | 778 template <> const char *InstARM32Vadd::Opcode = "vadd"; |
| 738 template <> const char *InstARM32Vdiv::Opcode = "vdiv"; | 779 template <> const char *InstARM32Vdiv::Opcode = "vdiv"; |
| 780 template <> const char *InstARM32Veor::Opcode = "veor"; |
| 781 template <> const char *InstARM32Vmla::Opcode = "vmla"; |
| 782 template <> const char *InstARM32Vmls::Opcode = "vmls"; |
| 739 template <> const char *InstARM32Vmul::Opcode = "vmul"; | 783 template <> const char *InstARM32Vmul::Opcode = "vmul"; |
| 740 template <> const char *InstARM32Veor::Opcode = "veor"; | |
| 741 template <> const char *InstARM32Vsub::Opcode = "vsub"; | 784 template <> const char *InstARM32Vsub::Opcode = "vsub"; |
| 742 // Four-addr ops | 785 // Four-addr ops |
| 743 template <> const char *InstARM32Mla::Opcode = "mla"; | 786 template <> const char *InstARM32Mla::Opcode = "mla"; |
| 744 template <> const char *InstARM32Mls::Opcode = "mls"; | 787 template <> const char *InstARM32Mls::Opcode = "mls"; |
| 745 // Cmp-like ops | 788 // Cmp-like ops |
| 746 template <> const char *InstARM32Cmn::Opcode = "cmn"; | 789 template <> const char *InstARM32Cmn::Opcode = "cmn"; |
| 747 template <> const char *InstARM32Cmp::Opcode = "cmp"; | 790 template <> const char *InstARM32Cmp::Opcode = "cmp"; |
| 748 template <> const char *InstARM32Tst::Opcode = "tst"; | 791 template <> const char *InstARM32Tst::Opcode = "tst"; |
| 749 | 792 |
| 750 void InstARM32::dump(const Cfg *Func) const { | 793 void InstARM32::dump(const Cfg *Func) const { |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 } | 1252 } |
| 1210 | 1253 |
| 1211 template <> void InstARM32Uxt::emitIAS(const Cfg *Func) const { | 1254 template <> void InstARM32Uxt::emitIAS(const Cfg *Func) const { |
| 1212 assert(getSrcSize() == 1); | 1255 assert(getSrcSize() == 1); |
| 1213 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1256 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 1214 Asm->uxt(getDest(), getSrc(0), getPredicate()); | 1257 Asm->uxt(getDest(), getSrc(0), getPredicate()); |
| 1215 if (Asm->needsTextFixup()) | 1258 if (Asm->needsTextFixup()) |
| 1216 emitUsingTextFixup(Func); | 1259 emitUsingTextFixup(Func); |
| 1217 } | 1260 } |
| 1218 | 1261 |
| 1262 namespace { |
| 1263 |
| 1264 bool isAssignedConsecutiveRegisters(Variable *Before, Variable *After) { |
| 1265 assert(Before->hasReg()); |
| 1266 assert(After->hasReg()); |
| 1267 return Before->getRegNum() + 1 == After->getRegNum(); |
| 1268 } |
| 1269 |
| 1270 } // end of anonymous namespace |
| 1271 |
| 1219 void InstARM32Pop::emit(const Cfg *Func) const { | 1272 void InstARM32Pop::emit(const Cfg *Func) const { |
| 1220 // TODO(jpp): Improve FP register save/restore. | |
| 1221 if (!BuildDefs::dump()) | 1273 if (!BuildDefs::dump()) |
| 1222 return; | 1274 return; |
| 1223 SizeT IntegerCount = 0; | 1275 |
| 1224 for (const Operand *Op : Dests) { | 1276 const SizeT DestSize = Dests.size(); |
| 1225 if (isScalarIntegerType(Op->getType())) { | 1277 if (DestSize == 0) { |
| 1226 ++IntegerCount; | 1278 assert(false && "Empty pop list"); |
| 1227 } | 1279 return; |
| 1228 } | 1280 } |
| 1281 |
| 1229 Ostream &Str = Func->getContext()->getStrEmit(); | 1282 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1230 bool NeedNewline = false; | 1283 |
| 1231 if (IntegerCount != 0) { | 1284 Variable *Reg = Dests[0]; |
| 1285 if (isScalarIntegerType(Reg->getType())) { |
| 1286 // GPR push. |
| 1232 Str << "\t" | 1287 Str << "\t" |
| 1233 << "pop" | 1288 "pop" |
| 1234 << "\t{"; | 1289 "\t{"; |
| 1235 bool PrintComma = false; | 1290 Reg->emit(Func); |
| 1236 for (const Operand *Op : Dests) { | 1291 for (SizeT i = 1; i < DestSize; ++i) { |
| 1237 if (isScalarIntegerType(Op->getType())) { | 1292 Str << ", "; |
| 1238 if (PrintComma) | 1293 Reg = Dests[i]; |
| 1239 Str << ", "; | 1294 Reg->emit(Func); |
| 1240 Op->emit(Func); | |
| 1241 PrintComma = true; | |
| 1242 } | |
| 1243 } | 1295 } |
| 1244 Str << "}"; | 1296 Str << "}"; |
| 1245 NeedNewline = true; | 1297 return; |
| 1246 } | 1298 } |
| 1247 | 1299 |
| 1248 for (const Operand *Op : Dests) { | 1300 // VFP "s" reg push. |
| 1249 if (isScalarIntegerType(Op->getType())) | 1301 SizeT End = DestSize - 1; |
| 1250 continue; | 1302 SizeT Start = DestSize - 1; |
| 1251 if (NeedNewline) { | 1303 Reg = Dests[DestSize - 1]; |
| 1252 Str << "\n"; | 1304 Str << "\t" |
| 1305 "vpop" |
| 1306 "\t{"; |
| 1307 for (SizeT i = 2; i <= DestSize; ++i) { |
| 1308 Variable *PreviousReg = Dests[DestSize - i]; |
| 1309 if (!isAssignedConsecutiveRegisters(PreviousReg, Reg)) { |
| 1310 Dests[Start]->emit(Func); |
| 1311 for (SizeT j = Start + 1; j <= End; ++j) { |
| 1312 Str << ", "; |
| 1313 Dests[j]->emit(Func); |
| 1314 } |
| 1253 startNextInst(Func); | 1315 startNextInst(Func); |
| 1254 NeedNewline = false; | 1316 Str << "}\n\t" |
| 1317 "vpop" |
| 1318 "\t{"; |
| 1319 End = DestSize - i; |
| 1255 } | 1320 } |
| 1256 Str << "\t" | 1321 Reg = PreviousReg; |
| 1257 << "vpop" | 1322 Start = DestSize - i; |
| 1258 << "\t{"; | |
| 1259 Op->emit(Func); | |
| 1260 Str << "}"; | |
| 1261 NeedNewline = true; | |
| 1262 } | 1323 } |
| 1263 assert(NeedNewline); // caller will add the newline | 1324 Dests[Start]->emit(Func); |
| 1325 for (SizeT j = Start + 1; j <= End; ++j) { |
| 1326 Str << ", "; |
| 1327 Dests[j]->emit(Func); |
| 1328 } |
| 1329 Str << "}"; |
| 1264 } | 1330 } |
| 1265 | 1331 |
| 1266 void InstARM32Pop::emitIAS(const Cfg *Func) const { | 1332 void InstARM32Pop::emitIAS(const Cfg *Func) const { |
| 1267 SizeT IntegerCount = 0; | 1333 SizeT IntegerCount = 0; |
| 1268 ARM32::IValueT GPRegisters = 0; | 1334 ARM32::IValueT GPRegisters = 0; |
| 1269 const Variable *LastDest = nullptr; | 1335 const Variable *LastDest = nullptr; |
| 1270 for (const Variable *Var : Dests) { | 1336 for (const Variable *Var : Dests) { |
| 1271 if (!isScalarIntegerType(Var->getType())) | 1337 if (!isScalarIntegerType(Var->getType())) |
| 1272 // TODO(kschimpf) Implement vpush. | 1338 // TODO(kschimpf) Implement vpush. |
| 1273 return emitUsingTextFixup(Func); | 1339 return emitUsingTextFixup(Func); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1303 Str << "pop" | 1369 Str << "pop" |
| 1304 << " "; | 1370 << " "; |
| 1305 for (SizeT I = 0; I < Dests.size(); ++I) { | 1371 for (SizeT I = 0; I < Dests.size(); ++I) { |
| 1306 if (I > 0) | 1372 if (I > 0) |
| 1307 Str << ", "; | 1373 Str << ", "; |
| 1308 Dests[I]->dump(Func); | 1374 Dests[I]->dump(Func); |
| 1309 } | 1375 } |
| 1310 } | 1376 } |
| 1311 | 1377 |
| 1312 void InstARM32Push::emit(const Cfg *Func) const { | 1378 void InstARM32Push::emit(const Cfg *Func) const { |
| 1313 // TODO(jpp): Improve FP register save/restore. | |
| 1314 if (!BuildDefs::dump()) | 1379 if (!BuildDefs::dump()) |
| 1315 return; | 1380 return; |
| 1316 SizeT IntegerCount = 0; | 1381 |
| 1317 for (SizeT i = 0; i < getSrcSize(); ++i) { | 1382 // Push can't be emitted if there are no registers to save. This should never |
| 1318 if (isScalarIntegerType(getSrc(i)->getType())) { | 1383 // happen, but if it does, we don't need to bring Subzero down -- we just skip |
| 1319 ++IntegerCount; | 1384 // emitting the push instruction (and maybe emit a nop?) The assert() is here |
| 1320 } | 1385 // so that we can detect this error during development. |
| 1386 const SizeT SrcSize = getSrcSize(); |
| 1387 if (SrcSize == 0) { |
| 1388 assert(false && "Empty push list"); |
| 1389 return; |
| 1321 } | 1390 } |
| 1391 |
| 1322 Ostream &Str = Func->getContext()->getStrEmit(); | 1392 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1323 bool NeedNewline = false; | 1393 |
| 1324 for (SizeT i = getSrcSize(); i > 0; --i) { | 1394 Variable *Reg = llvm::cast<Variable>(getSrc(0)); |
| 1325 Operand *Op = getSrc(i - 1); | 1395 if (isScalarIntegerType(Reg->getType())) { |
| 1326 if (isScalarIntegerType(Op->getType())) | 1396 // GPR push. |
| 1327 continue; | |
| 1328 if (NeedNewline) { | |
| 1329 Str << "\n"; | |
| 1330 startNextInst(Func); | |
| 1331 NeedNewline = false; | |
| 1332 } | |
| 1333 Str << "\t" | 1397 Str << "\t" |
| 1334 << "vpush" | 1398 "push" |
| 1335 << "\t{"; | 1399 "\t{"; |
| 1336 Op->emit(Func); | 1400 Reg->emit(Func); |
| 1337 Str << "}"; | 1401 for (SizeT i = 1; i < SrcSize; ++i) { |
| 1338 NeedNewline = true; | 1402 Str << ", "; |
| 1339 } | 1403 getSrc(i)->emit(Func); |
| 1340 if (IntegerCount != 0) { | |
| 1341 if (NeedNewline) { | |
| 1342 Str << "\n"; | |
| 1343 startNextInst(Func); | |
| 1344 NeedNewline = false; | |
| 1345 } | |
| 1346 Str << "\t" | |
| 1347 << "push" | |
| 1348 << "\t{"; | |
| 1349 bool PrintComma = false; | |
| 1350 for (SizeT i = 0; i < getSrcSize(); ++i) { | |
| 1351 Operand *Op = getSrc(i); | |
| 1352 if (isScalarIntegerType(Op->getType())) { | |
| 1353 if (PrintComma) | |
| 1354 Str << ", "; | |
| 1355 Op->emit(Func); | |
| 1356 PrintComma = true; | |
| 1357 } | |
| 1358 } | 1404 } |
| 1359 Str << "}"; | 1405 Str << "}"; |
| 1360 NeedNewline = true; | 1406 return; |
| 1361 } | 1407 } |
| 1362 assert(NeedNewline); // caller will add the newline | 1408 |
| 1409 // VFP "s" reg push. |
| 1410 Str << "\t" |
| 1411 "vpush" |
| 1412 "\t{"; |
| 1413 Reg->emit(Func); |
| 1414 for (SizeT i = 1; i < SrcSize; ++i) { |
| 1415 Variable *NextReg = llvm::cast<Variable>(getSrc(i)); |
| 1416 if (isAssignedConsecutiveRegisters(Reg, NextReg)) { |
| 1417 Str << ", "; |
| 1418 } else { |
| 1419 startNextInst(Func); |
| 1420 Str << "}\n\t" |
| 1421 "vpush" |
| 1422 "\t{"; |
| 1423 } |
| 1424 Reg = NextReg; |
| 1425 Reg->emit(Func); |
| 1426 } |
| 1427 Str << "}"; |
| 1363 } | 1428 } |
| 1364 | 1429 |
| 1365 void InstARM32Push::emitIAS(const Cfg *Func) const { | 1430 void InstARM32Push::emitIAS(const Cfg *Func) const { |
| 1366 SizeT IntegerCount = 0; | 1431 SizeT IntegerCount = 0; |
| 1367 ARM32::IValueT GPRegisters = 0; | 1432 ARM32::IValueT GPRegisters = 0; |
| 1368 const Variable *LastSrc = nullptr; | 1433 const Variable *LastSrc = nullptr; |
| 1369 for (SizeT Index = 0; Index < getSrcSize(); ++Index) { | 1434 for (SizeT Index = 0; Index < getSrcSize(); ++Index) { |
| 1370 if (!isScalarIntegerType(getSrc(Index)->getType())) | 1435 if (!isScalarIntegerType(getSrc(Index)->getType())) |
| 1371 // TODO(kschimpf) Implement vpush. | 1436 // TODO(kschimpf) Implement vpush. |
| 1372 return emitUsingTextFixup(Func); | 1437 return emitUsingTextFixup(Func); |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1918 template class InstARM32ThreeAddrGPR<InstARM32::Orr>; | 1983 template class InstARM32ThreeAddrGPR<InstARM32::Orr>; |
| 1919 template class InstARM32ThreeAddrGPR<InstARM32::Rsb>; | 1984 template class InstARM32ThreeAddrGPR<InstARM32::Rsb>; |
| 1920 template class InstARM32ThreeAddrGPR<InstARM32::Rsc>; | 1985 template class InstARM32ThreeAddrGPR<InstARM32::Rsc>; |
| 1921 template class InstARM32ThreeAddrGPR<InstARM32::Sbc>; | 1986 template class InstARM32ThreeAddrGPR<InstARM32::Sbc>; |
| 1922 template class InstARM32ThreeAddrGPR<InstARM32::Sdiv>; | 1987 template class InstARM32ThreeAddrGPR<InstARM32::Sdiv>; |
| 1923 template class InstARM32ThreeAddrGPR<InstARM32::Sub>; | 1988 template class InstARM32ThreeAddrGPR<InstARM32::Sub>; |
| 1924 template class InstARM32ThreeAddrGPR<InstARM32::Udiv>; | 1989 template class InstARM32ThreeAddrGPR<InstARM32::Udiv>; |
| 1925 | 1990 |
| 1926 template class InstARM32ThreeAddrFP<InstARM32::Vadd>; | 1991 template class InstARM32ThreeAddrFP<InstARM32::Vadd>; |
| 1927 template class InstARM32ThreeAddrFP<InstARM32::Vdiv>; | 1992 template class InstARM32ThreeAddrFP<InstARM32::Vdiv>; |
| 1993 template class InstARM32ThreeAddrFP<InstARM32::Veor>; |
| 1928 template class InstARM32ThreeAddrFP<InstARM32::Vmul>; | 1994 template class InstARM32ThreeAddrFP<InstARM32::Vmul>; |
| 1929 template class InstARM32ThreeAddrFP<InstARM32::Veor>; | 1995 template class InstARM32ThreeAddrFP<InstARM32::Vmla>; |
| 1996 template class InstARM32ThreeAddrFP<InstARM32::Vmls>; |
| 1930 template class InstARM32ThreeAddrFP<InstARM32::Vsub>; | 1997 template class InstARM32ThreeAddrFP<InstARM32::Vsub>; |
| 1931 | 1998 |
| 1932 template class InstARM32LoadBase<InstARM32::Ldr>; | 1999 template class InstARM32LoadBase<InstARM32::Ldr>; |
| 1933 template class InstARM32LoadBase<InstARM32::Ldrex>; | 2000 template class InstARM32LoadBase<InstARM32::Ldrex>; |
| 1934 | 2001 |
| 1935 template class InstARM32TwoAddrGPR<InstARM32::Movt>; | 2002 template class InstARM32TwoAddrGPR<InstARM32::Movt>; |
| 1936 | 2003 |
| 1937 template class InstARM32UnaryopGPR<InstARM32::Movw, false>; | 2004 template class InstARM32UnaryopGPR<InstARM32::Movw, false>; |
| 1938 template class InstARM32UnaryopGPR<InstARM32::Clz, false>; | 2005 template class InstARM32UnaryopGPR<InstARM32::Clz, false>; |
| 1939 template class InstARM32UnaryopGPR<InstARM32::Mvn, false>; | 2006 template class InstARM32UnaryopGPR<InstARM32::Mvn, false>; |
| 1940 template class InstARM32UnaryopGPR<InstARM32::Rbit, false>; | 2007 template class InstARM32UnaryopGPR<InstARM32::Rbit, false>; |
| 1941 template class InstARM32UnaryopGPR<InstARM32::Rev, false>; | 2008 template class InstARM32UnaryopGPR<InstARM32::Rev, false>; |
| 1942 template class InstARM32UnaryopGPR<InstARM32::Sxt, true>; | 2009 template class InstARM32UnaryopGPR<InstARM32::Sxt, true>; |
| 1943 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>; | 2010 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>; |
| 1944 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; | 2011 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; |
| 1945 | 2012 |
| 1946 template class InstARM32FourAddrGPR<InstARM32::Mla>; | 2013 template class InstARM32FourAddrGPR<InstARM32::Mla>; |
| 1947 template class InstARM32FourAddrGPR<InstARM32::Mls>; | 2014 template class InstARM32FourAddrGPR<InstARM32::Mls>; |
| 1948 | 2015 |
| 1949 template class InstARM32CmpLike<InstARM32::Cmn>; | 2016 template class InstARM32CmpLike<InstARM32::Cmn>; |
| 1950 template class InstARM32CmpLike<InstARM32::Cmp>; | 2017 template class InstARM32CmpLike<InstARM32::Cmp>; |
| 1951 template class InstARM32CmpLike<InstARM32::Tst>; | 2018 template class InstARM32CmpLike<InstARM32::Tst>; |
| 1952 | 2019 |
| 1953 } // end of namespace Ice | 2020 } // end of namespace Ice |
| OLD | NEW |