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

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: changes suggested by stichnot and jpp 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
« no previous file with comments | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/llvm2ice_tests/64bit.pnacl.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
590 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
591 Variable *Src0LoR = legalizeToReg(loOperand(Src0));
592 Variable *Src1LoR = legalizeToReg(loOperand(Src1));
593 Variable *Src0HiR = legalizeToReg(hiOperand(Src0));
594 Variable *Src1HiR = legalizeToReg(hiOperand(Src1));
595
596 switch (Op) {
597 case InstArithmetic::_num:
598 llvm::report_fatal_error("Unknown arithmetic operator");
599 return;
600 case InstArithmetic::Add: {
601 Variable *T_Carry = makeReg(IceType_i32);
602 Variable *T_Lo = makeReg(IceType_i32);
603 Variable *T_Hi = makeReg(IceType_i32);
604 Variable *T_Hi2 = makeReg(IceType_i32);
605 _addu(T_Lo, Src0LoR, Src1LoR);
606 _mov(DestLo, T_Lo);
607 _sltu(T_Carry, T_Lo, Src0LoR);
608 _addu(T_Hi, T_Carry, Src0HiR);
609 _addu(T_Hi2, Src1HiR, T_Hi);
610 _mov(DestHi, T_Hi2);
611 return;
612 }
613 case InstArithmetic::And: {
614 Variable *T_Lo = makeReg(IceType_i32);
615 Variable *T_Hi = makeReg(IceType_i32);
616 _and(T_Lo, Src0LoR, Src1LoR);
617 _mov(DestLo, T_Lo);
618 _and(T_Hi, Src0HiR, Src1HiR);
619 _mov(DestHi, T_Hi);
620 return;
621 }
622 case InstArithmetic::Sub: {
623 Variable *T_Borrow = makeReg(IceType_i32);
624 Variable *T_Lo = makeReg(IceType_i32);
625 Variable *T_Hi = makeReg(IceType_i32);
626 Variable *T_Hi2 = makeReg(IceType_i32);
627 _subu(T_Lo, Src0LoR, Src1LoR);
628 _mov(DestLo, T_Lo);
629 _sltu(T_Borrow, Src0LoR, Src1LoR);
630 _addu(T_Hi, T_Borrow, Src1HiR);
631 _subu(T_Hi2, Src0HiR, T_Hi);
632 _mov(DestHi, T_Hi2);
633 return;
634 }
635 case InstArithmetic::Or: {
636 Variable *T_Lo = makeReg(IceType_i32);
637 Variable *T_Hi = makeReg(IceType_i32);
638 _or(T_Lo, Src0LoR, Src1LoR);
639 _mov(DestLo, T_Lo);
640 _or(T_Hi, Src0HiR, Src1HiR);
641 _mov(DestHi, T_Hi);
642 return;
643 }
644 case InstArithmetic::Xor: {
645 Variable *T_Lo = makeReg(IceType_i32);
646 Variable *T_Hi = makeReg(IceType_i32);
647 _xor(T_Lo, Src0LoR, Src1LoR);
648 _mov(DestLo, T_Lo);
649 _xor(T_Hi, Src0HiR, Src1HiR);
650 _mov(DestHi, T_Hi);
651 return;
652 }
653 default:
654 UnimplementedLoweringError(this, Inst);
655 return;
656 }
657 }
658
574 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { 659 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) {
575 Variable *Dest = Inst->getDest(); 660 Variable *Dest = Inst->getDest();
576 // We need to signal all the UnimplementedLoweringError errors before any 661 // We need to signal all the UnimplementedLoweringError errors before any
577 // legalization into new variables, otherwise Om1 register allocation may fail 662 // legalization into new variables, otherwise Om1 register allocation may fail
578 // when it sees variables that are defined but not used. 663 // when it sees variables that are defined but not used.
579 if (Dest->getType() == IceType_i64) { 664 Type DestTy = Dest->getType();
580 UnimplementedLoweringError(this, Inst); 665 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
666 Operand *Src1 = legalizeUndef(Inst->getSrc(1));
667 if (DestTy == IceType_i64) {
668 lowerInt64Arithmetic(Inst, Inst->getDest(), Src0, Src1);
581 return; 669 return;
582 } 670 }
583 if (isVectorType(Dest->getType())) { 671 if (isVectorType(Dest->getType())) {
584 UnimplementedLoweringError(this, Inst); 672 UnimplementedLoweringError(this, Inst);
585 return; 673 return;
586 } 674 }
587 switch (Inst->getOp()) { 675 switch (Inst->getOp()) {
588 default: 676 default:
589 break; 677 break;
590 case InstArithmetic::Shl: 678 case InstArithmetic::Shl:
591 case InstArithmetic::Lshr: 679 case InstArithmetic::Lshr:
592 case InstArithmetic::Ashr: 680 case InstArithmetic::Ashr:
593 case InstArithmetic::Udiv: 681 case InstArithmetic::Udiv:
594 case InstArithmetic::Sdiv: 682 case InstArithmetic::Sdiv:
595 case InstArithmetic::Urem: 683 case InstArithmetic::Urem:
596 case InstArithmetic::Srem: 684 case InstArithmetic::Srem:
597 case InstArithmetic::Fadd: 685 case InstArithmetic::Fadd:
598 case InstArithmetic::Fsub: 686 case InstArithmetic::Fsub:
599 case InstArithmetic::Fmul: 687 case InstArithmetic::Fmul:
600 case InstArithmetic::Fdiv: 688 case InstArithmetic::Fdiv:
601 case InstArithmetic::Frem: 689 case InstArithmetic::Frem:
602 UnimplementedLoweringError(this, Inst); 690 UnimplementedLoweringError(this, Inst);
603 return; 691 return;
604 } 692 }
605 693
606 // At this point Dest->getType() is non-i64 scalar 694 // At this point Dest->getType() is non-i64 scalar
607 695
608 Variable *T = makeReg(Dest->getType()); 696 Variable *T = makeReg(Dest->getType());
609 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
610 Operand *Src1 = legalizeUndef(Inst->getSrc(1));
611 Variable *Src0R = legalizeToReg(Src0); 697 Variable *Src0R = legalizeToReg(Src0);
612 Variable *Src1R = legalizeToReg(Src1); 698 Variable *Src1R = legalizeToReg(Src1);
613 699
614 switch (Inst->getOp()) { 700 switch (Inst->getOp()) {
615 case InstArithmetic::_num: 701 case InstArithmetic::_num:
616 break; 702 break;
617 case InstArithmetic::Add: 703 case InstArithmetic::Add:
618 _add(T, Src0R, Src1R); 704 _addu(T, Src0R, Src1R);
619 _mov(Dest, T); 705 _mov(Dest, T);
620 return; 706 return;
621 case InstArithmetic::And: 707 case InstArithmetic::And:
622 _and(T, Src0R, Src1R); 708 _and(T, Src0R, Src1R);
623 _mov(Dest, T); 709 _mov(Dest, T);
624 return; 710 return;
625 case InstArithmetic::Or: 711 case InstArithmetic::Or:
626 _or(T, Src0R, Src1R); 712 _or(T, Src0R, Src1R);
627 _mov(Dest, T); 713 _mov(Dest, T);
628 return; 714 return;
629 case InstArithmetic::Xor: 715 case InstArithmetic::Xor:
630 _xor(T, Src0R, Src1R); 716 _xor(T, Src0R, Src1R);
631 _mov(Dest, T); 717 _mov(Dest, T);
632 return; 718 return;
633 case InstArithmetic::Sub: 719 case InstArithmetic::Sub:
634 _sub(T, Src0R, Src1R); 720 _subu(T, Src0R, Src1R);
635 _mov(Dest, T); 721 _mov(Dest, T);
636 return; 722 return;
637 case InstArithmetic::Mul: { 723 case InstArithmetic::Mul: {
638 _mul(T, Src0R, Src1R); 724 _mul(T, Src0R, Src1R);
639 _mov(Dest, T); 725 _mov(Dest, T);
640 return; 726 return;
641 } 727 }
642 case InstArithmetic::Shl: 728 case InstArithmetic::Shl:
643 break; 729 break;
644 case InstArithmetic::Lshr: 730 case InstArithmetic::Lshr:
(...skipping 12 matching lines...) Expand all
657 break; 743 break;
658 case InstArithmetic::Fsub: 744 case InstArithmetic::Fsub:
659 break; 745 break;
660 case InstArithmetic::Fmul: 746 case InstArithmetic::Fmul:
661 break; 747 break;
662 case InstArithmetic::Fdiv: 748 case InstArithmetic::Fdiv:
663 break; 749 break;
664 case InstArithmetic::Frem: 750 case InstArithmetic::Frem:
665 break; 751 break;
666 } 752 }
753 UnimplementedLoweringError(this, Inst);
667 } 754 }
668 755
669 void TargetMIPS32::lowerAssign(const InstAssign *Inst) { 756 void TargetMIPS32::lowerAssign(const InstAssign *Inst) {
670 Variable *Dest = Inst->getDest(); 757 Variable *Dest = Inst->getDest();
671 Operand *Src0 = Inst->getSrc(0); 758 Operand *Src0 = Inst->getSrc(0);
672 assert(Dest->getType() == Src0->getType()); 759 assert(Dest->getType() == Src0->getType());
673 if (Dest->getType() == IceType_i64) { 760 if (Dest->getType() == IceType_i64) {
674 Src0 = legalizeUndef(Src0); 761 Src0 = legalizeUndef(Src0);
675 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); 762 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg);
676 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); 763 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg);
(...skipping 24 matching lines...) Expand all
701 } else { 788 } else {
702 _mov(Dest, SrcR); 789 _mov(Dest, SrcR);
703 } 790 }
704 } 791 }
705 } 792 }
706 793
707 void TargetMIPS32::lowerBr(const InstBr *Inst) { 794 void TargetMIPS32::lowerBr(const InstBr *Inst) {
708 UnimplementedLoweringError(this, Inst); 795 UnimplementedLoweringError(this, Inst);
709 } 796 }
710 797
711 void TargetMIPS32::lowerCall(const InstCall *Inst) { 798 void TargetMIPS32::lowerCall(const InstCall *Instr) {
712 UnimplementedLoweringError(this, Inst); 799 // TODO(rkotler): assign arguments to registers and stack. Also reserve stack.
800 if (Instr->getNumArgs()) {
801 UnimplementedLoweringError(this, Instr);
802 return;
803 }
804 // Generate the call instruction. Assign its result to a temporary with high
805 // register allocation weight.
806 Variable *Dest = Instr->getDest();
807 // ReturnReg doubles as ReturnRegLo as necessary.
808 Variable *ReturnReg = nullptr;
809 Variable *ReturnRegHi = nullptr;
810 if (Dest) {
811 switch (Dest->getType()) {
812 case IceType_NUM:
813 llvm_unreachable("Invalid Call dest type");
814 return;
815 case IceType_void:
816 break;
817 case IceType_i1:
818 case IceType_i8:
819 case IceType_i16:
820 case IceType_i32:
821 ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0);
822 break;
823 case IceType_i64:
824 ReturnReg = makeReg(IceType_i32, RegMIPS32::Reg_V0);
825 ReturnRegHi = makeReg(IceType_i32, RegMIPS32::Reg_V1);
826 break;
827 case IceType_f32:
828 case IceType_f64:
829 UnimplementedLoweringError(this, Instr);
830 return;
831 case IceType_v4i1:
832 case IceType_v8i1:
833 case IceType_v16i1:
834 case IceType_v16i8:
835 case IceType_v8i16:
836 case IceType_v4i32:
837 case IceType_v4f32:
838 UnimplementedLoweringError(this, Instr);
839 return;
840 }
841 }
842 Operand *CallTarget = Instr->getCallTarget();
843 // Allow ConstantRelocatable to be left alone as a direct call,
844 // but force other constants like ConstantInteger32 to be in
845 // a register and make it an indirect call.
846 if (!llvm::isa<ConstantRelocatable>(CallTarget)) {
847 CallTarget = legalize(CallTarget, Legal_Reg);
848 }
849 Inst *NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget);
850 Context.insert(NewCall);
851 if (ReturnRegHi)
852 Context.insert(InstFakeDef::create(Func, ReturnRegHi));
853 // Insert a register-kill pseudo instruction.
854 Context.insert(InstFakeKill::create(Func, NewCall));
855 // Generate a FakeUse to keep the call live if necessary.
856 if (Instr->hasSideEffects() && ReturnReg) {
857 Context.insert<InstFakeDef>(ReturnReg);
858 }
859 if (Dest == nullptr)
860 return;
861
862 // Assign the result of the call to Dest.
863 if (ReturnReg) {
864 if (ReturnRegHi) {
865 assert(Dest->getType() == IceType_i64);
866 auto *Dest64On32 = llvm::cast<Variable64On32>(Dest);
867 Variable *DestLo = Dest64On32->getLo();
868 Variable *DestHi = Dest64On32->getHi();
869 _mov(DestLo, ReturnReg);
870 _mov(DestHi, ReturnRegHi);
871 } else {
872 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 ||
873 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 ||
874 isVectorType(Dest->getType()));
875 if (isFloatingType(Dest->getType()) || isVectorType(Dest->getType())) {
876 UnimplementedLoweringError(this, Instr);
877 return;
878 } else {
879 _mov(Dest, ReturnReg);
880 }
881 }
882 }
713 } 883 }
714 884
715 void TargetMIPS32::lowerCast(const InstCast *Inst) { 885 void TargetMIPS32::lowerCast(const InstCast *Inst) {
716 InstCast::OpKind CastKind = Inst->getCastKind(); 886 InstCast::OpKind CastKind = Inst->getCastKind();
717 switch (CastKind) { 887 switch (CastKind) {
718 default: 888 default:
719 Func->setError("Cast type not supported"); 889 Func->setError("Cast type not supported");
720 return; 890 return;
721 case InstCast::Sext: { 891 case InstCast::Sext: {
722 UnimplementedLoweringError(this, Inst); 892 UnimplementedLoweringError(this, Inst);
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve 1143 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve
974 // integrity of liveness analysis. Undef values are also turned into zeroes, 1144 // integrity of liveness analysis. Undef values are also turned into zeroes,
975 // since loOperand() and hiOperand() don't expect Undef input. 1145 // since loOperand() and hiOperand() don't expect Undef input.
976 void TargetMIPS32::prelowerPhis() { 1146 void TargetMIPS32::prelowerPhis() {
977 PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func); 1147 PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func);
978 } 1148 }
979 1149
980 void TargetMIPS32::postLower() { 1150 void TargetMIPS32::postLower() {
981 if (Ctx->getFlags().getOptLevel() == Opt_m1) 1151 if (Ctx->getFlags().getOptLevel() == Opt_m1)
982 return; 1152 return;
983 // Find two-address non-SSA instructions where Dest==Src0, and set the 1153 // TODO(rkotler): Find two-address non-SSA instructions where Dest==Src0,
984 // IsDestRedefined flag to keep liveness analysis consistent. 1154 // and set the IsDestRedefined flag to keep liveness analysis consistent.
985 UnimplementedError(Func->getContext()->getFlags()); 1155 UnimplementedError(Func->getContext()->getFlags());
986 } 1156 }
987 1157
988 void TargetMIPS32::makeRandomRegisterPermutation( 1158 void TargetMIPS32::makeRandomRegisterPermutation(
989 llvm::SmallVectorImpl<int32_t> &Permutation, 1159 llvm::SmallVectorImpl<int32_t> &Permutation,
990 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { 1160 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
991 (void)Permutation; 1161 (void)Permutation;
992 (void)ExcludeRegisters; 1162 (void)ExcludeRegisters;
993 (void)Salt; 1163 (void)Salt;
994 UnimplementedError(Func->getContext()->getFlags()); 1164 UnimplementedError(Func->getContext()->getFlags());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 // if a Flexible second operand is allowed. We need to know the exact 1250 // if a Flexible second operand is allowed. We need to know the exact
1081 // value, so that rules out relocatable constants. 1251 // value, so that rules out relocatable constants.
1082 // Also try the inverse and use MVN if possible. 1252 // Also try the inverse and use MVN if possible.
1083 // Do a movw/movt to a register. 1253 // Do a movw/movt to a register.
1084 Variable *Reg; 1254 Variable *Reg;
1085 if (RegNum == Variable::NoRegister) 1255 if (RegNum == Variable::NoRegister)
1086 Reg = makeReg(Ty, RegNum); 1256 Reg = makeReg(Ty, RegNum);
1087 else 1257 else
1088 Reg = getPhysicalRegister(RegNum); 1258 Reg = getPhysicalRegister(RegNum);
1089 if (isInt<16>(int32_t(Value))) { 1259 if (isInt<16>(int32_t(Value))) {
1090 _addiu(Reg, getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty), Value); 1260 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty);
1261 Context.insert<InstFakeDef>(Zero);
1262 _addiu(Reg, Zero, Value);
1091 } else { 1263 } else {
1092 uint32_t UpperBits = (Value >> 16) & 0xFFFF; 1264 uint32_t UpperBits = (Value >> 16) & 0xFFFF;
1093 (void)UpperBits; 1265 (void)UpperBits;
1094 uint32_t LowerBits = Value & 0xFFFF; 1266 uint32_t LowerBits = Value & 0xFFFF;
1095 Variable *TReg = makeReg(Ty, RegNum); 1267 Variable *TReg = makeReg(Ty, RegNum);
1096 _lui(TReg, UpperBits); 1268 _lui(TReg, UpperBits);
1097 _ori(Reg, TReg, LowerBits); 1269 _ori(Reg, TReg, LowerBits);
1098 } 1270 }
1099 return Reg; 1271 return Reg;
1100 } 1272 }
(...skipping 26 matching lines...) Expand all
1127 Str << "\t.set\t" 1299 Str << "\t.set\t"
1128 << "nomips16\n"; 1300 << "nomips16\n";
1129 } 1301 }
1130 1302
1131 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 1303 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
1132 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 1304 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
1133 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 1305 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
1134 1306
1135 } // end of namespace MIPS32 1307 } // end of namespace MIPS32
1136 } // end of namespace Ice 1308 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/llvm2ice_tests/64bit.pnacl.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698