| OLD | NEW |
| 1 //===- subzero/src/IceInstMips32.cpp - Mips32 instruction implementation --===// | 1 //===- subzero/src/IceInstMips32.cpp - Mips32 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 /// \file | 10 /// \file |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); | 276 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); |
| 277 Asm->bindLocalLabel(this, Number); | 277 Asm->bindLocalLabel(this, Number); |
| 278 } | 278 } |
| 279 | 279 |
| 280 InstMIPS32Call::InstMIPS32Call(Cfg *Func, Variable *Dest, Operand *CallTarget) | 280 InstMIPS32Call::InstMIPS32Call(Cfg *Func, Variable *Dest, Operand *CallTarget) |
| 281 : InstMIPS32(Func, InstMIPS32::Call, 1, Dest) { | 281 : InstMIPS32(Func, InstMIPS32::Call, 1, Dest) { |
| 282 HasSideEffects = true; | 282 HasSideEffects = true; |
| 283 addSource(CallTarget); | 283 addSource(CallTarget); |
| 284 } | 284 } |
| 285 | 285 |
| 286 InstMIPS32Mov::InstMIPS32Mov(Cfg *Func, Variable *Dest, Operand *Src) | 286 InstMIPS32Mov::InstMIPS32Mov(Cfg *Func, Variable *Dest, Operand *Src, |
| 287 Operand *Src2) |
| 287 : InstMIPS32(Func, InstMIPS32::Mov, 2, Dest) { | 288 : InstMIPS32(Func, InstMIPS32::Mov, 2, Dest) { |
| 288 auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest); | 289 auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest); |
| 289 auto *Src64 = llvm::dyn_cast<Variable64On32>(Src); | 290 auto *Src64 = llvm::dyn_cast<Variable64On32>(Src); |
| 290 | 291 |
| 291 assert(Dest64 == nullptr || Src64 == nullptr); | 292 assert(Dest64 == nullptr || Src64 == nullptr); |
| 292 | 293 |
| 294 if (Dest->getType() == IceType_f64 && Src2 != nullptr) { |
| 295 addSource(Src); |
| 296 addSource(Src2); |
| 297 return; |
| 298 } |
| 299 |
| 293 if (Dest64 != nullptr) { | 300 if (Dest64 != nullptr) { |
| 294 // this-> is needed below because there is a parameter named Dest. | 301 // this-> is needed below because there is a parameter named Dest. |
| 295 this->Dest = Dest64->getLo(); | 302 this->Dest = Dest64->getLo(); |
| 296 DestHi = Dest64->getHi(); | 303 DestHi = Dest64->getHi(); |
| 297 } | 304 } |
| 298 | 305 |
| 299 if (Src64 == nullptr) { | 306 if (Src64 == nullptr) { |
| 300 addSource(Src); | 307 addSource(Src); |
| 301 } else { | 308 } else { |
| 302 addSource(Src64->getLo()); | 309 addSource(Src64->getLo()); |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 return; | 588 return; |
| 582 Ostream &Str = Func->getContext()->getStrDump(); | 589 Ostream &Str = Func->getContext()->getStrDump(); |
| 583 Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType()); | 590 Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType()); |
| 584 Str << "ret." << Ty << " "; | 591 Str << "ret." << Ty << " "; |
| 585 dumpSources(Func); | 592 dumpSources(Func); |
| 586 } | 593 } |
| 587 | 594 |
| 588 void InstMIPS32Mov::emit(const Cfg *Func) const { | 595 void InstMIPS32Mov::emit(const Cfg *Func) const { |
| 589 if (!BuildDefs::dump()) | 596 if (!BuildDefs::dump()) |
| 590 return; | 597 return; |
| 591 assert(!(isMultiDest() && isMultiSource()) && "Invalid mov type."); | |
| 592 if (isMultiDest()) { | |
| 593 emitMultiDestSingleSource(Func); | |
| 594 return; | |
| 595 } | |
| 596 | 598 |
| 597 if (isMultiSource()) { | |
| 598 emitSingleDestMultiSource(Func); | |
| 599 return; | |
| 600 } | |
| 601 | |
| 602 emitSingleDestSingleSource(Func); | |
| 603 } | |
| 604 | |
| 605 // TODO(jaydeep.patil) Handle all types of operands in mov | |
| 606 void InstMIPS32Mov::emitIAS(const Cfg *Func) const { | |
| 607 assert(!(isMultiDest() && isMultiSource()) && "Invalid mov type."); | |
| 608 | |
| 609 if (isMultiDest()) { | |
| 610 llvm_unreachable("Not yet implemented"); | |
| 611 } | |
| 612 if (isMultiSource()) { | |
| 613 llvm_unreachable("Not yet implemented"); | |
| 614 } | |
| 615 | |
| 616 Variable *Dest = getDest(); | |
| 617 Operand *Src = getSrc(0); | |
| 618 auto *SrcV = llvm::dyn_cast<Variable>(Src); | |
| 619 assert(!llvm::isa<Constant>(Src)); | |
| 620 const bool DestIsReg = Dest->hasReg(); | |
| 621 const bool SrcIsReg = (SrcV && SrcV->hasReg()); | |
| 622 | |
| 623 // reg to reg | |
| 624 if (DestIsReg && SrcIsReg) { | |
| 625 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); | |
| 626 Asm->move(getDest(), getSrc(0)); | |
| 627 return; | |
| 628 } | |
| 629 llvm_unreachable("Not yet implemented"); | |
| 630 } | |
| 631 | |
| 632 void InstMIPS32Mov::dump(const Cfg *Func) const { | |
| 633 if (!BuildDefs::dump()) | |
| 634 return; | |
| 635 assert(getSrcSize() == 1 || getSrcSize() == 2); | |
| 636 Ostream &Str = Func->getContext()->getStrDump(); | |
| 637 Variable *Dest = getDest(); | |
| 638 Variable *DestHi = getDestHi(); | |
| 639 Dest->dump(Func); | |
| 640 if (DestHi) { | |
| 641 Str << ", "; | |
| 642 DestHi->dump(Func); | |
| 643 } | |
| 644 dumpOpcode(Str, " = mov", getDest()->getType()); | |
| 645 Str << " "; | |
| 646 dumpSources(Func); | |
| 647 } | |
| 648 | |
| 649 void InstMIPS32Mov::emitMultiDestSingleSource(const Cfg *Func) const { | |
| 650 if (!BuildDefs::dump()) | |
| 651 return; | |
| 652 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 653 Variable *DestLo = getDest(); | |
| 654 Variable *DestHi = getDestHi(); | |
| 655 auto *Src = llvm::cast<Variable>(getSrc(0)); | |
| 656 | |
| 657 assert(DestHi->hasReg()); | |
| 658 assert(DestLo->hasReg()); | |
| 659 assert(llvm::isa<Variable>(Src) && Src->hasReg()); | |
| 660 | |
| 661 // Str << "\t" | |
| 662 // << "vmov" << getPredicate() << "\t"; | |
| 663 DestLo->emit(Func); | |
| 664 Str << ", "; | |
| 665 DestHi->emit(Func); | |
| 666 Str << ", "; | |
| 667 Src->emit(Func); | |
| 668 } | |
| 669 | |
| 670 void InstMIPS32Mov::emitSingleDestMultiSource(const Cfg *Func) const { | |
| 671 if (!BuildDefs::dump()) | |
| 672 return; | |
| 673 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 674 Variable *Dest = getDest(); | |
| 675 auto *SrcLo = llvm::cast<Variable>(getSrc(0)); | |
| 676 auto *SrcHi = llvm::cast<Variable>(getSrc(1)); | |
| 677 | |
| 678 assert(SrcHi->hasReg()); | |
| 679 assert(SrcLo->hasReg()); | |
| 680 assert(Dest->hasReg()); | |
| 681 assert(getSrcSize() == 2); | |
| 682 | |
| 683 // Str << "\t" | |
| 684 // << "vmov" << getPredicate() << "\t"; | |
| 685 Dest->emit(Func); | |
| 686 Str << ", "; | |
| 687 SrcLo->emit(Func); | |
| 688 Str << ", "; | |
| 689 SrcHi->emit(Func); | |
| 690 } | |
| 691 | |
| 692 void InstMIPS32Mov::emitSingleDestSingleSource(const Cfg *Func) const { | |
| 693 if (!BuildDefs::dump()) | |
| 694 return; | |
| 695 Ostream &Str = Func->getContext()->getStrEmit(); | 599 Ostream &Str = Func->getContext()->getStrEmit(); |
| 696 Variable *Dest = getDest(); | 600 Variable *Dest = getDest(); |
| 697 Operand *Src = getSrc(0); | 601 Operand *Src = getSrc(0); |
| 698 auto *SrcV = llvm::dyn_cast<Variable>(Src); | 602 auto *SrcV = llvm::dyn_cast<Variable>(Src); |
| 699 | 603 |
| 700 assert(!llvm::isa<Constant>(Src)); | 604 assert(!llvm::isa<Constant>(Src)); |
| 701 | 605 |
| 702 const char *ActualOpcode = nullptr; | 606 const char *ActualOpcode = nullptr; |
| 703 const bool DestIsReg = Dest->hasReg(); | 607 const bool DestIsReg = Dest->hasReg(); |
| 704 const bool SrcIsReg = (SrcV && SrcV->hasReg()); | 608 const bool SrcIsReg = (SrcV && SrcV->hasReg()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 Str << "\t" << ActualOpcode << "\t"; | 649 Str << "\t" << ActualOpcode << "\t"; |
| 746 getDest()->emit(Func); | 650 getDest()->emit(Func); |
| 747 Str << ", "; | 651 Str << ", "; |
| 748 getSrc(0)->emit(Func); | 652 getSrc(0)->emit(Func); |
| 749 return; | 653 return; |
| 750 } | 654 } |
| 751 | 655 |
| 752 llvm::report_fatal_error("Invalid mov instruction. Dest or Src is memory."); | 656 llvm::report_fatal_error("Invalid mov instruction. Dest or Src is memory."); |
| 753 } | 657 } |
| 754 | 658 |
| 659 // TODO(jaydeep.patil) Handle all types of operands in mov |
| 660 void InstMIPS32Mov::emitIAS(const Cfg *Func) const { |
| 661 Variable *Dest = getDest(); |
| 662 Operand *Src = getSrc(0); |
| 663 auto *SrcV = llvm::dyn_cast<Variable>(Src); |
| 664 assert(!llvm::isa<Constant>(Src)); |
| 665 const bool DestIsReg = Dest->hasReg(); |
| 666 const bool SrcIsReg = (SrcV && SrcV->hasReg()); |
| 667 |
| 668 // reg to reg |
| 669 if (DestIsReg && SrcIsReg) { |
| 670 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); |
| 671 Asm->move(getDest(), getSrc(0)); |
| 672 return; |
| 673 } |
| 674 llvm_unreachable("Not yet implemented"); |
| 675 } |
| 676 |
| 677 void InstMIPS32Mov::dump(const Cfg *Func) const { |
| 678 if (!BuildDefs::dump()) |
| 679 return; |
| 680 assert(getSrcSize() == 1 || getSrcSize() == 2); |
| 681 Ostream &Str = Func->getContext()->getStrDump(); |
| 682 Variable *Dest = getDest(); |
| 683 Variable *DestHi = getDestHi(); |
| 684 Dest->dump(Func); |
| 685 if (DestHi) { |
| 686 Str << ", "; |
| 687 DestHi->dump(Func); |
| 688 } |
| 689 dumpOpcode(Str, " = mov", getDest()->getType()); |
| 690 Str << " "; |
| 691 dumpSources(Func); |
| 692 } |
| 693 |
| 755 template <> void InstMIPS32Abs_d::emitIAS(const Cfg *Func) const { | 694 template <> void InstMIPS32Abs_d::emitIAS(const Cfg *Func) const { |
| 756 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); | 695 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); |
| 757 Asm->abs_d(getDest(), getSrc(0)); | 696 Asm->abs_d(getDest(), getSrc(0)); |
| 758 } | 697 } |
| 759 | 698 |
| 760 template <> void InstMIPS32Abs_s::emitIAS(const Cfg *Func) const { | 699 template <> void InstMIPS32Abs_s::emitIAS(const Cfg *Func) const { |
| 761 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); | 700 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); |
| 762 Asm->abs_s(getDest(), getSrc(0)); | 701 Asm->abs_s(getDest(), getSrc(0)); |
| 763 } | 702 } |
| 764 | 703 |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1207 Asm->xor_(getDest(), getSrc(0), getSrc(1)); | 1146 Asm->xor_(getDest(), getSrc(0), getSrc(1)); |
| 1208 } | 1147 } |
| 1209 | 1148 |
| 1210 template <> void InstMIPS32Xori::emitIAS(const Cfg *Func) const { | 1149 template <> void InstMIPS32Xori::emitIAS(const Cfg *Func) const { |
| 1211 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); | 1150 auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); |
| 1212 Asm->xori(getDest(), getSrc(0), Imm); | 1151 Asm->xori(getDest(), getSrc(0), Imm); |
| 1213 } | 1152 } |
| 1214 | 1153 |
| 1215 } // end of namespace MIPS32 | 1154 } // end of namespace MIPS32 |
| 1216 } // end of namespace Ice | 1155 } // end of namespace Ice |
| OLD | NEW |