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())) { | |
| 525 UnimplementedError(Func->getContext()->getFlags()); | 530 UnimplementedError(Func->getContext()->getFlags()); |
|
Jim Stichnoth
2015/11/05 05:21:28
You may want to add this for the future:
Contex
rkotlerimgtec
2015/11/05 22:12:27
Done.
| |
| 526 } else { // Dest->getType() is non-i64 scalar | 531 } else { // Dest->getType() is non-i64 scalar |
|
Jim Stichnoth
2015/11/05 05:21:28
Here, I think you can do:
if (isVectorType(Dest
rkotlerimgtec
2015/11/05 22:12:27
Done.
| |
| 532 Variable *T = makeReg(Dest->getType()); | |
| 533 Variable *Src0R = legalizeToReg(Src0); | |
| 534 Operand *Src1R_ = legalize(Src1, Legal_Reg); | |
|
Jim Stichnoth
2015/11/05 05:21:28
I think you can just do:
Variable *Src1R = lega
rkotlerimgtec
2015/11/05 22:12:27
Done.
| |
| 535 // TODO(reed kotler): need to allow for incompleteness of | |
| 536 // legalize at this time. | |
| 537 if (Src1R_ == Src1) { | |
| 538 Context.insert(InstFakeUse::create(Func, Src0R)); | |
| 539 Context.insert(InstFakeDef::create(Func, Dest)); | |
| 540 UnimplementedError(Func->getContext()->getFlags()); | |
| 541 return; | |
| 542 } | |
| 543 Variable *Src1R = legalizeToReg(Src1R_); | |
| 527 switch (Inst->getOp()) { | 544 switch (Inst->getOp()) { |
| 528 case InstArithmetic::_num: | 545 case InstArithmetic::_num: |
| 529 UnimplementedError(Func->getContext()->getFlags()); | |
| 530 break; | 546 break; |
| 531 case InstArithmetic::Add: | 547 case InstArithmetic::Add: |
| 532 UnimplementedError(Func->getContext()->getFlags()); | 548 _add(T, Src0R, Src1R); |
| 533 // Variable *T = makeReg(Dest->getType()); | 549 _mov(Dest, T); |
| 534 // _add(T, Src0, Src1); | |
| 535 // _mov(Dest, T); | |
| 536 return; | 550 return; |
| 537 case InstArithmetic::And: | 551 case InstArithmetic::And: |
| 538 UnimplementedError(Func->getContext()->getFlags()); | 552 _and(T, Src0R, Src1R); |
| 539 break; | 553 _mov(Dest, T); |
| 554 return; | |
| 540 case InstArithmetic::Or: | 555 case InstArithmetic::Or: |
| 541 UnimplementedError(Func->getContext()->getFlags()); | 556 _or(T, Src0R, Src1R); |
| 542 break; | 557 _mov(Dest, T); |
| 558 return; | |
| 543 case InstArithmetic::Xor: | 559 case InstArithmetic::Xor: |
| 544 UnimplementedError(Func->getContext()->getFlags()); | 560 _xor(T, Src0R, Src1R); |
| 545 break; | 561 _mov(Dest, T); |
| 562 return; | |
| 546 case InstArithmetic::Sub: | 563 case InstArithmetic::Sub: |
| 547 UnimplementedError(Func->getContext()->getFlags()); | 564 _sub(T, Src0R, Src1R); |
| 548 break; | 565 _mov(Dest, T); |
| 549 case InstArithmetic::Mul: | 566 return; |
| 550 UnimplementedError(Func->getContext()->getFlags()); | 567 case InstArithmetic::Mul: { |
| 551 break; | 568 // Variable *Src1R_ = legalizeToReg(Src1R); |
|
Jim Stichnoth
2015/11/05 05:21:28
remove comment
rkotlerimgtec
2015/11/05 22:12:27
Done.
| |
| 569 _mul(T, Src0R, Src1R); | |
| 570 _mov(Dest, T); | |
| 571 return; | |
| 572 } | |
| 552 case InstArithmetic::Shl: | 573 case InstArithmetic::Shl: |
| 553 UnimplementedError(Func->getContext()->getFlags()); | |
| 554 break; | 574 break; |
| 555 case InstArithmetic::Lshr: | 575 case InstArithmetic::Lshr: |
| 556 UnimplementedError(Func->getContext()->getFlags()); | |
| 557 break; | 576 break; |
| 558 case InstArithmetic::Ashr: | 577 case InstArithmetic::Ashr: |
| 559 UnimplementedError(Func->getContext()->getFlags()); | |
| 560 break; | 578 break; |
| 561 case InstArithmetic::Udiv: | 579 case InstArithmetic::Udiv: |
| 562 UnimplementedError(Func->getContext()->getFlags()); | |
| 563 break; | 580 break; |
| 564 case InstArithmetic::Sdiv: | 581 case InstArithmetic::Sdiv: |
| 565 UnimplementedError(Func->getContext()->getFlags()); | |
| 566 break; | 582 break; |
| 567 case InstArithmetic::Urem: | 583 case InstArithmetic::Urem: |
| 568 UnimplementedError(Func->getContext()->getFlags()); | |
| 569 break; | 584 break; |
| 570 case InstArithmetic::Srem: | 585 case InstArithmetic::Srem: |
| 571 UnimplementedError(Func->getContext()->getFlags()); | |
| 572 break; | 586 break; |
| 573 case InstArithmetic::Fadd: | 587 case InstArithmetic::Fadd: |
| 574 UnimplementedError(Func->getContext()->getFlags()); | |
| 575 break; | 588 break; |
| 576 case InstArithmetic::Fsub: | 589 case InstArithmetic::Fsub: |
| 577 UnimplementedError(Func->getContext()->getFlags()); | |
| 578 break; | 590 break; |
| 579 case InstArithmetic::Fmul: | 591 case InstArithmetic::Fmul: |
| 580 UnimplementedError(Func->getContext()->getFlags()); | |
| 581 break; | 592 break; |
| 582 case InstArithmetic::Fdiv: | 593 case InstArithmetic::Fdiv: |
| 583 UnimplementedError(Func->getContext()->getFlags()); | |
| 584 break; | 594 break; |
| 585 case InstArithmetic::Frem: | 595 case InstArithmetic::Frem: |
| 586 UnimplementedError(Func->getContext()->getFlags()); | |
| 587 break; | 596 break; |
| 588 } | 597 } |
| 598 // TODO(reed kotler): | |
| 599 // fakedef and fakeuse needed for now until all cases are implemented | |
| 600 Context.insert(InstFakeUse::create(Func, Src0R)); | |
| 601 if (auto *S1 = llvm::dyn_cast<Variable>(Src1R)) { | |
|
Jim Stichnoth
2015/11/05 05:21:28
After changing Src1R to be Variable* above, you sh
rkotlerimgtec
2015/11/05 22:12:27
Done.
| |
| 602 Context.insert(InstFakeUse::create(Func, S1)); | |
| 603 } | |
| 604 Context.insert(InstFakeDef::create(Func, Dest)); | |
| 605 UnimplementedError(Func->getContext()->getFlags()); | |
| 589 } | 606 } |
| 590 } | 607 } |
| 591 | 608 |
| 592 void TargetMIPS32::lowerAssign(const InstAssign *Inst) { | 609 void TargetMIPS32::lowerAssign(const InstAssign *Inst) { |
| 593 Variable *Dest = Inst->getDest(); | 610 Variable *Dest = Inst->getDest(); |
| 594 Operand *Src0 = Inst->getSrc(0); | 611 Operand *Src0 = Inst->getSrc(0); |
| 595 assert(Dest->getType() == Src0->getType()); | 612 assert(Dest->getType() == Src0->getType()); |
| 596 if (Dest->getType() == IceType_i64) { | 613 if (Dest->getType() == IceType_i64) { |
| 597 Src0 = legalizeUndef(Src0); | 614 Src0 = legalizeUndef(Src0); |
| 598 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); | 615 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 988 } | 1005 } |
| 989 | 1006 |
| 990 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, | 1007 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, |
| 991 int32_t RegNum) { | 1008 int32_t RegNum) { |
| 992 Type Ty = From->getType(); | 1009 Type Ty = From->getType(); |
| 993 // Assert that a physical register is allowed. To date, all calls | 1010 // Assert that a physical register is allowed. To date, all calls |
| 994 // to legalize() allow a physical register. Legal_Flex converts | 1011 // to legalize() allow a physical register. Legal_Flex converts |
| 995 // registers to the right type OperandMIPS32FlexReg as needed. | 1012 // registers to the right type OperandMIPS32FlexReg as needed. |
| 996 assert(Allowed & Legal_Reg); | 1013 assert(Allowed & Legal_Reg); |
| 997 // Go through the various types of operands: | 1014 // Go through the various types of operands: |
| 998 // OperandMIPS32Mem, OperandMIPS32Flex, Constant, and Variable. | 1015 // OperandMIPS32Mem, Constant, and Variable. |
| 999 // Given the above assertion, if type of operand is not legal | 1016 // Given the above assertion, if type of operand is not legal |
| 1000 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy | 1017 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy |
| 1001 // to a register. | 1018 // to a register. |
| 1002 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { | 1019 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { |
| 1003 (void)C; | 1020 (void)C; |
| 1004 return From; | 1021 return From; |
|
Jim Stichnoth
2015/11/05 05:21:28
This is causing a problem for function @ShlReloc i
rkotlerimgtec
2015/11/05 22:12:27
Done.
| |
| 1005 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { | 1022 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { |
| 1006 uint32_t Value = static_cast<uint32_t>(C32->getValue()); | 1023 uint32_t Value = static_cast<uint32_t>(C32->getValue()); |
| 1007 // Check if the immediate will fit in a Flexible second operand, | 1024 // 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 | 1025 // if a Flexible second operand is allowed. We need to know the exact |
| 1009 // value, so that rules out relocatable constants. | 1026 // value, so that rules out relocatable constants. |
| 1010 // Also try the inverse and use MVN if possible. | 1027 // Also try the inverse and use MVN if possible. |
| 1011 // Do a movw/movt to a register. | 1028 // Do a movw/movt to a register. |
| 1012 Variable *Reg; | 1029 Variable *Reg; |
| 1013 if (RegNum == Variable::NoRegister) | 1030 if (RegNum == Variable::NoRegister) |
| 1014 Reg = makeReg(Ty, RegNum); | 1031 Reg = makeReg(Ty, RegNum); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1052 Ostream &Str = Ctx->getStrEmit(); | 1069 Ostream &Str = Ctx->getStrEmit(); |
| 1053 Str << "\t.set\tnomicromips\n"; | 1070 Str << "\t.set\tnomicromips\n"; |
| 1054 Str << "\t.set\tnomips16\n"; | 1071 Str << "\t.set\tnomips16\n"; |
| 1055 } | 1072 } |
| 1056 | 1073 |
| 1057 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[IceType_NUM]; | 1074 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[IceType_NUM]; |
| 1058 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 1075 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 1059 llvm::SmallBitVector TargetMIPS32::ScratchRegs; | 1076 llvm::SmallBitVector TargetMIPS32::ScratchRegs; |
| 1060 | 1077 |
| 1061 } // end of namespace Ice | 1078 } // end of namespace Ice |
| OLD | NEW |