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 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2129 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2129 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2130 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2130 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
2131 Variable *T_1 = nullptr; | 2131 Variable *T_1 = nullptr; |
2132 if (Traits::Is64Bit && Dest->getType() == IceType_i64) { | 2132 if (Traits::Is64Bit && Dest->getType() == IceType_i64) { |
2133 T_1 = makeReg(IceType_i64); | 2133 T_1 = makeReg(IceType_i64); |
2134 } else { | 2134 } else { |
2135 assert(Dest->getType() != IceType_i64); | 2135 assert(Dest->getType() != IceType_i64); |
2136 T_1 = makeReg(IceType_i32); | 2136 T_1 = makeReg(IceType_i32); |
2137 } | 2137 } |
2138 // cvt() requires its integer argument to be a GPR. | 2138 // cvt() requires its integer argument to be a GPR. |
2139 T_1->setMustHaveReg(); | |
2140 Variable *T_2 = makeReg(Dest->getType()); | 2139 Variable *T_2 = makeReg(Dest->getType()); |
2141 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); | 2140 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); |
2142 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 2141 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
2143 if (Dest->getType() == IceType_i1) | 2142 if (Dest->getType() == IceType_i1) |
2144 _and(T_2, Ctx->getConstantInt1(1)); | 2143 _and(T_2, Ctx->getConstantInt1(1)); |
2145 _mov(Dest, T_2); | 2144 _mov(Dest, T_2); |
2146 } | 2145 } |
2147 break; | 2146 break; |
2148 case InstCast::Fptoui: | 2147 case InstCast::Fptoui: |
2149 if (isVectorType(Dest->getType())) { | 2148 if (isVectorType(Dest->getType())) { |
(...skipping 28 matching lines...) Expand all Loading... |
2178 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2177 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2179 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2178 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
2180 assert(Dest->getType() != IceType_i64); | 2179 assert(Dest->getType() != IceType_i64); |
2181 Variable *T_1 = nullptr; | 2180 Variable *T_1 = nullptr; |
2182 if (Traits::Is64Bit && Dest->getType() == IceType_i32) { | 2181 if (Traits::Is64Bit && Dest->getType() == IceType_i32) { |
2183 T_1 = makeReg(IceType_i64); | 2182 T_1 = makeReg(IceType_i64); |
2184 } else { | 2183 } else { |
2185 assert(Dest->getType() != IceType_i32); | 2184 assert(Dest->getType() != IceType_i32); |
2186 T_1 = makeReg(IceType_i32); | 2185 T_1 = makeReg(IceType_i32); |
2187 } | 2186 } |
2188 T_1->setMustHaveReg(); | |
2189 Variable *T_2 = makeReg(Dest->getType()); | 2187 Variable *T_2 = makeReg(Dest->getType()); |
2190 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); | 2188 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); |
2191 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 2189 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
2192 if (Dest->getType() == IceType_i1) | 2190 if (Dest->getType() == IceType_i1) |
2193 _and(T_2, Ctx->getConstantInt1(1)); | 2191 _and(T_2, Ctx->getConstantInt1(1)); |
2194 _mov(Dest, T_2); | 2192 _mov(Dest, T_2); |
2195 } | 2193 } |
2196 break; | 2194 break; |
2197 case InstCast::Sitofp: | 2195 case InstCast::Sitofp: |
2198 if (isVectorType(Dest->getType())) { | 2196 if (isVectorType(Dest->getType())) { |
(...skipping 21 matching lines...) Expand all Loading... |
2220 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2218 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2221 // Sign-extend the operand. | 2219 // Sign-extend the operand. |
2222 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 2220 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
2223 Variable *T_1 = nullptr; | 2221 Variable *T_1 = nullptr; |
2224 if (Traits::Is64Bit && Src0RM->getType() == IceType_i64) { | 2222 if (Traits::Is64Bit && Src0RM->getType() == IceType_i64) { |
2225 T_1 = makeReg(IceType_i64); | 2223 T_1 = makeReg(IceType_i64); |
2226 } else { | 2224 } else { |
2227 assert(Src0RM->getType() != IceType_i64); | 2225 assert(Src0RM->getType() != IceType_i64); |
2228 T_1 = makeReg(IceType_i32); | 2226 T_1 = makeReg(IceType_i32); |
2229 } | 2227 } |
2230 T_1->setMustHaveReg(); | |
2231 Variable *T_2 = makeReg(Dest->getType()); | 2228 Variable *T_2 = makeReg(Dest->getType()); |
2232 if (Src0RM->getType() == T_1->getType()) | 2229 if (Src0RM->getType() == T_1->getType()) |
2233 _mov(T_1, Src0RM); | 2230 _mov(T_1, Src0RM); |
2234 else | 2231 else |
2235 _movsx(T_1, Src0RM); | 2232 _movsx(T_1, Src0RM); |
2236 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); | 2233 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); |
2237 _mov(Dest, T_2); | 2234 _mov(Dest, T_2); |
2238 } | 2235 } |
2239 break; | 2236 break; |
2240 case InstCast::Uitofp: { | 2237 case InstCast::Uitofp: { |
(...skipping 28 matching lines...) Expand all Loading... |
2269 // Zero-extend the operand. | 2266 // Zero-extend the operand. |
2270 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 2267 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
2271 Variable *T_1 = nullptr; | 2268 Variable *T_1 = nullptr; |
2272 if (Traits::Is64Bit && Src0RM->getType() == IceType_i32) { | 2269 if (Traits::Is64Bit && Src0RM->getType() == IceType_i32) { |
2273 T_1 = makeReg(IceType_i64); | 2270 T_1 = makeReg(IceType_i64); |
2274 } else { | 2271 } else { |
2275 assert(Src0RM->getType() != IceType_i64); | 2272 assert(Src0RM->getType() != IceType_i64); |
2276 assert(Traits::Is64Bit || Src0RM->getType() != IceType_i32); | 2273 assert(Traits::Is64Bit || Src0RM->getType() != IceType_i32); |
2277 T_1 = makeReg(IceType_i32); | 2274 T_1 = makeReg(IceType_i32); |
2278 } | 2275 } |
2279 T_1->setMustHaveReg(); | |
2280 Variable *T_2 = makeReg(Dest->getType()); | 2276 Variable *T_2 = makeReg(Dest->getType()); |
2281 if (Src0RM->getType() == T_1->getType()) | 2277 if (Src0RM->getType() == T_1->getType()) |
2282 _mov(T_1, Src0RM); | 2278 _mov(T_1, Src0RM); |
2283 else | 2279 else |
2284 _movzx(T_1, Src0RM); | 2280 _movzx(T_1, Src0RM); |
2285 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); | 2281 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); |
2286 _mov(Dest, T_2); | 2282 _mov(Dest, T_2); |
2287 } | 2283 } |
2288 break; | 2284 break; |
2289 } | 2285 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2378 _mov(DestHi, T_Hi); | 2374 _mov(DestHi, T_Hi); |
2379 } | 2375 } |
2380 } break; | 2376 } break; |
2381 case IceType_f64: { | 2377 case IceType_f64: { |
2382 assert(Src0->getType() == IceType_i64); | 2378 assert(Src0->getType() == IceType_i64); |
2383 if (Traits::Is64Bit) { | 2379 if (Traits::Is64Bit) { |
2384 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 2380 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
2385 Variable *T = makeReg(IceType_f64); | 2381 Variable *T = makeReg(IceType_f64); |
2386 // Movd requires its fp argument (in this case, the bitcast | 2382 // Movd requires its fp argument (in this case, the bitcast |
2387 // destination) to be an xmm register. | 2383 // destination) to be an xmm register. |
2388 T->setMustHaveReg(); | |
2389 _movd(T, Src0RM); | 2384 _movd(T, Src0RM); |
2390 _mov(Dest, T); | 2385 _mov(Dest, T); |
2391 } else { | 2386 } else { |
2392 Src0 = legalize(Src0); | 2387 Src0 = legalize(Src0); |
2393 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) { | 2388 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) { |
2394 Variable *T = Func->makeVariable(Dest->getType()); | 2389 Variable *T = Func->makeVariable(Dest->getType()); |
2395 _movq(T, Src0); | 2390 _movq(T, Src0); |
2396 _movq(Dest, T); | 2391 _movq(Dest, T); |
2397 break; | 2392 break; |
2398 } | 2393 } |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2625 Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem); | 2620 Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem); |
2626 Variable *T = nullptr; | 2621 Variable *T = nullptr; |
2627 _mov(T, Src0); | 2622 _mov(T, Src0); |
2628 _ucomiss(T, Src1RM); | 2623 _ucomiss(T, Src1RM); |
2629 if (!HasC2) { | 2624 if (!HasC2) { |
2630 assert(Traits::TableFcmp[Index].Default); | 2625 assert(Traits::TableFcmp[Index].Default); |
2631 _setcc(Dest, Traits::TableFcmp[Index].C1); | 2626 _setcc(Dest, Traits::TableFcmp[Index].C1); |
2632 return; | 2627 return; |
2633 } | 2628 } |
2634 } | 2629 } |
2635 Constant *Default = Ctx->getConstantInt32(Traits::TableFcmp[Index].Default); | 2630 Constant *Default = |
| 2631 Ctx->getConstantInt(Dest->getType(), Traits::TableFcmp[Index].Default); |
2636 _mov(Dest, Default); | 2632 _mov(Dest, Default); |
2637 if (HasC1) { | 2633 if (HasC1) { |
2638 typename Traits::Insts::Label *Label = | 2634 typename Traits::Insts::Label *Label = |
2639 Traits::Insts::Label::create(Func, this); | 2635 Traits::Insts::Label::create(Func, this); |
2640 _br(Traits::TableFcmp[Index].C1, Label); | 2636 _br(Traits::TableFcmp[Index].C1, Label); |
2641 if (HasC2) { | 2637 if (HasC2) { |
2642 _br(Traits::TableFcmp[Index].C2, Label); | 2638 _br(Traits::TableFcmp[Index].C2, Label); |
2643 } | 2639 } |
2644 Constant *NonDefault = | 2640 Constant *NonDefault = |
2645 Ctx->getConstantInt32(!Traits::TableFcmp[Index].Default); | 2641 Ctx->getConstantInt(Dest->getType(), !Traits::TableFcmp[Index].Default); |
2646 _mov_redefined(Dest, NonDefault); | 2642 _mov_redefined(Dest, NonDefault); |
2647 Context.insert(Label); | 2643 Context.insert(Label); |
2648 } | 2644 } |
2649 } | 2645 } |
2650 | 2646 |
2651 inline bool isZero(const Operand *Opnd) { | 2647 inline bool isZero(const Operand *Opnd) { |
2652 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Opnd)) | 2648 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Opnd)) |
2653 return C64->getValue() == 0; | 2649 return C64->getValue() == 0; |
2654 if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(Opnd)) | 2650 if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(Opnd)) |
2655 return C32->getValue() == 0; | 2651 return C32->getValue() == 0; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2812 // Legalize the portions of Src0 that are going to be needed. | 2808 // Legalize the portions of Src0 that are going to be needed. |
2813 if (isZero(Src1)) { | 2809 if (isZero(Src1)) { |
2814 switch (Condition) { | 2810 switch (Condition) { |
2815 default: | 2811 default: |
2816 llvm_unreachable("unexpected condition"); | 2812 llvm_unreachable("unexpected condition"); |
2817 break; | 2813 break; |
2818 // These two are not optimized, so we fall through to the general case, | 2814 // These two are not optimized, so we fall through to the general case, |
2819 // which needs the upper and lower halves legalized. | 2815 // which needs the upper and lower halves legalized. |
2820 case InstIcmp::Sgt: | 2816 case InstIcmp::Sgt: |
2821 case InstIcmp::Sle: | 2817 case InstIcmp::Sle: |
2822 // These four compare after performing an "or" of the high and low half, so
they | 2818 // These four compare after performing an "or" of the high and low half, so |
2823 // need the upper and lower halves legalized. | 2819 // they need the upper and lower halves legalized. |
2824 case InstIcmp::Eq: | 2820 case InstIcmp::Eq: |
2825 case InstIcmp::Ule: | 2821 case InstIcmp::Ule: |
2826 case InstIcmp::Ne: | 2822 case InstIcmp::Ne: |
2827 case InstIcmp::Ugt: | 2823 case InstIcmp::Ugt: |
2828 Src0LoRM = legalize(loOperand(Src0), Legal_Reg | Legal_Mem); | 2824 Src0LoRM = legalize(loOperand(Src0), Legal_Reg | Legal_Mem); |
2829 // These two test only the high half's sign bit, so they need only | 2825 // These two test only the high half's sign bit, so they need only |
2830 // the upper half legalized. | 2826 // the upper half legalized. |
2831 case InstIcmp::Sge: | 2827 case InstIcmp::Sge: |
2832 case InstIcmp::Slt: | 2828 case InstIcmp::Slt: |
2833 Src0HiRM = legalize(hiOperand(Src0), Legal_Reg | Legal_Mem); | 2829 Src0HiRM = legalize(hiOperand(Src0), Legal_Reg | Legal_Mem); |
(...skipping 2345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5179 Const = llvm::cast<Constant>(From); | 5175 Const = llvm::cast<Constant>(From); |
5180 } | 5176 } |
5181 // There should be no constants of vector type (other than undef). | 5177 // There should be no constants of vector type (other than undef). |
5182 assert(!isVectorType(Ty)); | 5178 assert(!isVectorType(Ty)); |
5183 | 5179 |
5184 // If the operand is a 64 bit constant integer we need to legalize it to a | 5180 // If the operand is a 64 bit constant integer we need to legalize it to a |
5185 // register in x86-64. | 5181 // register in x86-64. |
5186 if (Traits::Is64Bit) { | 5182 if (Traits::Is64Bit) { |
5187 if (llvm::isa<ConstantInteger64>(Const)) { | 5183 if (llvm::isa<ConstantInteger64>(Const)) { |
5188 Variable *V = copyToReg(Const, RegNum); | 5184 Variable *V = copyToReg(Const, RegNum); |
5189 V->setMustHaveReg(); | |
5190 return V; | 5185 return V; |
5191 } | 5186 } |
5192 } | 5187 } |
5193 | 5188 |
5194 // If the operand is an 32 bit constant integer, we should check whether we | 5189 // If the operand is an 32 bit constant integer, we should check whether we |
5195 // need to randomize it or pool it. | 5190 // need to randomize it or pool it. |
5196 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(Const)) { | 5191 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(Const)) { |
5197 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); | 5192 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); |
5198 if (NewConst != Const) { | 5193 if (NewConst != Const) { |
5199 return NewConst; | 5194 return NewConst; |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5605 } | 5600 } |
5606 // the offset is not eligible for blinding or pooling, return the original | 5601 // the offset is not eligible for blinding or pooling, return the original |
5607 // mem operand | 5602 // mem operand |
5608 return MemOperand; | 5603 return MemOperand; |
5609 } | 5604 } |
5610 | 5605 |
5611 } // end of namespace X86Internal | 5606 } // end of namespace X86Internal |
5612 } // end of namespace Ice | 5607 } // end of namespace Ice |
5613 | 5608 |
5614 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 5609 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |