Chromium Code Reviews| 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()); |
| 1098 (unsigned)RegNum <= RegMIPS32::Reg_A3) || | 1161 if (SrcTy == IceType_f32 && IsSrcGPReg == true) { |
| 1099 ((unsigned)RegNum >= RegMIPS32::Reg_A0A1 && | |
| 1100 (unsigned)RegNum <= RegMIPS32::Reg_A2A3); | |
| 1101 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: { |
|
obucinac
2016/09/13 17:49:01
Fptosi cast is covered by genTargetHelperCallSFor.
jaydeep.patil
2016/09/14 04:42:44
Done.
| |
| 2031 UnimplementedLoweringError(this, Instr); | 2087 if (Src0Ty == IceType_f32 && DestTy == IceType_i32) { |
| 2088 Variable *Src0R = legalizeToReg(Src0); | |
| 2089 Variable *FTmp = makeReg(IceType_f32); | |
| 2090 _trunc_w_s(FTmp, Src0R); | |
| 2091 _mov(Dest, FTmp); | |
| 2092 } else { | |
| 2093 UnimplementedLoweringError(this, Instr); | |
| 2094 } | |
| 2032 break; | 2095 break; |
| 2096 } | |
| 2033 case InstCast::Fptoui: | 2097 case InstCast::Fptoui: |
| 2034 UnimplementedLoweringError(this, Instr); | 2098 UnimplementedLoweringError(this, Instr); |
| 2035 break; | 2099 break; |
| 2036 case InstCast::Sitofp: | 2100 case InstCast::Sitofp: { |
|
obucinac
2016/09/13 17:49:01
Sitofp cast is covered by genTargetHelperCallSFor.
jaydeep.patil
2016/09/14 04:42:44
Done.
| |
| 2037 UnimplementedLoweringError(this, Instr); | 2101 if (Src0Ty == IceType_i32 && DestTy == IceType_f32) { |
| 2102 Variable *Src0R = legalizeToReg(Src0); | |
| 2103 Variable *FTmp1 = makeReg(IceType_f32); | |
| 2104 Variable *FTmp2 = makeReg(IceType_f32); | |
| 2105 _mov(FTmp1, Src0R); | |
| 2106 _cvt_s_w(FTmp2, FTmp1); | |
| 2107 _mov(Dest, FTmp2); | |
| 2108 } else { | |
| 2109 UnimplementedLoweringError(this, Instr); | |
| 2110 } | |
| 2038 break; | 2111 break; |
| 2112 } | |
| 2039 case InstCast::Uitofp: { | 2113 case InstCast::Uitofp: { |
| 2040 UnimplementedLoweringError(this, Instr); | 2114 UnimplementedLoweringError(this, Instr); |
| 2041 break; | 2115 break; |
| 2042 } | 2116 } |
| 2043 case InstCast::Bitcast: { | 2117 case InstCast::Bitcast: { |
| 2044 UnimplementedLoweringError(this, Instr); | 2118 UnimplementedLoweringError(this, Instr); |
| 2045 break; | 2119 break; |
| 2046 } | 2120 } |
| 2047 } | 2121 } |
| 2048 } | 2122 } |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2729 Str << "\t.set\t" | 2803 Str << "\t.set\t" |
| 2730 << "nomips16\n"; | 2804 << "nomips16\n"; |
| 2731 } | 2805 } |
| 2732 | 2806 |
| 2733 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 2807 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 2734 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 2808 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 2735 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 2809 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 2736 | 2810 |
| 2737 } // end of namespace MIPS32 | 2811 } // end of namespace MIPS32 |
| 2738 } // end of namespace Ice | 2812 } // end of namespace Ice |
| OLD | NEW |