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