OLD | NEW |
1 // | 1 // |
2 // The Subzero Code Generator | 2 // The Subzero Code Generator |
3 // | 3 // |
4 // This file is distributed under the University of Illinois Open Source | 4 // This file is distributed under the University of Illinois Open Source |
5 // License. See LICENSE.TXT for details. | 5 // License. See LICENSE.TXT for details. |
6 // | 6 // |
7 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
8 /// | 8 /// |
9 /// \file | 9 /// \file |
10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost | 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 } | 212 } |
213 } | 213 } |
214 | 214 |
215 uint32_t TargetMIPS32::getStackAlignment() const { | 215 uint32_t TargetMIPS32::getStackAlignment() const { |
216 return MIPS32_STACK_ALIGNMENT_BYTES; | 216 return MIPS32_STACK_ALIGNMENT_BYTES; |
217 } | 217 } |
218 | 218 |
219 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { | 219 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { |
220 constexpr bool NoTailCall = false; | 220 constexpr bool NoTailCall = false; |
221 constexpr bool IsTargetHelperCall = true; | 221 constexpr bool IsTargetHelperCall = true; |
| 222 Variable *Dest = Instr->getDest(); |
| 223 const Type DestTy = Dest ? Dest->getType() : IceType_void; |
222 | 224 |
223 switch (Instr->getKind()) { | 225 switch (Instr->getKind()) { |
224 default: | 226 default: |
225 return; | 227 return; |
| 228 case Inst::Select: { |
| 229 if (isVectorType(DestTy)) { |
| 230 Operand *SrcT = llvm::cast<InstSelect>(Instr)->getTrueOperand(); |
| 231 Operand *SrcF = llvm::cast<InstSelect>(Instr)->getFalseOperand(); |
| 232 Operand *Cond = llvm::cast<InstSelect>(Instr)->getCondition(); |
| 233 Variable *T = Func->makeVariable(DestTy); |
| 234 auto *Undef = ConstantUndef::create(Ctx, DestTy); |
| 235 Context.insert<InstAssign>(T, Undef); |
| 236 auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T); |
| 237 VarVecOn32->initVecElement(Func); |
| 238 for (SizeT I = 0; I < typeNumElements(DestTy); ++I) { |
| 239 auto *Index = Ctx->getConstantInt32(I); |
| 240 auto *OpC = Func->makeVariable(typeElementType(Cond->getType())); |
| 241 Context.insert<InstExtractElement>(OpC, Cond, Index); |
| 242 auto *OpT = Func->makeVariable(typeElementType(DestTy)); |
| 243 Context.insert<InstExtractElement>(OpT, SrcT, Index); |
| 244 auto *OpF = Func->makeVariable(typeElementType(DestTy)); |
| 245 Context.insert<InstExtractElement>(OpF, SrcF, Index); |
| 246 auto *Dst = Func->makeVariable(typeElementType(DestTy)); |
| 247 Variable *DestT = Func->makeVariable(DestTy); |
| 248 Context.insert<InstSelect>(Dst, OpC, OpT, OpF); |
| 249 Context.insert<InstInsertElement>(DestT, T, Dst, Index); |
| 250 T = DestT; |
| 251 } |
| 252 Context.insert<InstAssign>(Dest, T); |
| 253 Instr->setDeleted(); |
| 254 } |
| 255 return; |
| 256 } |
| 257 case Inst::Fcmp: { |
| 258 if (isVectorType(DestTy)) { |
| 259 InstFcmp::FCond Cond = llvm::cast<InstFcmp>(Instr)->getCondition(); |
| 260 Operand *Src0 = Instr->getSrc(0); |
| 261 Operand *Src1 = Instr->getSrc(1); |
| 262 Variable *T = Func->makeVariable(IceType_v4f32); |
| 263 auto *Undef = ConstantUndef::create(Ctx, IceType_v4f32); |
| 264 Context.insert<InstAssign>(T, Undef); |
| 265 auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T); |
| 266 VarVecOn32->initVecElement(Func); |
| 267 for (SizeT I = 0; I < typeNumElements(IceType_v4f32); ++I) { |
| 268 auto *Index = Ctx->getConstantInt32(I); |
| 269 auto *Op0 = Func->makeVariable(IceType_f32); |
| 270 Context.insert<InstExtractElement>(Op0, Src0, Index); |
| 271 auto *Op1 = Func->makeVariable(IceType_f32); |
| 272 Context.insert<InstExtractElement>(Op1, Src1, Index); |
| 273 auto *Dst = Func->makeVariable(IceType_f32); |
| 274 Variable *DestT = Func->makeVariable(IceType_v4f32); |
| 275 Context.insert<InstFcmp>(Cond, Dst, Op0, Op1); |
| 276 Context.insert<InstInsertElement>(DestT, T, Dst, Index); |
| 277 T = DestT; |
| 278 } |
| 279 Context.insert<InstAssign>(Dest, T); |
| 280 Instr->setDeleted(); |
| 281 } |
| 282 return; |
| 283 } |
| 284 case Inst::Icmp: { |
| 285 if (isVectorType(DestTy)) { |
| 286 InstIcmp::ICond Cond = llvm::cast<InstIcmp>(Instr)->getCondition(); |
| 287 Operand *Src0 = Instr->getSrc(0); |
| 288 Operand *Src1 = Instr->getSrc(1); |
| 289 const Type SrcType = Src0->getType(); |
| 290 Variable *T = Func->makeVariable(DestTy); |
| 291 auto *Undef = ConstantUndef::create(Ctx, DestTy); |
| 292 Context.insert<InstAssign>(T, Undef); |
| 293 auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T); |
| 294 VarVecOn32->initVecElement(Func); |
| 295 for (SizeT I = 0; I < typeNumElements(SrcType); ++I) { |
| 296 auto *Index = Ctx->getConstantInt32(I); |
| 297 auto *Op0 = Func->makeVariable(typeElementType(SrcType)); |
| 298 Context.insert<InstExtractElement>(Op0, Src0, Index); |
| 299 auto *Op1 = Func->makeVariable(typeElementType(SrcType)); |
| 300 Context.insert<InstExtractElement>(Op1, Src1, Index); |
| 301 auto *Dst = Func->makeVariable(typeElementType(DestTy)); |
| 302 Variable *DestT = Func->makeVariable(DestTy); |
| 303 Context.insert<InstIcmp>(Cond, Dst, Op0, Op1); |
| 304 Context.insert<InstInsertElement>(DestT, T, Dst, Index); |
| 305 T = DestT; |
| 306 } |
| 307 Context.insert<InstAssign>(Dest, T); |
| 308 Instr->setDeleted(); |
| 309 } |
| 310 return; |
| 311 } |
226 case Inst::Arithmetic: { | 312 case Inst::Arithmetic: { |
227 Variable *Dest = Instr->getDest(); | |
228 const Type DestTy = Dest->getType(); | |
229 const InstArithmetic::OpKind Op = | 313 const InstArithmetic::OpKind Op = |
230 llvm::cast<InstArithmetic>(Instr)->getOp(); | 314 llvm::cast<InstArithmetic>(Instr)->getOp(); |
231 if (isVectorType(DestTy)) { | 315 if (isVectorType(DestTy)) { |
232 scalarizeArithmetic(Op, Dest, Instr->getSrc(0), Instr->getSrc(1)); | 316 scalarizeArithmetic(Op, Dest, Instr->getSrc(0), Instr->getSrc(1)); |
233 Instr->setDeleted(); | 317 Instr->setDeleted(); |
234 return; | 318 return; |
235 } | 319 } |
236 switch (DestTy) { | 320 switch (DestTy) { |
237 default: | 321 default: |
238 return; | 322 return; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 NoTailCall, IsTargetHelperCall); | 365 NoTailCall, IsTargetHelperCall); |
282 Call->addArg(Instr->getSrc(0)); | 366 Call->addArg(Instr->getSrc(0)); |
283 Call->addArg(Instr->getSrc(1)); | 367 Call->addArg(Instr->getSrc(1)); |
284 Instr->setDeleted(); | 368 Instr->setDeleted(); |
285 return; | 369 return; |
286 } | 370 } |
287 } | 371 } |
288 llvm::report_fatal_error("Control flow should never have reached here."); | 372 llvm::report_fatal_error("Control flow should never have reached here."); |
289 } | 373 } |
290 case Inst::Cast: { | 374 case Inst::Cast: { |
291 Variable *Dest = Instr->getDest(); | |
292 Operand *Src0 = Instr->getSrc(0); | 375 Operand *Src0 = Instr->getSrc(0); |
293 const Type DestTy = Dest->getType(); | |
294 const Type SrcTy = Src0->getType(); | 376 const Type SrcTy = Src0->getType(); |
295 auto *CastInstr = llvm::cast<InstCast>(Instr); | 377 auto *CastInstr = llvm::cast<InstCast>(Instr); |
296 const InstCast::OpKind CastKind = CastInstr->getCastKind(); | 378 const InstCast::OpKind CastKind = CastInstr->getCastKind(); |
| 379 |
| 380 if (isVectorType(DestTy)) { |
| 381 Variable *T = Func->makeVariable(DestTy); |
| 382 auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T); |
| 383 VarVecOn32->initVecElement(Func); |
| 384 auto *Undef = ConstantUndef::create(Ctx, DestTy); |
| 385 Context.insert<InstAssign>(T, Undef); |
| 386 for (SizeT I = 0; I < typeNumElements(DestTy); ++I) { |
| 387 auto *Index = Ctx->getConstantInt32(I); |
| 388 auto *Op = Func->makeVariable(typeElementType(SrcTy)); |
| 389 Context.insert<InstExtractElement>(Op, Src0, Index); |
| 390 auto *Dst = Func->makeVariable(typeElementType(DestTy)); |
| 391 Variable *DestT = Func->makeVariable(DestTy); |
| 392 Context.insert<InstCast>(CastKind, Dst, Op); |
| 393 Context.insert<InstInsertElement>(DestT, T, Dst, Index); |
| 394 T = DestT; |
| 395 } |
| 396 Context.insert<InstAssign>(Dest, T); |
| 397 Instr->setDeleted(); |
| 398 return; |
| 399 } |
| 400 |
297 switch (CastKind) { | 401 switch (CastKind) { |
298 default: | 402 default: |
299 return; | 403 return; |
300 case InstCast::Fptosi: | 404 case InstCast::Fptosi: |
301 case InstCast::Fptoui: { | 405 case InstCast::Fptoui: { |
302 if ((DestTy != IceType_i32) && (DestTy != IceType_i64)) { | 406 if ((DestTy != IceType_i32) && (DestTy != IceType_i64)) { |
303 return; | 407 return; |
304 } | 408 } |
305 const bool DestIs32 = DestTy == IceType_i32; | 409 const bool DestIs32 = DestTy == IceType_i32; |
306 const bool DestIsSigned = CastKind == InstCast::Fptosi; | 410 const bool DestIsSigned = CastKind == InstCast::Fptosi; |
(...skipping 19 matching lines...) Expand all Loading... |
326 Instr->setDeleted(); | 430 Instr->setDeleted(); |
327 return; | 431 return; |
328 } | 432 } |
329 case InstCast::Sitofp: | 433 case InstCast::Sitofp: |
330 case InstCast::Uitofp: { | 434 case InstCast::Uitofp: { |
331 if ((SrcTy != IceType_i32) && (SrcTy != IceType_i64)) { | 435 if ((SrcTy != IceType_i32) && (SrcTy != IceType_i64)) { |
332 return; | 436 return; |
333 } | 437 } |
334 const bool SourceIs32 = SrcTy == IceType_i32; | 438 const bool SourceIs32 = SrcTy == IceType_i32; |
335 const bool SourceIsSigned = CastKind == InstCast::Sitofp; | 439 const bool SourceIsSigned = CastKind == InstCast::Sitofp; |
336 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); | 440 const bool DestIsF32 = isFloat32Asserting32Or64(DestTy); |
337 RuntimeHelper RTHFunc = RuntimeHelper::H_Num; | 441 RuntimeHelper RTHFunc = RuntimeHelper::H_Num; |
338 if (SourceIsSigned) { | 442 if (SourceIsSigned) { |
339 if (SourceIs32) { | 443 if (SourceIs32) { |
340 return; | 444 return; |
341 } | 445 } |
342 RTHFunc = DestIsF32 ? RuntimeHelper::H_sitofp_i64_f32 | 446 RTHFunc = DestIsF32 ? RuntimeHelper::H_sitofp_i64_f32 |
343 : RuntimeHelper::H_sitofp_i64_f64; | 447 : RuntimeHelper::H_sitofp_i64_f64; |
344 } else { | 448 } else { |
345 RTHFunc = DestIsF32 ? (SourceIs32 ? RuntimeHelper::H_uitofp_i32_f32 | 449 RTHFunc = DestIsF32 ? (SourceIs32 ? RuntimeHelper::H_uitofp_i32_f32 |
346 : RuntimeHelper::H_uitofp_i64_f32) | 450 : RuntimeHelper::H_uitofp_i64_f32) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); | 494 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); |
391 Src0 = Src0AsI32; | 495 Src0 = Src0AsI32; |
392 } break; | 496 } break; |
393 } | 497 } |
394 constexpr SizeT MaxSrcs = 1; | 498 constexpr SizeT MaxSrcs = 1; |
395 InstCall *Call = makeHelperCall(HelperID, CallDest, MaxSrcs); | 499 InstCall *Call = makeHelperCall(HelperID, CallDest, MaxSrcs); |
396 Call->addArg(Src0); | 500 Call->addArg(Src0); |
397 Context.insert(Call); | 501 Context.insert(Call); |
398 // The PNaCl ABI disallows i8/i16 return types, so truncate the helper | 502 // The PNaCl ABI disallows i8/i16 return types, so truncate the helper |
399 // call result to the appropriate type as necessary. | 503 // call result to the appropriate type as necessary. |
400 if (CallDest->getType() != Dest->getType()) | 504 if (CallDest->getType() != DestTy) |
401 Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest); | 505 Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest); |
402 Instr->setDeleted(); | 506 Instr->setDeleted(); |
403 return; | 507 return; |
404 } | 508 } |
405 case InstCast::Trunc: { | 509 case InstCast::Trunc: { |
406 if (DestTy == SrcTy) { | 510 if (DestTy == SrcTy) { |
407 return; | 511 return; |
408 } | 512 } |
409 if (!isVectorType(SrcTy)) { | 513 if (!isVectorType(SrcTy)) { |
410 return; | 514 return; |
(...skipping 13 matching lines...) Expand all Loading... |
424 } | 528 } |
425 assert(typeNumElements(DestTy) == typeNumElements(SrcTy)); | 529 assert(typeNumElements(DestTy) == typeNumElements(SrcTy)); |
426 assert(typeElementType(SrcTy) == IceType_i1); | 530 assert(typeElementType(SrcTy) == IceType_i1); |
427 assert(isVectorIntegerType(DestTy)); | 531 assert(isVectorIntegerType(DestTy)); |
428 return; | 532 return; |
429 } | 533 } |
430 } | 534 } |
431 llvm::report_fatal_error("Control flow should never have reached here."); | 535 llvm::report_fatal_error("Control flow should never have reached here."); |
432 } | 536 } |
433 case Inst::IntrinsicCall: { | 537 case Inst::IntrinsicCall: { |
434 Variable *Dest = Instr->getDest(); | |
435 auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr); | 538 auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr); |
436 Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID; | 539 Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID; |
437 if (Dest && isVectorType(Dest->getType()) && ID == Intrinsics::Fabs) { | 540 if (isVectorType(DestTy) && ID == Intrinsics::Fabs) { |
438 Operand *Src0 = IntrinsicCall->getArg(0); | 541 Operand *Src0 = IntrinsicCall->getArg(0); |
439 GlobalString FabsFloat = Ctx->getGlobalString("llvm.fabs.f32"); | 542 GlobalString FabsFloat = Ctx->getGlobalString("llvm.fabs.f32"); |
440 Operand *CallTarget = Ctx->getConstantExternSym(FabsFloat); | 543 Operand *CallTarget = Ctx->getConstantExternSym(FabsFloat); |
441 GlobalString FabsVec = Ctx->getGlobalString("llvm.fabs.v4f32"); | 544 GlobalString FabsVec = Ctx->getGlobalString("llvm.fabs.v4f32"); |
442 bool BadIntrinsic = false; | 545 bool BadIntrinsic = false; |
443 const Intrinsics::FullIntrinsicInfo *FullInfo = | 546 const Intrinsics::FullIntrinsicInfo *FullInfo = |
444 Ctx->getIntrinsicsInfo().find(FabsVec, BadIntrinsic); | 547 Ctx->getIntrinsicsInfo().find(FabsVec, BadIntrinsic); |
445 Intrinsics::IntrinsicInfo Info = FullInfo->Info; | 548 Intrinsics::IntrinsicInfo Info = FullInfo->Info; |
446 | 549 |
447 Variable *T = Func->makeVariable(IceType_v4f32); | 550 Variable *T = Func->makeVariable(IceType_v4f32); |
448 auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); | 551 auto *Undef = ConstantUndef::create(Ctx, IceType_v4f32); |
| 552 Context.insert<InstAssign>(T, Undef); |
| 553 auto *VarVecOn32 = llvm::cast<VariableVecOn32>(T); |
449 VarVecOn32->initVecElement(Func); | 554 VarVecOn32->initVecElement(Func); |
450 Context.insert<InstFakeDef>(T); | |
451 | 555 |
452 for (SizeT i = 0; i < VarVecOn32->ElementsPerContainer; ++i) { | 556 for (SizeT i = 0; i < typeNumElements(IceType_v4f32); ++i) { |
453 auto *Index = Ctx->getConstantInt32(i); | 557 auto *Index = Ctx->getConstantInt32(i); |
454 auto *Op = Func->makeVariable(IceType_f32); | 558 auto *Op = Func->makeVariable(IceType_f32); |
455 Context.insert<InstExtractElement>(Op, Src0, Index); | 559 Context.insert<InstExtractElement>(Op, Src0, Index); |
456 auto *Res = Func->makeVariable(IceType_f32); | 560 auto *Res = Func->makeVariable(IceType_f32); |
457 Variable *DestT = Func->makeVariable(IceType_v4f32); | 561 Variable *DestT = Func->makeVariable(IceType_v4f32); |
458 auto *Call = | 562 auto *Call = |
459 Context.insert<InstIntrinsicCall>(1, Res, CallTarget, Info); | 563 Context.insert<InstIntrinsicCall>(1, Res, CallTarget, Info); |
460 Call->addArg(Op); | 564 Call->addArg(Op); |
461 Context.insert<InstInsertElement>(DestT, T, Res, Index); | 565 Context.insert<InstInsertElement>(DestT, T, Res, Index); |
462 T = DestT; | 566 T = DestT; |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 TargetMIPS32::CallingConv CC; | 1176 TargetMIPS32::CallingConv CC; |
1073 | 1177 |
1074 // For each register argument, replace Arg in the argument list with the home | 1178 // For each register argument, replace Arg in the argument list with the home |
1075 // register. Then generate an instruction in the prolog to copy the home | 1179 // register. Then generate an instruction in the prolog to copy the home |
1076 // register to the assigned location of Arg. | 1180 // register to the assigned location of Arg. |
1077 Context.init(Func->getEntryNode()); | 1181 Context.init(Func->getEntryNode()); |
1078 Context.setInsertPoint(Context.getCur()); | 1182 Context.setInsertPoint(Context.getCur()); |
1079 | 1183 |
1080 // v4f32 is returned through stack. $4 is setup by the caller and passed as | 1184 // v4f32 is returned through stack. $4 is setup by the caller and passed as |
1081 // first argument implicitly. Callee then copies the return vector at $4. | 1185 // first argument implicitly. Callee then copies the return vector at $4. |
| 1186 Variable *ImplicitRetVec = nullptr; |
1082 if (isVectorFloatingType(Func->getReturnType())) { | 1187 if (isVectorFloatingType(Func->getReturnType())) { |
1083 Variable *ImplicitRetVec = Func->makeVariable(IceType_i32); | 1188 ImplicitRetVec = Func->makeVariable(IceType_i32); |
1084 ImplicitRetVec->setName(Func, "ImplicitRet_v4f32"); | 1189 ImplicitRetVec->setName(Func, "ImplicitRet_v4f32"); |
1085 ImplicitRetVec->setIsArg(); | 1190 ImplicitRetVec->setIsArg(); |
1086 Args.insert(Args.begin(), ImplicitRetVec); | 1191 Args.insert(Args.begin(), ImplicitRetVec); |
1087 setImplicitRet(ImplicitRetVec); | 1192 setImplicitRet(ImplicitRetVec); |
1088 Context.insert<InstFakeDef>(ImplicitRetVec); | |
1089 for (CfgNode *Node : Func->getNodes()) { | |
1090 for (Inst &Instr : Node->getInsts()) { | |
1091 if (llvm::isa<InstRet>(&Instr)) { | |
1092 Context.setInsertPoint(Instr); | |
1093 Context.insert<InstFakeUse>(ImplicitRetVec); | |
1094 break; | |
1095 } | |
1096 } | |
1097 } | |
1098 Context.setInsertPoint(Context.getCur()); | |
1099 } | 1193 } |
1100 | 1194 |
1101 for (SizeT i = 0, E = Args.size(); i < E; ++i) { | 1195 for (SizeT i = 0, E = Args.size(); i < E; ++i) { |
1102 Variable *Arg = Args[i]; | 1196 Variable *Arg = Args[i]; |
1103 Type Ty = Arg->getType(); | 1197 Type Ty = Arg->getType(); |
1104 RegNumT RegNum; | 1198 RegNumT RegNum; |
1105 if (!CC.argInReg(Ty, i, &RegNum)) { | 1199 if (!CC.argInReg(Ty, i, &RegNum)) { |
1106 continue; | 1200 continue; |
1107 } | 1201 } |
1108 Variable *RegisterArg = Func->makeVariable(Ty); | 1202 Variable *RegisterArg = Func->makeVariable(Ty); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 RegisterArg64->initHiLo(Func); | 1236 RegisterArg64->initHiLo(Func); |
1143 RegisterArg64->getLo()->setRegNum( | 1237 RegisterArg64->getLo()->setRegNum( |
1144 RegNumT::fixme(RegMIPS32::get64PairFirstRegNum(RegNum))); | 1238 RegNumT::fixme(RegMIPS32::get64PairFirstRegNum(RegNum))); |
1145 RegisterArg64->getHi()->setRegNum( | 1239 RegisterArg64->getHi()->setRegNum( |
1146 RegNumT::fixme(RegMIPS32::get64PairSecondRegNum(RegNum))); | 1240 RegNumT::fixme(RegMIPS32::get64PairSecondRegNum(RegNum))); |
1147 } break; | 1241 } break; |
1148 } | 1242 } |
1149 } | 1243 } |
1150 Context.insert<InstAssign>(Arg, RegisterArg); | 1244 Context.insert<InstAssign>(Arg, RegisterArg); |
1151 } | 1245 } |
| 1246 |
| 1247 // Insert fake use of ImplicitRet_v4f32 to keep it live |
| 1248 if (ImplicitRetVec) { |
| 1249 for (CfgNode *Node : Func->getNodes()) { |
| 1250 for (Inst &Instr : Node->getInsts()) { |
| 1251 if (llvm::isa<InstRet>(&Instr)) { |
| 1252 Context.setInsertPoint(Instr); |
| 1253 Context.insert<InstFakeUse>(ImplicitRetVec); |
| 1254 break; |
| 1255 } |
| 1256 } |
| 1257 } |
| 1258 } |
1152 } | 1259 } |
1153 | 1260 |
1154 Type TargetMIPS32::stackSlotType() { return IceType_i32; } | 1261 Type TargetMIPS32::stackSlotType() { return IceType_i32; } |
1155 | 1262 |
1156 // Helper function for addProlog(). | 1263 // Helper function for addProlog(). |
1157 // | 1264 // |
1158 // This assumes Arg is an argument passed on the stack. This sets the frame | 1265 // This assumes Arg is an argument passed on the stack. This sets the frame |
1159 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an | 1266 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an |
1160 // I64 arg that has been split into Lo and Hi components, it calls itself | 1267 // I64 arg that has been split into Lo and Hi components, it calls itself |
1161 // recursively on the components, taking care to handle Lo first because of the | 1268 // recursively on the components, taking care to handle Lo first because of the |
(...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2240 // legalization into new variables, otherwise Om1 register allocation may fail | 2347 // legalization into new variables, otherwise Om1 register allocation may fail |
2241 // when it sees variables that are defined but not used. | 2348 // when it sees variables that are defined but not used. |
2242 Type DestTy = Dest->getType(); | 2349 Type DestTy = Dest->getType(); |
2243 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); | 2350 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); |
2244 Operand *Src1 = legalizeUndef(Instr->getSrc(1)); | 2351 Operand *Src1 = legalizeUndef(Instr->getSrc(1)); |
2245 if (DestTy == IceType_i64) { | 2352 if (DestTy == IceType_i64) { |
2246 lowerInt64Arithmetic(Instr, Instr->getDest(), Src0, Src1); | 2353 lowerInt64Arithmetic(Instr, Instr->getDest(), Src0, Src1); |
2247 return; | 2354 return; |
2248 } | 2355 } |
2249 if (isVectorType(Dest->getType())) { | 2356 if (isVectorType(Dest->getType())) { |
2250 UnimplementedLoweringError(this, Instr); | 2357 llvm::report_fatal_error("Arithmetic: Destination type is vector"); |
2251 return; | 2358 return; |
2252 } | 2359 } |
2253 | 2360 |
2254 Variable *T = makeReg(Dest->getType()); | 2361 Variable *T = makeReg(Dest->getType()); |
2255 Variable *Src0R = legalizeToReg(Src0); | 2362 Variable *Src0R = legalizeToReg(Src0); |
2256 Variable *Src1R = legalizeToReg(Src1); | 2363 Variable *Src1R = legalizeToReg(Src1); |
2257 constexpr uint32_t DivideByZeroTrapCode = 7; | 2364 constexpr uint32_t DivideByZeroTrapCode = 7; |
2258 | 2365 |
2259 switch (Instr->getOp()) { | 2366 switch (Instr->getOp()) { |
2260 case InstArithmetic::_num: | 2367 case InstArithmetic::_num: |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2388 } | 2495 } |
2389 | 2496 |
2390 void TargetMIPS32::lowerAssign(const InstAssign *Instr) { | 2497 void TargetMIPS32::lowerAssign(const InstAssign *Instr) { |
2391 Variable *Dest = Instr->getDest(); | 2498 Variable *Dest = Instr->getDest(); |
2392 | 2499 |
2393 if (Dest->isRematerializable()) { | 2500 if (Dest->isRematerializable()) { |
2394 Context.insert<InstFakeDef>(Dest); | 2501 Context.insert<InstFakeDef>(Dest); |
2395 return; | 2502 return; |
2396 } | 2503 } |
2397 | 2504 |
| 2505 // Source type may not be same as destination |
| 2506 if (isVectorType(Dest->getType())) { |
| 2507 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); |
| 2508 auto *DstVec = llvm::dyn_cast<VariableVecOn32>(Dest); |
| 2509 for (SizeT i = 0; i < DstVec->ContainersPerVector; ++i) { |
| 2510 auto *DCont = DstVec->getContainers()[i]; |
| 2511 auto *SCont = |
| 2512 legalize(getOperandAtIndex(Src0, IceType_i32, i), Legal_Reg); |
| 2513 auto *TReg = makeReg(IceType_i32); |
| 2514 _mov(TReg, SCont); |
| 2515 _mov(DCont, TReg); |
| 2516 } |
| 2517 return; |
| 2518 } |
2398 Operand *Src0 = Instr->getSrc(0); | 2519 Operand *Src0 = Instr->getSrc(0); |
2399 assert(Dest->getType() == Src0->getType()); | 2520 assert(Dest->getType() == Src0->getType()); |
2400 if (Dest->getType() == IceType_i64) { | 2521 if (Dest->getType() == IceType_i64) { |
2401 Src0 = legalizeUndef(Src0); | 2522 Src0 = legalizeUndef(Src0); |
2402 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); | 2523 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); |
2403 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); | 2524 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); |
2404 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 2525 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
2405 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 2526 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
2406 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); | 2527 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); |
2407 _mov(T_Lo, Src0Lo); | 2528 _mov(T_Lo, Src0Lo); |
2408 _mov(DestLo, T_Lo); | 2529 _mov(DestLo, T_Lo); |
2409 _mov(T_Hi, Src0Hi); | 2530 _mov(T_Hi, Src0Hi); |
2410 _mov(DestHi, T_Hi); | 2531 _mov(DestHi, T_Hi); |
2411 return; | 2532 return; |
2412 } | 2533 } |
2413 if (isVectorType(Dest->getType())) { | |
2414 auto *DstVec = llvm::dyn_cast<VariableVecOn32>(Dest); | |
2415 for (SizeT i = 0; i < DstVec->ElementsPerContainer; ++i) { | |
2416 auto *DCont = DstVec->getContainers()[i]; | |
2417 auto *SCont = | |
2418 legalize(getOperandAtIndex(Src0, IceType_i32, i), Legal_Reg); | |
2419 auto *TReg = makeReg(IceType_i32); | |
2420 _mov(TReg, SCont); | |
2421 _mov(DCont, TReg); | |
2422 } | |
2423 return; | |
2424 } | |
2425 Operand *SrcR; | 2534 Operand *SrcR; |
2426 if (Dest->hasReg()) { | 2535 if (Dest->hasReg()) { |
2427 // If Dest already has a physical register, then legalize the Src operand | 2536 // If Dest already has a physical register, then legalize the Src operand |
2428 // into a Variable with the same register assignment. This especially | 2537 // into a Variable with the same register assignment. This especially |
2429 // helps allow the use of Flex operands. | 2538 // helps allow the use of Flex operands. |
2430 SrcR = legalize(Src0, Legal_Reg, Dest->getRegNum()); | 2539 SrcR = legalize(Src0, Legal_Reg, Dest->getRegNum()); |
2431 } else { | 2540 } else { |
2432 // Dest could be a stack operand. Since we could potentially need | 2541 // Dest could be a stack operand. Since we could potentially need |
2433 // to do a Store (and store can only have Register operands), | 2542 // to do a Store (and store can only have Register operands), |
2434 // legalize this to a register. | 2543 // legalize this to a register. |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2823 break; | 2932 break; |
2824 case IceType_v4i1: | 2933 case IceType_v4i1: |
2825 case IceType_v8i1: | 2934 case IceType_v8i1: |
2826 case IceType_v16i1: | 2935 case IceType_v16i1: |
2827 case IceType_v16i8: | 2936 case IceType_v16i8: |
2828 case IceType_v8i16: | 2937 case IceType_v8i16: |
2829 case IceType_v4i32: { | 2938 case IceType_v4i32: { |
2830 ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0); | 2939 ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0); |
2831 auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg); | 2940 auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg); |
2832 RetVec->initVecElement(Func); | 2941 RetVec->initVecElement(Func); |
2833 for (SizeT i = 0; i < RetVec->ElementsPerContainer; ++i) { | 2942 for (SizeT i = 0; i < RetVec->ContainersPerVector; ++i) { |
2834 auto *Var = RetVec->getContainers()[i]; | 2943 auto *Var = RetVec->getContainers()[i]; |
2835 Var->setRegNum(RegNumT::fixme(RegMIPS32::Reg_V0 + i)); | 2944 Var->setRegNum(RegNumT::fixme(RegMIPS32::Reg_V0 + i)); |
2836 } | 2945 } |
2837 break; | 2946 break; |
2838 } | 2947 } |
2839 case IceType_v4f32: | 2948 case IceType_v4f32: |
2840 ReturnReg = makeReg(IceType_i32, RegMIPS32::Reg_V0); | 2949 ReturnReg = makeReg(IceType_i32, RegMIPS32::Reg_V0); |
2841 break; | 2950 break; |
2842 } | 2951 } |
2843 } | 2952 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2914 } | 3023 } |
2915 } | 3024 } |
2916 | 3025 |
2917 if (Dest == nullptr) | 3026 if (Dest == nullptr) |
2918 return; | 3027 return; |
2919 | 3028 |
2920 // Assign the result of the call to Dest. | 3029 // Assign the result of the call to Dest. |
2921 if (ReturnReg) { | 3030 if (ReturnReg) { |
2922 if (RetVecFloat) { | 3031 if (RetVecFloat) { |
2923 auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); | 3032 auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); |
2924 for (SizeT i = 0; i < DestVecOn32->ElementsPerContainer; ++i) { | 3033 for (SizeT i = 0; i < DestVecOn32->ContainersPerVector; ++i) { |
2925 auto *Var = DestVecOn32->getContainers()[i]; | 3034 auto *Var = DestVecOn32->getContainers()[i]; |
2926 OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( | 3035 OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( |
2927 Func, IceType_i32, RetVecFloat, | 3036 Func, IceType_i32, RetVecFloat, |
2928 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4))); | 3037 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4))); |
2929 _lw(Var, Mem); | 3038 _lw(Var, Mem); |
2930 } | 3039 } |
2931 } else if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) { | 3040 } else if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) { |
2932 auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); | 3041 auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); |
2933 for (SizeT i = 0; i < DestVecOn32->ElementsPerContainer; ++i) { | 3042 for (SizeT i = 0; i < DestVecOn32->ContainersPerVector; ++i) { |
2934 _mov(DestVecOn32->getContainers()[i], RetVec->getContainers()[i]); | 3043 _mov(DestVecOn32->getContainers()[i], RetVec->getContainers()[i]); |
2935 } | 3044 } |
2936 } else if (ReturnRegHi) { | 3045 } else if (ReturnRegHi) { |
2937 assert(Dest->getType() == IceType_i64); | 3046 assert(Dest->getType() == IceType_i64); |
2938 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); | 3047 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); |
2939 Variable *DestLo = Dest64On32->getLo(); | 3048 Variable *DestLo = Dest64On32->getLo(); |
2940 Variable *DestHi = Dest64On32->getHi(); | 3049 Variable *DestHi = Dest64On32->getHi(); |
2941 _mov(DestLo, ReturnReg); | 3050 _mov(DestLo, ReturnReg); |
2942 _mov(DestHi, ReturnRegHi); | 3051 _mov(DestHi, ReturnRegHi); |
2943 } else { | 3052 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
2959 const uint32_t ShiftAmount = | 3068 const uint32_t ShiftAmount = |
2960 (Src0Ty == IceType_i1 | 3069 (Src0Ty == IceType_i1 |
2961 ? INT32_BITS - 1 | 3070 ? INT32_BITS - 1 |
2962 : INT32_BITS - (CHAR_BITS * typeWidthInBytes(Src0Ty))); | 3071 : INT32_BITS - (CHAR_BITS * typeWidthInBytes(Src0Ty))); |
2963 const uint32_t Mask = | 3072 const uint32_t Mask = |
2964 (Src0Ty == IceType_i1 | 3073 (Src0Ty == IceType_i1 |
2965 ? 1 | 3074 ? 1 |
2966 : (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1); | 3075 : (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1); |
2967 | 3076 |
2968 if (isVectorType(DestTy)) { | 3077 if (isVectorType(DestTy)) { |
2969 UnimplementedLoweringError(this, Instr); | 3078 llvm::report_fatal_error("Cast: Destination type is vector"); |
2970 return; | 3079 return; |
2971 } | 3080 } |
2972 switch (CastKind) { | 3081 switch (CastKind) { |
2973 default: | 3082 default: |
2974 Func->setError("Cast type not supported"); | 3083 Func->setError("Cast type not supported"); |
2975 return; | 3084 return; |
2976 case InstCast::Sext: { | 3085 case InstCast::Sext: { |
2977 if (DestTy == IceType_i64) { | 3086 if (DestTy == IceType_i64) { |
2978 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 3087 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
2979 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3088 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3122 UnimplementedLoweringError(this, Instr); | 3231 UnimplementedLoweringError(this, Instr); |
3123 break; | 3232 break; |
3124 } | 3233 } |
3125 case InstCast::Bitcast: { | 3234 case InstCast::Bitcast: { |
3126 Operand *Src0 = Instr->getSrc(0); | 3235 Operand *Src0 = Instr->getSrc(0); |
3127 if (DestTy == Src0->getType()) { | 3236 if (DestTy == Src0->getType()) { |
3128 auto *Assign = InstAssign::create(Func, Dest, Src0); | 3237 auto *Assign = InstAssign::create(Func, Dest, Src0); |
3129 lowerAssign(Assign); | 3238 lowerAssign(Assign); |
3130 return; | 3239 return; |
3131 } | 3240 } |
| 3241 if (isVectorType(DestTy) || isVectorType(Src0->getType())) { |
| 3242 llvm::report_fatal_error( |
| 3243 "Bitcast: vector type should have been prelowered."); |
| 3244 return; |
| 3245 } |
3132 switch (DestTy) { | 3246 switch (DestTy) { |
3133 case IceType_NUM: | 3247 case IceType_NUM: |
3134 case IceType_void: | 3248 case IceType_void: |
3135 llvm::report_fatal_error("Unexpected bitcast."); | 3249 llvm::report_fatal_error("Unexpected bitcast."); |
3136 case IceType_i1: | 3250 case IceType_i1: |
3137 UnimplementedLoweringError(this, Instr); | 3251 UnimplementedLoweringError(this, Instr); |
3138 break; | 3252 break; |
3139 case IceType_i8: | 3253 case IceType_i8: |
3140 assert(Src0->getType() == IceType_v8i1); | 3254 assert(Src0->getType() == IceType_v8i1); |
3141 llvm::report_fatal_error( | 3255 llvm::report_fatal_error( |
(...skipping 29 matching lines...) Expand all Loading... |
3171 RegHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits)); | 3285 RegHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits)); |
3172 _mov(Dest, RegHi, RegLo); | 3286 _mov(Dest, RegHi, RegLo); |
3173 } else { | 3287 } else { |
3174 auto *Var64On32 = llvm::cast<Variable64On32>(Src0); | 3288 auto *Var64On32 = llvm::cast<Variable64On32>(Src0); |
3175 auto *RegLo = legalizeToReg(loOperand(Var64On32)); | 3289 auto *RegLo = legalizeToReg(loOperand(Var64On32)); |
3176 auto *RegHi = legalizeToReg(hiOperand(Var64On32)); | 3290 auto *RegHi = legalizeToReg(hiOperand(Var64On32)); |
3177 _mov(Dest, RegHi, RegLo); | 3291 _mov(Dest, RegHi, RegLo); |
3178 } | 3292 } |
3179 break; | 3293 break; |
3180 } | 3294 } |
3181 case IceType_v8i1: | |
3182 assert(Src0->getType() == IceType_i8); | |
3183 llvm::report_fatal_error( | |
3184 "v8i1 to i8 conversion should have been prelowered."); | |
3185 break; | |
3186 case IceType_v16i1: | |
3187 assert(Src0->getType() == IceType_i16); | |
3188 llvm::report_fatal_error( | |
3189 "v16i1 to i16 conversion should have been prelowered."); | |
3190 break; | |
3191 default: | 3295 default: |
3192 UnimplementedLoweringError(this, Instr); | 3296 UnimplementedLoweringError(this, Instr); |
3193 } | 3297 } |
3194 break; | 3298 break; |
3195 } | 3299 } |
3196 } | 3300 } |
3197 } | 3301 } |
3198 | 3302 |
3199 void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) { | 3303 void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) { |
3200 Variable *Dest = Instr->getDest(); | 3304 Variable *Dest = Instr->getDest(); |
3201 const Type DestTy = Dest->getType(); | 3305 const Type DestTy = Dest->getType(); |
3202 Operand *Src1 = Instr->getSrc(1); | 3306 Operand *Src1 = Instr->getSrc(1); |
3203 if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src1)) { | 3307 if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src1)) { |
3204 const uint32_t Index = Imm->getValue(); | 3308 const uint32_t Index = Imm->getValue(); |
3205 Variable *TDest = makeReg(DestTy); | 3309 Variable *TDest = makeReg(DestTy); |
3206 Variable *TReg = makeReg(DestTy); | 3310 Variable *TReg = makeReg(DestTy); |
3207 auto *Src0 = legalizeUndef(Instr->getSrc(0)); | 3311 auto *Src0 = legalizeUndef(Instr->getSrc(0)); |
3208 auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); | 3312 auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); |
3209 // Number of elements in each container | 3313 // Number of elements in each container |
3210 uint32_t ElemPerCont = | 3314 uint32_t ElemPerCont = |
3211 typeNumElements(Src0->getType()) / Src0R->ElementsPerContainer; | 3315 typeNumElements(Src0->getType()) / Src0R->ContainersPerVector; |
3212 auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; | 3316 auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; |
3213 // Position of the element in the container | 3317 // Position of the element in the container |
3214 uint32_t PosInCont = Index % ElemPerCont; | 3318 uint32_t PosInCont = Index % ElemPerCont; |
3215 if (ElemPerCont == 1) { | 3319 if (ElemPerCont == 1) { |
3216 _mov(TDest, SrcE); | 3320 _mov(TDest, SrcE); |
3217 } else if (ElemPerCont == 2) { | 3321 } else if (ElemPerCont == 2) { |
3218 switch (PosInCont) { | 3322 switch (PosInCont) { |
3219 case 0: | 3323 case 0: |
3220 _andi(TDest, SrcE, 0xffff); | 3324 _andi(TDest, SrcE, 0xffff); |
3221 break; | 3325 break; |
(...skipping 19 matching lines...) Expand all Loading... |
3241 break; | 3345 break; |
3242 case 3: | 3346 case 3: |
3243 _srl(TDest, SrcE, 24); | 3347 _srl(TDest, SrcE, 24); |
3244 break; | 3348 break; |
3245 default: | 3349 default: |
3246 llvm::report_fatal_error("ExtractElement: Invalid PosInCont"); | 3350 llvm::report_fatal_error("ExtractElement: Invalid PosInCont"); |
3247 break; | 3351 break; |
3248 } | 3352 } |
3249 } | 3353 } |
3250 if (typeElementType(Src0R->getType()) == IceType_i1) { | 3354 if (typeElementType(Src0R->getType()) == IceType_i1) { |
3251 _andi(TReg, TDest, 0x1); | 3355 Variable *TReg1 = makeReg(DestTy); |
3252 _mov(Dest, TReg); | 3356 _andi(TReg1, TDest, 0x1); |
| 3357 _mov(Dest, TReg1); |
3253 } else { | 3358 } else { |
3254 _mov(Dest, TDest); | 3359 _mov(Dest, TDest); |
3255 } | 3360 } |
3256 return; | 3361 return; |
3257 } | 3362 } |
3258 llvm::report_fatal_error("ExtractElement requires a constant index"); | 3363 llvm::report_fatal_error("ExtractElement requires a constant index"); |
3259 } | 3364 } |
3260 | 3365 |
3261 void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) { | 3366 void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) { |
3262 Variable *Dest = Instr->getDest(); | 3367 Variable *Dest = Instr->getDest(); |
3263 if (isVectorType(Dest->getType())) { | 3368 if (isVectorType(Dest->getType())) { |
3264 UnimplementedLoweringError(this, Instr); | 3369 llvm::report_fatal_error("Fcmp: Destination type is vector"); |
3265 return; | 3370 return; |
3266 } | 3371 } |
3267 | 3372 |
3268 auto *Src0 = Instr->getSrc(0); | 3373 auto *Src0 = Instr->getSrc(0); |
3269 auto *Src1 = Instr->getSrc(1); | 3374 auto *Src1 = Instr->getSrc(1); |
3270 auto *Zero = getZero(); | 3375 auto *Zero = getZero(); |
3271 | 3376 |
3272 InstFcmp::FCond Cond = Instr->getCondition(); | 3377 InstFcmp::FCond Cond = Instr->getCondition(); |
3273 auto *DestR = makeReg(Dest->getType()); | 3378 auto *DestR = makeReg(IceType_i32); |
3274 auto *Src0R = legalizeToReg(Src0); | 3379 auto *Src0R = legalizeToReg(Src0); |
3275 auto *Src1R = legalizeToReg(Src1); | 3380 auto *Src1R = legalizeToReg(Src1); |
3276 const Type Src0Ty = Src0->getType(); | 3381 const Type Src0Ty = Src0->getType(); |
3277 | 3382 |
3278 Operand *FCC0 = OperandMIPS32FCC::create(getFunc(), OperandMIPS32FCC::FCC0); | 3383 Operand *FCC0 = OperandMIPS32FCC::create(getFunc(), OperandMIPS32FCC::FCC0); |
3279 | 3384 |
3280 switch (Cond) { | 3385 switch (Cond) { |
3281 default: { | 3386 default: { |
3282 UnimplementedLoweringError(this, Instr); | 3387 UnimplementedLoweringError(this, Instr); |
3283 return; | 3388 return; |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3601 | 3706 |
3602 void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) { | 3707 void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) { |
3603 auto *Src0 = Instr->getSrc(0); | 3708 auto *Src0 = Instr->getSrc(0); |
3604 auto *Src1 = Instr->getSrc(1); | 3709 auto *Src1 = Instr->getSrc(1); |
3605 if (Src0->getType() == IceType_i64) { | 3710 if (Src0->getType() == IceType_i64) { |
3606 lower64Icmp(Instr); | 3711 lower64Icmp(Instr); |
3607 return; | 3712 return; |
3608 } | 3713 } |
3609 Variable *Dest = Instr->getDest(); | 3714 Variable *Dest = Instr->getDest(); |
3610 if (isVectorType(Dest->getType())) { | 3715 if (isVectorType(Dest->getType())) { |
3611 UnimplementedLoweringError(this, Instr); | 3716 llvm::report_fatal_error("Icmp: Destination type is vector"); |
3612 return; | 3717 return; |
3613 } | 3718 } |
3614 InstIcmp::ICond Cond = Instr->getCondition(); | 3719 InstIcmp::ICond Cond = Instr->getCondition(); |
3615 auto *Src0R = legalizeToReg(Src0); | 3720 auto *Src0R = legalizeToReg(Src0); |
3616 auto *Src1R = legalizeToReg(Src1); | 3721 auto *Src1R = legalizeToReg(Src1); |
3617 const Type Src0Ty = Src0R->getType(); | 3722 const Type Src0Ty = Src0R->getType(); |
3618 const uint32_t ShAmt = INT32_BITS - getScalarIntBitWidth(Src0->getType()); | 3723 const uint32_t ShAmt = INT32_BITS - getScalarIntBitWidth(Src0->getType()); |
3619 Variable *Src0RT = I32Reg(); | 3724 Variable *Src0RT = I32Reg(); |
3620 Variable *Src1RT = I32Reg(); | 3725 Variable *Src1RT = I32Reg(); |
3621 | 3726 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3707 } | 3812 } |
3708 } | 3813 } |
3709 | 3814 |
3710 void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) { | 3815 void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) { |
3711 Variable *Dest = Instr->getDest(); | 3816 Variable *Dest = Instr->getDest(); |
3712 const Type DestTy = Dest->getType(); | 3817 const Type DestTy = Dest->getType(); |
3713 Operand *Src2 = Instr->getSrc(2); | 3818 Operand *Src2 = Instr->getSrc(2); |
3714 if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2)) { | 3819 if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2)) { |
3715 const uint32_t Index = Imm->getValue(); | 3820 const uint32_t Index = Imm->getValue(); |
3716 // Vector to insert in | 3821 // Vector to insert in |
3717 auto *Src0 = Instr->getSrc(0); | 3822 auto *Src0 = legalizeUndef(Instr->getSrc(0)); |
3718 auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); | 3823 auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); |
3719 // Number of elements in each container | 3824 // Number of elements in each container |
3720 uint32_t ElemPerCont = | 3825 uint32_t ElemPerCont = |
3721 typeNumElements(Src0->getType()) / Src0R->ElementsPerContainer; | 3826 typeNumElements(Src0->getType()) / Src0R->ContainersPerVector; |
3722 // Source Element | 3827 // Source Element |
3723 auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; | 3828 auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; |
3724 Context.insert<InstFakeDef>(SrcE); | |
3725 // Dest is a vector | 3829 // Dest is a vector |
3726 auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest); | 3830 auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest); |
3727 VDest->initVecElement(Func); | 3831 VDest->initVecElement(Func); |
3728 // Temp vector variable | 3832 // Temp vector variable |
3729 auto *TDest = makeReg(DestTy); | 3833 auto *TDest = makeReg(DestTy); |
3730 auto *TVDest = llvm::dyn_cast<VariableVecOn32>(TDest); | 3834 auto *TVDest = llvm::dyn_cast<VariableVecOn32>(TDest); |
3731 TVDest->initVecElement(Func); | 3835 TVDest->initVecElement(Func); |
3732 // Destination element | 3836 // Destination element |
3733 auto *DstE = TVDest->getContainers()[Index / ElemPerCont]; | 3837 auto *DstE = TVDest->getContainers()[Index / ElemPerCont]; |
3734 // Element to insert | 3838 // Element to insert |
3735 auto *Src1R = legalizeToReg(Instr->getSrc(1)); | 3839 auto *Src1R = legalizeToReg(Instr->getSrc(1)); |
3736 auto *TReg1 = makeReg(Src1R->getType()); | 3840 auto *TReg1 = makeReg(Src1R->getType()); |
3737 auto *TReg2 = makeReg(Src1R->getType()); | 3841 auto *TReg2 = makeReg(Src1R->getType()); |
3738 auto *TReg3 = makeReg(Src1R->getType()); | 3842 auto *TReg3 = makeReg(Src1R->getType()); |
3739 auto *TReg4 = makeReg(Src1R->getType()); | 3843 auto *TReg4 = makeReg(Src1R->getType()); |
3740 auto *TReg5 = makeReg(Src1R->getType()); | 3844 auto *TReg5 = makeReg(Src1R->getType()); |
3741 // Position of the element in the container | 3845 // Position of the element in the container |
3742 uint32_t PosInCont = Index % ElemPerCont; | 3846 uint32_t PosInCont = Index % ElemPerCont; |
3743 // Load source vector in a temporary vector | 3847 // Load source vector in a temporary vector |
3744 for (SizeT i = 0; i < TVDest->ElementsPerContainer; ++i) { | 3848 for (SizeT i = 0; i < TVDest->ContainersPerVector; ++i) { |
3745 auto *DCont = TVDest->getContainers()[i]; | 3849 auto *DCont = TVDest->getContainers()[i]; |
3746 // Do not define DstE as we are going to redefine it | 3850 // Do not define DstE as we are going to redefine it |
3747 if (DCont == DstE) | 3851 if (DCont == DstE) |
3748 continue; | 3852 continue; |
3749 auto *SCont = Src0R->getContainers()[i]; | 3853 auto *SCont = Src0R->getContainers()[i]; |
3750 auto *TReg = makeReg(IceType_i32); | 3854 auto *TReg = makeReg(IceType_i32); |
3751 _mov(TReg, SCont); | 3855 _mov(TReg, SCont); |
3752 _mov(DCont, TReg); | 3856 _mov(DCont, TReg); |
3753 } | 3857 } |
3754 // Insert the element | 3858 // Insert the element |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4285 | 4389 |
4286 Func->resetCurrentNode(); | 4390 Func->resetCurrentNode(); |
4287 if (Func->isVerbose(IceV_AddrOpt)) { | 4391 if (Func->isVerbose(IceV_AddrOpt)) { |
4288 OstreamLocker _(Func->getContext()); | 4392 OstreamLocker _(Func->getContext()); |
4289 Ostream &Str = Func->getContext()->getStrDump(); | 4393 Ostream &Str = Func->getContext()->getStrDump(); |
4290 Str << "\nAddress mode formation:\t"; | 4394 Str << "\nAddress mode formation:\t"; |
4291 LdSt->dumpDecorated(Func); | 4395 LdSt->dumpDecorated(Func); |
4292 } | 4396 } |
4293 | 4397 |
4294 if (isVectorType(Ty)) { | 4398 if (isVectorType(Ty)) { |
4295 UnimplementedError(getFlags()); | |
4296 return nullptr; | 4399 return nullptr; |
4297 } | 4400 } |
4298 | 4401 |
4299 auto *BaseVar = llvm::dyn_cast<Variable>(Base); | 4402 auto *BaseVar = llvm::dyn_cast<Variable>(Base); |
4300 if (BaseVar == nullptr) | 4403 if (BaseVar == nullptr) |
4301 return nullptr; | 4404 return nullptr; |
4302 | 4405 |
4303 const VariablesMetadata *VMetadata = Func->getVMetadata(); | 4406 const VariablesMetadata *VMetadata = Func->getVMetadata(); |
4304 const Inst *Reason = nullptr; | 4407 const Inst *Reason = nullptr; |
4305 | 4408 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4428 Context.insert<InstFakeUse>(V1); | 4531 Context.insert<InstFakeUse>(V1); |
4429 Context.insert<InstFakeUse>(A0); | 4532 Context.insert<InstFakeUse>(A0); |
4430 Context.insert<InstFakeUse>(A1); | 4533 Context.insert<InstFakeUse>(A1); |
4431 break; | 4534 break; |
4432 } | 4535 } |
4433 case IceType_v4f32: { | 4536 case IceType_v4f32: { |
4434 auto *SrcVec = llvm::dyn_cast<VariableVecOn32>(Src0); | 4537 auto *SrcVec = llvm::dyn_cast<VariableVecOn32>(Src0); |
4435 Reg = getImplicitRet(); | 4538 Reg = getImplicitRet(); |
4436 auto *RegT = legalizeToReg(Reg); | 4539 auto *RegT = legalizeToReg(Reg); |
4437 // Return the vector through buffer in implicit argument a0 | 4540 // Return the vector through buffer in implicit argument a0 |
4438 for (SizeT i = 0; i < SrcVec->ElementsPerContainer; ++i) { | 4541 for (SizeT i = 0; i < SrcVec->ContainersPerVector; ++i) { |
4439 OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( | 4542 OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( |
4440 Func, IceType_f32, RegT, | 4543 Func, IceType_f32, RegT, |
4441 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4))); | 4544 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4))); |
4442 Variable *Var = legalizeToReg(SrcVec->getContainers()[i]); | 4545 Variable *Var = legalizeToReg(SrcVec->getContainers()[i]); |
4443 _sw(Var, Mem); | 4546 _sw(Var, Mem); |
4444 } | 4547 } |
4445 Variable *V0 = makeReg(IceType_i32, RegMIPS32::Reg_V0); | 4548 Variable *V0 = makeReg(IceType_i32, RegMIPS32::Reg_V0); |
4446 _mov(V0, Reg); // move v0,a0 | 4549 _mov(V0, Reg); // move v0,a0 |
4447 Context.insert<InstFakeUse>(Reg); | 4550 Context.insert<InstFakeUse>(Reg); |
4448 Context.insert<InstFakeUse>(V0); | 4551 Context.insert<InstFakeUse>(V0); |
4449 break; | 4552 break; |
4450 } | 4553 } |
4451 default: | 4554 default: |
4452 llvm::report_fatal_error("Ret: Invalid type."); | 4555 llvm::report_fatal_error("Ret: Invalid type."); |
4453 break; | 4556 break; |
4454 } | 4557 } |
4455 } | 4558 } |
4456 _ret(getPhysicalRegister(RegMIPS32::Reg_RA), Reg); | 4559 _ret(getPhysicalRegister(RegMIPS32::Reg_RA), Reg); |
4457 } | 4560 } |
4458 | 4561 |
4459 void TargetMIPS32::lowerSelect(const InstSelect *Instr) { | 4562 void TargetMIPS32::lowerSelect(const InstSelect *Instr) { |
4460 Variable *Dest = Instr->getDest(); | 4563 Variable *Dest = Instr->getDest(); |
4461 const Type DestTy = Dest->getType(); | 4564 const Type DestTy = Dest->getType(); |
4462 | 4565 |
4463 if (isVectorType(DestTy)) { | 4566 if (isVectorType(DestTy)) { |
4464 UnimplementedLoweringError(this, Instr); | 4567 llvm::report_fatal_error("Select: Destination type is vector"); |
4465 return; | 4568 return; |
4466 } | 4569 } |
4467 | 4570 |
4468 Variable *DestR = nullptr; | 4571 Variable *DestR = nullptr; |
4469 Variable *DestHiR = nullptr; | 4572 Variable *DestHiR = nullptr; |
4470 Variable *SrcTR = nullptr; | 4573 Variable *SrcTR = nullptr; |
4471 Variable *SrcTHiR = nullptr; | 4574 Variable *SrcTHiR = nullptr; |
4472 Variable *SrcFR = nullptr; | 4575 Variable *SrcFR = nullptr; |
4473 Variable *SrcFHiR = nullptr; | 4576 Variable *SrcFHiR = nullptr; |
4474 | 4577 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4526 Type Ty = NewAddr->getType(); | 4629 Type Ty = NewAddr->getType(); |
4527 | 4630 |
4528 if (Ty == IceType_i64) { | 4631 if (Ty == IceType_i64) { |
4529 Value = legalizeUndef(Value); | 4632 Value = legalizeUndef(Value); |
4530 Variable *ValueHi = legalizeToReg(hiOperand(Value)); | 4633 Variable *ValueHi = legalizeToReg(hiOperand(Value)); |
4531 Variable *ValueLo = legalizeToReg(loOperand(Value)); | 4634 Variable *ValueLo = legalizeToReg(loOperand(Value)); |
4532 _sw(ValueHi, llvm::cast<OperandMIPS32Mem>(hiOperand(NewAddr))); | 4635 _sw(ValueHi, llvm::cast<OperandMIPS32Mem>(hiOperand(NewAddr))); |
4533 _sw(ValueLo, llvm::cast<OperandMIPS32Mem>(loOperand(NewAddr))); | 4636 _sw(ValueLo, llvm::cast<OperandMIPS32Mem>(loOperand(NewAddr))); |
4534 } else if (isVectorType(Value->getType())) { | 4637 } else if (isVectorType(Value->getType())) { |
4535 auto *DataVec = llvm::dyn_cast<VariableVecOn32>(Value); | 4638 auto *DataVec = llvm::dyn_cast<VariableVecOn32>(Value); |
4536 for (SizeT i = 0; i < DataVec->ElementsPerContainer; ++i) { | 4639 for (SizeT i = 0; i < DataVec->ContainersPerVector; ++i) { |
4537 auto *DCont = legalizeToReg(DataVec->getContainers()[i]); | 4640 auto *DCont = legalizeToReg(DataVec->getContainers()[i]); |
4538 auto *MCont = llvm::cast<OperandMIPS32Mem>( | 4641 auto *MCont = llvm::cast<OperandMIPS32Mem>( |
4539 getOperandAtIndex(NewAddr, IceType_i32, i)); | 4642 getOperandAtIndex(NewAddr, IceType_i32, i)); |
4540 _sw(DCont, MCont); | 4643 _sw(DCont, MCont); |
4541 } | 4644 } |
4542 } else { | 4645 } else { |
4543 Variable *ValueR = legalizeToReg(Value); | 4646 Variable *ValueR = legalizeToReg(Value); |
4544 _sw(ValueR, NewAddr); | 4647 _sw(ValueR, NewAddr); |
4545 } | 4648 } |
4546 } | 4649 } |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5000 Str << "\t.set\t" | 5103 Str << "\t.set\t" |
5001 << "nomips16\n"; | 5104 << "nomips16\n"; |
5002 } | 5105 } |
5003 | 5106 |
5004 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 5107 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
5005 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 5108 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
5006 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 5109 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
5007 | 5110 |
5008 } // end of namespace MIPS32 | 5111 } // end of namespace MIPS32 |
5009 } // end of namespace Ice | 5112 } // end of namespace Ice |
OLD | NEW |