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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1775253003: Cache common constants before lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Clean up code. Created 4 years, 9 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
OLDNEW
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
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 RuntimeHelperFuncKind HelperName = H_Num;
Jim Stichnoth 2016/03/10 00:24:46 Nit: it's more of a HelperID than a HelperName.
Karl 2016/03/16 22:50:52 Changed to HelperID.
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 HelperName = H_udiv_i64;
477 break; 477 break;
478 case InstArithmetic::Sdiv: 478 case InstArithmetic::Sdiv:
479 TargetHelper = Ctx->getConstantExternSym(H_sdiv_i64); 479 HelperName = H_sdiv_i64;
480 break; 480 break;
481 case InstArithmetic::Urem: 481 case InstArithmetic::Urem:
482 TargetHelper = Ctx->getConstantExternSym(H_urem_i64); 482 HelperName = H_urem_i64;
483 break; 483 break;
484 case InstArithmetic::Srem: 484 case InstArithmetic::Srem:
485 TargetHelper = Ctx->getConstantExternSym(H_srem_i64); 485 HelperName = H_srem_i64;
486 break; 486 break;
487 } 487 }
488 assert(TargetHelper != nullptr); 488 Operand *TargetHelper = getRuntimeHelperFunc(HelperName);
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 RuntimeHelperFuncKind HelperName = 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 HelperName = 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 HelperName = 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 HelperName = 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 HelperName = 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 (HelperName == H_Num) {
529 // TargetHelper should only ever be nullptr when the processor does not 525 // HelperName 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
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(HelperName);
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);
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
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 RuntimeHelperFuncKind HelperName = 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 HelperName = 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);
(...skipping 10 matching lines...) Expand all
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 HelperName = 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(HelperName, 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 1905 matching lines...) Expand 10 before | Expand all | Expand 10 after
2712 if (ShAmtImm >= 32) { 2707 if (ShAmtImm >= 32) {
2713 if (ShAmtImm == 32) { 2708 if (ShAmtImm == 32) {
2714 _mov(DestHi, Src0RLo); 2709 _mov(DestHi, Src0RLo);
2715 } else { 2710 } else {
2716 Operand *ShAmtOp = shAmtImm(ShAmtImm - 32); 2711 Operand *ShAmtOp = shAmtImm(ShAmtImm - 32);
2717 _lsl(T_Hi, Src0RLo, ShAmtOp); 2712 _lsl(T_Hi, Src0RLo, ShAmtOp);
2718 _mov(DestHi, T_Hi); 2713 _mov(DestHi, T_Hi);
2719 } 2714 }
2720 2715
2721 Operand *_0 = 2716 Operand *_0 =
2722 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); 2717 legalize(getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
2723 _mov(T_Lo, _0); 2718 _mov(T_Lo, _0);
2724 _mov(DestLo, T_Lo); 2719 _mov(DestLo, T_Lo);
2725 return; 2720 return;
2726 } 2721 }
2727 2722
2728 Variable *Src0RHi = SrcsHi.src0R(this); 2723 Variable *Src0RHi = SrcsHi.src0R(this);
2729 Operand *ShAmtOp = shAmtImm(ShAmtImm); 2724 Operand *ShAmtOp = shAmtImm(ShAmtImm);
2730 Operand *ComplShAmtOp = shAmtImm(32 - ShAmtImm); 2725 Operand *ComplShAmtOp = shAmtImm(32 - ShAmtImm);
2731 _lsl(T_Hi, Src0RHi, ShAmtOp); 2726 _lsl(T_Hi, Src0RHi, ShAmtOp);
2732 _orr(T_Hi, T_Hi, 2727 _orr(T_Hi, T_Hi,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2765 // a.hi = t_hi 2760 // a.hi = t_hi
2766 // 2761 //
2767 // These are incompatible, therefore we mimic pnacl-llc. 2762 // These are incompatible, therefore we mimic pnacl-llc.
2768 // Can be strength-reduced for constant-shifts, but we don't do that for 2763 // Can be strength-reduced for constant-shifts, but we don't do that for
2769 // now. 2764 // now.
2770 // Given the sub/rsb T_C, C.lo, #32, one of the T_C will be negative. On 2765 // Given the sub/rsb T_C, C.lo, #32, one of the T_C will be negative. On
2771 // ARM, shifts only take the lower 8 bits of the shift register, and 2766 // ARM, shifts only take the lower 8 bits of the shift register, and
2772 // saturate to the range 0-32, so the negative value will saturate to 32. 2767 // saturate to the range 0-32, so the negative value will saturate to 32.
2773 Operand *_32 = legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex); 2768 Operand *_32 = legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex);
2774 Operand *_0 = 2769 Operand *_0 =
2775 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); 2770 legalize(getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
2776 Variable *T0 = makeReg(IceType_i32); 2771 Variable *T0 = makeReg(IceType_i32);
2777 Variable *T1 = makeReg(IceType_i32); 2772 Variable *T1 = makeReg(IceType_i32);
2778 Variable *T2 = makeReg(IceType_i32); 2773 Variable *T2 = makeReg(IceType_i32);
2779 Variable *TA_Hi = makeReg(IceType_i32); 2774 Variable *TA_Hi = makeReg(IceType_i32);
2780 Variable *TA_Lo = makeReg(IceType_i32); 2775 Variable *TA_Lo = makeReg(IceType_i32);
2781 Variable *Src0RLo = SrcsLo.unswappedSrc0R(this); 2776 Variable *Src0RLo = SrcsLo.unswappedSrc0R(this);
2782 Variable *Src0RHi = SrcsHi.unswappedSrc0R(this); 2777 Variable *Src0RHi = SrcsHi.unswappedSrc0R(this);
2783 Variable *Src1RLo = SrcsLo.unswappedSrc1R(this); 2778 Variable *Src1RLo = SrcsLo.unswappedSrc1R(this);
2784 _rsb(T0, Src1RLo, _32); 2779 _rsb(T0, Src1RLo, _32);
2785 _lsr(T1, Src0RLo, T0); 2780 _lsr(T1, Src0RLo, T0);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 } else { 2812 } else {
2818 _lsr(T_Lo, Src0RHi, ShAmtImm); 2813 _lsr(T_Lo, Src0RHi, ShAmtImm);
2819 } 2814 }
2820 _mov(DestLo, T_Lo); 2815 _mov(DestLo, T_Lo);
2821 } 2816 }
2822 2817
2823 if (ASR) { 2818 if (ASR) {
2824 Operand *_31 = shAmtImm(31); 2819 Operand *_31 = shAmtImm(31);
2825 _asr(T_Hi, Src0RHi, _31); 2820 _asr(T_Hi, Src0RHi, _31);
2826 } else { 2821 } else {
2827 Operand *_0 = legalize(Ctx->getConstantZero(IceType_i32), 2822 Operand *_0 =
2828 Legal_Reg | Legal_Flex); 2823 legalize(getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
2829 _mov(T_Hi, _0); 2824 _mov(T_Hi, _0);
2830 } 2825 }
2831 _mov(DestHi, T_Hi); 2826 _mov(DestHi, T_Hi);
2832 return; 2827 return;
2833 } 2828 }
2834 2829
2835 Variable *Src0RLo = SrcsLo.src0R(this); 2830 Variable *Src0RLo = SrcsLo.src0R(this);
2836 Operand *ShAmtImm = shAmtImm(ShAmt); 2831 Operand *ShAmtImm = shAmtImm(ShAmt);
2837 Operand *ComplShAmtImm = shAmtImm(32 - ShAmt); 2832 Operand *ComplShAmtImm = shAmtImm(32 - ShAmt);
2838 _lsr(T_Lo, Src0RLo, ShAmtImm); 2833 _lsr(T_Lo, Src0RLo, ShAmtImm);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2871 // orr t_lo, t_lo, b.hi, lsl t_c1 2866 // orr t_lo, t_lo, b.hi, lsl t_c1
2872 // sub t_c2, c.lo, #32 2867 // sub t_c2, c.lo, #32
2873 // orr t_lo, t_lo, b.hi, lsr t_c2 2868 // orr t_lo, t_lo, b.hi, lsr t_c2
2874 // lsr t_hi, b.hi, c.lo 2869 // lsr t_hi, b.hi, c.lo
2875 // mov a.lo, t_lo 2870 // mov a.lo, t_lo
2876 // mov a.hi, t_hi 2871 // mov a.hi, t_hi
2877 // 2872 //
2878 // These are incompatible, therefore we mimic pnacl-llc. 2873 // These are incompatible, therefore we mimic pnacl-llc.
2879 Operand *_32 = legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex); 2874 Operand *_32 = legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex);
2880 Operand *_0 = 2875 Operand *_0 =
2881 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); 2876 legalize(getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
2882 Variable *T0 = makeReg(IceType_i32); 2877 Variable *T0 = makeReg(IceType_i32);
2883 Variable *T1 = makeReg(IceType_i32); 2878 Variable *T1 = makeReg(IceType_i32);
2884 Variable *T2 = makeReg(IceType_i32); 2879 Variable *T2 = makeReg(IceType_i32);
2885 Variable *TA_Lo = makeReg(IceType_i32); 2880 Variable *TA_Lo = makeReg(IceType_i32);
2886 Variable *TA_Hi = makeReg(IceType_i32); 2881 Variable *TA_Hi = makeReg(IceType_i32);
2887 Variable *Src0RLo = SrcsLo.unswappedSrc0R(this); 2882 Variable *Src0RLo = SrcsLo.unswappedSrc0R(this);
2888 Variable *Src0RHi = SrcsHi.unswappedSrc0R(this); 2883 Variable *Src0RHi = SrcsHi.unswappedSrc0R(this);
2889 Variable *Src1RLo = SrcsLo.unswappedSrc1R(this); 2884 Variable *Src1RLo = SrcsLo.unswappedSrc1R(this);
2890 _lsr(T0, Src0RLo, Src1RLo); 2885 _lsr(T0, Src0RLo, Src1RLo);
2891 _rsb(T1, Src1RLo, _32); 2886 _rsb(T1, Src1RLo, _32);
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
3337 } 3332 }
3338 case InstArithmetic::Mul: { 3333 case InstArithmetic::Mul: {
3339 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; 3334 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1;
3340 if (!OptM1 && Srcs.hasConstOperand()) { 3335 if (!OptM1 && Srcs.hasConstOperand()) {
3341 constexpr std::size_t MaxShifts = 4; 3336 constexpr std::size_t MaxShifts = 4;
3342 std::array<StrengthReduction::AggregationElement, MaxShifts> Shifts; 3337 std::array<StrengthReduction::AggregationElement, MaxShifts> Shifts;
3343 SizeT NumOperations; 3338 SizeT NumOperations;
3344 int32_t Const = Srcs.getConstantValue(); 3339 int32_t Const = Srcs.getConstantValue();
3345 const bool Invert = Const < 0; 3340 const bool Invert = Const < 0;
3346 const bool MultiplyByZero = Const == 0; 3341 const bool MultiplyByZero = Const == 0;
3347 Operand *_0 = 3342 Operand *_0 = legalize(getConstantZero(DestTy), Legal_Reg | Legal_Flex);
3348 legalize(Ctx->getConstantZero(DestTy), Legal_Reg | Legal_Flex);
3349 3343
3350 if (MultiplyByZero) { 3344 if (MultiplyByZero) {
3351 _mov(T, _0); 3345 _mov(T, _0);
3352 _mov(Dest, T); 3346 _mov(Dest, T);
3353 return; 3347 return;
3354 } 3348 }
3355 3349
3356 if (Invert) { 3350 if (Invert) {
3357 Const = -Const; 3351 Const = -Const;
3358 } 3352 }
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
3858 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 3852 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
3859 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 3853 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
3860 Variable *T_Lo = makeReg(DestLo->getType()); 3854 Variable *T_Lo = makeReg(DestLo->getType());
3861 if (Src0->getType() == IceType_i32) { 3855 if (Src0->getType() == IceType_i32) {
3862 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); 3856 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex);
3863 _mov(T_Lo, Src0RF); 3857 _mov(T_Lo, Src0RF);
3864 } else if (Src0->getType() != IceType_i1) { 3858 } else if (Src0->getType() != IceType_i1) {
3865 Variable *Src0R = legalizeToReg(Src0); 3859 Variable *Src0R = legalizeToReg(Src0);
3866 _sxt(T_Lo, Src0R); 3860 _sxt(T_Lo, Src0R);
3867 } else { 3861 } else {
3868 Operand *_0 = Ctx->getConstantZero(IceType_i32); 3862 Operand *_0 = getConstantZero(IceType_i32);
3869 Operand *_m1 = Ctx->getConstantInt32(-1); 3863 Operand *_m1 = Ctx->getConstantInt32(-1);
3870 lowerInt1ForSelect(T_Lo, Src0, _m1, _0); 3864 lowerInt1ForSelect(T_Lo, Src0, _m1, _0);
3871 } 3865 }
3872 _mov(DestLo, T_Lo); 3866 _mov(DestLo, T_Lo);
3873 Variable *T_Hi = makeReg(DestHi->getType()); 3867 Variable *T_Hi = makeReg(DestHi->getType());
3874 if (Src0->getType() != IceType_i1) { 3868 if (Src0->getType() != IceType_i1) {
3875 _mov(T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, T_Lo, 3869 _mov(T_Hi, OperandARM32FlexReg::create(Func, IceType_i32, T_Lo,
3876 OperandARM32::ASR, ShiftAmt)); 3870 OperandARM32::ASR, ShiftAmt));
3877 } else { 3871 } else {
3878 // For i1, the asr instruction is already done above. 3872 // For i1, the asr instruction is already done above.
3879 _mov(T_Hi, T_Lo); 3873 _mov(T_Hi, T_Lo);
3880 } 3874 }
3881 _mov(DestHi, T_Hi); 3875 _mov(DestHi, T_Hi);
3882 } else if (Src0->getType() != IceType_i1) { 3876 } else if (Src0->getType() != IceType_i1) {
3883 // t1 = sxt src; dst = t1 3877 // t1 = sxt src; dst = t1
3884 Variable *Src0R = legalizeToReg(Src0); 3878 Variable *Src0R = legalizeToReg(Src0);
3885 Variable *T = makeReg(Dest->getType()); 3879 Variable *T = makeReg(Dest->getType());
3886 _sxt(T, Src0R); 3880 _sxt(T, Src0R);
3887 _mov(Dest, T); 3881 _mov(Dest, T);
3888 } else { 3882 } else {
3889 Constant *_0 = Ctx->getConstantZero(IceType_i32); 3883 Constant *_0 = getConstantZero(IceType_i32);
3890 Operand *_m1 = Ctx->getConstantInt(Dest->getType(), -1); 3884 Operand *_m1 = Ctx->getConstantInt(Dest->getType(), -1);
3891 Variable *T = makeReg(Dest->getType()); 3885 Variable *T = makeReg(Dest->getType());
3892 lowerInt1ForSelect(T, Src0, _m1, _0); 3886 lowerInt1ForSelect(T, Src0, _m1, _0);
3893 _mov(Dest, T); 3887 _mov(Dest, T);
3894 } 3888 }
3895 break; 3889 break;
3896 } 3890 }
3897 case InstCast::Zext: { 3891 case InstCast::Zext: {
3898 if (isVectorType(Dest->getType())) { 3892 if (isVectorType(Dest->getType())) {
3899 UnimplementedLoweringError(this, Instr); 3893 UnimplementedLoweringError(this, Instr);
3900 } else if (Dest->getType() == IceType_i64) { 3894 } else if (Dest->getType() == IceType_i64) {
3901 // t1=uxtb src; dst.lo=t1; dst.hi=0 3895 // t1=uxtb src; dst.lo=t1; dst.hi=0
3902 Operand *_0 = 3896 Operand *_0 =
3903 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); 3897 legalize(getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
3904 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 3898 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
3905 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 3899 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
3906 Variable *T_Lo = makeReg(DestLo->getType()); 3900 Variable *T_Lo = makeReg(DestLo->getType());
3907 3901
3908 switch (Src0->getType()) { 3902 switch (Src0->getType()) {
3909 default: { 3903 default: {
3910 assert(Src0->getType() != IceType_i64); 3904 assert(Src0->getType() != IceType_i64);
3911 _uxt(T_Lo, legalizeToReg(Src0)); 3905 _uxt(T_Lo, legalizeToReg(Src0));
3912 } break; 3906 } break;
3913 case IceType_i32: { 3907 case IceType_i32: {
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
4246 4240
4247 void TargetARM32::lowerFcmp(const InstFcmp *Instr) { 4241 void TargetARM32::lowerFcmp(const InstFcmp *Instr) {
4248 Variable *Dest = Instr->getDest(); 4242 Variable *Dest = Instr->getDest();
4249 if (isVectorType(Dest->getType())) { 4243 if (isVectorType(Dest->getType())) {
4250 UnimplementedLoweringError(this, Instr); 4244 UnimplementedLoweringError(this, Instr);
4251 return; 4245 return;
4252 } 4246 }
4253 4247
4254 Variable *T = makeReg(IceType_i1); 4248 Variable *T = makeReg(IceType_i1);
4255 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex); 4249 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex);
4256 Operand *_0 = 4250 Operand *_0 = legalize(getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
4257 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
4258 4251
4259 CondWhenTrue Cond = lowerFcmpCond(Instr); 4252 CondWhenTrue Cond = lowerFcmpCond(Instr);
4260 4253
4261 bool RedefineT = false; 4254 bool RedefineT = false;
4262 if (Cond.WhenTrue0 != CondARM32::AL) { 4255 if (Cond.WhenTrue0 != CondARM32::AL) {
4263 _mov(T, _0); 4256 _mov(T, _0);
4264 RedefineT = true; 4257 RedefineT = true;
4265 } 4258 }
4266 4259
4267 if (Cond.WhenTrue0 == CondARM32::kNone) { 4260 if (Cond.WhenTrue0 == CondARM32::kNone) {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 } 4537 }
4545 4538
4546 void TargetARM32::lowerIcmp(const InstIcmp *Instr) { 4539 void TargetARM32::lowerIcmp(const InstIcmp *Instr) {
4547 Variable *Dest = Instr->getDest(); 4540 Variable *Dest = Instr->getDest();
4548 4541
4549 if (isVectorType(Dest->getType())) { 4542 if (isVectorType(Dest->getType())) {
4550 UnimplementedLoweringError(this, Instr); 4543 UnimplementedLoweringError(this, Instr);
4551 return; 4544 return;
4552 } 4545 }
4553 4546
4554 Operand *_0 = 4547 Operand *_0 = legalize(getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
4555 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
4556 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex); 4548 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex);
4557 Variable *T = makeReg(IceType_i1); 4549 Variable *T = makeReg(IceType_i1);
4558 4550
4559 _mov(T, _0); 4551 _mov(T, _0);
4560 CondWhenTrue Cond = lowerIcmpCond(Instr); 4552 CondWhenTrue Cond = lowerIcmpCond(Instr);
4561 _mov_redefined(T, _1, Cond.WhenTrue0); 4553 _mov_redefined(T, _1, Cond.WhenTrue0);
4562 _mov(Dest, T); 4554 _mov(Dest, T);
4563 4555
4564 assert(Cond.WhenTrue1 == CondARM32::kNone); 4556 assert(Cond.WhenTrue1 == CondARM32::kNone);
4565 4557
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4601 4593
4602 void TargetARM32::lowerLoadLinkedStoreExclusive( 4594 void TargetARM32::lowerLoadLinkedStoreExclusive(
4603 Type Ty, Operand *Addr, std::function<Variable *(Variable *)> Operation, 4595 Type Ty, Operand *Addr, std::function<Variable *(Variable *)> Operation,
4604 CondARM32::Cond Cond) { 4596 CondARM32::Cond Cond) {
4605 4597
4606 auto *Retry = Context.insert<InstARM32Label>(this); 4598 auto *Retry = Context.insert<InstARM32Label>(this);
4607 4599
4608 { // scoping for loop highlighting. 4600 { // scoping for loop highlighting.
4609 Variable *Success = makeReg(IceType_i32); 4601 Variable *Success = makeReg(IceType_i32);
4610 Variable *Tmp = (Ty == IceType_i64) ? makeI64RegPair() : makeReg(Ty); 4602 Variable *Tmp = (Ty == IceType_i64) ? makeI64RegPair() : makeReg(Ty);
4611 auto *_0 = Ctx->getConstantZero(IceType_i32); 4603 auto *_0 = getConstantZero(IceType_i32);
4612 4604
4613 Context.insert<InstFakeDef>(Tmp); 4605 Context.insert<InstFakeDef>(Tmp);
4614 Context.insert<InstFakeUse>(Tmp); 4606 Context.insert<InstFakeUse>(Tmp);
4615 Variable *AddrR = legalizeToReg(Addr); 4607 Variable *AddrR = legalizeToReg(Addr);
4616 _ldrex(Tmp, formMemoryOperand(AddrR, Ty))->setDestRedefined(); 4608 _ldrex(Tmp, formMemoryOperand(AddrR, Ty))->setDestRedefined();
4617 auto *StoreValue = Operation(Tmp); 4609 auto *StoreValue = Operation(Tmp);
4618 assert(StoreValue->mustHaveReg()); 4610 assert(StoreValue->mustHaveReg());
4619 // strex requires Dest to be a register other than Value or Addr. This 4611 // strex requires Dest to be a register other than Value or Addr. This
4620 // restriction is cleanly represented by adding an "early" definition of 4612 // restriction is cleanly represented by adding an "early" definition of
4621 // Dest (or a latter use of all the sources.) 4613 // Dest (or a latter use of all the sources.)
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4766 Operand *Arg0 = Instr->getArg(0); 4758 Operand *Arg0 = Instr->getArg(0);
4767 if (isInt32Asserting32Or64(Arg0->getType())) { 4759 if (isInt32Asserting32Or64(Arg0->getType())) {
4768 return; 4760 return;
4769 } 4761 }
4770 // The popcount helpers always return 32-bit values, while the intrinsic's 4762 // The popcount helpers always return 32-bit values, while the intrinsic's
4771 // signature matches some 64-bit platform's native instructions and expect to 4763 // signature matches some 64-bit platform's native instructions and expect to
4772 // fill a 64-bit reg. Thus, clear the upper bits of the dest just in case the 4764 // fill a 64-bit reg. Thus, clear the upper bits of the dest just in case the
4773 // user doesn't do that in the IR or doesn't toss the bits via truncate. 4765 // user doesn't do that in the IR or doesn't toss the bits via truncate.
4774 auto *DestHi = llvm::cast<Variable>(hiOperand(Instr->getDest())); 4766 auto *DestHi = llvm::cast<Variable>(hiOperand(Instr->getDest()));
4775 Variable *T = makeReg(IceType_i32); 4767 Variable *T = makeReg(IceType_i32);
4776 Operand *_0 = 4768 Operand *_0 = legalize(getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
4777 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
4778 _mov(T, _0); 4769 _mov(T, _0);
4779 _mov(DestHi, T); 4770 _mov(DestHi, T);
4780 } 4771 }
4781 4772
4782 void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { 4773 void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
4783 Variable *Dest = Instr->getDest(); 4774 Variable *Dest = Instr->getDest();
4784 Type DestTy = (Dest != nullptr) ? Dest->getType() : IceType_void; 4775 Type DestTy = (Dest != nullptr) ? Dest->getType() : IceType_void;
4785 Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID; 4776 Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID;
4786 switch (ID) { 4777 switch (ID) {
4787 case Intrinsics::AtomicFence: 4778 case Intrinsics::AtomicFence:
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
5057 } 5048 }
5058 case Intrinsics::Memset: { 5049 case Intrinsics::Memset: {
5059 llvm::report_fatal_error("memmove should have been prelowered."); 5050 llvm::report_fatal_error("memmove should have been prelowered.");
5060 } 5051 }
5061 case Intrinsics::NaClReadTP: { 5052 case Intrinsics::NaClReadTP: {
5062 if (SandboxingType != ST_NaCl) { 5053 if (SandboxingType != ST_NaCl) {
5063 llvm::report_fatal_error("nacl-read-tp should have been prelowered."); 5054 llvm::report_fatal_error("nacl-read-tp should have been prelowered.");
5064 } 5055 }
5065 Variable *TP = legalizeToReg(OperandARM32Mem::create( 5056 Variable *TP = legalizeToReg(OperandARM32Mem::create(
5066 Func, getPointerType(), getPhysicalRegister(RegARM32::Reg_r9), 5057 Func, getPointerType(), getPhysicalRegister(RegARM32::Reg_r9),
5067 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32)))); 5058 llvm::cast<ConstantInteger32>(getConstantZero(IceType_i32))));
5068 _mov(Dest, TP); 5059 _mov(Dest, TP);
5069 return; 5060 return;
5070 } 5061 }
5071 case Intrinsics::Setjmp: { 5062 case Intrinsics::Setjmp: {
5072 llvm::report_fatal_error("setjmp should have been prelowered."); 5063 llvm::report_fatal_error("setjmp should have been prelowered.");
5073 } 5064 }
5074 case Intrinsics::Sqrt: { 5065 case Intrinsics::Sqrt: {
5075 Variable *Src = legalizeToReg(Instr->getArg(0)); 5066 Variable *Src = legalizeToReg(Instr->getArg(0));
5076 Variable *T = makeReg(Dest->getType()); 5067 Variable *T = makeReg(Dest->getType());
5077 _vsqrt(T, Src); 5068 _vsqrt(T, Src);
(...skipping 22 matching lines...) Expand all
5100 5091
5101 void TargetARM32::lowerCLZ(Variable *Dest, Variable *ValLoR, Variable *ValHiR) { 5092 void TargetARM32::lowerCLZ(Variable *Dest, Variable *ValLoR, Variable *ValHiR) {
5102 Type Ty = Dest->getType(); 5093 Type Ty = Dest->getType();
5103 assert(Ty == IceType_i32 || Ty == IceType_i64); 5094 assert(Ty == IceType_i32 || Ty == IceType_i64);
5104 Variable *T = makeReg(IceType_i32); 5095 Variable *T = makeReg(IceType_i32);
5105 _clz(T, ValLoR); 5096 _clz(T, ValLoR);
5106 if (Ty == IceType_i64) { 5097 if (Ty == IceType_i64) {
5107 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 5098 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
5108 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 5099 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
5109 Operand *Zero = 5100 Operand *Zero =
5110 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); 5101 legalize(getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
5111 Operand *ThirtyTwo = 5102 Operand *ThirtyTwo =
5112 legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex); 5103 legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex);
5113 _cmp(ValHiR, Zero); 5104 _cmp(ValHiR, Zero);
5114 Variable *T2 = makeReg(IceType_i32); 5105 Variable *T2 = makeReg(IceType_i32);
5115 _add(T2, T, ThirtyTwo); 5106 _add(T2, T, ThirtyTwo);
5116 _clz(T2, ValHiR, CondARM32::NE); 5107 _clz(T2, ValHiR, CondARM32::NE);
5117 // T2 is actually a source as well when the predicate is not AL (since it 5108 // T2 is actually a source as well when the predicate is not AL (since it
5118 // may leave T2 alone). We use _set_dest_redefined to prolong the liveness 5109 // may leave T2 alone). We use _set_dest_redefined to prolong the liveness
5119 // of T2 as if it was used as a source. 5110 // of T2 as if it was used as a source.
5120 _set_dest_redefined(); 5111 _set_dest_redefined();
(...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after
6044 // in less predictable code. 6035 // in less predictable code.
6045 // 6036 //
6046 // If in the future the implementation is changed to lower undef values to 6037 // If in the future the implementation is changed to lower undef values to
6047 // uninitialized registers, a FakeDef will be needed: 6038 // uninitialized registers, a FakeDef will be needed:
6048 // Context.insert(InstFakeDef::create(Func, Reg)); This is in order to 6039 // Context.insert(InstFakeDef::create(Func, Reg)); This is in order to
6049 // ensure that the live range of Reg is not overestimated. If the constant 6040 // ensure that the live range of Reg is not overestimated. If the constant
6050 // being lowered is a 64 bit value, then the result should be split and the 6041 // being lowered is a 64 bit value, then the result should be split and the
6051 // lo and hi components will need to go in uninitialized registers. 6042 // lo and hi components will need to go in uninitialized registers.
6052 if (isVectorType(Ty)) 6043 if (isVectorType(Ty))
6053 return makeVectorOfZeros(Ty, RegNum); 6044 return makeVectorOfZeros(Ty, RegNum);
6054 return Ctx->getConstantZero(Ty); 6045 return getConstantZero(Ty);
6055 } 6046 }
6056 return From; 6047 return From;
6057 } 6048 }
6058 6049
6059 OperandARM32Mem *TargetARM32::formMemoryOperand(Operand *Operand, Type Ty) { 6050 OperandARM32Mem *TargetARM32::formMemoryOperand(Operand *Operand, Type Ty) {
6060 auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand); 6051 auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand);
6061 // It may be the case that address mode optimization already creates an 6052 // It may be the case that address mode optimization already creates an
6062 // OperandARM32Mem, so in that case it wouldn't need another level of 6053 // OperandARM32Mem, so in that case it wouldn't need another level of
6063 // transformation. 6054 // transformation.
6064 if (Mem) { 6055 if (Mem) {
6065 return llvm::cast<OperandARM32Mem>(legalize(Mem)); 6056 return llvm::cast<OperandARM32Mem>(legalize(Mem));
6066 } 6057 }
6067 // If we didn't do address mode optimization, then we only have a 6058 // If we didn't do address mode optimization, then we only have a
6068 // base/offset to work with. ARM always requires a base register, so 6059 // base/offset to work with. ARM always requires a base register, so
6069 // just use that to hold the operand. 6060 // just use that to hold the operand.
6070 auto *Base = llvm::cast<Variable>( 6061 auto *Base = llvm::cast<Variable>(
6071 legalize(Operand, Legal_Reg | Legal_Rematerializable)); 6062 legalize(Operand, Legal_Reg | Legal_Rematerializable));
6072 return OperandARM32Mem::create( 6063 return OperandARM32Mem::create(
6073 Func, Ty, Base, 6064 Func, Ty, Base,
6074 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))); 6065 llvm::cast<ConstantInteger32>(getConstantZero(IceType_i32)));
6075 } 6066 }
6076 6067
6077 Variable64On32 *TargetARM32::makeI64RegPair() { 6068 Variable64On32 *TargetARM32::makeI64RegPair() {
6078 Variable64On32 *Reg = 6069 Variable64On32 *Reg =
6079 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); 6070 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
6080 Reg->setMustHaveReg(); 6071 Reg->setMustHaveReg();
6081 Reg->initHiLo(Func); 6072 Reg->initHiLo(Func);
6082 Reg->getLo()->setMustNotHaveReg(); 6073 Reg->getLo()->setMustNotHaveReg();
6083 Reg->getHi()->setMustNotHaveReg(); 6074 Reg->getHi()->setMustNotHaveReg();
6084 return Reg; 6075 return Reg;
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
6287 _mov(DestLo, T_Lo); 6278 _mov(DestLo, T_Lo);
6288 if (DestHi) { 6279 if (DestHi) {
6289 _mov(DestHi, T_Hi); 6280 _mov(DestHi, T_Hi);
6290 } 6281 }
6291 } 6282 }
6292 6283
6293 TargetARM32::SafeBoolChain TargetARM32::lowerInt1(Variable *Dest, 6284 TargetARM32::SafeBoolChain TargetARM32::lowerInt1(Variable *Dest,
6294 Operand *Boolean) { 6285 Operand *Boolean) {
6295 assert(Boolean->getType() == IceType_i1); 6286 assert(Boolean->getType() == IceType_i1);
6296 Variable *T = makeReg(IceType_i1); 6287 Variable *T = makeReg(IceType_i1);
6297 Operand *_0 = 6288 Operand *_0 = legalize(getConstantZero(IceType_i1), Legal_Reg | Legal_Flex);
6298 legalize(Ctx->getConstantZero(IceType_i1), Legal_Reg | Legal_Flex);
6299 Operand *_1 = legalize(Ctx->getConstantInt1(1), Legal_Reg | Legal_Flex); 6289 Operand *_1 = legalize(Ctx->getConstantInt1(1), Legal_Reg | Legal_Flex);
6300 6290
6301 SafeBoolChain Safe = SBC_Yes; 6291 SafeBoolChain Safe = SBC_Yes;
6302 if (const Inst *Producer = Computations.getProducerOf(Boolean)) { 6292 if (const Inst *Producer = Computations.getProducerOf(Boolean)) {
6303 switch (Producer->getKind()) { 6293 switch (Producer->getKind()) {
6304 default: 6294 default:
6305 llvm::report_fatal_error("Unexpected producer."); 6295 llvm::report_fatal_error("Unexpected producer.");
6306 case Inst::Icmp: { 6296 case Inst::Icmp: {
6307 _mov(T, _0); 6297 _mov(T, _0);
6308 CondWhenTrue Cond = lowerIcmpCond(llvm::cast<InstIcmp>(Producer)); 6298 CondWhenTrue Cond = lowerIcmpCond(llvm::cast<InstIcmp>(Producer));
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
6893 // However, for compatibility with current NaCl LLVM, don't claim that. 6883 // However, for compatibility with current NaCl LLVM, don't claim that.
6894 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 6884 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
6895 } 6885 }
6896 6886
6897 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; 6887 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM];
6898 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; 6888 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM];
6899 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; 6889 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM];
6900 6890
6901 } // end of namespace ARM32 6891 } // end of namespace ARM32
6902 } // end of namespace Ice 6892 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698