OLD | NEW |
---|---|
1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// | 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 return; | 461 return; |
462 } | 462 } |
463 } | 463 } |
464 switch (DestTy) { | 464 switch (DestTy) { |
465 default: | 465 default: |
466 return; | 466 return; |
467 case IceType_i64: { | 467 case IceType_i64: { |
468 // Technically, ARM has its own aeabi routines, but we can use the | 468 // Technically, ARM has its own aeabi routines, but we can use the |
469 // non-aeabi routine as well. LLVM uses __aeabi_ldivmod for div, but uses | 469 // non-aeabi routine as well. LLVM uses __aeabi_ldivmod for div, but uses |
470 // the more standard __moddi3 for rem. | 470 // the more standard __moddi3 for rem. |
471 Operand *TargetHelper = nullptr; | 471 RuntimeHelperFuncID HelperID = H_Num; |
472 switch (Op) { | 472 switch (Op) { |
473 default: | 473 default: |
474 return; | 474 return; |
475 case InstArithmetic::Udiv: | 475 case InstArithmetic::Udiv: |
476 TargetHelper = Ctx->getConstantExternSym(H_udiv_i64); | 476 HelperID = H_udiv_i64; |
477 break; | 477 break; |
478 case InstArithmetic::Sdiv: | 478 case InstArithmetic::Sdiv: |
479 TargetHelper = Ctx->getConstantExternSym(H_sdiv_i64); | 479 HelperID = H_sdiv_i64; |
480 break; | 480 break; |
481 case InstArithmetic::Urem: | 481 case InstArithmetic::Urem: |
482 TargetHelper = Ctx->getConstantExternSym(H_urem_i64); | 482 HelperID = H_urem_i64; |
483 break; | 483 break; |
484 case InstArithmetic::Srem: | 484 case InstArithmetic::Srem: |
485 TargetHelper = Ctx->getConstantExternSym(H_srem_i64); | 485 HelperID = H_srem_i64; |
486 break; | 486 break; |
487 } | 487 } |
488 assert(TargetHelper != nullptr); | 488 Operand *TargetHelper = getRuntimeHelperFunc(HelperID); |
489 ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; | 489 ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; |
490 constexpr SizeT MaxArgs = 2; | 490 constexpr SizeT MaxArgs = 2; |
491 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 491 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
492 NoTailCall, IsTargetHelperCall); | 492 NoTailCall, IsTargetHelperCall); |
493 Call->addArg(Instr->getSrc(0)); | 493 Call->addArg(Instr->getSrc(0)); |
494 Call->addArg(Instr->getSrc(1)); | 494 Call->addArg(Instr->getSrc(1)); |
495 Instr->setDeleted(); | 495 Instr->setDeleted(); |
496 return; | 496 return; |
497 } | 497 } |
498 case IceType_i32: | 498 case IceType_i32: |
499 case IceType_i16: | 499 case IceType_i16: |
500 case IceType_i8: { | 500 case IceType_i8: { |
501 const bool HasHWDiv = hasCPUFeature(TargetARM32Features::HWDivArm); | 501 const bool HasHWDiv = hasCPUFeature(TargetARM32Features::HWDivArm); |
502 InstCast::OpKind CastKind; | 502 InstCast::OpKind CastKind; |
503 Operand *TargetHelper; | 503 RuntimeHelperFuncID HelperID = H_Num; |
504 switch (Op) { | 504 switch (Op) { |
505 default: | 505 default: |
506 return; | 506 return; |
507 case InstArithmetic::Udiv: | 507 case InstArithmetic::Udiv: |
508 TargetHelper = | 508 HelperID = HasHWDiv ? H_Num : H_udiv_i32; |
509 HasHWDiv ? nullptr : Ctx->getConstantExternSym(H_udiv_i32); | |
510 CastKind = InstCast::Zext; | 509 CastKind = InstCast::Zext; |
511 break; | 510 break; |
512 case InstArithmetic::Sdiv: | 511 case InstArithmetic::Sdiv: |
513 TargetHelper = | 512 HelperID = HasHWDiv ? H_Num : H_sdiv_i32; |
514 HasHWDiv ? nullptr : Ctx->getConstantExternSym(H_sdiv_i32); | |
515 CastKind = InstCast::Sext; | 513 CastKind = InstCast::Sext; |
516 break; | 514 break; |
517 case InstArithmetic::Urem: | 515 case InstArithmetic::Urem: |
518 TargetHelper = | 516 HelperID = HasHWDiv ? H_Num : H_urem_i32; |
519 HasHWDiv ? nullptr : Ctx->getConstantExternSym(H_urem_i32); | |
520 CastKind = InstCast::Zext; | 517 CastKind = InstCast::Zext; |
521 break; | 518 break; |
522 case InstArithmetic::Srem: | 519 case InstArithmetic::Srem: |
523 TargetHelper = | 520 HelperID = HasHWDiv ? H_Num : H_srem_i32; |
524 HasHWDiv ? nullptr : Ctx->getConstantExternSym(H_srem_i32); | |
525 CastKind = InstCast::Sext; | 521 CastKind = InstCast::Sext; |
526 break; | 522 break; |
527 } | 523 } |
528 if (TargetHelper == nullptr) { | 524 if (HelperID == H_Num) { |
529 // TargetHelper should only ever be nullptr when the processor does not | 525 // HelperID should only ever be undefined when the processor does not |
530 // have a hardware divider. If any other helpers are ever introduced, | 526 // have a hardware divider. If any other helpers are ever introduced, |
531 // the following assert will have to be modified. | 527 // the following assert will have to be modified. |
532 assert(HasHWDiv); | 528 assert(HasHWDiv); |
533 return; | 529 return; |
534 } | 530 } |
535 Operand *Src0 = Instr->getSrc(0); | 531 Operand *Src0 = Instr->getSrc(0); |
536 Operand *Src1 = Instr->getSrc(1); | 532 Operand *Src1 = Instr->getSrc(1); |
537 if (DestTy != IceType_i32) { | 533 if (DestTy != IceType_i32) { |
538 // Src0 and Src1 have to be zero-, or signed-extended to i32. For Src0, | 534 // Src0 and Src1 have to be zero-, or signed-extended to i32. For Src0, |
539 // we just insert a InstCast right before the call to the helper. | 535 // we just insert a InstCast right before the call to the helper. |
(...skipping 13 matching lines...) Expand all Loading... | |
553 } else { | 549 } else { |
554 NewC = (NewC << ShAmt) >> ShAmt; | 550 NewC = (NewC << ShAmt) >> ShAmt; |
555 } | 551 } |
556 Src1 = Ctx->getConstantInt32(NewC); | 552 Src1 = Ctx->getConstantInt32(NewC); |
557 } else { | 553 } else { |
558 Variable *Src1_32 = Func->makeVariable(IceType_i32); | 554 Variable *Src1_32 = Func->makeVariable(IceType_i32); |
559 Context.insert<InstCast>(CastKind, Src1_32, Src1); | 555 Context.insert<InstCast>(CastKind, Src1_32, Src1); |
560 Src1 = Src1_32; | 556 Src1 = Src1_32; |
561 } | 557 } |
562 } | 558 } |
563 assert(TargetHelper != nullptr); | 559 Operand *TargetHelper = getRuntimeHelperFunc(HelperID); |
564 ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; | 560 ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; |
565 constexpr SizeT MaxArgs = 2; | 561 constexpr SizeT MaxArgs = 2; |
566 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 562 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
567 NoTailCall, IsTargetHelperCall); | 563 NoTailCall, IsTargetHelperCall); |
568 assert(Src0->getType() == IceType_i32); | 564 assert(Src0->getType() == IceType_i32); |
569 Call->addArg(Src0); | 565 Call->addArg(Src0); |
570 assert(Src1->getType() == IceType_i32); | 566 assert(Src1->getType() == IceType_i32); |
571 Call->addArg(Src1); | 567 Call->addArg(Src1); |
572 Instr->setDeleted(); | 568 Instr->setDeleted(); |
573 return; | 569 return; |
574 } | 570 } |
575 case IceType_f64: | 571 case IceType_f64: |
576 case IceType_f32: { | 572 case IceType_f32: { |
577 if (Op != InstArithmetic::Frem) { | 573 if (Op != InstArithmetic::Frem) { |
578 return; | 574 return; |
579 } | 575 } |
580 constexpr SizeT MaxArgs = 2; | 576 constexpr SizeT MaxArgs = 2; |
581 Operand *TargetHelper = Ctx->getConstantExternSym( | 577 Operand *TargetHelper = |
582 DestTy == IceType_f32 ? H_frem_f32 : H_frem_f64); | 578 getRuntimeHelperFunc(DestTy == IceType_f32 ? H_frem_f32 : H_frem_f64); |
Jim Stichnoth
2016/03/17 00:14:52
It seems that TargetLowering::getRuntimeHelperFunc
John
2016/03/17 14:31:33
to avoid tons of changes, maybe just add a todo to
Karl
2016/03/17 16:40:53
See we scoped the enum RuntimeFunctionFuncID, we n
| |
583 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 579 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
584 NoTailCall, IsTargetHelperCall); | 580 NoTailCall, IsTargetHelperCall); |
585 Call->addArg(Instr->getSrc(0)); | 581 Call->addArg(Instr->getSrc(0)); |
586 Call->addArg(Instr->getSrc(1)); | 582 Call->addArg(Instr->getSrc(1)); |
587 Instr->setDeleted(); | 583 Instr->setDeleted(); |
588 return; | 584 return; |
589 } | 585 } |
590 } | 586 } |
591 llvm::report_fatal_error("Control flow should never have reached here."); | 587 llvm::report_fatal_error("Control flow should never have reached here."); |
592 } | 588 } |
(...skipping 19 matching lines...) Expand all Loading... | |
612 switch (CastKind) { | 608 switch (CastKind) { |
613 default: | 609 default: |
614 return; | 610 return; |
615 case InstCast::Fptosi: | 611 case InstCast::Fptosi: |
616 case InstCast::Fptoui: { | 612 case InstCast::Fptoui: { |
617 if (DestTy != IceType_i64) { | 613 if (DestTy != IceType_i64) { |
618 return; | 614 return; |
619 } | 615 } |
620 const bool DestIsSigned = CastKind == InstCast::Fptosi; | 616 const bool DestIsSigned = CastKind == InstCast::Fptosi; |
621 const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy); | 617 const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy); |
622 Operand *TargetHelper = Ctx->getConstantExternSym( | 618 Operand *TargetHelper = getRuntimeHelperFunc( |
623 Src0IsF32 ? (DestIsSigned ? H_fptosi_f32_i64 : H_fptoui_f32_i64) | 619 Src0IsF32 ? (DestIsSigned ? H_fptosi_f32_i64 : H_fptoui_f32_i64) |
624 : (DestIsSigned ? H_fptosi_f64_i64 : H_fptoui_f64_i64)); | 620 : (DestIsSigned ? H_fptosi_f64_i64 : H_fptoui_f64_i64)); |
625 static constexpr SizeT MaxArgs = 1; | 621 static constexpr SizeT MaxArgs = 1; |
626 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 622 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
627 NoTailCall, IsTargetHelperCall); | 623 NoTailCall, IsTargetHelperCall); |
628 Call->addArg(Src0); | 624 Call->addArg(Src0); |
629 Instr->setDeleted(); | 625 Instr->setDeleted(); |
630 return; | 626 return; |
631 } | 627 } |
632 case InstCast::Sitofp: | 628 case InstCast::Sitofp: |
633 case InstCast::Uitofp: { | 629 case InstCast::Uitofp: { |
634 if (SrcTy != IceType_i64) { | 630 if (SrcTy != IceType_i64) { |
635 return; | 631 return; |
636 } | 632 } |
637 const bool SourceIsSigned = CastKind == InstCast::Sitofp; | 633 const bool SourceIsSigned = CastKind == InstCast::Sitofp; |
638 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); | 634 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); |
639 Operand *TargetHelper = Ctx->getConstantExternSym( | 635 Operand *TargetHelper = getRuntimeHelperFunc( |
640 DestIsF32 ? (SourceIsSigned ? H_sitofp_i64_f32 : H_uitofp_i64_f32) | 636 DestIsF32 ? (SourceIsSigned ? H_sitofp_i64_f32 : H_uitofp_i64_f32) |
641 : (SourceIsSigned ? H_sitofp_i64_f64 : H_uitofp_i64_f64)); | 637 : (SourceIsSigned ? H_sitofp_i64_f64 : H_uitofp_i64_f64)); |
642 static constexpr SizeT MaxArgs = 1; | 638 static constexpr SizeT MaxArgs = 1; |
643 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 639 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
644 NoTailCall, IsTargetHelperCall); | 640 NoTailCall, IsTargetHelperCall); |
645 Call->addArg(Src0); | 641 Call->addArg(Src0); |
646 Instr->setDeleted(); | 642 Instr->setDeleted(); |
647 return; | 643 return; |
648 } | 644 } |
649 case InstCast::Bitcast: { | 645 case InstCast::Bitcast: { |
650 if (DestTy == SrcTy) { | 646 if (DestTy == SrcTy) { |
651 return; | 647 return; |
652 } | 648 } |
653 Variable *CallDest = Dest; | 649 Variable *CallDest = Dest; |
654 const char *HelperName = nullptr; | 650 RuntimeHelperFuncID HelperID = H_Num; |
655 switch (DestTy) { | 651 switch (DestTy) { |
656 default: | 652 default: |
657 return; | 653 return; |
658 case IceType_i8: | 654 case IceType_i8: |
659 assert(SrcTy == IceType_v8i1); | 655 assert(SrcTy == IceType_v8i1); |
660 HelperName = H_bitcast_8xi1_i8; | 656 HelperID = H_bitcast_8xi1_i8; |
661 CallDest = Func->makeVariable(IceType_i32); | 657 CallDest = Func->makeVariable(IceType_i32); |
662 break; | 658 break; |
663 case IceType_i16: | 659 case IceType_i16: |
664 assert(SrcTy == IceType_v16i1); | 660 assert(SrcTy == IceType_v16i1); |
665 HelperName = H_bitcast_16xi1_i16; | 661 HelperID = H_bitcast_16xi1_i16; |
666 CallDest = Func->makeVariable(IceType_i32); | 662 CallDest = Func->makeVariable(IceType_i32); |
667 break; | 663 break; |
668 case IceType_v8i1: { | 664 case IceType_v8i1: { |
669 assert(SrcTy == IceType_i8); | 665 assert(SrcTy == IceType_i8); |
670 HelperName = H_bitcast_i8_8xi1; | 666 HelperID = H_bitcast_i8_8xi1; |
671 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); | 667 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
672 // Arguments to functions are required to be at least 32 bits wide. | 668 // Arguments to functions are required to be at least 32 bits wide. |
673 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); | 669 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); |
674 Src0 = Src0AsI32; | 670 Src0 = Src0AsI32; |
675 } break; | 671 } break; |
676 case IceType_v16i1: { | 672 case IceType_v16i1: { |
677 assert(SrcTy == IceType_i16); | 673 assert(SrcTy == IceType_i16); |
678 HelperName = H_bitcast_i16_16xi1; | 674 HelperID = H_bitcast_i16_16xi1; |
679 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); | 675 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
680 // Arguments to functions are required to be at least 32 bits wide. | 676 // Arguments to functions are required to be at least 32 bits wide. |
681 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); | 677 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); |
682 Src0 = Src0AsI32; | 678 Src0 = Src0AsI32; |
683 } break; | 679 } break; |
684 } | 680 } |
685 assert(HelperName != nullptr); | |
686 constexpr SizeT MaxSrcs = 1; | 681 constexpr SizeT MaxSrcs = 1; |
687 InstCall *Call = makeHelperCall(HelperName, CallDest, MaxSrcs); | 682 InstCall *Call = makeHelperCall(HelperID, CallDest, MaxSrcs); |
688 Call->addArg(Src0); | 683 Call->addArg(Src0); |
689 Context.insert(Call); | 684 Context.insert(Call); |
690 // The PNaCl ABI disallows i8/i16 return types, so truncate the helper | 685 // The PNaCl ABI disallows i8/i16 return types, so truncate the helper |
691 // call result to the appropriate type as necessary. | 686 // call result to the appropriate type as necessary. |
692 if (CallDest->getType() != Dest->getType()) | 687 if (CallDest->getType() != Dest->getType()) |
693 Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest); | 688 Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest); |
694 Instr->setDeleted(); | 689 Instr->setDeleted(); |
695 return; | 690 return; |
696 } | 691 } |
697 } | 692 } |
698 llvm::report_fatal_error("Control flow should never have reached here."); | 693 llvm::report_fatal_error("Control flow should never have reached here."); |
699 } | 694 } |
700 case Inst::IntrinsicCall: { | 695 case Inst::IntrinsicCall: { |
701 Variable *Dest = Instr->getDest(); | 696 Variable *Dest = Instr->getDest(); |
702 auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr); | 697 auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr); |
703 Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID; | 698 Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID; |
704 switch (ID) { | 699 switch (ID) { |
705 default: | 700 default: |
706 return; | 701 return; |
707 case Intrinsics::Ctpop: { | 702 case Intrinsics::Ctpop: { |
708 Operand *Src0 = IntrinsicCall->getArg(0); | 703 Operand *Src0 = IntrinsicCall->getArg(0); |
709 Operand *TargetHelper = Ctx->getConstantExternSym( | 704 Operand *TargetHelper = getRuntimeHelperFunc( |
710 isInt32Asserting32Or64(Src0->getType()) ? H_call_ctpop_i32 | 705 isInt32Asserting32Or64(Src0->getType()) ? H_call_ctpop_i32 |
711 : H_call_ctpop_i64); | 706 : H_call_ctpop_i64); |
712 static constexpr SizeT MaxArgs = 1; | 707 static constexpr SizeT MaxArgs = 1; |
713 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 708 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
714 NoTailCall, IsTargetHelperCall); | 709 NoTailCall, IsTargetHelperCall); |
715 Call->addArg(Src0); | 710 Call->addArg(Src0); |
716 Instr->setDeleted(); | 711 Instr->setDeleted(); |
717 if (Src0->getType() == IceType_i64) { | 712 if (Src0->getType() == IceType_i64) { |
718 ARM32HelpersPostamble[TargetHelper] = &TargetARM32::postambleCtpop64; | 713 ARM32HelpersPostamble[TargetHelper] = &TargetARM32::postambleCtpop64; |
719 } | 714 } |
720 return; | 715 return; |
721 } | 716 } |
722 case Intrinsics::Longjmp: { | 717 case Intrinsics::Longjmp: { |
723 static constexpr SizeT MaxArgs = 2; | 718 static constexpr SizeT MaxArgs = 2; |
724 static constexpr Variable *NoDest = nullptr; | 719 static constexpr Variable *NoDest = nullptr; |
725 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_longjmp); | 720 Operand *TargetHelper = getRuntimeHelperFunc(H_call_longjmp); |
726 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, | 721 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, |
727 NoTailCall, IsTargetHelperCall); | 722 NoTailCall, IsTargetHelperCall); |
728 Call->addArg(IntrinsicCall->getArg(0)); | 723 Call->addArg(IntrinsicCall->getArg(0)); |
729 Call->addArg(IntrinsicCall->getArg(1)); | 724 Call->addArg(IntrinsicCall->getArg(1)); |
730 Instr->setDeleted(); | 725 Instr->setDeleted(); |
731 return; | 726 return; |
732 } | 727 } |
733 case Intrinsics::Memcpy: { | 728 case Intrinsics::Memcpy: { |
734 // In the future, we could potentially emit an inline memcpy/memset, etc. | 729 // In the future, we could potentially emit an inline memcpy/memset, etc. |
735 // for intrinsic calls w/ a known length. | 730 // for intrinsic calls w/ a known length. |
736 static constexpr SizeT MaxArgs = 3; | 731 static constexpr SizeT MaxArgs = 3; |
737 static constexpr Variable *NoDest = nullptr; | 732 static constexpr Variable *NoDest = nullptr; |
738 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memcpy); | 733 Operand *TargetHelper = getRuntimeHelperFunc(H_call_memcpy); |
739 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, | 734 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, |
740 NoTailCall, IsTargetHelperCall); | 735 NoTailCall, IsTargetHelperCall); |
741 Call->addArg(IntrinsicCall->getArg(0)); | 736 Call->addArg(IntrinsicCall->getArg(0)); |
742 Call->addArg(IntrinsicCall->getArg(1)); | 737 Call->addArg(IntrinsicCall->getArg(1)); |
743 Call->addArg(IntrinsicCall->getArg(2)); | 738 Call->addArg(IntrinsicCall->getArg(2)); |
744 Instr->setDeleted(); | 739 Instr->setDeleted(); |
745 return; | 740 return; |
746 } | 741 } |
747 case Intrinsics::Memmove: { | 742 case Intrinsics::Memmove: { |
748 static constexpr SizeT MaxArgs = 3; | 743 static constexpr SizeT MaxArgs = 3; |
749 static constexpr Variable *NoDest = nullptr; | 744 static constexpr Variable *NoDest = nullptr; |
750 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memmove); | 745 Operand *TargetHelper = getRuntimeHelperFunc(H_call_memmove); |
751 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, | 746 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, |
752 NoTailCall, IsTargetHelperCall); | 747 NoTailCall, IsTargetHelperCall); |
753 Call->addArg(IntrinsicCall->getArg(0)); | 748 Call->addArg(IntrinsicCall->getArg(0)); |
754 Call->addArg(IntrinsicCall->getArg(1)); | 749 Call->addArg(IntrinsicCall->getArg(1)); |
755 Call->addArg(IntrinsicCall->getArg(2)); | 750 Call->addArg(IntrinsicCall->getArg(2)); |
756 Instr->setDeleted(); | 751 Instr->setDeleted(); |
757 return; | 752 return; |
758 } | 753 } |
759 case Intrinsics::Memset: { | 754 case Intrinsics::Memset: { |
760 // The value operand needs to be extended to a stack slot size because the | 755 // The value operand needs to be extended to a stack slot size because the |
761 // PNaCl ABI requires arguments to be at least 32 bits wide. | 756 // PNaCl ABI requires arguments to be at least 32 bits wide. |
762 Operand *ValOp = IntrinsicCall->getArg(1); | 757 Operand *ValOp = IntrinsicCall->getArg(1); |
763 assert(ValOp->getType() == IceType_i8); | 758 assert(ValOp->getType() == IceType_i8); |
764 Variable *ValExt = Func->makeVariable(stackSlotType()); | 759 Variable *ValExt = Func->makeVariable(stackSlotType()); |
765 Context.insert<InstCast>(InstCast::Zext, ValExt, ValOp); | 760 Context.insert<InstCast>(InstCast::Zext, ValExt, ValOp); |
766 | 761 |
767 // Technically, ARM has its own __aeabi_memset, but we can use plain | 762 // Technically, ARM has its own __aeabi_memset, but we can use plain |
768 // memset too. The value and size argument need to be flipped if we ever | 763 // memset too. The value and size argument need to be flipped if we ever |
769 // decide to use __aeabi_memset. | 764 // decide to use __aeabi_memset. |
770 static constexpr SizeT MaxArgs = 3; | 765 static constexpr SizeT MaxArgs = 3; |
771 static constexpr Variable *NoDest = nullptr; | 766 static constexpr Variable *NoDest = nullptr; |
772 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memset); | 767 Operand *TargetHelper = getRuntimeHelperFunc(H_call_memset); |
773 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, | 768 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, |
774 NoTailCall, IsTargetHelperCall); | 769 NoTailCall, IsTargetHelperCall); |
775 Call->addArg(IntrinsicCall->getArg(0)); | 770 Call->addArg(IntrinsicCall->getArg(0)); |
776 Call->addArg(ValExt); | 771 Call->addArg(ValExt); |
777 Call->addArg(IntrinsicCall->getArg(2)); | 772 Call->addArg(IntrinsicCall->getArg(2)); |
778 Instr->setDeleted(); | 773 Instr->setDeleted(); |
779 return; | 774 return; |
780 } | 775 } |
781 case Intrinsics::NaClReadTP: { | 776 case Intrinsics::NaClReadTP: { |
782 if (SandboxingType == ST_NaCl) { | 777 if (SandboxingType == ST_NaCl) { |
783 return; | 778 return; |
784 } | 779 } |
785 static constexpr SizeT MaxArgs = 0; | 780 static constexpr SizeT MaxArgs = 0; |
786 const char *ReadTP = | 781 Operand *TargetHelper = SandboxingType == ST_Nonsfi |
787 SandboxingType == ST_Nonsfi ? "__aeabi_read_tp" : H_call_read_tp; | 782 ? Ctx->getConstantExternSym("__aeabi_read_tp") |
788 Operand *TargetHelper = Ctx->getConstantExternSym(ReadTP); | 783 : getRuntimeHelperFunc(H_call_read_tp); |
789 Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall, | 784 Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall, |
790 IsTargetHelperCall); | 785 IsTargetHelperCall); |
791 Instr->setDeleted(); | 786 Instr->setDeleted(); |
792 return; | 787 return; |
793 } | 788 } |
794 case Intrinsics::Setjmp: { | 789 case Intrinsics::Setjmp: { |
795 static constexpr SizeT MaxArgs = 1; | 790 static constexpr SizeT MaxArgs = 1; |
796 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_setjmp); | 791 Operand *TargetHelper = getRuntimeHelperFunc(H_call_setjmp); |
797 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 792 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
798 NoTailCall, IsTargetHelperCall); | 793 NoTailCall, IsTargetHelperCall); |
799 Call->addArg(IntrinsicCall->getArg(0)); | 794 Call->addArg(IntrinsicCall->getArg(0)); |
800 Instr->setDeleted(); | 795 Instr->setDeleted(); |
801 return; | 796 return; |
802 } | 797 } |
803 } | 798 } |
804 llvm::report_fatal_error("Control flow should never have reached here."); | 799 llvm::report_fatal_error("Control flow should never have reached here."); |
805 } | 800 } |
806 case Inst::Icmp: { | 801 case Inst::Icmp: { |
(...skipping 6090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6897 // However, for compatibility with current NaCl LLVM, don't claim that. | 6892 // However, for compatibility with current NaCl LLVM, don't claim that. |
6898 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 6893 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
6899 } | 6894 } |
6900 | 6895 |
6901 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; | 6896 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; |
6902 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; | 6897 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; |
6903 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 6898 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
6904 | 6899 |
6905 } // end of namespace ARM32 | 6900 } // end of namespace ARM32 |
6906 } // end of namespace Ice | 6901 } // end of namespace Ice |
OLD | NEW |