Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: src/IceInstARM32.cpp

Issue 1481133002: Subzero. ARM32. Show FP lowering some love. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 } 573 }
558 574
559 InstARM32Label::InstARM32Label(Cfg *Func, TargetARM32 *Target) 575 InstARM32Label::InstARM32Label(Cfg *Func, TargetARM32 *Target)
560 : InstARM32(Func, InstARM32::Label, 0, nullptr), 576 : InstARM32(Func, InstARM32::Label, 0, nullptr),
561 Number(Target->makeNextLabelNumber()) {} 577 Number(Target->makeNextLabelNumber()) {}
562 578
563 IceString InstARM32Label::getName(const Cfg *Func) const { 579 IceString InstARM32Label::getName(const Cfg *Func) const {
564 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); 580 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number);
565 } 581 }
566 582
583 namespace {
584 //
Jim Stichnoth 2015/12/08 19:20:16 Fill in the comment, or delete this line.
John 2015/12/09 13:11:08 Done.
585 void ValidatePushOrPopRegisterListOrDie(const VarList &RegList) {
Jim Stichnoth 2015/12/08 19:20:16 lowerCase function name
John 2015/12/09 13:11:08 Done.
586 Type PreviousTy = IceType_void;
587 for (Variable *Reg : RegList) {
588 if (PreviousTy != IceType_void && Reg->getType() != PreviousTy) {
589 llvm::report_fatal_error("Type mismatch when popping/pushing "
590 "registers.");
591 }
592
593 if (!Reg->hasReg()) {
594 llvm::report_fatal_error("Push/pop operand does not have a register "
595 "assigned to it.");
596 }
597
598 PreviousTy = Reg->getType();
599 }
600 }
601 } // end of anonymous namespace
602
567 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests) 603 InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests)
568 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) { 604 : InstARM32(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) {
569 // Track modifications to Dests separately via FakeDefs. Also, a pop 605 // Track modifications to Dests separately via FakeDefs. Also, a pop
570 // instruction affects the stack pointer and so it should not be allowed to 606 // instruction affects the stack pointer and so it should not be allowed to
571 // be automatically dead-code eliminated. This is automatic since we leave 607 // be automatically dead-code eliminated. This is automatic since we leave
572 // the Dest as nullptr. 608 // the Dest as nullptr.
609 ValidatePushOrPopRegisterListOrDie(Dests);
573 } 610 }
574 611
575 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs) 612 InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs)
576 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) { 613 : InstARM32(Func, InstARM32::Push, Srcs.size(), nullptr) {
577 for (Variable *Source : Srcs) 614 ValidatePushOrPopRegisterListOrDie(Srcs);
615 for (Variable *Source : Srcs) {
578 addSource(Source); 616 addSource(Source);
617 }
579 } 618 }
580 619
581 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) 620 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source)
582 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { 621 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) {
583 addSource(LR); 622 addSource(LR);
584 if (Source) 623 if (Source)
585 addSource(Source); 624 addSource(Source);
586 } 625 }
587 626
588 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, 627 InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 template <> const char *InstARM32Orr::Opcode = "orr"; 753 template <> const char *InstARM32Orr::Opcode = "orr";
715 template <> const char *InstARM32Rsb::Opcode = "rsb"; 754 template <> const char *InstARM32Rsb::Opcode = "rsb";
716 template <> const char *InstARM32Rsc::Opcode = "rsc"; 755 template <> const char *InstARM32Rsc::Opcode = "rsc";
717 template <> const char *InstARM32Sbc::Opcode = "sbc"; 756 template <> const char *InstARM32Sbc::Opcode = "sbc";
718 template <> const char *InstARM32Sdiv::Opcode = "sdiv"; 757 template <> const char *InstARM32Sdiv::Opcode = "sdiv";
719 template <> const char *InstARM32Sub::Opcode = "sub"; 758 template <> const char *InstARM32Sub::Opcode = "sub";
720 template <> const char *InstARM32Udiv::Opcode = "udiv"; 759 template <> const char *InstARM32Udiv::Opcode = "udiv";
721 // FP 760 // FP
722 template <> const char *InstARM32Vadd::Opcode = "vadd"; 761 template <> const char *InstARM32Vadd::Opcode = "vadd";
723 template <> const char *InstARM32Vdiv::Opcode = "vdiv"; 762 template <> const char *InstARM32Vdiv::Opcode = "vdiv";
763 template <> const char *InstARM32Veor::Opcode = "veor";
764 template <> const char *InstARM32Vmla::Opcode = "vmla";
765 template <> const char *InstARM32Vmls::Opcode = "vmls";
724 template <> const char *InstARM32Vmul::Opcode = "vmul"; 766 template <> const char *InstARM32Vmul::Opcode = "vmul";
725 template <> const char *InstARM32Veor::Opcode = "veor";
726 template <> const char *InstARM32Vsub::Opcode = "vsub"; 767 template <> const char *InstARM32Vsub::Opcode = "vsub";
727 // Four-addr ops 768 // Four-addr ops
728 template <> const char *InstARM32Mla::Opcode = "mla"; 769 template <> const char *InstARM32Mla::Opcode = "mla";
729 template <> const char *InstARM32Mls::Opcode = "mls"; 770 template <> const char *InstARM32Mls::Opcode = "mls";
730 // Cmp-like ops 771 // Cmp-like ops
731 template <> const char *InstARM32Cmn::Opcode = "cmn"; 772 template <> const char *InstARM32Cmn::Opcode = "cmn";
732 template <> const char *InstARM32Cmp::Opcode = "cmp"; 773 template <> const char *InstARM32Cmp::Opcode = "cmp";
733 template <> const char *InstARM32Tst::Opcode = "tst"; 774 template <> const char *InstARM32Tst::Opcode = "tst";
734 775
735 void InstARM32::dump(const Cfg *Func) const { 776 void InstARM32::dump(const Cfg *Func) const {
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 } 1227 }
1187 1228
1188 template <> void InstARM32Uxt::emitIAS(const Cfg *Func) const { 1229 template <> void InstARM32Uxt::emitIAS(const Cfg *Func) const {
1189 assert(getSrcSize() == 1); 1230 assert(getSrcSize() == 1);
1190 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 1231 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
1191 Asm->uxt(getDest(), getSrc(0), getPredicate()); 1232 Asm->uxt(getDest(), getSrc(0), getPredicate());
1192 if (Asm->needsTextFixup()) 1233 if (Asm->needsTextFixup())
1193 emitUsingTextFixup(Func); 1234 emitUsingTextFixup(Func);
1194 } 1235 }
1195 1236
1237 namespace {
1238
1239 bool isAssignedConsecutiveRegisters(Variable *Before, Variable *After) {
1240 assert(Before->hasReg());
1241 assert(After->hasReg());
1242 return Before->getRegNum() + 1 == After->getRegNum();
1243 }
1244
1245 } // end of anonymous namespace
1246
1196 void InstARM32Pop::emit(const Cfg *Func) const { 1247 void InstARM32Pop::emit(const Cfg *Func) const {
1197 // TODO(jpp): Improve FP register save/restore. 1248 // TODO(jpp): Improve FP register save/restore.
1198 if (!BuildDefs::dump()) 1249 if (!BuildDefs::dump())
1199 return; 1250 return;
1200 SizeT IntegerCount = 0; 1251 Ostream &Str = Func->getContext()->getStrEmit();
1201 for (const Operand *Op : Dests) { 1252 const SizeT DestSize = Dests.size();
1202 if (isScalarIntegerType(Op->getType())) { 1253 assert(DestSize > 0);
1203 ++IntegerCount; 1254 if (DestSize == 0) {
1204 } 1255 return;
1205 } 1256 }
1206 Ostream &Str = Func->getContext()->getStrEmit(); 1257
1207 bool NeedNewline = false; 1258 Variable *Reg = Dests[0];
1208 if (IntegerCount != 0) { 1259 if (isScalarIntegerType(Reg->getType())) {
1260 // GPR push.
1209 Str << "\t" 1261 Str << "\t"
1210 << "pop" 1262 "pop"
1211 << "\t{"; 1263 "\t{";
1212 bool PrintComma = false; 1264 Reg->emit(Func);
1213 for (const Operand *Op : Dests) { 1265 for (SizeT i = 1; i < DestSize; ++i) {
1214 if (isScalarIntegerType(Op->getType())) { 1266 Str << ", ";
1215 if (PrintComma) 1267 Reg = Dests[i];
1216 Str << ", "; 1268 Reg->emit(Func);
1217 Op->emit(Func);
1218 PrintComma = true;
1219 }
1220 } 1269 }
1221 Str << "}"; 1270 Str << "}";
1222 NeedNewline = true; 1271 return;
1223 } 1272 }
1224 1273
1225 for (const Operand *Op : Dests) { 1274 // VFP "s" reg push.
1226 if (isScalarIntegerType(Op->getType())) 1275 SizeT End = DestSize - 1;
1227 continue; 1276 SizeT Start = DestSize - 1;
1228 if (NeedNewline) { 1277 Reg = Dests[DestSize - 1];
1229 Str << "\n"; 1278 Str << "\t"
1279 "vpop"
1280 "\t{";
1281 for (SizeT i = 2; i <= DestSize; ++i) {
1282 Variable *PreviousReg = Dests[DestSize - i];
1283 if (!isAssignedConsecutiveRegisters(PreviousReg, Reg)) {
1284 Dests[Start]->emit(Func);
1285 for (SizeT j = Start + 1; j <= End; ++j) {
1286 Str << ", ";
1287 Dests[j]->emit(Func);
1288 }
1230 startNextInst(Func); 1289 startNextInst(Func);
1231 NeedNewline = false; 1290 Str << "}\n\t"
1291 "vpop"
1292 "\t{";
1293 End = DestSize - i;
1232 } 1294 }
1233 Str << "\t" 1295 Reg = PreviousReg;
1234 << "vpop" 1296 Start = DestSize - i;
1235 << "\t{";
1236 Op->emit(Func);
1237 Str << "}";
1238 NeedNewline = true;
1239 } 1297 }
1240 assert(NeedNewline); // caller will add the newline 1298 Dests[Start]->emit(Func);
1299 for (SizeT j = Start + 1; j <= End; ++j) {
1300 Str << ", ";
1301 Dests[j]->emit(Func);
1302 }
1303 Str << "}";
1241 } 1304 }
1242 1305
1243 void InstARM32Pop::emitIAS(const Cfg *Func) const { 1306 void InstARM32Pop::emitIAS(const Cfg *Func) const {
1244 SizeT IntegerCount = 0; 1307 SizeT IntegerCount = 0;
1245 ARM32::IValueT GPRegisters = 0; 1308 ARM32::IValueT GPRegisters = 0;
1246 const Variable *LastDest = nullptr; 1309 const Variable *LastDest = nullptr;
1247 for (const Variable *Var : Dests) { 1310 for (const Variable *Var : Dests) {
1248 if (!isScalarIntegerType(Var->getType())) 1311 if (!isScalarIntegerType(Var->getType()))
1249 // TODO(kschimpf) Implement vpush. 1312 // TODO(kschimpf) Implement vpush.
1250 return emitUsingTextFixup(Func); 1313 return emitUsingTextFixup(Func);
1251 assert((Var && Var->hasReg()) && "pop only applies to registers"); 1314 assert((Var && Var->hasReg()) && "pop only applies to registers");
1252 int32_t Reg = Var->getRegNum(); 1315 int32_t Reg = Var->getRegNum();
1253 assert(Reg != RegARM32::Encoded_Not_GPR); 1316 assert(Reg != RegARM32::Encoded_Not_GPR);
1254 LastDest = Var; 1317 LastDest = Var;
1255 GPRegisters |= (1 << Reg); 1318 GPRegisters |= (1 << Reg);
1256 ++IntegerCount; 1319 ++IntegerCount;
1257 } 1320 }
1258 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); 1321 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
1259 switch (IntegerCount) { 1322 switch (IntegerCount) {
1260 case 0: 1323 case 0:
1261 return; 1324 return;
1262 case 1: 1325 case 1:
1263 // Note: Can only apply pop register if single register is not sp. 1326 // Note: Can only apply pop register if single register is not sp.
1264 assert((RegARM32::Encoded_Reg_sp != LastDest->getRegNum()) && 1327 assert((RegARM32::Encoded_Reg_sp != LastDest->getRegNum()) &&
1265 "Effects of pop register SP is undefined!"); 1328 "Effects of pop register SP is undefined!");
1266 // TODO(kschimpf) ARM sandbox does not allow the single register form of 1329 // TODO(kschimpf): ARM sandbox does not allow the single register form of
1267 // pop, and the popList form expects multiple registers. Convert this 1330 // pop, and the popList form expects multiple registers. Convert this
1268 // assert to a conditional check once it has been shown that popList 1331 // assert to a conditional check once it has been shown that popList
1269 // works. 1332 // works.
1270 assert(!Func->getContext()->getFlags().getUseSandboxing() && 1333 assert(!Func->getContext()->getFlags().getUseSandboxing() &&
1271 "pop register not in ARM sandbox!"); 1334 "pop register not in ARM sandbox!");
1272 Asm->pop(LastDest, CondARM32::AL); 1335 Asm->pop(LastDest, CondARM32::AL);
1273 break; 1336 break;
1274 default: 1337 default:
1275 Asm->popList(GPRegisters, CondARM32::AL); 1338 Asm->popList(GPRegisters, CondARM32::AL);
1276 break; 1339 break;
(...skipping 12 matching lines...) Expand all
1289 if (I > 0) 1352 if (I > 0)
1290 Str << ", "; 1353 Str << ", ";
1291 Dests[I]->dump(Func); 1354 Dests[I]->dump(Func);
1292 } 1355 }
1293 } 1356 }
1294 1357
1295 void InstARM32Push::emit(const Cfg *Func) const { 1358 void InstARM32Push::emit(const Cfg *Func) const {
1296 // TODO(jpp): Improve FP register save/restore. 1359 // TODO(jpp): Improve FP register save/restore.
1297 if (!BuildDefs::dump()) 1360 if (!BuildDefs::dump())
1298 return; 1361 return;
1299 SizeT IntegerCount = 0; 1362
1300 for (SizeT i = 0; i < getSrcSize(); ++i) { 1363 // Push can't be emitted if there are no registers to save. This should never
1301 if (isScalarIntegerType(getSrc(i)->getType())) { 1364 // happen, but if it does, we don't need to bring Subzero down -- we just skip
1302 ++IntegerCount; 1365 // emitting the push instruction (and maybe emit a nop?) The assert() is here
1303 } 1366 // so that we can detect this error during development.
1367 const SizeT SrcSize = getSrcSize();
1368 if (SrcSize == 0) {
1369 assert(false && "Empty push list");
1370 return;
1304 } 1371 }
1372
1305 Ostream &Str = Func->getContext()->getStrEmit(); 1373 Ostream &Str = Func->getContext()->getStrEmit();
1306 bool NeedNewline = false; 1374
1307 for (SizeT i = getSrcSize(); i > 0; --i) { 1375 Variable *Reg = llvm::cast<Variable>(getSrc(0));
1308 Operand *Op = getSrc(i - 1); 1376 if (isScalarIntegerType(Reg->getType())) {
1309 if (isScalarIntegerType(Op->getType())) 1377 // GPR push.
1310 continue;
1311 if (NeedNewline) {
1312 Str << "\n";
1313 startNextInst(Func);
1314 NeedNewline = false;
1315 }
1316 Str << "\t" 1378 Str << "\t"
1317 << "vpush" 1379 "push"
1318 << "\t{"; 1380 "\t{";
1319 Op->emit(Func); 1381 Reg->emit(Func);
1320 Str << "}"; 1382 for (SizeT i = 1; i < SrcSize; ++i) {
1321 NeedNewline = true; 1383 Str << ", ";
1322 } 1384 getSrc(i)->emit(Func);
1323 if (IntegerCount != 0) {
1324 if (NeedNewline) {
1325 Str << "\n";
1326 startNextInst(Func);
1327 NeedNewline = false;
1328 }
1329 Str << "\t"
1330 << "push"
1331 << "\t{";
1332 bool PrintComma = false;
1333 for (SizeT i = 0; i < getSrcSize(); ++i) {
1334 Operand *Op = getSrc(i);
1335 if (isScalarIntegerType(Op->getType())) {
1336 if (PrintComma)
1337 Str << ", ";
1338 Op->emit(Func);
1339 PrintComma = true;
1340 }
1341 } 1385 }
1342 Str << "}"; 1386 Str << "}";
1343 NeedNewline = true; 1387 return;
1344 } 1388 }
1345 assert(NeedNewline); // caller will add the newline 1389
1390 // VFP "s" reg push.
1391 Str << "\t"
1392 "vpush"
1393 "\t{";
1394 Reg->emit(Func);
1395 for (SizeT i = 1; i < SrcSize; ++i) {
1396 Variable *NextReg = llvm::cast<Variable>(getSrc(i));
1397 if (isAssignedConsecutiveRegisters(Reg, NextReg)) {
1398 Str << ", ";
1399 } else {
1400 startNextInst(Func);
1401 Str << "}\n\t"
1402 "vpush"
1403 "\t{";
1404 }
1405 Reg = NextReg;
1406 Reg->emit(Func);
1407 }
1408 Str << "}";
1346 } 1409 }
1347 1410
1348 void InstARM32Push::emitIAS(const Cfg *Func) const { 1411 void InstARM32Push::emitIAS(const Cfg *Func) const {
1349 SizeT IntegerCount = 0; 1412 SizeT IntegerCount = 0;
1350 ARM32::IValueT GPRegisters = 0; 1413 ARM32::IValueT GPRegisters = 0;
1351 const Variable *LastSrc = nullptr; 1414 const Variable *LastSrc = nullptr;
1352 for (SizeT Index = 0; Index < getSrcSize(); ++Index) { 1415 for (SizeT Index = 0; Index < getSrcSize(); ++Index) {
1353 if (!isScalarIntegerType(getSrc(Index)->getType())) 1416 if (!isScalarIntegerType(getSrc(Index)->getType()))
1354 // TODO(kschimpf) Implement vpush. 1417 // TODO(kschimpf) Implement vpush.
1355 return emitUsingTextFixup(Func); 1418 return emitUsingTextFixup(Func);
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 template class InstARM32ThreeAddrGPR<InstARM32::Orr>; 1955 template class InstARM32ThreeAddrGPR<InstARM32::Orr>;
1893 template class InstARM32ThreeAddrGPR<InstARM32::Rsb>; 1956 template class InstARM32ThreeAddrGPR<InstARM32::Rsb>;
1894 template class InstARM32ThreeAddrGPR<InstARM32::Rsc>; 1957 template class InstARM32ThreeAddrGPR<InstARM32::Rsc>;
1895 template class InstARM32ThreeAddrGPR<InstARM32::Sbc>; 1958 template class InstARM32ThreeAddrGPR<InstARM32::Sbc>;
1896 template class InstARM32ThreeAddrGPR<InstARM32::Sdiv>; 1959 template class InstARM32ThreeAddrGPR<InstARM32::Sdiv>;
1897 template class InstARM32ThreeAddrGPR<InstARM32::Sub>; 1960 template class InstARM32ThreeAddrGPR<InstARM32::Sub>;
1898 template class InstARM32ThreeAddrGPR<InstARM32::Udiv>; 1961 template class InstARM32ThreeAddrGPR<InstARM32::Udiv>;
1899 1962
1900 template class InstARM32ThreeAddrFP<InstARM32::Vadd>; 1963 template class InstARM32ThreeAddrFP<InstARM32::Vadd>;
1901 template class InstARM32ThreeAddrFP<InstARM32::Vdiv>; 1964 template class InstARM32ThreeAddrFP<InstARM32::Vdiv>;
1965 template class InstARM32ThreeAddrFP<InstARM32::Veor>;
1902 template class InstARM32ThreeAddrFP<InstARM32::Vmul>; 1966 template class InstARM32ThreeAddrFP<InstARM32::Vmul>;
1903 template class InstARM32ThreeAddrFP<InstARM32::Veor>; 1967 template class InstARM32ThreeAddrFP<InstARM32::Vmla>;
1968 template class InstARM32ThreeAddrFP<InstARM32::Vmls>;
1904 template class InstARM32ThreeAddrFP<InstARM32::Vsub>; 1969 template class InstARM32ThreeAddrFP<InstARM32::Vsub>;
1905 1970
1906 template class InstARM32LoadBase<InstARM32::Ldr>; 1971 template class InstARM32LoadBase<InstARM32::Ldr>;
1907 template class InstARM32LoadBase<InstARM32::Ldrex>; 1972 template class InstARM32LoadBase<InstARM32::Ldrex>;
1908 1973
1909 template class InstARM32TwoAddrGPR<InstARM32::Movt>; 1974 template class InstARM32TwoAddrGPR<InstARM32::Movt>;
1910 1975
1911 template class InstARM32UnaryopGPR<InstARM32::Movw, false>; 1976 template class InstARM32UnaryopGPR<InstARM32::Movw, false>;
1912 template class InstARM32UnaryopGPR<InstARM32::Clz, false>; 1977 template class InstARM32UnaryopGPR<InstARM32::Clz, false>;
1913 template class InstARM32UnaryopGPR<InstARM32::Mvn, false>; 1978 template class InstARM32UnaryopGPR<InstARM32::Mvn, false>;
1914 template class InstARM32UnaryopGPR<InstARM32::Rbit, false>; 1979 template class InstARM32UnaryopGPR<InstARM32::Rbit, false>;
1915 template class InstARM32UnaryopGPR<InstARM32::Rev, false>; 1980 template class InstARM32UnaryopGPR<InstARM32::Rev, false>;
1916 template class InstARM32UnaryopGPR<InstARM32::Sxt, true>; 1981 template class InstARM32UnaryopGPR<InstARM32::Sxt, true>;
1917 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>; 1982 template class InstARM32UnaryopGPR<InstARM32::Uxt, true>;
1918 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; 1983 template class InstARM32UnaryopFP<InstARM32::Vsqrt>;
1919 1984
1920 template class InstARM32FourAddrGPR<InstARM32::Mla>; 1985 template class InstARM32FourAddrGPR<InstARM32::Mla>;
1921 template class InstARM32FourAddrGPR<InstARM32::Mls>; 1986 template class InstARM32FourAddrGPR<InstARM32::Mls>;
1922 1987
1923 template class InstARM32CmpLike<InstARM32::Cmn>; 1988 template class InstARM32CmpLike<InstARM32::Cmn>;
1924 template class InstARM32CmpLike<InstARM32::Cmp>; 1989 template class InstARM32CmpLike<InstARM32::Cmp>;
1925 template class InstARM32CmpLike<InstARM32::Tst>; 1990 template class InstARM32CmpLike<InstARM32::Tst>;
1926 1991
1927 } // end of namespace Ice 1992 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698