| OLD | NEW |
| 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
| 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 implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "IceInst.h" | 21 #include "IceInst.h" |
| 22 #include "IceRegistersX8632.h" | 22 #include "IceRegistersX8632.h" |
| 23 #include "IceTargetLoweringX8632.h" | 23 #include "IceTargetLoweringX8632.h" |
| 24 #include "IceOperand.h" | 24 #include "IceOperand.h" |
| 25 | 25 |
| 26 namespace Ice { | 26 namespace Ice { |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 const struct InstX8632BrAttributes_ { | 30 const struct InstX8632BrAttributes_ { |
| 31 CondX86::BrCond Opposite; | 31 X8632::Traits::Cond::BrCond Opposite; |
| 32 const char *DisplayString; | 32 const char *DisplayString; |
| 33 const char *EmitString; | 33 const char *EmitString; |
| 34 } InstX8632BrAttributes[] = { | 34 } InstX8632BrAttributes[] = { |
| 35 #define X(tag, encode, opp, dump, emit) \ | 35 #define X(tag, encode, opp, dump, emit) \ |
| 36 { CondX86::opp, dump, emit } \ | 36 { X8632::Traits::Cond::opp, dump, emit } \ |
| 37 , | 37 , |
| 38 ICEINSTX8632BR_TABLE | 38 ICEINSTX8632BR_TABLE |
| 39 #undef X | 39 #undef X |
| 40 }; | 40 }; |
| 41 | 41 |
| 42 const struct InstX8632CmppsAttributes_ { | 42 const struct InstX8632CmppsAttributes_ { |
| 43 const char *EmitString; | 43 const char *EmitString; |
| 44 } InstX8632CmppsAttributes[] = { | 44 } InstX8632CmppsAttributes[] = { |
| 45 #define X(tag, emit) \ | 45 #define X(tag, emit) \ |
| 46 { emit } \ | 46 { emit } \ |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 } // end of anonymous namespace | 78 } // end of anonymous namespace |
| 79 | 79 |
| 80 const char *InstX8632::getWidthString(Type Ty) { | 80 const char *InstX8632::getWidthString(Type Ty) { |
| 81 return TypeX8632Attributes[Ty].WidthString; | 81 return TypeX8632Attributes[Ty].WidthString; |
| 82 } | 82 } |
| 83 | 83 |
| 84 const char *InstX8632::getFldString(Type Ty) { | 84 const char *InstX8632::getFldString(Type Ty) { |
| 85 return TypeX8632Attributes[Ty].FldString; | 85 return TypeX8632Attributes[Ty].FldString; |
| 86 } | 86 } |
| 87 | 87 |
| 88 CondX86::BrCond InstX8632::getOppositeCondition(CondX86::BrCond Cond) { | 88 X8632::Traits::Cond::BrCond |
| 89 InstX8632::getOppositeCondition(X8632::Traits::Cond::BrCond Cond) { |
| 89 return InstX8632BrAttributes[Cond].Opposite; | 90 return InstX8632BrAttributes[Cond].Opposite; |
| 90 } | 91 } |
| 91 | 92 |
| 92 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, | 93 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, |
| 93 Constant *Offset, Variable *Index, | 94 Constant *Offset, Variable *Index, |
| 94 uint16_t Shift, SegmentRegisters SegmentReg) | 95 uint16_t Shift, SegmentRegisters SegmentReg) |
| 95 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 96 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
| 96 Shift(Shift), SegmentReg(SegmentReg), Randomized(false) { | 97 Shift(Shift), SegmentReg(SegmentReg), Randomized(false) { |
| 97 assert(Shift <= 3); | 98 assert(Shift <= 3); |
| 98 Vars = nullptr; | 99 Vars = nullptr; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 InstX8632Label::InstX8632Label(Cfg *Func, TargetX8632 *Target) | 153 InstX8632Label::InstX8632Label(Cfg *Func, TargetX8632 *Target) |
| 153 : InstX8632(Func, InstX8632::Label, 0, nullptr), | 154 : InstX8632(Func, InstX8632::Label, 0, nullptr), |
| 154 Number(Target->makeNextLabelNumber()) {} | 155 Number(Target->makeNextLabelNumber()) {} |
| 155 | 156 |
| 156 IceString InstX8632Label::getName(const Cfg *Func) const { | 157 IceString InstX8632Label::getName(const Cfg *Func) const { |
| 157 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); | 158 return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number); |
| 158 } | 159 } |
| 159 | 160 |
| 160 InstX8632Br::InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, | 161 InstX8632Br::InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, |
| 161 const CfgNode *TargetFalse, | 162 const CfgNode *TargetFalse, |
| 162 const InstX8632Label *Label, CondX86::BrCond Condition) | 163 const InstX8632Label *Label, |
| 164 X8632::Traits::Cond::BrCond Condition) |
| 163 : InstX8632(Func, InstX8632::Br, 0, nullptr), Condition(Condition), | 165 : InstX8632(Func, InstX8632::Br, 0, nullptr), Condition(Condition), |
| 164 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} | 166 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} |
| 165 | 167 |
| 166 bool InstX8632Br::optimizeBranch(const CfgNode *NextNode) { | 168 bool InstX8632Br::optimizeBranch(const CfgNode *NextNode) { |
| 167 // If there is no next block, then there can be no fallthrough to | 169 // If there is no next block, then there can be no fallthrough to |
| 168 // optimize. | 170 // optimize. |
| 169 if (NextNode == nullptr) | 171 if (NextNode == nullptr) |
| 170 return false; | 172 return false; |
| 171 // Intra-block conditional branches can't be optimized. | 173 // Intra-block conditional branches can't be optimized. |
| 172 if (Label) | 174 if (Label) |
| 173 return false; | 175 return false; |
| 174 // If there is no fallthrough node, such as a non-default case label | 176 // If there is no fallthrough node, such as a non-default case label |
| 175 // for a switch instruction, then there is no opportunity to | 177 // for a switch instruction, then there is no opportunity to |
| 176 // optimize. | 178 // optimize. |
| 177 if (getTargetFalse() == nullptr) | 179 if (getTargetFalse() == nullptr) |
| 178 return false; | 180 return false; |
| 179 | 181 |
| 180 // Unconditional branch to the next node can be removed. | 182 // Unconditional branch to the next node can be removed. |
| 181 if (Condition == CondX86::Br_None && getTargetFalse() == NextNode) { | 183 if (Condition == X8632::Traits::Cond::Br_None && |
| 184 getTargetFalse() == NextNode) { |
| 182 assert(getTargetTrue() == nullptr); | 185 assert(getTargetTrue() == nullptr); |
| 183 setDeleted(); | 186 setDeleted(); |
| 184 return true; | 187 return true; |
| 185 } | 188 } |
| 186 // If the fallthrough is to the next node, set fallthrough to nullptr | 189 // If the fallthrough is to the next node, set fallthrough to nullptr |
| 187 // to indicate. | 190 // to indicate. |
| 188 if (getTargetFalse() == NextNode) { | 191 if (getTargetFalse() == NextNode) { |
| 189 TargetFalse = nullptr; | 192 TargetFalse = nullptr; |
| 190 return true; | 193 return true; |
| 191 } | 194 } |
| 192 // If TargetTrue is the next node, and TargetFalse is not nullptr | 195 // If TargetTrue is the next node, and TargetFalse is not nullptr |
| 193 // (which was already tested above), then invert the branch | 196 // (which was already tested above), then invert the branch |
| 194 // condition, swap the targets, and set new fallthrough to nullptr. | 197 // condition, swap the targets, and set new fallthrough to nullptr. |
| 195 if (getTargetTrue() == NextNode) { | 198 if (getTargetTrue() == NextNode) { |
| 196 assert(Condition != CondX86::Br_None); | 199 assert(Condition != X8632::Traits::Cond::Br_None); |
| 197 Condition = getOppositeCondition(Condition); | 200 Condition = getOppositeCondition(Condition); |
| 198 TargetTrue = getTargetFalse(); | 201 TargetTrue = getTargetFalse(); |
| 199 TargetFalse = nullptr; | 202 TargetFalse = nullptr; |
| 200 return true; | 203 return true; |
| 201 } | 204 } |
| 202 return false; | 205 return false; |
| 203 } | 206 } |
| 204 | 207 |
| 205 bool InstX8632Br::repointEdge(CfgNode *OldNode, CfgNode *NewNode) { | 208 bool InstX8632Br::repointEdge(CfgNode *OldNode, CfgNode *NewNode) { |
| 206 if (TargetFalse == OldNode) { | 209 if (TargetFalse == OldNode) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 218 addSource(Target); | 221 addSource(Target); |
| 219 } | 222 } |
| 220 | 223 |
| 221 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) | 224 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) |
| 222 : InstX8632(Func, InstX8632::Call, 1, Dest) { | 225 : InstX8632(Func, InstX8632::Call, 1, Dest) { |
| 223 HasSideEffects = true; | 226 HasSideEffects = true; |
| 224 addSource(CallTarget); | 227 addSource(CallTarget); |
| 225 } | 228 } |
| 226 | 229 |
| 227 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, | 230 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, |
| 228 CondX86::BrCond Condition) | 231 X8632::Traits::Cond::BrCond Condition) |
| 229 : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) { | 232 : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) { |
| 230 // The final result is either the original Dest, or Source, so mark | 233 // The final result is either the original Dest, or Source, so mark |
| 231 // both as sources. | 234 // both as sources. |
| 232 addSource(Dest); | 235 addSource(Dest); |
| 233 addSource(Source); | 236 addSource(Source); |
| 234 } | 237 } |
| 235 | 238 |
| 236 InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, | 239 InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, |
| 237 CondX86::CmppsCond Condition) | 240 X8632::Traits::Cond::CmppsCond Condition) |
| 238 : InstX8632(Func, InstX8632::Cmpps, 2, Dest), Condition(Condition) { | 241 : InstX8632(Func, InstX8632::Cmpps, 2, Dest), Condition(Condition) { |
| 239 addSource(Dest); | 242 addSource(Dest); |
| 240 addSource(Source); | 243 addSource(Source); |
| 241 } | 244 } |
| 242 | 245 |
| 243 InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, | 246 InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, |
| 244 Variable *Eax, Variable *Desired, | 247 Variable *Eax, Variable *Desired, |
| 245 bool Locked) | 248 bool Locked) |
| 246 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, | 249 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, |
| 247 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { | 250 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 : InstX8632(Func, InstX8632::Push, 1, nullptr) { | 348 : InstX8632(Func, InstX8632::Push, 1, nullptr) { |
| 346 addSource(Source); | 349 addSource(Source); |
| 347 } | 350 } |
| 348 | 351 |
| 349 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) | 352 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) |
| 350 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, nullptr) { | 353 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, nullptr) { |
| 351 if (Source) | 354 if (Source) |
| 352 addSource(Source); | 355 addSource(Source); |
| 353 } | 356 } |
| 354 | 357 |
| 355 InstX8632Setcc::InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond) | 358 InstX8632Setcc::InstX8632Setcc(Cfg *Func, Variable *Dest, |
| 359 X8632::Traits::Cond::BrCond Cond) |
| 356 : InstX8632(Func, InstX8632::Setcc, 0, Dest), Condition(Cond) {} | 360 : InstX8632(Func, InstX8632::Setcc, 0, Dest), Condition(Cond) {} |
| 357 | 361 |
| 358 InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, | 362 InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, |
| 359 bool Locked) | 363 bool Locked) |
| 360 : InstX8632Lockable(Func, InstX8632::Xadd, 2, | 364 : InstX8632Lockable(Func, InstX8632::Xadd, 2, |
| 361 llvm::dyn_cast<Variable>(Dest), Locked) { | 365 llvm::dyn_cast<Variable>(Dest), Locked) { |
| 362 addSource(Dest); | 366 addSource(Dest); |
| 363 addSource(Source); | 367 addSource(Source); |
| 364 } | 368 } |
| 365 | 369 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 Ostream &Str = Func->getContext()->getStrDump(); | 414 Ostream &Str = Func->getContext()->getStrDump(); |
| 411 Str << getName(Func) << ":"; | 415 Str << getName(Func) << ":"; |
| 412 } | 416 } |
| 413 | 417 |
| 414 void InstX8632Br::emit(const Cfg *Func) const { | 418 void InstX8632Br::emit(const Cfg *Func) const { |
| 415 if (!BuildDefs::dump()) | 419 if (!BuildDefs::dump()) |
| 416 return; | 420 return; |
| 417 Ostream &Str = Func->getContext()->getStrEmit(); | 421 Ostream &Str = Func->getContext()->getStrEmit(); |
| 418 Str << "\t"; | 422 Str << "\t"; |
| 419 | 423 |
| 420 if (Condition == CondX86::Br_None) { | 424 if (Condition == X8632::Traits::Cond::Br_None) { |
| 421 Str << "jmp"; | 425 Str << "jmp"; |
| 422 } else { | 426 } else { |
| 423 Str << InstX8632BrAttributes[Condition].EmitString; | 427 Str << InstX8632BrAttributes[Condition].EmitString; |
| 424 } | 428 } |
| 425 | 429 |
| 426 if (Label) { | 430 if (Label) { |
| 427 Str << "\t" << Label->getName(Func); | 431 Str << "\t" << Label->getName(Func); |
| 428 } else { | 432 } else { |
| 429 if (Condition == CondX86::Br_None) { | 433 if (Condition == X8632::Traits::Cond::Br_None) { |
| 430 Str << "\t" << getTargetFalse()->getAsmName(); | 434 Str << "\t" << getTargetFalse()->getAsmName(); |
| 431 } else { | 435 } else { |
| 432 Str << "\t" << getTargetTrue()->getAsmName(); | 436 Str << "\t" << getTargetTrue()->getAsmName(); |
| 433 if (getTargetFalse()) { | 437 if (getTargetFalse()) { |
| 434 Str << "\n\tjmp\t" << getTargetFalse()->getAsmName(); | 438 Str << "\n\tjmp\t" << getTargetFalse()->getAsmName(); |
| 435 } | 439 } |
| 436 } | 440 } |
| 437 } | 441 } |
| 438 } | 442 } |
| 439 | 443 |
| 440 void InstX8632Br::emitIAS(const Cfg *Func) const { | 444 void InstX8632Br::emitIAS(const Cfg *Func) const { |
| 441 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 445 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 442 if (Label) { | 446 if (Label) { |
| 443 X8632::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber()); | 447 X8632::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber()); |
| 444 // In all these cases, local Labels should only be used for Near. | 448 // In all these cases, local Labels should only be used for Near. |
| 445 const bool Near = true; | 449 const bool Near = true; |
| 446 if (Condition == CondX86::Br_None) { | 450 if (Condition == X8632::Traits::Cond::Br_None) { |
| 447 Asm->jmp(L, Near); | 451 Asm->jmp(L, Near); |
| 448 } else { | 452 } else { |
| 449 Asm->j(Condition, L, Near); | 453 Asm->j(Condition, L, Near); |
| 450 } | 454 } |
| 451 } else { | 455 } else { |
| 452 // Pessimistically assume it's far. This only affects Labels that | 456 // Pessimistically assume it's far. This only affects Labels that |
| 453 // are not Bound. | 457 // are not Bound. |
| 454 const bool Near = false; | 458 const bool Near = false; |
| 455 if (Condition == CondX86::Br_None) { | 459 if (Condition == X8632::Traits::Cond::Br_None) { |
| 456 X8632::Label *L = | 460 X8632::Label *L = |
| 457 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 461 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
| 458 assert(!getTargetTrue()); | 462 assert(!getTargetTrue()); |
| 459 Asm->jmp(L, Near); | 463 Asm->jmp(L, Near); |
| 460 } else { | 464 } else { |
| 461 X8632::Label *L = | 465 X8632::Label *L = |
| 462 Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); | 466 Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); |
| 463 Asm->j(Condition, L, Near); | 467 Asm->j(Condition, L, Near); |
| 464 if (getTargetFalse()) { | 468 if (getTargetFalse()) { |
| 465 X8632::Label *L2 = | 469 X8632::Label *L2 = |
| 466 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 470 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
| 467 Asm->jmp(L2, Near); | 471 Asm->jmp(L2, Near); |
| 468 } | 472 } |
| 469 } | 473 } |
| 470 } | 474 } |
| 471 } | 475 } |
| 472 | 476 |
| 473 void InstX8632Br::dump(const Cfg *Func) const { | 477 void InstX8632Br::dump(const Cfg *Func) const { |
| 474 if (!BuildDefs::dump()) | 478 if (!BuildDefs::dump()) |
| 475 return; | 479 return; |
| 476 Ostream &Str = Func->getContext()->getStrDump(); | 480 Ostream &Str = Func->getContext()->getStrDump(); |
| 477 Str << "br "; | 481 Str << "br "; |
| 478 | 482 |
| 479 if (Condition == CondX86::Br_None) { | 483 if (Condition == X8632::Traits::Cond::Br_None) { |
| 480 Str << "label %" | 484 Str << "label %" |
| 481 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); | 485 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); |
| 482 return; | 486 return; |
| 483 } | 487 } |
| 484 | 488 |
| 485 Str << InstX8632BrAttributes[Condition].DisplayString; | 489 Str << InstX8632BrAttributes[Condition].DisplayString; |
| 486 if (Label) { | 490 if (Label) { |
| 487 Str << ", label %" << Label->getName(Func); | 491 Str << ", label %" << Label->getName(Func); |
| 488 } else { | 492 } else { |
| 489 Str << ", label %" << getTargetTrue()->getName(); | 493 Str << ", label %" << getTargetTrue()->getName(); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, | 633 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, |
| 630 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter) { | 634 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter) { |
| 631 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 635 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 632 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { | 636 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { |
| 633 if (Var->hasReg()) { | 637 if (Var->hasReg()) { |
| 634 // We cheat a little and use GPRRegister even for byte operations. | 638 // We cheat a little and use GPRRegister even for byte operations. |
| 635 RegX8632::GPRRegister VarReg = | 639 RegX8632::GPRRegister VarReg = |
| 636 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); | 640 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
| 637 (Asm->*(Emitter.Reg))(Ty, VarReg); | 641 (Asm->*(Emitter.Reg))(Ty, VarReg); |
| 638 } else { | 642 } else { |
| 639 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 643 X8632::Traits::Address StackAddr( |
| 640 ->stackVarToAsmOperand(Var)); | 644 static_cast<TargetX8632 *>(Func->getTarget()) |
| 645 ->stackVarToAsmOperand(Var)); |
| 641 (Asm->*(Emitter.Addr))(Ty, StackAddr); | 646 (Asm->*(Emitter.Addr))(Ty, StackAddr); |
| 642 } | 647 } |
| 643 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { | 648 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { |
| 644 Mem->emitSegmentOverride(Asm); | 649 Mem->emitSegmentOverride(Asm); |
| 645 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); | 650 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); |
| 646 } else { | 651 } else { |
| 647 llvm_unreachable("Unexpected operand type"); | 652 llvm_unreachable("Unexpected operand type"); |
| 648 } | 653 } |
| 649 } | 654 } |
| 650 | 655 |
| 651 template <bool VarCanBeByte, bool SrcCanBeByte> | 656 template <bool VarCanBeByte, bool SrcCanBeByte> |
| 652 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, | 657 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, |
| 653 const Operand *Src, | 658 const Operand *Src, |
| 654 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter) { | 659 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter) { |
| 655 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 660 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 656 assert(Var->hasReg()); | 661 assert(Var->hasReg()); |
| 657 // We cheat a little and use GPRRegister even for byte operations. | 662 // We cheat a little and use GPRRegister even for byte operations. |
| 658 RegX8632::GPRRegister VarReg = | 663 RegX8632::GPRRegister VarReg = |
| 659 VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()) | 664 VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()) |
| 660 : RegX8632::getEncodedGPR(Var->getRegNum()); | 665 : RegX8632::getEncodedGPR(Var->getRegNum()); |
| 661 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 666 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 662 if (SrcVar->hasReg()) { | 667 if (SrcVar->hasReg()) { |
| 663 RegX8632::GPRRegister SrcReg = | 668 RegX8632::GPRRegister SrcReg = |
| 664 SrcCanBeByte | 669 SrcCanBeByte |
| 665 ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()) | 670 ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()) |
| 666 : RegX8632::getEncodedGPR(SrcVar->getRegNum()); | 671 : RegX8632::getEncodedGPR(SrcVar->getRegNum()); |
| 667 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 672 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
| 668 } else { | 673 } else { |
| 669 X8632::Address SrcStackAddr = | 674 X8632::Traits::Address SrcStackAddr = |
| 670 static_cast<TargetX8632 *>(Func->getTarget()) | 675 static_cast<TargetX8632 *>(Func->getTarget()) |
| 671 ->stackVarToAsmOperand(SrcVar); | 676 ->stackVarToAsmOperand(SrcVar); |
| 672 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 677 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
| 673 } | 678 } |
| 674 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 679 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 675 Mem->emitSegmentOverride(Asm); | 680 Mem->emitSegmentOverride(Asm); |
| 676 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 681 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 677 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 682 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 678 (Asm->*(Emitter.GPRImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); | 683 (Asm->*(Emitter.GPRImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); |
| 679 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 684 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 680 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); | 685 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); |
| 681 (Asm->*(Emitter.GPRImm))(Ty, VarReg, | 686 (Asm->*(Emitter.GPRImm))(Ty, VarReg, |
| 682 X8632::Immediate(Reloc->getOffset(), Fixup)); | 687 X8632::Immediate(Reloc->getOffset(), Fixup)); |
| 683 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { | 688 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { |
| 684 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); | 689 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); |
| 685 } else { | 690 } else { |
| 686 llvm_unreachable("Unexpected operand type"); | 691 llvm_unreachable("Unexpected operand type"); |
| 687 } | 692 } |
| 688 } | 693 } |
| 689 | 694 |
| 690 void emitIASAddrOpTyGPR( | 695 void emitIASAddrOpTyGPR( |
| 691 const Cfg *Func, Type Ty, const X8632::Address &Addr, const Operand *Src, | 696 const Cfg *Func, Type Ty, const X8632::Traits::Address &Addr, |
| 697 const Operand *Src, |
| 692 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) { | 698 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) { |
| 693 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 699 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 694 // Src can only be Reg or Immediate. | 700 // Src can only be Reg or Immediate. |
| 695 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 701 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 696 assert(SrcVar->hasReg()); | 702 assert(SrcVar->hasReg()); |
| 697 RegX8632::GPRRegister SrcReg = | 703 RegX8632::GPRRegister SrcReg = |
| 698 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); | 704 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 699 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 705 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
| 700 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 706 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 701 (Asm->*(Emitter.AddrImm))(Ty, Addr, X8632::Immediate(Imm->getValue())); | 707 (Asm->*(Emitter.AddrImm))(Ty, Addr, X8632::Immediate(Imm->getValue())); |
| 702 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 708 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 703 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); | 709 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); |
| 704 (Asm->*(Emitter.AddrImm))(Ty, Addr, | 710 (Asm->*(Emitter.AddrImm))(Ty, Addr, |
| 705 X8632::Immediate(Reloc->getOffset(), Fixup)); | 711 X8632::Immediate(Reloc->getOffset(), Fixup)); |
| 706 } else { | 712 } else { |
| 707 llvm_unreachable("Unexpected operand type"); | 713 llvm_unreachable("Unexpected operand type"); |
| 708 } | 714 } |
| 709 } | 715 } |
| 710 | 716 |
| 711 void emitIASAsAddrOpTyGPR( | 717 void emitIASAsAddrOpTyGPR( |
| 712 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, | 718 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, |
| 713 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) { | 719 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) { |
| 714 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) { | 720 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) { |
| 715 assert(!Op0Var->hasReg()); | 721 assert(!Op0Var->hasReg()); |
| 716 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 722 X8632::Traits::Address StackAddr( |
| 717 ->stackVarToAsmOperand(Op0Var)); | 723 static_cast<TargetX8632 *>(Func->getTarget()) |
| 724 ->stackVarToAsmOperand(Op0Var)); |
| 718 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter); | 725 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter); |
| 719 } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) { | 726 } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) { |
| 720 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 727 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 721 Op0Mem->emitSegmentOverride(Asm); | 728 Op0Mem->emitSegmentOverride(Asm); |
| 722 emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter); | 729 emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter); |
| 723 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) { | 730 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) { |
| 724 emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter); | 731 emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter); |
| 725 } else { | 732 } else { |
| 726 llvm_unreachable("Unexpected operand type"); | 733 llvm_unreachable("Unexpected operand type"); |
| 727 } | 734 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter) { | 786 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter) { |
| 780 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 787 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 781 assert(Var->hasReg()); | 788 assert(Var->hasReg()); |
| 782 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 789 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 783 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 790 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 784 if (SrcVar->hasReg()) { | 791 if (SrcVar->hasReg()) { |
| 785 RegX8632::XmmRegister SrcReg = | 792 RegX8632::XmmRegister SrcReg = |
| 786 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 793 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 787 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 794 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 788 } else { | 795 } else { |
| 789 X8632::Address SrcStackAddr = | 796 X8632::Traits::Address SrcStackAddr = |
| 790 static_cast<TargetX8632 *>(Func->getTarget()) | 797 static_cast<TargetX8632 *>(Func->getTarget()) |
| 791 ->stackVarToAsmOperand(SrcVar); | 798 ->stackVarToAsmOperand(SrcVar); |
| 792 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 799 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 793 } | 800 } |
| 794 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 801 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 795 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 802 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 796 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 803 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 797 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 804 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 798 (Asm->*(Emitter.XmmImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); | 805 (Asm->*(Emitter.XmmImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); |
| 799 } else { | 806 } else { |
| 800 llvm_unreachable("Unexpected operand type"); | 807 llvm_unreachable("Unexpected operand type"); |
| 801 } | 808 } |
| 802 } | 809 } |
| 803 | 810 |
| 804 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | 811 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
| 805 const Operand *Src, | 812 const Operand *Src, |
| 806 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { | 813 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { |
| 807 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 814 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 808 assert(Var->hasReg()); | 815 assert(Var->hasReg()); |
| 809 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 816 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 810 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 817 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 811 if (SrcVar->hasReg()) { | 818 if (SrcVar->hasReg()) { |
| 812 RegX8632::XmmRegister SrcReg = | 819 RegX8632::XmmRegister SrcReg = |
| 813 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 820 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 814 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 821 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 815 } else { | 822 } else { |
| 816 X8632::Address SrcStackAddr = | 823 X8632::Traits::Address SrcStackAddr = |
| 817 static_cast<TargetX8632 *>(Func->getTarget()) | 824 static_cast<TargetX8632 *>(Func->getTarget()) |
| 818 ->stackVarToAsmOperand(SrcVar); | 825 ->stackVarToAsmOperand(SrcVar); |
| 819 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 826 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 820 } | 827 } |
| 821 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 828 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 822 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 829 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 823 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 830 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 824 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 831 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
| 825 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, | 832 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, |
| 826 X8632::Address::ofConstPool(Asm, Imm)); | 833 X8632::Traits::Address::ofConstPool(Asm, Imm)); |
| 827 } else { | 834 } else { |
| 828 llvm_unreachable("Unexpected operand type"); | 835 llvm_unreachable("Unexpected operand type"); |
| 829 } | 836 } |
| 830 } | 837 } |
| 831 | 838 |
| 832 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), | 839 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), |
| 833 SReg_t (*srcEnc)(int32_t)> | 840 SReg_t (*srcEnc)(int32_t)> |
| 834 void emitIASCastRegOp( | 841 void emitIASCastRegOp( |
| 835 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, | 842 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, |
| 836 const X8632::AssemblerX8632::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { | 843 const X8632::AssemblerX8632::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { |
| 837 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 844 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 838 assert(Dest->hasReg()); | 845 assert(Dest->hasReg()); |
| 839 DReg_t DestReg = destEnc(Dest->getRegNum()); | 846 DReg_t DestReg = destEnc(Dest->getRegNum()); |
| 840 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 847 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 841 if (SrcVar->hasReg()) { | 848 if (SrcVar->hasReg()) { |
| 842 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 849 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
| 843 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); | 850 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); |
| 844 } else { | 851 } else { |
| 845 X8632::Address SrcStackAddr = | 852 X8632::Traits::Address SrcStackAddr = |
| 846 static_cast<TargetX8632 *>(Func->getTarget()) | 853 static_cast<TargetX8632 *>(Func->getTarget()) |
| 847 ->stackVarToAsmOperand(SrcVar); | 854 ->stackVarToAsmOperand(SrcVar); |
| 848 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); | 855 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); |
| 849 } | 856 } |
| 850 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 857 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 851 Mem->emitSegmentOverride(Asm); | 858 Mem->emitSegmentOverride(Asm); |
| 852 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); | 859 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); |
| 853 } else { | 860 } else { |
| 854 llvm_unreachable("Unexpected operand type"); | 861 llvm_unreachable("Unexpected operand type"); |
| 855 } | 862 } |
| 856 } | 863 } |
| 857 | 864 |
| 858 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), | 865 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), |
| 859 SReg_t (*srcEnc)(int32_t)> | 866 SReg_t (*srcEnc)(int32_t)> |
| 860 void emitIASThreeOpImmOps( | 867 void emitIASThreeOpImmOps( |
| 861 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, | 868 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, |
| 862 const Operand *Src1, | 869 const Operand *Src1, |
| 863 const X8632::AssemblerX8632::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { | 870 const X8632::AssemblerX8632::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { |
| 864 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 871 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 865 // This only handles Dest being a register, and Src1 being an immediate. | 872 // This only handles Dest being a register, and Src1 being an immediate. |
| 866 assert(Dest->hasReg()); | 873 assert(Dest->hasReg()); |
| 867 DReg_t DestReg = destEnc(Dest->getRegNum()); | 874 DReg_t DestReg = destEnc(Dest->getRegNum()); |
| 868 X8632::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); | 875 X8632::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); |
| 869 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) { | 876 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) { |
| 870 if (SrcVar->hasReg()) { | 877 if (SrcVar->hasReg()) { |
| 871 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 878 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
| 872 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); | 879 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); |
| 873 } else { | 880 } else { |
| 874 X8632::Address SrcStackAddr = | 881 X8632::Traits::Address SrcStackAddr = |
| 875 static_cast<TargetX8632 *>(Func->getTarget()) | 882 static_cast<TargetX8632 *>(Func->getTarget()) |
| 876 ->stackVarToAsmOperand(SrcVar); | 883 ->stackVarToAsmOperand(SrcVar); |
| 877 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); | 884 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); |
| 878 } | 885 } |
| 879 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) { | 886 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 880 Mem->emitSegmentOverride(Asm); | 887 Mem->emitSegmentOverride(Asm); |
| 881 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), | 888 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), |
| 882 Imm); | 889 Imm); |
| 883 } else { | 890 } else { |
| 884 llvm_unreachable("Unexpected operand type"); | 891 llvm_unreachable("Unexpected operand type"); |
| 885 } | 892 } |
| 886 } | 893 } |
| 887 | 894 |
| 888 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, | 895 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
| 889 const Operand *Src, | 896 const Operand *Src, |
| 890 const X8632::AssemblerX8632::XmmEmitterMovOps Emitter) { | 897 const X8632::AssemblerX8632::XmmEmitterMovOps Emitter) { |
| 891 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 898 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 892 if (Dest->hasReg()) { | 899 if (Dest->hasReg()) { |
| 893 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); | 900 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
| 894 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 901 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 895 if (SrcVar->hasReg()) { | 902 if (SrcVar->hasReg()) { |
| 896 (Asm->*(Emitter.XmmXmm))(DestReg, | 903 (Asm->*(Emitter.XmmXmm))(DestReg, |
| 897 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 904 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 898 } else { | 905 } else { |
| 899 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 906 X8632::Traits::Address StackAddr( |
| 900 ->stackVarToAsmOperand(SrcVar)); | 907 static_cast<TargetX8632 *>(Func->getTarget()) |
| 908 ->stackVarToAsmOperand(SrcVar)); |
| 901 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); | 909 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); |
| 902 } | 910 } |
| 903 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 911 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 904 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 912 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 905 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); | 913 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); |
| 906 } else { | 914 } else { |
| 907 llvm_unreachable("Unexpected operand type"); | 915 llvm_unreachable("Unexpected operand type"); |
| 908 } | 916 } |
| 909 } else { | 917 } else { |
| 910 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 918 X8632::Traits::Address StackAddr( |
| 911 ->stackVarToAsmOperand(Dest)); | 919 static_cast<TargetX8632 *>(Func->getTarget()) |
| 920 ->stackVarToAsmOperand(Dest)); |
| 912 // Src must be a register in this case. | 921 // Src must be a register in this case. |
| 913 const auto SrcVar = llvm::cast<Variable>(Src); | 922 const auto SrcVar = llvm::cast<Variable>(Src); |
| 914 assert(SrcVar->hasReg()); | 923 assert(SrcVar->hasReg()); |
| 915 (Asm->*(Emitter.AddrXmm))(StackAddr, | 924 (Asm->*(Emitter.AddrXmm))(StackAddr, |
| 916 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 925 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 917 } | 926 } |
| 918 } | 927 } |
| 919 | 928 |
| 920 // In-place ops | 929 // In-place ops |
| 921 template <> const char *InstX8632Bswap::Opcode = "bswap"; | 930 template <> const char *InstX8632Bswap::Opcode = "bswap"; |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 | 1196 |
| 1188 template <> void InstX8632Pmull::emit(const Cfg *Func) const { | 1197 template <> void InstX8632Pmull::emit(const Cfg *Func) const { |
| 1189 if (!BuildDefs::dump()) | 1198 if (!BuildDefs::dump()) |
| 1190 return; | 1199 return; |
| 1191 char buf[30]; | 1200 char buf[30]; |
| 1192 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || | 1201 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || |
| 1193 getDest()->getType() == IceType_v8i16; | 1202 getDest()->getType() == IceType_v8i16; |
| 1194 bool InstructionSetIsValid = | 1203 bool InstructionSetIsValid = |
| 1195 getDest()->getType() == IceType_v8i16 || | 1204 getDest()->getType() == IceType_v8i16 || |
| 1196 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1205 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1197 TargetX8632::SSE4_1; | 1206 X8632::Traits::SSE4_1; |
| 1198 (void)TypesAreValid; | 1207 (void)TypesAreValid; |
| 1199 (void)InstructionSetIsValid; | 1208 (void)InstructionSetIsValid; |
| 1200 assert(TypesAreValid); | 1209 assert(TypesAreValid); |
| 1201 assert(InstructionSetIsValid); | 1210 assert(InstructionSetIsValid); |
| 1202 snprintf(buf, llvm::array_lengthof(buf), "pmull%s", | 1211 snprintf(buf, llvm::array_lengthof(buf), "pmull%s", |
| 1203 TypeX8632Attributes[getDest()->getType()].PackString); | 1212 TypeX8632Attributes[getDest()->getType()].PackString); |
| 1204 emitTwoAddress(buf, this, Func); | 1213 emitTwoAddress(buf, this, Func); |
| 1205 } | 1214 } |
| 1206 | 1215 |
| 1207 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const { | 1216 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const { |
| 1208 Type Ty = getDest()->getType(); | 1217 Type Ty = getDest()->getType(); |
| 1209 bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16; | 1218 bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16; |
| 1210 bool InstructionSetIsValid = | 1219 bool InstructionSetIsValid = |
| 1211 Ty == IceType_v8i16 || | 1220 Ty == IceType_v8i16 || |
| 1212 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1221 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1213 TargetX8632::SSE4_1; | 1222 X8632::Traits::SSE4_1; |
| 1214 (void)TypesAreValid; | 1223 (void)TypesAreValid; |
| 1215 (void)InstructionSetIsValid; | 1224 (void)InstructionSetIsValid; |
| 1216 assert(TypesAreValid); | 1225 assert(TypesAreValid); |
| 1217 assert(InstructionSetIsValid); | 1226 assert(InstructionSetIsValid); |
| 1218 assert(getSrcSize() == 2); | 1227 assert(getSrcSize() == 2); |
| 1219 Type ElementTy = typeElementType(Ty); | 1228 Type ElementTy = typeElementType(Ty); |
| 1220 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); | 1229 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); |
| 1221 } | 1230 } |
| 1222 | 1231 |
| 1223 template <> void InstX8632Subss::emit(const Cfg *Func) const { | 1232 template <> void InstX8632Subss::emit(const Cfg *Func) const { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 const Operand *Src = Inst->getSrc(1); | 1338 const Operand *Src = Inst->getSrc(1); |
| 1330 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); | 1339 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); |
| 1331 } | 1340 } |
| 1332 | 1341 |
| 1333 } // end anonymous namespace | 1342 } // end anonymous namespace |
| 1334 | 1343 |
| 1335 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { | 1344 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { |
| 1336 if (!BuildDefs::dump()) | 1345 if (!BuildDefs::dump()) |
| 1337 return; | 1346 return; |
| 1338 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1347 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1339 TargetX8632::SSE4_1); | 1348 X8632::Traits::SSE4_1); |
| 1340 emitVariableBlendInst(Opcode, this, Func); | 1349 emitVariableBlendInst(Opcode, this, Func); |
| 1341 } | 1350 } |
| 1342 | 1351 |
| 1343 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { | 1352 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { |
| 1344 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1353 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1345 TargetX8632::SSE4_1); | 1354 X8632::Traits::SSE4_1); |
| 1346 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1355 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1347 &X8632::AssemblerX8632::blendvps, &X8632::AssemblerX8632::blendvps}; | 1356 &X8632::AssemblerX8632::blendvps, &X8632::AssemblerX8632::blendvps}; |
| 1348 emitIASVariableBlendInst(this, Func, Emitter); | 1357 emitIASVariableBlendInst(this, Func, Emitter); |
| 1349 } | 1358 } |
| 1350 | 1359 |
| 1351 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { | 1360 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { |
| 1352 if (!BuildDefs::dump()) | 1361 if (!BuildDefs::dump()) |
| 1353 return; | 1362 return; |
| 1354 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1363 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1355 TargetX8632::SSE4_1); | 1364 X8632::Traits::SSE4_1); |
| 1356 emitVariableBlendInst(Opcode, this, Func); | 1365 emitVariableBlendInst(Opcode, this, Func); |
| 1357 } | 1366 } |
| 1358 | 1367 |
| 1359 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { | 1368 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { |
| 1360 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1369 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1361 TargetX8632::SSE4_1); | 1370 X8632::Traits::SSE4_1); |
| 1362 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1371 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
| 1363 &X8632::AssemblerX8632::pblendvb, &X8632::AssemblerX8632::pblendvb}; | 1372 &X8632::AssemblerX8632::pblendvb, &X8632::AssemblerX8632::pblendvb}; |
| 1364 emitIASVariableBlendInst(this, Func, Emitter); | 1373 emitIASVariableBlendInst(this, Func, Emitter); |
| 1365 } | 1374 } |
| 1366 | 1375 |
| 1367 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 1376 template <> void InstX8632Imul::emit(const Cfg *Func) const { |
| 1368 if (!BuildDefs::dump()) | 1377 if (!BuildDefs::dump()) |
| 1369 return; | 1378 return; |
| 1370 Ostream &Str = Func->getContext()->getStrEmit(); | 1379 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1371 assert(getSrcSize() == 2); | 1380 assert(getSrcSize() == 2); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 const X8632::AssemblerX8632::GPREmitterRegOp Emitter = { | 1418 const X8632::AssemblerX8632::GPREmitterRegOp Emitter = { |
| 1410 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul, | 1419 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul, |
| 1411 &X8632::AssemblerX8632::imul}; | 1420 &X8632::AssemblerX8632::imul}; |
| 1412 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); | 1421 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); |
| 1413 } | 1422 } |
| 1414 } | 1423 } |
| 1415 | 1424 |
| 1416 template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const { | 1425 template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const { |
| 1417 assert(getSrcSize() == 3); | 1426 assert(getSrcSize() == 3); |
| 1418 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1427 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 1419 TargetX8632::SSE4_1); | 1428 X8632::Traits::SSE4_1); |
| 1420 const Variable *Dest = getDest(); | 1429 const Variable *Dest = getDest(); |
| 1421 assert(Dest == getSrc(0)); | 1430 assert(Dest == getSrc(0)); |
| 1422 Type Ty = Dest->getType(); | 1431 Type Ty = Dest->getType(); |
| 1423 static const X8632::AssemblerX8632::ThreeOpImmEmitter< | 1432 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 1424 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 1433 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
| 1425 &X8632::AssemblerX8632::insertps, &X8632::AssemblerX8632::insertps}; | 1434 &X8632::AssemblerX8632::insertps, &X8632::AssemblerX8632::insertps}; |
| 1426 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 1435 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
| 1427 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 1436 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
| 1428 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 1437 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); |
| 1429 } | 1438 } |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1594 Str << " = shrd." << getDest()->getType() << " "; | 1603 Str << " = shrd." << getDest()->getType() << " "; |
| 1595 dumpSources(Func); | 1604 dumpSources(Func); |
| 1596 } | 1605 } |
| 1597 | 1606 |
| 1598 void InstX8632Cmov::emit(const Cfg *Func) const { | 1607 void InstX8632Cmov::emit(const Cfg *Func) const { |
| 1599 if (!BuildDefs::dump()) | 1608 if (!BuildDefs::dump()) |
| 1600 return; | 1609 return; |
| 1601 Ostream &Str = Func->getContext()->getStrEmit(); | 1610 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1602 Variable *Dest = getDest(); | 1611 Variable *Dest = getDest(); |
| 1603 Str << "\t"; | 1612 Str << "\t"; |
| 1604 assert(Condition != CondX86::Br_None); | 1613 assert(Condition != X8632::Traits::Cond::Br_None); |
| 1605 assert(getDest()->hasReg()); | 1614 assert(getDest()->hasReg()); |
| 1606 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString | 1615 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString |
| 1607 << getWidthString(Dest->getType()) << "\t"; | 1616 << getWidthString(Dest->getType()) << "\t"; |
| 1608 getSrc(1)->emit(Func); | 1617 getSrc(1)->emit(Func); |
| 1609 Str << ", "; | 1618 Str << ", "; |
| 1610 Dest->emit(Func); | 1619 Dest->emit(Func); |
| 1611 } | 1620 } |
| 1612 | 1621 |
| 1613 void InstX8632Cmov::emitIAS(const Cfg *Func) const { | 1622 void InstX8632Cmov::emitIAS(const Cfg *Func) const { |
| 1614 assert(Condition != CondX86::Br_None); | 1623 assert(Condition != X8632::Traits::Cond::Br_None); |
| 1615 assert(getDest()->hasReg()); | 1624 assert(getDest()->hasReg()); |
| 1616 assert(getSrcSize() == 2); | 1625 assert(getSrcSize() == 2); |
| 1617 Operand *Src = getSrc(1); | 1626 Operand *Src = getSrc(1); |
| 1618 Type SrcTy = Src->getType(); | 1627 Type SrcTy = Src->getType(); |
| 1619 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32); | 1628 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32); |
| 1620 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1629 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1621 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 1630 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 1622 if (SrcVar->hasReg()) { | 1631 if (SrcVar->hasReg()) { |
| 1623 Asm->cmov(SrcTy, Condition, | 1632 Asm->cmov(SrcTy, Condition, |
| 1624 RegX8632::getEncodedGPR(getDest()->getRegNum()), | 1633 RegX8632::getEncodedGPR(getDest()->getRegNum()), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1647 dumpDest(Func); | 1656 dumpDest(Func); |
| 1648 Str << ", "; | 1657 Str << ", "; |
| 1649 dumpSources(Func); | 1658 dumpSources(Func); |
| 1650 } | 1659 } |
| 1651 | 1660 |
| 1652 void InstX8632Cmpps::emit(const Cfg *Func) const { | 1661 void InstX8632Cmpps::emit(const Cfg *Func) const { |
| 1653 if (!BuildDefs::dump()) | 1662 if (!BuildDefs::dump()) |
| 1654 return; | 1663 return; |
| 1655 Ostream &Str = Func->getContext()->getStrEmit(); | 1664 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1656 assert(getSrcSize() == 2); | 1665 assert(getSrcSize() == 2); |
| 1657 assert(Condition < CondX86::Cmpps_Invalid); | 1666 assert(Condition < X8632::Traits::Cond::Cmpps_Invalid); |
| 1658 Str << "\t"; | 1667 Str << "\t"; |
| 1659 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1668 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
| 1660 << "\t"; | 1669 << "\t"; |
| 1661 getSrc(1)->emit(Func); | 1670 getSrc(1)->emit(Func); |
| 1662 Str << ", "; | 1671 Str << ", "; |
| 1663 getDest()->emit(Func); | 1672 getDest()->emit(Func); |
| 1664 } | 1673 } |
| 1665 | 1674 |
| 1666 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { | 1675 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { |
| 1667 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1676 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1668 assert(getSrcSize() == 2); | 1677 assert(getSrcSize() == 2); |
| 1669 assert(Condition < CondX86::Cmpps_Invalid); | 1678 assert(Condition < X8632::Traits::Cond::Cmpps_Invalid); |
| 1670 // Assuming there isn't any load folding for cmpps, and vector constants | 1679 // Assuming there isn't any load folding for cmpps, and vector constants |
| 1671 // are not allowed in PNaCl. | 1680 // are not allowed in PNaCl. |
| 1672 assert(llvm::isa<Variable>(getSrc(1))); | 1681 assert(llvm::isa<Variable>(getSrc(1))); |
| 1673 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); | 1682 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); |
| 1674 if (SrcVar->hasReg()) { | 1683 if (SrcVar->hasReg()) { |
| 1675 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), | 1684 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), |
| 1676 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); | 1685 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
| 1677 } else { | 1686 } else { |
| 1678 X8632::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 1687 X8632::Traits::Address SrcStackAddr = |
| 1679 ->stackVarToAsmOperand(SrcVar); | 1688 static_cast<TargetX8632 *>(Func->getTarget()) |
| 1689 ->stackVarToAsmOperand(SrcVar); |
| 1680 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, | 1690 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
| 1681 Condition); | 1691 Condition); |
| 1682 } | 1692 } |
| 1683 } | 1693 } |
| 1684 | 1694 |
| 1685 void InstX8632Cmpps::dump(const Cfg *Func) const { | 1695 void InstX8632Cmpps::dump(const Cfg *Func) const { |
| 1686 if (!BuildDefs::dump()) | 1696 if (!BuildDefs::dump()) |
| 1687 return; | 1697 return; |
| 1688 Ostream &Str = Func->getContext()->getStrDump(); | 1698 Ostream &Str = Func->getContext()->getStrDump(); |
| 1689 assert(Condition < CondX86::Cmpps_Invalid); | 1699 assert(Condition < X8632::Traits::Cond::Cmpps_Invalid); |
| 1690 dumpDest(Func); | 1700 dumpDest(Func); |
| 1691 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1701 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
| 1692 << "\t"; | 1702 << "\t"; |
| 1693 dumpSources(Func); | 1703 dumpSources(Func); |
| 1694 } | 1704 } |
| 1695 | 1705 |
| 1696 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 1706 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
| 1697 if (!BuildDefs::dump()) | 1707 if (!BuildDefs::dump()) |
| 1698 return; | 1708 return; |
| 1699 Ostream &Str = Func->getContext()->getStrEmit(); | 1709 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1700 assert(getSrcSize() == 3); | 1710 assert(getSrcSize() == 3); |
| 1701 if (Locked) { | 1711 if (Locked) { |
| 1702 Str << "\tlock"; | 1712 Str << "\tlock"; |
| 1703 } | 1713 } |
| 1704 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; | 1714 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; |
| 1705 getSrc(2)->emit(Func); | 1715 getSrc(2)->emit(Func); |
| 1706 Str << ", "; | 1716 Str << ", "; |
| 1707 getSrc(0)->emit(Func); | 1717 getSrc(0)->emit(Func); |
| 1708 } | 1718 } |
| 1709 | 1719 |
| 1710 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1720 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
| 1711 assert(getSrcSize() == 3); | 1721 assert(getSrcSize() == 3); |
| 1712 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1722 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1713 Type Ty = getSrc(0)->getType(); | 1723 Type Ty = getSrc(0)->getType(); |
| 1714 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1724 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1715 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1725 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1716 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 1726 const X8632::Traits::Address Addr = Mem->toAsmAddress(Asm); |
| 1717 const auto VarReg = llvm::cast<Variable>(getSrc(2)); | 1727 const auto VarReg = llvm::cast<Variable>(getSrc(2)); |
| 1718 assert(VarReg->hasReg()); | 1728 assert(VarReg->hasReg()); |
| 1719 const RegX8632::GPRRegister Reg = | 1729 const RegX8632::GPRRegister Reg = |
| 1720 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 1730 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 1721 Asm->cmpxchg(Ty, Addr, Reg, Locked); | 1731 Asm->cmpxchg(Ty, Addr, Reg, Locked); |
| 1722 } | 1732 } |
| 1723 | 1733 |
| 1724 void InstX8632Cmpxchg::dump(const Cfg *Func) const { | 1734 void InstX8632Cmpxchg::dump(const Cfg *Func) const { |
| 1725 if (!BuildDefs::dump()) | 1735 if (!BuildDefs::dump()) |
| 1726 return; | 1736 return; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1742 } | 1752 } |
| 1743 Str << "\tcmpxchg8b\t"; | 1753 Str << "\tcmpxchg8b\t"; |
| 1744 getSrc(0)->emit(Func); | 1754 getSrc(0)->emit(Func); |
| 1745 } | 1755 } |
| 1746 | 1756 |
| 1747 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1757 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
| 1748 assert(getSrcSize() == 5); | 1758 assert(getSrcSize() == 5); |
| 1749 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1759 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 1750 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1760 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1751 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1761 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 1752 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 1762 const X8632::Traits::Address Addr = Mem->toAsmAddress(Asm); |
| 1753 Asm->cmpxchg8b(Addr, Locked); | 1763 Asm->cmpxchg8b(Addr, Locked); |
| 1754 } | 1764 } |
| 1755 | 1765 |
| 1756 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1766 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
| 1757 if (!BuildDefs::dump()) | 1767 if (!BuildDefs::dump()) |
| 1758 return; | 1768 return; |
| 1759 Ostream &Str = Func->getContext()->getStrDump(); | 1769 Ostream &Str = Func->getContext()->getStrDump(); |
| 1760 if (Locked) { | 1770 if (Locked) { |
| 1761 Str << "lock "; | 1771 Str << "lock "; |
| 1762 } | 1772 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2020 const Operand *Src = getSrc(0); | 2030 const Operand *Src = getSrc(0); |
| 2021 Type DestTy = Dest->getType(); | 2031 Type DestTy = Dest->getType(); |
| 2022 if (isScalarFloatingType(DestTy)) { | 2032 if (isScalarFloatingType(DestTy)) { |
| 2023 // Src must be a register, since Dest is a Mem operand of some kind. | 2033 // Src must be a register, since Dest is a Mem operand of some kind. |
| 2024 const auto SrcVar = llvm::cast<Variable>(Src); | 2034 const auto SrcVar = llvm::cast<Variable>(Src); |
| 2025 assert(SrcVar->hasReg()); | 2035 assert(SrcVar->hasReg()); |
| 2026 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 2036 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 2027 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2037 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2028 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) { | 2038 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) { |
| 2029 assert(!DestVar->hasReg()); | 2039 assert(!DestVar->hasReg()); |
| 2030 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2040 X8632::Traits::Address StackAddr( |
| 2031 ->stackVarToAsmOperand(DestVar)); | 2041 static_cast<TargetX8632 *>(Func->getTarget()) |
| 2042 ->stackVarToAsmOperand(DestVar)); |
| 2032 Asm->movss(DestTy, StackAddr, SrcReg); | 2043 Asm->movss(DestTy, StackAddr, SrcReg); |
| 2033 } else { | 2044 } else { |
| 2034 const auto DestMem = llvm::cast<OperandX8632Mem>(Dest); | 2045 const auto DestMem = llvm::cast<OperandX8632Mem>(Dest); |
| 2035 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2046 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2036 Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg); | 2047 Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg); |
| 2037 } | 2048 } |
| 2038 return; | 2049 return; |
| 2039 } else { | 2050 } else { |
| 2040 assert(isScalarIntegerType(DestTy)); | 2051 assert(isScalarIntegerType(DestTy)); |
| 2041 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { | 2052 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2210 // when both Src and Dest are integer types. | 2221 // when both Src and Dest are integer types. |
| 2211 if (isScalarIntegerType(SrcTy)) { | 2222 if (isScalarIntegerType(SrcTy)) { |
| 2212 DestTy = SrcTy; | 2223 DestTy = SrcTy; |
| 2213 } | 2224 } |
| 2214 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); | 2225 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); |
| 2215 return; | 2226 return; |
| 2216 } | 2227 } |
| 2217 } else { | 2228 } else { |
| 2218 // Dest must be Stack and Src *could* be a register. Use Src's type | 2229 // Dest must be Stack and Src *could* be a register. Use Src's type |
| 2219 // to decide on the emitters. | 2230 // to decide on the emitters. |
| 2220 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2231 X8632::Traits::Address StackAddr( |
| 2221 ->stackVarToAsmOperand(Dest)); | 2232 static_cast<TargetX8632 *>(Func->getTarget()) |
| 2233 ->stackVarToAsmOperand(Dest)); |
| 2222 if (isScalarFloatingType(SrcTy)) { | 2234 if (isScalarFloatingType(SrcTy)) { |
| 2223 // Src must be a register. | 2235 // Src must be a register. |
| 2224 const auto SrcVar = llvm::cast<Variable>(Src); | 2236 const auto SrcVar = llvm::cast<Variable>(Src); |
| 2225 assert(SrcVar->hasReg()); | 2237 assert(SrcVar->hasReg()); |
| 2226 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2238 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2227 Asm->movss(SrcTy, StackAddr, | 2239 Asm->movss(SrcTy, StackAddr, |
| 2228 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2240 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 2229 return; | 2241 return; |
| 2230 } else { | 2242 } else { |
| 2231 // Src can be a register or immediate. | 2243 // Src can be a register or immediate. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2244 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2256 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
| 2245 // For insert/extract element (one of Src/Dest is an Xmm vector and | 2257 // For insert/extract element (one of Src/Dest is an Xmm vector and |
| 2246 // the other is an int type). | 2258 // the other is an int type). |
| 2247 if (SrcVar->getType() == IceType_i32) { | 2259 if (SrcVar->getType() == IceType_i32) { |
| 2248 assert(isVectorType(Dest->getType())); | 2260 assert(isVectorType(Dest->getType())); |
| 2249 assert(Dest->hasReg()); | 2261 assert(Dest->hasReg()); |
| 2250 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); | 2262 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
| 2251 if (SrcVar->hasReg()) { | 2263 if (SrcVar->hasReg()) { |
| 2252 Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum())); | 2264 Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum())); |
| 2253 } else { | 2265 } else { |
| 2254 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2266 X8632::Traits::Address StackAddr( |
| 2255 ->stackVarToAsmOperand(SrcVar)); | 2267 static_cast<TargetX8632 *>(Func->getTarget()) |
| 2268 ->stackVarToAsmOperand(SrcVar)); |
| 2256 Asm->movd(DestReg, StackAddr); | 2269 Asm->movd(DestReg, StackAddr); |
| 2257 } | 2270 } |
| 2258 } else { | 2271 } else { |
| 2259 assert(isVectorType(SrcVar->getType())); | 2272 assert(isVectorType(SrcVar->getType())); |
| 2260 assert(SrcVar->hasReg()); | 2273 assert(SrcVar->hasReg()); |
| 2261 assert(Dest->getType() == IceType_i32); | 2274 assert(Dest->getType() == IceType_i32); |
| 2262 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 2275 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 2263 if (Dest->hasReg()) { | 2276 if (Dest->hasReg()) { |
| 2264 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); | 2277 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); |
| 2265 } else { | 2278 } else { |
| 2266 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2279 X8632::Traits::Address StackAddr( |
| 2267 ->stackVarToAsmOperand(Dest)); | 2280 static_cast<TargetX8632 *>(Func->getTarget()) |
| 2281 ->stackVarToAsmOperand(Dest)); |
| 2268 Asm->movd(StackAddr, SrcReg); | 2282 Asm->movd(StackAddr, SrcReg); |
| 2269 } | 2283 } |
| 2270 } | 2284 } |
| 2271 } | 2285 } |
| 2272 | 2286 |
| 2273 template <> void InstX8632Movp::emit(const Cfg *Func) const { | 2287 template <> void InstX8632Movp::emit(const Cfg *Func) const { |
| 2274 if (!BuildDefs::dump()) | 2288 if (!BuildDefs::dump()) |
| 2275 return; | 2289 return; |
| 2276 // TODO(wala,stichnot): movups works with all vector operands, but | 2290 // TODO(wala,stichnot): movups works with all vector operands, but |
| 2277 // there exist other instructions (movaps, movdqa, movdqu) that may | 2291 // there exist other instructions (movaps, movdqa, movdqu) that may |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2407 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2421 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2408 assert(getSrcSize() == 1); | 2422 assert(getSrcSize() == 1); |
| 2409 const Operand *Src = getSrc(0); | 2423 const Operand *Src = getSrc(0); |
| 2410 Type Ty = Src->getType(); | 2424 Type Ty = Src->getType(); |
| 2411 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { | 2425 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { |
| 2412 if (Var->hasReg()) { | 2426 if (Var->hasReg()) { |
| 2413 // This is a physical xmm register, so we need to spill it to a | 2427 // This is a physical xmm register, so we need to spill it to a |
| 2414 // temporary stack slot. | 2428 // temporary stack slot. |
| 2415 X8632::Immediate Width(typeWidthInBytes(Ty)); | 2429 X8632::Immediate Width(typeWidthInBytes(Ty)); |
| 2416 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2430 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2417 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); | 2431 X8632::Traits::Address StackSlot = |
| 2432 X8632::Traits::Address(RegX8632::Encoded_Reg_esp, 0); |
| 2418 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); | 2433 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); |
| 2419 Asm->fld(Ty, StackSlot); | 2434 Asm->fld(Ty, StackSlot); |
| 2420 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2435 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2421 } else { | 2436 } else { |
| 2422 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2437 X8632::Traits::Address StackAddr( |
| 2423 ->stackVarToAsmOperand(Var)); | 2438 static_cast<TargetX8632 *>(Func->getTarget()) |
| 2439 ->stackVarToAsmOperand(Var)); |
| 2424 Asm->fld(Ty, StackAddr); | 2440 Asm->fld(Ty, StackAddr); |
| 2425 } | 2441 } |
| 2426 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 2442 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 2427 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2443 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2428 Asm->fld(Ty, Mem->toAsmAddress(Asm)); | 2444 Asm->fld(Ty, Mem->toAsmAddress(Asm)); |
| 2429 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 2445 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
| 2430 Asm->fld(Ty, X8632::Address::ofConstPool(Asm, Imm)); | 2446 Asm->fld(Ty, X8632::Traits::Address::ofConstPool(Asm, Imm)); |
| 2431 } else { | 2447 } else { |
| 2432 llvm_unreachable("Unexpected operand type"); | 2448 llvm_unreachable("Unexpected operand type"); |
| 2433 } | 2449 } |
| 2434 } | 2450 } |
| 2435 | 2451 |
| 2436 void InstX8632Fld::dump(const Cfg *Func) const { | 2452 void InstX8632Fld::dump(const Cfg *Func) const { |
| 2437 if (!BuildDefs::dump()) | 2453 if (!BuildDefs::dump()) |
| 2438 return; | 2454 return; |
| 2439 Ostream &Str = Func->getContext()->getStrDump(); | 2455 Ostream &Str = Func->getContext()->getStrDump(); |
| 2440 Str << "fld." << getSrc(0)->getType() << " "; | 2456 Str << "fld." << getSrc(0)->getType() << " "; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2482 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to | 2498 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
| 2483 // "partially" delete the fstp if the Dest is unused. | 2499 // "partially" delete the fstp if the Dest is unused. |
| 2484 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2500 // Even if Dest is unused, the fstp should be kept for the SideEffects |
| 2485 // of popping the stack. | 2501 // of popping the stack. |
| 2486 if (!Dest) { | 2502 if (!Dest) { |
| 2487 Asm->fstp(RegX8632::getEncodedSTReg(0)); | 2503 Asm->fstp(RegX8632::getEncodedSTReg(0)); |
| 2488 return; | 2504 return; |
| 2489 } | 2505 } |
| 2490 Type Ty = Dest->getType(); | 2506 Type Ty = Dest->getType(); |
| 2491 if (!Dest->hasReg()) { | 2507 if (!Dest->hasReg()) { |
| 2492 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2508 X8632::Traits::Address StackAddr( |
| 2493 ->stackVarToAsmOperand(Dest)); | 2509 static_cast<TargetX8632 *>(Func->getTarget()) |
| 2510 ->stackVarToAsmOperand(Dest)); |
| 2494 Asm->fstp(Ty, StackAddr); | 2511 Asm->fstp(Ty, StackAddr); |
| 2495 } else { | 2512 } else { |
| 2496 // Dest is a physical (xmm) register, so st(0) needs to go through | 2513 // Dest is a physical (xmm) register, so st(0) needs to go through |
| 2497 // memory. Hack this by creating a temporary stack slot, spilling | 2514 // memory. Hack this by creating a temporary stack slot, spilling |
| 2498 // st(0) there, loading it into the xmm register, and deallocating | 2515 // st(0) there, loading it into the xmm register, and deallocating |
| 2499 // the stack slot. | 2516 // the stack slot. |
| 2500 X8632::Immediate Width(typeWidthInBytes(Ty)); | 2517 X8632::Immediate Width(typeWidthInBytes(Ty)); |
| 2501 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2518 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2502 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); | 2519 X8632::Traits::Address StackSlot = |
| 2520 X8632::Traits::Address(RegX8632::Encoded_Reg_esp, 0); |
| 2503 Asm->fstp(Ty, StackSlot); | 2521 Asm->fstp(Ty, StackSlot); |
| 2504 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); | 2522 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); |
| 2505 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2523 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
| 2506 } | 2524 } |
| 2507 } | 2525 } |
| 2508 | 2526 |
| 2509 void InstX8632Fstp::dump(const Cfg *Func) const { | 2527 void InstX8632Fstp::dump(const Cfg *Func) const { |
| 2510 if (!BuildDefs::dump()) | 2528 if (!BuildDefs::dump()) |
| 2511 return; | 2529 return; |
| 2512 Ostream &Str = Func->getContext()->getStrDump(); | 2530 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2534 | 2552 |
| 2535 template <> void InstX8632Pextr::emit(const Cfg *Func) const { | 2553 template <> void InstX8632Pextr::emit(const Cfg *Func) const { |
| 2536 if (!BuildDefs::dump()) | 2554 if (!BuildDefs::dump()) |
| 2537 return; | 2555 return; |
| 2538 Ostream &Str = Func->getContext()->getStrEmit(); | 2556 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2539 assert(getSrcSize() == 2); | 2557 assert(getSrcSize() == 2); |
| 2540 // pextrb and pextrd are SSE4.1 instructions. | 2558 // pextrb and pextrd are SSE4.1 instructions. |
| 2541 assert(getSrc(0)->getType() == IceType_v8i16 || | 2559 assert(getSrc(0)->getType() == IceType_v8i16 || |
| 2542 getSrc(0)->getType() == IceType_v8i1 || | 2560 getSrc(0)->getType() == IceType_v8i1 || |
| 2543 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2561 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 2544 TargetX8632::SSE4_1); | 2562 X8632::Traits::SSE4_1); |
| 2545 Str << "\t" << Opcode << TypeX8632Attributes[getSrc(0)->getType()].PackString | 2563 Str << "\t" << Opcode << TypeX8632Attributes[getSrc(0)->getType()].PackString |
| 2546 << "\t"; | 2564 << "\t"; |
| 2547 getSrc(1)->emit(Func); | 2565 getSrc(1)->emit(Func); |
| 2548 Str << ", "; | 2566 Str << ", "; |
| 2549 getSrc(0)->emit(Func); | 2567 getSrc(0)->emit(Func); |
| 2550 Str << ", "; | 2568 Str << ", "; |
| 2551 Variable *Dest = getDest(); | 2569 Variable *Dest = getDest(); |
| 2552 // pextrw must take a register dest. There is an SSE4.1 version that takes | 2570 // pextrw must take a register dest. There is an SSE4.1 version that takes |
| 2553 // a memory dest, but we aren't using it. For uniformity, just restrict | 2571 // a memory dest, but we aren't using it. For uniformity, just restrict |
| 2554 // them all to have a register dest for now. | 2572 // them all to have a register dest for now. |
| 2555 assert(Dest->hasReg()); | 2573 assert(Dest->hasReg()); |
| 2556 Dest->asType(IceType_i32)->emit(Func); | 2574 Dest->asType(IceType_i32)->emit(Func); |
| 2557 } | 2575 } |
| 2558 | 2576 |
| 2559 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const { | 2577 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const { |
| 2560 assert(getSrcSize() == 2); | 2578 assert(getSrcSize() == 2); |
| 2561 // pextrb and pextrd are SSE4.1 instructions. | 2579 // pextrb and pextrd are SSE4.1 instructions. |
| 2562 const Variable *Dest = getDest(); | 2580 const Variable *Dest = getDest(); |
| 2563 Type DispatchTy = Dest->getType(); | 2581 Type DispatchTy = Dest->getType(); |
| 2564 assert(DispatchTy == IceType_i16 || | 2582 assert(DispatchTy == IceType_i16 || |
| 2565 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2583 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 2566 TargetX8632::SSE4_1); | 2584 X8632::Traits::SSE4_1); |
| 2567 // pextrw must take a register dest. There is an SSE4.1 version that takes | 2585 // pextrw must take a register dest. There is an SSE4.1 version that takes |
| 2568 // a memory dest, but we aren't using it. For uniformity, just restrict | 2586 // a memory dest, but we aren't using it. For uniformity, just restrict |
| 2569 // them all to have a register dest for now. | 2587 // them all to have a register dest for now. |
| 2570 assert(Dest->hasReg()); | 2588 assert(Dest->hasReg()); |
| 2571 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). | 2589 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). |
| 2572 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); | 2590 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); |
| 2573 static const X8632::AssemblerX8632::ThreeOpImmEmitter< | 2591 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 2574 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { | 2592 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { |
| 2575 &X8632::AssemblerX8632::pextr, nullptr}; | 2593 &X8632::AssemblerX8632::pextr, nullptr}; |
| 2576 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, | 2594 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, |
| 2577 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( | 2595 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( |
| 2578 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); | 2596 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); |
| 2579 } | 2597 } |
| 2580 | 2598 |
| 2581 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { | 2599 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { |
| 2582 if (!BuildDefs::dump()) | 2600 if (!BuildDefs::dump()) |
| 2583 return; | 2601 return; |
| 2584 Ostream &Str = Func->getContext()->getStrEmit(); | 2602 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2585 assert(getSrcSize() == 3); | 2603 assert(getSrcSize() == 3); |
| 2586 // pinsrb and pinsrd are SSE4.1 instructions. | 2604 // pinsrb and pinsrd are SSE4.1 instructions. |
| 2587 assert(getDest()->getType() == IceType_v8i16 || | 2605 assert(getDest()->getType() == IceType_v8i16 || |
| 2588 getDest()->getType() == IceType_v8i1 || | 2606 getDest()->getType() == IceType_v8i1 || |
| 2589 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2607 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 2590 TargetX8632::SSE4_1); | 2608 X8632::Traits::SSE4_1); |
| 2591 Str << "\t" << Opcode << TypeX8632Attributes[getDest()->getType()].PackString | 2609 Str << "\t" << Opcode << TypeX8632Attributes[getDest()->getType()].PackString |
| 2592 << "\t"; | 2610 << "\t"; |
| 2593 getSrc(2)->emit(Func); | 2611 getSrc(2)->emit(Func); |
| 2594 Str << ", "; | 2612 Str << ", "; |
| 2595 Operand *Src1 = getSrc(1); | 2613 Operand *Src1 = getSrc(1); |
| 2596 if (const auto Src1Var = llvm::dyn_cast<Variable>(Src1)) { | 2614 if (const auto Src1Var = llvm::dyn_cast<Variable>(Src1)) { |
| 2597 // If src1 is a register, it should always be r32. | 2615 // If src1 is a register, it should always be r32. |
| 2598 if (Src1Var->hasReg()) { | 2616 if (Src1Var->hasReg()) { |
| 2599 Src1Var->asType(IceType_i32)->emit(Func); | 2617 Src1Var->asType(IceType_i32)->emit(Func); |
| 2600 } else { | 2618 } else { |
| 2601 Src1Var->emit(Func); | 2619 Src1Var->emit(Func); |
| 2602 } | 2620 } |
| 2603 } else { | 2621 } else { |
| 2604 Src1->emit(Func); | 2622 Src1->emit(Func); |
| 2605 } | 2623 } |
| 2606 Str << ", "; | 2624 Str << ", "; |
| 2607 getDest()->emit(Func); | 2625 getDest()->emit(Func); |
| 2608 } | 2626 } |
| 2609 | 2627 |
| 2610 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { | 2628 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { |
| 2611 assert(getSrcSize() == 3); | 2629 assert(getSrcSize() == 3); |
| 2612 assert(getDest() == getSrc(0)); | 2630 assert(getDest() == getSrc(0)); |
| 2613 // pinsrb and pinsrd are SSE4.1 instructions. | 2631 // pinsrb and pinsrd are SSE4.1 instructions. |
| 2614 const Operand *Src0 = getSrc(1); | 2632 const Operand *Src0 = getSrc(1); |
| 2615 Type DispatchTy = Src0->getType(); | 2633 Type DispatchTy = Src0->getType(); |
| 2616 assert(DispatchTy == IceType_i16 || | 2634 assert(DispatchTy == IceType_i16 || |
| 2617 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2635 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 2618 TargetX8632::SSE4_1); | 2636 X8632::Traits::SSE4_1); |
| 2619 // If src1 is a register, it should always be r32 (this should fall out | 2637 // If src1 is a register, it should always be r32 (this should fall out |
| 2620 // from the encodings for ByteRegs overlapping the encodings for r32), | 2638 // from the encodings for ByteRegs overlapping the encodings for r32), |
| 2621 // but we have to trust the regalloc to not choose "ah", where it | 2639 // but we have to trust the regalloc to not choose "ah", where it |
| 2622 // doesn't overlap. | 2640 // doesn't overlap. |
| 2623 static const X8632::AssemblerX8632::ThreeOpImmEmitter< | 2641 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
| 2624 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { | 2642 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { |
| 2625 &X8632::AssemblerX8632::pinsr, &X8632::AssemblerX8632::pinsr}; | 2643 &X8632::AssemblerX8632::pinsr, &X8632::AssemblerX8632::pinsr}; |
| 2626 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::GPRRegister, | 2644 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::GPRRegister, |
| 2627 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( | 2645 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( |
| 2628 Func, DispatchTy, getDest(), Src0, getSrc(2), Emitter); | 2646 Func, DispatchTy, getDest(), Src0, getSrc(2), Emitter); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2789 | 2807 |
| 2790 void InstX8632Setcc::emit(const Cfg *Func) const { | 2808 void InstX8632Setcc::emit(const Cfg *Func) const { |
| 2791 if (!BuildDefs::dump()) | 2809 if (!BuildDefs::dump()) |
| 2792 return; | 2810 return; |
| 2793 Ostream &Str = Func->getContext()->getStrEmit(); | 2811 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2794 Str << "\tset" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 2812 Str << "\tset" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
| 2795 Dest->emit(Func); | 2813 Dest->emit(Func); |
| 2796 } | 2814 } |
| 2797 | 2815 |
| 2798 void InstX8632Setcc::emitIAS(const Cfg *Func) const { | 2816 void InstX8632Setcc::emitIAS(const Cfg *Func) const { |
| 2799 assert(Condition != CondX86::Br_None); | 2817 assert(Condition != X8632::Traits::Cond::Br_None); |
| 2800 assert(getDest()->getType() == IceType_i1); | 2818 assert(getDest()->getType() == IceType_i1); |
| 2801 assert(getSrcSize() == 0); | 2819 assert(getSrcSize() == 0); |
| 2802 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2820 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2803 if (getDest()->hasReg()) | 2821 if (getDest()->hasReg()) |
| 2804 Asm->setcc(Condition, RegX8632::getEncodedByteReg(getDest()->getRegNum())); | 2822 Asm->setcc(Condition, RegX8632::getEncodedByteReg(getDest()->getRegNum())); |
| 2805 else | 2823 else |
| 2806 Asm->setcc(Condition, static_cast<TargetX8632 *>(Func->getTarget()) | 2824 Asm->setcc(Condition, static_cast<TargetX8632 *>(Func->getTarget()) |
| 2807 ->stackVarToAsmOperand(getDest())); | 2825 ->stackVarToAsmOperand(getDest())); |
| 2808 return; | 2826 return; |
| 2809 } | 2827 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2828 Str << ", "; | 2846 Str << ", "; |
| 2829 getSrc(0)->emit(Func); | 2847 getSrc(0)->emit(Func); |
| 2830 } | 2848 } |
| 2831 | 2849 |
| 2832 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 2850 void InstX8632Xadd::emitIAS(const Cfg *Func) const { |
| 2833 assert(getSrcSize() == 2); | 2851 assert(getSrcSize() == 2); |
| 2834 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2852 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2835 Type Ty = getSrc(0)->getType(); | 2853 Type Ty = getSrc(0)->getType(); |
| 2836 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2854 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2837 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2855 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2838 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 2856 const X8632::Traits::Address Addr = Mem->toAsmAddress(Asm); |
| 2839 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2857 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2840 assert(VarReg->hasReg()); | 2858 assert(VarReg->hasReg()); |
| 2841 const RegX8632::GPRRegister Reg = | 2859 const RegX8632::GPRRegister Reg = |
| 2842 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2860 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2843 Asm->xadd(Ty, Addr, Reg, Locked); | 2861 Asm->xadd(Ty, Addr, Reg, Locked); |
| 2844 } | 2862 } |
| 2845 | 2863 |
| 2846 void InstX8632Xadd::dump(const Cfg *Func) const { | 2864 void InstX8632Xadd::dump(const Cfg *Func) const { |
| 2847 if (!BuildDefs::dump()) | 2865 if (!BuildDefs::dump()) |
| 2848 return; | 2866 return; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2864 Str << ", "; | 2882 Str << ", "; |
| 2865 getSrc(0)->emit(Func); | 2883 getSrc(0)->emit(Func); |
| 2866 } | 2884 } |
| 2867 | 2885 |
| 2868 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 2886 void InstX8632Xchg::emitIAS(const Cfg *Func) const { |
| 2869 assert(getSrcSize() == 2); | 2887 assert(getSrcSize() == 2); |
| 2870 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2888 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
| 2871 Type Ty = getSrc(0)->getType(); | 2889 Type Ty = getSrc(0)->getType(); |
| 2872 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2890 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2873 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2891 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 2874 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 2892 const X8632::Traits::Address Addr = Mem->toAsmAddress(Asm); |
| 2875 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2893 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
| 2876 assert(VarReg->hasReg()); | 2894 assert(VarReg->hasReg()); |
| 2877 const RegX8632::GPRRegister Reg = | 2895 const RegX8632::GPRRegister Reg = |
| 2878 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2896 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
| 2879 Asm->xchg(Ty, Addr, Reg); | 2897 Asm->xchg(Ty, Addr, Reg); |
| 2880 } | 2898 } |
| 2881 | 2899 |
| 2882 void InstX8632Xchg::dump(const Cfg *Func) const { | 2900 void InstX8632Xchg::dump(const Cfg *Func) const { |
| 2883 if (!BuildDefs::dump()) | 2901 if (!BuildDefs::dump()) |
| 2884 return; | 2902 return; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2975 Str << "]"; | 2993 Str << "]"; |
| 2976 } | 2994 } |
| 2977 | 2995 |
| 2978 void OperandX8632Mem::emitSegmentOverride(X8632::AssemblerX8632 *Asm) const { | 2996 void OperandX8632Mem::emitSegmentOverride(X8632::AssemblerX8632 *Asm) const { |
| 2979 if (SegmentReg != DefaultSegment) { | 2997 if (SegmentReg != DefaultSegment) { |
| 2980 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 2998 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
| 2981 Asm->emitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); | 2999 Asm->emitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); |
| 2982 } | 3000 } |
| 2983 } | 3001 } |
| 2984 | 3002 |
| 2985 X8632::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { | 3003 X8632::Traits::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { |
| 2986 int32_t Disp = 0; | 3004 int32_t Disp = 0; |
| 2987 AssemblerFixup *Fixup = nullptr; | 3005 AssemblerFixup *Fixup = nullptr; |
| 2988 // Determine the offset (is it relocatable?) | 3006 // Determine the offset (is it relocatable?) |
| 2989 if (getOffset()) { | 3007 if (getOffset()) { |
| 2990 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 3008 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
| 2991 Disp = static_cast<int32_t>(CI->getValue()); | 3009 Disp = static_cast<int32_t>(CI->getValue()); |
| 2992 } else if (const auto CR = | 3010 } else if (const auto CR = |
| 2993 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 3011 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
| 2994 Disp = CR->getOffset(); | 3012 Disp = CR->getOffset(); |
| 2995 Fixup = Asm->createFixup(llvm::ELF::R_386_32, CR); | 3013 Fixup = Asm->createFixup(llvm::ELF::R_386_32, CR); |
| 2996 } else { | 3014 } else { |
| 2997 llvm_unreachable("Unexpected offset type"); | 3015 llvm_unreachable("Unexpected offset type"); |
| 2998 } | 3016 } |
| 2999 } | 3017 } |
| 3000 | 3018 |
| 3001 // Now convert to the various possible forms. | 3019 // Now convert to the various possible forms. |
| 3002 if (getBase() && getIndex()) { | 3020 if (getBase() && getIndex()) { |
| 3003 return X8632::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), | 3021 return X8632::Traits::Address( |
| 3004 RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 3022 RegX8632::getEncodedGPR(getBase()->getRegNum()), |
| 3005 X8632::ScaleFactor(getShift()), Disp); | 3023 RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 3024 X8632::Traits::ScaleFactor(getShift()), Disp); |
| 3006 } else if (getBase()) { | 3025 } else if (getBase()) { |
| 3007 return X8632::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), | 3026 return X8632::Traits::Address( |
| 3008 Disp); | 3027 RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); |
| 3009 } else if (getIndex()) { | 3028 } else if (getIndex()) { |
| 3010 return X8632::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 3029 return X8632::Traits::Address( |
| 3011 X8632::ScaleFactor(getShift()), Disp); | 3030 RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
| 3031 X8632::Traits::ScaleFactor(getShift()), Disp); |
| 3012 } else if (Fixup) { | 3032 } else if (Fixup) { |
| 3013 return X8632::Address::Absolute(Disp, Fixup); | 3033 return X8632::Traits::Address::Absolute(Disp, Fixup); |
| 3014 } else { | 3034 } else { |
| 3015 return X8632::Address::Absolute(Disp); | 3035 return X8632::Traits::Address::Absolute(Disp); |
| 3016 } | 3036 } |
| 3017 } | 3037 } |
| 3018 | 3038 |
| 3019 X8632::Address VariableSplit::toAsmAddress(const Cfg *Func) const { | 3039 X8632::Traits::Address VariableSplit::toAsmAddress(const Cfg *Func) const { |
| 3020 assert(!Var->hasReg()); | 3040 assert(!Var->hasReg()); |
| 3021 const TargetLowering *Target = Func->getTarget(); | 3041 const TargetLowering *Target = Func->getTarget(); |
| 3022 int32_t Offset = | 3042 int32_t Offset = |
| 3023 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 3043 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
| 3024 return X8632::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), | 3044 return X8632::Traits::Address( |
| 3025 Offset); | 3045 RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), Offset); |
| 3026 } | 3046 } |
| 3027 | 3047 |
| 3028 void VariableSplit::emit(const Cfg *Func) const { | 3048 void VariableSplit::emit(const Cfg *Func) const { |
| 3029 if (!BuildDefs::dump()) | 3049 if (!BuildDefs::dump()) |
| 3030 return; | 3050 return; |
| 3031 Ostream &Str = Func->getContext()->getStrEmit(); | 3051 Ostream &Str = Func->getContext()->getStrEmit(); |
| 3032 assert(!Var->hasReg()); | 3052 assert(!Var->hasReg()); |
| 3033 // The following is copied/adapted from TargetX8632::emitVariable(). | 3053 // The following is copied/adapted from TargetX8632::emitVariable(). |
| 3034 const TargetLowering *Target = Func->getTarget(); | 3054 const TargetLowering *Target = Func->getTarget(); |
| 3035 const Type Ty = IceType_i32; | 3055 const Type Ty = IceType_i32; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3053 } | 3073 } |
| 3054 Str << "("; | 3074 Str << "("; |
| 3055 if (Func) | 3075 if (Func) |
| 3056 Var->dump(Func); | 3076 Var->dump(Func); |
| 3057 else | 3077 else |
| 3058 Var->dump(Str); | 3078 Var->dump(Str); |
| 3059 Str << ")"; | 3079 Str << ")"; |
| 3060 } | 3080 } |
| 3061 | 3081 |
| 3062 } // end of namespace Ice | 3082 } // end of namespace Ice |
| OLD | NEW |