OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 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 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 llvm::SmallBitVector CalleeSaves = | 956 llvm::SmallBitVector CalleeSaves = |
957 getRegisterSet(RegSet_CalleeSave, RegSet_None); | 957 getRegisterSet(RegSet_CalleeSave, RegSet_None); |
958 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { | 958 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { |
959 SizeT j = CalleeSaves.size() - i - 1; | 959 SizeT j = CalleeSaves.size() - i - 1; |
960 if (j == RegX8632::Reg_ebp && IsEbpBasedFrame) | 960 if (j == RegX8632::Reg_ebp && IsEbpBasedFrame) |
961 continue; | 961 continue; |
962 if (CalleeSaves[j] && RegsUsed[j]) { | 962 if (CalleeSaves[j] && RegsUsed[j]) { |
963 _pop(getPhysicalRegister(j)); | 963 _pop(getPhysicalRegister(j)); |
964 } | 964 } |
965 } | 965 } |
| 966 |
| 967 if (!Ctx->getFlags().getUseSandboxing()) |
| 968 return; |
| 969 // Change the original ret instruction into a sandboxed return sequence. |
| 970 // bundle_lock |
| 971 // t:ecx = pop |
| 972 // and t, ~31 |
| 973 // jmp *t |
| 974 // bundle_unlock |
| 975 // FakeUse <original_ret_operand> |
| 976 const SizeT BundleSize = 1 |
| 977 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); |
| 978 Variable *T_ecx = makeReg(IceType_i32, RegX8632::Reg_ecx); |
| 979 _pop(T_ecx); |
| 980 _bundle_lock(); |
| 981 _and(T_ecx, Ctx->getConstantInt32(~(BundleSize - 1))); |
| 982 _jmp(T_ecx); |
| 983 _bundle_unlock(); |
| 984 if (RI->getSrcSize()) { |
| 985 Variable *RetValue = llvm::cast<Variable>(RI->getSrc(0)); |
| 986 Context.insert(InstFakeUse::create(Func, RetValue)); |
| 987 } |
| 988 RI->setDeleted(); |
966 } | 989 } |
967 | 990 |
968 void TargetX8632::split64(Variable *Var) { | 991 void TargetX8632::split64(Variable *Var) { |
969 switch (Var->getType()) { | 992 switch (Var->getType()) { |
970 default: | 993 default: |
971 return; | 994 return; |
972 case IceType_i64: | 995 case IceType_i64: |
973 // TODO: Only consider F64 if we need to push each half when | 996 // TODO: Only consider F64 if we need to push each half when |
974 // passing as an argument to a function call. Note that each half | 997 // passing as an argument to a function call. Note that each half |
975 // is still typed as I32. | 998 // is still typed as I32. |
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1808 case IceType_v16i1: | 1831 case IceType_v16i1: |
1809 case IceType_v16i8: | 1832 case IceType_v16i8: |
1810 case IceType_v8i16: | 1833 case IceType_v8i16: |
1811 case IceType_v4i32: | 1834 case IceType_v4i32: |
1812 case IceType_v4f32: | 1835 case IceType_v4f32: |
1813 ReturnReg = makeReg(Dest->getType(), RegX8632::Reg_xmm0); | 1836 ReturnReg = makeReg(Dest->getType(), RegX8632::Reg_xmm0); |
1814 break; | 1837 break; |
1815 } | 1838 } |
1816 } | 1839 } |
1817 Operand *CallTarget = legalize(Instr->getCallTarget()); | 1840 Operand *CallTarget = legalize(Instr->getCallTarget()); |
| 1841 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
| 1842 if (NeedSandboxing) { |
| 1843 if (llvm::isa<Constant>(CallTarget)) { |
| 1844 _bundle_lock(InstBundleLock::Opt_AlignToEnd); |
| 1845 } else { |
| 1846 Variable *CallTargetVar = nullptr; |
| 1847 _mov(CallTargetVar, CallTarget); |
| 1848 _bundle_lock(InstBundleLock::Opt_AlignToEnd); |
| 1849 const SizeT BundleSize = |
| 1850 1 << Func->getAssembler<>()->getBundleAlignLog2Bytes(); |
| 1851 _and(CallTargetVar, Ctx->getConstantInt32(~(BundleSize - 1))); |
| 1852 CallTarget = CallTargetVar; |
| 1853 } |
| 1854 } |
1818 Inst *NewCall = InstX8632Call::create(Func, ReturnReg, CallTarget); | 1855 Inst *NewCall = InstX8632Call::create(Func, ReturnReg, CallTarget); |
1819 Context.insert(NewCall); | 1856 Context.insert(NewCall); |
| 1857 if (NeedSandboxing) |
| 1858 _bundle_unlock(); |
1820 if (ReturnRegHi) | 1859 if (ReturnRegHi) |
1821 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); | 1860 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); |
1822 | 1861 |
1823 // Add the appropriate offset to esp. The call instruction takes care | 1862 // Add the appropriate offset to esp. The call instruction takes care |
1824 // of resetting the stack offset during emission. | 1863 // of resetting the stack offset during emission. |
1825 if (ParameterAreaSizeBytes) { | 1864 if (ParameterAreaSizeBytes) { |
1826 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp); | 1865 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp); |
1827 _add(esp, Ctx->getConstantInt32(ParameterAreaSizeBytes)); | 1866 _add(esp, Ctx->getConstantInt32(ParameterAreaSizeBytes)); |
1828 } | 1867 } |
1829 | 1868 |
(...skipping 1992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3822 Reg = eax; | 3861 Reg = eax; |
3823 Context.insert(InstFakeUse::create(Func, edx)); | 3862 Context.insert(InstFakeUse::create(Func, edx)); |
3824 } else if (isScalarFloatingType(Src0->getType())) { | 3863 } else if (isScalarFloatingType(Src0->getType())) { |
3825 _fld(Src0); | 3864 _fld(Src0); |
3826 } else if (isVectorType(Src0->getType())) { | 3865 } else if (isVectorType(Src0->getType())) { |
3827 Reg = legalizeToVar(Src0, RegX8632::Reg_xmm0); | 3866 Reg = legalizeToVar(Src0, RegX8632::Reg_xmm0); |
3828 } else { | 3867 } else { |
3829 _mov(Reg, Src0, RegX8632::Reg_eax); | 3868 _mov(Reg, Src0, RegX8632::Reg_eax); |
3830 } | 3869 } |
3831 } | 3870 } |
| 3871 // Add a ret instruction even if sandboxing is enabled, because |
| 3872 // addEpilog explicitly looks for a ret instruction as a marker for |
| 3873 // where to insert the frame removal instructions. |
3832 _ret(Reg); | 3874 _ret(Reg); |
3833 // Add a fake use of esp to make sure esp stays alive for the entire | 3875 // Add a fake use of esp to make sure esp stays alive for the entire |
3834 // function. Otherwise post-call esp adjustments get dead-code | 3876 // function. Otherwise post-call esp adjustments get dead-code |
3835 // eliminated. TODO: Are there more places where the fake use | 3877 // eliminated. TODO: Are there more places where the fake use |
3836 // should be inserted? E.g. "void f(int n){while(1) g(n);}" may not | 3878 // should be inserted? E.g. "void f(int n){while(1) g(n);}" may not |
3837 // have a ret instruction. | 3879 // have a ret instruction. |
3838 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp); | 3880 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp); |
3839 Context.insert(InstFakeUse::create(Func, esp)); | 3881 Context.insert(InstFakeUse::create(Func, esp)); |
3840 } | 3882 } |
3841 | 3883 |
(...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4729 case FT_Asm: | 4771 case FT_Asm: |
4730 case FT_Iasm: { | 4772 case FT_Iasm: { |
4731 OstreamLocker L(Ctx); | 4773 OstreamLocker L(Ctx); |
4732 emitConstantPool<PoolTypeConverter<float>>(Ctx); | 4774 emitConstantPool<PoolTypeConverter<float>>(Ctx); |
4733 emitConstantPool<PoolTypeConverter<double>>(Ctx); | 4775 emitConstantPool<PoolTypeConverter<double>>(Ctx); |
4734 } break; | 4776 } break; |
4735 } | 4777 } |
4736 } | 4778 } |
4737 | 4779 |
4738 } // end of namespace Ice | 4780 } // end of namespace Ice |
OLD | NEW |