OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 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 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 // gcc does the following: | 1207 // gcc does the following: |
1208 // a=b*c ==> | 1208 // a=b*c ==> |
1209 // t1 = b.hi; t1 *=(imul) c.lo | 1209 // t1 = b.hi; t1 *=(imul) c.lo |
1210 // t2 = c.hi; t2 *=(imul) b.lo | 1210 // t2 = c.hi; t2 *=(imul) b.lo |
1211 // t3:eax = b.lo | 1211 // t3:eax = b.lo |
1212 // t4.hi:edx,t4.lo:eax = t3:eax *(mul) c.lo | 1212 // t4.hi:edx,t4.lo:eax = t3:eax *(mul) c.lo |
1213 // a.lo = t4.lo | 1213 // a.lo = t4.lo |
1214 // t4.hi += t1 | 1214 // t4.hi += t1 |
1215 // t4.hi += t2 | 1215 // t4.hi += t2 |
1216 // a.hi = t4.hi | 1216 // a.hi = t4.hi |
| 1217 // The mul instruction cannot take an immediate operand. |
| 1218 Src1Lo = legalize(Src1Lo, Legal_Reg | Legal_Mem); |
1217 _mov(T_1, Src0Hi); | 1219 _mov(T_1, Src0Hi); |
1218 _imul(T_1, Src1Lo); | 1220 _imul(T_1, Src1Lo); |
1219 _mov(T_2, Src1Hi); | 1221 _mov(T_2, Src1Hi); |
1220 _imul(T_2, Src0Lo); | 1222 _imul(T_2, Src0Lo); |
1221 _mov(T_3, Src0Lo, Reg_eax); | 1223 _mov(T_3, Src0Lo, Reg_eax); |
1222 _mul(T_4Lo, T_3, Src1Lo); | 1224 _mul(T_4Lo, T_3, Src1Lo); |
1223 // The mul instruction produces two dest variables, edx:eax. We | 1225 // The mul instruction produces two dest variables, edx:eax. We |
1224 // create a fake definition of edx to account for this. | 1226 // create a fake definition of edx to account for this. |
1225 Context.insert(InstFakeDef::create(Func, T_4Hi, T_4Lo)); | 1227 Context.insert(InstFakeDef::create(Func, T_4Hi, T_4Lo)); |
1226 _mov(DestLo, T_4Lo); | 1228 _mov(DestLo, T_4Lo); |
(...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2598 if (Var->hasReg()) | 2600 if (Var->hasReg()) |
2599 IsSrc1ImmOrReg = true; | 2601 IsSrc1ImmOrReg = true; |
2600 } | 2602 } |
2601 | 2603 |
2602 // Try to fuse a compare immediately followed by a conditional branch. This | 2604 // Try to fuse a compare immediately followed by a conditional branch. This |
2603 // is possible when the compare dest and the branch source operands are the | 2605 // is possible when the compare dest and the branch source operands are the |
2604 // same, and are their only uses. TODO: implement this optimization for i64. | 2606 // same, and are their only uses. TODO: implement this optimization for i64. |
2605 if (InstBr *NextBr = llvm::dyn_cast_or_null<InstBr>(Context.getNextInst())) { | 2607 if (InstBr *NextBr = llvm::dyn_cast_or_null<InstBr>(Context.getNextInst())) { |
2606 if (Src0->getType() != IceType_i64 && !NextBr->isUnconditional() && | 2608 if (Src0->getType() != IceType_i64 && !NextBr->isUnconditional() && |
2607 Dest == NextBr->getSrc(0) && NextBr->isLastUse(Dest)) { | 2609 Dest == NextBr->getSrc(0) && NextBr->isLastUse(Dest)) { |
2608 Operand *Src0New = legalize( | 2610 Operand *Src0RM = legalize( |
2609 Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg, true); | 2611 Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg, true); |
2610 _cmp(Src0New, Src1); | 2612 _cmp(Src0RM, Src1); |
2611 _br(getIcmp32Mapping(Inst->getCondition()), NextBr->getTargetTrue(), | 2613 _br(getIcmp32Mapping(Inst->getCondition()), NextBr->getTargetTrue(), |
2612 NextBr->getTargetFalse()); | 2614 NextBr->getTargetFalse()); |
2613 // Skip over the following branch instruction. | 2615 // Skip over the following branch instruction. |
2614 NextBr->setDeleted(); | 2616 NextBr->setDeleted(); |
2615 Context.advanceNext(); | 2617 Context.advanceNext(); |
2616 return; | 2618 return; |
2617 } | 2619 } |
2618 } | 2620 } |
2619 | 2621 |
2620 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: | 2622 // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: |
2621 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 2623 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
2622 Constant *One = Ctx->getConstantInt(IceType_i32, 1); | 2624 Constant *One = Ctx->getConstantInt(IceType_i32, 1); |
2623 if (Src0->getType() == IceType_i64) { | 2625 if (Src0->getType() == IceType_i64) { |
2624 InstIcmp::ICond Condition = Inst->getCondition(); | 2626 InstIcmp::ICond Condition = Inst->getCondition(); |
2625 size_t Index = static_cast<size_t>(Condition); | 2627 size_t Index = static_cast<size_t>(Condition); |
2626 assert(Index < TableIcmp64Size); | 2628 assert(Index < TableIcmp64Size); |
| 2629 Operand *Src0LoRM = legalize(loOperand(Src0), Legal_Reg | Legal_Mem); |
| 2630 Operand *Src0HiRM = legalize(hiOperand(Src0), Legal_Reg | Legal_Mem); |
2627 Operand *Src1LoRI = legalize(loOperand(Src1), Legal_Reg | Legal_Imm); | 2631 Operand *Src1LoRI = legalize(loOperand(Src1), Legal_Reg | Legal_Imm); |
2628 Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm); | 2632 Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm); |
2629 if (Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) { | 2633 if (Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) { |
2630 InstX8632Label *Label = InstX8632Label::create(Func, this); | 2634 InstX8632Label *Label = InstX8632Label::create(Func, this); |
2631 _mov(Dest, (Condition == InstIcmp::Eq ? Zero : One)); | 2635 _mov(Dest, (Condition == InstIcmp::Eq ? Zero : One)); |
2632 _cmp(loOperand(Src0), Src1LoRI); | 2636 _cmp(Src0LoRM, Src1LoRI); |
2633 _br(InstX8632Br::Br_ne, Label); | 2637 _br(InstX8632Br::Br_ne, Label); |
2634 _cmp(hiOperand(Src0), Src1HiRI); | 2638 _cmp(Src0HiRM, Src1HiRI); |
2635 _br(InstX8632Br::Br_ne, Label); | 2639 _br(InstX8632Br::Br_ne, Label); |
2636 Context.insert(InstFakeUse::create(Func, Dest)); | 2640 Context.insert(InstFakeUse::create(Func, Dest)); |
2637 _mov(Dest, (Condition == InstIcmp::Eq ? One : Zero)); | 2641 _mov(Dest, (Condition == InstIcmp::Eq ? One : Zero)); |
2638 Context.insert(Label); | 2642 Context.insert(Label); |
2639 } else { | 2643 } else { |
2640 InstX8632Label *LabelFalse = InstX8632Label::create(Func, this); | 2644 InstX8632Label *LabelFalse = InstX8632Label::create(Func, this); |
2641 InstX8632Label *LabelTrue = InstX8632Label::create(Func, this); | 2645 InstX8632Label *LabelTrue = InstX8632Label::create(Func, this); |
2642 _mov(Dest, One); | 2646 _mov(Dest, One); |
2643 _cmp(hiOperand(Src0), Src1HiRI); | 2647 _cmp(Src0HiRM, Src1HiRI); |
2644 _br(TableIcmp64[Index].C1, LabelTrue); | 2648 _br(TableIcmp64[Index].C1, LabelTrue); |
2645 _br(TableIcmp64[Index].C2, LabelFalse); | 2649 _br(TableIcmp64[Index].C2, LabelFalse); |
2646 _cmp(loOperand(Src0), Src1LoRI); | 2650 _cmp(Src0LoRM, Src1LoRI); |
2647 _br(TableIcmp64[Index].C3, LabelTrue); | 2651 _br(TableIcmp64[Index].C3, LabelTrue); |
2648 Context.insert(LabelFalse); | 2652 Context.insert(LabelFalse); |
2649 Context.insert(InstFakeUse::create(Func, Dest)); | 2653 Context.insert(InstFakeUse::create(Func, Dest)); |
2650 _mov(Dest, Zero); | 2654 _mov(Dest, Zero); |
2651 Context.insert(LabelTrue); | 2655 Context.insert(LabelTrue); |
2652 } | 2656 } |
2653 return; | 2657 return; |
2654 } | 2658 } |
2655 | 2659 |
2656 // cmp b, c | 2660 // cmp b, c |
2657 Operand *Src0New = | 2661 Operand *Src0RM = legalize( |
2658 legalize(Src0, IsSrc1ImmOrReg ? Legal_All : Legal_Reg, true); | 2662 Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg, true); |
2659 InstX8632Label *Label = InstX8632Label::create(Func, this); | 2663 InstX8632Label *Label = InstX8632Label::create(Func, this); |
2660 _cmp(Src0New, Src1); | 2664 _cmp(Src0RM, Src1); |
2661 _mov(Dest, One); | 2665 _mov(Dest, One); |
2662 _br(getIcmp32Mapping(Inst->getCondition()), Label); | 2666 _br(getIcmp32Mapping(Inst->getCondition()), Label); |
2663 Context.insert(InstFakeUse::create(Func, Dest)); | 2667 Context.insert(InstFakeUse::create(Func, Dest)); |
2664 _mov(Dest, Zero); | 2668 _mov(Dest, Zero); |
2665 Context.insert(Label); | 2669 Context.insert(Label); |
2666 } | 2670 } |
2667 | 2671 |
2668 void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { | 2672 void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { |
2669 Operand *SourceVectNotLegalized = Inst->getSrc(0); | 2673 Operand *SourceVectNotLegalized = Inst->getSrc(0); |
2670 Operand *ElementToInsertNotLegalized = Inst->getSrc(1); | 2674 Operand *ElementToInsertNotLegalized = Inst->getSrc(1); |
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3787 _movp(T2, T); | 3791 _movp(T2, T); |
3788 _pand(T, SrcTRM); | 3792 _pand(T, SrcTRM); |
3789 _pandn(T2, SrcFRM); | 3793 _pandn(T2, SrcFRM); |
3790 _por(T, T2); | 3794 _por(T, T2); |
3791 _movp(Dest, T); | 3795 _movp(Dest, T); |
3792 | 3796 |
3793 return; | 3797 return; |
3794 } | 3798 } |
3795 | 3799 |
3796 // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1: | 3800 // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1: |
3797 Operand *ConditionRMI = legalize(Condition); | 3801 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); |
3798 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 3802 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
3799 InstX8632Label *Label = InstX8632Label::create(Func, this); | 3803 InstX8632Label *Label = InstX8632Label::create(Func, this); |
3800 | 3804 |
3801 if (Dest->getType() == IceType_i64) { | 3805 if (Dest->getType() == IceType_i64) { |
3802 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 3806 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
3803 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3807 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
3804 Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm, true); | 3808 Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm, true); |
3805 Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm, true); | 3809 Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm, true); |
3806 _cmp(ConditionRMI, Zero); | 3810 _cmp(ConditionRM, Zero); |
3807 _mov(DestLo, SrcLoRI); | 3811 _mov(DestLo, SrcLoRI); |
3808 _mov(DestHi, SrcHiRI); | 3812 _mov(DestHi, SrcHiRI); |
3809 _br(InstX8632Br::Br_ne, Label); | 3813 _br(InstX8632Br::Br_ne, Label); |
3810 Context.insert(InstFakeUse::create(Func, DestLo)); | 3814 Context.insert(InstFakeUse::create(Func, DestLo)); |
3811 Context.insert(InstFakeUse::create(Func, DestHi)); | 3815 Context.insert(InstFakeUse::create(Func, DestHi)); |
3812 Operand *SrcFLo = loOperand(SrcF); | 3816 Operand *SrcFLo = loOperand(SrcF); |
3813 Operand *SrcFHi = hiOperand(SrcF); | 3817 Operand *SrcFHi = hiOperand(SrcF); |
3814 SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm, true); | 3818 SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm, true); |
3815 SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm, true); | 3819 SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm, true); |
3816 _mov(DestLo, SrcLoRI); | 3820 _mov(DestLo, SrcLoRI); |
3817 _mov(DestHi, SrcHiRI); | 3821 _mov(DestHi, SrcHiRI); |
3818 } else { | 3822 } else { |
3819 _cmp(ConditionRMI, Zero); | 3823 _cmp(ConditionRM, Zero); |
3820 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm, true); | 3824 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm, true); |
3821 _mov(Dest, SrcT); | 3825 _mov(Dest, SrcT); |
3822 _br(InstX8632Br::Br_ne, Label); | 3826 _br(InstX8632Br::Br_ne, Label); |
3823 Context.insert(InstFakeUse::create(Func, Dest)); | 3827 Context.insert(InstFakeUse::create(Func, Dest)); |
3824 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true); | 3828 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true); |
3825 _mov(Dest, SrcF); | 3829 _mov(Dest, SrcF); |
3826 } | 3830 } |
3827 | 3831 |
3828 Context.insert(Label); | 3832 Context.insert(Label); |
3829 } | 3833 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3875 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { | 3879 void TargetX8632::lowerSwitch(const InstSwitch *Inst) { |
3876 // This implements the most naive possible lowering. | 3880 // This implements the most naive possible lowering. |
3877 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default | 3881 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default |
3878 Operand *Src0 = Inst->getComparison(); | 3882 Operand *Src0 = Inst->getComparison(); |
3879 SizeT NumCases = Inst->getNumCases(); | 3883 SizeT NumCases = Inst->getNumCases(); |
3880 // OK, we'll be slightly less naive by forcing Src into a physical | 3884 // OK, we'll be slightly less naive by forcing Src into a physical |
3881 // register if there are 2 or more uses. | 3885 // register if there are 2 or more uses. |
3882 if (NumCases >= 2) | 3886 if (NumCases >= 2) |
3883 Src0 = legalizeToVar(Src0, true); | 3887 Src0 = legalizeToVar(Src0, true); |
3884 else | 3888 else |
3885 Src0 = legalize(Src0, Legal_All, true); | 3889 Src0 = legalize(Src0, Legal_Reg | Legal_Mem, true); |
3886 for (SizeT I = 0; I < NumCases; ++I) { | 3890 for (SizeT I = 0; I < NumCases; ++I) { |
3887 Operand *Value = Ctx->getConstantInt(IceType_i32, Inst->getValue(I)); | 3891 Operand *Value = Ctx->getConstantInt(IceType_i32, Inst->getValue(I)); |
3888 _cmp(Src0, Value); | 3892 _cmp(Src0, Value); |
3889 _br(InstX8632Br::Br_e, Inst->getLabel(I)); | 3893 _br(InstX8632Br::Br_e, Inst->getLabel(I)); |
3890 } | 3894 } |
3891 | 3895 |
3892 _br(Inst->getLabelDefault()); | 3896 _br(Inst->getLabelDefault()); |
3893 } | 3897 } |
3894 | 3898 |
3895 void TargetX8632::scalarizeArithmetic(InstArithmetic::OpKind Kind, | 3899 void TargetX8632::scalarizeArithmetic(InstArithmetic::OpKind Kind, |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4383 Str << "\t.align\t" << Align << "\n"; | 4387 Str << "\t.align\t" << Align << "\n"; |
4384 Str << MangledName << ":\n"; | 4388 Str << MangledName << ":\n"; |
4385 for (SizeT i = 0; i < Size; ++i) { | 4389 for (SizeT i = 0; i < Size; ++i) { |
4386 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4390 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
4387 } | 4391 } |
4388 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4392 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4389 } | 4393 } |
4390 } | 4394 } |
4391 | 4395 |
4392 } // end of namespace Ice | 4396 } // end of namespace Ice |
OLD | NEW |