OLD | NEW |
---|---|
1 // | 1 // |
2 // The Subzero Code Generator | 2 // The Subzero Code Generator |
3 // | 3 // |
4 // This file is distributed under the University of Illinois Open Source | 4 // This file is distributed under the University of Illinois Open Source |
5 // License. See LICENSE.TXT for details. | 5 // License. See LICENSE.TXT for details. |
6 // | 6 // |
7 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
8 /// | 8 /// |
9 /// \file | 9 /// \file |
10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost | 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost |
(...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1070 | 1070 |
1071 Operand *Src = MovInstr->getSrc(0); | 1071 Operand *Src = MovInstr->getSrc(0); |
1072 const Type SrcTy = Src->getType(); | 1072 const Type SrcTy = Src->getType(); |
1073 (void)SrcTy; | 1073 (void)SrcTy; |
1074 assert(SrcTy != IceType_i64); | 1074 assert(SrcTy != IceType_i64); |
1075 | 1075 |
1076 if (MovInstr->isMultiDest() || MovInstr->isMultiSource()) | 1076 if (MovInstr->isMultiDest() || MovInstr->isMultiSource()) |
1077 return; | 1077 return; |
1078 | 1078 |
1079 bool Legalized = false; | 1079 bool Legalized = false; |
1080 auto *SrcR = llvm::cast<Variable>(Src); | |
1081 if (Dest->hasReg() && SrcR->hasReg()) { | |
1082 // This might be a GP to/from FP move generated due to argument passing. | |
1083 // Use mtc1/mfc1 instead of mov.[s/d] if src and dst registers are of | |
1084 // different types. | |
1085 const bool IsDstGPR = RegMIPS32::isGPRReg(Dest->getRegNum()); | |
1086 const bool IsSrcGPR = RegMIPS32::isGPRReg(SrcR->getRegNum()); | |
1087 const RegNumT SRegNum = SrcR->getRegNum(); | |
1088 const RegNumT DRegNum = Dest->getRegNum(); | |
1089 if (IsDstGPR != IsSrcGPR) { | |
1090 if (IsDstGPR) { | |
1091 // Dest is GPR and SrcR is FPR. Use mfc1. | |
1092 if (typeWidthInBytes(Dest->getType()) == 8) { | |
1093 // Split it into two mfc1 instructions | |
1094 Variable *SrcGPRHi = Target->makeReg( | |
1095 IceType_f32, RegMIPS32::get64PairFirstRegNum(SRegNum)); | |
1096 Variable *SrcGPRLo = Target->makeReg( | |
1097 IceType_f32, RegMIPS32::get64PairSecondRegNum(SRegNum)); | |
1098 Variable *DstFPRHi = Target->makeReg( | |
1099 IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum)); | |
1100 Variable *DstFPRLo = Target->makeReg( | |
1101 IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum)); | |
1102 Target->_mov(DstFPRHi, SrcGPRLo); | |
1103 Target->_mov(DstFPRLo, SrcGPRHi); | |
1104 Legalized = true; | |
1105 } else { | |
1106 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum); | |
1107 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum); | |
1108 Target->_mov(DstFPR, SrcGPR); | |
1109 Legalized = true; | |
1110 } | |
1111 } else { | |
1112 // Dest is FPR and SrcR is GPR. Use mtc1. | |
1113 if (typeWidthInBytes(SrcR->getType()) == 8) { | |
1114 // Split it into two mtc1 instructions | |
1115 Variable *SrcGPRHi = Target->makeReg( | |
1116 IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); | |
1117 Variable *SrcGPRLo = Target->makeReg( | |
1118 IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); | |
1119 Variable *DstFPRHi = Target->makeReg( | |
1120 IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum)); | |
1121 Variable *DstFPRLo = Target->makeReg( | |
1122 IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum)); | |
1123 Target->_mov(DstFPRHi, SrcGPRLo); | |
1124 Target->_mov(DstFPRLo, SrcGPRHi); | |
1125 Legalized = true; | |
1126 } else { | |
1127 Variable *SrcGPR = Target->makeReg(IceType_i32, SRegNum); | |
1128 Variable *DstFPR = Target->makeReg(IceType_f32, DRegNum); | |
1129 Target->_mov(DstFPR, SrcGPR); | |
1130 Legalized = true; | |
1131 } | |
1132 } | |
1133 } | |
1134 if (Legalized) { | |
1135 if (MovInstr->isDestRedefined()) { | |
1136 Target->_set_dest_redefined(); | |
1137 } | |
1138 MovInstr->setDeleted(); | |
1139 return; | |
1140 } | |
1141 } | |
1142 | |
1080 if (!Dest->hasReg()) { | 1143 if (!Dest->hasReg()) { |
1081 auto *SrcR = llvm::cast<Variable>(Src); | 1144 auto *SrcR = llvm::cast<Variable>(Src); |
1082 assert(SrcR->hasReg()); | 1145 assert(SrcR->hasReg()); |
1083 assert(!SrcR->isRematerializable()); | 1146 assert(!SrcR->isRematerializable()); |
1084 const int32_t Offset = Dest->getStackOffset(); | 1147 const int32_t Offset = Dest->getStackOffset(); |
1085 | 1148 |
1086 // This is a _mov(Mem(), Variable), i.e., a store. | 1149 // This is a _mov(Mem(), Variable), i.e., a store. |
1087 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); | 1150 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); |
1088 | 1151 |
1089 OperandMIPS32Mem *Addr = OperandMIPS32Mem::create( | 1152 OperandMIPS32Mem *Addr = OperandMIPS32Mem::create( |
1090 Target->Func, DestTy, Base, | 1153 Target->Func, DestTy, Base, |
1091 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); | 1154 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); |
1092 | 1155 |
1093 // FP arguments are passed in GP reg if first argument is in GP. In this | 1156 // FP arguments are passed in GP reg if first argument is in GP. In this |
1094 // case type of the SrcR is still FP thus we need to explicitly generate sw | 1157 // case type of the SrcR is still FP thus we need to explicitly generate sw |
1095 // instead of swc1. | 1158 // instead of swc1. |
1096 const RegNumT RegNum = SrcR->getRegNum(); | 1159 const RegNumT RegNum = SrcR->getRegNum(); |
1097 const bool isSrcGPReg = ((unsigned)RegNum >= RegMIPS32::Reg_A0 && | 1160 const bool isSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
Jim Stichnoth
2016/09/07 15:39:31
capitalize IsSrcGPReg per LLVM coding style
jaydeep.patil
2016/09/13 06:18:36
Done.
| |
1098 (unsigned)RegNum <= RegMIPS32::Reg_A3) || | |
1099 ((unsigned)RegNum >= RegMIPS32::Reg_A0A1 && | |
1100 (unsigned)RegNum <= RegMIPS32::Reg_A2A3); | |
1101 if (SrcTy == IceType_f32 && isSrcGPReg == true) { | 1161 if (SrcTy == IceType_f32 && isSrcGPReg == true) { |
1102 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); | 1162 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); |
1103 Target->_sw(SrcGPR, Addr); | 1163 Target->_sw(SrcGPR, Addr); |
1104 } else if (SrcTy == IceType_f64 && isSrcGPReg == true) { | 1164 } else if (SrcTy == IceType_f64 && isSrcGPReg == true) { |
1105 Variable *SrcGPRHi, *SrcGPRLo; | 1165 Variable *SrcGPRHi = |
1106 if (RegNum == RegMIPS32::Reg_A0A1) { | 1166 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); |
1107 SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A0); | 1167 Variable *SrcGPRLo = Target->makeReg( |
1108 SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A1); | 1168 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
1109 } else { | |
1110 SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A2); | |
1111 SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A3); | |
1112 } | |
1113 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( | 1169 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( |
1114 Target->Func, DestTy, Base, | 1170 Target->Func, DestTy, Base, |
1115 llvm::cast<ConstantInteger32>( | 1171 llvm::cast<ConstantInteger32>( |
1116 Target->Ctx->getConstantInt32(Offset + 4))); | 1172 Target->Ctx->getConstantInt32(Offset + 4))); |
1117 Target->_sw(SrcGPRLo, Addr); | 1173 Target->_sw(SrcGPRLo, Addr); |
1118 Target->_sw(SrcGPRHi, AddrHi); | 1174 Target->_sw(SrcGPRHi, AddrHi); |
1119 } else { | 1175 } else { |
1120 Target->_sw(SrcR, Addr); | 1176 Target->_sw(SrcR, Addr); |
1121 } | 1177 } |
1122 | 1178 |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2020 } | 2076 } |
2021 case InstCast::Fptrunc: | 2077 case InstCast::Fptrunc: |
2022 // Use _cvt_d_s | 2078 // Use _cvt_d_s |
2023 UnimplementedLoweringError(this, Instr); | 2079 UnimplementedLoweringError(this, Instr); |
2024 break; | 2080 break; |
2025 case InstCast::Fpext: { | 2081 case InstCast::Fpext: { |
2026 // Use _cvt_s_d | 2082 // Use _cvt_s_d |
2027 UnimplementedLoweringError(this, Instr); | 2083 UnimplementedLoweringError(this, Instr); |
2028 break; | 2084 break; |
2029 } | 2085 } |
2030 case InstCast::Fptosi: | 2086 case InstCast::Fptosi: { |
2031 UnimplementedLoweringError(this, Instr); | 2087 if (Src0Ty == IceType_f32 && DestTy == IceType_i32) { |
2088 Variable *Src0R = legalizeToReg(Src0); | |
2089 Variable *FTmp1 = makeReg(IceType_f32); | |
2090 Variable *FTmp2 = makeReg(IceType_f32); | |
2091 _mov(FTmp1, Src0R); | |
Jim Stichnoth
2016/09/07 15:39:31
Is it really necessary to copy Src0R through a tem
jaydeep.patil
2016/09/13 06:18:36
Done.
| |
2092 _trunc_w_s(FTmp2, FTmp1); | |
2093 _mov(Dest, FTmp2); | |
2094 } else { | |
2095 UnimplementedLoweringError(this, Instr); | |
2096 } | |
2032 break; | 2097 break; |
2098 } | |
2033 case InstCast::Fptoui: | 2099 case InstCast::Fptoui: |
2034 UnimplementedLoweringError(this, Instr); | 2100 UnimplementedLoweringError(this, Instr); |
2035 break; | 2101 break; |
2036 case InstCast::Sitofp: | 2102 case InstCast::Sitofp: { |
2037 UnimplementedLoweringError(this, Instr); | 2103 if (Src0Ty == IceType_i32 && DestTy == IceType_f32) { |
2104 Variable *Src0R = legalizeToReg(Src0); | |
2105 Variable *FTmp1 = makeReg(IceType_f32); | |
2106 Variable *FTmp2 = makeReg(IceType_f32); | |
2107 _mov(FTmp1, Src0R); | |
2108 _cvt_s_w(FTmp2, FTmp1); | |
2109 _mov(Dest, FTmp2); | |
2110 } else { | |
2111 UnimplementedLoweringError(this, Instr); | |
2112 } | |
2038 break; | 2113 break; |
2114 } | |
2039 case InstCast::Uitofp: { | 2115 case InstCast::Uitofp: { |
2040 UnimplementedLoweringError(this, Instr); | 2116 UnimplementedLoweringError(this, Instr); |
2041 break; | 2117 break; |
2042 } | 2118 } |
2043 case InstCast::Bitcast: { | 2119 case InstCast::Bitcast: { |
2044 UnimplementedLoweringError(this, Instr); | 2120 UnimplementedLoweringError(this, Instr); |
2045 break; | 2121 break; |
2046 } | 2122 } |
2047 } | 2123 } |
2048 } | 2124 } |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2729 Str << "\t.set\t" | 2805 Str << "\t.set\t" |
2730 << "nomips16\n"; | 2806 << "nomips16\n"; |
2731 } | 2807 } |
2732 | 2808 |
2733 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 2809 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
2734 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 2810 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
2735 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 2811 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
2736 | 2812 |
2737 } // end of namespace MIPS32 | 2813 } // end of namespace MIPS32 |
2738 } // end of namespace Ice | 2814 } // end of namespace Ice |
OLD | NEW |