Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(846)

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 1640913004: Subzero: Mips: Lower some i64 arithmetic instructions (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: First parallel patch to ARM Issue 1151663004 Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 UsesFramePointer = true; 564 UsesFramePointer = true;
565 // Conservatively require the stack to be aligned. Some stack adjustment 565 // Conservatively require the stack to be aligned. Some stack adjustment
566 // operations implemented below assume that the stack is aligned before the 566 // operations implemented below assume that the stack is aligned before the
567 // alloca. All the alloca code ensures that the stack alignment is preserved 567 // alloca. All the alloca code ensures that the stack alignment is preserved
568 // after the alloca. The stack alignment restriction can be relaxed in some 568 // after the alloca. The stack alignment restriction can be relaxed in some
569 // cases. 569 // cases.
570 NeedsStackAlignment = true; 570 NeedsStackAlignment = true;
571 UnimplementedLoweringError(this, Inst); 571 UnimplementedLoweringError(this, Inst);
572 } 572 }
573 573
574 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Inst,
575 Variable *Dest, Operand *Src0,
576 Operand *Src1) {
577 InstArithmetic::OpKind Op = Inst->getOp();
578 switch (Op) {
579 case InstArithmetic::Add:
580 case InstArithmetic::And:
581 case InstArithmetic::Or:
582 case InstArithmetic::Sub:
583 case InstArithmetic::Xor:
584 break;
585 default:
586 UnimplementedLoweringError(this, Inst);
587 return;
588 }
589 Src0 = legalizeUndef(Src0);
Jim Stichnoth 2016/01/30 17:03:28 Can this be removed? It's already being done in t
rkotlerimgtec 2016/01/30 23:48:30 Done.
590 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg);
591 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg);
592 Operand *Src1Lo = legalize(loOperand(Src1), Legal_Reg);
593 Operand *Src1Hi = legalize(hiOperand(Src1), Legal_Reg);
594 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
595 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
596
597 Variable *Src0LoR = legalizeToReg(Src0Lo);
Jim Stichnoth 2016/01/30 17:03:28 This can just be: Variable *Src0LoR = legalizeT
rkotlerimgtec 2016/01/30 23:48:31 Done.
598 Variable *Src1LoR = legalizeToReg(Src1Lo);
599 Variable *Src0HiR = legalizeToReg(Src0Hi);
600 Variable *Src1HiR = legalizeToReg(Src1Hi);
601
602 switch (Op) {
603 case InstArithmetic::_num:
604 llvm::report_fatal_error("Unknown arithmetic operator");
605 return;
606 case InstArithmetic::Add: {
607 Variable *T_Lo = makeReg(IceType_i32);
Jim Stichnoth 2016/01/30 17:03:28 This lowering sequence has a problem in that inval
rkotlerimgtec 2016/01/30 23:48:30 Done.
608 Variable *T_Hi = makeReg(IceType_i32);
609 _addu(DestLo, Src0LoR, Src1LoR);
610 _sltu(T_Lo, DestLo, Src0LoR);
611 _addu(T_Hi, T_Lo, Src0HiR);
612 _addu(DestHi, Src1HiR, T_Hi);
613 return;
614 }
615 case InstArithmetic::And: {
616 _and(DestLo, Src0LoR, Src1LoR);
Jim Stichnoth 2016/01/30 17:03:28 Similar to above, you need to ensure the _and dest
rkotlerimgtec 2016/01/30 23:48:30 Done.
rkotlerimgtec 2016/01/30 23:48:31 Done.
617 _and(DestHi, Src0HiR, Src1HiR);
618 return;
619 }
620 case InstArithmetic::Sub: {
621 Variable *T_Lo = makeReg(IceType_i32);
Jim Stichnoth 2016/01/30 17:03:29 Similar comment as for Add, maybe calling it "Borr
rkotlerimgtec 2016/01/30 23:48:30 Done.
622 Variable *T_Hi = makeReg(IceType_i32);
623 _subu(DestLo, Src0LoR, Src1LoR);
624 _sltu(T_Lo, Src0LoR, Src1LoR);
625 _addu(T_Hi, T_Lo, Src1HiR);
626 _subu(DestHi, Src0HiR, T_Hi);
627 return;
628 }
629 case InstArithmetic::Or: {
630 _or(DestLo, Src0LoR, Src1LoR);
631 _or(DestHi, Src0HiR, Src1HiR);
632 return;
633 }
634 case InstArithmetic::Xor: {
635 _xor(DestLo, Src0LoR, Src1LoR);
636 _xor(DestHi, Src0HiR, Src1HiR);
637 return;
638 }
639 default:
640 UnimplementedLoweringError(this, Inst);
641 return;
642 //}
Jim Stichnoth 2016/01/30 17:03:29 remove this
rkotlerimgtec 2016/01/30 23:48:30 Done.
643 }
644 }
645
574 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { 646 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) {
575 Variable *Dest = Inst->getDest(); 647 Variable *Dest = Inst->getDest();
576 // We need to signal all the UnimplementedLoweringError errors before any 648 // We need to signal all the UnimplementedLoweringError errors before any
577 // legalization into new variables, otherwise Om1 register allocation may fail 649 // legalization into new variables, otherwise Om1 register allocation may fail
578 // when it sees variables that are defined but not used. 650 // when it sees variables that are defined but not used.
579 if (Dest->getType() == IceType_i64) { 651 Type DestTy = Dest->getType();
580 UnimplementedLoweringError(this, Inst); 652 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
653 Operand *Src1 = legalizeUndef(Inst->getSrc(1));
654 if (DestTy == IceType_i64) {
655 lowerInt64Arithmetic(Inst, Inst->getDest(), Src0, Src1);
581 return; 656 return;
582 } 657 }
583 if (isVectorType(Dest->getType())) { 658 if (isVectorType(Dest->getType())) {
584 UnimplementedLoweringError(this, Inst); 659 UnimplementedLoweringError(this, Inst);
585 return; 660 return;
586 } 661 }
587 switch (Inst->getOp()) { 662 switch (Inst->getOp()) {
588 default: 663 default:
589 break; 664 break;
590 case InstArithmetic::Shl: 665 case InstArithmetic::Shl:
591 case InstArithmetic::Lshr: 666 case InstArithmetic::Lshr:
592 case InstArithmetic::Ashr: 667 case InstArithmetic::Ashr:
593 case InstArithmetic::Udiv: 668 case InstArithmetic::Udiv:
594 case InstArithmetic::Sdiv: 669 case InstArithmetic::Sdiv:
595 case InstArithmetic::Urem: 670 case InstArithmetic::Urem:
596 case InstArithmetic::Srem: 671 case InstArithmetic::Srem:
597 case InstArithmetic::Fadd: 672 case InstArithmetic::Fadd:
598 case InstArithmetic::Fsub: 673 case InstArithmetic::Fsub:
599 case InstArithmetic::Fmul: 674 case InstArithmetic::Fmul:
600 case InstArithmetic::Fdiv: 675 case InstArithmetic::Fdiv:
601 case InstArithmetic::Frem: 676 case InstArithmetic::Frem:
602 UnimplementedLoweringError(this, Inst); 677 UnimplementedLoweringError(this, Inst);
603 return; 678 return;
604 } 679 }
605 680
606 // At this point Dest->getType() is non-i64 scalar 681 // At this point Dest->getType() is non-i64 scalar
607 682
608 Variable *T = makeReg(Dest->getType()); 683 Variable *T = makeReg(Dest->getType());
609 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
610 Operand *Src1 = legalizeUndef(Inst->getSrc(1));
611 Variable *Src0R = legalizeToReg(Src0); 684 Variable *Src0R = legalizeToReg(Src0);
612 Variable *Src1R = legalizeToReg(Src1); 685 Variable *Src1R = legalizeToReg(Src1);
613 686
614 switch (Inst->getOp()) { 687 switch (Inst->getOp()) {
615 case InstArithmetic::_num: 688 case InstArithmetic::_num:
616 break; 689 break;
617 case InstArithmetic::Add: 690 case InstArithmetic::Add:
618 _add(T, Src0R, Src1R); 691 _add(T, Src0R, Src1R);
619 _mov(Dest, T); 692 _mov(Dest, T);
620 return; 693 return;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 break; 730 break;
658 case InstArithmetic::Fsub: 731 case InstArithmetic::Fsub:
659 break; 732 break;
660 case InstArithmetic::Fmul: 733 case InstArithmetic::Fmul:
661 break; 734 break;
662 case InstArithmetic::Fdiv: 735 case InstArithmetic::Fdiv:
663 break; 736 break;
664 case InstArithmetic::Frem: 737 case InstArithmetic::Frem:
665 break; 738 break;
666 } 739 }
740 UnimplementedLoweringError(this, Inst);
667 } 741 }
668 742
669 void TargetMIPS32::lowerAssign(const InstAssign *Inst) { 743 void TargetMIPS32::lowerAssign(const InstAssign *Inst) {
670 Variable *Dest = Inst->getDest(); 744 Variable *Dest = Inst->getDest();
671 Operand *Src0 = Inst->getSrc(0); 745 Operand *Src0 = Inst->getSrc(0);
672 assert(Dest->getType() == Src0->getType()); 746 assert(Dest->getType() == Src0->getType());
673 if (Dest->getType() == IceType_i64) { 747 if (Dest->getType() == IceType_i64) {
674 Src0 = legalizeUndef(Src0); 748 Src0 = legalizeUndef(Src0);
675 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); 749 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg);
676 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); 750 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg);
(...skipping 24 matching lines...) Expand all
701 } else { 775 } else {
702 _mov(Dest, SrcR); 776 _mov(Dest, SrcR);
703 } 777 }
704 } 778 }
705 } 779 }
706 780
707 void TargetMIPS32::lowerBr(const InstBr *Inst) { 781 void TargetMIPS32::lowerBr(const InstBr *Inst) {
708 UnimplementedLoweringError(this, Inst); 782 UnimplementedLoweringError(this, Inst);
709 } 783 }
710 784
711 void TargetMIPS32::lowerCall(const InstCall *Inst) { 785 void TargetMIPS32::lowerCall(const InstCall *Instr) {
712 UnimplementedLoweringError(this, Inst); 786 // TODO(jvoung): assign arguments to registers and stack. Also reserve stack.
Jim Stichnoth 2016/01/30 17:03:28 Don't add jvoung to a TODO. :)
rkotlerimgtec 2016/01/30 23:48:31 Done.
787 if (Instr->getNumArgs()) {
788 UnimplementedLoweringError(this, Instr);
789 return;
790 }
791 // Generate the call instruction. Assign its result to a temporary
Jim Stichnoth 2016/01/30 17:03:28 reflow to 80-col
rkotlerimgtec 2016/01/30 23:48:31 Done.
792 // with high register allocation weight.
793 Variable *Dest = Instr->getDest();
794 // ReturnReg doubles as ReturnRegLo as necessary.
795 Variable *ReturnReg = nullptr;
796 Variable *ReturnRegHi = nullptr;
797 if (Dest) {
798 switch (Dest->getType()) {
799 case IceType_NUM:
800 llvm_unreachable("Invalid Call dest type");
801 return;
802 case IceType_void:
803 break;
804 case IceType_i1:
805 case IceType_i8:
806 case IceType_i16:
807 case IceType_i32:
808 ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0);
809 break;
810 case IceType_i64:
811 ReturnReg = makeReg(IceType_i32, RegMIPS32::Reg_V0);
812 ReturnRegHi = makeReg(IceType_i32, RegMIPS32::Reg_V1);
813 break;
814 case IceType_f32:
815 case IceType_f64:
816 UnimplementedLoweringError(this, Instr);
817 return;
818 case IceType_v4i1:
819 case IceType_v8i1:
820 case IceType_v16i1:
821 case IceType_v16i8:
822 case IceType_v8i16:
823 case IceType_v4i32:
824 case IceType_v4f32:
825 UnimplementedLoweringError(this, Instr);
826 return;
827 }
828 }
829 Operand *CallTarget = Instr->getCallTarget();
830 // Allow ConstantRelocatable to be left alone as a direct call,
831 // but force other constants like ConstantInteger32 to be in
832 // a register and make it an indirect call.
833 if (!llvm::isa<ConstantRelocatable>(CallTarget)) {
834 CallTarget = legalize(CallTarget, Legal_Reg);
835 }
836 Inst *NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget);
837 Context.insert(NewCall);
838 if (ReturnRegHi)
839 Context.insert(InstFakeDef::create(Func, ReturnRegHi));
840 // Insert a register-kill pseudo instruction.
841 Context.insert(InstFakeKill::create(Func, NewCall));
842 // Generate a FakeUse to keep the call live if necessary.
843 if (Instr->hasSideEffects() && ReturnReg) {
844 Inst *FakeUse = InstFakeUse::create(Func, ReturnReg);
845 Context.insert(FakeUse);
846 }
847 if (!Dest)
Jim Stichnoth 2016/01/30 17:03:28 Dest == nullptr
rkotlerimgtec 2016/01/30 23:48:31 Done.
848 return;
849
850 // Assign the result of the call to Dest.
851 if (ReturnReg) {
852 if (ReturnRegHi) {
853 assert(Dest->getType() == IceType_i64);
854 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest);
855 Variable *DestLo = Dest64On32->getLo();
856 Variable *DestHi = Dest64On32->getHi();
857 _mov(DestLo, ReturnReg);
858 _mov(DestHi, ReturnRegHi);
859 } else {
860 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 ||
861 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 ||
862 isVectorType(Dest->getType()));
863 if (isFloatingType(Dest->getType()) || isVectorType(Dest->getType())) {
864 UnimplementedLoweringError(this, Instr);
865 return;
866 } else {
867 _mov(Dest, ReturnReg);
868 }
869 }
870 }
871 UnimplementedLoweringError(this, Instr);
713 } 872 }
714 873
715 void TargetMIPS32::lowerCast(const InstCast *Inst) { 874 void TargetMIPS32::lowerCast(const InstCast *Inst) {
716 InstCast::OpKind CastKind = Inst->getCastKind(); 875 InstCast::OpKind CastKind = Inst->getCastKind();
717 switch (CastKind) { 876 switch (CastKind) {
718 default: 877 default:
719 Func->setError("Cast type not supported"); 878 Func->setError("Cast type not supported");
720 return; 879 return;
721 case InstCast::Sext: { 880 case InstCast::Sext: {
722 UnimplementedLoweringError(this, Inst); 881 UnimplementedLoweringError(this, Inst);
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 // since loOperand() and hiOperand() don't expect Undef input. 1134 // since loOperand() and hiOperand() don't expect Undef input.
976 void TargetMIPS32::prelowerPhis() { 1135 void TargetMIPS32::prelowerPhis() {
977 PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func); 1136 PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func);
978 } 1137 }
979 1138
980 void TargetMIPS32::postLower() { 1139 void TargetMIPS32::postLower() {
981 if (Ctx->getFlags().getOptLevel() == Opt_m1) 1140 if (Ctx->getFlags().getOptLevel() == Opt_m1)
982 return; 1141 return;
983 // Find two-address non-SSA instructions where Dest==Src0, and set the 1142 // Find two-address non-SSA instructions where Dest==Src0, and set the
984 // IsDestRedefined flag to keep liveness analysis consistent. 1143 // IsDestRedefined flag to keep liveness analysis consistent.
985 UnimplementedError(Func->getContext()->getFlags()); 1144 UnimplementedError(Func->getContext()->getFlags());
Jim Stichnoth 2016/01/30 17:03:29 Remove this line, and replace it with "markRedefin
986 } 1145 }
987 1146
988 void TargetMIPS32::makeRandomRegisterPermutation( 1147 void TargetMIPS32::makeRandomRegisterPermutation(
989 llvm::SmallVectorImpl<int32_t> &Permutation, 1148 llvm::SmallVectorImpl<int32_t> &Permutation,
990 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { 1149 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
991 (void)Permutation; 1150 (void)Permutation;
992 (void)ExcludeRegisters; 1151 (void)ExcludeRegisters;
993 (void)Salt; 1152 (void)Salt;
994 UnimplementedError(Func->getContext()->getFlags()); 1153 UnimplementedError(Func->getContext()->getFlags());
995 } 1154 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 // if a Flexible second operand is allowed. We need to know the exact 1239 // if a Flexible second operand is allowed. We need to know the exact
1081 // value, so that rules out relocatable constants. 1240 // value, so that rules out relocatable constants.
1082 // Also try the inverse and use MVN if possible. 1241 // Also try the inverse and use MVN if possible.
1083 // Do a movw/movt to a register. 1242 // Do a movw/movt to a register.
1084 Variable *Reg; 1243 Variable *Reg;
1085 if (RegNum == Variable::NoRegister) 1244 if (RegNum == Variable::NoRegister)
1086 Reg = makeReg(Ty, RegNum); 1245 Reg = makeReg(Ty, RegNum);
1087 else 1246 else
1088 Reg = getPhysicalRegister(RegNum); 1247 Reg = getPhysicalRegister(RegNum);
1089 if (isInt<16>(int32_t(Value))) { 1248 if (isInt<16>(int32_t(Value))) {
1090 _addiu(Reg, getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty), Value); 1249 //_addiu(Reg, getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty), Value);
Jim Stichnoth 2016/01/30 17:03:28 remove this
rkotlerimgtec 2016/01/30 23:48:31 Done.
1250 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty);
1251 Context.insert<InstFakeDef>(Zero);
1252 _addiu(Reg, Zero, Value);
1091 } else { 1253 } else {
1092 uint32_t UpperBits = (Value >> 16) & 0xFFFF; 1254 uint32_t UpperBits = (Value >> 16) & 0xFFFF;
1093 (void)UpperBits; 1255 (void)UpperBits;
1094 uint32_t LowerBits = Value & 0xFFFF; 1256 uint32_t LowerBits = Value & 0xFFFF;
1095 Variable *TReg = makeReg(Ty, RegNum); 1257 Variable *TReg = makeReg(Ty, RegNum);
1096 _lui(TReg, UpperBits); 1258 _lui(TReg, UpperBits);
1097 _ori(Reg, TReg, LowerBits); 1259 _ori(Reg, TReg, LowerBits);
1098 } 1260 }
1099 return Reg; 1261 return Reg;
1100 } 1262 }
(...skipping 26 matching lines...) Expand all
1127 Str << "\t.set\t" 1289 Str << "\t.set\t"
1128 << "nomips16\n"; 1290 << "nomips16\n";
1129 } 1291 }
1130 1292
1131 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 1293 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
1132 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 1294 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
1133 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 1295 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
1134 1296
1135 } // end of namespace MIPS32 1297 } // end of namespace MIPS32
1136 } // end of namespace Ice 1298 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698