OLD | NEW |
---|---|
1 //===- subzero/src/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===// | 1 //===- subzero/src/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===// |
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 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
564 UsesFramePointer = true; | 564 UsesFramePointer = true; |
565 // Conservatively require the stack to be aligned. Some stack adjustment | 565 // Conservatively require the stack to be aligned. Some stack adjustment |
566 // operations implemented below assume that the stack is aligned before the | 566 // operations implemented below assume that the stack is aligned before the |
567 // alloca. All the alloca code ensures that the stack alignment is preserved | 567 // alloca. All the alloca code ensures that the stack alignment is preserved |
568 // after the alloca. The stack alignment restriction can be relaxed in some | 568 // after the alloca. The stack alignment restriction can be relaxed in some |
569 // cases. | 569 // cases. |
570 NeedsStackAlignment = true; | 570 NeedsStackAlignment = true; |
571 UnimplementedLoweringError(this, Inst); | 571 UnimplementedLoweringError(this, Inst); |
572 } | 572 } |
573 | 573 |
574 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Inst, | |
575 Variable *Dest, Operand *Src0, | |
576 Operand *Src1) { | |
577 InstArithmetic::OpKind Op = Inst->getOp(); | |
578 switch (Op) { | |
579 case InstArithmetic::Add: | |
580 case InstArithmetic::And: | |
581 case InstArithmetic::Or: | |
582 case InstArithmetic::Sub: | |
583 case InstArithmetic::Xor: | |
584 break; | |
585 default: | |
586 UnimplementedLoweringError(this, Inst); | |
587 return; | |
588 } | |
589 Src0 = legalizeUndef(Src0); | |
Jim Stichnoth
2016/01/30 17:03:28
Can this be removed? It's already being done in t
rkotlerimgtec
2016/01/30 23:48:30
Done.
| |
590 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); | |
591 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); | |
592 Operand *Src1Lo = legalize(loOperand(Src1), Legal_Reg); | |
593 Operand *Src1Hi = legalize(hiOperand(Src1), Legal_Reg); | |
594 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | |
595 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | |
596 | |
597 Variable *Src0LoR = legalizeToReg(Src0Lo); | |
Jim Stichnoth
2016/01/30 17:03:28
This can just be:
Variable *Src0LoR = legalizeT
rkotlerimgtec
2016/01/30 23:48:31
Done.
| |
598 Variable *Src1LoR = legalizeToReg(Src1Lo); | |
599 Variable *Src0HiR = legalizeToReg(Src0Hi); | |
600 Variable *Src1HiR = legalizeToReg(Src1Hi); | |
601 | |
602 switch (Op) { | |
603 case InstArithmetic::_num: | |
604 llvm::report_fatal_error("Unknown arithmetic operator"); | |
605 return; | |
606 case InstArithmetic::Add: { | |
607 Variable *T_Lo = makeReg(IceType_i32); | |
Jim Stichnoth
2016/01/30 17:03:28
This lowering sequence has a problem in that inval
rkotlerimgtec
2016/01/30 23:48:30
Done.
| |
608 Variable *T_Hi = makeReg(IceType_i32); | |
609 _addu(DestLo, Src0LoR, Src1LoR); | |
610 _sltu(T_Lo, DestLo, Src0LoR); | |
611 _addu(T_Hi, T_Lo, Src0HiR); | |
612 _addu(DestHi, Src1HiR, T_Hi); | |
613 return; | |
614 } | |
615 case InstArithmetic::And: { | |
616 _and(DestLo, Src0LoR, Src1LoR); | |
Jim Stichnoth
2016/01/30 17:03:28
Similar to above, you need to ensure the _and dest
rkotlerimgtec
2016/01/30 23:48:30
Done.
rkotlerimgtec
2016/01/30 23:48:31
Done.
| |
617 _and(DestHi, Src0HiR, Src1HiR); | |
618 return; | |
619 } | |
620 case InstArithmetic::Sub: { | |
621 Variable *T_Lo = makeReg(IceType_i32); | |
Jim Stichnoth
2016/01/30 17:03:29
Similar comment as for Add, maybe calling it "Borr
rkotlerimgtec
2016/01/30 23:48:30
Done.
| |
622 Variable *T_Hi = makeReg(IceType_i32); | |
623 _subu(DestLo, Src0LoR, Src1LoR); | |
624 _sltu(T_Lo, Src0LoR, Src1LoR); | |
625 _addu(T_Hi, T_Lo, Src1HiR); | |
626 _subu(DestHi, Src0HiR, T_Hi); | |
627 return; | |
628 } | |
629 case InstArithmetic::Or: { | |
630 _or(DestLo, Src0LoR, Src1LoR); | |
631 _or(DestHi, Src0HiR, Src1HiR); | |
632 return; | |
633 } | |
634 case InstArithmetic::Xor: { | |
635 _xor(DestLo, Src0LoR, Src1LoR); | |
636 _xor(DestHi, Src0HiR, Src1HiR); | |
637 return; | |
638 } | |
639 default: | |
640 UnimplementedLoweringError(this, Inst); | |
641 return; | |
642 //} | |
Jim Stichnoth
2016/01/30 17:03:29
remove this
rkotlerimgtec
2016/01/30 23:48:30
Done.
| |
643 } | |
644 } | |
645 | |
574 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { | 646 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { |
575 Variable *Dest = Inst->getDest(); | 647 Variable *Dest = Inst->getDest(); |
576 // We need to signal all the UnimplementedLoweringError errors before any | 648 // We need to signal all the UnimplementedLoweringError errors before any |
577 // legalization into new variables, otherwise Om1 register allocation may fail | 649 // legalization into new variables, otherwise Om1 register allocation may fail |
578 // when it sees variables that are defined but not used. | 650 // when it sees variables that are defined but not used. |
579 if (Dest->getType() == IceType_i64) { | 651 Type DestTy = Dest->getType(); |
580 UnimplementedLoweringError(this, Inst); | 652 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); |
653 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); | |
654 if (DestTy == IceType_i64) { | |
655 lowerInt64Arithmetic(Inst, Inst->getDest(), Src0, Src1); | |
581 return; | 656 return; |
582 } | 657 } |
583 if (isVectorType(Dest->getType())) { | 658 if (isVectorType(Dest->getType())) { |
584 UnimplementedLoweringError(this, Inst); | 659 UnimplementedLoweringError(this, Inst); |
585 return; | 660 return; |
586 } | 661 } |
587 switch (Inst->getOp()) { | 662 switch (Inst->getOp()) { |
588 default: | 663 default: |
589 break; | 664 break; |
590 case InstArithmetic::Shl: | 665 case InstArithmetic::Shl: |
591 case InstArithmetic::Lshr: | 666 case InstArithmetic::Lshr: |
592 case InstArithmetic::Ashr: | 667 case InstArithmetic::Ashr: |
593 case InstArithmetic::Udiv: | 668 case InstArithmetic::Udiv: |
594 case InstArithmetic::Sdiv: | 669 case InstArithmetic::Sdiv: |
595 case InstArithmetic::Urem: | 670 case InstArithmetic::Urem: |
596 case InstArithmetic::Srem: | 671 case InstArithmetic::Srem: |
597 case InstArithmetic::Fadd: | 672 case InstArithmetic::Fadd: |
598 case InstArithmetic::Fsub: | 673 case InstArithmetic::Fsub: |
599 case InstArithmetic::Fmul: | 674 case InstArithmetic::Fmul: |
600 case InstArithmetic::Fdiv: | 675 case InstArithmetic::Fdiv: |
601 case InstArithmetic::Frem: | 676 case InstArithmetic::Frem: |
602 UnimplementedLoweringError(this, Inst); | 677 UnimplementedLoweringError(this, Inst); |
603 return; | 678 return; |
604 } | 679 } |
605 | 680 |
606 // At this point Dest->getType() is non-i64 scalar | 681 // At this point Dest->getType() is non-i64 scalar |
607 | 682 |
608 Variable *T = makeReg(Dest->getType()); | 683 Variable *T = makeReg(Dest->getType()); |
609 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); | |
610 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); | |
611 Variable *Src0R = legalizeToReg(Src0); | 684 Variable *Src0R = legalizeToReg(Src0); |
612 Variable *Src1R = legalizeToReg(Src1); | 685 Variable *Src1R = legalizeToReg(Src1); |
613 | 686 |
614 switch (Inst->getOp()) { | 687 switch (Inst->getOp()) { |
615 case InstArithmetic::_num: | 688 case InstArithmetic::_num: |
616 break; | 689 break; |
617 case InstArithmetic::Add: | 690 case InstArithmetic::Add: |
618 _add(T, Src0R, Src1R); | 691 _add(T, Src0R, Src1R); |
619 _mov(Dest, T); | 692 _mov(Dest, T); |
620 return; | 693 return; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
657 break; | 730 break; |
658 case InstArithmetic::Fsub: | 731 case InstArithmetic::Fsub: |
659 break; | 732 break; |
660 case InstArithmetic::Fmul: | 733 case InstArithmetic::Fmul: |
661 break; | 734 break; |
662 case InstArithmetic::Fdiv: | 735 case InstArithmetic::Fdiv: |
663 break; | 736 break; |
664 case InstArithmetic::Frem: | 737 case InstArithmetic::Frem: |
665 break; | 738 break; |
666 } | 739 } |
740 UnimplementedLoweringError(this, Inst); | |
667 } | 741 } |
668 | 742 |
669 void TargetMIPS32::lowerAssign(const InstAssign *Inst) { | 743 void TargetMIPS32::lowerAssign(const InstAssign *Inst) { |
670 Variable *Dest = Inst->getDest(); | 744 Variable *Dest = Inst->getDest(); |
671 Operand *Src0 = Inst->getSrc(0); | 745 Operand *Src0 = Inst->getSrc(0); |
672 assert(Dest->getType() == Src0->getType()); | 746 assert(Dest->getType() == Src0->getType()); |
673 if (Dest->getType() == IceType_i64) { | 747 if (Dest->getType() == IceType_i64) { |
674 Src0 = legalizeUndef(Src0); | 748 Src0 = legalizeUndef(Src0); |
675 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); | 749 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); |
676 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); | 750 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); |
(...skipping 24 matching lines...) Expand all Loading... | |
701 } else { | 775 } else { |
702 _mov(Dest, SrcR); | 776 _mov(Dest, SrcR); |
703 } | 777 } |
704 } | 778 } |
705 } | 779 } |
706 | 780 |
707 void TargetMIPS32::lowerBr(const InstBr *Inst) { | 781 void TargetMIPS32::lowerBr(const InstBr *Inst) { |
708 UnimplementedLoweringError(this, Inst); | 782 UnimplementedLoweringError(this, Inst); |
709 } | 783 } |
710 | 784 |
711 void TargetMIPS32::lowerCall(const InstCall *Inst) { | 785 void TargetMIPS32::lowerCall(const InstCall *Instr) { |
712 UnimplementedLoweringError(this, Inst); | 786 // TODO(jvoung): assign arguments to registers and stack. Also reserve stack. |
Jim Stichnoth
2016/01/30 17:03:28
Don't add jvoung to a TODO. :)
rkotlerimgtec
2016/01/30 23:48:31
Done.
| |
787 if (Instr->getNumArgs()) { | |
788 UnimplementedLoweringError(this, Instr); | |
789 return; | |
790 } | |
791 // Generate the call instruction. Assign its result to a temporary | |
Jim Stichnoth
2016/01/30 17:03:28
reflow to 80-col
rkotlerimgtec
2016/01/30 23:48:31
Done.
| |
792 // with high register allocation weight. | |
793 Variable *Dest = Instr->getDest(); | |
794 // ReturnReg doubles as ReturnRegLo as necessary. | |
795 Variable *ReturnReg = nullptr; | |
796 Variable *ReturnRegHi = nullptr; | |
797 if (Dest) { | |
798 switch (Dest->getType()) { | |
799 case IceType_NUM: | |
800 llvm_unreachable("Invalid Call dest type"); | |
801 return; | |
802 case IceType_void: | |
803 break; | |
804 case IceType_i1: | |
805 case IceType_i8: | |
806 case IceType_i16: | |
807 case IceType_i32: | |
808 ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0); | |
809 break; | |
810 case IceType_i64: | |
811 ReturnReg = makeReg(IceType_i32, RegMIPS32::Reg_V0); | |
812 ReturnRegHi = makeReg(IceType_i32, RegMIPS32::Reg_V1); | |
813 break; | |
814 case IceType_f32: | |
815 case IceType_f64: | |
816 UnimplementedLoweringError(this, Instr); | |
817 return; | |
818 case IceType_v4i1: | |
819 case IceType_v8i1: | |
820 case IceType_v16i1: | |
821 case IceType_v16i8: | |
822 case IceType_v8i16: | |
823 case IceType_v4i32: | |
824 case IceType_v4f32: | |
825 UnimplementedLoweringError(this, Instr); | |
826 return; | |
827 } | |
828 } | |
829 Operand *CallTarget = Instr->getCallTarget(); | |
830 // Allow ConstantRelocatable to be left alone as a direct call, | |
831 // but force other constants like ConstantInteger32 to be in | |
832 // a register and make it an indirect call. | |
833 if (!llvm::isa<ConstantRelocatable>(CallTarget)) { | |
834 CallTarget = legalize(CallTarget, Legal_Reg); | |
835 } | |
836 Inst *NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget); | |
837 Context.insert(NewCall); | |
838 if (ReturnRegHi) | |
839 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); | |
840 // Insert a register-kill pseudo instruction. | |
841 Context.insert(InstFakeKill::create(Func, NewCall)); | |
842 // Generate a FakeUse to keep the call live if necessary. | |
843 if (Instr->hasSideEffects() && ReturnReg) { | |
844 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); | |
845 Context.insert(FakeUse); | |
846 } | |
847 if (!Dest) | |
Jim Stichnoth
2016/01/30 17:03:28
Dest == nullptr
rkotlerimgtec
2016/01/30 23:48:31
Done.
| |
848 return; | |
849 | |
850 // Assign the result of the call to Dest. | |
851 if (ReturnReg) { | |
852 if (ReturnRegHi) { | |
853 assert(Dest->getType() == IceType_i64); | |
854 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); | |
855 Variable *DestLo = Dest64On32->getLo(); | |
856 Variable *DestHi = Dest64On32->getHi(); | |
857 _mov(DestLo, ReturnReg); | |
858 _mov(DestHi, ReturnRegHi); | |
859 } else { | |
860 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 || | |
861 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 || | |
862 isVectorType(Dest->getType())); | |
863 if (isFloatingType(Dest->getType()) || isVectorType(Dest->getType())) { | |
864 UnimplementedLoweringError(this, Instr); | |
865 return; | |
866 } else { | |
867 _mov(Dest, ReturnReg); | |
868 } | |
869 } | |
870 } | |
871 UnimplementedLoweringError(this, Instr); | |
713 } | 872 } |
714 | 873 |
715 void TargetMIPS32::lowerCast(const InstCast *Inst) { | 874 void TargetMIPS32::lowerCast(const InstCast *Inst) { |
716 InstCast::OpKind CastKind = Inst->getCastKind(); | 875 InstCast::OpKind CastKind = Inst->getCastKind(); |
717 switch (CastKind) { | 876 switch (CastKind) { |
718 default: | 877 default: |
719 Func->setError("Cast type not supported"); | 878 Func->setError("Cast type not supported"); |
720 return; | 879 return; |
721 case InstCast::Sext: { | 880 case InstCast::Sext: { |
722 UnimplementedLoweringError(this, Inst); | 881 UnimplementedLoweringError(this, Inst); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
975 // since loOperand() and hiOperand() don't expect Undef input. | 1134 // since loOperand() and hiOperand() don't expect Undef input. |
976 void TargetMIPS32::prelowerPhis() { | 1135 void TargetMIPS32::prelowerPhis() { |
977 PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func); | 1136 PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func); |
978 } | 1137 } |
979 | 1138 |
980 void TargetMIPS32::postLower() { | 1139 void TargetMIPS32::postLower() { |
981 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 1140 if (Ctx->getFlags().getOptLevel() == Opt_m1) |
982 return; | 1141 return; |
983 // Find two-address non-SSA instructions where Dest==Src0, and set the | 1142 // Find two-address non-SSA instructions where Dest==Src0, and set the |
984 // IsDestRedefined flag to keep liveness analysis consistent. | 1143 // IsDestRedefined flag to keep liveness analysis consistent. |
985 UnimplementedError(Func->getContext()->getFlags()); | 1144 UnimplementedError(Func->getContext()->getFlags()); |
Jim Stichnoth
2016/01/30 17:03:29
Remove this line, and replace it with "markRedefin
| |
986 } | 1145 } |
987 | 1146 |
988 void TargetMIPS32::makeRandomRegisterPermutation( | 1147 void TargetMIPS32::makeRandomRegisterPermutation( |
989 llvm::SmallVectorImpl<int32_t> &Permutation, | 1148 llvm::SmallVectorImpl<int32_t> &Permutation, |
990 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { | 1149 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { |
991 (void)Permutation; | 1150 (void)Permutation; |
992 (void)ExcludeRegisters; | 1151 (void)ExcludeRegisters; |
993 (void)Salt; | 1152 (void)Salt; |
994 UnimplementedError(Func->getContext()->getFlags()); | 1153 UnimplementedError(Func->getContext()->getFlags()); |
995 } | 1154 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1080 // if a Flexible second operand is allowed. We need to know the exact | 1239 // if a Flexible second operand is allowed. We need to know the exact |
1081 // value, so that rules out relocatable constants. | 1240 // value, so that rules out relocatable constants. |
1082 // Also try the inverse and use MVN if possible. | 1241 // Also try the inverse and use MVN if possible. |
1083 // Do a movw/movt to a register. | 1242 // Do a movw/movt to a register. |
1084 Variable *Reg; | 1243 Variable *Reg; |
1085 if (RegNum == Variable::NoRegister) | 1244 if (RegNum == Variable::NoRegister) |
1086 Reg = makeReg(Ty, RegNum); | 1245 Reg = makeReg(Ty, RegNum); |
1087 else | 1246 else |
1088 Reg = getPhysicalRegister(RegNum); | 1247 Reg = getPhysicalRegister(RegNum); |
1089 if (isInt<16>(int32_t(Value))) { | 1248 if (isInt<16>(int32_t(Value))) { |
1090 _addiu(Reg, getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty), Value); | 1249 //_addiu(Reg, getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty), Value); |
Jim Stichnoth
2016/01/30 17:03:28
remove this
rkotlerimgtec
2016/01/30 23:48:31
Done.
| |
1250 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); | |
1251 Context.insert<InstFakeDef>(Zero); | |
1252 _addiu(Reg, Zero, Value); | |
1091 } else { | 1253 } else { |
1092 uint32_t UpperBits = (Value >> 16) & 0xFFFF; | 1254 uint32_t UpperBits = (Value >> 16) & 0xFFFF; |
1093 (void)UpperBits; | 1255 (void)UpperBits; |
1094 uint32_t LowerBits = Value & 0xFFFF; | 1256 uint32_t LowerBits = Value & 0xFFFF; |
1095 Variable *TReg = makeReg(Ty, RegNum); | 1257 Variable *TReg = makeReg(Ty, RegNum); |
1096 _lui(TReg, UpperBits); | 1258 _lui(TReg, UpperBits); |
1097 _ori(Reg, TReg, LowerBits); | 1259 _ori(Reg, TReg, LowerBits); |
1098 } | 1260 } |
1099 return Reg; | 1261 return Reg; |
1100 } | 1262 } |
(...skipping 26 matching lines...) Expand all Loading... | |
1127 Str << "\t.set\t" | 1289 Str << "\t.set\t" |
1128 << "nomips16\n"; | 1290 << "nomips16\n"; |
1129 } | 1291 } |
1130 | 1292 |
1131 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 1293 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
1132 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 1294 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
1133 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 1295 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
1134 | 1296 |
1135 } // end of namespace MIPS32 | 1297 } // end of namespace MIPS32 |
1136 } // end of namespace Ice | 1298 } // end of namespace Ice |
OLD | NEW |