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 |