Chromium Code Reviews| 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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 if (!BuildDefs::dump()) | 311 if (!BuildDefs::dump()) |
| 312 return; | 312 return; |
| 313 Ostream &Str = Ctx->getStrEmit(); | 313 Ostream &Str = Ctx->getStrEmit(); |
| 314 const Type FrameSPTy = IceType_i32; | 314 const Type FrameSPTy = IceType_i32; |
| 315 if (Var->hasReg()) { | 315 if (Var->hasReg()) { |
| 316 Str << '$' << getRegName(Var->getRegNum(), Var->getType()); | 316 Str << '$' << getRegName(Var->getRegNum(), Var->getType()); |
| 317 return; | 317 return; |
| 318 } else { | 318 } else { |
| 319 int32_t Offset = Var->getStackOffset(); | 319 int32_t Offset = Var->getStackOffset(); |
| 320 Str << Offset; | 320 Str << Offset; |
| 321 Str << "(" << getRegName(getFrameOrStackReg(), FrameSPTy); | 321 Str << "($" << getRegName(getFrameOrStackReg(), FrameSPTy); |
| 322 Str << ")"; | 322 Str << ")"; |
| 323 } | 323 } |
| 324 UnimplementedError(Func->getContext()->getFlags()); | 324 UnimplementedError(Func->getContext()->getFlags()); |
| 325 } | 325 } |
| 326 | 326 |
| 327 void TargetMIPS32::lowerArguments() { | 327 void TargetMIPS32::lowerArguments() { |
| 328 VarList &Args = Func->getArgs(); | 328 VarList &Args = Func->getArgs(); |
| 329 // We are only handling integer registers for now. The Mips o32 ABI is | 329 // We are only handling integer registers for now. The Mips o32 ABI is |
| 330 // somewhat complex but will be implemented in its totality through follow | 330 // somewhat complex but will be implemented in its totality through follow |
| 331 // on patches. | 331 // on patches. |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 510 // cases. | 510 // cases. |
| 511 NeedsStackAlignment = true; | 511 NeedsStackAlignment = true; |
| 512 (void)Inst; | 512 (void)Inst; |
| 513 UnimplementedError(Func->getContext()->getFlags()); | 513 UnimplementedError(Func->getContext()->getFlags()); |
| 514 } | 514 } |
| 515 | 515 |
| 516 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { | 516 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { |
| 517 Variable *Dest = Inst->getDest(); | 517 Variable *Dest = Inst->getDest(); |
| 518 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); | 518 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); |
| 519 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); | 519 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); |
| 520 (void)Src0; | |
| 521 (void)Src1; | |
| 522 if (Dest->getType() == IceType_i64) { | 520 if (Dest->getType() == IceType_i64) { |
| 521 // TODO(reed kotler): fakedef needed for now until all cases are implemented | |
| 522 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | |
| 523 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | |
| 524 Context.insert(InstFakeDef::create(Func, DestLo)); | |
| 525 Context.insert(InstFakeDef::create(Func, DestHi)); | |
| 523 UnimplementedError(Func->getContext()->getFlags()); | 526 UnimplementedError(Func->getContext()->getFlags()); |
| 524 } else if (isVectorType(Dest->getType())) { | 527 return; |
| 528 } | |
| 529 if (isVectorType(Dest->getType())) { | |
| 530 Context.insert(InstFakeDef::create(Func, Dest)); | |
| 525 UnimplementedError(Func->getContext()->getFlags()); | 531 UnimplementedError(Func->getContext()->getFlags()); |
| 526 } else { // Dest->getType() is non-i64 scalar | 532 return; |
| 527 switch (Inst->getOp()) { | |
| 528 case InstArithmetic::_num: | |
| 529 UnimplementedError(Func->getContext()->getFlags()); | |
| 530 break; | |
| 531 case InstArithmetic::Add: | |
| 532 UnimplementedError(Func->getContext()->getFlags()); | |
| 533 // Variable *T = makeReg(Dest->getType()); | |
| 534 // _add(T, Src0, Src1); | |
| 535 // _mov(Dest, T); | |
| 536 return; | |
| 537 case InstArithmetic::And: | |
| 538 UnimplementedError(Func->getContext()->getFlags()); | |
| 539 break; | |
| 540 case InstArithmetic::Or: | |
| 541 UnimplementedError(Func->getContext()->getFlags()); | |
| 542 break; | |
| 543 case InstArithmetic::Xor: | |
| 544 UnimplementedError(Func->getContext()->getFlags()); | |
| 545 break; | |
| 546 case InstArithmetic::Sub: | |
| 547 UnimplementedError(Func->getContext()->getFlags()); | |
| 548 break; | |
| 549 case InstArithmetic::Mul: | |
| 550 UnimplementedError(Func->getContext()->getFlags()); | |
| 551 break; | |
| 552 case InstArithmetic::Shl: | |
| 553 UnimplementedError(Func->getContext()->getFlags()); | |
| 554 break; | |
| 555 case InstArithmetic::Lshr: | |
| 556 UnimplementedError(Func->getContext()->getFlags()); | |
| 557 break; | |
| 558 case InstArithmetic::Ashr: | |
| 559 UnimplementedError(Func->getContext()->getFlags()); | |
| 560 break; | |
| 561 case InstArithmetic::Udiv: | |
| 562 UnimplementedError(Func->getContext()->getFlags()); | |
| 563 break; | |
| 564 case InstArithmetic::Sdiv: | |
| 565 UnimplementedError(Func->getContext()->getFlags()); | |
| 566 break; | |
| 567 case InstArithmetic::Urem: | |
| 568 UnimplementedError(Func->getContext()->getFlags()); | |
| 569 break; | |
| 570 case InstArithmetic::Srem: | |
| 571 UnimplementedError(Func->getContext()->getFlags()); | |
| 572 break; | |
| 573 case InstArithmetic::Fadd: | |
| 574 UnimplementedError(Func->getContext()->getFlags()); | |
| 575 break; | |
| 576 case InstArithmetic::Fsub: | |
| 577 UnimplementedError(Func->getContext()->getFlags()); | |
| 578 break; | |
| 579 case InstArithmetic::Fmul: | |
| 580 UnimplementedError(Func->getContext()->getFlags()); | |
| 581 break; | |
| 582 case InstArithmetic::Fdiv: | |
| 583 UnimplementedError(Func->getContext()->getFlags()); | |
| 584 break; | |
| 585 case InstArithmetic::Frem: | |
| 586 UnimplementedError(Func->getContext()->getFlags()); | |
| 587 break; | |
| 588 } | |
| 589 } | 533 } |
| 534 // Dest->getType() is non-i64 scalar | |
| 535 Variable *T = makeReg(Dest->getType()); | |
| 536 Variable *Src0R = legalizeToReg(Src0); | |
| 537 Variable *Src1R = legalizeToReg(Src1); | |
| 538 switch (Inst->getOp()) { | |
| 539 case InstArithmetic::_num: | |
| 540 break; | |
| 541 case InstArithmetic::Add: | |
| 542 _add(T, Src0R, Src1R); | |
| 543 _mov(Dest, T); | |
| 544 return; | |
| 545 case InstArithmetic::And: | |
| 546 _and(T, Src0R, Src1R); | |
| 547 _mov(Dest, T); | |
| 548 return; | |
| 549 case InstArithmetic::Or: | |
| 550 _or(T, Src0R, Src1R); | |
| 551 _mov(Dest, T); | |
| 552 return; | |
| 553 case InstArithmetic::Xor: | |
| 554 _xor(T, Src0R, Src1R); | |
| 555 _mov(Dest, T); | |
| 556 return; | |
| 557 case InstArithmetic::Sub: | |
| 558 _sub(T, Src0R, Src1R); | |
| 559 _mov(Dest, T); | |
| 560 return; | |
| 561 case InstArithmetic::Mul: { | |
| 562 _mul(T, Src0R, Src1R); | |
| 563 _mov(Dest, T); | |
| 564 return; | |
| 565 } | |
| 566 case InstArithmetic::Shl: | |
| 567 break; | |
| 568 case InstArithmetic::Lshr: | |
| 569 break; | |
| 570 case InstArithmetic::Ashr: | |
| 571 break; | |
| 572 case InstArithmetic::Udiv: | |
| 573 break; | |
| 574 case InstArithmetic::Sdiv: | |
| 575 break; | |
| 576 case InstArithmetic::Urem: | |
| 577 break; | |
| 578 case InstArithmetic::Srem: | |
| 579 break; | |
| 580 case InstArithmetic::Fadd: | |
| 581 break; | |
| 582 case InstArithmetic::Fsub: | |
| 583 break; | |
| 584 case InstArithmetic::Fmul: | |
| 585 break; | |
| 586 case InstArithmetic::Fdiv: | |
| 587 break; | |
| 588 case InstArithmetic::Frem: | |
| 589 break; | |
| 590 } | |
| 591 // TODO(reed kotler): | |
| 592 // fakedef and fakeuse needed for now until all cases are implemented | |
| 593 Context.insert(InstFakeUse::create(Func, Src0R)); | |
| 594 Context.insert(InstFakeUse::create(Func, Src1R)); | |
| 595 Context.insert(InstFakeDef::create(Func, Dest)); | |
| 596 UnimplementedError(Func->getContext()->getFlags()); | |
| 590 } | 597 } |
| 591 | 598 |
| 592 void TargetMIPS32::lowerAssign(const InstAssign *Inst) { | 599 void TargetMIPS32::lowerAssign(const InstAssign *Inst) { |
| 593 Variable *Dest = Inst->getDest(); | 600 Variable *Dest = Inst->getDest(); |
| 594 Operand *Src0 = Inst->getSrc(0); | 601 Operand *Src0 = Inst->getSrc(0); |
| 595 assert(Dest->getType() == Src0->getType()); | 602 assert(Dest->getType() == Src0->getType()); |
| 596 if (Dest->getType() == IceType_i64) { | 603 if (Dest->getType() == IceType_i64) { |
| 597 Src0 = legalizeUndef(Src0); | 604 Src0 = legalizeUndef(Src0); |
| 598 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); | 605 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); |
| 599 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); | 606 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 988 } | 995 } |
| 989 | 996 |
| 990 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, | 997 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, |
| 991 int32_t RegNum) { | 998 int32_t RegNum) { |
| 992 Type Ty = From->getType(); | 999 Type Ty = From->getType(); |
| 993 // Assert that a physical register is allowed. To date, all calls | 1000 // Assert that a physical register is allowed. To date, all calls |
| 994 // to legalize() allow a physical register. Legal_Flex converts | 1001 // to legalize() allow a physical register. Legal_Flex converts |
| 995 // registers to the right type OperandMIPS32FlexReg as needed. | 1002 // registers to the right type OperandMIPS32FlexReg as needed. |
| 996 assert(Allowed & Legal_Reg); | 1003 assert(Allowed & Legal_Reg); |
| 997 // Go through the various types of operands: | 1004 // Go through the various types of operands: |
| 998 // OperandMIPS32Mem, OperandMIPS32Flex, Constant, and Variable. | 1005 // OperandMIPS32Mem, Constant, and Variable. |
| 999 // Given the above assertion, if type of operand is not legal | 1006 // Given the above assertion, if type of operand is not legal |
| 1000 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy | 1007 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy |
| 1001 // to a register. | 1008 // to a register. |
| 1002 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { | 1009 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { |
| 1003 (void)C; | 1010 (void)C; |
| 1004 return From; | 1011 Variable *Reg = makeReg(Ty, RegNum); |
|
Jim Stichnoth
2015/11/06 00:45:15
Also add a TODO for a proper implementation.
rkotlerimgtec
2015/11/06 00:58:18
Done.
| |
| 1012 Context.insert(InstFakeDef::create(Func, Reg)); | |
| 1013 return Reg; | |
| 1005 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { | 1014 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { |
| 1006 uint32_t Value = static_cast<uint32_t>(C32->getValue()); | 1015 uint32_t Value = static_cast<uint32_t>(C32->getValue()); |
| 1007 // Check if the immediate will fit in a Flexible second operand, | 1016 // Check if the immediate will fit in a Flexible second operand, |
| 1008 // if a Flexible second operand is allowed. We need to know the exact | 1017 // if a Flexible second operand is allowed. We need to know the exact |
| 1009 // value, so that rules out relocatable constants. | 1018 // value, so that rules out relocatable constants. |
| 1010 // Also try the inverse and use MVN if possible. | 1019 // Also try the inverse and use MVN if possible. |
| 1011 // Do a movw/movt to a register. | 1020 // Do a movw/movt to a register. |
| 1012 Variable *Reg; | 1021 Variable *Reg; |
| 1013 if (RegNum == Variable::NoRegister) | 1022 if (RegNum == Variable::NoRegister) |
| 1014 Reg = makeReg(Ty, RegNum); | 1023 Reg = makeReg(Ty, RegNum); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1052 Ostream &Str = Ctx->getStrEmit(); | 1061 Ostream &Str = Ctx->getStrEmit(); |
| 1053 Str << "\t.set\tnomicromips\n"; | 1062 Str << "\t.set\tnomicromips\n"; |
| 1054 Str << "\t.set\tnomips16\n"; | 1063 Str << "\t.set\tnomips16\n"; |
| 1055 } | 1064 } |
| 1056 | 1065 |
| 1057 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[IceType_NUM]; | 1066 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[IceType_NUM]; |
| 1058 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 1067 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 1059 llvm::SmallBitVector TargetMIPS32::ScratchRegs; | 1068 llvm::SmallBitVector TargetMIPS32::ScratchRegs; |
| 1060 | 1069 |
| 1061 } // end of namespace Ice | 1070 } // end of namespace Ice |
| OLD | NEW |