OLD | NEW |
---|---|
1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// | 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// |
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 2670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2681 // Emit the call to the function. | 2681 // Emit the call to the function. |
2682 Operand *CallTarget = | 2682 Operand *CallTarget = |
2683 legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm | Legal_AddrAbs); | 2683 legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm | Legal_AddrAbs); |
2684 Inst *NewCall = emitCallToTarget(CallTarget, ReturnReg); | 2684 Inst *NewCall = emitCallToTarget(CallTarget, ReturnReg); |
2685 // Keep the upper return register live on 32-bit platform. | 2685 // Keep the upper return register live on 32-bit platform. |
2686 if (ReturnRegHi) | 2686 if (ReturnRegHi) |
2687 Context.insert<InstFakeDef>(ReturnRegHi); | 2687 Context.insert<InstFakeDef>(ReturnRegHi); |
2688 // Mark the call as killing all the caller-save registers. | 2688 // Mark the call as killing all the caller-save registers. |
2689 Context.insert<InstFakeKill>(NewCall); | 2689 Context.insert<InstFakeKill>(NewCall); |
2690 // Handle x86-32 floating point returns. | 2690 // Handle x86-32 floating point returns. |
2691 if (Dest != nullptr && isScalarFloatingType(Dest->getType()) && | 2691 if (Dest != nullptr && isScalarFloatingType(DestTy) && |
2692 !Traits::X86_PASS_SCALAR_FP_IN_XMM) { | 2692 !Traits::X86_PASS_SCALAR_FP_IN_XMM) { |
2693 // Special treatment for an FP function which returns its result in st(0). | 2693 // Special treatment for an FP function which returns its result in st(0). |
2694 // If Dest ends up being a physical xmm register, the fstp emit code will | 2694 // If Dest ends up being a physical xmm register, the fstp emit code will |
2695 // route st(0) through the space reserved in the function argument area | 2695 // route st(0) through the space reserved in the function argument area |
2696 // we allocated. | 2696 // we allocated. |
2697 _fstp(Dest); | 2697 _fstp(Dest); |
2698 // Create a fake use of Dest in case it actually isn't used, because st(0) | 2698 // Create a fake use of Dest in case it actually isn't used, because st(0) |
2699 // still needs to be popped. | 2699 // still needs to be popped. |
2700 Context.insert<InstFakeUse>(Dest); | 2700 Context.insert<InstFakeUse>(Dest); |
2701 } | 2701 } |
2702 // Generate a FakeUse to keep the call live if necessary. | 2702 // Generate a FakeUse to keep the call live if necessary. |
2703 if (Instr->hasSideEffects() && ReturnReg) { | 2703 if (Instr->hasSideEffects() && ReturnReg) { |
2704 Context.insert<InstFakeUse>(ReturnReg); | 2704 Context.insert<InstFakeUse>(ReturnReg); |
2705 } | 2705 } |
2706 // Process the return value, if any. | 2706 // Process the return value, if any. |
2707 if (Dest == nullptr) | 2707 if (Dest == nullptr) |
2708 return; | 2708 return; |
2709 // Assign the result of the call to Dest. | 2709 // Assign the result of the call to Dest. Route it through a temporary so |
2710 // that the local register availability peephole can be subsequently used. | |
2711 Variable *Tmp = nullptr; | |
2710 if (isVectorType(DestTy)) { | 2712 if (isVectorType(DestTy)) { |
2711 assert(ReturnReg && "Vector type requires a return register"); | 2713 assert(ReturnReg && "Vector type requires a return register"); |
2712 _movp(Dest, ReturnReg); | 2714 Tmp = makeReg(DestTy); |
2715 _movp(Tmp, ReturnReg); | |
2716 _movp(Dest, Tmp); | |
2713 } else if (isScalarFloatingType(DestTy)) { | 2717 } else if (isScalarFloatingType(DestTy)) { |
2714 if (Traits::X86_PASS_SCALAR_FP_IN_XMM) { | 2718 if (Traits::X86_PASS_SCALAR_FP_IN_XMM) { |
2715 assert(ReturnReg && "FP type requires a return register"); | 2719 assert(ReturnReg && "FP type requires a return register"); |
2716 _mov(Dest, ReturnReg); | 2720 _mov(Tmp, ReturnReg); |
2721 _mov(Dest, Tmp); | |
2717 } | 2722 } |
2718 } else { | 2723 } else { |
2719 assert(isScalarIntegerType(DestTy)); | 2724 assert(isScalarIntegerType(DestTy)); |
2720 assert(ReturnReg && "Integer type requires a return register"); | 2725 assert(ReturnReg && "Integer type requires a return register"); |
2721 if (DestTy == IceType_i64 && !Traits::Is64Bit) { | 2726 if (DestTy == IceType_i64 && !Traits::Is64Bit) { |
2722 assert(ReturnRegHi && "64-bit type requires two return registers"); | 2727 assert(ReturnRegHi && "64-bit type requires two return registers"); |
2723 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); | 2728 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); |
2724 Variable *DestLo = Dest64On32->getLo(); | 2729 Variable *DestLo = Dest64On32->getLo(); |
2725 Variable *DestHi = Dest64On32->getHi(); | 2730 Variable *DestHi = Dest64On32->getHi(); |
2726 _mov(DestLo, ReturnReg); | 2731 _mov(Tmp, ReturnReg); |
2727 _mov(DestHi, ReturnRegHi); | 2732 _mov(DestLo, Tmp); |
2733 Variable *TmpHi = nullptr; | |
Eric Holk
2016/06/15 00:14:38
Why is it okay for TmpHi to be NULL?
Jim Stichnoth
2016/06/15 00:35:31
The _mov() method is "special" in that if the dest
| |
2734 _mov(TmpHi, ReturnRegHi); | |
2735 _mov(DestHi, TmpHi); | |
2728 } else { | 2736 } else { |
2729 _mov(Dest, ReturnReg); | 2737 _mov(Tmp, ReturnReg); |
2738 _mov(Dest, Tmp); | |
2730 } | 2739 } |
2731 } | 2740 } |
2732 } | 2741 } |
2733 | 2742 |
2734 template <typename TraitsType> | 2743 template <typename TraitsType> |
2735 void TargetX86Base<TraitsType>::lowerCast(const InstCast *Instr) { | 2744 void TargetX86Base<TraitsType>::lowerCast(const InstCast *Instr) { |
2736 // a = cast(b) ==> t=cast(b); a=t; (link t->b, link a->t, no overlap) | 2745 // a = cast(b) ==> t=cast(b); a=t; (link t->b, link a->t, no overlap) |
2737 InstCast::OpKind CastKind = Instr->getCastKind(); | 2746 InstCast::OpKind CastKind = Instr->getCastKind(); |
2738 Variable *Dest = Instr->getDest(); | 2747 Variable *Dest = Instr->getDest(); |
2739 Type DestTy = Dest->getType(); | 2748 Type DestTy = Dest->getType(); |
(...skipping 5231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7971 emitGlobal(*Var, SectionSuffix); | 7980 emitGlobal(*Var, SectionSuffix); |
7972 } | 7981 } |
7973 } | 7982 } |
7974 } break; | 7983 } break; |
7975 } | 7984 } |
7976 } | 7985 } |
7977 } // end of namespace X86NAMESPACE | 7986 } // end of namespace X86NAMESPACE |
7978 } // end of namespace Ice | 7987 } // end of namespace Ice |
7979 | 7988 |
7980 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 7989 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |