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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2412053002: [SubZero] Implement Fcmp, ICmp, Cast and Select for vector type (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Rebase to master Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLowering.h ('k') | tests_lit/llvm2ice_tests/fp.cmp.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceTargetLowering.h ('k') | tests_lit/llvm2ice_tests/fp.cmp.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698