| 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 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 } | 389 } |
| 390 | 390 |
| 391 OperandARM32FlexFpZero::OperandARM32FlexFpZero(Cfg * /*Func*/, Type Ty) | 391 OperandARM32FlexFpZero::OperandARM32FlexFpZero(Cfg * /*Func*/, Type Ty) |
| 392 : OperandARM32Flex(kFlexFpZero, Ty) {} | 392 : OperandARM32Flex(kFlexFpZero, Ty) {} |
| 393 | 393 |
| 394 OperandARM32FlexReg::OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg, | 394 OperandARM32FlexReg::OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg, |
| 395 ShiftKind ShiftOp, Operand *ShiftAmt) | 395 ShiftKind ShiftOp, Operand *ShiftAmt) |
| 396 : OperandARM32Flex(kFlexReg, Ty), Reg(Reg), ShiftOp(ShiftOp), | 396 : OperandARM32Flex(kFlexReg, Ty), Reg(Reg), ShiftOp(ShiftOp), |
| 397 ShiftAmt(ShiftAmt) { | 397 ShiftAmt(ShiftAmt) { |
| 398 NumVars = 1; | 398 NumVars = 1; |
| 399 Variable *ShiftVar = llvm::dyn_cast_or_null<Variable>(ShiftAmt); | 399 auto *ShiftVar = llvm::dyn_cast_or_null<Variable>(ShiftAmt); |
| 400 if (ShiftVar) | 400 if (ShiftVar) |
| 401 ++NumVars; | 401 ++NumVars; |
| 402 Vars = Func->allocateArrayOf<Variable *>(NumVars); | 402 Vars = Func->allocateArrayOf<Variable *>(NumVars); |
| 403 Vars[0] = Reg; | 403 Vars[0] = Reg; |
| 404 if (ShiftVar) | 404 if (ShiftVar) |
| 405 Vars[1] = ShiftVar; | 405 Vars[1] = ShiftVar; |
| 406 } | 406 } |
| 407 | 407 |
| 408 InstARM32Br::InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, | 408 InstARM32Br::InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, |
| 409 const CfgNode *TargetFalse, | 409 const CfgNode *TargetFalse, |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 DestHi->emit(Func); | 817 DestHi->emit(Func); |
| 818 Str << ", "; | 818 Str << ", "; |
| 819 Src->emit(Func); | 819 Src->emit(Func); |
| 820 } | 820 } |
| 821 | 821 |
| 822 void InstARM32Mov::emitSingleDestMultiSource(const Cfg *Func) const { | 822 void InstARM32Mov::emitSingleDestMultiSource(const Cfg *Func) const { |
| 823 if (!BuildDefs::dump()) | 823 if (!BuildDefs::dump()) |
| 824 return; | 824 return; |
| 825 Ostream &Str = Func->getContext()->getStrEmit(); | 825 Ostream &Str = Func->getContext()->getStrEmit(); |
| 826 Variable *Dest = getDest(); | 826 Variable *Dest = getDest(); |
| 827 Variable *SrcLo = llvm::cast<Variable>(getSrc(0)); | 827 auto *SrcLo = llvm::cast<Variable>(getSrc(0)); |
| 828 Variable *SrcHi = llvm::cast<Variable>(getSrc(1)); | 828 auto *SrcHi = llvm::cast<Variable>(getSrc(1)); |
| 829 | 829 |
| 830 assert(SrcHi->hasReg()); | 830 assert(SrcHi->hasReg()); |
| 831 assert(SrcLo->hasReg()); | 831 assert(SrcLo->hasReg()); |
| 832 assert(Dest->hasReg()); | 832 assert(Dest->hasReg()); |
| 833 assert(getSrcSize() == 2); | 833 assert(getSrcSize() == 2); |
| 834 | 834 |
| 835 Str << "\t" | 835 Str << "\t" |
| 836 << "vmov" << getPredicate() << "\t"; | 836 << "vmov" << getPredicate() << "\t"; |
| 837 Dest->emit(Func); | 837 Dest->emit(Func); |
| 838 Str << ", "; | 838 Str << ", "; |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1185 } | 1185 } |
| 1186 | 1186 |
| 1187 template <> void InstARM32Movw::emit(const Cfg *Func) const { | 1187 template <> void InstARM32Movw::emit(const Cfg *Func) const { |
| 1188 if (!BuildDefs::dump()) | 1188 if (!BuildDefs::dump()) |
| 1189 return; | 1189 return; |
| 1190 Ostream &Str = Func->getContext()->getStrEmit(); | 1190 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1191 assert(getSrcSize() == 1); | 1191 assert(getSrcSize() == 1); |
| 1192 Str << "\t" << Opcode << getPredicate() << "\t"; | 1192 Str << "\t" << Opcode << getPredicate() << "\t"; |
| 1193 getDest()->emit(Func); | 1193 getDest()->emit(Func); |
| 1194 Str << ", "; | 1194 Str << ", "; |
| 1195 Constant *Src0 = llvm::cast<Constant>(getSrc(0)); | 1195 auto *Src0 = llvm::cast<Constant>(getSrc(0)); |
| 1196 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { | 1196 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { |
| 1197 Str << "#:lower16:"; | 1197 Str << "#:lower16:"; |
| 1198 CR->emitWithoutPrefix(Func->getTarget()); | 1198 CR->emitWithoutPrefix(Func->getTarget()); |
| 1199 } else { | 1199 } else { |
| 1200 Src0->emit(Func); | 1200 Src0->emit(Func); |
| 1201 } | 1201 } |
| 1202 } | 1202 } |
| 1203 | 1203 |
| 1204 template <> void InstARM32Movw::emitIAS(const Cfg *Func) const { | 1204 template <> void InstARM32Movw::emitIAS(const Cfg *Func) const { |
| 1205 assert(getSrcSize() == 1); | 1205 assert(getSrcSize() == 1); |
| 1206 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1206 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
| 1207 Asm->movw(getDest(), getSrc(0), getPredicate()); | 1207 Asm->movw(getDest(), getSrc(0), getPredicate()); |
| 1208 if (Asm->needsTextFixup()) | 1208 if (Asm->needsTextFixup()) |
| 1209 emitUsingTextFixup(Func); | 1209 emitUsingTextFixup(Func); |
| 1210 } | 1210 } |
| 1211 | 1211 |
| 1212 template <> void InstARM32Movt::emit(const Cfg *Func) const { | 1212 template <> void InstARM32Movt::emit(const Cfg *Func) const { |
| 1213 if (!BuildDefs::dump()) | 1213 if (!BuildDefs::dump()) |
| 1214 return; | 1214 return; |
| 1215 Ostream &Str = Func->getContext()->getStrEmit(); | 1215 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1216 assert(getSrcSize() == 2); | 1216 assert(getSrcSize() == 2); |
| 1217 Variable *Dest = getDest(); | 1217 Variable *Dest = getDest(); |
| 1218 Constant *Src1 = llvm::cast<Constant>(getSrc(1)); | 1218 auto *Src1 = llvm::cast<Constant>(getSrc(1)); |
| 1219 Str << "\t" << Opcode << getPredicate() << "\t"; | 1219 Str << "\t" << Opcode << getPredicate() << "\t"; |
| 1220 Dest->emit(Func); | 1220 Dest->emit(Func); |
| 1221 Str << ", "; | 1221 Str << ", "; |
| 1222 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) { | 1222 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) { |
| 1223 Str << "#:upper16:"; | 1223 Str << "#:upper16:"; |
| 1224 CR->emitWithoutPrefix(Func->getTarget()); | 1224 CR->emitWithoutPrefix(Func->getTarget()); |
| 1225 } else { | 1225 } else { |
| 1226 Src1->emit(Func); | 1226 Src1->emit(Func); |
| 1227 } | 1227 } |
| 1228 } | 1228 } |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1384 // emitting the push instruction (and maybe emit a nop?) The assert() is here | 1384 // emitting the push instruction (and maybe emit a nop?) The assert() is here |
| 1385 // so that we can detect this error during development. | 1385 // so that we can detect this error during development. |
| 1386 const SizeT SrcSize = getSrcSize(); | 1386 const SizeT SrcSize = getSrcSize(); |
| 1387 if (SrcSize == 0) { | 1387 if (SrcSize == 0) { |
| 1388 assert(false && "Empty push list"); | 1388 assert(false && "Empty push list"); |
| 1389 return; | 1389 return; |
| 1390 } | 1390 } |
| 1391 | 1391 |
| 1392 Ostream &Str = Func->getContext()->getStrEmit(); | 1392 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1393 | 1393 |
| 1394 Variable *Reg = llvm::cast<Variable>(getSrc(0)); | 1394 auto *Reg = llvm::cast<Variable>(getSrc(0)); |
| 1395 if (isScalarIntegerType(Reg->getType())) { | 1395 if (isScalarIntegerType(Reg->getType())) { |
| 1396 // GPR push. | 1396 // GPR push. |
| 1397 Str << "\t" | 1397 Str << "\t" |
| 1398 "push" | 1398 "push" |
| 1399 "\t{"; | 1399 "\t{"; |
| 1400 Reg->emit(Func); | 1400 Reg->emit(Func); |
| 1401 for (SizeT i = 1; i < SrcSize; ++i) { | 1401 for (SizeT i = 1; i < SrcSize; ++i) { |
| 1402 Str << ", "; | 1402 Str << ", "; |
| 1403 getSrc(i)->emit(Func); | 1403 getSrc(i)->emit(Func); |
| 1404 } | 1404 } |
| 1405 Str << "}"; | 1405 Str << "}"; |
| 1406 return; | 1406 return; |
| 1407 } | 1407 } |
| 1408 | 1408 |
| 1409 // VFP "s" reg push. | 1409 // VFP "s" reg push. |
| 1410 Str << "\t" | 1410 Str << "\t" |
| 1411 "vpush" | 1411 "vpush" |
| 1412 "\t{"; | 1412 "\t{"; |
| 1413 Reg->emit(Func); | 1413 Reg->emit(Func); |
| 1414 for (SizeT i = 1; i < SrcSize; ++i) { | 1414 for (SizeT i = 1; i < SrcSize; ++i) { |
| 1415 Variable *NextReg = llvm::cast<Variable>(getSrc(i)); | 1415 auto *NextReg = llvm::cast<Variable>(getSrc(i)); |
| 1416 if (isAssignedConsecutiveRegisters(Reg, NextReg)) { | 1416 if (isAssignedConsecutiveRegisters(Reg, NextReg)) { |
| 1417 Str << ", "; | 1417 Str << ", "; |
| 1418 } else { | 1418 } else { |
| 1419 startNextInst(Func); | 1419 startNextInst(Func); |
| 1420 Str << "}\n\t" | 1420 Str << "}\n\t" |
| 1421 "vpush" | 1421 "vpush" |
| 1422 "\t{"; | 1422 "\t{"; |
| 1423 } | 1423 } |
| 1424 Reg = NextReg; | 1424 Reg = NextReg; |
| 1425 Reg->emit(Func); | 1425 Reg->emit(Func); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1469 Ostream &Str = Func->getContext()->getStrDump(); | 1469 Ostream &Str = Func->getContext()->getStrDump(); |
| 1470 Str << "push" | 1470 Str << "push" |
| 1471 << " "; | 1471 << " "; |
| 1472 dumpSources(Func); | 1472 dumpSources(Func); |
| 1473 } | 1473 } |
| 1474 | 1474 |
| 1475 void InstARM32Ret::emit(const Cfg *Func) const { | 1475 void InstARM32Ret::emit(const Cfg *Func) const { |
| 1476 if (!BuildDefs::dump()) | 1476 if (!BuildDefs::dump()) |
| 1477 return; | 1477 return; |
| 1478 assert(getSrcSize() > 0); | 1478 assert(getSrcSize() > 0); |
| 1479 Variable *LR = llvm::cast<Variable>(getSrc(0)); | 1479 auto *LR = llvm::cast<Variable>(getSrc(0)); |
| 1480 assert(LR->hasReg()); | 1480 assert(LR->hasReg()); |
| 1481 assert(LR->getRegNum() == RegARM32::Reg_lr); | 1481 assert(LR->getRegNum() == RegARM32::Reg_lr); |
| 1482 Ostream &Str = Func->getContext()->getStrEmit(); | 1482 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1483 Str << "\t" | 1483 Str << "\t" |
| 1484 << "bx" | 1484 << "bx" |
| 1485 << "\t"; | 1485 << "\t"; |
| 1486 LR->emit(Func); | 1486 LR->emit(Func); |
| 1487 } | 1487 } |
| 1488 | 1488 |
| 1489 void InstARM32Ret::emitIAS(const Cfg *Func) const { | 1489 void InstARM32Ret::emitIAS(const Cfg *Func) const { |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2020 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; | 2020 template class InstARM32UnaryopFP<InstARM32::Vsqrt>; |
| 2021 | 2021 |
| 2022 template class InstARM32FourAddrGPR<InstARM32::Mla>; | 2022 template class InstARM32FourAddrGPR<InstARM32::Mla>; |
| 2023 template class InstARM32FourAddrGPR<InstARM32::Mls>; | 2023 template class InstARM32FourAddrGPR<InstARM32::Mls>; |
| 2024 | 2024 |
| 2025 template class InstARM32CmpLike<InstARM32::Cmn>; | 2025 template class InstARM32CmpLike<InstARM32::Cmn>; |
| 2026 template class InstARM32CmpLike<InstARM32::Cmp>; | 2026 template class InstARM32CmpLike<InstARM32::Cmp>; |
| 2027 template class InstARM32CmpLike<InstARM32::Tst>; | 2027 template class InstARM32CmpLike<InstARM32::Tst>; |
| 2028 | 2028 |
| 2029 } // end of namespace Ice | 2029 } // end of namespace Ice |
| OLD | NEW |