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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 } | 87 } |
88 } | 88 } |
89 | 89 |
90 InstX8632Mul::InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, | 90 InstX8632Mul::InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, |
91 Operand *Source2) | 91 Operand *Source2) |
92 : InstX8632(Func, InstX8632::Mul, 2, Dest) { | 92 : InstX8632(Func, InstX8632::Mul, 2, Dest) { |
93 addSource(Source1); | 93 addSource(Source1); |
94 addSource(Source2); | 94 addSource(Source2); |
95 } | 95 } |
96 | 96 |
| 97 InstX8632Neg::InstX8632Neg(Cfg *Func, Operand *SrcDest) |
| 98 : InstX8632(Func, InstX8632::Neg, 1, llvm::dyn_cast<Variable>(SrcDest)) { |
| 99 addSource(SrcDest); |
| 100 } |
| 101 |
97 InstX8632Shld::InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, | 102 InstX8632Shld::InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, |
98 Variable *Source2) | 103 Variable *Source2) |
99 : InstX8632(Func, InstX8632::Shld, 3, Dest) { | 104 : InstX8632(Func, InstX8632::Shld, 3, Dest) { |
100 addSource(Dest); | 105 addSource(Dest); |
101 addSource(Source1); | 106 addSource(Source1); |
102 addSource(Source2); | 107 addSource(Source2); |
103 } | 108 } |
104 | 109 |
105 InstX8632Shrd::InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, | 110 InstX8632Shrd::InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, |
106 Variable *Source2) | 111 Variable *Source2) |
107 : InstX8632(Func, InstX8632::Shrd, 3, Dest) { | 112 : InstX8632(Func, InstX8632::Shrd, 3, Dest) { |
108 addSource(Dest); | 113 addSource(Dest); |
109 addSource(Source1); | 114 addSource(Source1); |
110 addSource(Source2); | 115 addSource(Source2); |
111 } | 116 } |
112 | 117 |
113 InstX8632Label::InstX8632Label(Cfg *Func, TargetX8632 *Target) | 118 InstX8632Label::InstX8632Label(Cfg *Func, TargetX8632 *Target) |
114 : InstX8632(Func, InstX8632::Label, 0, NULL), | 119 : InstX8632(Func, InstX8632::Label, 0, NULL), |
115 Number(Target->makeNextLabelNumber()) {} | 120 Number(Target->makeNextLabelNumber()) {} |
116 | 121 |
117 IceString InstX8632Label::getName(const Cfg *Func) const { | 122 IceString InstX8632Label::getName(const Cfg *Func) const { |
118 char buf[30]; | 123 char buf[30]; |
119 snprintf(buf, llvm::array_lengthof(buf), "%u", Number); | 124 snprintf(buf, llvm::array_lengthof(buf), "%u", Number); |
120 return ".L" + Func->getFunctionName() + "$__" + buf; | 125 return ".L" + Func->getFunctionName() + "$__" + buf; |
121 } | 126 } |
122 | 127 |
123 InstX8632Br::InstX8632Br(Cfg *Func, CfgNode *TargetTrue, CfgNode *TargetFalse, | 128 InstX8632Br::InstX8632Br(Cfg *Func, CfgNode *TargetTrue, CfgNode *TargetFalse, |
124 InstX8632Label *Label, InstX8632Br::BrCond Condition) | 129 InstX8632Label *Label, InstX8632::BrCond Condition) |
125 : InstX8632(Func, InstX8632::Br, 0, NULL), Condition(Condition), | 130 : InstX8632(Func, InstX8632::Br, 0, NULL), Condition(Condition), |
126 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} | 131 TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {} |
127 | 132 |
128 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) | 133 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) |
129 : InstX8632(Func, InstX8632::Call, 1, Dest) { | 134 : InstX8632(Func, InstX8632::Call, 1, Dest) { |
130 HasSideEffects = true; | 135 HasSideEffects = true; |
131 addSource(CallTarget); | 136 addSource(CallTarget); |
132 } | 137 } |
133 | 138 |
134 InstX8632Cdq::InstX8632Cdq(Cfg *Func, Variable *Dest, Operand *Source) | 139 InstX8632Cdq::InstX8632Cdq(Cfg *Func, Variable *Dest, Operand *Source) |
135 : InstX8632(Func, InstX8632::Cdq, 1, Dest) { | 140 : InstX8632(Func, InstX8632::Cdq, 1, Dest) { |
136 assert(Dest->getRegNum() == TargetX8632::Reg_edx); | 141 assert(Dest->getRegNum() == TargetX8632::Reg_edx); |
137 assert(llvm::isa<Variable>(Source)); | 142 assert(llvm::isa<Variable>(Source)); |
138 assert(llvm::dyn_cast<Variable>(Source)->getRegNum() == TargetX8632::Reg_eax); | 143 assert(llvm::dyn_cast<Variable>(Source)->getRegNum() == TargetX8632::Reg_eax); |
139 addSource(Source); | 144 addSource(Source); |
140 } | 145 } |
141 | 146 |
| 147 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, |
| 148 InstX8632::BrCond Condition) |
| 149 : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) { |
| 150 // The final result is either the original Dest, or Source, so mark |
| 151 // both as sources. |
| 152 addSource(Dest); |
| 153 addSource(Source); |
| 154 } |
| 155 |
142 InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, | 156 InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, |
143 Variable *Eax, Variable *Desired, | 157 Variable *Eax, Variable *Desired, |
144 bool Locked) | 158 bool Locked) |
145 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, | 159 : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3, |
146 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { | 160 llvm::dyn_cast<Variable>(DestOrAddr), Locked) { |
147 assert(Eax->getRegNum() == TargetX8632::Reg_eax); | 161 assert(Eax->getRegNum() == TargetX8632::Reg_eax); |
148 addSource(DestOrAddr); | 162 addSource(DestOrAddr); |
149 addSource(Eax); | 163 addSource(Eax); |
150 addSource(Desired); | 164 addSource(Desired); |
151 } | 165 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 return false; | 304 return false; |
291 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { | 305 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { |
292 return true; | 306 return true; |
293 } | 307 } |
294 if (!getDest()->hasReg() && !Src->hasReg() && | 308 if (!getDest()->hasReg() && !Src->hasReg() && |
295 Dest->getStackOffset() == Src->getStackOffset()) | 309 Dest->getStackOffset() == Src->getStackOffset()) |
296 return true; | 310 return true; |
297 return false; | 311 return false; |
298 } | 312 } |
299 | 313 |
300 InstX8632Sqrtss::InstX8632Sqrtss(Cfg *Func, Variable *Dest, Operand *Source) | |
301 : InstX8632(Func, InstX8632::Sqrtss, 1, Dest) { | |
302 addSource(Source); | |
303 } | |
304 | |
305 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) | 314 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) |
306 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) { | 315 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) { |
307 if (Source) | 316 if (Source) |
308 addSource(Source); | 317 addSource(Source); |
309 } | 318 } |
310 | 319 |
311 InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, | 320 InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, |
312 bool Locked) | 321 bool Locked) |
313 : InstX8632Lockable(Func, InstX8632::Xadd, 2, | 322 : InstX8632Lockable(Func, InstX8632::Xadd, 2, |
314 llvm::dyn_cast<Variable>(Dest), Locked) { | 323 llvm::dyn_cast<Variable>(Dest), Locked) { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 if (ShiftReg && ShiftReg->getRegNum() == TargetX8632::Reg_ecx) { | 431 if (ShiftReg && ShiftReg->getRegNum() == TargetX8632::Reg_ecx) { |
423 Str << "cl"; | 432 Str << "cl"; |
424 EmittedSrc1 = true; | 433 EmittedSrc1 = true; |
425 } | 434 } |
426 } | 435 } |
427 if (!EmittedSrc1) | 436 if (!EmittedSrc1) |
428 Inst->getSrc(1)->emit(Func); | 437 Inst->getSrc(1)->emit(Func); |
429 Str << "\n"; | 438 Str << "\n"; |
430 } | 439 } |
431 | 440 |
432 template <> const char *InstX8632Neg::Opcode = "neg"; | 441 template <> const char *InstX8632Bsf::Opcode = "bsf"; |
| 442 template <> const char *InstX8632Bsr::Opcode = "bsr"; |
| 443 template <> const char *InstX8632Sqrtss::Opcode = "sqrtss"; |
433 template <> const char *InstX8632Add::Opcode = "add"; | 444 template <> const char *InstX8632Add::Opcode = "add"; |
434 template <> const char *InstX8632Addps::Opcode = "addps"; | 445 template <> const char *InstX8632Addps::Opcode = "addps"; |
435 template <> const char *InstX8632Adc::Opcode = "adc"; | 446 template <> const char *InstX8632Adc::Opcode = "adc"; |
436 template <> const char *InstX8632Addss::Opcode = "addss"; | 447 template <> const char *InstX8632Addss::Opcode = "addss"; |
437 template <> const char *InstX8632Sub::Opcode = "sub"; | 448 template <> const char *InstX8632Sub::Opcode = "sub"; |
438 template <> const char *InstX8632Subps::Opcode = "subps"; | 449 template <> const char *InstX8632Subps::Opcode = "subps"; |
439 template <> const char *InstX8632Subss::Opcode = "subss"; | 450 template <> const char *InstX8632Subss::Opcode = "subss"; |
440 template <> const char *InstX8632Sbb::Opcode = "sbb"; | 451 template <> const char *InstX8632Sbb::Opcode = "sbb"; |
441 template <> const char *InstX8632And::Opcode = "and"; | 452 template <> const char *InstX8632And::Opcode = "and"; |
442 template <> const char *InstX8632Or::Opcode = "or"; | 453 template <> const char *InstX8632Or::Opcode = "or"; |
443 template <> const char *InstX8632Xor::Opcode = "xor"; | 454 template <> const char *InstX8632Xor::Opcode = "xor"; |
444 template <> const char *InstX8632Pxor::Opcode = "pxor"; | 455 template <> const char *InstX8632Pxor::Opcode = "pxor"; |
445 template <> const char *InstX8632Imul::Opcode = "imul"; | 456 template <> const char *InstX8632Imul::Opcode = "imul"; |
446 template <> const char *InstX8632Mulps::Opcode = "mulps"; | 457 template <> const char *InstX8632Mulps::Opcode = "mulps"; |
447 template <> const char *InstX8632Mulss::Opcode = "mulss"; | 458 template <> const char *InstX8632Mulss::Opcode = "mulss"; |
448 template <> const char *InstX8632Div::Opcode = "div"; | 459 template <> const char *InstX8632Div::Opcode = "div"; |
449 template <> const char *InstX8632Divps::Opcode = "divps"; | 460 template <> const char *InstX8632Divps::Opcode = "divps"; |
450 template <> const char *InstX8632Idiv::Opcode = "idiv"; | 461 template <> const char *InstX8632Idiv::Opcode = "idiv"; |
451 template <> const char *InstX8632Divss::Opcode = "divss"; | 462 template <> const char *InstX8632Divss::Opcode = "divss"; |
452 template <> const char *InstX8632Shl::Opcode = "shl"; | 463 template <> const char *InstX8632Shl::Opcode = "shl"; |
453 template <> const char *InstX8632Shr::Opcode = "shr"; | 464 template <> const char *InstX8632Shr::Opcode = "shr"; |
454 template <> const char *InstX8632Sar::Opcode = "sar"; | 465 template <> const char *InstX8632Sar::Opcode = "sar"; |
455 | 466 |
| 467 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { |
| 468 Ostream &Str = Func->getContext()->getStrEmit(); |
| 469 assert(getSrcSize() == 1); |
| 470 Type Ty = getSrc(0)->getType(); |
| 471 assert(Ty == IceType_f32 || Ty == IceType_f64); |
| 472 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
| 473 getDest()->emit(Func); |
| 474 Str << ", "; |
| 475 getSrc(0)->emit(Func); |
| 476 Str << "\n"; |
| 477 } |
| 478 |
456 template <> void InstX8632Addss::emit(const Cfg *Func) const { | 479 template <> void InstX8632Addss::emit(const Cfg *Func) const { |
457 char buf[30]; | 480 char buf[30]; |
458 snprintf(buf, llvm::array_lengthof(buf), "add%s", | 481 snprintf(buf, llvm::array_lengthof(buf), "add%s", |
459 TypeX8632Attributes[getDest()->getType()].SdSsString); | 482 TypeX8632Attributes[getDest()->getType()].SdSsString); |
460 emitTwoAddress(buf, this, Func); | 483 emitTwoAddress(buf, this, Func); |
461 } | 484 } |
462 | 485 |
463 template <> void InstX8632Subss::emit(const Cfg *Func) const { | 486 template <> void InstX8632Subss::emit(const Cfg *Func) const { |
464 char buf[30]; | 487 char buf[30]; |
465 snprintf(buf, llvm::array_lengthof(buf), "sub%s", | 488 snprintf(buf, llvm::array_lengthof(buf), "sub%s", |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 Str << "\n"; | 539 Str << "\n"; |
517 } | 540 } |
518 | 541 |
519 void InstX8632Mul::dump(const Cfg *Func) const { | 542 void InstX8632Mul::dump(const Cfg *Func) const { |
520 Ostream &Str = Func->getContext()->getStrDump(); | 543 Ostream &Str = Func->getContext()->getStrDump(); |
521 dumpDest(Func); | 544 dumpDest(Func); |
522 Str << " = mul." << getDest()->getType() << " "; | 545 Str << " = mul." << getDest()->getType() << " "; |
523 dumpSources(Func); | 546 dumpSources(Func); |
524 } | 547 } |
525 | 548 |
| 549 void InstX8632Neg::emit(const Cfg *Func) const { |
| 550 Ostream &Str = Func->getContext()->getStrEmit(); |
| 551 assert(getSrcSize() == 1); |
| 552 Str << "\tneg\t"; |
| 553 getSrc(0)->emit(Func); |
| 554 Str << "\n"; |
| 555 } |
| 556 |
| 557 void InstX8632Neg::dump(const Cfg *Func) const { |
| 558 Ostream &Str = Func->getContext()->getStrDump(); |
| 559 dumpDest(Func); |
| 560 Str << " = neg." << getDest()->getType() << " "; |
| 561 dumpSources(Func); |
| 562 } |
| 563 |
526 void InstX8632Shld::emit(const Cfg *Func) const { | 564 void InstX8632Shld::emit(const Cfg *Func) const { |
527 Ostream &Str = Func->getContext()->getStrEmit(); | 565 Ostream &Str = Func->getContext()->getStrEmit(); |
528 assert(getSrcSize() == 3); | 566 assert(getSrcSize() == 3); |
529 assert(getDest() == getSrc(0)); | 567 assert(getDest() == getSrc(0)); |
530 Str << "\tshld\t"; | 568 Str << "\tshld\t"; |
531 getDest()->emit(Func); | 569 getDest()->emit(Func); |
532 Str << ", "; | 570 Str << ", "; |
533 getSrc(1)->emit(Func); | 571 getSrc(1)->emit(Func); |
534 Str << ", "; | 572 Str << ", "; |
535 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 573 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 Str << "\tcdq\n"; | 617 Str << "\tcdq\n"; |
580 } | 618 } |
581 | 619 |
582 void InstX8632Cdq::dump(const Cfg *Func) const { | 620 void InstX8632Cdq::dump(const Cfg *Func) const { |
583 Ostream &Str = Func->getContext()->getStrDump(); | 621 Ostream &Str = Func->getContext()->getStrDump(); |
584 dumpDest(Func); | 622 dumpDest(Func); |
585 Str << " = cdq." << getSrc(0)->getType() << " "; | 623 Str << " = cdq." << getSrc(0)->getType() << " "; |
586 dumpSources(Func); | 624 dumpSources(Func); |
587 } | 625 } |
588 | 626 |
| 627 void InstX8632Cmov::emit(const Cfg *Func) const { |
| 628 Ostream &Str = Func->getContext()->getStrEmit(); |
| 629 Str << "\t"; |
| 630 assert(Condition != Br_None); |
| 631 assert(getDest()->hasReg()); |
| 632 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
| 633 getDest()->emit(Func); |
| 634 Str << ", "; |
| 635 getSrc(1)->emit(Func); |
| 636 Str << "\n"; |
| 637 } |
| 638 |
| 639 void InstX8632Cmov::dump(const Cfg *Func) const { |
| 640 Ostream &Str = Func->getContext()->getStrDump(); |
| 641 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
| 642 Str << getDest()->getType() << " "; |
| 643 dumpDest(Func); |
| 644 Str << ", "; |
| 645 dumpSources(Func); |
| 646 } |
| 647 |
589 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 648 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
590 Ostream &Str = Func->getContext()->getStrEmit(); | 649 Ostream &Str = Func->getContext()->getStrEmit(); |
591 assert(getSrcSize() == 3); | 650 assert(getSrcSize() == 3); |
592 if (Locked) { | 651 if (Locked) { |
593 Str << "\tlock"; | 652 Str << "\tlock"; |
594 } | 653 } |
595 Str << "\tcmpxchg\t"; | 654 Str << "\tcmpxchg\t"; |
596 getSrc(0)->emit(Func); | 655 getSrc(0)->emit(Func); |
597 Str << ", "; | 656 Str << ", "; |
598 getSrc(2)->emit(Func); | 657 getSrc(2)->emit(Func); |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 Str << "\tret\n"; | 1059 Str << "\tret\n"; |
1001 } | 1060 } |
1002 | 1061 |
1003 void InstX8632Ret::dump(const Cfg *Func) const { | 1062 void InstX8632Ret::dump(const Cfg *Func) const { |
1004 Ostream &Str = Func->getContext()->getStrDump(); | 1063 Ostream &Str = Func->getContext()->getStrDump(); |
1005 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 1064 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
1006 Str << "ret." << Ty << " "; | 1065 Str << "ret." << Ty << " "; |
1007 dumpSources(Func); | 1066 dumpSources(Func); |
1008 } | 1067 } |
1009 | 1068 |
1010 void InstX8632Sqrtss::emit(const Cfg *Func) const { | |
1011 Ostream &Str = Func->getContext()->getStrEmit(); | |
1012 assert(getSrcSize() == 1); | |
1013 Type Ty = getSrc(0)->getType(); | |
1014 assert(Ty == IceType_f32 || Ty == IceType_f64); | |
1015 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | |
1016 getDest()->emit(Func); | |
1017 Str << ", "; | |
1018 getSrc(0)->emit(Func); | |
1019 Str << "\n"; | |
1020 } | |
1021 | |
1022 void InstX8632Sqrtss::dump(const Cfg *Func) const { | |
1023 Ostream &Str = Func->getContext()->getStrDump(); | |
1024 dumpDest(Func); | |
1025 Str << " = sqrt." << getDest()->getType() << " "; | |
1026 dumpSources(Func); | |
1027 } | |
1028 | |
1029 void InstX8632Xadd::emit(const Cfg *Func) const { | 1069 void InstX8632Xadd::emit(const Cfg *Func) const { |
1030 Ostream &Str = Func->getContext()->getStrEmit(); | 1070 Ostream &Str = Func->getContext()->getStrEmit(); |
1031 if (Locked) { | 1071 if (Locked) { |
1032 Str << "\tlock"; | 1072 Str << "\tlock"; |
1033 } | 1073 } |
1034 Str << "\txadd\t"; | 1074 Str << "\txadd\t"; |
1035 getSrc(0)->emit(Func); | 1075 getSrc(0)->emit(Func); |
1036 Str << ", "; | 1076 Str << ", "; |
1037 getSrc(1)->emit(Func); | 1077 getSrc(1)->emit(Func); |
1038 Str << "\n"; | 1078 Str << "\n"; |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1190 default: | 1230 default: |
1191 Str << "???"; | 1231 Str << "???"; |
1192 break; | 1232 break; |
1193 } | 1233 } |
1194 Str << "("; | 1234 Str << "("; |
1195 Var->dump(Func); | 1235 Var->dump(Func); |
1196 Str << ")"; | 1236 Str << ")"; |
1197 } | 1237 } |
1198 | 1238 |
1199 } // end of namespace Ice | 1239 } // end of namespace Ice |
OLD | NEW |