| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX86Base.h - x86 lowering ----*- C++ -*-===// | 1 //===- subzero/src/IceTargetLoweringX86Base.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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override; | 176 void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override; |
| 177 void lowerInsertElement(const InstInsertElement *Inst) override; | 177 void lowerInsertElement(const InstInsertElement *Inst) override; |
| 178 void lowerLoad(const InstLoad *Inst) override; | 178 void lowerLoad(const InstLoad *Inst) override; |
| 179 void lowerPhi(const InstPhi *Inst) override; | 179 void lowerPhi(const InstPhi *Inst) override; |
| 180 void lowerRet(const InstRet *Inst) override; | 180 void lowerRet(const InstRet *Inst) override; |
| 181 void lowerSelect(const InstSelect *Inst) override; | 181 void lowerSelect(const InstSelect *Inst) override; |
| 182 void lowerStore(const InstStore *Inst) override; | 182 void lowerStore(const InstStore *Inst) override; |
| 183 void lowerSwitch(const InstSwitch *Inst) override; | 183 void lowerSwitch(const InstSwitch *Inst) override; |
| 184 void lowerUnreachable(const InstUnreachable *Inst) override; | 184 void lowerUnreachable(const InstUnreachable *Inst) override; |
| 185 void lowerOther(const Inst *Instr) override; | 185 void lowerOther(const Inst *Instr) override; |
| 186 void lowerRMW(const InstX8632FakeRMW *RMW); | 186 void lowerRMW(const typename Traits::Insts::FakeRMW *RMW); |
| 187 void prelowerPhis() override; | 187 void prelowerPhis() override; |
| 188 void lowerPhiAssignments(CfgNode *Node, | 188 void lowerPhiAssignments(CfgNode *Node, |
| 189 const AssignList &Assignments) override; | 189 const AssignList &Assignments) override; |
| 190 void doAddressOptLoad() override; | 190 void doAddressOptLoad() override; |
| 191 void doAddressOptStore() override; | 191 void doAddressOptStore() override; |
| 192 void randomlyInsertNop(float Probability) override; | 192 void randomlyInsertNop(float Probability) override; |
| 193 | 193 |
| 194 /// Naive lowering of cmpxchg. | 194 /// Naive lowering of cmpxchg. |
| 195 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, | 195 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, |
| 196 Operand *Desired); | 196 Operand *Desired); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 227 }; | 227 }; |
| 228 typedef uint32_t LegalMask; | 228 typedef uint32_t LegalMask; |
| 229 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | 229 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
| 230 int32_t RegNum = Variable::NoRegister); | 230 int32_t RegNum = Variable::NoRegister); |
| 231 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); | 231 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); |
| 232 /// Legalize the first source operand for use in the cmp instruction. | 232 /// Legalize the first source operand for use in the cmp instruction. |
| 233 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); | 233 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); |
| 234 /// Turn a pointer operand into a memory operand that can be | 234 /// Turn a pointer operand into a memory operand that can be |
| 235 /// used by a real load/store operation. Legalizes the operand as well. | 235 /// used by a real load/store operation. Legalizes the operand as well. |
| 236 /// This is a nop if the operand is already a legal memory operand. | 236 /// This is a nop if the operand is already a legal memory operand. |
| 237 OperandX8632Mem *formMemoryOperand(Operand *Ptr, Type Ty, | 237 typename Traits::X86OperandMem *formMemoryOperand(Operand *Ptr, Type Ty, |
| 238 bool DoLegalize = true); | 238 bool DoLegalize = true); |
| 239 | 239 |
| 240 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 240 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 241 static Type stackSlotType(); | 241 static Type stackSlotType(); |
| 242 | 242 |
| 243 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); | 243 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); |
| 244 | 244 |
| 245 /// Returns a vector in a register with the given constant entries. | 245 /// Returns a vector in a register with the given constant entries. |
| 246 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); | 246 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 247 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister); | 247 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 248 Variable *makeVectorOfMinusOnes(Type Ty, | 248 Variable *makeVectorOfMinusOnes(Type Ty, |
| 249 int32_t RegNum = Variable::NoRegister); | 249 int32_t RegNum = Variable::NoRegister); |
| 250 Variable *makeVectorOfHighOrderBits(Type Ty, | 250 Variable *makeVectorOfHighOrderBits(Type Ty, |
| 251 int32_t RegNum = Variable::NoRegister); | 251 int32_t RegNum = Variable::NoRegister); |
| 252 Variable *makeVectorOfFabsMask(Type Ty, | 252 Variable *makeVectorOfFabsMask(Type Ty, |
| 253 int32_t RegNum = Variable::NoRegister); | 253 int32_t RegNum = Variable::NoRegister); |
| 254 | 254 |
| 255 /// Return a memory operand corresponding to a stack allocated Variable. | 255 /// Return a memory operand corresponding to a stack allocated Variable. |
| 256 OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot, | 256 typename Traits::X86OperandMem * |
| 257 uint32_t Offset = 0); | 257 getMemoryOperandForStackSlot(Type Ty, Variable *Slot, uint32_t Offset = 0); |
| 258 | 258 |
| 259 void makeRandomRegisterPermutation( | 259 void makeRandomRegisterPermutation( |
| 260 llvm::SmallVectorImpl<int32_t> &Permutation, | 260 llvm::SmallVectorImpl<int32_t> &Permutation, |
| 261 const llvm::SmallBitVector &ExcludeRegisters) const override; | 261 const llvm::SmallBitVector &ExcludeRegisters) const override; |
| 262 | 262 |
| 263 // TODO(jpp): move the helper methods below to the MachineTraits. | |
| 264 /// The following are helpers that insert lowered x86 instructions | 263 /// The following are helpers that insert lowered x86 instructions |
| 265 /// with minimal syntactic overhead, so that the lowering code can | 264 /// with minimal syntactic overhead, so that the lowering code can |
| 266 /// look as close to assembly as practical. | 265 /// look as close to assembly as practical. |
| 267 void _adc(Variable *Dest, Operand *Src0) { | 266 void _adc(Variable *Dest, Operand *Src0) { |
| 268 Context.insert(InstX8632Adc::create(Func, Dest, Src0)); | 267 Context.insert(Traits::Insts::Adc::create(Func, Dest, Src0)); |
| 269 } | 268 } |
| 270 void _adc_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 269 void _adc_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
| 271 Context.insert(InstX8632AdcRMW::create(Func, DestSrc0, Src1)); | 270 Context.insert(Traits::Insts::AdcRMW::create(Func, DestSrc0, Src1)); |
| 272 } | 271 } |
| 273 void _add(Variable *Dest, Operand *Src0) { | 272 void _add(Variable *Dest, Operand *Src0) { |
| 274 Context.insert(InstX8632Add::create(Func, Dest, Src0)); | 273 Context.insert(Traits::Insts::Add::create(Func, Dest, Src0)); |
| 275 } | 274 } |
| 276 void _add_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 275 void _add_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
| 277 Context.insert(InstX8632AddRMW::create(Func, DestSrc0, Src1)); | 276 Context.insert(Traits::Insts::AddRMW::create(Func, DestSrc0, Src1)); |
| 278 } | 277 } |
| 279 void _adjust_stack(int32_t Amount) { | 278 void _adjust_stack(int32_t Amount) { |
| 280 Context.insert(InstX8632AdjustStack::create( | 279 Context.insert(Traits::Insts::AdjustStack::create( |
| 281 Func, Amount, getPhysicalRegister(Traits::RegisterSet::Reg_esp))); | 280 Func, Amount, getPhysicalRegister(Traits::RegisterSet::Reg_esp))); |
| 282 } | 281 } |
| 283 void _addps(Variable *Dest, Operand *Src0) { | 282 void _addps(Variable *Dest, Operand *Src0) { |
| 284 Context.insert(InstX8632Addps::create(Func, Dest, Src0)); | 283 Context.insert(Traits::Insts::Addps::create(Func, Dest, Src0)); |
| 285 } | 284 } |
| 286 void _addss(Variable *Dest, Operand *Src0) { | 285 void _addss(Variable *Dest, Operand *Src0) { |
| 287 Context.insert(InstX8632Addss::create(Func, Dest, Src0)); | 286 Context.insert(Traits::Insts::Addss::create(Func, Dest, Src0)); |
| 288 } | 287 } |
| 289 void _and(Variable *Dest, Operand *Src0) { | 288 void _and(Variable *Dest, Operand *Src0) { |
| 290 Context.insert(InstX8632And::create(Func, Dest, Src0)); | 289 Context.insert(Traits::Insts::And::create(Func, Dest, Src0)); |
| 291 } | 290 } |
| 292 void _and_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 291 void _and_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
| 293 Context.insert(InstX8632AndRMW::create(Func, DestSrc0, Src1)); | 292 Context.insert(Traits::Insts::AndRMW::create(Func, DestSrc0, Src1)); |
| 294 } | 293 } |
| 295 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { | 294 void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 296 Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1)); | 295 Context.insert(Traits::Insts::Blendvps::create(Func, Dest, Src0, Src1)); |
| 297 } | 296 } |
| 298 void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue, | 297 void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue, |
| 299 CfgNode *TargetFalse) { | 298 CfgNode *TargetFalse) { |
| 300 Context.insert( | 299 Context.insert( |
| 301 InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition)); | 300 Traits::Insts::Br::create(Func, TargetTrue, TargetFalse, Condition)); |
| 302 } | 301 } |
| 303 void _br(CfgNode *Target) { | 302 void _br(CfgNode *Target) { |
| 304 Context.insert(InstX8632Br::create(Func, Target)); | 303 Context.insert(Traits::Insts::Br::create(Func, Target)); |
| 305 } | 304 } |
| 306 void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) { | 305 void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) { |
| 307 Context.insert(InstX8632Br::create(Func, Target, Condition)); | 306 Context.insert(Traits::Insts::Br::create(Func, Target, Condition)); |
| 308 } | 307 } |
| 309 void _br(typename Traits::Cond::BrCond Condition, InstX8632Label *Label) { | 308 void _br(typename Traits::Cond::BrCond Condition, |
| 310 Context.insert(InstX8632Br::create(Func, Label, Condition)); | 309 typename Traits::Insts::Label *Label) { |
| 310 Context.insert(Traits::Insts::Br::create(Func, Label, Condition)); |
| 311 } | 311 } |
| 312 void _bsf(Variable *Dest, Operand *Src0) { | 312 void _bsf(Variable *Dest, Operand *Src0) { |
| 313 Context.insert(InstX8632Bsf::create(Func, Dest, Src0)); | 313 Context.insert(Traits::Insts::Bsf::create(Func, Dest, Src0)); |
| 314 } | 314 } |
| 315 void _bsr(Variable *Dest, Operand *Src0) { | 315 void _bsr(Variable *Dest, Operand *Src0) { |
| 316 Context.insert(InstX8632Bsr::create(Func, Dest, Src0)); | 316 Context.insert(Traits::Insts::Bsr::create(Func, Dest, Src0)); |
| 317 } | 317 } |
| 318 void _bswap(Variable *SrcDest) { | 318 void _bswap(Variable *SrcDest) { |
| 319 Context.insert(InstX8632Bswap::create(Func, SrcDest)); | 319 Context.insert(Traits::Insts::Bswap::create(Func, SrcDest)); |
| 320 } | 320 } |
| 321 void _cbwdq(Variable *Dest, Operand *Src0) { | 321 void _cbwdq(Variable *Dest, Operand *Src0) { |
| 322 Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0)); | 322 Context.insert(Traits::Insts::Cbwdq::create(Func, Dest, Src0)); |
| 323 } | 323 } |
| 324 void _cmov(Variable *Dest, Operand *Src0, | 324 void _cmov(Variable *Dest, Operand *Src0, |
| 325 typename Traits::Cond::BrCond Condition) { | 325 typename Traits::Cond::BrCond Condition) { |
| 326 Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition)); | 326 Context.insert(Traits::Insts::Cmov::create(Func, Dest, Src0, Condition)); |
| 327 } | 327 } |
| 328 void _cmp(Operand *Src0, Operand *Src1) { | 328 void _cmp(Operand *Src0, Operand *Src1) { |
| 329 Context.insert(InstX8632Icmp::create(Func, Src0, Src1)); | 329 Context.insert(Traits::Insts::Icmp::create(Func, Src0, Src1)); |
| 330 } | 330 } |
| 331 void _cmpps(Variable *Dest, Operand *Src0, | 331 void _cmpps(Variable *Dest, Operand *Src0, |
| 332 typename Traits::Cond::CmppsCond Condition) { | 332 typename Traits::Cond::CmppsCond Condition) { |
| 333 Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition)); | 333 Context.insert(Traits::Insts::Cmpps::create(Func, Dest, Src0, Condition)); |
| 334 } | 334 } |
| 335 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, | 335 void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, |
| 336 bool Locked) { | 336 bool Locked) { |
| 337 Context.insert( | 337 Context.insert( |
| 338 InstX8632Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked)); | 338 Traits::Insts::Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked)); |
| 339 // Mark eax as possibly modified by cmpxchg. | 339 // Mark eax as possibly modified by cmpxchg. |
| 340 Context.insert( | 340 Context.insert( |
| 341 InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr))); | 341 InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr))); |
| 342 _set_dest_nonkillable(); | 342 _set_dest_nonkillable(); |
| 343 Context.insert(InstFakeUse::create(Func, Eax)); | 343 Context.insert(InstFakeUse::create(Func, Eax)); |
| 344 } | 344 } |
| 345 void _cmpxchg8b(OperandX8632Mem *Addr, Variable *Edx, Variable *Eax, | 345 void _cmpxchg8b(typename Traits::X86OperandMem *Addr, Variable *Edx, |
| 346 Variable *Ecx, Variable *Ebx, bool Locked) { | 346 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked) { |
| 347 Context.insert( | 347 Context.insert(Traits::Insts::Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, |
| 348 InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked)); | 348 Ebx, Locked)); |
| 349 // Mark edx, and eax as possibly modified by cmpxchg8b. | 349 // Mark edx, and eax as possibly modified by cmpxchg8b. |
| 350 Context.insert(InstFakeDef::create(Func, Edx)); | 350 Context.insert(InstFakeDef::create(Func, Edx)); |
| 351 _set_dest_nonkillable(); | 351 _set_dest_nonkillable(); |
| 352 Context.insert(InstFakeUse::create(Func, Edx)); | 352 Context.insert(InstFakeUse::create(Func, Edx)); |
| 353 Context.insert(InstFakeDef::create(Func, Eax)); | 353 Context.insert(InstFakeDef::create(Func, Eax)); |
| 354 _set_dest_nonkillable(); | 354 _set_dest_nonkillable(); |
| 355 Context.insert(InstFakeUse::create(Func, Eax)); | 355 Context.insert(InstFakeUse::create(Func, Eax)); |
| 356 } | 356 } |
| 357 void _cvt(Variable *Dest, Operand *Src0, InstX8632Cvt::CvtVariant Variant) { | 357 void _cvt(Variable *Dest, Operand *Src0, |
| 358 Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Variant)); | 358 typename Traits::Insts::Cvt::CvtVariant Variant) { |
| 359 Context.insert(Traits::Insts::Cvt::create(Func, Dest, Src0, Variant)); |
| 359 } | 360 } |
| 360 void _div(Variable *Dest, Operand *Src0, Operand *Src1) { | 361 void _div(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 361 Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1)); | 362 Context.insert(Traits::Insts::Div::create(Func, Dest, Src0, Src1)); |
| 362 } | 363 } |
| 363 void _divps(Variable *Dest, Operand *Src0) { | 364 void _divps(Variable *Dest, Operand *Src0) { |
| 364 Context.insert(InstX8632Divps::create(Func, Dest, Src0)); | 365 Context.insert(Traits::Insts::Divps::create(Func, Dest, Src0)); |
| 365 } | 366 } |
| 366 void _divss(Variable *Dest, Operand *Src0) { | 367 void _divss(Variable *Dest, Operand *Src0) { |
| 367 Context.insert(InstX8632Divss::create(Func, Dest, Src0)); | 368 Context.insert(Traits::Insts::Divss::create(Func, Dest, Src0)); |
| 368 } | 369 } |
| 369 void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); } | 370 void _fld(Operand *Src0) { |
| 371 Context.insert(Traits::Insts::Fld::create(Func, Src0)); |
| 372 } |
| 370 void _fstp(Variable *Dest) { | 373 void _fstp(Variable *Dest) { |
| 371 Context.insert(InstX8632Fstp::create(Func, Dest)); | 374 Context.insert(Traits::Insts::Fstp::create(Func, Dest)); |
| 372 } | 375 } |
| 373 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { | 376 void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 374 Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1)); | 377 Context.insert(Traits::Insts::Idiv::create(Func, Dest, Src0, Src1)); |
| 375 } | 378 } |
| 376 void _imul(Variable *Dest, Operand *Src0) { | 379 void _imul(Variable *Dest, Operand *Src0) { |
| 377 Context.insert(InstX8632Imul::create(Func, Dest, Src0)); | 380 Context.insert(Traits::Insts::Imul::create(Func, Dest, Src0)); |
| 378 } | 381 } |
| 379 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { | 382 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 380 Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1)); | 383 Context.insert(Traits::Insts::Insertps::create(Func, Dest, Src0, Src1)); |
| 381 } | 384 } |
| 382 void _jmp(Operand *Target) { | 385 void _jmp(Operand *Target) { |
| 383 Context.insert(InstX8632Jmp::create(Func, Target)); | 386 Context.insert(Traits::Insts::Jmp::create(Func, Target)); |
| 384 } | 387 } |
| 385 void _lea(Variable *Dest, Operand *Src0) { | 388 void _lea(Variable *Dest, Operand *Src0) { |
| 386 Context.insert(InstX8632Lea::create(Func, Dest, Src0)); | 389 Context.insert(Traits::Insts::Lea::create(Func, Dest, Src0)); |
| 387 } | 390 } |
| 388 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); } | 391 void _mfence() { Context.insert(Traits::Insts::Mfence::create(Func)); } |
| 389 /// If Dest=nullptr is passed in, then a new variable is created, | 392 /// If Dest=nullptr is passed in, then a new variable is created, |
| 390 /// marked as infinite register allocation weight, and returned | 393 /// marked as infinite register allocation weight, and returned |
| 391 /// through the in/out Dest argument. | 394 /// through the in/out Dest argument. |
| 392 void _mov(Variable *&Dest, Operand *Src0, | 395 void _mov(Variable *&Dest, Operand *Src0, |
| 393 int32_t RegNum = Variable::NoRegister) { | 396 int32_t RegNum = Variable::NoRegister) { |
| 394 if (Dest == nullptr) | 397 if (Dest == nullptr) |
| 395 Dest = makeReg(Src0->getType(), RegNum); | 398 Dest = makeReg(Src0->getType(), RegNum); |
| 396 Context.insert(InstX8632Mov::create(Func, Dest, Src0)); | 399 Context.insert(Traits::Insts::Mov::create(Func, Dest, Src0)); |
| 397 } | 400 } |
| 398 void _mov_nonkillable(Variable *Dest, Operand *Src0) { | 401 void _mov_nonkillable(Variable *Dest, Operand *Src0) { |
| 399 Inst *NewInst = InstX8632Mov::create(Func, Dest, Src0); | 402 Inst *NewInst = Traits::Insts::Mov::create(Func, Dest, Src0); |
| 400 NewInst->setDestNonKillable(); | 403 NewInst->setDestNonKillable(); |
| 401 Context.insert(NewInst); | 404 Context.insert(NewInst); |
| 402 } | 405 } |
| 403 void _movd(Variable *Dest, Operand *Src0) { | 406 void _movd(Variable *Dest, Operand *Src0) { |
| 404 Context.insert(InstX8632Movd::create(Func, Dest, Src0)); | 407 Context.insert(Traits::Insts::Movd::create(Func, Dest, Src0)); |
| 405 } | 408 } |
| 406 void _movp(Variable *Dest, Operand *Src0) { | 409 void _movp(Variable *Dest, Operand *Src0) { |
| 407 Context.insert(InstX8632Movp::create(Func, Dest, Src0)); | 410 Context.insert(Traits::Insts::Movp::create(Func, Dest, Src0)); |
| 408 } | 411 } |
| 409 void _movq(Variable *Dest, Operand *Src0) { | 412 void _movq(Variable *Dest, Operand *Src0) { |
| 410 Context.insert(InstX8632Movq::create(Func, Dest, Src0)); | 413 Context.insert(Traits::Insts::Movq::create(Func, Dest, Src0)); |
| 411 } | 414 } |
| 412 void _movss(Variable *Dest, Variable *Src0) { | 415 void _movss(Variable *Dest, Variable *Src0) { |
| 413 Context.insert(InstX8632MovssRegs::create(Func, Dest, Src0)); | 416 Context.insert(Traits::Insts::MovssRegs::create(Func, Dest, Src0)); |
| 414 } | 417 } |
| 415 void _movsx(Variable *Dest, Operand *Src0) { | 418 void _movsx(Variable *Dest, Operand *Src0) { |
| 416 Context.insert(InstX8632Movsx::create(Func, Dest, Src0)); | 419 Context.insert(Traits::Insts::Movsx::create(Func, Dest, Src0)); |
| 417 } | 420 } |
| 418 void _movzx(Variable *Dest, Operand *Src0) { | 421 void _movzx(Variable *Dest, Operand *Src0) { |
| 419 Context.insert(InstX8632Movzx::create(Func, Dest, Src0)); | 422 Context.insert(Traits::Insts::Movzx::create(Func, Dest, Src0)); |
| 420 } | 423 } |
| 421 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { | 424 void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { |
| 422 Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1)); | 425 Context.insert(Traits::Insts::Mul::create(Func, Dest, Src0, Src1)); |
| 423 } | 426 } |
| 424 void _mulps(Variable *Dest, Operand *Src0) { | 427 void _mulps(Variable *Dest, Operand *Src0) { |
| 425 Context.insert(InstX8632Mulps::create(Func, Dest, Src0)); | 428 Context.insert(Traits::Insts::Mulps::create(Func, Dest, Src0)); |
| 426 } | 429 } |
| 427 void _mulss(Variable *Dest, Operand *Src0) { | 430 void _mulss(Variable *Dest, Operand *Src0) { |
| 428 Context.insert(InstX8632Mulss::create(Func, Dest, Src0)); | 431 Context.insert(Traits::Insts::Mulss::create(Func, Dest, Src0)); |
| 429 } | 432 } |
| 430 void _neg(Variable *SrcDest) { | 433 void _neg(Variable *SrcDest) { |
| 431 Context.insert(InstX8632Neg::create(Func, SrcDest)); | 434 Context.insert(Traits::Insts::Neg::create(Func, SrcDest)); |
| 432 } | 435 } |
| 433 void _nop(SizeT Variant) { | 436 void _nop(SizeT Variant) { |
| 434 Context.insert(InstX8632Nop::create(Func, Variant)); | 437 Context.insert(Traits::Insts::Nop::create(Func, Variant)); |
| 435 } | 438 } |
| 436 void _or(Variable *Dest, Operand *Src0) { | 439 void _or(Variable *Dest, Operand *Src0) { |
| 437 Context.insert(InstX8632Or::create(Func, Dest, Src0)); | 440 Context.insert(Traits::Insts::Or::create(Func, Dest, Src0)); |
| 438 } | 441 } |
| 439 void _or_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 442 void _or_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
| 440 Context.insert(InstX8632OrRMW::create(Func, DestSrc0, Src1)); | 443 Context.insert(Traits::Insts::OrRMW::create(Func, DestSrc0, Src1)); |
| 441 } | 444 } |
| 442 void _padd(Variable *Dest, Operand *Src0) { | 445 void _padd(Variable *Dest, Operand *Src0) { |
| 443 Context.insert(InstX8632Padd::create(Func, Dest, Src0)); | 446 Context.insert(Traits::Insts::Padd::create(Func, Dest, Src0)); |
| 444 } | 447 } |
| 445 void _pand(Variable *Dest, Operand *Src0) { | 448 void _pand(Variable *Dest, Operand *Src0) { |
| 446 Context.insert(InstX8632Pand::create(Func, Dest, Src0)); | 449 Context.insert(Traits::Insts::Pand::create(Func, Dest, Src0)); |
| 447 } | 450 } |
| 448 void _pandn(Variable *Dest, Operand *Src0) { | 451 void _pandn(Variable *Dest, Operand *Src0) { |
| 449 Context.insert(InstX8632Pandn::create(Func, Dest, Src0)); | 452 Context.insert(Traits::Insts::Pandn::create(Func, Dest, Src0)); |
| 450 } | 453 } |
| 451 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) { | 454 void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 452 Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1)); | 455 Context.insert(Traits::Insts::Pblendvb::create(Func, Dest, Src0, Src1)); |
| 453 } | 456 } |
| 454 void _pcmpeq(Variable *Dest, Operand *Src0) { | 457 void _pcmpeq(Variable *Dest, Operand *Src0) { |
| 455 Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0)); | 458 Context.insert(Traits::Insts::Pcmpeq::create(Func, Dest, Src0)); |
| 456 } | 459 } |
| 457 void _pcmpgt(Variable *Dest, Operand *Src0) { | 460 void _pcmpgt(Variable *Dest, Operand *Src0) { |
| 458 Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0)); | 461 Context.insert(Traits::Insts::Pcmpgt::create(Func, Dest, Src0)); |
| 459 } | 462 } |
| 460 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) { | 463 void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 461 Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1)); | 464 Context.insert(Traits::Insts::Pextr::create(Func, Dest, Src0, Src1)); |
| 462 } | 465 } |
| 463 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) { | 466 void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 464 Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1)); | 467 Context.insert(Traits::Insts::Pinsr::create(Func, Dest, Src0, Src1)); |
| 465 } | 468 } |
| 466 void _pmull(Variable *Dest, Operand *Src0) { | 469 void _pmull(Variable *Dest, Operand *Src0) { |
| 467 Context.insert(InstX8632Pmull::create(Func, Dest, Src0)); | 470 Context.insert(Traits::Insts::Pmull::create(Func, Dest, Src0)); |
| 468 } | 471 } |
| 469 void _pmuludq(Variable *Dest, Operand *Src0) { | 472 void _pmuludq(Variable *Dest, Operand *Src0) { |
| 470 Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0)); | 473 Context.insert(Traits::Insts::Pmuludq::create(Func, Dest, Src0)); |
| 471 } | 474 } |
| 472 void _pop(Variable *Dest) { | 475 void _pop(Variable *Dest) { |
| 473 Context.insert(InstX8632Pop::create(Func, Dest)); | 476 Context.insert(Traits::Insts::Pop::create(Func, Dest)); |
| 474 } | 477 } |
| 475 void _por(Variable *Dest, Operand *Src0) { | 478 void _por(Variable *Dest, Operand *Src0) { |
| 476 Context.insert(InstX8632Por::create(Func, Dest, Src0)); | 479 Context.insert(Traits::Insts::Por::create(Func, Dest, Src0)); |
| 477 } | 480 } |
| 478 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) { | 481 void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 479 Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1)); | 482 Context.insert(Traits::Insts::Pshufd::create(Func, Dest, Src0, Src1)); |
| 480 } | 483 } |
| 481 void _psll(Variable *Dest, Operand *Src0) { | 484 void _psll(Variable *Dest, Operand *Src0) { |
| 482 Context.insert(InstX8632Psll::create(Func, Dest, Src0)); | 485 Context.insert(Traits::Insts::Psll::create(Func, Dest, Src0)); |
| 483 } | 486 } |
| 484 void _psra(Variable *Dest, Operand *Src0) { | 487 void _psra(Variable *Dest, Operand *Src0) { |
| 485 Context.insert(InstX8632Psra::create(Func, Dest, Src0)); | 488 Context.insert(Traits::Insts::Psra::create(Func, Dest, Src0)); |
| 486 } | 489 } |
| 487 void _psrl(Variable *Dest, Operand *Src0) { | 490 void _psrl(Variable *Dest, Operand *Src0) { |
| 488 Context.insert(InstX8632Psrl::create(Func, Dest, Src0)); | 491 Context.insert(Traits::Insts::Psrl::create(Func, Dest, Src0)); |
| 489 } | 492 } |
| 490 void _psub(Variable *Dest, Operand *Src0) { | 493 void _psub(Variable *Dest, Operand *Src0) { |
| 491 Context.insert(InstX8632Psub::create(Func, Dest, Src0)); | 494 Context.insert(Traits::Insts::Psub::create(Func, Dest, Src0)); |
| 492 } | 495 } |
| 493 void _push(Variable *Src0) { | 496 void _push(Variable *Src0) { |
| 494 Context.insert(InstX8632Push::create(Func, Src0)); | 497 Context.insert(Traits::Insts::Push::create(Func, Src0)); |
| 495 } | 498 } |
| 496 void _pxor(Variable *Dest, Operand *Src0) { | 499 void _pxor(Variable *Dest, Operand *Src0) { |
| 497 Context.insert(InstX8632Pxor::create(Func, Dest, Src0)); | 500 Context.insert(Traits::Insts::Pxor::create(Func, Dest, Src0)); |
| 498 } | 501 } |
| 499 void _ret(Variable *Src0 = nullptr) { | 502 void _ret(Variable *Src0 = nullptr) { |
| 500 Context.insert(InstX8632Ret::create(Func, Src0)); | 503 Context.insert(Traits::Insts::Ret::create(Func, Src0)); |
| 501 } | 504 } |
| 502 void _rol(Variable *Dest, Operand *Src0) { | 505 void _rol(Variable *Dest, Operand *Src0) { |
| 503 Context.insert(InstX8632Rol::create(Func, Dest, Src0)); | 506 Context.insert(Traits::Insts::Rol::create(Func, Dest, Src0)); |
| 504 } | 507 } |
| 505 void _sar(Variable *Dest, Operand *Src0) { | 508 void _sar(Variable *Dest, Operand *Src0) { |
| 506 Context.insert(InstX8632Sar::create(Func, Dest, Src0)); | 509 Context.insert(Traits::Insts::Sar::create(Func, Dest, Src0)); |
| 507 } | 510 } |
| 508 void _sbb(Variable *Dest, Operand *Src0) { | 511 void _sbb(Variable *Dest, Operand *Src0) { |
| 509 Context.insert(InstX8632Sbb::create(Func, Dest, Src0)); | 512 Context.insert(Traits::Insts::Sbb::create(Func, Dest, Src0)); |
| 510 } | 513 } |
| 511 void _sbb_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 514 void _sbb_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
| 512 Context.insert(InstX8632SbbRMW::create(Func, DestSrc0, Src1)); | 515 Context.insert(Traits::Insts::SbbRMW::create(Func, DestSrc0, Src1)); |
| 513 } | 516 } |
| 514 void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) { | 517 void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) { |
| 515 Context.insert(InstX8632Setcc::create(Func, Dest, Condition)); | 518 Context.insert(Traits::Insts::Setcc::create(Func, Dest, Condition)); |
| 516 } | 519 } |
| 517 void _shl(Variable *Dest, Operand *Src0) { | 520 void _shl(Variable *Dest, Operand *Src0) { |
| 518 Context.insert(InstX8632Shl::create(Func, Dest, Src0)); | 521 Context.insert(Traits::Insts::Shl::create(Func, Dest, Src0)); |
| 519 } | 522 } |
| 520 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) { | 523 void _shld(Variable *Dest, Variable *Src0, Variable *Src1) { |
| 521 Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1)); | 524 Context.insert(Traits::Insts::Shld::create(Func, Dest, Src0, Src1)); |
| 522 } | 525 } |
| 523 void _shr(Variable *Dest, Operand *Src0) { | 526 void _shr(Variable *Dest, Operand *Src0) { |
| 524 Context.insert(InstX8632Shr::create(Func, Dest, Src0)); | 527 Context.insert(Traits::Insts::Shr::create(Func, Dest, Src0)); |
| 525 } | 528 } |
| 526 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { | 529 void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) { |
| 527 Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1)); | 530 Context.insert(Traits::Insts::Shrd::create(Func, Dest, Src0, Src1)); |
| 528 } | 531 } |
| 529 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) { | 532 void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 530 Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1)); | 533 Context.insert(Traits::Insts::Shufps::create(Func, Dest, Src0, Src1)); |
| 531 } | 534 } |
| 532 void _sqrtss(Variable *Dest, Operand *Src0) { | 535 void _sqrtss(Variable *Dest, Operand *Src0) { |
| 533 Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0)); | 536 Context.insert(Traits::Insts::Sqrtss::create(Func, Dest, Src0)); |
| 534 } | 537 } |
| 535 void _store(Operand *Value, OperandX8632 *Mem) { | 538 void _store(Operand *Value, typename Traits::X86Operand *Mem) { |
| 536 Context.insert(InstX8632Store::create(Func, Value, Mem)); | 539 Context.insert(Traits::Insts::Store::create(Func, Value, Mem)); |
| 537 } | 540 } |
| 538 void _storep(Variable *Value, OperandX8632Mem *Mem) { | 541 void _storep(Variable *Value, typename Traits::X86OperandMem *Mem) { |
| 539 Context.insert(InstX8632StoreP::create(Func, Value, Mem)); | 542 Context.insert(Traits::Insts::StoreP::create(Func, Value, Mem)); |
| 540 } | 543 } |
| 541 void _storeq(Variable *Value, OperandX8632Mem *Mem) { | 544 void _storeq(Variable *Value, typename Traits::X86OperandMem *Mem) { |
| 542 Context.insert(InstX8632StoreQ::create(Func, Value, Mem)); | 545 Context.insert(Traits::Insts::StoreQ::create(Func, Value, Mem)); |
| 543 } | 546 } |
| 544 void _sub(Variable *Dest, Operand *Src0) { | 547 void _sub(Variable *Dest, Operand *Src0) { |
| 545 Context.insert(InstX8632Sub::create(Func, Dest, Src0)); | 548 Context.insert(Traits::Insts::Sub::create(Func, Dest, Src0)); |
| 546 } | 549 } |
| 547 void _sub_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 550 void _sub_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
| 548 Context.insert(InstX8632SubRMW::create(Func, DestSrc0, Src1)); | 551 Context.insert(Traits::Insts::SubRMW::create(Func, DestSrc0, Src1)); |
| 549 } | 552 } |
| 550 void _subps(Variable *Dest, Operand *Src0) { | 553 void _subps(Variable *Dest, Operand *Src0) { |
| 551 Context.insert(InstX8632Subps::create(Func, Dest, Src0)); | 554 Context.insert(Traits::Insts::Subps::create(Func, Dest, Src0)); |
| 552 } | 555 } |
| 553 void _subss(Variable *Dest, Operand *Src0) { | 556 void _subss(Variable *Dest, Operand *Src0) { |
| 554 Context.insert(InstX8632Subss::create(Func, Dest, Src0)); | 557 Context.insert(Traits::Insts::Subss::create(Func, Dest, Src0)); |
| 555 } | 558 } |
| 556 void _test(Operand *Src0, Operand *Src1) { | 559 void _test(Operand *Src0, Operand *Src1) { |
| 557 Context.insert(InstX8632Test::create(Func, Src0, Src1)); | 560 Context.insert(Traits::Insts::Test::create(Func, Src0, Src1)); |
| 558 } | 561 } |
| 559 void _ucomiss(Operand *Src0, Operand *Src1) { | 562 void _ucomiss(Operand *Src0, Operand *Src1) { |
| 560 Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1)); | 563 Context.insert(Traits::Insts::Ucomiss::create(Func, Src0, Src1)); |
| 561 } | 564 } |
| 562 void _ud2() { Context.insert(InstX8632UD2::create(Func)); } | 565 void _ud2() { Context.insert(Traits::Insts::UD2::create(Func)); } |
| 563 void _xadd(Operand *Dest, Variable *Src, bool Locked) { | 566 void _xadd(Operand *Dest, Variable *Src, bool Locked) { |
| 564 Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked)); | 567 Context.insert(Traits::Insts::Xadd::create(Func, Dest, Src, Locked)); |
| 565 // The xadd exchanges Dest and Src (modifying Src). | 568 // The xadd exchanges Dest and Src (modifying Src). |
| 566 // Model that update with a FakeDef followed by a FakeUse. | 569 // Model that update with a FakeDef followed by a FakeUse. |
| 567 Context.insert( | 570 Context.insert( |
| 568 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); | 571 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); |
| 569 _set_dest_nonkillable(); | 572 _set_dest_nonkillable(); |
| 570 Context.insert(InstFakeUse::create(Func, Src)); | 573 Context.insert(InstFakeUse::create(Func, Src)); |
| 571 } | 574 } |
| 572 void _xchg(Operand *Dest, Variable *Src) { | 575 void _xchg(Operand *Dest, Variable *Src) { |
| 573 Context.insert(InstX8632Xchg::create(Func, Dest, Src)); | 576 Context.insert(Traits::Insts::Xchg::create(Func, Dest, Src)); |
| 574 // The xchg modifies Dest and Src -- model that update with a | 577 // The xchg modifies Dest and Src -- model that update with a |
| 575 // FakeDef/FakeUse. | 578 // FakeDef/FakeUse. |
| 576 Context.insert( | 579 Context.insert( |
| 577 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); | 580 InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest))); |
| 578 _set_dest_nonkillable(); | 581 _set_dest_nonkillable(); |
| 579 Context.insert(InstFakeUse::create(Func, Src)); | 582 Context.insert(InstFakeUse::create(Func, Src)); |
| 580 } | 583 } |
| 581 void _xor(Variable *Dest, Operand *Src0) { | 584 void _xor(Variable *Dest, Operand *Src0) { |
| 582 Context.insert(InstX8632Xor::create(Func, Dest, Src0)); | 585 Context.insert(Traits::Insts::Xor::create(Func, Dest, Src0)); |
| 583 } | 586 } |
| 584 void _xor_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 587 void _xor_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { |
| 585 Context.insert(InstX8632XorRMW::create(Func, DestSrc0, Src1)); | 588 Context.insert(Traits::Insts::XorRMW::create(Func, DestSrc0, Src1)); |
| 586 } | 589 } |
| 587 void _set_dest_nonkillable() { | 590 void _set_dest_nonkillable() { |
| 588 Context.getLastInserted()->setDestNonKillable(); | 591 Context.getLastInserted()->setDestNonKillable(); |
| 589 } | 592 } |
| 590 | 593 |
| 591 bool optimizeScalarMul(Variable *Dest, Operand *Src0, int32_t Src1); | 594 bool optimizeScalarMul(Variable *Dest, Operand *Src0, int32_t Src1); |
| 592 void findRMW(); | 595 void findRMW(); |
| 593 | 596 |
| 594 typename Traits::InstructionSet InstructionSet = | 597 typename Traits::InstructionSet InstructionSet = |
| 595 Traits::InstructionSet::Begin; | 598 Traits::InstructionSet::Begin; |
| 596 bool IsEbpBasedFrame = false; | 599 bool IsEbpBasedFrame = false; |
| 597 bool NeedsStackAlignment = false; | 600 bool NeedsStackAlignment = false; |
| 598 size_t SpillAreaSizeBytes = 0; | 601 size_t SpillAreaSizeBytes = 0; |
| 599 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 602 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
| 600 llvm::SmallBitVector ScratchRegs; | 603 llvm::SmallBitVector ScratchRegs; |
| 601 llvm::SmallBitVector RegsUsed; | 604 llvm::SmallBitVector RegsUsed; |
| 602 VarList PhysicalRegisters[IceType_NUM]; | 605 VarList PhysicalRegisters[IceType_NUM]; |
| 603 static IceString RegNames[]; | |
| 604 | 606 |
| 605 /// Randomize a given immediate operand | 607 /// Randomize a given immediate operand |
| 606 Operand *randomizeOrPoolImmediate(Constant *Immediate, | 608 Operand *randomizeOrPoolImmediate(Constant *Immediate, |
| 607 int32_t RegNum = Variable::NoRegister); | 609 int32_t RegNum = Variable::NoRegister); |
| 608 OperandX8632Mem * | 610 typename Traits::X86OperandMem * |
| 609 randomizeOrPoolImmediate(OperandX8632Mem *MemOperand, | 611 randomizeOrPoolImmediate(typename Traits::X86OperandMem *MemOperand, |
| 610 int32_t RegNum = Variable::NoRegister); | 612 int32_t RegNum = Variable::NoRegister); |
| 611 bool RandomizationPoolingPaused = false; | 613 bool RandomizationPoolingPaused = false; |
| 612 | 614 |
| 613 private: | 615 private: |
| 614 ~TargetX86Base() override {} | 616 ~TargetX86Base() override {} |
| 615 BoolFolding FoldingInfo; | 617 BoolFolding FoldingInfo; |
| 616 }; | 618 }; |
| 617 } // end of namespace X86Internal | 619 } // end of namespace X86Internal |
| 618 } // end of namespace Ice | 620 } // end of namespace Ice |
| 619 | 621 |
| 620 #include "IceTargetLoweringX86BaseImpl.h" | 622 #include "IceTargetLoweringX86BaseImpl.h" |
| 621 | 623 |
| 622 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H | 624 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H |
| OLD | NEW |