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 |