| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 auto ClassNum = static_cast<RegClassMIPS32>(C); | 76 auto ClassNum = static_cast<RegClassMIPS32>(C); |
| 77 assert(ClassNum < RCMIPS32_NUM); | 77 assert(ClassNum < RCMIPS32_NUM); |
| 78 switch (ClassNum) { | 78 switch (ClassNum) { |
| 79 default: | 79 default: |
| 80 assert(C < RC_Target); | 80 assert(C < RC_Target); |
| 81 return regClassString(C); | 81 return regClassString(C); |
| 82 // Add handling of new register classes below. | 82 // Add handling of new register classes below. |
| 83 } | 83 } |
| 84 } | 84 } |
| 85 | 85 |
| 86 // Value is in bytes. Return Value adjusted to the next highest multiple of the |
| 87 // stack alignment. |
| 88 uint32_t applyStackAlignment(uint32_t Value) { |
| 89 return Utils::applyAlignment(Value, MIPS32_STACK_ALIGNMENT_BYTES); |
| 90 } |
| 91 |
| 86 } // end of anonymous namespace | 92 } // end of anonymous namespace |
| 87 | 93 |
| 88 TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {} | 94 TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {} |
| 89 | 95 |
| 90 void TargetMIPS32::staticInit(GlobalContext *Ctx) { | 96 void TargetMIPS32::staticInit(GlobalContext *Ctx) { |
| 91 (void)Ctx; | 97 (void)Ctx; |
| 92 RegNumT::setLimit(RegMIPS32::Reg_NUM); | 98 RegNumT::setLimit(RegMIPS32::Reg_NUM); |
| 93 SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM); | 99 SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM); |
| 94 SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM); | 100 SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM); |
| 95 SmallBitVector Float32Registers(RegMIPS32::Reg_NUM); | 101 SmallBitVector Float32Registers(RegMIPS32::Reg_NUM); |
| (...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 case InstIcmp::Sle: { | 1083 case InstIcmp::Sle: { |
| 1078 _slt(DestT, Src1R, Src0R); | 1084 _slt(DestT, Src1R, Src0R); |
| 1079 _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); | 1085 _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
| 1080 break; | 1086 break; |
| 1081 } | 1087 } |
| 1082 } | 1088 } |
| 1083 } | 1089 } |
| 1084 } | 1090 } |
| 1085 | 1091 |
| 1086 void TargetMIPS32::lowerCall(const InstCall *Instr) { | 1092 void TargetMIPS32::lowerCall(const InstCall *Instr) { |
| 1087 // TODO(rkotler): assign arguments to registers and stack. Also reserve stack. | 1093 NeedsStackAlignment = true; |
| 1088 if (Instr->getNumArgs()) { | 1094 |
| 1089 UnimplementedLoweringError(this, Instr); | 1095 // Assign arguments to registers and stack. Also reserve stack. |
| 1090 return; | 1096 TargetMIPS32::CallingConv CC; |
| 1097 |
| 1098 // Pair of Arg Operand -> GPR number assignments. |
| 1099 llvm::SmallVector<std::pair<Operand *, RegNumT>, MIPS32_MAX_GPR_ARG> GPRArgs; |
| 1100 llvm::SmallVector<std::pair<Operand *, RegNumT>, MIPS32_MAX_FP_ARG> FPArgs; |
| 1101 // Pair of Arg Operand -> stack offset. |
| 1102 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs; |
| 1103 size_t ParameterAreaSizeBytes = 16; |
| 1104 |
| 1105 // Classify each argument operand according to the location where the |
| 1106 // argument is passed. |
| 1107 |
| 1108 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { |
| 1109 Operand *Arg = legalizeUndef(Instr->getArg(i)); |
| 1110 const Type Ty = Arg->getType(); |
| 1111 bool InReg = false; |
| 1112 RegNumT Reg; |
| 1113 |
| 1114 InReg = CC.argInReg(Ty, i, &Reg); |
| 1115 |
| 1116 if (!InReg) { |
| 1117 ParameterAreaSizeBytes = |
| 1118 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); |
| 1119 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); |
| 1120 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty); |
| 1121 continue; |
| 1122 } |
| 1123 |
| 1124 if (Ty == IceType_i64) { |
| 1125 Operand *Lo = loOperand(Arg); |
| 1126 Operand *Hi = hiOperand(Arg); |
| 1127 GPRArgs.push_back( |
| 1128 std::make_pair(Lo, RegMIPS32::getI64PairFirstGPRNum(Reg))); |
| 1129 GPRArgs.push_back( |
| 1130 std::make_pair(Hi, RegMIPS32::getI64PairSecondGPRNum(Reg))); |
| 1131 } else if (isScalarIntegerType(Ty)) { |
| 1132 GPRArgs.push_back(std::make_pair(Arg, Reg)); |
| 1133 } else { |
| 1134 FPArgs.push_back(std::make_pair(Arg, Reg)); |
| 1135 } |
| 1091 } | 1136 } |
| 1137 |
| 1138 // Adjust the parameter area so that the stack is aligned. It is assumed that |
| 1139 // the stack is already aligned at the start of the calling sequence. |
| 1140 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes); |
| 1141 |
| 1142 // Copy arguments that are passed on the stack to the appropriate stack |
| 1143 // locations. |
| 1144 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 1145 for (auto &StackArg : StackArgs) { |
| 1146 ConstantInteger32 *Loc = |
| 1147 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackArg.second)); |
| 1148 Type Ty = StackArg.first->getType(); |
| 1149 OperandMIPS32Mem *Addr; |
| 1150 constexpr bool SignExt = false; |
| 1151 if (OperandMIPS32Mem::canHoldOffset(Ty, SignExt, StackArg.second)) { |
| 1152 Addr = OperandMIPS32Mem::create(Func, Ty, SP, Loc); |
| 1153 } else { |
| 1154 Variable *NewBase = Func->makeVariable(SP->getType()); |
| 1155 lowerArithmetic( |
| 1156 InstArithmetic::create(Func, InstArithmetic::Add, NewBase, SP, Loc)); |
| 1157 Addr = formMemoryOperand(NewBase, Ty); |
| 1158 } |
| 1159 lowerStore(InstStore::create(Func, StackArg.first, Addr)); |
| 1160 } |
| 1161 |
| 1092 // Generate the call instruction. Assign its result to a temporary with high | 1162 // Generate the call instruction. Assign its result to a temporary with high |
| 1093 // register allocation weight. | 1163 // register allocation weight. |
| 1094 Variable *Dest = Instr->getDest(); | 1164 Variable *Dest = Instr->getDest(); |
| 1095 // ReturnReg doubles as ReturnRegLo as necessary. | 1165 // ReturnReg doubles as ReturnRegLo as necessary. |
| 1096 Variable *ReturnReg = nullptr; | 1166 Variable *ReturnReg = nullptr; |
| 1097 Variable *ReturnRegHi = nullptr; | 1167 Variable *ReturnRegHi = nullptr; |
| 1098 if (Dest) { | 1168 if (Dest) { |
| 1099 switch (Dest->getType()) { | 1169 switch (Dest->getType()) { |
| 1100 case IceType_NUM: | 1170 case IceType_NUM: |
| 1101 llvm_unreachable("Invalid Call dest type"); | 1171 llvm_unreachable("Invalid Call dest type"); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1127 return; | 1197 return; |
| 1128 } | 1198 } |
| 1129 } | 1199 } |
| 1130 Operand *CallTarget = Instr->getCallTarget(); | 1200 Operand *CallTarget = Instr->getCallTarget(); |
| 1131 // Allow ConstantRelocatable to be left alone as a direct call, | 1201 // Allow ConstantRelocatable to be left alone as a direct call, |
| 1132 // but force other constants like ConstantInteger32 to be in | 1202 // but force other constants like ConstantInteger32 to be in |
| 1133 // a register and make it an indirect call. | 1203 // a register and make it an indirect call. |
| 1134 if (!llvm::isa<ConstantRelocatable>(CallTarget)) { | 1204 if (!llvm::isa<ConstantRelocatable>(CallTarget)) { |
| 1135 CallTarget = legalize(CallTarget, Legal_Reg); | 1205 CallTarget = legalize(CallTarget, Legal_Reg); |
| 1136 } | 1206 } |
| 1207 |
| 1208 // Copy arguments to be passed in registers to the appropriate registers. |
| 1209 CfgVector<Variable *> RegArgs; |
| 1210 for (auto &FPArg : FPArgs) { |
| 1211 RegArgs.emplace_back(legalizeToReg(FPArg.first, FPArg.second)); |
| 1212 } |
| 1213 for (auto &GPRArg : GPRArgs) { |
| 1214 RegArgs.emplace_back(legalizeToReg(GPRArg.first, GPRArg.second)); |
| 1215 } |
| 1216 |
| 1217 // Generate a FakeUse of register arguments so that they do not get dead code |
| 1218 // eliminated as a result of the FakeKill of scratch registers after the call. |
| 1219 // These fake-uses need to be placed here to avoid argument registers from |
| 1220 // being used during the legalizeToReg() calls above. |
| 1221 for (auto *RegArg : RegArgs) { |
| 1222 Context.insert<InstFakeUse>(RegArg); |
| 1223 } |
| 1224 |
| 1137 Inst *NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget); | 1225 Inst *NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget); |
| 1138 Context.insert(NewCall); | 1226 Context.insert(NewCall); |
| 1139 if (ReturnRegHi) | 1227 if (ReturnRegHi) |
| 1140 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); | 1228 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); |
| 1141 // Insert a register-kill pseudo instruction. | 1229 // Insert a register-kill pseudo instruction. |
| 1142 Context.insert(InstFakeKill::create(Func, NewCall)); | 1230 Context.insert(InstFakeKill::create(Func, NewCall)); |
| 1143 // Generate a FakeUse to keep the call live if necessary. | 1231 // Generate a FakeUse to keep the call live if necessary. |
| 1144 if (Instr->hasSideEffects() && ReturnReg) { | 1232 if (Instr->hasSideEffects() && ReturnReg) { |
| 1145 Context.insert<InstFakeDef>(ReturnReg); | 1233 Context.insert<InstFakeUse>(ReturnReg); |
| 1146 } | 1234 } |
| 1147 if (Dest == nullptr) | 1235 if (Dest == nullptr) |
| 1148 return; | 1236 return; |
| 1149 | 1237 |
| 1150 // Assign the result of the call to Dest. | 1238 // Assign the result of the call to Dest. |
| 1151 if (ReturnReg) { | 1239 if (ReturnReg) { |
| 1152 if (ReturnRegHi) { | 1240 if (ReturnRegHi) { |
| 1153 assert(Dest->getType() == IceType_i64); | 1241 assert(Dest->getType() == IceType_i64); |
| 1154 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); | 1242 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); |
| 1155 Variable *DestLo = Dest64On32->getLo(); | 1243 Variable *DestLo = Dest64On32->getLo(); |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1868 Str << "\t.set\t" | 1956 Str << "\t.set\t" |
| 1869 << "nomips16\n"; | 1957 << "nomips16\n"; |
| 1870 } | 1958 } |
| 1871 | 1959 |
| 1872 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 1960 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 1873 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 1961 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 1874 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 1962 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 1875 | 1963 |
| 1876 } // end of namespace MIPS32 | 1964 } // end of namespace MIPS32 |
| 1877 } // end of namespace Ice | 1965 } // end of namespace Ice |
| OLD | NEW |