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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2317653004: Subzero, MIPS32: Introduction of genTargetHelperCallFor (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 3 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/IceTargetLoweringMIPS32.h ('k') | tests_lit/llvm2ice_tests/64bit.pnacl.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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 return; 208 return;
209 } 209 }
210 } 210 }
211 } 211 }
212 } 212 }
213 213
214 uint32_t TargetMIPS32::getStackAlignment() const { 214 uint32_t TargetMIPS32::getStackAlignment() const {
215 return MIPS32_STACK_ALIGNMENT_BYTES; 215 return MIPS32_STACK_ALIGNMENT_BYTES;
216 } 216 }
217 217
218 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) {
219 constexpr bool NoTailCall = false;
220 constexpr bool IsTargetHelperCall = true;
221
222 switch (Instr->getKind()) {
223 default:
224 return;
225 case Inst::Arithmetic: {
226 Variable *Dest = Instr->getDest();
227 const Type DestTy = Dest->getType();
228 const InstArithmetic::OpKind Op =
229 llvm::cast<InstArithmetic>(Instr)->getOp();
230 if (isVectorType(DestTy)) {
231 switch (Op) {
232 default:
233 break;
234 case InstArithmetic::Fdiv:
235 case InstArithmetic::Frem:
236 case InstArithmetic::Sdiv:
237 case InstArithmetic::Srem:
238 case InstArithmetic::Udiv:
239 case InstArithmetic::Urem:
240 scalarizeArithmetic(Op, Dest, Instr->getSrc(0), Instr->getSrc(1));
241 Instr->setDeleted();
242 return;
243 }
244 }
245 switch (DestTy) {
246 default:
247 return;
248 case IceType_i64: {
249 RuntimeHelper HelperID = RuntimeHelper::H_Num;
250 switch (Op) {
251 default:
252 return;
253 case InstArithmetic::Udiv:
254 HelperID = RuntimeHelper::H_udiv_i64;
255 break;
256 case InstArithmetic::Sdiv:
257 HelperID = RuntimeHelper::H_sdiv_i64;
258 break;
259 case InstArithmetic::Urem:
260 HelperID = RuntimeHelper::H_urem_i64;
261 break;
262 case InstArithmetic::Srem:
263 HelperID = RuntimeHelper::H_srem_i64;
264 break;
265 }
266
267 if (HelperID == RuntimeHelper::H_Num) {
268 return;
269 }
270
271 Operand *TargetHelper = Ctx->getRuntimeHelperFunc(HelperID);
272 constexpr SizeT MaxArgs = 2;
273 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
274 NoTailCall, IsTargetHelperCall);
275 Call->addArg(Instr->getSrc(0));
276 Call->addArg(Instr->getSrc(1));
277 Instr->setDeleted();
278 return;
279 }
280 case IceType_i32:
281 case IceType_i16:
282 case IceType_i8: {
283 InstCast::OpKind CastKind;
284 RuntimeHelper HelperID = RuntimeHelper::H_Num;
285 switch (Op) {
286 default:
287 return;
288 case InstArithmetic::Udiv:
289 HelperID = RuntimeHelper::H_udiv_i32;
290 CastKind = InstCast::Zext;
291 break;
292 case InstArithmetic::Sdiv:
293 HelperID = RuntimeHelper::H_sdiv_i32;
294 CastKind = InstCast::Sext;
295 break;
296 case InstArithmetic::Urem:
297 HelperID = RuntimeHelper::H_urem_i32;
298 CastKind = InstCast::Zext;
299 break;
300 case InstArithmetic::Srem:
301 HelperID = RuntimeHelper::H_srem_i32;
302 CastKind = InstCast::Sext;
303 break;
304 }
305
306 if (HelperID == RuntimeHelper::H_Num) {
307 return;
308 }
309
310 Operand *Src0 = Instr->getSrc(0);
311 Operand *Src1 = Instr->getSrc(1);
312 if (DestTy != IceType_i32) {
313 // Src0 and Src1 have to be zero-, or signed-extended to i32. For Src0,
314 // we just insert a InstCast right before the call to the helper.
315 Variable *Src0_32 = Func->makeVariable(IceType_i32);
316 Context.insert<InstCast>(CastKind, Src0_32, Src0);
317 Src0 = Src0_32;
318
319 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) {
320 const int32_t ShAmt = (DestTy == IceType_i16) ? 16 : 24;
321 int32_t NewC = C->getValue();
322 if (CastKind == InstCast::Zext) {
323 NewC &= ~(0x80000000l >> ShAmt);
324 } else {
325 NewC = (NewC << ShAmt) >> ShAmt;
326 }
327 Src1 = Ctx->getConstantInt32(NewC);
328 } else {
329 Variable *Src1_32 = Func->makeVariable(IceType_i32);
330 Context.insert<InstCast>(CastKind, Src1_32, Src1);
331 Src1 = Src1_32;
332 }
333 }
334 Operand *TargetHelper = Ctx->getRuntimeHelperFunc(HelperID);
335 constexpr SizeT MaxArgs = 2;
336 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
337 NoTailCall, IsTargetHelperCall);
338 assert(Src0->getType() == IceType_i32);
339 Call->addArg(Src0);
340 assert(Src1->getType() == IceType_i32);
341 Call->addArg(Src1);
342 Instr->setDeleted();
343 return;
344 }
345 //case IceType_f64:
346 //case IceType_f32: {
347 // if (Op != InstArithmetic::Frem) {
Jim Stichnoth 2016/09/07 04:17:31 Could you leave this code uncommented? Maybe prep
obucinac 2016/09/07 15:08:55 I decided to remove it, until we fix the lowerCall
348 // return;
349 // }
350 // constexpr SizeT MaxArgs = 2;
351 // Operand *TargetHelper = Ctx->getRuntimeHelperFunc(
352 // DestTy == IceType_f32 ? RuntimeHelper::H_frem_f32
353 // : RuntimeHelper::H_frem_f64);
354 // auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
355 // NoTailCall, IsTargetHelperCall);
356 // Call->addArg(Instr->getSrc(0));
357 // Call->addArg(Instr->getSrc(1));
358 // Instr->setDeleted();
359 // return;
360 //}
361 }
362 llvm::report_fatal_error("Control flow should never have reached here.");
363 }
364 case Inst::Cast: {
365 Variable *Dest = Instr->getDest();
366 Operand *Src0 = Instr->getSrc(0);
367 const Type DestTy = Dest->getType();
368 const Type SrcTy = Src0->getType();
369 auto *CastInstr = llvm::cast<InstCast>(Instr);
370 const InstCast::OpKind CastKind = CastInstr->getCastKind();
371
372 switch (CastKind) {
373 default:
374 return;
375 case InstCast::Fptosi:
376 case InstCast::Fptoui: {
377 if (DestTy != IceType_i64) {
378 return;
379 }
380 const bool DestIsSigned = CastKind == InstCast::Fptosi;
381 const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy);
382 Operand *TargetHelper = Ctx->getRuntimeHelperFunc(
383 Src0IsF32 ? (DestIsSigned ? RuntimeHelper::H_fptosi_f32_i64
384 : RuntimeHelper::H_fptoui_f32_i64)
385 : (DestIsSigned ? RuntimeHelper::H_fptosi_f64_i64
386 : RuntimeHelper::H_fptoui_f64_i64));
387 static constexpr SizeT MaxArgs = 1;
388 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
389 NoTailCall, IsTargetHelperCall);
390 Call->addArg(Src0);
391 Instr->setDeleted();
392 return;
393 }
394 case InstCast::Sitofp:
395 case InstCast::Uitofp: {
396 if (SrcTy != IceType_i64) {
397 return;
398 }
399 const bool SourceIsSigned = CastKind == InstCast::Sitofp;
400 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType());
401 Operand *TargetHelper = Ctx->getRuntimeHelperFunc(
402 DestIsF32 ? (SourceIsSigned ? RuntimeHelper::H_sitofp_i64_f32
403 : RuntimeHelper::H_uitofp_i64_f32)
404 : (SourceIsSigned ? RuntimeHelper::H_sitofp_i64_f64
405 : RuntimeHelper::H_uitofp_i64_f64));
406 static constexpr SizeT MaxArgs = 1;
407 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
408 NoTailCall, IsTargetHelperCall);
409 Call->addArg(Src0);
410 Instr->setDeleted();
411 return;
412 }
413 case InstCast::Bitcast: {
414 if (DestTy == SrcTy) {
415 return;
416 }
417 Variable *CallDest = Dest;
418 RuntimeHelper HelperID = RuntimeHelper::H_Num;
419 switch (DestTy) {
420 default:
421 return;
422 case IceType_i8:
423 assert(SrcTy == IceType_v8i1);
424 HelperID = RuntimeHelper::H_bitcast_8xi1_i8;
425 CallDest = Func->makeVariable(IceType_i32);
426 break;
427 case IceType_i16:
428 assert(SrcTy == IceType_v16i1);
429 HelperID = RuntimeHelper::H_bitcast_16xi1_i16;
430 CallDest = Func->makeVariable(IceType_i32);
431 break;
432 case IceType_v8i1: {
433 assert(SrcTy == IceType_i8);
434 HelperID = RuntimeHelper::H_bitcast_i8_8xi1;
435 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
436 // Arguments to functions are required to be at least 32 bits wide.
437 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
438 Src0 = Src0AsI32;
439 } break;
440 case IceType_v16i1: {
441 assert(SrcTy == IceType_i16);
442 HelperID = RuntimeHelper::H_bitcast_i16_16xi1;
443 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
444 // Arguments to functions are required to be at least 32 bits wide.
445 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
446 Src0 = Src0AsI32;
447 } break;
448 }
449 constexpr SizeT MaxSrcs = 1;
450 InstCall *Call = makeHelperCall(HelperID, CallDest, MaxSrcs);
451 Call->addArg(Src0);
452 Context.insert(Call);
453 // The PNaCl ABI disallows i8/i16 return types, so truncate the helper
454 // call result to the appropriate type as necessary.
455 if (CallDest->getType() != Dest->getType())
456 Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest);
457 Instr->setDeleted();
458 return;
459 }
460 case InstCast::Trunc: {
461 if (DestTy == SrcTy) {
462 return;
463 }
464 if (!isVectorType(SrcTy)) {
465 return;
466 }
467 assert(typeNumElements(DestTy) == typeNumElements(SrcTy));
468 assert(typeElementType(DestTy) == IceType_i1);
469 assert(isVectorIntegerType(SrcTy));
470 return;
471 }
472 case InstCast::Sext:
473 case InstCast::Zext: {
474 if (DestTy == SrcTy) {
475 return;
476 }
477 if (!isVectorType(DestTy)) {
478 return;
479 }
480 assert(typeNumElements(DestTy) == typeNumElements(SrcTy));
481 assert(typeElementType(SrcTy) == IceType_i1);
482 assert(isVectorIntegerType(DestTy));
483 return;
484 }
485 }
486 llvm::report_fatal_error("Control flow should never have reached here.");
487 }
488 case Inst::IntrinsicCall: {
489 Variable *Dest = Instr->getDest();
490 auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr);
491 Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID;
492 switch (ID) {
493 default:
494 return;
495 case Intrinsics::Ctpop: {
496 Operand *Src0 = IntrinsicCall->getArg(0);
497 Operand *TargetHelper =
498 Ctx->getRuntimeHelperFunc(isInt32Asserting32Or64(Src0->getType())
499 ? RuntimeHelper::H_call_ctpop_i32
500 : RuntimeHelper::H_call_ctpop_i64);
501 static constexpr SizeT MaxArgs = 1;
502 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
503 NoTailCall, IsTargetHelperCall);
504 Call->addArg(Src0);
505 Instr->setDeleted();
506 return;
507 }
508 case Intrinsics::Longjmp: {
509 static constexpr SizeT MaxArgs = 2;
510 static constexpr Variable *NoDest = nullptr;
511 Operand *TargetHelper =
512 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_longjmp);
513 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
514 NoTailCall, IsTargetHelperCall);
515 Call->addArg(IntrinsicCall->getArg(0));
516 Call->addArg(IntrinsicCall->getArg(1));
517 Instr->setDeleted();
518 return;
519 }
520 case Intrinsics::Memcpy: {
521 static constexpr SizeT MaxArgs = 3;
522 static constexpr Variable *NoDest = nullptr;
523 Operand *TargetHelper =
524 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memcpy);
525 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
526 NoTailCall, IsTargetHelperCall);
527 Call->addArg(IntrinsicCall->getArg(0));
528 Call->addArg(IntrinsicCall->getArg(1));
529 Call->addArg(IntrinsicCall->getArg(2));
530 Instr->setDeleted();
531 return;
532 }
533 case Intrinsics::Memmove: {
534 static constexpr SizeT MaxArgs = 3;
535 static constexpr Variable *NoDest = nullptr;
536 Operand *TargetHelper =
537 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memmove);
538 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
539 NoTailCall, IsTargetHelperCall);
540 Call->addArg(IntrinsicCall->getArg(0));
541 Call->addArg(IntrinsicCall->getArg(1));
542 Call->addArg(IntrinsicCall->getArg(2));
543 Instr->setDeleted();
544 return;
545 }
546 case Intrinsics::Memset: {
547 Operand *ValOp = IntrinsicCall->getArg(1);
548 assert(ValOp->getType() == IceType_i8);
549 Variable *ValExt = Func->makeVariable(stackSlotType());
550 Context.insert<InstCast>(InstCast::Zext, ValExt, ValOp);
551
552 static constexpr SizeT MaxArgs = 3;
553 static constexpr Variable *NoDest = nullptr;
554 Operand *TargetHelper =
555 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memset);
556 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
557 NoTailCall, IsTargetHelperCall);
558 Call->addArg(IntrinsicCall->getArg(0));
559 Call->addArg(ValExt);
560 Call->addArg(IntrinsicCall->getArg(2));
561 Instr->setDeleted();
562 return;
563 }
564 case Intrinsics::NaClReadTP: {
565 if (SandboxingType == ST_NaCl) {
566 return;
567 }
568 static constexpr SizeT MaxArgs = 0;
569 Operand *TargetHelper =
570 SandboxingType == ST_Nonsfi
571 ? Ctx->getConstantExternSym(
572 Ctx->getGlobalString("__aeabi_read_tp"))
Jim Stichnoth 2016/09/07 04:17:31 Pretty sure this helper function is ARM-only. The
obucinac 2016/09/07 15:08:55 Done.
573 : Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_read_tp);
574 Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall,
575 IsTargetHelperCall);
576 Instr->setDeleted();
577 return;
578 }
579 case Intrinsics::Setjmp: {
580 static constexpr SizeT MaxArgs = 1;
581 Operand *TargetHelper =
582 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_setjmp);
583 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
584 NoTailCall, IsTargetHelperCall);
585 Call->addArg(IntrinsicCall->getArg(0));
586 Instr->setDeleted();
587 return;
588 }
589 }
590 llvm::report_fatal_error("Control flow should never have reached here.");
591 }
592 }
593 }
594
218 void TargetMIPS32::findMaxStackOutArgsSize() { 595 void TargetMIPS32::findMaxStackOutArgsSize() {
219 // MinNeededOutArgsBytes should be updated if the Target ever creates a 596 // MinNeededOutArgsBytes should be updated if the Target ever creates a
220 // high-level InstCall that requires more stack bytes. 597 // high-level InstCall that requires more stack bytes.
221 size_t MinNeededOutArgsBytes = 0; 598 size_t MinNeededOutArgsBytes = 0;
222 if (!MaybeLeafFunc) 599 if (!MaybeLeafFunc)
223 MinNeededOutArgsBytes = MIPS32_MAX_GPR_ARG * 4; 600 MinNeededOutArgsBytes = MIPS32_MAX_GPR_ARG * 4;
224 MaxOutArgsSizeBytes = MinNeededOutArgsBytes; 601 MaxOutArgsSizeBytes = MinNeededOutArgsBytes;
225 for (CfgNode *Node : Func->getNodes()) { 602 for (CfgNode *Node : Func->getNodes()) {
226 Context.init(Node); 603 Context.init(Node);
227 while (!Context.atEnd()) { 604 while (!Context.atEnd()) {
(...skipping 2067 matching lines...) Expand 10 before | Expand all | Expand 10 after
2295 return; 2672 return;
2296 case Intrinsics::UnknownIntrinsic: 2673 case Intrinsics::UnknownIntrinsic:
2297 Func->setError("Should not be lowering UnknownIntrinsic"); 2674 Func->setError("Should not be lowering UnknownIntrinsic");
2298 return; 2675 return;
2299 } 2676 }
2300 return; 2677 return;
2301 } 2678 }
2302 2679
2303 void TargetMIPS32::lowerLoad(const InstLoad *Instr) { 2680 void TargetMIPS32::lowerLoad(const InstLoad *Instr) {
2304 // A Load instruction can be treated the same as an Assign instruction, after 2681 // A Load instruction can be treated the same as an Assign instruction, after
2305 // the source operand is transformed into an OperandARM32Mem operand. 2682 // the source operand is transformed into an OperandMIPS32Mem operand.
2306 Type Ty = Instr->getDest()->getType(); 2683 Type Ty = Instr->getDest()->getType();
2307 Operand *Src0 = formMemoryOperand(Instr->getSourceAddress(), Ty); 2684 Operand *Src0 = formMemoryOperand(Instr->getSourceAddress(), Ty);
2308 Variable *DestLoad = Instr->getDest(); 2685 Variable *DestLoad = Instr->getDest();
2309 auto *Assign = InstAssign::create(Func, DestLoad, Src0); 2686 auto *Assign = InstAssign::create(Func, DestLoad, Src0);
2310 lowerAssign(Assign); 2687 lowerAssign(Assign);
2311 } 2688 }
2312 2689
2313 void TargetMIPS32::doAddressOptLoad() { UnimplementedError(getFlags()); } 2690 void TargetMIPS32::doAddressOptLoad() { UnimplementedError(getFlags()); }
2314 2691
2315 void TargetMIPS32::randomlyInsertNop(float Probability, 2692 void TargetMIPS32::randomlyInsertNop(float Probability,
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
2729 Str << "\t.set\t" 3106 Str << "\t.set\t"
2730 << "nomips16\n"; 3107 << "nomips16\n";
2731 } 3108 }
2732 3109
2733 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 3110 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
2734 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 3111 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
2735 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 3112 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
2736 3113
2737 } // end of namespace MIPS32 3114 } // end of namespace MIPS32
2738 } // end of namespace Ice 3115 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/llvm2ice_tests/64bit.pnacl.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698