Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/Mips/MipsFastISel.cpp @ 120:1172e4bd9c6f
update 4.0.0
author | mir3636 |
---|---|
date | Fri, 25 Nov 2016 19:14:25 +0900 |
parents | 7d135dc70f03 |
children | 803732b1fca8 |
comparison
equal
deleted
inserted
replaced
101:34baf5011add | 120:1172e4bd9c6f |
---|---|
1 //===-- MipsastISel.cpp - Mips FastISel implementation | 1 //===-- MipsFastISel.cpp - Mips FastISel implementation --------------------===// |
2 //---------------------===// | 2 // |
3 // The LLVM Compiler Infrastructure | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 //===----------------------------------------------------------------------===// | |
9 /// | |
10 /// \file | |
11 /// \brief This file defines the MIPS-specific support for the FastISel class. | |
12 /// Some of the target-specific code is generated by tablegen in the file | |
13 /// MipsGenFastISel.inc, which is #included here. | |
14 /// | |
15 //===----------------------------------------------------------------------===// | |
3 | 16 |
4 #include "MipsCCState.h" | 17 #include "MipsCCState.h" |
5 #include "MipsInstrInfo.h" | 18 #include "MipsInstrInfo.h" |
6 #include "MipsISelLowering.h" | 19 #include "MipsISelLowering.h" |
7 #include "MipsMachineFunction.h" | 20 #include "MipsMachineFunction.h" |
16 #include "llvm/IR/GetElementPtrTypeIterator.h" | 29 #include "llvm/IR/GetElementPtrTypeIterator.h" |
17 #include "llvm/IR/GlobalAlias.h" | 30 #include "llvm/IR/GlobalAlias.h" |
18 #include "llvm/IR/GlobalVariable.h" | 31 #include "llvm/IR/GlobalVariable.h" |
19 #include "llvm/MC/MCSymbol.h" | 32 #include "llvm/MC/MCSymbol.h" |
20 #include "llvm/Target/TargetInstrInfo.h" | 33 #include "llvm/Target/TargetInstrInfo.h" |
34 #include "llvm/Support/Debug.h" | |
35 | |
36 #define DEBUG_TYPE "mips-fastisel" | |
21 | 37 |
22 using namespace llvm; | 38 using namespace llvm; |
23 | 39 |
24 namespace { | 40 namespace { |
25 | 41 |
80 MipsFunctionInfo *MFI; | 96 MipsFunctionInfo *MFI; |
81 | 97 |
82 // Convenience variables to avoid some queries. | 98 // Convenience variables to avoid some queries. |
83 LLVMContext *Context; | 99 LLVMContext *Context; |
84 | 100 |
101 bool fastLowerArguments() override; | |
85 bool fastLowerCall(CallLoweringInfo &CLI) override; | 102 bool fastLowerCall(CallLoweringInfo &CLI) override; |
86 bool fastLowerIntrinsicCall(const IntrinsicInst *II) override; | 103 bool fastLowerIntrinsicCall(const IntrinsicInst *II) override; |
87 | 104 |
88 bool TargetSupported; | |
89 bool UnsupportedFPMode; // To allow fast-isel to proceed and just not handle | 105 bool UnsupportedFPMode; // To allow fast-isel to proceed and just not handle |
90 // floating point but not reject doing fast-isel in other | 106 // floating point but not reject doing fast-isel in other |
91 // situations | 107 // situations |
92 | 108 |
93 private: | 109 private: |
180 private: | 196 private: |
181 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC) const; | 197 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC) const; |
182 bool processCallArgs(CallLoweringInfo &CLI, SmallVectorImpl<MVT> &ArgVTs, | 198 bool processCallArgs(CallLoweringInfo &CLI, SmallVectorImpl<MVT> &ArgVTs, |
183 unsigned &NumBytes); | 199 unsigned &NumBytes); |
184 bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes); | 200 bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes); |
201 const MipsABIInfo &getABI() const { | |
202 return static_cast<const MipsTargetMachine &>(TM).getABI(); | |
203 } | |
185 | 204 |
186 public: | 205 public: |
187 // Backend specific FastISel code. | 206 // Backend specific FastISel code. |
188 explicit MipsFastISel(FunctionLoweringInfo &funcInfo, | 207 explicit MipsFastISel(FunctionLoweringInfo &funcInfo, |
189 const TargetLibraryInfo *libInfo) | 208 const TargetLibraryInfo *libInfo) |
190 : FastISel(funcInfo, libInfo), TM(funcInfo.MF->getTarget()), | 209 : FastISel(funcInfo, libInfo), TM(funcInfo.MF->getTarget()), |
191 Subtarget(&funcInfo.MF->getSubtarget<MipsSubtarget>()), | 210 Subtarget(&funcInfo.MF->getSubtarget<MipsSubtarget>()), |
192 TII(*Subtarget->getInstrInfo()), TLI(*Subtarget->getTargetLowering()) { | 211 TII(*Subtarget->getInstrInfo()), TLI(*Subtarget->getTargetLowering()) { |
193 MFI = funcInfo.MF->getInfo<MipsFunctionInfo>(); | 212 MFI = funcInfo.MF->getInfo<MipsFunctionInfo>(); |
194 Context = &funcInfo.Fn->getContext(); | 213 Context = &funcInfo.Fn->getContext(); |
195 bool ISASupported = !Subtarget->hasMips32r6() && Subtarget->hasMips32(); | 214 UnsupportedFPMode = Subtarget->isFP64bit() || Subtarget->useSoftFloat(); |
196 TargetSupported = | |
197 ISASupported && (TM.getRelocationModel() == Reloc::PIC_) && | |
198 (static_cast<const MipsTargetMachine &>(TM).getABI().IsO32()); | |
199 UnsupportedFPMode = Subtarget->isFP64bit(); | |
200 } | 215 } |
201 | 216 |
202 unsigned fastMaterializeAlloca(const AllocaInst *AI) override; | 217 unsigned fastMaterializeAlloca(const AllocaInst *AI) override; |
203 unsigned fastMaterializeConstant(const Constant *C) override; | 218 unsigned fastMaterializeConstant(const Constant *C) override; |
204 bool fastSelectInstruction(const Instruction *I) override; | 219 bool fastSelectInstruction(const Instruction *I) override; |
269 emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg); | 284 emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg); |
270 return ResultReg; | 285 return ResultReg; |
271 } | 286 } |
272 | 287 |
273 unsigned MipsFastISel::fastMaterializeAlloca(const AllocaInst *AI) { | 288 unsigned MipsFastISel::fastMaterializeAlloca(const AllocaInst *AI) { |
274 if (!TargetSupported) | |
275 return 0; | |
276 | |
277 assert(TLI.getValueType(DL, AI->getType(), true) == MVT::i32 && | 289 assert(TLI.getValueType(DL, AI->getType(), true) == MVT::i32 && |
278 "Alloca should always return a pointer."); | 290 "Alloca should always return a pointer."); |
279 | 291 |
280 DenseMap<const AllocaInst *, int>::iterator SI = | 292 DenseMap<const AllocaInst *, int>::iterator SI = |
281 FuncInfo.StaticAllocaMap.find(AI); | 293 FuncInfo.StaticAllocaMap.find(AI); |
382 } | 394 } |
383 | 395 |
384 // Materialize a constant into a register, and return the register | 396 // Materialize a constant into a register, and return the register |
385 // number (or zero if we failed to handle it). | 397 // number (or zero if we failed to handle it). |
386 unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) { | 398 unsigned MipsFastISel::fastMaterializeConstant(const Constant *C) { |
387 if (!TargetSupported) | |
388 return 0; | |
389 | |
390 EVT CEVT = TLI.getValueType(DL, C->getType(), true); | 399 EVT CEVT = TLI.getValueType(DL, C->getType(), true); |
391 | 400 |
392 // Only handle simple types. | 401 // Only handle simple types. |
393 if (!CEVT.isSimple()) | 402 if (!CEVT.isSimple()) |
394 return 0; | 403 return 0; |
427 // Look through bitcasts. | 436 // Look through bitcasts. |
428 return computeAddress(U->getOperand(0), Addr); | 437 return computeAddress(U->getOperand(0), Addr); |
429 } | 438 } |
430 case Instruction::GetElementPtr: { | 439 case Instruction::GetElementPtr: { |
431 Address SavedAddr = Addr; | 440 Address SavedAddr = Addr; |
432 uint64_t TmpOffset = Addr.getOffset(); | 441 int64_t TmpOffset = Addr.getOffset(); |
433 // Iterate through the GEP folding the constants into offsets where | 442 // Iterate through the GEP folding the constants into offsets where |
434 // we can. | 443 // we can. |
435 gep_type_iterator GTI = gep_type_begin(U); | 444 gep_type_iterator GTI = gep_type_begin(U); |
436 for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e; | 445 for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e; |
437 ++i, ++GTI) { | 446 ++i, ++GTI) { |
689 unsigned RegWithOne = createResultReg(&Mips::GPR32RegClass); | 698 unsigned RegWithOne = createResultReg(&Mips::GPR32RegClass); |
690 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0); | 699 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0); |
691 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1); | 700 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1); |
692 emitInst(Opc).addReg(LeftReg).addReg(RightReg).addReg( | 701 emitInst(Opc).addReg(LeftReg).addReg(RightReg).addReg( |
693 Mips::FCC0, RegState::ImplicitDefine); | 702 Mips::FCC0, RegState::ImplicitDefine); |
694 MachineInstrBuilder MI = emitInst(CondMovOpc, ResultReg) | 703 emitInst(CondMovOpc, ResultReg) |
695 .addReg(RegWithOne) | 704 .addReg(RegWithOne) |
696 .addReg(Mips::FCC0) | 705 .addReg(Mips::FCC0) |
697 .addReg(RegWithZero, RegState::Implicit); | 706 .addReg(RegWithZero); |
698 MI->tieOperands(0, 3); | |
699 break; | 707 break; |
700 } | 708 } |
701 } | 709 } |
702 return true; | 710 return true; |
703 } | 711 } |
746 return true; | 754 return true; |
747 } | 755 } |
748 if (Addr.isFIBase()) { | 756 if (Addr.isFIBase()) { |
749 unsigned FI = Addr.getFI(); | 757 unsigned FI = Addr.getFI(); |
750 unsigned Align = 4; | 758 unsigned Align = 4; |
751 unsigned Offset = Addr.getOffset(); | 759 int64_t Offset = Addr.getOffset(); |
752 MachineFrameInfo &MFI = *MF->getFrameInfo(); | 760 MachineFrameInfo &MFI = MF->getFrameInfo(); |
753 MachineMemOperand *MMO = MF->getMachineMemOperand( | 761 MachineMemOperand *MMO = MF->getMachineMemOperand( |
754 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, | 762 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, |
755 MFI.getObjectSize(FI), Align); | 763 MFI.getObjectSize(FI), Align); |
756 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg) | 764 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg) |
757 .addFrameIndex(FI) | 765 .addFrameIndex(FI) |
797 return true; | 805 return true; |
798 } | 806 } |
799 if (Addr.isFIBase()) { | 807 if (Addr.isFIBase()) { |
800 unsigned FI = Addr.getFI(); | 808 unsigned FI = Addr.getFI(); |
801 unsigned Align = 4; | 809 unsigned Align = 4; |
802 unsigned Offset = Addr.getOffset(); | 810 int64_t Offset = Addr.getOffset(); |
803 MachineFrameInfo &MFI = *MF->getFrameInfo(); | 811 MachineFrameInfo &MFI = MF->getFrameInfo(); |
804 MachineMemOperand *MMO = MF->getMachineMemOperand( | 812 MachineMemOperand *MMO = MF->getMachineMemOperand( |
805 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad, | 813 MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore, |
806 MFI.getObjectSize(FI), Align); | 814 MFI.getObjectSize(FI), Align); |
807 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)) | 815 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)) |
808 .addReg(SrcReg) | 816 .addReg(SrcReg) |
809 .addFrameIndex(FI) | 817 .addFrameIndex(FI) |
810 .addImm(Offset) | 818 .addImm(Offset) |
941 | 949 |
942 if (SrcVT != MVT::f32 || DestVT != MVT::f64) | 950 if (SrcVT != MVT::f32 || DestVT != MVT::f64) |
943 return false; | 951 return false; |
944 | 952 |
945 unsigned SrcReg = | 953 unsigned SrcReg = |
946 getRegForValue(Src); // his must be a 32 bit floating point register class | 954 getRegForValue(Src); // this must be a 32bit floating point register class |
947 // maybe we should handle this differently | 955 // maybe we should handle this differently |
948 if (!SrcReg) | 956 if (!SrcReg) |
949 return false; | 957 return false; |
950 | 958 |
951 unsigned DestReg = createResultReg(&Mips::AFGR64RegClass); | 959 unsigned DestReg = createResultReg(&Mips::AFGR64RegClass); |
955 } | 963 } |
956 | 964 |
957 bool MipsFastISel::selectSelect(const Instruction *I) { | 965 bool MipsFastISel::selectSelect(const Instruction *I) { |
958 assert(isa<SelectInst>(I) && "Expected a select instruction."); | 966 assert(isa<SelectInst>(I) && "Expected a select instruction."); |
959 | 967 |
968 DEBUG(dbgs() << "selectSelect\n"); | |
969 | |
960 MVT VT; | 970 MVT VT; |
961 if (!isTypeSupported(I->getType(), VT)) | 971 if (!isTypeSupported(I->getType(), VT) || UnsupportedFPMode) { |
962 return false; | 972 DEBUG(dbgs() << ".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n"); |
973 return false; | |
974 } | |
963 | 975 |
964 unsigned CondMovOpc; | 976 unsigned CondMovOpc; |
965 const TargetRegisterClass *RC; | 977 const TargetRegisterClass *RC; |
966 | 978 |
967 if (VT.isInteger() && !VT.isVector() && VT.getSizeInBits() <= 32) { | 979 if (VT.isInteger() && !VT.isVector() && VT.getSizeInBits() <= 32) { |
1205 } | 1217 } |
1206 | 1218 |
1207 bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT, | 1219 bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT, |
1208 unsigned NumBytes) { | 1220 unsigned NumBytes) { |
1209 CallingConv::ID CC = CLI.CallConv; | 1221 CallingConv::ID CC = CLI.CallConv; |
1210 emitInst(Mips::ADJCALLSTACKUP).addImm(16); | 1222 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0); |
1211 if (RetVT != MVT::isVoid) { | 1223 if (RetVT != MVT::isVoid) { |
1212 SmallVector<CCValAssign, 16> RVLocs; | 1224 SmallVector<CCValAssign, 16> RVLocs; |
1213 CCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context); | 1225 CCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context); |
1214 CCInfo.AnalyzeCallResult(RetVT, RetCC_Mips); | 1226 CCInfo.AnalyzeCallResult(RetVT, RetCC_Mips); |
1215 | 1227 |
1234 CLI.NumResultRegs = 1; | 1246 CLI.NumResultRegs = 1; |
1235 } | 1247 } |
1236 return true; | 1248 return true; |
1237 } | 1249 } |
1238 | 1250 |
1251 bool MipsFastISel::fastLowerArguments() { | |
1252 DEBUG(dbgs() << "fastLowerArguments\n"); | |
1253 | |
1254 if (!FuncInfo.CanLowerReturn) { | |
1255 DEBUG(dbgs() << ".. gave up (!CanLowerReturn)\n"); | |
1256 return false; | |
1257 } | |
1258 | |
1259 const Function *F = FuncInfo.Fn; | |
1260 if (F->isVarArg()) { | |
1261 DEBUG(dbgs() << ".. gave up (varargs)\n"); | |
1262 return false; | |
1263 } | |
1264 | |
1265 CallingConv::ID CC = F->getCallingConv(); | |
1266 if (CC != CallingConv::C) { | |
1267 DEBUG(dbgs() << ".. gave up (calling convention is not C)\n"); | |
1268 return false; | |
1269 } | |
1270 | |
1271 const ArrayRef<MCPhysReg> GPR32ArgRegs = {Mips::A0, Mips::A1, Mips::A2, | |
1272 Mips::A3}; | |
1273 const ArrayRef<MCPhysReg> FGR32ArgRegs = {Mips::F12, Mips::F14}; | |
1274 const ArrayRef<MCPhysReg> AFGR64ArgRegs = {Mips::D6, Mips::D7}; | |
1275 ArrayRef<MCPhysReg>::iterator NextGPR32 = GPR32ArgRegs.begin(); | |
1276 ArrayRef<MCPhysReg>::iterator NextFGR32 = FGR32ArgRegs.begin(); | |
1277 ArrayRef<MCPhysReg>::iterator NextAFGR64 = AFGR64ArgRegs.begin(); | |
1278 | |
1279 struct AllocatedReg { | |
1280 const TargetRegisterClass *RC; | |
1281 unsigned Reg; | |
1282 AllocatedReg(const TargetRegisterClass *RC, unsigned Reg) | |
1283 : RC(RC), Reg(Reg) {} | |
1284 }; | |
1285 | |
1286 // Only handle simple cases. i.e. All arguments are directly mapped to | |
1287 // registers of the appropriate type. | |
1288 SmallVector<AllocatedReg, 4> Allocation; | |
1289 unsigned Idx = 1; | |
1290 for (const auto &FormalArg : F->args()) { | |
1291 if (F->getAttributes().hasAttribute(Idx, Attribute::InReg) || | |
1292 F->getAttributes().hasAttribute(Idx, Attribute::StructRet) || | |
1293 F->getAttributes().hasAttribute(Idx, Attribute::ByVal)) { | |
1294 DEBUG(dbgs() << ".. gave up (inreg, structret, byval)\n"); | |
1295 return false; | |
1296 } | |
1297 | |
1298 Type *ArgTy = FormalArg.getType(); | |
1299 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) { | |
1300 DEBUG(dbgs() << ".. gave up (struct, array, or vector)\n"); | |
1301 return false; | |
1302 } | |
1303 | |
1304 EVT ArgVT = TLI.getValueType(DL, ArgTy); | |
1305 DEBUG(dbgs() << ".. " << (Idx - 1) << ": " << ArgVT.getEVTString() << "\n"); | |
1306 if (!ArgVT.isSimple()) { | |
1307 DEBUG(dbgs() << ".. .. gave up (not a simple type)\n"); | |
1308 return false; | |
1309 } | |
1310 | |
1311 switch (ArgVT.getSimpleVT().SimpleTy) { | |
1312 case MVT::i1: | |
1313 case MVT::i8: | |
1314 case MVT::i16: | |
1315 if (!F->getAttributes().hasAttribute(Idx, Attribute::SExt) && | |
1316 !F->getAttributes().hasAttribute(Idx, Attribute::ZExt)) { | |
1317 // It must be any extend, this shouldn't happen for clang-generated IR | |
1318 // so just fall back on SelectionDAG. | |
1319 DEBUG(dbgs() << ".. .. gave up (i8/i16 arg is not extended)\n"); | |
1320 return false; | |
1321 } | |
1322 | |
1323 if (NextGPR32 == GPR32ArgRegs.end()) { | |
1324 DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n"); | |
1325 return false; | |
1326 } | |
1327 | |
1328 DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n"); | |
1329 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++); | |
1330 | |
1331 // Allocating any GPR32 prohibits further use of floating point arguments. | |
1332 NextFGR32 = FGR32ArgRegs.end(); | |
1333 NextAFGR64 = AFGR64ArgRegs.end(); | |
1334 break; | |
1335 | |
1336 case MVT::i32: | |
1337 if (F->getAttributes().hasAttribute(Idx, Attribute::ZExt)) { | |
1338 // The O32 ABI does not permit a zero-extended i32. | |
1339 DEBUG(dbgs() << ".. .. gave up (i32 arg is zero extended)\n"); | |
1340 return false; | |
1341 } | |
1342 | |
1343 if (NextGPR32 == GPR32ArgRegs.end()) { | |
1344 DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n"); | |
1345 return false; | |
1346 } | |
1347 | |
1348 DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n"); | |
1349 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++); | |
1350 | |
1351 // Allocating any GPR32 prohibits further use of floating point arguments. | |
1352 NextFGR32 = FGR32ArgRegs.end(); | |
1353 NextAFGR64 = AFGR64ArgRegs.end(); | |
1354 break; | |
1355 | |
1356 case MVT::f32: | |
1357 if (UnsupportedFPMode) { | |
1358 DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n"); | |
1359 return false; | |
1360 } | |
1361 if (NextFGR32 == FGR32ArgRegs.end()) { | |
1362 DEBUG(dbgs() << ".. .. gave up (ran out of FGR32 arguments)\n"); | |
1363 return false; | |
1364 } | |
1365 DEBUG(dbgs() << ".. .. FGR32(" << *NextFGR32 << ")\n"); | |
1366 Allocation.emplace_back(&Mips::FGR32RegClass, *NextFGR32++); | |
1367 // Allocating an FGR32 also allocates the super-register AFGR64, and | |
1368 // ABI rules require us to skip the corresponding GPR32. | |
1369 if (NextGPR32 != GPR32ArgRegs.end()) | |
1370 NextGPR32++; | |
1371 if (NextAFGR64 != AFGR64ArgRegs.end()) | |
1372 NextAFGR64++; | |
1373 break; | |
1374 | |
1375 case MVT::f64: | |
1376 if (UnsupportedFPMode) { | |
1377 DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n"); | |
1378 return false; | |
1379 } | |
1380 if (NextAFGR64 == AFGR64ArgRegs.end()) { | |
1381 DEBUG(dbgs() << ".. .. gave up (ran out of AFGR64 arguments)\n"); | |
1382 return false; | |
1383 } | |
1384 DEBUG(dbgs() << ".. .. AFGR64(" << *NextAFGR64 << ")\n"); | |
1385 Allocation.emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++); | |
1386 // Allocating an FGR32 also allocates the super-register AFGR64, and | |
1387 // ABI rules require us to skip the corresponding GPR32 pair. | |
1388 if (NextGPR32 != GPR32ArgRegs.end()) | |
1389 NextGPR32++; | |
1390 if (NextGPR32 != GPR32ArgRegs.end()) | |
1391 NextGPR32++; | |
1392 if (NextFGR32 != FGR32ArgRegs.end()) | |
1393 NextFGR32++; | |
1394 break; | |
1395 | |
1396 default: | |
1397 DEBUG(dbgs() << ".. .. gave up (unknown type)\n"); | |
1398 return false; | |
1399 } | |
1400 | |
1401 ++Idx; | |
1402 } | |
1403 | |
1404 Idx = 0; | |
1405 for (const auto &FormalArg : F->args()) { | |
1406 unsigned SrcReg = Allocation[Idx].Reg; | |
1407 unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[Idx].RC); | |
1408 // FIXME: Unfortunately it's necessary to emit a copy from the livein copy. | |
1409 // Without this, EmitLiveInCopies may eliminate the livein if its only | |
1410 // use is a bitcast (which isn't turned into an instruction). | |
1411 unsigned ResultReg = createResultReg(Allocation[Idx].RC); | |
1412 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, | |
1413 TII.get(TargetOpcode::COPY), ResultReg) | |
1414 .addReg(DstReg, getKillRegState(true)); | |
1415 updateValueMap(&FormalArg, ResultReg); | |
1416 ++Idx; | |
1417 } | |
1418 | |
1419 // Calculate the size of the incoming arguments area. | |
1420 // We currently reject all the cases where this would be non-zero. | |
1421 unsigned IncomingArgSizeInBytes = 0; | |
1422 | |
1423 // Account for the reserved argument area on ABI's that have one (O32). | |
1424 // It seems strange to do this on the caller side but it's necessary in | |
1425 // SelectionDAG's implementation. | |
1426 IncomingArgSizeInBytes = std::min(getABI().GetCalleeAllocdArgSizeInBytes(CC), | |
1427 IncomingArgSizeInBytes); | |
1428 | |
1429 MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes, | |
1430 false); | |
1431 | |
1432 return true; | |
1433 } | |
1434 | |
1239 bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) { | 1435 bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) { |
1240 if (!TargetSupported) | |
1241 return false; | |
1242 | |
1243 CallingConv::ID CC = CLI.CallConv; | 1436 CallingConv::ID CC = CLI.CallConv; |
1244 bool IsTailCall = CLI.IsTailCall; | 1437 bool IsTailCall = CLI.IsTailCall; |
1245 bool IsVarArg = CLI.IsVarArg; | 1438 bool IsVarArg = CLI.IsVarArg; |
1246 const Value *Callee = CLI.Callee; | 1439 const Value *Callee = CLI.Callee; |
1247 MCSymbol *Symbol = CLI.Symbol; | 1440 MCSymbol *Symbol = CLI.Symbol; |
1322 // Finish off the call including any return values. | 1515 // Finish off the call including any return values. |
1323 return finishCall(CLI, RetVT, NumBytes); | 1516 return finishCall(CLI, RetVT, NumBytes); |
1324 } | 1517 } |
1325 | 1518 |
1326 bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) { | 1519 bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) { |
1327 if (!TargetSupported) | |
1328 return false; | |
1329 | |
1330 switch (II->getIntrinsicID()) { | 1520 switch (II->getIntrinsicID()) { |
1331 default: | 1521 default: |
1332 return false; | 1522 return false; |
1333 case Intrinsic::bswap: { | 1523 case Intrinsic::bswap: { |
1334 Type *RetTy = II->getCalledFunction()->getReturnType(); | 1524 Type *RetTy = II->getCalledFunction()->getReturnType(); |
1420 | 1610 |
1421 bool MipsFastISel::selectRet(const Instruction *I) { | 1611 bool MipsFastISel::selectRet(const Instruction *I) { |
1422 const Function &F = *I->getParent()->getParent(); | 1612 const Function &F = *I->getParent()->getParent(); |
1423 const ReturnInst *Ret = cast<ReturnInst>(I); | 1613 const ReturnInst *Ret = cast<ReturnInst>(I); |
1424 | 1614 |
1615 DEBUG(dbgs() << "selectRet\n"); | |
1616 | |
1425 if (!FuncInfo.CanLowerReturn) | 1617 if (!FuncInfo.CanLowerReturn) |
1426 return false; | 1618 return false; |
1427 | 1619 |
1428 // Build a list of return value registers. | 1620 // Build a list of return value registers. |
1429 SmallVector<unsigned, 4> RetRegs; | 1621 SmallVector<unsigned, 4> RetRegs; |
1479 return false; | 1671 return false; |
1480 | 1672 |
1481 MVT RVVT = RVEVT.getSimpleVT(); | 1673 MVT RVVT = RVEVT.getSimpleVT(); |
1482 if (RVVT == MVT::f128) | 1674 if (RVVT == MVT::f128) |
1483 return false; | 1675 return false; |
1676 | |
1677 // Do not handle FGR64 returns for now. | |
1678 if (RVVT == MVT::f64 && UnsupportedFPMode) { | |
1679 DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode\n"); | |
1680 return false; | |
1681 } | |
1484 | 1682 |
1485 MVT DestVT = VA.getValVT(); | 1683 MVT DestVT = VA.getValVT(); |
1486 // Special handling for extended integers. | 1684 // Special handling for extended integers. |
1487 if (RVVT != DestVT) { | 1685 if (RVVT != DestVT) { |
1488 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16) | 1686 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16) |
1763 updateValueMap(I, ResultReg); | 1961 updateValueMap(I, ResultReg); |
1764 return true; | 1962 return true; |
1765 } | 1963 } |
1766 | 1964 |
1767 bool MipsFastISel::fastSelectInstruction(const Instruction *I) { | 1965 bool MipsFastISel::fastSelectInstruction(const Instruction *I) { |
1768 if (!TargetSupported) | |
1769 return false; | |
1770 switch (I->getOpcode()) { | 1966 switch (I->getOpcode()) { |
1771 default: | 1967 default: |
1772 break; | 1968 break; |
1773 case Instruction::Load: | 1969 case Instruction::Load: |
1774 return selectLoad(I); | 1970 return selectLoad(I); |