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, |
11 // primarily the constructors and the dump()/emit() methods. | 11 // primarily the constructors and the dump()/emit() methods. |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #include "IceCfg.h" | 15 #include "IceCfg.h" |
16 #include "IceCfgNode.h" | 16 #include "IceCfgNode.h" |
| 17 #include "IceConditionCodesX8632.h" |
17 #include "IceInst.h" | 18 #include "IceInst.h" |
18 #include "IceInstX8632.h" | 19 #include "IceInstX8632.h" |
| 20 #include "IceRegistersX8632.h" |
19 #include "IceTargetLoweringX8632.h" | 21 #include "IceTargetLoweringX8632.h" |
20 #include "IceOperand.h" | 22 #include "IceOperand.h" |
21 | 23 |
22 namespace Ice { | 24 namespace Ice { |
23 | 25 |
24 namespace { | 26 namespace { |
25 | 27 |
26 const struct InstX8632BrAttributes_ { | 28 const struct InstX8632BrAttributes_ { |
27 InstX8632::BrCond Opposite; | 29 CondX86::BrCond Opposite; |
28 const char *DisplayString; | 30 const char *DisplayString; |
29 const char *EmitString; | 31 const char *EmitString; |
30 } InstX8632BrAttributes[] = { | 32 } InstX8632BrAttributes[] = { |
31 #define X(tag, opp, dump, emit) \ | 33 #define X(tag, encode, opp, dump, emit) \ |
32 { InstX8632::opp, dump, emit } \ | 34 { CondX86::opp, dump, emit } \ |
33 , | 35 , |
34 ICEINSTX8632BR_TABLE | 36 ICEINSTX8632BR_TABLE |
35 #undef X | 37 #undef X |
36 }; | 38 }; |
37 | 39 |
38 const struct InstX8632CmppsAttributes_ { | 40 const struct InstX8632CmppsAttributes_ { |
39 const char *EmitString; | 41 const char *EmitString; |
40 } InstX8632CmppsAttributes[] = { | 42 } InstX8632CmppsAttributes[] = { |
41 #define X(tag, emit) \ | 43 #define X(tag, emit) \ |
42 { emit } \ | 44 { emit } \ |
(...skipping 81 matching lines...) Loading... |
124 Number(Target->makeNextLabelNumber()) {} | 126 Number(Target->makeNextLabelNumber()) {} |
125 | 127 |
126 IceString InstX8632Label::getName(const Cfg *Func) const { | 128 IceString InstX8632Label::getName(const Cfg *Func) const { |
127 char buf[30]; | 129 char buf[30]; |
128 snprintf(buf, llvm::array_lengthof(buf), "%u", Number); | 130 snprintf(buf, llvm::array_lengthof(buf), "%u", Number); |
129 return ".L" + Func->getFunctionName() + "$local$__" + buf; | 131 return ".L" + Func->getFunctionName() + "$local$__" + buf; |
130 } | 132 } |
131 | 133 |
132 InstX8632Br::InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, | 134 InstX8632Br::InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, |
133 const CfgNode *TargetFalse, | 135 const CfgNode *TargetFalse, |
134 const InstX8632Label *Label, | 136 const InstX8632Label *Label, CondX86::BrCond Condition) |
135 InstX8632::BrCond Condition) | |
136 : InstX8632(Func, InstX8632::Br, 0, NULL), Condition(Condition), | 137 : InstX8632(Func, InstX8632::Br, 0, NULL), Condition(Condition), |
137 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} | 138 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} |
138 | 139 |
139 bool InstX8632Br::optimizeBranch(const CfgNode *NextNode) { | 140 bool InstX8632Br::optimizeBranch(const CfgNode *NextNode) { |
140 // If there is no next block, then there can be no fallthrough to | 141 // If there is no next block, then there can be no fallthrough to |
141 // optimize. | 142 // optimize. |
142 if (NextNode == NULL) | 143 if (NextNode == NULL) |
143 return false; | 144 return false; |
144 // Intra-block conditional branches can't be optimized. | 145 // Intra-block conditional branches can't be optimized. |
145 if (Label) | 146 if (Label) |
146 return false; | 147 return false; |
147 // If there is no fallthrough node, such as a non-default case label | 148 // If there is no fallthrough node, such as a non-default case label |
148 // for a switch instruction, then there is no opportunity to | 149 // for a switch instruction, then there is no opportunity to |
149 // optimize. | 150 // optimize. |
150 if (getTargetFalse() == NULL) | 151 if (getTargetFalse() == NULL) |
151 return false; | 152 return false; |
152 | 153 |
153 // Unconditional branch to the next node can be removed. | 154 // Unconditional branch to the next node can be removed. |
154 if (Condition == Br_None && getTargetFalse() == NextNode) { | 155 if (Condition == CondX86::Br_None && getTargetFalse() == NextNode) { |
155 assert(getTargetTrue() == NULL); | 156 assert(getTargetTrue() == NULL); |
156 setDeleted(); | 157 setDeleted(); |
157 return true; | 158 return true; |
158 } | 159 } |
159 // If the fallthrough is to the next node, set fallthrough to NULL | 160 // If the fallthrough is to the next node, set fallthrough to NULL |
160 // to indicate. | 161 // to indicate. |
161 if (getTargetFalse() == NextNode) { | 162 if (getTargetFalse() == NextNode) { |
162 TargetFalse = NULL; | 163 TargetFalse = NULL; |
163 return true; | 164 return true; |
164 } | 165 } |
165 // If TargetTrue is the next node, and TargetFalse is non-NULL | 166 // If TargetTrue is the next node, and TargetFalse is non-NULL |
166 // (which was already tested above), then invert the branch | 167 // (which was already tested above), then invert the branch |
167 // condition, swap the targets, and set new fallthrough to NULL. | 168 // condition, swap the targets, and set new fallthrough to NULL. |
168 if (getTargetTrue() == NextNode) { | 169 if (getTargetTrue() == NextNode) { |
169 assert(Condition != Br_None); | 170 assert(Condition != CondX86::Br_None); |
170 Condition = InstX8632BrAttributes[Condition].Opposite; | 171 Condition = InstX8632BrAttributes[Condition].Opposite; |
171 TargetTrue = getTargetFalse(); | 172 TargetTrue = getTargetFalse(); |
172 TargetFalse = NULL; | 173 TargetFalse = NULL; |
173 return true; | 174 return true; |
174 } | 175 } |
175 return false; | 176 return false; |
176 } | 177 } |
177 | 178 |
178 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) | 179 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) |
179 : InstX8632(Func, InstX8632::Call, 1, Dest) { | 180 : InstX8632(Func, InstX8632::Call, 1, Dest) { |
180 HasSideEffects = true; | 181 HasSideEffects = true; |
181 addSource(CallTarget); | 182 addSource(CallTarget); |
182 } | 183 } |
183 | 184 |
184 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, | 185 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, |
185 InstX8632::BrCond Condition) | 186 CondX86::BrCond Condition) |
186 : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) { | 187 : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) { |
187 // The final result is either the original Dest, or Source, so mark | 188 // The final result is either the original Dest, or Source, so mark |
188 // both as sources. | 189 // both as sources. |
189 addSource(Dest); | 190 addSource(Dest); |
190 addSource(Source); | 191 addSource(Source); |
191 } | 192 } |
192 | 193 |
193 InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, | 194 InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, |
194 InstX8632Cmpps::CmppsCond Condition) | 195 CondX86::CmppsCond Condition) |
195 : InstX8632(Func, InstX8632::Cmpps, 2, Dest), Condition(Condition) { | 196 : InstX8632(Func, InstX8632::Cmpps, 2, Dest), Condition(Condition) { |
196 addSource(Dest); | 197 addSource(Dest); |
197 addSource(Source); | 198 addSource(Source); |
198 } | 199 } |
199 | 200 |
200 InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, | 201 InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, |
201 Variable *Eax, Variable *Desired, | 202 Variable *Eax, Variable *Desired, |
202 bool Locked) | 203 bool Locked) |
203 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, | 204 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, |
204 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { | 205 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { |
205 assert(Eax->getRegNum() == TargetX8632::Reg_eax); | 206 assert(Eax->getRegNum() == RegX8632::Reg_eax); |
206 addSource(DestOrAddr); | 207 addSource(DestOrAddr); |
207 addSource(Eax); | 208 addSource(Eax); |
208 addSource(Desired); | 209 addSource(Desired); |
209 } | 210 } |
210 | 211 |
211 InstX8632Cmpxchg8b::InstX8632Cmpxchg8b(Cfg *Func, OperandX8632 *Addr, | 212 InstX8632Cmpxchg8b::InstX8632Cmpxchg8b(Cfg *Func, OperandX8632 *Addr, |
212 Variable *Edx, Variable *Eax, | 213 Variable *Edx, Variable *Eax, |
213 Variable *Ecx, Variable *Ebx, | 214 Variable *Ecx, Variable *Ebx, |
214 bool Locked) | 215 bool Locked) |
215 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 5, NULL, Locked) { | 216 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 5, NULL, Locked) { |
216 assert(Edx->getRegNum() == TargetX8632::Reg_edx); | 217 assert(Edx->getRegNum() == RegX8632::Reg_edx); |
217 assert(Eax->getRegNum() == TargetX8632::Reg_eax); | 218 assert(Eax->getRegNum() == RegX8632::Reg_eax); |
218 assert(Ecx->getRegNum() == TargetX8632::Reg_ecx); | 219 assert(Ecx->getRegNum() == RegX8632::Reg_ecx); |
219 assert(Ebx->getRegNum() == TargetX8632::Reg_ebx); | 220 assert(Ebx->getRegNum() == RegX8632::Reg_ebx); |
220 addSource(Addr); | 221 addSource(Addr); |
221 addSource(Edx); | 222 addSource(Edx); |
222 addSource(Eax); | 223 addSource(Eax); |
223 addSource(Ecx); | 224 addSource(Ecx); |
224 addSource(Ebx); | 225 addSource(Ebx); |
225 } | 226 } |
226 | 227 |
227 InstX8632Cvt::InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, | 228 InstX8632Cvt::InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, |
228 bool Trunc) | 229 bool Trunc) |
229 : InstX8632(Func, InstX8632::Cvt, 1, Dest), Trunc(Trunc) { | 230 : InstX8632(Func, InstX8632::Cvt, 1, Dest), Trunc(Trunc) { |
(...skipping 110 matching lines...) Loading... |
340 | 341 |
341 void InstX8632Label::dump(const Cfg *Func) const { | 342 void InstX8632Label::dump(const Cfg *Func) const { |
342 Ostream &Str = Func->getContext()->getStrDump(); | 343 Ostream &Str = Func->getContext()->getStrDump(); |
343 Str << getName(Func) << ":"; | 344 Str << getName(Func) << ":"; |
344 } | 345 } |
345 | 346 |
346 void InstX8632Br::emit(const Cfg *Func) const { | 347 void InstX8632Br::emit(const Cfg *Func) const { |
347 Ostream &Str = Func->getContext()->getStrEmit(); | 348 Ostream &Str = Func->getContext()->getStrEmit(); |
348 Str << "\t"; | 349 Str << "\t"; |
349 | 350 |
350 if (Condition == Br_None) { | 351 if (Condition == CondX86::Br_None) { |
351 Str << "jmp"; | 352 Str << "jmp"; |
352 } else { | 353 } else { |
353 Str << InstX8632BrAttributes[Condition].EmitString; | 354 Str << InstX8632BrAttributes[Condition].EmitString; |
354 } | 355 } |
355 | 356 |
356 if (Label) { | 357 if (Label) { |
357 Str << "\t" << Label->getName(Func) << "\n"; | 358 Str << "\t" << Label->getName(Func) << "\n"; |
358 } else { | 359 } else { |
359 if (Condition == Br_None) { | 360 if (Condition == CondX86::Br_None) { |
360 Str << "\t" << getTargetFalse()->getAsmName() << "\n"; | 361 Str << "\t" << getTargetFalse()->getAsmName() << "\n"; |
361 } else { | 362 } else { |
362 Str << "\t" << getTargetTrue()->getAsmName() << "\n"; | 363 Str << "\t" << getTargetTrue()->getAsmName() << "\n"; |
363 if (getTargetFalse()) { | 364 if (getTargetFalse()) { |
364 Str << "\tjmp\t" << getTargetFalse()->getAsmName() << "\n"; | 365 Str << "\tjmp\t" << getTargetFalse()->getAsmName() << "\n"; |
365 } | 366 } |
366 } | 367 } |
367 } | 368 } |
368 } | 369 } |
369 | 370 |
370 void InstX8632Br::dump(const Cfg *Func) const { | 371 void InstX8632Br::dump(const Cfg *Func) const { |
371 Ostream &Str = Func->getContext()->getStrDump(); | 372 Ostream &Str = Func->getContext()->getStrDump(); |
372 Str << "br "; | 373 Str << "br "; |
373 | 374 |
374 if (Condition == Br_None) { | 375 if (Condition == CondX86::Br_None) { |
375 Str << "label %" | 376 Str << "label %" |
376 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); | 377 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); |
377 return; | 378 return; |
378 } | 379 } |
379 | 380 |
380 Str << InstX8632BrAttributes[Condition].DisplayString; | 381 Str << InstX8632BrAttributes[Condition].DisplayString; |
381 if (Label) { | 382 if (Label) { |
382 Str << ", label %" << Label->getName(Func); | 383 Str << ", label %" << Label->getName(Func); |
383 } else { | 384 } else { |
384 Str << ", label %" << getTargetTrue()->getName(); | 385 Str << ", label %" << getTargetTrue()->getName(); |
(...skipping 30 matching lines...) Loading... |
415 bool ShiftHack) { | 416 bool ShiftHack) { |
416 Ostream &Str = Func->getContext()->getStrEmit(); | 417 Ostream &Str = Func->getContext()->getStrEmit(); |
417 assert(Inst->getSrcSize() == 2); | 418 assert(Inst->getSrcSize() == 2); |
418 assert(Inst->getDest() == Inst->getSrc(0)); | 419 assert(Inst->getDest() == Inst->getSrc(0)); |
419 Str << "\t" << Opcode << "\t"; | 420 Str << "\t" << Opcode << "\t"; |
420 Inst->getDest()->emit(Func); | 421 Inst->getDest()->emit(Func); |
421 Str << ", "; | 422 Str << ", "; |
422 bool EmittedSrc1 = false; | 423 bool EmittedSrc1 = false; |
423 if (ShiftHack) { | 424 if (ShiftHack) { |
424 Variable *ShiftReg = llvm::dyn_cast<Variable>(Inst->getSrc(1)); | 425 Variable *ShiftReg = llvm::dyn_cast<Variable>(Inst->getSrc(1)); |
425 if (ShiftReg && ShiftReg->getRegNum() == TargetX8632::Reg_ecx) { | 426 if (ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) { |
426 Str << "cl"; | 427 Str << "cl"; |
427 EmittedSrc1 = true; | 428 EmittedSrc1 = true; |
428 } | 429 } |
429 } | 430 } |
430 if (!EmittedSrc1) | 431 if (!EmittedSrc1) |
431 Inst->getSrc(1)->emit(Func); | 432 Inst->getSrc(1)->emit(Func); |
432 Str << "\n"; | 433 Str << "\n"; |
433 } | 434 } |
434 | 435 |
435 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { | 436 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { |
(...skipping 168 matching lines...) Loading... |
604 | 605 |
605 namespace { | 606 namespace { |
606 | 607 |
607 // pblendvb and blendvps take xmm0 as a final implicit argument. | 608 // pblendvb and blendvps take xmm0 as a final implicit argument. |
608 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, | 609 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, |
609 const Cfg *Func) { | 610 const Cfg *Func) { |
610 Ostream &Str = Func->getContext()->getStrEmit(); | 611 Ostream &Str = Func->getContext()->getStrEmit(); |
611 assert(Inst->getSrcSize() == 3); | 612 assert(Inst->getSrcSize() == 3); |
612 assert(llvm::isa<Variable>(Inst->getSrc(2))); | 613 assert(llvm::isa<Variable>(Inst->getSrc(2))); |
613 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 614 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == |
614 TargetX8632::Reg_xmm0); | 615 RegX8632::Reg_xmm0); |
615 Str << "\t" << Opcode << "\t"; | 616 Str << "\t" << Opcode << "\t"; |
616 Inst->getDest()->emit(Func); | 617 Inst->getDest()->emit(Func); |
617 Str << ", "; | 618 Str << ", "; |
618 Inst->getSrc(1)->emit(Func); | 619 Inst->getSrc(1)->emit(Func); |
619 Str << "\n"; | 620 Str << "\n"; |
620 } | 621 } |
621 | 622 |
622 } // end anonymous namespace | 623 } // end anonymous namespace |
623 | 624 |
624 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { | 625 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { |
625 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 626 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
626 TargetX8632::SSE4_1); | 627 TargetX8632::SSE4_1); |
627 emitVariableBlendInst(Opcode, this, Func); | 628 emitVariableBlendInst(Opcode, this, Func); |
628 } | 629 } |
629 | 630 |
630 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { | 631 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { |
631 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 632 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
632 TargetX8632::SSE4_1); | 633 TargetX8632::SSE4_1); |
633 emitVariableBlendInst(Opcode, this, Func); | 634 emitVariableBlendInst(Opcode, this, Func); |
634 } | 635 } |
635 | 636 |
636 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 637 template <> void InstX8632Imul::emit(const Cfg *Func) const { |
637 Ostream &Str = Func->getContext()->getStrEmit(); | 638 Ostream &Str = Func->getContext()->getStrEmit(); |
638 assert(getSrcSize() == 2); | 639 assert(getSrcSize() == 2); |
639 if (getDest()->getType() == IceType_i8) { | 640 if (getDest()->getType() == IceType_i8) { |
640 // The 8-bit version of imul only allows the form "imul r/m8". | 641 // The 8-bit version of imul only allows the form "imul r/m8". |
641 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); | 642 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); |
642 (void)Src0; | 643 (void)Src0; |
643 assert(Src0 && Src0->getRegNum() == TargetX8632::Reg_eax); | 644 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); |
644 Str << "\timul\t"; | 645 Str << "\timul\t"; |
645 getSrc(1)->emit(Func); | 646 getSrc(1)->emit(Func); |
646 Str << "\n"; | 647 Str << "\n"; |
647 } else if (llvm::isa<Constant>(getSrc(1))) { | 648 } else if (llvm::isa<Constant>(getSrc(1))) { |
648 Str << "\timul\t"; | 649 Str << "\timul\t"; |
649 getDest()->emit(Func); | 650 getDest()->emit(Func); |
650 Str << ", "; | 651 Str << ", "; |
651 getSrc(0)->emit(Func); | 652 getSrc(0)->emit(Func); |
652 Str << ", "; | 653 Str << ", "; |
653 getSrc(1)->emit(Func); | 654 getSrc(1)->emit(Func); |
654 Str << "\n"; | 655 Str << "\n"; |
655 } else { | 656 } else { |
656 emitTwoAddress("imul", this, Func); | 657 emitTwoAddress("imul", this, Func); |
657 } | 658 } |
658 } | 659 } |
659 | 660 |
660 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { | 661 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { |
661 Ostream &Str = Func->getContext()->getStrEmit(); | 662 Ostream &Str = Func->getContext()->getStrEmit(); |
662 assert(getSrcSize() == 1); | 663 assert(getSrcSize() == 1); |
663 Operand *Src0 = getSrc(0); | 664 Operand *Src0 = getSrc(0); |
664 assert(llvm::isa<Variable>(Src0)); | 665 assert(llvm::isa<Variable>(Src0)); |
665 assert(llvm::cast<Variable>(Src0)->getRegNum() == TargetX8632::Reg_eax); | 666 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
666 switch (Src0->getType()) { | 667 switch (Src0->getType()) { |
667 default: | 668 default: |
668 llvm_unreachable("unexpected source type!"); | 669 llvm_unreachable("unexpected source type!"); |
669 break; | 670 break; |
670 case IceType_i8: | 671 case IceType_i8: |
671 assert(getDest()->getRegNum() == TargetX8632::Reg_eax); | 672 assert(getDest()->getRegNum() == RegX8632::Reg_eax); |
672 Str << "\tcbw\n"; | 673 Str << "\tcbw\n"; |
673 break; | 674 break; |
674 case IceType_i16: | 675 case IceType_i16: |
675 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); | 676 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
676 Str << "\tcwd\n"; | 677 Str << "\tcwd\n"; |
677 break; | 678 break; |
678 case IceType_i32: | 679 case IceType_i32: |
679 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); | 680 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
680 Str << "\tcdq\n"; | 681 Str << "\tcdq\n"; |
681 break; | 682 break; |
682 } | 683 } |
683 } | 684 } |
684 | 685 |
685 void InstX8632Mul::emit(const Cfg *Func) const { | 686 void InstX8632Mul::emit(const Cfg *Func) const { |
686 Ostream &Str = Func->getContext()->getStrEmit(); | 687 Ostream &Str = Func->getContext()->getStrEmit(); |
687 assert(getSrcSize() == 2); | 688 assert(getSrcSize() == 2); |
688 assert(llvm::isa<Variable>(getSrc(0))); | 689 assert(llvm::isa<Variable>(getSrc(0))); |
689 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == | 690 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
690 TargetX8632::Reg_eax); | 691 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
691 assert(getDest()->getRegNum() == TargetX8632::Reg_eax); // TODO: allow edx? | |
692 Str << "\tmul\t"; | 692 Str << "\tmul\t"; |
693 getSrc(1)->emit(Func); | 693 getSrc(1)->emit(Func); |
694 Str << "\n"; | 694 Str << "\n"; |
695 } | 695 } |
696 | 696 |
697 void InstX8632Mul::dump(const Cfg *Func) const { | 697 void InstX8632Mul::dump(const Cfg *Func) const { |
698 Ostream &Str = Func->getContext()->getStrDump(); | 698 Ostream &Str = Func->getContext()->getStrDump(); |
699 dumpDest(Func); | 699 dumpDest(Func); |
700 Str << " = mul." << getDest()->getType() << " "; | 700 Str << " = mul." << getDest()->getType() << " "; |
701 dumpSources(Func); | 701 dumpSources(Func); |
702 } | 702 } |
703 | 703 |
704 void InstX8632Shld::emit(const Cfg *Func) const { | 704 void InstX8632Shld::emit(const Cfg *Func) const { |
705 Ostream &Str = Func->getContext()->getStrEmit(); | 705 Ostream &Str = Func->getContext()->getStrEmit(); |
706 assert(getSrcSize() == 3); | 706 assert(getSrcSize() == 3); |
707 assert(getDest() == getSrc(0)); | 707 assert(getDest() == getSrc(0)); |
708 Str << "\tshld\t"; | 708 Str << "\tshld\t"; |
709 getDest()->emit(Func); | 709 getDest()->emit(Func); |
710 Str << ", "; | 710 Str << ", "; |
711 getSrc(1)->emit(Func); | 711 getSrc(1)->emit(Func); |
712 Str << ", "; | 712 Str << ", "; |
713 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 713 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
714 (void)ShiftReg; | 714 (void)ShiftReg; |
715 assert(ShiftReg->getRegNum() == TargetX8632::Reg_ecx); | 715 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
716 Str << "cl"; | 716 Str << "cl"; |
717 } else { | 717 } else { |
718 getSrc(2)->emit(Func); | 718 getSrc(2)->emit(Func); |
719 } | 719 } |
720 Str << "\n"; | 720 Str << "\n"; |
721 } | 721 } |
722 | 722 |
723 void InstX8632Shld::dump(const Cfg *Func) const { | 723 void InstX8632Shld::dump(const Cfg *Func) const { |
724 Ostream &Str = Func->getContext()->getStrDump(); | 724 Ostream &Str = Func->getContext()->getStrDump(); |
725 dumpDest(Func); | 725 dumpDest(Func); |
726 Str << " = shld." << getDest()->getType() << " "; | 726 Str << " = shld." << getDest()->getType() << " "; |
727 dumpSources(Func); | 727 dumpSources(Func); |
728 } | 728 } |
729 | 729 |
730 void InstX8632Shrd::emit(const Cfg *Func) const { | 730 void InstX8632Shrd::emit(const Cfg *Func) const { |
731 Ostream &Str = Func->getContext()->getStrEmit(); | 731 Ostream &Str = Func->getContext()->getStrEmit(); |
732 assert(getSrcSize() == 3); | 732 assert(getSrcSize() == 3); |
733 assert(getDest() == getSrc(0)); | 733 assert(getDest() == getSrc(0)); |
734 Str << "\tshrd\t"; | 734 Str << "\tshrd\t"; |
735 getDest()->emit(Func); | 735 getDest()->emit(Func); |
736 Str << ", "; | 736 Str << ", "; |
737 getSrc(1)->emit(Func); | 737 getSrc(1)->emit(Func); |
738 Str << ", "; | 738 Str << ", "; |
739 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 739 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
740 (void)ShiftReg; | 740 (void)ShiftReg; |
741 assert(ShiftReg->getRegNum() == TargetX8632::Reg_ecx); | 741 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
742 Str << "cl"; | 742 Str << "cl"; |
743 } else { | 743 } else { |
744 getSrc(2)->emit(Func); | 744 getSrc(2)->emit(Func); |
745 } | 745 } |
746 Str << "\n"; | 746 Str << "\n"; |
747 } | 747 } |
748 | 748 |
749 void InstX8632Shrd::dump(const Cfg *Func) const { | 749 void InstX8632Shrd::dump(const Cfg *Func) const { |
750 Ostream &Str = Func->getContext()->getStrDump(); | 750 Ostream &Str = Func->getContext()->getStrDump(); |
751 dumpDest(Func); | 751 dumpDest(Func); |
752 Str << " = shrd." << getDest()->getType() << " "; | 752 Str << " = shrd." << getDest()->getType() << " "; |
753 dumpSources(Func); | 753 dumpSources(Func); |
754 } | 754 } |
755 | 755 |
756 void InstX8632Cmov::emit(const Cfg *Func) const { | 756 void InstX8632Cmov::emit(const Cfg *Func) const { |
757 Ostream &Str = Func->getContext()->getStrEmit(); | 757 Ostream &Str = Func->getContext()->getStrEmit(); |
758 Str << "\t"; | 758 Str << "\t"; |
759 assert(Condition != Br_None); | 759 assert(Condition != CondX86::Br_None); |
760 assert(getDest()->hasReg()); | 760 assert(getDest()->hasReg()); |
761 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 761 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
762 getDest()->emit(Func); | 762 getDest()->emit(Func); |
763 Str << ", "; | 763 Str << ", "; |
764 getSrc(1)->emit(Func); | 764 getSrc(1)->emit(Func); |
765 Str << "\n"; | 765 Str << "\n"; |
766 } | 766 } |
767 | 767 |
768 void InstX8632Cmov::dump(const Cfg *Func) const { | 768 void InstX8632Cmov::dump(const Cfg *Func) const { |
769 Ostream &Str = Func->getContext()->getStrDump(); | 769 Ostream &Str = Func->getContext()->getStrDump(); |
770 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 770 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
771 Str << getDest()->getType() << " "; | 771 Str << getDest()->getType() << " "; |
772 dumpDest(Func); | 772 dumpDest(Func); |
773 Str << ", "; | 773 Str << ", "; |
774 dumpSources(Func); | 774 dumpSources(Func); |
775 } | 775 } |
776 | 776 |
777 void InstX8632Cmpps::emit(const Cfg *Func) const { | 777 void InstX8632Cmpps::emit(const Cfg *Func) const { |
778 Ostream &Str = Func->getContext()->getStrEmit(); | 778 Ostream &Str = Func->getContext()->getStrEmit(); |
779 assert(getSrcSize() == 2); | 779 assert(getSrcSize() == 2); |
780 assert(Condition < Cmpps_Invalid); | 780 assert(Condition < CondX86::Cmpps_Invalid); |
781 Str << "\t"; | 781 Str << "\t"; |
782 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 782 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
783 << "\t"; | 783 << "\t"; |
784 getDest()->emit(Func); | 784 getDest()->emit(Func); |
785 Str << ", "; | 785 Str << ", "; |
786 getSrc(1)->emit(Func); | 786 getSrc(1)->emit(Func); |
787 Str << "\n"; | 787 Str << "\n"; |
788 } | 788 } |
789 | 789 |
790 void InstX8632Cmpps::dump(const Cfg *Func) const { | 790 void InstX8632Cmpps::dump(const Cfg *Func) const { |
791 Ostream &Str = Func->getContext()->getStrDump(); | 791 Ostream &Str = Func->getContext()->getStrDump(); |
792 assert(Condition < Cmpps_Invalid); | 792 assert(Condition < CondX86::Cmpps_Invalid); |
793 dumpDest(Func); | 793 dumpDest(Func); |
794 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 794 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
795 << "\t"; | 795 << "\t"; |
796 dumpSources(Func); | 796 dumpSources(Func); |
797 } | 797 } |
798 | 798 |
799 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 799 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
800 Ostream &Str = Func->getContext()->getStrEmit(); | 800 Ostream &Str = Func->getContext()->getStrEmit(); |
801 assert(getSrcSize() == 3); | 801 assert(getSrcSize() == 3); |
802 if (Locked) { | 802 if (Locked) { |
(...skipping 727 matching lines...) Loading... |
1530 } | 1530 } |
1531 Str << "("; | 1531 Str << "("; |
1532 if (Func) | 1532 if (Func) |
1533 Var->dump(Func); | 1533 Var->dump(Func); |
1534 else | 1534 else |
1535 Var->dump(Str); | 1535 Var->dump(Str); |
1536 Str << ")"; | 1536 Str << ")"; |
1537 } | 1537 } |
1538 | 1538 |
1539 } // end of namespace Ice | 1539 } // end of namespace Ice |
OLD | NEW |