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 |