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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 | 214 |
| 215 uint32_t TargetMIPS32::getStackAlignment() const { | 215 uint32_t TargetMIPS32::getStackAlignment() const { |
| 216 return MIPS32_STACK_ALIGNMENT_BYTES; | 216 return MIPS32_STACK_ALIGNMENT_BYTES; |
| 217 } | 217 } |
| 218 | 218 |
| 219 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { | 219 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { |
| 220 constexpr bool NoTailCall = false; | 220 constexpr bool NoTailCall = false; |
| 221 constexpr bool IsTargetHelperCall = true; | 221 constexpr bool IsTargetHelperCall = true; |
| 222 | 222 |
|
Jim Stichnoth
2016/10/14 13:43:37
Would be nice to factor out Dest queries to the to
jaydeep.patil
2016/10/15 03:47:57
Done.
| |
| 223 switch (Instr->getKind()) { | 223 switch (Instr->getKind()) { |
| 224 default: | 224 default: |
| 225 return; | 225 return; |
| 226 case Inst::Select: { | |
| 227 Variable *Dest = Instr->getDest(); | |
| 228 if (isVectorType(Dest->getType())) { | |
| 229 Operand *SrcT = llvm::cast<InstSelect>(Instr)->getTrueOperand(); | |
| 230 Operand *SrcF = llvm::cast<InstSelect>(Instr)->getFalseOperand(); | |
| 231 Operand *Cond = llvm::cast<InstSelect>(Instr)->getCondition(); | |
| 232 Variable *T = Func->makeVariable(Dest->getType()); | |
| 233 auto *Undef = ConstantUndef::create(Ctx, Dest->getType()); | |
| 234 Context.insert<InstAssign>(T, Undef); | |
| 235 auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); | |
|
Jim Stichnoth
2016/10/14 13:43:37
Use llvm::cast<> since the next statement assumes
jaydeep.patil
2016/10/15 03:47:57
Done.
| |
| 236 VarVecOn32->initVecElement(Func); | |
| 237 for (SizeT I = 0; I < typeNumElements(Dest->getType()); ++I) { | |
| 238 auto *Index = Ctx->getConstantInt32(I); | |
| 239 auto *OpC = Func->makeVariable(typeElementType(Cond->getType())); | |
| 240 Context.insert<InstExtractElement>(OpC, Cond, Index); | |
| 241 auto *OpT = Func->makeVariable(typeElementType(T->getType())); | |
|
Jim Stichnoth
2016/10/14 13:43:37
I would use DestTy instead of T->getType() just to
jaydeep.patil
2016/10/15 03:47:56
Done.
| |
| 242 Context.insert<InstExtractElement>(OpT, SrcT, Index); | |
| 243 auto *OpF = Func->makeVariable(typeElementType(T->getType())); | |
| 244 Context.insert<InstExtractElement>(OpF, SrcF, Index); | |
| 245 auto *Dst = Func->makeVariable(typeElementType(Dest->getType())); | |
| 246 Variable *DestT = Func->makeVariable(Dest->getType()); | |
| 247 Context.insert<InstSelect>(Dst, OpC, OpT, OpF); | |
| 248 Context.insert<InstInsertElement>(DestT, T, Dst, Index); | |
| 249 T = DestT; | |
| 250 } | |
| 251 Context.insert<InstAssign>(Dest, T); | |
| 252 Instr->setDeleted(); | |
| 253 } | |
| 254 return; | |
| 255 } | |
| 256 case Inst::Fcmp: { | |
| 257 Variable *Dest = Instr->getDest(); | |
| 258 if (isVectorType(Dest->getType())) { | |
| 259 InstFcmp::FCond Cond = llvm::cast<InstFcmp>(Instr)->getCondition(); | |
| 260 Operand *Src0 = Instr->getSrc(0); | |
| 261 Operand *Src1 = Instr->getSrc(1); | |
| 262 Variable *T = Func->makeVariable(IceType_v4f32); | |
| 263 auto *Undef = ConstantUndef::create(Ctx, IceType_v4f32); | |
| 264 Context.insert<InstAssign>(T, Undef); | |
| 265 auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); | |
| 266 VarVecOn32->initVecElement(Func); | |
| 267 for (SizeT I = 0; I < typeNumElements(IceType_v4f32); ++I) { | |
| 268 auto *Index = Ctx->getConstantInt32(I); | |
| 269 auto *Op0 = Func->makeVariable(IceType_f32); | |
| 270 Context.insert<InstExtractElement>(Op0, Src0, Index); | |
| 271 auto *Op1 = Func->makeVariable(IceType_f32); | |
| 272 Context.insert<InstExtractElement>(Op1, Src1, Index); | |
| 273 auto *Dst = Func->makeVariable(IceType_f32); | |
| 274 Variable *DestT = Func->makeVariable(IceType_v4f32); | |
| 275 Context.insert<InstFcmp>(Cond, Dst, Op0, Op1); | |
| 276 Context.insert<InstInsertElement>(DestT, T, Dst, Index); | |
| 277 T = DestT; | |
| 278 } | |
| 279 Context.insert<InstAssign>(Dest, T); | |
| 280 Instr->setDeleted(); | |
| 281 } | |
| 282 return; | |
| 283 } | |
| 284 case Inst::Icmp: { | |
| 285 Variable *Dest = Instr->getDest(); | |
| 286 const Type DetType = Dest->getType(); | |
| 287 if (isVectorType(DetType)) { | |
| 288 InstIcmp::ICond Cond = llvm::cast<InstIcmp>(Instr)->getCondition(); | |
| 289 Operand *Src0 = Instr->getSrc(0); | |
| 290 Operand *Src1 = Instr->getSrc(1); | |
| 291 const Type SrcType = Src0->getType(); | |
| 292 Variable *T = Func->makeVariable(DetType); | |
| 293 auto *Undef = ConstantUndef::create(Ctx, DetType); | |
| 294 Context.insert<InstAssign>(T, Undef); | |
| 295 auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); | |
| 296 VarVecOn32->initVecElement(Func); | |
| 297 for (SizeT I = 0; I < typeNumElements(SrcType); ++I) { | |
| 298 auto *Index = Ctx->getConstantInt32(I); | |
| 299 auto *Op0 = Func->makeVariable(typeElementType(SrcType)); | |
| 300 Context.insert<InstExtractElement>(Op0, Src0, Index); | |
| 301 auto *Op1 = Func->makeVariable(typeElementType(SrcType)); | |
| 302 Context.insert<InstExtractElement>(Op1, Src1, Index); | |
| 303 auto *Dst = Func->makeVariable(typeElementType(DetType)); | |
| 304 Variable *DestT = Func->makeVariable(DetType); | |
| 305 Context.insert<InstIcmp>(Cond, Dst, Op0, Op1); | |
| 306 Context.insert<InstInsertElement>(DestT, T, Dst, Index); | |
| 307 T = DestT; | |
| 308 } | |
| 309 Context.insert<InstAssign>(Dest, T); | |
| 310 Instr->setDeleted(); | |
| 311 } | |
| 312 return; | |
| 313 } | |
| 226 case Inst::Arithmetic: { | 314 case Inst::Arithmetic: { |
| 227 Variable *Dest = Instr->getDest(); | 315 Variable *Dest = Instr->getDest(); |
| 228 const Type DestTy = Dest->getType(); | 316 const Type DestTy = Dest->getType(); |
| 229 const InstArithmetic::OpKind Op = | 317 const InstArithmetic::OpKind Op = |
| 230 llvm::cast<InstArithmetic>(Instr)->getOp(); | 318 llvm::cast<InstArithmetic>(Instr)->getOp(); |
| 231 if (isVectorType(DestTy)) { | 319 if (isVectorType(DestTy)) { |
| 232 scalarizeArithmetic(Op, Dest, Instr->getSrc(0), Instr->getSrc(1)); | 320 scalarizeArithmetic(Op, Dest, Instr->getSrc(0), Instr->getSrc(1)); |
| 233 Instr->setDeleted(); | 321 Instr->setDeleted(); |
| 234 return; | 322 return; |
| 235 } | 323 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 } | 375 } |
| 288 llvm::report_fatal_error("Control flow should never have reached here."); | 376 llvm::report_fatal_error("Control flow should never have reached here."); |
| 289 } | 377 } |
| 290 case Inst::Cast: { | 378 case Inst::Cast: { |
| 291 Variable *Dest = Instr->getDest(); | 379 Variable *Dest = Instr->getDest(); |
| 292 Operand *Src0 = Instr->getSrc(0); | 380 Operand *Src0 = Instr->getSrc(0); |
| 293 const Type DestTy = Dest->getType(); | 381 const Type DestTy = Dest->getType(); |
| 294 const Type SrcTy = Src0->getType(); | 382 const Type SrcTy = Src0->getType(); |
| 295 auto *CastInstr = llvm::cast<InstCast>(Instr); | 383 auto *CastInstr = llvm::cast<InstCast>(Instr); |
| 296 const InstCast::OpKind CastKind = CastInstr->getCastKind(); | 384 const InstCast::OpKind CastKind = CastInstr->getCastKind(); |
| 385 | |
| 386 if (isVectorType(Dest->getType())) { | |
| 387 Variable *T = Func->makeVariable(DestTy); | |
| 388 auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); | |
| 389 VarVecOn32->initVecElement(Func); | |
| 390 auto *Undef = ConstantUndef::create(Ctx, DestTy); | |
| 391 Context.insert<InstAssign>(T, Undef); | |
| 392 for (SizeT I = 0; I < typeNumElements(DestTy); ++I) { | |
| 393 auto *Index = Ctx->getConstantInt32(I); | |
| 394 auto *Op = Func->makeVariable(typeElementType(SrcTy)); | |
| 395 Context.insert<InstExtractElement>(Op, Src0, Index); | |
| 396 auto *Dst = Func->makeVariable(typeElementType(DestTy)); | |
| 397 Variable *DestT = Func->makeVariable(DestTy); | |
| 398 Context.insert<InstCast>(CastKind, Dst, Op); | |
| 399 Context.insert<InstInsertElement>(DestT, T, Dst, Index); | |
| 400 T = DestT; | |
| 401 } | |
| 402 Context.insert<InstAssign>(Dest, T); | |
| 403 Instr->setDeleted(); | |
| 404 return; | |
| 405 } | |
| 406 | |
| 297 switch (CastKind) { | 407 switch (CastKind) { |
| 298 default: | 408 default: |
| 299 return; | 409 return; |
| 300 case InstCast::Fptosi: | 410 case InstCast::Fptosi: |
| 301 case InstCast::Fptoui: { | 411 case InstCast::Fptoui: { |
| 302 if ((DestTy != IceType_i32) && (DestTy != IceType_i64)) { | 412 if ((DestTy != IceType_i32) && (DestTy != IceType_i64)) { |
| 303 return; | 413 return; |
| 304 } | 414 } |
| 305 const bool DestIs32 = DestTy == IceType_i32; | 415 const bool DestIs32 = DestTy == IceType_i32; |
| 306 const bool DestIsSigned = CastKind == InstCast::Fptosi; | 416 const bool DestIsSigned = CastKind == InstCast::Fptosi; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 Operand *Src0 = IntrinsicCall->getArg(0); | 548 Operand *Src0 = IntrinsicCall->getArg(0); |
| 439 GlobalString FabsFloat = Ctx->getGlobalString("llvm.fabs.f32"); | 549 GlobalString FabsFloat = Ctx->getGlobalString("llvm.fabs.f32"); |
| 440 Operand *CallTarget = Ctx->getConstantExternSym(FabsFloat); | 550 Operand *CallTarget = Ctx->getConstantExternSym(FabsFloat); |
| 441 GlobalString FabsVec = Ctx->getGlobalString("llvm.fabs.v4f32"); | 551 GlobalString FabsVec = Ctx->getGlobalString("llvm.fabs.v4f32"); |
| 442 bool BadIntrinsic = false; | 552 bool BadIntrinsic = false; |
| 443 const Intrinsics::FullIntrinsicInfo *FullInfo = | 553 const Intrinsics::FullIntrinsicInfo *FullInfo = |
| 444 Ctx->getIntrinsicsInfo().find(FabsVec, BadIntrinsic); | 554 Ctx->getIntrinsicsInfo().find(FabsVec, BadIntrinsic); |
| 445 Intrinsics::IntrinsicInfo Info = FullInfo->Info; | 555 Intrinsics::IntrinsicInfo Info = FullInfo->Info; |
| 446 | 556 |
| 447 Variable *T = Func->makeVariable(IceType_v4f32); | 557 Variable *T = Func->makeVariable(IceType_v4f32); |
| 558 auto *Undef = ConstantUndef::create(Ctx, IceType_v4f32); | |
| 559 Context.insert<InstAssign>(T, Undef); | |
| 448 auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); | 560 auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); |
| 449 VarVecOn32->initVecElement(Func); | 561 VarVecOn32->initVecElement(Func); |
| 450 Context.insert<InstFakeDef>(T); | |
| 451 | 562 |
| 452 for (SizeT i = 0; i < VarVecOn32->ElementsPerContainer; ++i) { | 563 for (SizeT i = 0; i < typeNumElements(IceType_v4f32); ++i) { |
| 453 auto *Index = Ctx->getConstantInt32(i); | 564 auto *Index = Ctx->getConstantInt32(i); |
| 454 auto *Op = Func->makeVariable(IceType_f32); | 565 auto *Op = Func->makeVariable(IceType_f32); |
| 455 Context.insert<InstExtractElement>(Op, Src0, Index); | 566 Context.insert<InstExtractElement>(Op, Src0, Index); |
| 456 auto *Res = Func->makeVariable(IceType_f32); | 567 auto *Res = Func->makeVariable(IceType_f32); |
| 457 Variable *DestT = Func->makeVariable(IceType_v4f32); | 568 Variable *DestT = Func->makeVariable(IceType_v4f32); |
| 458 auto *Call = | 569 auto *Call = |
| 459 Context.insert<InstIntrinsicCall>(1, Res, CallTarget, Info); | 570 Context.insert<InstIntrinsicCall>(1, Res, CallTarget, Info); |
| 460 Call->addArg(Op); | 571 Call->addArg(Op); |
| 461 Context.insert<InstInsertElement>(DestT, T, Res, Index); | 572 Context.insert<InstInsertElement>(DestT, T, Res, Index); |
| 462 T = DestT; | 573 T = DestT; |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1072 TargetMIPS32::CallingConv CC; | 1183 TargetMIPS32::CallingConv CC; |
| 1073 | 1184 |
| 1074 // For each register argument, replace Arg in the argument list with the home | 1185 // For each register argument, replace Arg in the argument list with the home |
| 1075 // register. Then generate an instruction in the prolog to copy the home | 1186 // register. Then generate an instruction in the prolog to copy the home |
| 1076 // register to the assigned location of Arg. | 1187 // register to the assigned location of Arg. |
| 1077 Context.init(Func->getEntryNode()); | 1188 Context.init(Func->getEntryNode()); |
| 1078 Context.setInsertPoint(Context.getCur()); | 1189 Context.setInsertPoint(Context.getCur()); |
| 1079 | 1190 |
| 1080 // v4f32 is returned through stack. $4 is setup by the caller and passed as | 1191 // v4f32 is returned through stack. $4 is setup by the caller and passed as |
| 1081 // first argument implicitly. Callee then copies the return vector at $4. | 1192 // first argument implicitly. Callee then copies the return vector at $4. |
| 1193 Variable *ImplicitRetVec = nullptr; | |
| 1082 if (isVectorFloatingType(Func->getReturnType())) { | 1194 if (isVectorFloatingType(Func->getReturnType())) { |
| 1083 Variable *ImplicitRetVec = Func->makeVariable(IceType_i32); | 1195 ImplicitRetVec = Func->makeVariable(IceType_i32); |
| 1084 ImplicitRetVec->setName(Func, "ImplicitRet_v4f32"); | 1196 ImplicitRetVec->setName(Func, "ImplicitRet_v4f32"); |
| 1085 ImplicitRetVec->setIsArg(); | 1197 ImplicitRetVec->setIsArg(); |
| 1086 Args.insert(Args.begin(), ImplicitRetVec); | 1198 Args.insert(Args.begin(), ImplicitRetVec); |
| 1087 setImplicitRet(ImplicitRetVec); | 1199 setImplicitRet(ImplicitRetVec); |
| 1088 Context.insert<InstFakeDef>(ImplicitRetVec); | |
| 1089 for (CfgNode *Node : Func->getNodes()) { | |
| 1090 for (Inst &Instr : Node->getInsts()) { | |
| 1091 if (llvm::isa<InstRet>(&Instr)) { | |
| 1092 Context.setInsertPoint(Instr); | |
| 1093 Context.insert<InstFakeUse>(ImplicitRetVec); | |
| 1094 break; | |
| 1095 } | |
| 1096 } | |
| 1097 } | |
| 1098 Context.setInsertPoint(Context.getCur()); | |
| 1099 } | 1200 } |
| 1100 | 1201 |
| 1101 for (SizeT i = 0, E = Args.size(); i < E; ++i) { | 1202 for (SizeT i = 0, E = Args.size(); i < E; ++i) { |
| 1102 Variable *Arg = Args[i]; | 1203 Variable *Arg = Args[i]; |
| 1103 Type Ty = Arg->getType(); | 1204 Type Ty = Arg->getType(); |
| 1104 RegNumT RegNum; | 1205 RegNumT RegNum; |
| 1105 if (!CC.argInReg(Ty, i, &RegNum)) { | 1206 if (!CC.argInReg(Ty, i, &RegNum)) { |
| 1106 continue; | 1207 continue; |
| 1107 } | 1208 } |
| 1108 Variable *RegisterArg = Func->makeVariable(Ty); | 1209 Variable *RegisterArg = Func->makeVariable(Ty); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1142 RegisterArg64->initHiLo(Func); | 1243 RegisterArg64->initHiLo(Func); |
| 1143 RegisterArg64->getLo()->setRegNum( | 1244 RegisterArg64->getLo()->setRegNum( |
| 1144 RegNumT::fixme(RegMIPS32::get64PairFirstRegNum(RegNum))); | 1245 RegNumT::fixme(RegMIPS32::get64PairFirstRegNum(RegNum))); |
| 1145 RegisterArg64->getHi()->setRegNum( | 1246 RegisterArg64->getHi()->setRegNum( |
| 1146 RegNumT::fixme(RegMIPS32::get64PairSecondRegNum(RegNum))); | 1247 RegNumT::fixme(RegMIPS32::get64PairSecondRegNum(RegNum))); |
| 1147 } break; | 1248 } break; |
| 1148 } | 1249 } |
| 1149 } | 1250 } |
| 1150 Context.insert<InstAssign>(Arg, RegisterArg); | 1251 Context.insert<InstAssign>(Arg, RegisterArg); |
| 1151 } | 1252 } |
| 1253 | |
| 1254 // Insert fake use of ImplicitRet_v4f32 to keep it live | |
| 1255 if (ImplicitRetVec) { | |
| 1256 for (CfgNode *Node : Func->getNodes()) { | |
| 1257 for (Inst &Instr : Node->getInsts()) { | |
| 1258 if (llvm::isa<InstRet>(&Instr)) { | |
| 1259 Context.setInsertPoint(Instr); | |
| 1260 Context.insert<InstFakeUse>(ImplicitRetVec); | |
| 1261 break; | |
| 1262 } | |
| 1263 } | |
| 1264 } | |
| 1265 } | |
| 1152 } | 1266 } |
| 1153 | 1267 |
| 1154 Type TargetMIPS32::stackSlotType() { return IceType_i32; } | 1268 Type TargetMIPS32::stackSlotType() { return IceType_i32; } |
| 1155 | 1269 |
| 1156 // Helper function for addProlog(). | 1270 // Helper function for addProlog(). |
| 1157 // | 1271 // |
| 1158 // This assumes Arg is an argument passed on the stack. This sets the frame | 1272 // This assumes Arg is an argument passed on the stack. This sets the frame |
| 1159 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an | 1273 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an |
| 1160 // I64 arg that has been split into Lo and Hi components, it calls itself | 1274 // I64 arg that has been split into Lo and Hi components, it calls itself |
| 1161 // recursively on the components, taking care to handle Lo first because of the | 1275 // recursively on the components, taking care to handle Lo first because of the |
| (...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2206 // legalization into new variables, otherwise Om1 register allocation may fail | 2320 // legalization into new variables, otherwise Om1 register allocation may fail |
| 2207 // when it sees variables that are defined but not used. | 2321 // when it sees variables that are defined but not used. |
| 2208 Type DestTy = Dest->getType(); | 2322 Type DestTy = Dest->getType(); |
| 2209 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); | 2323 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); |
| 2210 Operand *Src1 = legalizeUndef(Instr->getSrc(1)); | 2324 Operand *Src1 = legalizeUndef(Instr->getSrc(1)); |
| 2211 if (DestTy == IceType_i64) { | 2325 if (DestTy == IceType_i64) { |
| 2212 lowerInt64Arithmetic(Instr, Instr->getDest(), Src0, Src1); | 2326 lowerInt64Arithmetic(Instr, Instr->getDest(), Src0, Src1); |
| 2213 return; | 2327 return; |
| 2214 } | 2328 } |
| 2215 if (isVectorType(Dest->getType())) { | 2329 if (isVectorType(Dest->getType())) { |
| 2216 UnimplementedLoweringError(this, Instr); | 2330 llvm::report_fatal_error("Arithmetic: Destination type is vector"); |
| 2217 return; | 2331 return; |
| 2218 } | 2332 } |
| 2219 | 2333 |
| 2220 Variable *T = makeReg(Dest->getType()); | 2334 Variable *T = makeReg(Dest->getType()); |
| 2221 Variable *Src0R = legalizeToReg(Src0); | 2335 Variable *Src0R = legalizeToReg(Src0); |
| 2222 Variable *Src1R = legalizeToReg(Src1); | 2336 Variable *Src1R = legalizeToReg(Src1); |
| 2223 constexpr uint32_t DivideByZeroTrapCode = 7; | 2337 constexpr uint32_t DivideByZeroTrapCode = 7; |
| 2224 | 2338 |
| 2225 switch (Instr->getOp()) { | 2339 switch (Instr->getOp()) { |
| 2226 case InstArithmetic::_num: | 2340 case InstArithmetic::_num: |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2354 } | 2468 } |
| 2355 | 2469 |
| 2356 void TargetMIPS32::lowerAssign(const InstAssign *Instr) { | 2470 void TargetMIPS32::lowerAssign(const InstAssign *Instr) { |
| 2357 Variable *Dest = Instr->getDest(); | 2471 Variable *Dest = Instr->getDest(); |
| 2358 | 2472 |
| 2359 if (Dest->isRematerializable()) { | 2473 if (Dest->isRematerializable()) { |
| 2360 Context.insert<InstFakeDef>(Dest); | 2474 Context.insert<InstFakeDef>(Dest); |
| 2361 return; | 2475 return; |
| 2362 } | 2476 } |
| 2363 | 2477 |
| 2478 // Source type may not be same as destination | |
| 2479 if (isVectorType(Dest->getType())) { | |
| 2480 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); | |
| 2481 auto *DstVec = llvm::dyn_cast<VariableVecOn32>(Dest); | |
| 2482 for (SizeT i = 0; i < DstVec->ContainersPerVector; ++i) { | |
| 2483 auto *DCont = DstVec->getContainers()[i]; | |
| 2484 auto *SCont = | |
| 2485 legalize(getOperandAtIndex(Src0, IceType_i32, i), Legal_Reg); | |
| 2486 auto *TReg = makeReg(IceType_i32); | |
| 2487 _mov(TReg, SCont); | |
| 2488 _mov(DCont, TReg); | |
| 2489 } | |
| 2490 return; | |
| 2491 } | |
| 2364 Operand *Src0 = Instr->getSrc(0); | 2492 Operand *Src0 = Instr->getSrc(0); |
| 2365 assert(Dest->getType() == Src0->getType()); | 2493 assert(Dest->getType() == Src0->getType()); |
| 2366 if (Dest->getType() == IceType_i64) { | 2494 if (Dest->getType() == IceType_i64) { |
| 2367 Src0 = legalizeUndef(Src0); | 2495 Src0 = legalizeUndef(Src0); |
| 2368 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); | 2496 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); |
| 2369 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); | 2497 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); |
| 2370 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 2498 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
| 2371 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 2499 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| 2372 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); | 2500 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); |
| 2373 _mov(T_Lo, Src0Lo); | 2501 _mov(T_Lo, Src0Lo); |
| 2374 _mov(DestLo, T_Lo); | 2502 _mov(DestLo, T_Lo); |
| 2375 _mov(T_Hi, Src0Hi); | 2503 _mov(T_Hi, Src0Hi); |
| 2376 _mov(DestHi, T_Hi); | 2504 _mov(DestHi, T_Hi); |
| 2377 return; | 2505 return; |
| 2378 } | 2506 } |
| 2379 if (isVectorType(Dest->getType())) { | |
| 2380 auto *DstVec = llvm::dyn_cast<VariableVecOn32>(Dest); | |
| 2381 for (SizeT i = 0; i < DstVec->ElementsPerContainer; ++i) { | |
| 2382 auto *DCont = DstVec->getContainers()[i]; | |
| 2383 auto *SCont = | |
| 2384 legalize(getOperandAtIndex(Src0, IceType_i32, i), Legal_Reg); | |
| 2385 auto *TReg = makeReg(IceType_i32); | |
| 2386 _mov(TReg, SCont); | |
| 2387 _mov(DCont, TReg); | |
| 2388 } | |
| 2389 return; | |
| 2390 } | |
| 2391 Operand *SrcR; | 2507 Operand *SrcR; |
| 2392 if (Dest->hasReg()) { | 2508 if (Dest->hasReg()) { |
| 2393 // If Dest already has a physical register, then legalize the Src operand | 2509 // If Dest already has a physical register, then legalize the Src operand |
| 2394 // into a Variable with the same register assignment. This especially | 2510 // into a Variable with the same register assignment. This especially |
| 2395 // helps allow the use of Flex operands. | 2511 // helps allow the use of Flex operands. |
| 2396 SrcR = legalize(Src0, Legal_Reg, Dest->getRegNum()); | 2512 SrcR = legalize(Src0, Legal_Reg, Dest->getRegNum()); |
| 2397 } else { | 2513 } else { |
| 2398 // Dest could be a stack operand. Since we could potentially need | 2514 // Dest could be a stack operand. Since we could potentially need |
| 2399 // to do a Store (and store can only have Register operands), | 2515 // to do a Store (and store can only have Register operands), |
| 2400 // legalize this to a register. | 2516 // legalize this to a register. |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2789 break; | 2905 break; |
| 2790 case IceType_v4i1: | 2906 case IceType_v4i1: |
| 2791 case IceType_v8i1: | 2907 case IceType_v8i1: |
| 2792 case IceType_v16i1: | 2908 case IceType_v16i1: |
| 2793 case IceType_v16i8: | 2909 case IceType_v16i8: |
| 2794 case IceType_v8i16: | 2910 case IceType_v8i16: |
| 2795 case IceType_v4i32: { | 2911 case IceType_v4i32: { |
| 2796 ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0); | 2912 ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0); |
| 2797 auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg); | 2913 auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg); |
| 2798 RetVec->initVecElement(Func); | 2914 RetVec->initVecElement(Func); |
| 2799 for (SizeT i = 0; i < RetVec->ElementsPerContainer; ++i) { | 2915 for (SizeT i = 0; i < RetVec->ContainersPerVector; ++i) { |
| 2800 auto *Var = RetVec->getContainers()[i]; | 2916 auto *Var = RetVec->getContainers()[i]; |
| 2801 Var->setRegNum(RegNumT::fixme(RegMIPS32::Reg_V0 + i)); | 2917 Var->setRegNum(RegNumT::fixme(RegMIPS32::Reg_V0 + i)); |
| 2802 } | 2918 } |
| 2803 break; | 2919 break; |
| 2804 } | 2920 } |
| 2805 case IceType_v4f32: | 2921 case IceType_v4f32: |
| 2806 ReturnReg = makeReg(IceType_i32, RegMIPS32::Reg_V0); | 2922 ReturnReg = makeReg(IceType_i32, RegMIPS32::Reg_V0); |
| 2807 break; | 2923 break; |
| 2808 } | 2924 } |
| 2809 } | 2925 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2880 } | 2996 } |
| 2881 } | 2997 } |
| 2882 | 2998 |
| 2883 if (Dest == nullptr) | 2999 if (Dest == nullptr) |
| 2884 return; | 3000 return; |
| 2885 | 3001 |
| 2886 // Assign the result of the call to Dest. | 3002 // Assign the result of the call to Dest. |
| 2887 if (ReturnReg) { | 3003 if (ReturnReg) { |
| 2888 if (RetVecFloat) { | 3004 if (RetVecFloat) { |
| 2889 auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); | 3005 auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); |
| 2890 for (SizeT i = 0; i < DestVecOn32->ElementsPerContainer; ++i) { | 3006 for (SizeT i = 0; i < DestVecOn32->ContainersPerVector; ++i) { |
| 2891 auto *Var = DestVecOn32->getContainers()[i]; | 3007 auto *Var = DestVecOn32->getContainers()[i]; |
| 2892 OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( | 3008 OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( |
| 2893 Func, IceType_i32, RetVecFloat, | 3009 Func, IceType_i32, RetVecFloat, |
| 2894 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4))); | 3010 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4))); |
| 2895 _lw(Var, Mem); | 3011 _lw(Var, Mem); |
| 2896 } | 3012 } |
| 2897 } else if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) { | 3013 } else if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) { |
| 2898 auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); | 3014 auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); |
| 2899 for (SizeT i = 0; i < DestVecOn32->ElementsPerContainer; ++i) { | 3015 for (SizeT i = 0; i < DestVecOn32->ContainersPerVector; ++i) { |
| 2900 _mov(DestVecOn32->getContainers()[i], RetVec->getContainers()[i]); | 3016 _mov(DestVecOn32->getContainers()[i], RetVec->getContainers()[i]); |
| 2901 } | 3017 } |
| 2902 } else if (ReturnRegHi) { | 3018 } else if (ReturnRegHi) { |
| 2903 assert(Dest->getType() == IceType_i64); | 3019 assert(Dest->getType() == IceType_i64); |
| 2904 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); | 3020 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); |
| 2905 Variable *DestLo = Dest64On32->getLo(); | 3021 Variable *DestLo = Dest64On32->getLo(); |
| 2906 Variable *DestHi = Dest64On32->getHi(); | 3022 Variable *DestHi = Dest64On32->getHi(); |
| 2907 _mov(DestLo, ReturnReg); | 3023 _mov(DestLo, ReturnReg); |
| 2908 _mov(DestHi, ReturnRegHi); | 3024 _mov(DestHi, ReturnRegHi); |
| 2909 } else { | 3025 } else { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2925 const uint32_t ShiftAmount = | 3041 const uint32_t ShiftAmount = |
| 2926 (Src0Ty == IceType_i1 | 3042 (Src0Ty == IceType_i1 |
| 2927 ? INT32_BITS - 1 | 3043 ? INT32_BITS - 1 |
| 2928 : INT32_BITS - (CHAR_BITS * typeWidthInBytes(Src0Ty))); | 3044 : INT32_BITS - (CHAR_BITS * typeWidthInBytes(Src0Ty))); |
| 2929 const uint32_t Mask = | 3045 const uint32_t Mask = |
| 2930 (Src0Ty == IceType_i1 | 3046 (Src0Ty == IceType_i1 |
| 2931 ? 1 | 3047 ? 1 |
| 2932 : (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1); | 3048 : (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1); |
| 2933 | 3049 |
| 2934 if (isVectorType(DestTy)) { | 3050 if (isVectorType(DestTy)) { |
| 2935 UnimplementedLoweringError(this, Instr); | 3051 llvm::report_fatal_error("Cast: Destination type is vector"); |
| 2936 return; | 3052 return; |
| 2937 } | 3053 } |
| 2938 switch (CastKind) { | 3054 switch (CastKind) { |
| 2939 default: | 3055 default: |
| 2940 Func->setError("Cast type not supported"); | 3056 Func->setError("Cast type not supported"); |
| 2941 return; | 3057 return; |
| 2942 case InstCast::Sext: { | 3058 case InstCast::Sext: { |
| 2943 if (DestTy == IceType_i64) { | 3059 if (DestTy == IceType_i64) { |
| 2944 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 3060 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
| 2945 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3061 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3088 UnimplementedLoweringError(this, Instr); | 3204 UnimplementedLoweringError(this, Instr); |
| 3089 break; | 3205 break; |
| 3090 } | 3206 } |
| 3091 case InstCast::Bitcast: { | 3207 case InstCast::Bitcast: { |
| 3092 Operand *Src0 = Instr->getSrc(0); | 3208 Operand *Src0 = Instr->getSrc(0); |
| 3093 if (DestTy == Src0->getType()) { | 3209 if (DestTy == Src0->getType()) { |
| 3094 auto *Assign = InstAssign::create(Func, Dest, Src0); | 3210 auto *Assign = InstAssign::create(Func, Dest, Src0); |
| 3095 lowerAssign(Assign); | 3211 lowerAssign(Assign); |
| 3096 return; | 3212 return; |
| 3097 } | 3213 } |
| 3214 if (isVectorType(DestTy) || isVectorType(Src0->getType())) { | |
| 3215 llvm::report_fatal_error( | |
| 3216 "Bitcast: vector type should have been prelowered."); | |
| 3217 return; | |
| 3218 } | |
| 3098 switch (DestTy) { | 3219 switch (DestTy) { |
| 3099 case IceType_NUM: | 3220 case IceType_NUM: |
| 3100 case IceType_void: | 3221 case IceType_void: |
| 3101 llvm::report_fatal_error("Unexpected bitcast."); | 3222 llvm::report_fatal_error("Unexpected bitcast."); |
| 3102 case IceType_i1: | 3223 case IceType_i1: |
| 3103 UnimplementedLoweringError(this, Instr); | 3224 UnimplementedLoweringError(this, Instr); |
| 3104 break; | 3225 break; |
| 3105 case IceType_i8: | 3226 case IceType_i8: |
| 3106 assert(Src0->getType() == IceType_v8i1); | 3227 UnimplementedLoweringError(this, Instr); |
| 3107 llvm::report_fatal_error( | |
| 3108 "i8 to v8i1 conversion should have been prelowered."); | |
| 3109 break; | 3228 break; |
| 3110 case IceType_i16: | 3229 case IceType_i16: |
| 3111 assert(Src0->getType() == IceType_v16i1); | 3230 UnimplementedLoweringError(this, Instr); |
| 3112 llvm::report_fatal_error( | |
| 3113 "i16 to v16i1 conversion should have been prelowered."); | |
| 3114 break; | |
| 3115 case IceType_v8i1: | |
| 3116 assert(Src0->getType() == IceType_i8); | |
| 3117 llvm::report_fatal_error( | |
| 3118 "v8i1 to i8 conversion should have been prelowered."); | |
| 3119 break; | |
| 3120 case IceType_v16i1: | |
| 3121 assert(Src0->getType() == IceType_i16); | |
| 3122 llvm::report_fatal_error( | |
| 3123 "v16i1 to i16 conversion should have been prelowered."); | |
| 3124 break; | 3231 break; |
| 3125 default: | 3232 default: |
| 3126 UnimplementedLoweringError(this, Instr); | 3233 UnimplementedLoweringError(this, Instr); |
| 3127 } | 3234 } |
| 3128 break; | 3235 break; |
| 3129 } | 3236 } |
| 3130 } | 3237 } |
| 3131 } | 3238 } |
| 3132 | 3239 |
| 3133 void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) { | 3240 void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) { |
| 3134 Variable *Dest = Instr->getDest(); | 3241 Variable *Dest = Instr->getDest(); |
| 3135 const Type DestTy = Dest->getType(); | 3242 const Type DestTy = Dest->getType(); |
| 3136 Operand *Src1 = Instr->getSrc(1); | 3243 Operand *Src1 = Instr->getSrc(1); |
| 3137 if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src1)) { | 3244 if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src1)) { |
| 3138 const uint32_t Index = Imm->getValue(); | 3245 const uint32_t Index = Imm->getValue(); |
| 3139 Variable *TDest = makeReg(DestTy); | 3246 Variable *TDest = makeReg(DestTy); |
| 3140 Variable *TReg = makeReg(DestTy); | 3247 Variable *TReg = makeReg(DestTy); |
| 3141 auto *Src0 = legalizeUndef(Instr->getSrc(0)); | 3248 auto *Src0 = legalizeUndef(Instr->getSrc(0)); |
| 3142 auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); | 3249 auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); |
| 3143 // Number of elements in each container | 3250 // Number of elements in each container |
| 3144 uint32_t ElemPerCont = | 3251 uint32_t ElemPerCont = |
| 3145 typeNumElements(Src0->getType()) / Src0R->ElementsPerContainer; | 3252 typeNumElements(Src0->getType()) / Src0R->ContainersPerVector; |
| 3146 auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; | 3253 auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; |
| 3147 // Position of the element in the container | 3254 // Position of the element in the container |
| 3148 uint32_t PosInCont = Index % ElemPerCont; | 3255 uint32_t PosInCont = Index % ElemPerCont; |
| 3149 if (ElemPerCont == 1) { | 3256 if (ElemPerCont == 1) { |
| 3150 _mov(TDest, SrcE); | 3257 _mov(TDest, SrcE); |
| 3151 } else if (ElemPerCont == 2) { | 3258 } else if (ElemPerCont == 2) { |
| 3152 switch (PosInCont) { | 3259 switch (PosInCont) { |
| 3153 case 0: | 3260 case 0: |
| 3154 _andi(TDest, SrcE, 0xffff); | 3261 _andi(TDest, SrcE, 0xffff); |
| 3155 break; | 3262 break; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 3175 break; | 3282 break; |
| 3176 case 3: | 3283 case 3: |
| 3177 _srl(TDest, SrcE, 24); | 3284 _srl(TDest, SrcE, 24); |
| 3178 break; | 3285 break; |
| 3179 default: | 3286 default: |
| 3180 llvm::report_fatal_error("ExtractElement: Invalid PosInCont"); | 3287 llvm::report_fatal_error("ExtractElement: Invalid PosInCont"); |
| 3181 break; | 3288 break; |
| 3182 } | 3289 } |
| 3183 } | 3290 } |
| 3184 if (typeElementType(Src0R->getType()) == IceType_i1) { | 3291 if (typeElementType(Src0R->getType()) == IceType_i1) { |
| 3185 _andi(TReg, TDest, 0x1); | 3292 Variable *TReg1 = makeReg(DestTy); |
| 3186 _mov(Dest, TReg); | 3293 _andi(TReg1, TDest, 0x1); |
| 3294 _mov(Dest, TReg1); | |
| 3187 } else { | 3295 } else { |
| 3188 _mov(Dest, TDest); | 3296 _mov(Dest, TDest); |
| 3189 } | 3297 } |
| 3190 return; | 3298 return; |
| 3191 } | 3299 } |
| 3192 llvm::report_fatal_error("ExtractElement requires a constant index"); | 3300 llvm::report_fatal_error("ExtractElement requires a constant index"); |
| 3193 } | 3301 } |
| 3194 | 3302 |
| 3195 void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) { | 3303 void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) { |
| 3196 Variable *Dest = Instr->getDest(); | 3304 Variable *Dest = Instr->getDest(); |
| 3197 if (isVectorType(Dest->getType())) { | 3305 if (isVectorType(Dest->getType())) { |
| 3198 UnimplementedLoweringError(this, Instr); | 3306 llvm::report_fatal_error("Fcmp: Destination type is vector"); |
| 3199 return; | 3307 return; |
| 3200 } | 3308 } |
| 3201 | 3309 |
| 3202 auto *Src0 = Instr->getSrc(0); | 3310 auto *Src0 = Instr->getSrc(0); |
| 3203 auto *Src1 = Instr->getSrc(1); | 3311 auto *Src1 = Instr->getSrc(1); |
| 3204 auto *Zero = getZero(); | 3312 auto *Zero = getZero(); |
| 3205 | 3313 |
| 3206 InstFcmp::FCond Cond = Instr->getCondition(); | 3314 InstFcmp::FCond Cond = Instr->getCondition(); |
| 3207 auto *DestR = makeReg(Dest->getType()); | 3315 auto *DestR = makeReg(IceType_i32); |
| 3208 auto *Src0R = legalizeToReg(Src0); | 3316 auto *Src0R = legalizeToReg(Src0); |
| 3209 auto *Src1R = legalizeToReg(Src1); | 3317 auto *Src1R = legalizeToReg(Src1); |
| 3210 const Type Src0Ty = Src0->getType(); | 3318 const Type Src0Ty = Src0->getType(); |
| 3211 | 3319 |
| 3212 Operand *FCC0 = OperandMIPS32FCC::create(getFunc(), OperandMIPS32FCC::FCC0); | 3320 Operand *FCC0 = OperandMIPS32FCC::create(getFunc(), OperandMIPS32FCC::FCC0); |
| 3213 | 3321 |
| 3214 switch (Cond) { | 3322 switch (Cond) { |
| 3215 default: { | 3323 default: { |
| 3216 UnimplementedLoweringError(this, Instr); | 3324 UnimplementedLoweringError(this, Instr); |
| 3217 return; | 3325 return; |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3535 | 3643 |
| 3536 void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) { | 3644 void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) { |
| 3537 auto *Src0 = Instr->getSrc(0); | 3645 auto *Src0 = Instr->getSrc(0); |
| 3538 auto *Src1 = Instr->getSrc(1); | 3646 auto *Src1 = Instr->getSrc(1); |
| 3539 if (Src0->getType() == IceType_i64) { | 3647 if (Src0->getType() == IceType_i64) { |
| 3540 lower64Icmp(Instr); | 3648 lower64Icmp(Instr); |
| 3541 return; | 3649 return; |
| 3542 } | 3650 } |
| 3543 Variable *Dest = Instr->getDest(); | 3651 Variable *Dest = Instr->getDest(); |
| 3544 if (isVectorType(Dest->getType())) { | 3652 if (isVectorType(Dest->getType())) { |
| 3545 UnimplementedLoweringError(this, Instr); | 3653 llvm::report_fatal_error("Icmp: Destination type is vector"); |
| 3546 return; | 3654 return; |
| 3547 } | 3655 } |
| 3548 InstIcmp::ICond Cond = Instr->getCondition(); | 3656 InstIcmp::ICond Cond = Instr->getCondition(); |
| 3549 auto *Src0R = legalizeToReg(Src0); | 3657 auto *Src0R = legalizeToReg(Src0); |
| 3550 auto *Src1R = legalizeToReg(Src1); | 3658 auto *Src1R = legalizeToReg(Src1); |
| 3551 const Type Src0Ty = Src0R->getType(); | 3659 const Type Src0Ty = Src0R->getType(); |
| 3552 const uint32_t ShAmt = INT32_BITS - getScalarIntBitWidth(Src0->getType()); | 3660 const uint32_t ShAmt = INT32_BITS - getScalarIntBitWidth(Src0->getType()); |
| 3553 Variable *Src0RT = I32Reg(); | 3661 Variable *Src0RT = I32Reg(); |
| 3554 Variable *Src1RT = I32Reg(); | 3662 Variable *Src1RT = I32Reg(); |
| 3555 | 3663 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3641 } | 3749 } |
| 3642 } | 3750 } |
| 3643 | 3751 |
| 3644 void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) { | 3752 void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) { |
| 3645 Variable *Dest = Instr->getDest(); | 3753 Variable *Dest = Instr->getDest(); |
| 3646 const Type DestTy = Dest->getType(); | 3754 const Type DestTy = Dest->getType(); |
| 3647 Operand *Src2 = Instr->getSrc(2); | 3755 Operand *Src2 = Instr->getSrc(2); |
| 3648 if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2)) { | 3756 if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2)) { |
| 3649 const uint32_t Index = Imm->getValue(); | 3757 const uint32_t Index = Imm->getValue(); |
| 3650 // Vector to insert in | 3758 // Vector to insert in |
| 3651 auto *Src0 = Instr->getSrc(0); | 3759 auto *Src0 = legalizeUndef(Instr->getSrc(0)); |
| 3652 auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); | 3760 auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); |
| 3653 // Number of elements in each container | 3761 // Number of elements in each container |
| 3654 uint32_t ElemPerCont = | 3762 uint32_t ElemPerCont = |
| 3655 typeNumElements(Src0->getType()) / Src0R->ElementsPerContainer; | 3763 typeNumElements(Src0->getType()) / Src0R->ContainersPerVector; |
| 3656 // Source Element | 3764 // Source Element |
| 3657 auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; | 3765 auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; |
| 3658 Context.insert<InstFakeDef>(SrcE); | |
| 3659 // Dest is a vector | 3766 // Dest is a vector |
| 3660 auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest); | 3767 auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest); |
| 3661 VDest->initVecElement(Func); | 3768 VDest->initVecElement(Func); |
| 3662 // Temp vector variable | 3769 // Temp vector variable |
| 3663 auto *TDest = makeReg(DestTy); | 3770 auto *TDest = makeReg(DestTy); |
| 3664 auto *TVDest = llvm::dyn_cast<VariableVecOn32>(TDest); | 3771 auto *TVDest = llvm::dyn_cast<VariableVecOn32>(TDest); |
| 3665 TVDest->initVecElement(Func); | 3772 TVDest->initVecElement(Func); |
| 3666 // Destination element | 3773 // Destination element |
| 3667 auto *DstE = TVDest->getContainers()[Index / ElemPerCont]; | 3774 auto *DstE = TVDest->getContainers()[Index / ElemPerCont]; |
| 3668 // Element to insert | 3775 // Element to insert |
| 3669 auto *Src1R = legalizeToReg(Instr->getSrc(1)); | 3776 auto *Src1R = legalizeToReg(Instr->getSrc(1)); |
| 3670 auto *TReg1 = makeReg(Src1R->getType()); | 3777 auto *TReg1 = makeReg(Src1R->getType()); |
| 3671 auto *TReg2 = makeReg(Src1R->getType()); | 3778 auto *TReg2 = makeReg(Src1R->getType()); |
| 3672 auto *TReg3 = makeReg(Src1R->getType()); | 3779 auto *TReg3 = makeReg(Src1R->getType()); |
| 3673 auto *TReg4 = makeReg(Src1R->getType()); | 3780 auto *TReg4 = makeReg(Src1R->getType()); |
| 3674 auto *TReg5 = makeReg(Src1R->getType()); | 3781 auto *TReg5 = makeReg(Src1R->getType()); |
| 3675 // Position of the element in the container | 3782 // Position of the element in the container |
| 3676 uint32_t PosInCont = Index % ElemPerCont; | 3783 uint32_t PosInCont = Index % ElemPerCont; |
| 3677 // Load source vector in a temporary vector | 3784 // Load source vector in a temporary vector |
| 3678 for (SizeT i = 0; i < TVDest->ElementsPerContainer; ++i) { | 3785 for (SizeT i = 0; i < TVDest->ContainersPerVector; ++i) { |
| 3679 auto *DCont = TVDest->getContainers()[i]; | 3786 auto *DCont = TVDest->getContainers()[i]; |
| 3680 // Do not define DstE as we are going to redefine it | 3787 // Do not define DstE as we are going to redefine it |
| 3681 if (DCont == DstE) | 3788 if (DCont == DstE) |
| 3682 continue; | 3789 continue; |
| 3683 auto *SCont = Src0R->getContainers()[i]; | 3790 auto *SCont = Src0R->getContainers()[i]; |
| 3684 auto *TReg = makeReg(IceType_i32); | 3791 auto *TReg = makeReg(IceType_i32); |
| 3685 _mov(TReg, SCont); | 3792 _mov(TReg, SCont); |
| 3686 _mov(DCont, TReg); | 3793 _mov(DCont, TReg); |
| 3687 } | 3794 } |
| 3688 // Insert the element | 3795 // Insert the element |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4211 | 4318 |
| 4212 Func->resetCurrentNode(); | 4319 Func->resetCurrentNode(); |
| 4213 if (Func->isVerbose(IceV_AddrOpt)) { | 4320 if (Func->isVerbose(IceV_AddrOpt)) { |
| 4214 OstreamLocker _(Func->getContext()); | 4321 OstreamLocker _(Func->getContext()); |
| 4215 Ostream &Str = Func->getContext()->getStrDump(); | 4322 Ostream &Str = Func->getContext()->getStrDump(); |
| 4216 Str << "\nAddress mode formation:\t"; | 4323 Str << "\nAddress mode formation:\t"; |
| 4217 LdSt->dumpDecorated(Func); | 4324 LdSt->dumpDecorated(Func); |
| 4218 } | 4325 } |
| 4219 | 4326 |
| 4220 if (isVectorType(Ty)) { | 4327 if (isVectorType(Ty)) { |
| 4221 UnimplementedError(getFlags()); | |
| 4222 return nullptr; | 4328 return nullptr; |
| 4223 } | 4329 } |
| 4224 | 4330 |
| 4225 auto *BaseVar = llvm::dyn_cast<Variable>(Base); | 4331 auto *BaseVar = llvm::dyn_cast<Variable>(Base); |
| 4226 if (BaseVar == nullptr) | 4332 if (BaseVar == nullptr) |
| 4227 return nullptr; | 4333 return nullptr; |
| 4228 | 4334 |
| 4229 const VariablesMetadata *VMetadata = Func->getVMetadata(); | 4335 const VariablesMetadata *VMetadata = Func->getVMetadata(); |
| 4230 const Inst *Reason = nullptr; | 4336 const Inst *Reason = nullptr; |
| 4231 | 4337 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4354 Context.insert<InstFakeUse>(V1); | 4460 Context.insert<InstFakeUse>(V1); |
| 4355 Context.insert<InstFakeUse>(A0); | 4461 Context.insert<InstFakeUse>(A0); |
| 4356 Context.insert<InstFakeUse>(A1); | 4462 Context.insert<InstFakeUse>(A1); |
| 4357 break; | 4463 break; |
| 4358 } | 4464 } |
| 4359 case IceType_v4f32: { | 4465 case IceType_v4f32: { |
| 4360 auto *SrcVec = llvm::dyn_cast<VariableVecOn32>(Src0); | 4466 auto *SrcVec = llvm::dyn_cast<VariableVecOn32>(Src0); |
| 4361 Reg = getImplicitRet(); | 4467 Reg = getImplicitRet(); |
| 4362 auto *RegT = legalizeToReg(Reg); | 4468 auto *RegT = legalizeToReg(Reg); |
| 4363 // Return the vector through buffer in implicit argument a0 | 4469 // Return the vector through buffer in implicit argument a0 |
| 4364 for (SizeT i = 0; i < SrcVec->ElementsPerContainer; ++i) { | 4470 for (SizeT i = 0; i < SrcVec->ContainersPerVector; ++i) { |
| 4365 OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( | 4471 OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( |
| 4366 Func, IceType_f32, RegT, | 4472 Func, IceType_f32, RegT, |
| 4367 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4))); | 4473 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4))); |
| 4368 Variable *Var = legalizeToReg(SrcVec->getContainers()[i]); | 4474 Variable *Var = legalizeToReg(SrcVec->getContainers()[i]); |
| 4369 _sw(Var, Mem); | 4475 _sw(Var, Mem); |
| 4370 } | 4476 } |
| 4371 Variable *V0 = makeReg(IceType_i32, RegMIPS32::Reg_V0); | 4477 Variable *V0 = makeReg(IceType_i32, RegMIPS32::Reg_V0); |
| 4372 _mov(V0, Reg); // move v0,a0 | 4478 _mov(V0, Reg); // move v0,a0 |
| 4373 Context.insert<InstFakeUse>(Reg); | 4479 Context.insert<InstFakeUse>(Reg); |
| 4374 Context.insert<InstFakeUse>(V0); | 4480 Context.insert<InstFakeUse>(V0); |
| 4375 break; | 4481 break; |
| 4376 } | 4482 } |
| 4377 default: | 4483 default: |
| 4378 llvm::report_fatal_error("Ret: Invalid type."); | 4484 llvm::report_fatal_error("Ret: Invalid type."); |
| 4379 break; | 4485 break; |
| 4380 } | 4486 } |
| 4381 } | 4487 } |
| 4382 _ret(getPhysicalRegister(RegMIPS32::Reg_RA), Reg); | 4488 _ret(getPhysicalRegister(RegMIPS32::Reg_RA), Reg); |
| 4383 } | 4489 } |
| 4384 | 4490 |
| 4385 void TargetMIPS32::lowerSelect(const InstSelect *Instr) { | 4491 void TargetMIPS32::lowerSelect(const InstSelect *Instr) { |
| 4386 Variable *Dest = Instr->getDest(); | 4492 Variable *Dest = Instr->getDest(); |
| 4387 const Type DestTy = Dest->getType(); | 4493 const Type DestTy = Dest->getType(); |
| 4388 | 4494 |
| 4389 if (isVectorType(DestTy)) { | 4495 if (isVectorType(DestTy)) { |
| 4390 UnimplementedLoweringError(this, Instr); | 4496 llvm::report_fatal_error("Select: Destination type is vector"); |
| 4391 return; | 4497 return; |
| 4392 } | 4498 } |
| 4393 | 4499 |
| 4394 Variable *DestR = nullptr; | 4500 Variable *DestR = nullptr; |
| 4395 Variable *DestHiR = nullptr; | 4501 Variable *DestHiR = nullptr; |
| 4396 Variable *SrcTR = nullptr; | 4502 Variable *SrcTR = nullptr; |
| 4397 Variable *SrcTHiR = nullptr; | 4503 Variable *SrcTHiR = nullptr; |
| 4398 Variable *SrcFR = nullptr; | 4504 Variable *SrcFR = nullptr; |
| 4399 Variable *SrcFHiR = nullptr; | 4505 Variable *SrcFHiR = nullptr; |
| 4400 | 4506 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4452 Type Ty = NewAddr->getType(); | 4558 Type Ty = NewAddr->getType(); |
| 4453 | 4559 |
| 4454 if (Ty == IceType_i64) { | 4560 if (Ty == IceType_i64) { |
| 4455 Value = legalizeUndef(Value); | 4561 Value = legalizeUndef(Value); |
| 4456 Variable *ValueHi = legalizeToReg(hiOperand(Value)); | 4562 Variable *ValueHi = legalizeToReg(hiOperand(Value)); |
| 4457 Variable *ValueLo = legalizeToReg(loOperand(Value)); | 4563 Variable *ValueLo = legalizeToReg(loOperand(Value)); |
| 4458 _sw(ValueHi, llvm::cast<OperandMIPS32Mem>(hiOperand(NewAddr))); | 4564 _sw(ValueHi, llvm::cast<OperandMIPS32Mem>(hiOperand(NewAddr))); |
| 4459 _sw(ValueLo, llvm::cast<OperandMIPS32Mem>(loOperand(NewAddr))); | 4565 _sw(ValueLo, llvm::cast<OperandMIPS32Mem>(loOperand(NewAddr))); |
| 4460 } else if (isVectorType(Value->getType())) { | 4566 } else if (isVectorType(Value->getType())) { |
| 4461 auto *DataVec = llvm::dyn_cast<VariableVecOn32>(Value); | 4567 auto *DataVec = llvm::dyn_cast<VariableVecOn32>(Value); |
| 4462 for (SizeT i = 0; i < DataVec->ElementsPerContainer; ++i) { | 4568 for (SizeT i = 0; i < DataVec->ContainersPerVector; ++i) { |
| 4463 auto *DCont = legalizeToReg(DataVec->getContainers()[i]); | 4569 auto *DCont = legalizeToReg(DataVec->getContainers()[i]); |
| 4464 auto *MCont = llvm::cast<OperandMIPS32Mem>( | 4570 auto *MCont = llvm::cast<OperandMIPS32Mem>( |
| 4465 getOperandAtIndex(NewAddr, IceType_i32, i)); | 4571 getOperandAtIndex(NewAddr, IceType_i32, i)); |
| 4466 _sw(DCont, MCont); | 4572 _sw(DCont, MCont); |
| 4467 } | 4573 } |
| 4468 } else { | 4574 } else { |
| 4469 Variable *ValueR = legalizeToReg(Value); | 4575 Variable *ValueR = legalizeToReg(Value); |
| 4470 _sw(ValueR, NewAddr); | 4576 _sw(ValueR, NewAddr); |
| 4471 } | 4577 } |
| 4472 } | 4578 } |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4926 Str << "\t.set\t" | 5032 Str << "\t.set\t" |
| 4927 << "nomips16\n"; | 5033 << "nomips16\n"; |
| 4928 } | 5034 } |
| 4929 | 5035 |
| 4930 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 5036 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 4931 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 5037 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 4932 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 5038 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 4933 | 5039 |
| 4934 } // end of namespace MIPS32 | 5040 } // end of namespace MIPS32 |
| 4935 } // end of namespace Ice | 5041 } // end of namespace Ice |
| OLD | NEW |