| 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 RuntimeHelper HelperID = RuntimeHelper::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 = RuntimeHelper::H_udiv_i64; |
| 477 break; | 477 break; |
| 478 case InstArithmetic::Sdiv: | 478 case InstArithmetic::Sdiv: |
| 479 TargetHelper = Ctx->getConstantExternSym(H_sdiv_i64); | 479 HelperID = RuntimeHelper::H_sdiv_i64; |
| 480 break; | 480 break; |
| 481 case InstArithmetic::Urem: | 481 case InstArithmetic::Urem: |
| 482 TargetHelper = Ctx->getConstantExternSym(H_urem_i64); | 482 HelperID = RuntimeHelper::H_urem_i64; |
| 483 break; | 483 break; |
| 484 case InstArithmetic::Srem: | 484 case InstArithmetic::Srem: |
| 485 TargetHelper = Ctx->getConstantExternSym(H_srem_i64); | 485 HelperID = RuntimeHelper::H_srem_i64; |
| 486 break; | 486 break; |
| 487 } | 487 } |
| 488 assert(TargetHelper != nullptr); | 488 Operand *TargetHelper = Ctx->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 RuntimeHelper HelperID = RuntimeHelper::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 ? RuntimeHelper::H_Num : RuntimeHelper::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 ? RuntimeHelper::H_Num : RuntimeHelper::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 ? RuntimeHelper::H_Num : RuntimeHelper::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 ? RuntimeHelper::H_Num : RuntimeHelper::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 == RuntimeHelper::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 = Ctx->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 = Ctx->getRuntimeHelperFunc( |
| 582 DestTy == IceType_f32 ? H_frem_f32 : H_frem_f64); | 578 DestTy == IceType_f32 ? RuntimeHelper::H_frem_f32 |
| 579 : RuntimeHelper::H_frem_f64); |
| 583 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 580 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
| 584 NoTailCall, IsTargetHelperCall); | 581 NoTailCall, IsTargetHelperCall); |
| 585 Call->addArg(Instr->getSrc(0)); | 582 Call->addArg(Instr->getSrc(0)); |
| 586 Call->addArg(Instr->getSrc(1)); | 583 Call->addArg(Instr->getSrc(1)); |
| 587 Instr->setDeleted(); | 584 Instr->setDeleted(); |
| 588 return; | 585 return; |
| 589 } | 586 } |
| 590 } | 587 } |
| 591 llvm::report_fatal_error("Control flow should never have reached here."); | 588 llvm::report_fatal_error("Control flow should never have reached here."); |
| 592 } | 589 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 612 switch (CastKind) { | 609 switch (CastKind) { |
| 613 default: | 610 default: |
| 614 return; | 611 return; |
| 615 case InstCast::Fptosi: | 612 case InstCast::Fptosi: |
| 616 case InstCast::Fptoui: { | 613 case InstCast::Fptoui: { |
| 617 if (DestTy != IceType_i64) { | 614 if (DestTy != IceType_i64) { |
| 618 return; | 615 return; |
| 619 } | 616 } |
| 620 const bool DestIsSigned = CastKind == InstCast::Fptosi; | 617 const bool DestIsSigned = CastKind == InstCast::Fptosi; |
| 621 const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy); | 618 const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy); |
| 622 Operand *TargetHelper = Ctx->getConstantExternSym( | 619 Operand *TargetHelper = Ctx->getRuntimeHelperFunc( |
| 623 Src0IsF32 ? (DestIsSigned ? H_fptosi_f32_i64 : H_fptoui_f32_i64) | 620 Src0IsF32 ? (DestIsSigned ? RuntimeHelper::H_fptosi_f32_i64 |
| 624 : (DestIsSigned ? H_fptosi_f64_i64 : H_fptoui_f64_i64)); | 621 : RuntimeHelper::H_fptoui_f32_i64) |
| 622 : (DestIsSigned ? RuntimeHelper::H_fptosi_f64_i64 |
| 623 : RuntimeHelper::H_fptoui_f64_i64)); |
| 625 static constexpr SizeT MaxArgs = 1; | 624 static constexpr SizeT MaxArgs = 1; |
| 626 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 625 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
| 627 NoTailCall, IsTargetHelperCall); | 626 NoTailCall, IsTargetHelperCall); |
| 628 Call->addArg(Src0); | 627 Call->addArg(Src0); |
| 629 Instr->setDeleted(); | 628 Instr->setDeleted(); |
| 630 return; | 629 return; |
| 631 } | 630 } |
| 632 case InstCast::Sitofp: | 631 case InstCast::Sitofp: |
| 633 case InstCast::Uitofp: { | 632 case InstCast::Uitofp: { |
| 634 if (SrcTy != IceType_i64) { | 633 if (SrcTy != IceType_i64) { |
| 635 return; | 634 return; |
| 636 } | 635 } |
| 637 const bool SourceIsSigned = CastKind == InstCast::Sitofp; | 636 const bool SourceIsSigned = CastKind == InstCast::Sitofp; |
| 638 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); | 637 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); |
| 639 Operand *TargetHelper = Ctx->getConstantExternSym( | 638 Operand *TargetHelper = Ctx->getRuntimeHelperFunc( |
| 640 DestIsF32 ? (SourceIsSigned ? H_sitofp_i64_f32 : H_uitofp_i64_f32) | 639 DestIsF32 ? (SourceIsSigned ? RuntimeHelper::H_sitofp_i64_f32 |
| 641 : (SourceIsSigned ? H_sitofp_i64_f64 : H_uitofp_i64_f64)); | 640 : RuntimeHelper::H_uitofp_i64_f32) |
| 641 : (SourceIsSigned ? RuntimeHelper::H_sitofp_i64_f64 |
| 642 : RuntimeHelper::H_uitofp_i64_f64)); |
| 642 static constexpr SizeT MaxArgs = 1; | 643 static constexpr SizeT MaxArgs = 1; |
| 643 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 644 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
| 644 NoTailCall, IsTargetHelperCall); | 645 NoTailCall, IsTargetHelperCall); |
| 645 Call->addArg(Src0); | 646 Call->addArg(Src0); |
| 646 Instr->setDeleted(); | 647 Instr->setDeleted(); |
| 647 return; | 648 return; |
| 648 } | 649 } |
| 649 case InstCast::Bitcast: { | 650 case InstCast::Bitcast: { |
| 650 if (DestTy == SrcTy) { | 651 if (DestTy == SrcTy) { |
| 651 return; | 652 return; |
| 652 } | 653 } |
| 653 Variable *CallDest = Dest; | 654 Variable *CallDest = Dest; |
| 654 const char *HelperName = nullptr; | 655 RuntimeHelper HelperID = RuntimeHelper::H_Num; |
| 655 switch (DestTy) { | 656 switch (DestTy) { |
| 656 default: | 657 default: |
| 657 return; | 658 return; |
| 658 case IceType_i8: | 659 case IceType_i8: |
| 659 assert(SrcTy == IceType_v8i1); | 660 assert(SrcTy == IceType_v8i1); |
| 660 HelperName = H_bitcast_8xi1_i8; | 661 HelperID = RuntimeHelper::H_bitcast_8xi1_i8; |
| 661 CallDest = Func->makeVariable(IceType_i32); | 662 CallDest = Func->makeVariable(IceType_i32); |
| 662 break; | 663 break; |
| 663 case IceType_i16: | 664 case IceType_i16: |
| 664 assert(SrcTy == IceType_v16i1); | 665 assert(SrcTy == IceType_v16i1); |
| 665 HelperName = H_bitcast_16xi1_i16; | 666 HelperID = RuntimeHelper::H_bitcast_16xi1_i16; |
| 666 CallDest = Func->makeVariable(IceType_i32); | 667 CallDest = Func->makeVariable(IceType_i32); |
| 667 break; | 668 break; |
| 668 case IceType_v8i1: { | 669 case IceType_v8i1: { |
| 669 assert(SrcTy == IceType_i8); | 670 assert(SrcTy == IceType_i8); |
| 670 HelperName = H_bitcast_i8_8xi1; | 671 HelperID = RuntimeHelper::H_bitcast_i8_8xi1; |
| 671 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); | 672 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
| 672 // Arguments to functions are required to be at least 32 bits wide. | 673 // Arguments to functions are required to be at least 32 bits wide. |
| 673 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); | 674 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); |
| 674 Src0 = Src0AsI32; | 675 Src0 = Src0AsI32; |
| 675 } break; | 676 } break; |
| 676 case IceType_v16i1: { | 677 case IceType_v16i1: { |
| 677 assert(SrcTy == IceType_i16); | 678 assert(SrcTy == IceType_i16); |
| 678 HelperName = H_bitcast_i16_16xi1; | 679 HelperID = RuntimeHelper::H_bitcast_i16_16xi1; |
| 679 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); | 680 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
| 680 // Arguments to functions are required to be at least 32 bits wide. | 681 // Arguments to functions are required to be at least 32 bits wide. |
| 681 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); | 682 Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); |
| 682 Src0 = Src0AsI32; | 683 Src0 = Src0AsI32; |
| 683 } break; | 684 } break; |
| 684 } | 685 } |
| 685 assert(HelperName != nullptr); | |
| 686 constexpr SizeT MaxSrcs = 1; | 686 constexpr SizeT MaxSrcs = 1; |
| 687 InstCall *Call = makeHelperCall(HelperName, CallDest, MaxSrcs); | 687 InstCall *Call = makeHelperCall(HelperID, CallDest, MaxSrcs); |
| 688 Call->addArg(Src0); | 688 Call->addArg(Src0); |
| 689 Context.insert(Call); | 689 Context.insert(Call); |
| 690 // The PNaCl ABI disallows i8/i16 return types, so truncate the helper | 690 // The PNaCl ABI disallows i8/i16 return types, so truncate the helper |
| 691 // call result to the appropriate type as necessary. | 691 // call result to the appropriate type as necessary. |
| 692 if (CallDest->getType() != Dest->getType()) | 692 if (CallDest->getType() != Dest->getType()) |
| 693 Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest); | 693 Context.insert<InstCast>(InstCast::Trunc, Dest, CallDest); |
| 694 Instr->setDeleted(); | 694 Instr->setDeleted(); |
| 695 return; | 695 return; |
| 696 } | 696 } |
| 697 } | 697 } |
| 698 llvm::report_fatal_error("Control flow should never have reached here."); | 698 llvm::report_fatal_error("Control flow should never have reached here."); |
| 699 } | 699 } |
| 700 case Inst::IntrinsicCall: { | 700 case Inst::IntrinsicCall: { |
| 701 Variable *Dest = Instr->getDest(); | 701 Variable *Dest = Instr->getDest(); |
| 702 auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr); | 702 auto *IntrinsicCall = llvm::cast<InstIntrinsicCall>(Instr); |
| 703 Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID; | 703 Intrinsics::IntrinsicID ID = IntrinsicCall->getIntrinsicInfo().ID; |
| 704 switch (ID) { | 704 switch (ID) { |
| 705 default: | 705 default: |
| 706 return; | 706 return; |
| 707 case Intrinsics::Ctpop: { | 707 case Intrinsics::Ctpop: { |
| 708 Operand *Src0 = IntrinsicCall->getArg(0); | 708 Operand *Src0 = IntrinsicCall->getArg(0); |
| 709 Operand *TargetHelper = Ctx->getConstantExternSym( | 709 Operand *TargetHelper = |
| 710 isInt32Asserting32Or64(Src0->getType()) ? H_call_ctpop_i32 | 710 Ctx->getRuntimeHelperFunc(isInt32Asserting32Or64(Src0->getType()) |
| 711 : H_call_ctpop_i64); | 711 ? RuntimeHelper::H_call_ctpop_i32 |
| 712 : RuntimeHelper::H_call_ctpop_i64); |
| 712 static constexpr SizeT MaxArgs = 1; | 713 static constexpr SizeT MaxArgs = 1; |
| 713 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 714 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
| 714 NoTailCall, IsTargetHelperCall); | 715 NoTailCall, IsTargetHelperCall); |
| 715 Call->addArg(Src0); | 716 Call->addArg(Src0); |
| 716 Instr->setDeleted(); | 717 Instr->setDeleted(); |
| 717 if (Src0->getType() == IceType_i64) { | 718 if (Src0->getType() == IceType_i64) { |
| 718 ARM32HelpersPostamble[TargetHelper] = &TargetARM32::postambleCtpop64; | 719 ARM32HelpersPostamble[TargetHelper] = &TargetARM32::postambleCtpop64; |
| 719 } | 720 } |
| 720 return; | 721 return; |
| 721 } | 722 } |
| 722 case Intrinsics::Longjmp: { | 723 case Intrinsics::Longjmp: { |
| 723 static constexpr SizeT MaxArgs = 2; | 724 static constexpr SizeT MaxArgs = 2; |
| 724 static constexpr Variable *NoDest = nullptr; | 725 static constexpr Variable *NoDest = nullptr; |
| 725 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_longjmp); | 726 Operand *TargetHelper = |
| 727 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_longjmp); |
| 726 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, | 728 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, |
| 727 NoTailCall, IsTargetHelperCall); | 729 NoTailCall, IsTargetHelperCall); |
| 728 Call->addArg(IntrinsicCall->getArg(0)); | 730 Call->addArg(IntrinsicCall->getArg(0)); |
| 729 Call->addArg(IntrinsicCall->getArg(1)); | 731 Call->addArg(IntrinsicCall->getArg(1)); |
| 730 Instr->setDeleted(); | 732 Instr->setDeleted(); |
| 731 return; | 733 return; |
| 732 } | 734 } |
| 733 case Intrinsics::Memcpy: { | 735 case Intrinsics::Memcpy: { |
| 734 // In the future, we could potentially emit an inline memcpy/memset, etc. | 736 // In the future, we could potentially emit an inline memcpy/memset, etc. |
| 735 // for intrinsic calls w/ a known length. | 737 // for intrinsic calls w/ a known length. |
| 736 static constexpr SizeT MaxArgs = 3; | 738 static constexpr SizeT MaxArgs = 3; |
| 737 static constexpr Variable *NoDest = nullptr; | 739 static constexpr Variable *NoDest = nullptr; |
| 738 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memcpy); | 740 Operand *TargetHelper = |
| 741 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memcpy); |
| 739 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, | 742 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, |
| 740 NoTailCall, IsTargetHelperCall); | 743 NoTailCall, IsTargetHelperCall); |
| 741 Call->addArg(IntrinsicCall->getArg(0)); | 744 Call->addArg(IntrinsicCall->getArg(0)); |
| 742 Call->addArg(IntrinsicCall->getArg(1)); | 745 Call->addArg(IntrinsicCall->getArg(1)); |
| 743 Call->addArg(IntrinsicCall->getArg(2)); | 746 Call->addArg(IntrinsicCall->getArg(2)); |
| 744 Instr->setDeleted(); | 747 Instr->setDeleted(); |
| 745 return; | 748 return; |
| 746 } | 749 } |
| 747 case Intrinsics::Memmove: { | 750 case Intrinsics::Memmove: { |
| 748 static constexpr SizeT MaxArgs = 3; | 751 static constexpr SizeT MaxArgs = 3; |
| 749 static constexpr Variable *NoDest = nullptr; | 752 static constexpr Variable *NoDest = nullptr; |
| 750 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memmove); | 753 Operand *TargetHelper = |
| 754 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memmove); |
| 751 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, | 755 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, |
| 752 NoTailCall, IsTargetHelperCall); | 756 NoTailCall, IsTargetHelperCall); |
| 753 Call->addArg(IntrinsicCall->getArg(0)); | 757 Call->addArg(IntrinsicCall->getArg(0)); |
| 754 Call->addArg(IntrinsicCall->getArg(1)); | 758 Call->addArg(IntrinsicCall->getArg(1)); |
| 755 Call->addArg(IntrinsicCall->getArg(2)); | 759 Call->addArg(IntrinsicCall->getArg(2)); |
| 756 Instr->setDeleted(); | 760 Instr->setDeleted(); |
| 757 return; | 761 return; |
| 758 } | 762 } |
| 759 case Intrinsics::Memset: { | 763 case Intrinsics::Memset: { |
| 760 // The value operand needs to be extended to a stack slot size because the | 764 // 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. | 765 // PNaCl ABI requires arguments to be at least 32 bits wide. |
| 762 Operand *ValOp = IntrinsicCall->getArg(1); | 766 Operand *ValOp = IntrinsicCall->getArg(1); |
| 763 assert(ValOp->getType() == IceType_i8); | 767 assert(ValOp->getType() == IceType_i8); |
| 764 Variable *ValExt = Func->makeVariable(stackSlotType()); | 768 Variable *ValExt = Func->makeVariable(stackSlotType()); |
| 765 Context.insert<InstCast>(InstCast::Zext, ValExt, ValOp); | 769 Context.insert<InstCast>(InstCast::Zext, ValExt, ValOp); |
| 766 | 770 |
| 767 // Technically, ARM has its own __aeabi_memset, but we can use plain | 771 // 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 | 772 // memset too. The value and size argument need to be flipped if we ever |
| 769 // decide to use __aeabi_memset. | 773 // decide to use __aeabi_memset. |
| 770 static constexpr SizeT MaxArgs = 3; | 774 static constexpr SizeT MaxArgs = 3; |
| 771 static constexpr Variable *NoDest = nullptr; | 775 static constexpr Variable *NoDest = nullptr; |
| 772 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memset); | 776 Operand *TargetHelper = |
| 777 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memset); |
| 773 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, | 778 auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, |
| 774 NoTailCall, IsTargetHelperCall); | 779 NoTailCall, IsTargetHelperCall); |
| 775 Call->addArg(IntrinsicCall->getArg(0)); | 780 Call->addArg(IntrinsicCall->getArg(0)); |
| 776 Call->addArg(ValExt); | 781 Call->addArg(ValExt); |
| 777 Call->addArg(IntrinsicCall->getArg(2)); | 782 Call->addArg(IntrinsicCall->getArg(2)); |
| 778 Instr->setDeleted(); | 783 Instr->setDeleted(); |
| 779 return; | 784 return; |
| 780 } | 785 } |
| 781 case Intrinsics::NaClReadTP: { | 786 case Intrinsics::NaClReadTP: { |
| 782 if (SandboxingType == ST_NaCl) { | 787 if (SandboxingType == ST_NaCl) { |
| 783 return; | 788 return; |
| 784 } | 789 } |
| 785 static constexpr SizeT MaxArgs = 0; | 790 static constexpr SizeT MaxArgs = 0; |
| 786 const char *ReadTP = | 791 Operand *TargetHelper = |
| 787 SandboxingType == ST_Nonsfi ? "__aeabi_read_tp" : H_call_read_tp; | 792 SandboxingType == ST_Nonsfi |
| 788 Operand *TargetHelper = Ctx->getConstantExternSym(ReadTP); | 793 ? Ctx->getConstantExternSym("__aeabi_read_tp") |
| 794 : Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_read_tp); |
| 789 Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall, | 795 Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall, |
| 790 IsTargetHelperCall); | 796 IsTargetHelperCall); |
| 791 Instr->setDeleted(); | 797 Instr->setDeleted(); |
| 792 return; | 798 return; |
| 793 } | 799 } |
| 794 case Intrinsics::Setjmp: { | 800 case Intrinsics::Setjmp: { |
| 795 static constexpr SizeT MaxArgs = 1; | 801 static constexpr SizeT MaxArgs = 1; |
| 796 Operand *TargetHelper = Ctx->getConstantExternSym(H_call_setjmp); | 802 Operand *TargetHelper = |
| 803 Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_setjmp); |
| 797 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 804 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
| 798 NoTailCall, IsTargetHelperCall); | 805 NoTailCall, IsTargetHelperCall); |
| 799 Call->addArg(IntrinsicCall->getArg(0)); | 806 Call->addArg(IntrinsicCall->getArg(0)); |
| 800 Instr->setDeleted(); | 807 Instr->setDeleted(); |
| 801 return; | 808 return; |
| 802 } | 809 } |
| 803 } | 810 } |
| 804 llvm::report_fatal_error("Control flow should never have reached here."); | 811 llvm::report_fatal_error("Control flow should never have reached here."); |
| 805 } | 812 } |
| 806 case Inst::Icmp: { | 813 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. | 6904 // 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"; | 6905 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
| 6899 } | 6906 } |
| 6900 | 6907 |
| 6901 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; | 6908 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; |
| 6902 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; | 6909 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; |
| 6903 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 6910 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
| 6904 | 6911 |
| 6905 } // end of namespace ARM32 | 6912 } // end of namespace ARM32 |
| 6906 } // end of namespace Ice | 6913 } // end of namespace Ice |
| OLD | NEW |