| 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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 if (Func->isVerbose(IceV_RMW)) { | 578 if (Func->isVerbose(IceV_RMW)) { |
| 579 Str << "Found RMW in " << Func->getFunctionName() << ":\n "; | 579 Str << "Found RMW in " << Func->getFunctionName() << ":\n "; |
| 580 Load->dump(Func); | 580 Load->dump(Func); |
| 581 Str << "\n "; | 581 Str << "\n "; |
| 582 Arith->dump(Func); | 582 Arith->dump(Func); |
| 583 Str << "\n "; | 583 Str << "\n "; |
| 584 Store->dump(Func); | 584 Store->dump(Func); |
| 585 Str << "\n"; | 585 Str << "\n"; |
| 586 } | 586 } |
| 587 Variable *Beacon = Func->makeVariable(IceType_i32); | 587 Variable *Beacon = Func->makeVariable(IceType_i32); |
| 588 Beacon->setWeight(0); | 588 Beacon->setMustNotHaveReg(); |
| 589 Store->setRmwBeacon(Beacon); | 589 Store->setRmwBeacon(Beacon); |
| 590 InstFakeDef *BeaconDef = InstFakeDef::create(Func, Beacon); | 590 InstFakeDef *BeaconDef = InstFakeDef::create(Func, Beacon); |
| 591 Node->getInsts().insert(I3, BeaconDef); | 591 Node->getInsts().insert(I3, BeaconDef); |
| 592 auto *RMW = Traits::Insts::FakeRMW::create( | 592 auto *RMW = Traits::Insts::FakeRMW::create( |
| 593 Func, ArithSrcOther, Store->getAddr(), Beacon, Arith->getOp()); | 593 Func, ArithSrcOther, Store->getAddr(), Beacon, Arith->getOp()); |
| 594 Node->getInsts().insert(I3, RMW); | 594 Node->getInsts().insert(I3, RMW); |
| 595 } | 595 } |
| 596 } | 596 } |
| 597 } | 597 } |
| 598 } | 598 } |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 | 756 |
| 757 template <class Machine> | 757 template <class Machine> |
| 758 void TargetX86Base<Machine>::emitVariable(const Variable *Var) const { | 758 void TargetX86Base<Machine>::emitVariable(const Variable *Var) const { |
| 759 if (!BuildDefs::dump()) | 759 if (!BuildDefs::dump()) |
| 760 return; | 760 return; |
| 761 Ostream &Str = Ctx->getStrEmit(); | 761 Ostream &Str = Ctx->getStrEmit(); |
| 762 if (Var->hasReg()) { | 762 if (Var->hasReg()) { |
| 763 Str << "%" << getRegName(Var->getRegNum(), Var->getType()); | 763 Str << "%" << getRegName(Var->getRegNum(), Var->getType()); |
| 764 return; | 764 return; |
| 765 } | 765 } |
| 766 if (Var->getWeight().isInf()) { | 766 if (Var->mustHaveReg()) { |
| 767 llvm_unreachable("Infinite-weight Variable has no register assigned"); | 767 llvm_unreachable("Infinite-weight Variable has no register assigned"); |
| 768 } | 768 } |
| 769 int32_t Offset = Var->getStackOffset(); | 769 int32_t Offset = Var->getStackOffset(); |
| 770 int32_t BaseRegNum = Var->getBaseRegNum(); | 770 int32_t BaseRegNum = Var->getBaseRegNum(); |
| 771 if (BaseRegNum == Variable::NoRegister) { | 771 if (BaseRegNum == Variable::NoRegister) { |
| 772 BaseRegNum = getFrameOrStackReg(); | 772 BaseRegNum = getFrameOrStackReg(); |
| 773 if (!hasFramePointer()) | 773 if (!hasFramePointer()) |
| 774 Offset += getStackAdjustment(); | 774 Offset += getStackAdjustment(); |
| 775 } | 775 } |
| 776 if (Offset) | 776 if (Offset) |
| 777 Str << Offset; | 777 Str << Offset; |
| 778 const Type FrameSPTy = Traits::WordType; | 778 const Type FrameSPTy = Traits::WordType; |
| 779 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")"; | 779 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")"; |
| 780 } | 780 } |
| 781 | 781 |
| 782 template <class Machine> | 782 template <class Machine> |
| 783 typename TargetX86Base<Machine>::Traits::Address | 783 typename TargetX86Base<Machine>::Traits::Address |
| 784 TargetX86Base<Machine>::stackVarToAsmOperand(const Variable *Var) const { | 784 TargetX86Base<Machine>::stackVarToAsmOperand(const Variable *Var) const { |
| 785 if (Var->hasReg()) | 785 if (Var->hasReg()) |
| 786 llvm_unreachable("Stack Variable has a register assigned"); | 786 llvm_unreachable("Stack Variable has a register assigned"); |
| 787 if (Var->getWeight().isInf()) { | 787 if (Var->mustHaveReg()) { |
| 788 llvm_unreachable("Infinite-weight Variable has no register assigned"); | 788 llvm_unreachable("Infinite-weight Variable has no register assigned"); |
| 789 } | 789 } |
| 790 int32_t Offset = Var->getStackOffset(); | 790 int32_t Offset = Var->getStackOffset(); |
| 791 int32_t BaseRegNum = Var->getBaseRegNum(); | 791 int32_t BaseRegNum = Var->getBaseRegNum(); |
| 792 if (Var->getBaseRegNum() == Variable::NoRegister) { | 792 if (Var->getBaseRegNum() == Variable::NoRegister) { |
| 793 BaseRegNum = getFrameOrStackReg(); | 793 BaseRegNum = getFrameOrStackReg(); |
| 794 if (!hasFramePointer()) | 794 if (!hasFramePointer()) |
| 795 Offset += getStackAdjustment(); | 795 Offset += getStackAdjustment(); |
| 796 } | 796 } |
| 797 return typename Traits::Address( | 797 return typename Traits::Address( |
| (...skipping 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2047 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2047 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
| 2048 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2048 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
| 2049 Variable *T_1 = nullptr; | 2049 Variable *T_1 = nullptr; |
| 2050 if (Traits::Is64Bit && Dest->getType() == IceType_i64) { | 2050 if (Traits::Is64Bit && Dest->getType() == IceType_i64) { |
| 2051 T_1 = makeReg(IceType_i64); | 2051 T_1 = makeReg(IceType_i64); |
| 2052 } else { | 2052 } else { |
| 2053 assert(Dest->getType() != IceType_i64); | 2053 assert(Dest->getType() != IceType_i64); |
| 2054 T_1 = makeReg(IceType_i32); | 2054 T_1 = makeReg(IceType_i32); |
| 2055 } | 2055 } |
| 2056 // cvt() requires its integer argument to be a GPR. | 2056 // cvt() requires its integer argument to be a GPR. |
| 2057 T_1->setWeightInfinite(); | 2057 T_1->setMustHaveReg(); |
| 2058 Variable *T_2 = makeReg(Dest->getType()); | 2058 Variable *T_2 = makeReg(Dest->getType()); |
| 2059 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); | 2059 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); |
| 2060 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 2060 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
| 2061 if (Dest->getType() == IceType_i1) | 2061 if (Dest->getType() == IceType_i1) |
| 2062 _and(T_2, Ctx->getConstantInt1(1)); | 2062 _and(T_2, Ctx->getConstantInt1(1)); |
| 2063 _mov(Dest, T_2); | 2063 _mov(Dest, T_2); |
| 2064 } | 2064 } |
| 2065 break; | 2065 break; |
| 2066 case InstCast::Fptoui: | 2066 case InstCast::Fptoui: |
| 2067 if (isVectorType(Dest->getType())) { | 2067 if (isVectorType(Dest->getType())) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2098 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2098 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
| 2099 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2099 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
| 2100 assert(Dest->getType() != IceType_i64); | 2100 assert(Dest->getType() != IceType_i64); |
| 2101 Variable *T_1 = nullptr; | 2101 Variable *T_1 = nullptr; |
| 2102 if (Traits::Is64Bit && Dest->getType() == IceType_i32) { | 2102 if (Traits::Is64Bit && Dest->getType() == IceType_i32) { |
| 2103 T_1 = makeReg(IceType_i64); | 2103 T_1 = makeReg(IceType_i64); |
| 2104 } else { | 2104 } else { |
| 2105 assert(Dest->getType() != IceType_i32); | 2105 assert(Dest->getType() != IceType_i32); |
| 2106 T_1 = makeReg(IceType_i32); | 2106 T_1 = makeReg(IceType_i32); |
| 2107 } | 2107 } |
| 2108 T_1->setWeightInfinite(); | 2108 T_1->setMustHaveReg(); |
| 2109 Variable *T_2 = makeReg(Dest->getType()); | 2109 Variable *T_2 = makeReg(Dest->getType()); |
| 2110 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); | 2110 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); |
| 2111 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 2111 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
| 2112 if (Dest->getType() == IceType_i1) | 2112 if (Dest->getType() == IceType_i1) |
| 2113 _and(T_2, Ctx->getConstantInt1(1)); | 2113 _and(T_2, Ctx->getConstantInt1(1)); |
| 2114 _mov(Dest, T_2); | 2114 _mov(Dest, T_2); |
| 2115 } | 2115 } |
| 2116 break; | 2116 break; |
| 2117 case InstCast::Sitofp: | 2117 case InstCast::Sitofp: |
| 2118 if (isVectorType(Dest->getType())) { | 2118 if (isVectorType(Dest->getType())) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2140 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2140 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
| 2141 // Sign-extend the operand. | 2141 // Sign-extend the operand. |
| 2142 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 2142 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
| 2143 Variable *T_1 = nullptr; | 2143 Variable *T_1 = nullptr; |
| 2144 if (Traits::Is64Bit && Src0RM->getType() == IceType_i64) { | 2144 if (Traits::Is64Bit && Src0RM->getType() == IceType_i64) { |
| 2145 T_1 = makeReg(IceType_i64); | 2145 T_1 = makeReg(IceType_i64); |
| 2146 } else { | 2146 } else { |
| 2147 assert(Src0RM->getType() != IceType_i64); | 2147 assert(Src0RM->getType() != IceType_i64); |
| 2148 T_1 = makeReg(IceType_i32); | 2148 T_1 = makeReg(IceType_i32); |
| 2149 } | 2149 } |
| 2150 T_1->setWeightInfinite(); | 2150 T_1->setMustHaveReg(); |
| 2151 Variable *T_2 = makeReg(Dest->getType()); | 2151 Variable *T_2 = makeReg(Dest->getType()); |
| 2152 if (Src0RM->getType() == T_1->getType()) | 2152 if (Src0RM->getType() == T_1->getType()) |
| 2153 _mov(T_1, Src0RM); | 2153 _mov(T_1, Src0RM); |
| 2154 else | 2154 else |
| 2155 _movsx(T_1, Src0RM); | 2155 _movsx(T_1, Src0RM); |
| 2156 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); | 2156 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); |
| 2157 _mov(Dest, T_2); | 2157 _mov(Dest, T_2); |
| 2158 } | 2158 } |
| 2159 break; | 2159 break; |
| 2160 case InstCast::Uitofp: { | 2160 case InstCast::Uitofp: { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2189 // Zero-extend the operand. | 2189 // Zero-extend the operand. |
| 2190 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 2190 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
| 2191 Variable *T_1 = nullptr; | 2191 Variable *T_1 = nullptr; |
| 2192 if (Traits::Is64Bit && Src0RM->getType() == IceType_i32) { | 2192 if (Traits::Is64Bit && Src0RM->getType() == IceType_i32) { |
| 2193 T_1 = makeReg(IceType_i64); | 2193 T_1 = makeReg(IceType_i64); |
| 2194 } else { | 2194 } else { |
| 2195 assert(Src0RM->getType() != IceType_i64); | 2195 assert(Src0RM->getType() != IceType_i64); |
| 2196 assert(Traits::Is64Bit || Src0RM->getType() != IceType_i32); | 2196 assert(Traits::Is64Bit || Src0RM->getType() != IceType_i32); |
| 2197 T_1 = makeReg(IceType_i32); | 2197 T_1 = makeReg(IceType_i32); |
| 2198 } | 2198 } |
| 2199 T_1->setWeightInfinite(); | 2199 T_1->setMustHaveReg(); |
| 2200 Variable *T_2 = makeReg(Dest->getType()); | 2200 Variable *T_2 = makeReg(Dest->getType()); |
| 2201 if (Src0RM->getType() == T_1->getType()) | 2201 if (Src0RM->getType() == T_1->getType()) |
| 2202 _mov(T_1, Src0RM); | 2202 _mov(T_1, Src0RM); |
| 2203 else | 2203 else |
| 2204 _movzx(T_1, Src0RM); | 2204 _movzx(T_1, Src0RM); |
| 2205 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); | 2205 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); |
| 2206 _mov(Dest, T_2); | 2206 _mov(Dest, T_2); |
| 2207 } | 2207 } |
| 2208 break; | 2208 break; |
| 2209 } | 2209 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2241 // t.f32 = b.f32 | 2241 // t.f32 = b.f32 |
| 2242 // s.f32 = spill t.f32 | 2242 // s.f32 = spill t.f32 |
| 2243 // a.i32 = s.f32 | 2243 // a.i32 = s.f32 |
| 2244 Variable *T = nullptr; | 2244 Variable *T = nullptr; |
| 2245 // TODO: Should be able to force a spill setup by calling legalize() with | 2245 // TODO: Should be able to force a spill setup by calling legalize() with |
| 2246 // Legal_Mem and not Legal_Reg or Legal_Imm. | 2246 // Legal_Mem and not Legal_Reg or Legal_Imm. |
| 2247 typename Traits::SpillVariable *SpillVar = | 2247 typename Traits::SpillVariable *SpillVar = |
| 2248 Func->makeVariable<typename Traits::SpillVariable>(SrcType); | 2248 Func->makeVariable<typename Traits::SpillVariable>(SrcType); |
| 2249 SpillVar->setLinkedTo(Dest); | 2249 SpillVar->setLinkedTo(Dest); |
| 2250 Variable *Spill = SpillVar; | 2250 Variable *Spill = SpillVar; |
| 2251 Spill->setWeight(RegWeight::Zero); | 2251 Spill->setMustNotHaveReg(); |
| 2252 _mov(T, Src0RM); | 2252 _mov(T, Src0RM); |
| 2253 _mov(Spill, T); | 2253 _mov(Spill, T); |
| 2254 _mov(Dest, Spill); | 2254 _mov(Dest, Spill); |
| 2255 } break; | 2255 } break; |
| 2256 case IceType_i64: { | 2256 case IceType_i64: { |
| 2257 assert(Src0->getType() == IceType_f64); | 2257 assert(Src0->getType() == IceType_f64); |
| 2258 if (Traits::Is64Bit) { | 2258 if (Traits::Is64Bit) { |
| 2259 // Movd requires its fp argument (in this case, the bitcast source) to | 2259 // Movd requires its fp argument (in this case, the bitcast source) to |
| 2260 // be an xmm register. | 2260 // be an xmm register. |
| 2261 Variable *Src0R = legalizeToReg(Src0); | 2261 Variable *Src0R = legalizeToReg(Src0); |
| 2262 Variable *T = makeReg(IceType_i64); | 2262 Variable *T = makeReg(IceType_i64); |
| 2263 _movd(T, Src0R); | 2263 _movd(T, Src0R); |
| 2264 _mov(Dest, T); | 2264 _mov(Dest, T); |
| 2265 } else { | 2265 } else { |
| 2266 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 2266 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
| 2267 // a.i64 = bitcast b.f64 ==> | 2267 // a.i64 = bitcast b.f64 ==> |
| 2268 // s.f64 = spill b.f64 | 2268 // s.f64 = spill b.f64 |
| 2269 // t_lo.i32 = lo(s.f64) | 2269 // t_lo.i32 = lo(s.f64) |
| 2270 // a_lo.i32 = t_lo.i32 | 2270 // a_lo.i32 = t_lo.i32 |
| 2271 // t_hi.i32 = hi(s.f64) | 2271 // t_hi.i32 = hi(s.f64) |
| 2272 // a_hi.i32 = t_hi.i32 | 2272 // a_hi.i32 = t_hi.i32 |
| 2273 Operand *SpillLo, *SpillHi; | 2273 Operand *SpillLo, *SpillHi; |
| 2274 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) { | 2274 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) { |
| 2275 typename Traits::SpillVariable *SpillVar = | 2275 typename Traits::SpillVariable *SpillVar = |
| 2276 Func->makeVariable<typename Traits::SpillVariable>(IceType_f64); | 2276 Func->makeVariable<typename Traits::SpillVariable>(IceType_f64); |
| 2277 SpillVar->setLinkedTo(Src0Var); | 2277 SpillVar->setLinkedTo(Src0Var); |
| 2278 Variable *Spill = SpillVar; | 2278 Variable *Spill = SpillVar; |
| 2279 Spill->setWeight(RegWeight::Zero); | 2279 Spill->setMustNotHaveReg(); |
| 2280 _movq(Spill, Src0RM); | 2280 _movq(Spill, Src0RM); |
| 2281 SpillLo = Traits::VariableSplit::create(Func, Spill, | 2281 SpillLo = Traits::VariableSplit::create(Func, Spill, |
| 2282 Traits::VariableSplit::Low); | 2282 Traits::VariableSplit::Low); |
| 2283 SpillHi = Traits::VariableSplit::create(Func, Spill, | 2283 SpillHi = Traits::VariableSplit::create(Func, Spill, |
| 2284 Traits::VariableSplit::High); | 2284 Traits::VariableSplit::High); |
| 2285 } else { | 2285 } else { |
| 2286 SpillLo = loOperand(Src0RM); | 2286 SpillLo = loOperand(Src0RM); |
| 2287 SpillHi = hiOperand(Src0RM); | 2287 SpillHi = hiOperand(Src0RM); |
| 2288 } | 2288 } |
| 2289 | 2289 |
| 2290 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 2290 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
| 2291 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 2291 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| 2292 Variable *T_Lo = makeReg(IceType_i32); | 2292 Variable *T_Lo = makeReg(IceType_i32); |
| 2293 Variable *T_Hi = makeReg(IceType_i32); | 2293 Variable *T_Hi = makeReg(IceType_i32); |
| 2294 | 2294 |
| 2295 _mov(T_Lo, SpillLo); | 2295 _mov(T_Lo, SpillLo); |
| 2296 _mov(DestLo, T_Lo); | 2296 _mov(DestLo, T_Lo); |
| 2297 _mov(T_Hi, SpillHi); | 2297 _mov(T_Hi, SpillHi); |
| 2298 _mov(DestHi, T_Hi); | 2298 _mov(DestHi, T_Hi); |
| 2299 } | 2299 } |
| 2300 } break; | 2300 } break; |
| 2301 case IceType_f64: { | 2301 case IceType_f64: { |
| 2302 assert(Src0->getType() == IceType_i64); | 2302 assert(Src0->getType() == IceType_i64); |
| 2303 if (Traits::Is64Bit) { | 2303 if (Traits::Is64Bit) { |
| 2304 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 2304 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
| 2305 Variable *T = makeReg(IceType_f64); | 2305 Variable *T = makeReg(IceType_f64); |
| 2306 // Movd requires its fp argument (in this case, the bitcast destination) | 2306 // Movd requires its fp argument (in this case, the bitcast destination) |
| 2307 // to be an xmm register. | 2307 // to be an xmm register. |
| 2308 T->setWeightInfinite(); | 2308 T->setMustHaveReg(); |
| 2309 _movd(T, Src0RM); | 2309 _movd(T, Src0RM); |
| 2310 _mov(Dest, T); | 2310 _mov(Dest, T); |
| 2311 } else { | 2311 } else { |
| 2312 Src0 = legalize(Src0); | 2312 Src0 = legalize(Src0); |
| 2313 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) { | 2313 if (llvm::isa<typename Traits::X86OperandMem>(Src0)) { |
| 2314 Variable *T = Func->makeVariable(Dest->getType()); | 2314 Variable *T = Func->makeVariable(Dest->getType()); |
| 2315 _movq(T, Src0); | 2315 _movq(T, Src0); |
| 2316 _movq(Dest, T); | 2316 _movq(Dest, T); |
| 2317 break; | 2317 break; |
| 2318 } | 2318 } |
| 2319 // a.f64 = bitcast b.i64 ==> | 2319 // a.f64 = bitcast b.i64 ==> |
| 2320 // t_lo.i32 = b_lo.i32 | 2320 // t_lo.i32 = b_lo.i32 |
| 2321 // FakeDef(s.f64) | 2321 // FakeDef(s.f64) |
| 2322 // lo(s.f64) = t_lo.i32 | 2322 // lo(s.f64) = t_lo.i32 |
| 2323 // t_hi.i32 = b_hi.i32 | 2323 // t_hi.i32 = b_hi.i32 |
| 2324 // hi(s.f64) = t_hi.i32 | 2324 // hi(s.f64) = t_hi.i32 |
| 2325 // a.f64 = s.f64 | 2325 // a.f64 = s.f64 |
| 2326 typename Traits::SpillVariable *SpillVar = | 2326 typename Traits::SpillVariable *SpillVar = |
| 2327 Func->makeVariable<typename Traits::SpillVariable>(IceType_f64); | 2327 Func->makeVariable<typename Traits::SpillVariable>(IceType_f64); |
| 2328 SpillVar->setLinkedTo(Dest); | 2328 SpillVar->setLinkedTo(Dest); |
| 2329 Variable *Spill = SpillVar; | 2329 Variable *Spill = SpillVar; |
| 2330 Spill->setWeight(RegWeight::Zero); | 2330 Spill->setMustNotHaveReg(); |
| 2331 | 2331 |
| 2332 Variable *T_Lo = nullptr, *T_Hi = nullptr; | 2332 Variable *T_Lo = nullptr, *T_Hi = nullptr; |
| 2333 typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create( | 2333 typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create( |
| 2334 Func, Spill, Traits::VariableSplit::Low); | 2334 Func, Spill, Traits::VariableSplit::Low); |
| 2335 typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create( | 2335 typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create( |
| 2336 Func, Spill, Traits::VariableSplit::High); | 2336 Func, Spill, Traits::VariableSplit::High); |
| 2337 _mov(T_Lo, loOperand(Src0)); | 2337 _mov(T_Lo, loOperand(Src0)); |
| 2338 // Technically, the Spill is defined after the _store happens, but | 2338 // Technically, the Spill is defined after the _store happens, but |
| 2339 // SpillLo is considered a "use" of Spill so define Spill before it | 2339 // SpillLo is considered a "use" of Spill so define Spill before it |
| 2340 // is used. | 2340 // is used. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2422 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); | 2422 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); |
| 2423 _movss(ExtractedElementR, T); | 2423 _movss(ExtractedElementR, T); |
| 2424 } | 2424 } |
| 2425 } else { | 2425 } else { |
| 2426 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); | 2426 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); |
| 2427 // Spill the value to a stack slot and do the extraction in memory. | 2427 // Spill the value to a stack slot and do the extraction in memory. |
| 2428 // | 2428 // |
| 2429 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when | 2429 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when |
| 2430 // support for legalizing to mem is implemented. | 2430 // support for legalizing to mem is implemented. |
| 2431 Variable *Slot = Func->makeVariable(Ty); | 2431 Variable *Slot = Func->makeVariable(Ty); |
| 2432 Slot->setWeight(RegWeight::Zero); | 2432 Slot->setMustNotHaveReg(); |
| 2433 _movp(Slot, legalizeToReg(SourceVectNotLegalized)); | 2433 _movp(Slot, legalizeToReg(SourceVectNotLegalized)); |
| 2434 | 2434 |
| 2435 // Compute the location of the element in memory. | 2435 // Compute the location of the element in memory. |
| 2436 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); | 2436 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); |
| 2437 typename Traits::X86OperandMem *Loc = | 2437 typename Traits::X86OperandMem *Loc = |
| 2438 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); | 2438 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); |
| 2439 _mov(ExtractedElementR, Loc); | 2439 _mov(ExtractedElementR, Loc); |
| 2440 } | 2440 } |
| 2441 | 2441 |
| 2442 if (ElementTy == IceType_i1) { | 2442 if (ElementTy == IceType_i1) { |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2831 _movp(Inst->getDest(), T); | 2831 _movp(Inst->getDest(), T); |
| 2832 } | 2832 } |
| 2833 } else { | 2833 } else { |
| 2834 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); | 2834 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); |
| 2835 // Spill the value to a stack slot and perform the insertion in | 2835 // Spill the value to a stack slot and perform the insertion in |
| 2836 // memory. | 2836 // memory. |
| 2837 // | 2837 // |
| 2838 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when | 2838 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when |
| 2839 // support for legalizing to mem is implemented. | 2839 // support for legalizing to mem is implemented. |
| 2840 Variable *Slot = Func->makeVariable(Ty); | 2840 Variable *Slot = Func->makeVariable(Ty); |
| 2841 Slot->setWeight(RegWeight::Zero); | 2841 Slot->setMustNotHaveReg(); |
| 2842 _movp(Slot, legalizeToReg(SourceVectNotLegalized)); | 2842 _movp(Slot, legalizeToReg(SourceVectNotLegalized)); |
| 2843 | 2843 |
| 2844 // Compute the location of the position to insert in memory. | 2844 // Compute the location of the position to insert in memory. |
| 2845 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); | 2845 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); |
| 2846 typename Traits::X86OperandMem *Loc = | 2846 typename Traits::X86OperandMem *Loc = |
| 2847 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); | 2847 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); |
| 2848 _store(legalizeToReg(ElementToInsertNotLegalized), Loc); | 2848 _store(legalizeToReg(ElementToInsertNotLegalized), Loc); |
| 2849 | 2849 |
| 2850 Variable *T = makeReg(Ty); | 2850 Variable *T = makeReg(Ty); |
| 2851 _movp(T, Slot); | 2851 _movp(T, Slot); |
| (...skipping 1989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4841 Variable *Reg = makeVectorOfMinusOnes(Ty, RegNum); | 4841 Variable *Reg = makeVectorOfMinusOnes(Ty, RegNum); |
| 4842 _psrl(Reg, Ctx->getConstantInt8(1)); | 4842 _psrl(Reg, Ctx->getConstantInt8(1)); |
| 4843 return Reg; | 4843 return Reg; |
| 4844 } | 4844 } |
| 4845 | 4845 |
| 4846 template <class Machine> | 4846 template <class Machine> |
| 4847 typename TargetX86Base<Machine>::Traits::X86OperandMem * | 4847 typename TargetX86Base<Machine>::Traits::X86OperandMem * |
| 4848 TargetX86Base<Machine>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot, | 4848 TargetX86Base<Machine>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot, |
| 4849 uint32_t Offset) { | 4849 uint32_t Offset) { |
| 4850 // Ensure that Loc is a stack slot. | 4850 // Ensure that Loc is a stack slot. |
| 4851 assert(Slot->getWeight().isZero()); | 4851 assert(Slot->mustNotHaveReg()); |
| 4852 assert(Slot->getRegNum() == Variable::NoRegister); | 4852 assert(Slot->getRegNum() == Variable::NoRegister); |
| 4853 // Compute the location of Loc in memory. | 4853 // Compute the location of Loc in memory. |
| 4854 // TODO(wala,stichnot): lea should not be required. The address of | 4854 // TODO(wala,stichnot): lea should not be required. The address of |
| 4855 // the stack slot is known at compile time (although not until after | 4855 // the stack slot is known at compile time (although not until after |
| 4856 // addProlog()). | 4856 // addProlog()). |
| 4857 const Type PointerType = IceType_i32; | 4857 const Type PointerType = IceType_i32; |
| 4858 Variable *Loc = makeReg(PointerType); | 4858 Variable *Loc = makeReg(PointerType); |
| 4859 _lea(Loc, Slot); | 4859 _lea(Loc, Slot); |
| 4860 Constant *ConstantOffset = Ctx->getConstantInt32(Offset); | 4860 Constant *ConstantOffset = Ctx->getConstantInt32(Offset); |
| 4861 return Traits::X86OperandMem::create(Func, Ty, Loc, ConstantOffset); | 4861 return Traits::X86OperandMem::create(Func, Ty, Loc, ConstantOffset); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4925 Const = llvm::cast<Constant>(From); | 4925 Const = llvm::cast<Constant>(From); |
| 4926 } | 4926 } |
| 4927 // There should be no constants of vector type (other than undef). | 4927 // There should be no constants of vector type (other than undef). |
| 4928 assert(!isVectorType(Ty)); | 4928 assert(!isVectorType(Ty)); |
| 4929 | 4929 |
| 4930 // If the operand is a 64 bit constant integer we need to legalize it to a | 4930 // If the operand is a 64 bit constant integer we need to legalize it to a |
| 4931 // register in x86-64. | 4931 // register in x86-64. |
| 4932 if (Traits::Is64Bit) { | 4932 if (Traits::Is64Bit) { |
| 4933 if (llvm::isa<ConstantInteger64>(Const)) { | 4933 if (llvm::isa<ConstantInteger64>(Const)) { |
| 4934 Variable *V = copyToReg(Const, RegNum); | 4934 Variable *V = copyToReg(Const, RegNum); |
| 4935 V->setWeightInfinite(); | 4935 V->setMustHaveReg(); |
| 4936 return V; | 4936 return V; |
| 4937 } | 4937 } |
| 4938 } | 4938 } |
| 4939 | 4939 |
| 4940 // If the operand is an 32 bit constant integer, we should check | 4940 // If the operand is an 32 bit constant integer, we should check |
| 4941 // whether we need to randomize it or pool it. | 4941 // whether we need to randomize it or pool it. |
| 4942 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(Const)) { | 4942 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(Const)) { |
| 4943 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); | 4943 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); |
| 4944 if (NewConst != Const) { | 4944 if (NewConst != Const) { |
| 4945 return NewConst; | 4945 return NewConst; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4966 NeedsReg = true; | 4966 NeedsReg = true; |
| 4967 if (NeedsReg) { | 4967 if (NeedsReg) { |
| 4968 From = copyToReg(From, RegNum); | 4968 From = copyToReg(From, RegNum); |
| 4969 } | 4969 } |
| 4970 return From; | 4970 return From; |
| 4971 } | 4971 } |
| 4972 if (auto Var = llvm::dyn_cast<Variable>(From)) { | 4972 if (auto Var = llvm::dyn_cast<Variable>(From)) { |
| 4973 // Check if the variable is guaranteed a physical register. This | 4973 // Check if the variable is guaranteed a physical register. This |
| 4974 // can happen either when the variable is pre-colored or when it is | 4974 // can happen either when the variable is pre-colored or when it is |
| 4975 // assigned infinite weight. | 4975 // assigned infinite weight. |
| 4976 bool MustHaveRegister = (Var->hasReg() || Var->getWeight().isInf()); | 4976 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); |
| 4977 // We need a new physical register for the operand if: | 4977 // We need a new physical register for the operand if: |
| 4978 // Mem is not allowed and Var isn't guaranteed a physical | 4978 // Mem is not allowed and Var isn't guaranteed a physical |
| 4979 // register, or | 4979 // register, or |
| 4980 // RegNum is required and Var->getRegNum() doesn't match. | 4980 // RegNum is required and Var->getRegNum() doesn't match. |
| 4981 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 4981 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
| 4982 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { | 4982 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { |
| 4983 From = copyToReg(From, RegNum); | 4983 From = copyToReg(From, RegNum); |
| 4984 } | 4984 } |
| 4985 return From; | 4985 return From; |
| 4986 } | 4986 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5070 return llvm::cast<typename Traits::X86OperandMem>( | 5070 return llvm::cast<typename Traits::X86OperandMem>( |
| 5071 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem)); | 5071 DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem)); |
| 5072 } | 5072 } |
| 5073 | 5073 |
| 5074 template <class Machine> | 5074 template <class Machine> |
| 5075 Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) { | 5075 Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) { |
| 5076 // There aren't any 64-bit integer registers for x86-32. | 5076 // There aren't any 64-bit integer registers for x86-32. |
| 5077 assert(Traits::Is64Bit || Type != IceType_i64); | 5077 assert(Traits::Is64Bit || Type != IceType_i64); |
| 5078 Variable *Reg = Func->makeVariable(Type); | 5078 Variable *Reg = Func->makeVariable(Type); |
| 5079 if (RegNum == Variable::NoRegister) | 5079 if (RegNum == Variable::NoRegister) |
| 5080 Reg->setWeightInfinite(); | 5080 Reg->setMustHaveReg(); |
| 5081 else | 5081 else |
| 5082 Reg->setRegNum(RegNum); | 5082 Reg->setRegNum(RegNum); |
| 5083 return Reg; | 5083 return Reg; |
| 5084 } | 5084 } |
| 5085 | 5085 |
| 5086 template <class Machine> | 5086 template <class Machine> |
| 5087 const Type TargetX86Base<Machine>::TypeForSize[] = { | 5087 const Type TargetX86Base<Machine>::TypeForSize[] = { |
| 5088 IceType_i8, IceType_i16, IceType_i32, | 5088 IceType_i8, IceType_i16, IceType_i32, |
| 5089 (Traits::Is64Bit ? IceType_i64 : IceType_f64), IceType_v16i8}; | 5089 (Traits::Is64Bit ? IceType_i64 : IceType_f64), IceType_v16i8}; |
| 5090 template <class Machine> | 5090 template <class Machine> |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5364 } | 5364 } |
| 5365 // the offset is not eligible for blinding or pooling, return the original | 5365 // the offset is not eligible for blinding or pooling, return the original |
| 5366 // mem operand | 5366 // mem operand |
| 5367 return MemOperand; | 5367 return MemOperand; |
| 5368 } | 5368 } |
| 5369 | 5369 |
| 5370 } // end of namespace X86Internal | 5370 } // end of namespace X86Internal |
| 5371 } // end of namespace Ice | 5371 } // end of namespace Ice |
| 5372 | 5372 |
| 5373 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 5373 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |