OLD | NEW |
1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// | 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 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 1906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1917 Registers[i] = false; | 1917 Registers[i] = false; |
1918 if (Entry.StackPtr && (Exclude & RegSet_StackPointer)) | 1918 if (Entry.StackPtr && (Exclude & RegSet_StackPointer)) |
1919 Registers[i] = false; | 1919 Registers[i] = false; |
1920 if (Entry.FramePtr && (Exclude & RegSet_FramePointer)) | 1920 if (Entry.FramePtr && (Exclude & RegSet_FramePointer)) |
1921 Registers[i] = false; | 1921 Registers[i] = false; |
1922 } | 1922 } |
1923 | 1923 |
1924 return Registers; | 1924 return Registers; |
1925 } | 1925 } |
1926 | 1926 |
1927 void TargetARM32::lowerAlloca(const InstAlloca *Inst) { | 1927 void TargetARM32::lowerAlloca(const InstAlloca *Instr) { |
1928 // Conservatively require the stack to be aligned. Some stack adjustment | 1928 // Conservatively require the stack to be aligned. Some stack adjustment |
1929 // operations implemented below assume that the stack is aligned before the | 1929 // operations implemented below assume that the stack is aligned before the |
1930 // alloca. All the alloca code ensures that the stack alignment is preserved | 1930 // alloca. All the alloca code ensures that the stack alignment is preserved |
1931 // after the alloca. The stack alignment restriction can be relaxed in some | 1931 // after the alloca. The stack alignment restriction can be relaxed in some |
1932 // cases. | 1932 // cases. |
1933 NeedsStackAlignment = true; | 1933 NeedsStackAlignment = true; |
1934 | 1934 |
1935 // For default align=0, set it to the real value 1, to avoid any | 1935 // For default align=0, set it to the real value 1, to avoid any |
1936 // bit-manipulation problems below. | 1936 // bit-manipulation problems below. |
1937 const uint32_t AlignmentParam = std::max(1u, Inst->getAlignInBytes()); | 1937 const uint32_t AlignmentParam = std::max(1u, Instr->getAlignInBytes()); |
1938 | 1938 |
1939 // LLVM enforces power of 2 alignment. | 1939 // LLVM enforces power of 2 alignment. |
1940 assert(llvm::isPowerOf2_32(AlignmentParam)); | 1940 assert(llvm::isPowerOf2_32(AlignmentParam)); |
1941 assert(llvm::isPowerOf2_32(ARM32_STACK_ALIGNMENT_BYTES)); | 1941 assert(llvm::isPowerOf2_32(ARM32_STACK_ALIGNMENT_BYTES)); |
1942 | 1942 |
1943 const uint32_t Alignment = | 1943 const uint32_t Alignment = |
1944 std::max(AlignmentParam, ARM32_STACK_ALIGNMENT_BYTES); | 1944 std::max(AlignmentParam, ARM32_STACK_ALIGNMENT_BYTES); |
1945 const bool OverAligned = Alignment > ARM32_STACK_ALIGNMENT_BYTES; | 1945 const bool OverAligned = Alignment > ARM32_STACK_ALIGNMENT_BYTES; |
1946 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; | 1946 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; |
1947 const bool AllocaWithKnownOffset = Inst->getKnownFrameOffset(); | 1947 const bool AllocaWithKnownOffset = Instr->getKnownFrameOffset(); |
1948 const bool UseFramePointer = | 1948 const bool UseFramePointer = |
1949 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1; | 1949 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1; |
1950 | 1950 |
1951 if (UseFramePointer) | 1951 if (UseFramePointer) |
1952 setHasFramePointer(); | 1952 setHasFramePointer(); |
1953 | 1953 |
1954 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); | 1954 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); |
1955 if (OverAligned) { | 1955 if (OverAligned) { |
1956 Sandboxer(this).align_sp(Alignment); | 1956 Sandboxer(this).align_sp(Alignment); |
1957 } | 1957 } |
1958 | 1958 |
1959 Variable *Dest = Inst->getDest(); | 1959 Variable *Dest = Instr->getDest(); |
1960 Operand *TotalSize = Inst->getSizeInBytes(); | 1960 Operand *TotalSize = Instr->getSizeInBytes(); |
1961 | 1961 |
1962 if (const auto *ConstantTotalSize = | 1962 if (const auto *ConstantTotalSize = |
1963 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { | 1963 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { |
1964 const uint32_t Value = | 1964 const uint32_t Value = |
1965 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment); | 1965 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment); |
1966 // Constant size alloca. | 1966 // Constant size alloca. |
1967 if (!UseFramePointer) { | 1967 if (!UseFramePointer) { |
1968 // If we don't need a Frame Pointer, this alloca has a known offset to the | 1968 // If we don't need a Frame Pointer, this alloca has a known offset to the |
1969 // stack pointer. We don't need adjust the stack pointer, nor assign any | 1969 // stack pointer. We don't need adjust the stack pointer, nor assign any |
1970 // value to Dest, as Dest is rematerializable. | 1970 // value to Dest, as Dest is rematerializable. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2055 _mls(T2, T, T1R, T0R); | 2055 _mls(T2, T, T1R, T0R); |
2056 T = T2; | 2056 T = T2; |
2057 } | 2057 } |
2058 _mov(Dest, T); | 2058 _mov(Dest, T); |
2059 } else { | 2059 } else { |
2060 llvm::report_fatal_error("div should have already been turned into a call"); | 2060 llvm::report_fatal_error("div should have already been turned into a call"); |
2061 } | 2061 } |
2062 } | 2062 } |
2063 | 2063 |
2064 TargetARM32::SafeBoolChain | 2064 TargetARM32::SafeBoolChain |
2065 TargetARM32::lowerInt1Arithmetic(const InstArithmetic *Inst) { | 2065 TargetARM32::lowerInt1Arithmetic(const InstArithmetic *Instr) { |
2066 Variable *Dest = Inst->getDest(); | 2066 Variable *Dest = Instr->getDest(); |
2067 assert(Dest->getType() == IceType_i1); | 2067 assert(Dest->getType() == IceType_i1); |
2068 | 2068 |
2069 // So folding didn't work for Inst. Not a problem: We just need to | 2069 // So folding didn't work for Instr. Not a problem: We just need to |
2070 // materialize the Sources, and perform the operation. We create regular | 2070 // materialize the Sources, and perform the operation. We create regular |
2071 // Variables (and not infinite-weight ones) because this call might recurse a | 2071 // Variables (and not infinite-weight ones) because this call might recurse a |
2072 // lot, and we might end up with tons of infinite weight temporaries. | 2072 // lot, and we might end up with tons of infinite weight temporaries. |
2073 assert(Inst->getSrcSize() == 2); | 2073 assert(Instr->getSrcSize() == 2); |
2074 Variable *Src0 = Func->makeVariable(IceType_i1); | 2074 Variable *Src0 = Func->makeVariable(IceType_i1); |
2075 SafeBoolChain Src0Safe = lowerInt1(Src0, Inst->getSrc(0)); | 2075 SafeBoolChain Src0Safe = lowerInt1(Src0, Instr->getSrc(0)); |
2076 | 2076 |
2077 Operand *Src1 = Inst->getSrc(1); | 2077 Operand *Src1 = Instr->getSrc(1); |
2078 SafeBoolChain Src1Safe = SBC_Yes; | 2078 SafeBoolChain Src1Safe = SBC_Yes; |
2079 | 2079 |
2080 if (!llvm::isa<Constant>(Src1)) { | 2080 if (!llvm::isa<Constant>(Src1)) { |
2081 Variable *Src1V = Func->makeVariable(IceType_i1); | 2081 Variable *Src1V = Func->makeVariable(IceType_i1); |
2082 Src1Safe = lowerInt1(Src1V, Src1); | 2082 Src1Safe = lowerInt1(Src1V, Src1); |
2083 Src1 = Src1V; | 2083 Src1 = Src1V; |
2084 } | 2084 } |
2085 | 2085 |
2086 Variable *T = makeReg(IceType_i1); | 2086 Variable *T = makeReg(IceType_i1); |
2087 Src0 = legalizeToReg(Src0); | 2087 Src0 = legalizeToReg(Src0); |
2088 Operand *Src1RF = legalize(Src1, Legal_Reg | Legal_Flex); | 2088 Operand *Src1RF = legalize(Src1, Legal_Reg | Legal_Flex); |
2089 switch (Inst->getOp()) { | 2089 switch (Instr->getOp()) { |
2090 default: | 2090 default: |
2091 // If this Unreachable is ever executed, add the offending operation to | 2091 // If this Unreachable is ever executed, add the offending operation to |
2092 // the list of valid consumers. | 2092 // the list of valid consumers. |
2093 llvm::report_fatal_error("Unhandled i1 Op"); | 2093 llvm::report_fatal_error("Unhandled i1 Op"); |
2094 case InstArithmetic::And: | 2094 case InstArithmetic::And: |
2095 _and(T, Src0, Src1RF); | 2095 _and(T, Src0, Src1RF); |
2096 break; | 2096 break; |
2097 case InstArithmetic::Or: | 2097 case InstArithmetic::Or: |
2098 _orr(T, Src0, Src1RF); | 2098 _orr(T, Src0, Src1RF); |
2099 break; | 2099 break; |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3168 case InstArithmetic::Fsub: | 3168 case InstArithmetic::Fsub: |
3169 case InstArithmetic::Fmul: | 3169 case InstArithmetic::Fmul: |
3170 case InstArithmetic::Fdiv: | 3170 case InstArithmetic::Fdiv: |
3171 case InstArithmetic::Frem: | 3171 case InstArithmetic::Frem: |
3172 llvm::report_fatal_error( | 3172 llvm::report_fatal_error( |
3173 "Floating point arith should have been handled earlier."); | 3173 "Floating point arith should have been handled earlier."); |
3174 return; | 3174 return; |
3175 } | 3175 } |
3176 } | 3176 } |
3177 | 3177 |
3178 void TargetARM32::lowerAssign(const InstAssign *Inst) { | 3178 void TargetARM32::lowerAssign(const InstAssign *Instr) { |
3179 Variable *Dest = Inst->getDest(); | 3179 Variable *Dest = Instr->getDest(); |
3180 | 3180 |
3181 if (Dest->isRematerializable()) { | 3181 if (Dest->isRematerializable()) { |
3182 Context.insert<InstFakeDef>(Dest); | 3182 Context.insert<InstFakeDef>(Dest); |
3183 return; | 3183 return; |
3184 } | 3184 } |
3185 | 3185 |
3186 Operand *Src0 = Inst->getSrc(0); | 3186 Operand *Src0 = Instr->getSrc(0); |
3187 assert(Dest->getType() == Src0->getType()); | 3187 assert(Dest->getType() == Src0->getType()); |
3188 if (Dest->getType() == IceType_i64) { | 3188 if (Dest->getType() == IceType_i64) { |
3189 Src0 = legalizeUndef(Src0); | 3189 Src0 = legalizeUndef(Src0); |
3190 | 3190 |
3191 Variable *T_Lo = makeReg(IceType_i32); | 3191 Variable *T_Lo = makeReg(IceType_i32); |
3192 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 3192 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
3193 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg | Legal_Flex); | 3193 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg | Legal_Flex); |
3194 _mov(T_Lo, Src0Lo); | 3194 _mov(T_Lo, Src0Lo); |
3195 _mov(DestLo, T_Lo); | 3195 _mov(DestLo, T_Lo); |
3196 | 3196 |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3537 } | 3537 } |
3538 | 3538 |
3539 namespace { | 3539 namespace { |
3540 void configureBitcastTemporary(Variable64On32 *Var) { | 3540 void configureBitcastTemporary(Variable64On32 *Var) { |
3541 Var->setMustNotHaveReg(); | 3541 Var->setMustNotHaveReg(); |
3542 Var->getHi()->setMustHaveReg(); | 3542 Var->getHi()->setMustHaveReg(); |
3543 Var->getLo()->setMustHaveReg(); | 3543 Var->getLo()->setMustHaveReg(); |
3544 } | 3544 } |
3545 } // end of anonymous namespace | 3545 } // end of anonymous namespace |
3546 | 3546 |
3547 void TargetARM32::lowerCast(const InstCast *Inst) { | 3547 void TargetARM32::lowerCast(const InstCast *Instr) { |
3548 InstCast::OpKind CastKind = Inst->getCastKind(); | 3548 InstCast::OpKind CastKind = Instr->getCastKind(); |
3549 Variable *Dest = Inst->getDest(); | 3549 Variable *Dest = Instr->getDest(); |
3550 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); | 3550 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); |
3551 switch (CastKind) { | 3551 switch (CastKind) { |
3552 default: | 3552 default: |
3553 Func->setError("Cast type not supported"); | 3553 Func->setError("Cast type not supported"); |
3554 return; | 3554 return; |
3555 case InstCast::Sext: { | 3555 case InstCast::Sext: { |
3556 if (isVectorType(Dest->getType())) { | 3556 if (isVectorType(Dest->getType())) { |
3557 UnimplementedLoweringError(this, Inst); | 3557 UnimplementedLoweringError(this, Instr); |
3558 } else if (Dest->getType() == IceType_i64) { | 3558 } else if (Dest->getType() == IceType_i64) { |
3559 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2 | 3559 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2 |
3560 Constant *ShiftAmt = Ctx->getConstantInt32(31); | 3560 Constant *ShiftAmt = Ctx->getConstantInt32(31); |
3561 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 3561 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
3562 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3562 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
3563 Variable *T_Lo = makeReg(DestLo->getType()); | 3563 Variable *T_Lo = makeReg(DestLo->getType()); |
3564 if (Src0->getType() == IceType_i32) { | 3564 if (Src0->getType() == IceType_i32) { |
3565 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); | 3565 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); |
3566 _mov(T_Lo, Src0RF); | 3566 _mov(T_Lo, Src0RF); |
3567 } else if (Src0->getType() != IceType_i1) { | 3567 } else if (Src0->getType() != IceType_i1) { |
(...skipping 24 matching lines...) Expand all Loading... |
3592 Constant *_0 = Ctx->getConstantZero(IceType_i32); | 3592 Constant *_0 = Ctx->getConstantZero(IceType_i32); |
3593 Operand *_m1 = Ctx->getConstantInt(Dest->getType(), -1); | 3593 Operand *_m1 = Ctx->getConstantInt(Dest->getType(), -1); |
3594 Variable *T = makeReg(Dest->getType()); | 3594 Variable *T = makeReg(Dest->getType()); |
3595 lowerInt1ForSelect(T, Src0, _m1, _0); | 3595 lowerInt1ForSelect(T, Src0, _m1, _0); |
3596 _mov(Dest, T); | 3596 _mov(Dest, T); |
3597 } | 3597 } |
3598 break; | 3598 break; |
3599 } | 3599 } |
3600 case InstCast::Zext: { | 3600 case InstCast::Zext: { |
3601 if (isVectorType(Dest->getType())) { | 3601 if (isVectorType(Dest->getType())) { |
3602 UnimplementedLoweringError(this, Inst); | 3602 UnimplementedLoweringError(this, Instr); |
3603 } else if (Dest->getType() == IceType_i64) { | 3603 } else if (Dest->getType() == IceType_i64) { |
3604 // t1=uxtb src; dst.lo=t1; dst.hi=0 | 3604 // t1=uxtb src; dst.lo=t1; dst.hi=0 |
3605 Operand *_0 = | 3605 Operand *_0 = |
3606 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); | 3606 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); |
3607 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 3607 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
3608 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3608 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
3609 Variable *T_Lo = makeReg(DestLo->getType()); | 3609 Variable *T_Lo = makeReg(DestLo->getType()); |
3610 | 3610 |
3611 switch (Src0->getType()) { | 3611 switch (Src0->getType()) { |
3612 default: { | 3612 default: { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3645 // t1 = uxt src; dst = t1 | 3645 // t1 = uxt src; dst = t1 |
3646 Variable *Src0R = legalizeToReg(Src0); | 3646 Variable *Src0R = legalizeToReg(Src0); |
3647 Variable *T = makeReg(Dest->getType()); | 3647 Variable *T = makeReg(Dest->getType()); |
3648 _uxt(T, Src0R); | 3648 _uxt(T, Src0R); |
3649 _mov(Dest, T); | 3649 _mov(Dest, T); |
3650 } | 3650 } |
3651 break; | 3651 break; |
3652 } | 3652 } |
3653 case InstCast::Trunc: { | 3653 case InstCast::Trunc: { |
3654 if (isVectorType(Dest->getType())) { | 3654 if (isVectorType(Dest->getType())) { |
3655 UnimplementedLoweringError(this, Inst); | 3655 UnimplementedLoweringError(this, Instr); |
3656 } else { | 3656 } else { |
3657 if (Src0->getType() == IceType_i64) | 3657 if (Src0->getType() == IceType_i64) |
3658 Src0 = loOperand(Src0); | 3658 Src0 = loOperand(Src0); |
3659 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); | 3659 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); |
3660 // t1 = trunc Src0RF; Dest = t1 | 3660 // t1 = trunc Src0RF; Dest = t1 |
3661 Variable *T = makeReg(Dest->getType()); | 3661 Variable *T = makeReg(Dest->getType()); |
3662 _mov(T, Src0RF); | 3662 _mov(T, Src0RF); |
3663 if (Dest->getType() == IceType_i1) | 3663 if (Dest->getType() == IceType_i1) |
3664 _and(T, T, Ctx->getConstantInt1(1)); | 3664 _and(T, T, Ctx->getConstantInt1(1)); |
3665 _mov(Dest, T); | 3665 _mov(Dest, T); |
3666 } | 3666 } |
3667 break; | 3667 break; |
3668 } | 3668 } |
3669 case InstCast::Fptrunc: | 3669 case InstCast::Fptrunc: |
3670 case InstCast::Fpext: { | 3670 case InstCast::Fpext: { |
3671 // fptrunc: dest.f32 = fptrunc src0.fp64 | 3671 // fptrunc: dest.f32 = fptrunc src0.fp64 |
3672 // fpext: dest.f64 = fptrunc src0.fp32 | 3672 // fpext: dest.f64 = fptrunc src0.fp32 |
3673 const bool IsTrunc = CastKind == InstCast::Fptrunc; | 3673 const bool IsTrunc = CastKind == InstCast::Fptrunc; |
3674 if (isVectorType(Dest->getType())) { | 3674 if (isVectorType(Dest->getType())) { |
3675 UnimplementedLoweringError(this, Inst); | 3675 UnimplementedLoweringError(this, Instr); |
3676 break; | 3676 break; |
3677 } | 3677 } |
3678 assert(Dest->getType() == (IsTrunc ? IceType_f32 : IceType_f64)); | 3678 assert(Dest->getType() == (IsTrunc ? IceType_f32 : IceType_f64)); |
3679 assert(Src0->getType() == (IsTrunc ? IceType_f64 : IceType_f32)); | 3679 assert(Src0->getType() == (IsTrunc ? IceType_f64 : IceType_f32)); |
3680 Variable *Src0R = legalizeToReg(Src0); | 3680 Variable *Src0R = legalizeToReg(Src0); |
3681 Variable *T = makeReg(Dest->getType()); | 3681 Variable *T = makeReg(Dest->getType()); |
3682 _vcvt(T, Src0R, IsTrunc ? InstARM32Vcvt::D2s : InstARM32Vcvt::S2d); | 3682 _vcvt(T, Src0R, IsTrunc ? InstARM32Vcvt::D2s : InstARM32Vcvt::S2d); |
3683 _mov(Dest, T); | 3683 _mov(Dest, T); |
3684 break; | 3684 break; |
3685 } | 3685 } |
3686 case InstCast::Fptosi: | 3686 case InstCast::Fptosi: |
3687 case InstCast::Fptoui: { | 3687 case InstCast::Fptoui: { |
3688 if (isVectorType(Dest->getType())) { | 3688 if (isVectorType(Dest->getType())) { |
3689 UnimplementedLoweringError(this, Inst); | 3689 UnimplementedLoweringError(this, Instr); |
3690 break; | 3690 break; |
3691 } | 3691 } |
3692 | 3692 |
3693 const bool DestIsSigned = CastKind == InstCast::Fptosi; | 3693 const bool DestIsSigned = CastKind == InstCast::Fptosi; |
3694 const bool Src0IsF32 = isFloat32Asserting32Or64(Src0->getType()); | 3694 const bool Src0IsF32 = isFloat32Asserting32Or64(Src0->getType()); |
3695 if (llvm::isa<Variable64On32>(Dest)) { | 3695 if (llvm::isa<Variable64On32>(Dest)) { |
3696 llvm::report_fatal_error("fp-to-i64 should have been pre-lowered."); | 3696 llvm::report_fatal_error("fp-to-i64 should have been pre-lowered."); |
3697 } | 3697 } |
3698 // fptosi: | 3698 // fptosi: |
3699 // t1.fp = vcvt src0.fp | 3699 // t1.fp = vcvt src0.fp |
(...skipping 15 matching lines...) Expand all Loading... |
3715 Variable *T_1 = makeReg(Dest->getType()); | 3715 Variable *T_1 = makeReg(Dest->getType()); |
3716 lowerCast(InstCast::create(Func, InstCast::Trunc, T_1, T)); | 3716 lowerCast(InstCast::create(Func, InstCast::Trunc, T_1, T)); |
3717 T = T_1; | 3717 T = T_1; |
3718 } | 3718 } |
3719 _mov(Dest, T); | 3719 _mov(Dest, T); |
3720 break; | 3720 break; |
3721 } | 3721 } |
3722 case InstCast::Sitofp: | 3722 case InstCast::Sitofp: |
3723 case InstCast::Uitofp: { | 3723 case InstCast::Uitofp: { |
3724 if (isVectorType(Dest->getType())) { | 3724 if (isVectorType(Dest->getType())) { |
3725 UnimplementedLoweringError(this, Inst); | 3725 UnimplementedLoweringError(this, Instr); |
3726 break; | 3726 break; |
3727 } | 3727 } |
3728 const bool SourceIsSigned = CastKind == InstCast::Sitofp; | 3728 const bool SourceIsSigned = CastKind == InstCast::Sitofp; |
3729 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); | 3729 const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); |
3730 if (Src0->getType() == IceType_i64) { | 3730 if (Src0->getType() == IceType_i64) { |
3731 llvm::report_fatal_error("i64-to-fp should have been pre-lowered."); | 3731 llvm::report_fatal_error("i64-to-fp should have been pre-lowered."); |
3732 } | 3732 } |
3733 // sitofp: | 3733 // sitofp: |
3734 // t1.i32 = sext src.int @ sign-extends src0 if needed. | 3734 // t1.i32 = sext src.int @ sign-extends src0 if needed. |
3735 // t2.fp32 = vmov t1.i32 | 3735 // t2.fp32 = vmov t1.i32 |
(...skipping 16 matching lines...) Expand all Loading... |
3752 Variable *T = makeReg(Dest->getType()); | 3752 Variable *T = makeReg(Dest->getType()); |
3753 const InstARM32Vcvt::VcvtVariant Conversion = | 3753 const InstARM32Vcvt::VcvtVariant Conversion = |
3754 DestIsF32 | 3754 DestIsF32 |
3755 ? (SourceIsSigned ? InstARM32Vcvt::Si2s : InstARM32Vcvt::Ui2s) | 3755 ? (SourceIsSigned ? InstARM32Vcvt::Si2s : InstARM32Vcvt::Ui2s) |
3756 : (SourceIsSigned ? InstARM32Vcvt::Si2d : InstARM32Vcvt::Ui2d); | 3756 : (SourceIsSigned ? InstARM32Vcvt::Si2d : InstARM32Vcvt::Ui2d); |
3757 _vcvt(T, Src0R, Conversion); | 3757 _vcvt(T, Src0R, Conversion); |
3758 _mov(Dest, T); | 3758 _mov(Dest, T); |
3759 break; | 3759 break; |
3760 } | 3760 } |
3761 case InstCast::Bitcast: { | 3761 case InstCast::Bitcast: { |
3762 Operand *Src0 = Inst->getSrc(0); | 3762 Operand *Src0 = Instr->getSrc(0); |
3763 if (Dest->getType() == Src0->getType()) { | 3763 if (Dest->getType() == Src0->getType()) { |
3764 auto *Assign = InstAssign::create(Func, Dest, Src0); | 3764 auto *Assign = InstAssign::create(Func, Dest, Src0); |
3765 lowerAssign(Assign); | 3765 lowerAssign(Assign); |
3766 return; | 3766 return; |
3767 } | 3767 } |
3768 Type DestType = Dest->getType(); | 3768 Type DestType = Dest->getType(); |
3769 switch (DestType) { | 3769 switch (DestType) { |
3770 case IceType_NUM: | 3770 case IceType_NUM: |
3771 case IceType_void: | 3771 case IceType_void: |
3772 llvm::report_fatal_error("Unexpected bitcast."); | 3772 llvm::report_fatal_error("Unexpected bitcast."); |
3773 case IceType_i1: | 3773 case IceType_i1: |
3774 UnimplementedLoweringError(this, Inst); | 3774 UnimplementedLoweringError(this, Instr); |
3775 break; | 3775 break; |
3776 case IceType_i8: | 3776 case IceType_i8: |
3777 UnimplementedLoweringError(this, Inst); | 3777 UnimplementedLoweringError(this, Instr); |
3778 break; | 3778 break; |
3779 case IceType_i16: | 3779 case IceType_i16: |
3780 UnimplementedLoweringError(this, Inst); | 3780 UnimplementedLoweringError(this, Instr); |
3781 break; | 3781 break; |
3782 case IceType_i32: | 3782 case IceType_i32: |
3783 case IceType_f32: { | 3783 case IceType_f32: { |
3784 Variable *Src0R = legalizeToReg(Src0); | 3784 Variable *Src0R = legalizeToReg(Src0); |
3785 Variable *T = makeReg(DestType); | 3785 Variable *T = makeReg(DestType); |
3786 _mov(T, Src0R); | 3786 _mov(T, Src0R); |
3787 lowerAssign(InstAssign::create(Func, Dest, T)); | 3787 lowerAssign(InstAssign::create(Func, Dest, T)); |
3788 break; | 3788 break; |
3789 } | 3789 } |
3790 case IceType_i64: { | 3790 case IceType_i64: { |
(...skipping 26 matching lines...) Expand all Loading... |
3817 lowerAssign(InstAssign::create(Func, Dest, T)); | 3817 lowerAssign(InstAssign::create(Func, Dest, T)); |
3818 break; | 3818 break; |
3819 } | 3819 } |
3820 case IceType_v4i1: | 3820 case IceType_v4i1: |
3821 case IceType_v8i1: | 3821 case IceType_v8i1: |
3822 case IceType_v16i1: | 3822 case IceType_v16i1: |
3823 case IceType_v8i16: | 3823 case IceType_v8i16: |
3824 case IceType_v16i8: | 3824 case IceType_v16i8: |
3825 case IceType_v4f32: | 3825 case IceType_v4f32: |
3826 case IceType_v4i32: { | 3826 case IceType_v4i32: { |
3827 UnimplementedLoweringError(this, Inst); | 3827 UnimplementedLoweringError(this, Instr); |
3828 break; | 3828 break; |
3829 } | 3829 } |
3830 } | 3830 } |
3831 break; | 3831 break; |
3832 } | 3832 } |
3833 } | 3833 } |
3834 } | 3834 } |
3835 | 3835 |
3836 void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) { | 3836 void TargetARM32::lowerExtractElement(const InstExtractElement *Instr) { |
3837 UnimplementedLoweringError(this, Inst); | 3837 UnimplementedLoweringError(this, Instr); |
3838 } | 3838 } |
3839 | 3839 |
3840 namespace { | 3840 namespace { |
3841 // Validates FCMPARM32_TABLE's declaration w.r.t. InstFcmp::FCondition ordering | 3841 // Validates FCMPARM32_TABLE's declaration w.r.t. InstFcmp::FCondition ordering |
3842 // (and naming). | 3842 // (and naming). |
3843 enum { | 3843 enum { |
3844 #define X(val, CC0, CC1) _fcmp_ll_##val, | 3844 #define X(val, CC0, CC1) _fcmp_ll_##val, |
3845 FCMPARM32_TABLE | 3845 FCMPARM32_TABLE |
3846 #undef X | 3846 #undef X |
3847 _fcmp_ll_NUM | 3847 _fcmp_ll_NUM |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4148 if (Srcs.swappedOperands()) { | 4148 if (Srcs.swappedOperands()) { |
4149 _cmp(ConstR, NonConstF); | 4149 _cmp(ConstR, NonConstF); |
4150 } else { | 4150 } else { |
4151 Variable *T = makeReg(IceType_i32); | 4151 Variable *T = makeReg(IceType_i32); |
4152 _rsbs(T, ConstR, NonConstF); | 4152 _rsbs(T, ConstR, NonConstF); |
4153 Context.insert<InstFakeUse>(T); | 4153 Context.insert<InstFakeUse>(T); |
4154 } | 4154 } |
4155 return CondWhenTrue(getIcmp32Mapping(Condition)); | 4155 return CondWhenTrue(getIcmp32Mapping(Condition)); |
4156 } | 4156 } |
4157 | 4157 |
4158 TargetARM32::CondWhenTrue TargetARM32::lowerIcmpCond(const InstIcmp *Inst) { | 4158 TargetARM32::CondWhenTrue TargetARM32::lowerIcmpCond(const InstIcmp *Instr) { |
4159 assert(Inst->getSrc(0)->getType() != IceType_i1); | 4159 assert(Instr->getSrc(0)->getType() != IceType_i1); |
4160 assert(Inst->getSrc(1)->getType() != IceType_i1); | 4160 assert(Instr->getSrc(1)->getType() != IceType_i1); |
4161 | 4161 |
4162 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); | 4162 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); |
4163 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); | 4163 Operand *Src1 = legalizeUndef(Instr->getSrc(1)); |
4164 | 4164 |
4165 const InstIcmp::ICond Condition = Inst->getCondition(); | 4165 const InstIcmp::ICond Condition = Instr->getCondition(); |
4166 // a=icmp cond b, c ==> | 4166 // a=icmp cond b, c ==> |
4167 // GCC does: | 4167 // GCC does: |
4168 // <u/s>xtb tb, b | 4168 // <u/s>xtb tb, b |
4169 // <u/s>xtb tc, c | 4169 // <u/s>xtb tc, c |
4170 // cmp tb, tc | 4170 // cmp tb, tc |
4171 // mov.C1 t, #0 | 4171 // mov.C1 t, #0 |
4172 // mov.C2 t, #1 | 4172 // mov.C2 t, #1 |
4173 // mov a, t | 4173 // mov a, t |
4174 // where the unsigned/sign extension is not needed for 32-bit. They also have | 4174 // where the unsigned/sign extension is not needed for 32-bit. They also have |
4175 // special cases for EQ and NE. E.g., for NE: | 4175 // special cases for EQ and NE. E.g., for NE: |
(...skipping 22 matching lines...) Expand all Loading... |
4198 case IceType_i8: | 4198 case IceType_i8: |
4199 case IceType_i16: | 4199 case IceType_i16: |
4200 return lowerInt8AndInt16IcmpCond(Condition, Src0, Src1); | 4200 return lowerInt8AndInt16IcmpCond(Condition, Src0, Src1); |
4201 case IceType_i32: | 4201 case IceType_i32: |
4202 return lowerInt32IcmpCond(Condition, Src0, Src1); | 4202 return lowerInt32IcmpCond(Condition, Src0, Src1); |
4203 case IceType_i64: | 4203 case IceType_i64: |
4204 return lowerInt64IcmpCond(Condition, Src0, Src1); | 4204 return lowerInt64IcmpCond(Condition, Src0, Src1); |
4205 } | 4205 } |
4206 } | 4206 } |
4207 | 4207 |
4208 void TargetARM32::lowerIcmp(const InstIcmp *Inst) { | 4208 void TargetARM32::lowerIcmp(const InstIcmp *Instr) { |
4209 Variable *Dest = Inst->getDest(); | 4209 Variable *Dest = Instr->getDest(); |
4210 | 4210 |
4211 if (isVectorType(Dest->getType())) { | 4211 if (isVectorType(Dest->getType())) { |
4212 UnimplementedLoweringError(this, Inst); | 4212 UnimplementedLoweringError(this, Instr); |
4213 return; | 4213 return; |
4214 } | 4214 } |
4215 | 4215 |
4216 Operand *_0 = | 4216 Operand *_0 = |
4217 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); | 4217 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); |
4218 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex); | 4218 Operand *_1 = legalize(Ctx->getConstantInt32(1), Legal_Reg | Legal_Flex); |
4219 Variable *T = makeReg(IceType_i1); | 4219 Variable *T = makeReg(IceType_i1); |
4220 | 4220 |
4221 _mov(T, _0); | 4221 _mov(T, _0); |
4222 CondWhenTrue Cond = lowerIcmpCond(Inst); | 4222 CondWhenTrue Cond = lowerIcmpCond(Instr); |
4223 _mov_redefined(T, _1, Cond.WhenTrue0); | 4223 _mov_redefined(T, _1, Cond.WhenTrue0); |
4224 _mov(Dest, T); | 4224 _mov(Dest, T); |
4225 | 4225 |
4226 assert(Cond.WhenTrue1 == CondARM32::kNone); | 4226 assert(Cond.WhenTrue1 == CondARM32::kNone); |
4227 | 4227 |
4228 return; | 4228 return; |
4229 } | 4229 } |
4230 | 4230 |
4231 void TargetARM32::lowerInsertElement(const InstInsertElement *Inst) { | 4231 void TargetARM32::lowerInsertElement(const InstInsertElement *Instr) { |
4232 UnimplementedLoweringError(this, Inst); | 4232 UnimplementedLoweringError(this, Instr); |
4233 } | 4233 } |
4234 | 4234 |
4235 namespace { | 4235 namespace { |
4236 inline uint64_t getConstantMemoryOrder(Operand *Opnd) { | 4236 inline uint64_t getConstantMemoryOrder(Operand *Opnd) { |
4237 if (auto *Integer = llvm::dyn_cast<ConstantInteger32>(Opnd)) | 4237 if (auto *Integer = llvm::dyn_cast<ConstantInteger32>(Opnd)) |
4238 return Integer->getValue(); | 4238 return Integer->getValue(); |
4239 return Intrinsics::MemoryOrderInvalid; | 4239 return Intrinsics::MemoryOrderInvalid; |
4240 } | 4240 } |
4241 } // end of anonymous namespace | 4241 } // end of anonymous namespace |
4242 | 4242 |
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4931 } | 4931 } |
4932 } | 4932 } |
4933 | 4933 |
4934 if (Optimized) { | 4934 if (Optimized) { |
4935 *Reason = VarAssign; | 4935 *Reason = VarAssign; |
4936 } | 4936 } |
4937 | 4937 |
4938 return Optimized; | 4938 return Optimized; |
4939 } | 4939 } |
4940 | 4940 |
4941 bool isAddOrSub(const Inst *Inst, InstArithmetic::OpKind *Kind) { | 4941 bool isAddOrSub(const Inst *Instr, InstArithmetic::OpKind *Kind) { |
4942 if (const auto *Arith = llvm::dyn_cast<InstArithmetic>(Inst)) { | 4942 if (const auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) { |
4943 switch (Arith->getOp()) { | 4943 switch (Arith->getOp()) { |
4944 default: | 4944 default: |
4945 return false; | 4945 return false; |
4946 case InstArithmetic::Add: | 4946 case InstArithmetic::Add: |
4947 case InstArithmetic::Sub: | 4947 case InstArithmetic::Sub: |
4948 *Kind = Arith->getOp(); | 4948 *Kind = Arith->getOp(); |
4949 return true; | 4949 return true; |
4950 } | 4950 } |
4951 } | 4951 } |
4952 return false; | 4952 return false; |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5309 } | 5309 } |
5310 | 5310 |
5311 void TargetARM32::randomlyInsertNop(float Probability, | 5311 void TargetARM32::randomlyInsertNop(float Probability, |
5312 RandomNumberGenerator &RNG) { | 5312 RandomNumberGenerator &RNG) { |
5313 RandomNumberGeneratorWrapper RNGW(RNG); | 5313 RandomNumberGeneratorWrapper RNGW(RNG); |
5314 if (RNGW.getTrueWithProbability(Probability)) { | 5314 if (RNGW.getTrueWithProbability(Probability)) { |
5315 UnimplementedError(Func->getContext()->getFlags()); | 5315 UnimplementedError(Func->getContext()->getFlags()); |
5316 } | 5316 } |
5317 } | 5317 } |
5318 | 5318 |
5319 void TargetARM32::lowerPhi(const InstPhi * /*Inst*/) { | 5319 void TargetARM32::lowerPhi(const InstPhi * /*Instr*/) { |
5320 Func->setError("Phi found in regular instruction list"); | 5320 Func->setError("Phi found in regular instruction list"); |
5321 } | 5321 } |
5322 | 5322 |
5323 void TargetARM32::lowerRet(const InstRet *Inst) { | 5323 void TargetARM32::lowerRet(const InstRet *Instr) { |
5324 Variable *Reg = nullptr; | 5324 Variable *Reg = nullptr; |
5325 if (Inst->hasRetValue()) { | 5325 if (Instr->hasRetValue()) { |
5326 Operand *Src0 = Inst->getRetValue(); | 5326 Operand *Src0 = Instr->getRetValue(); |
5327 Type Ty = Src0->getType(); | 5327 Type Ty = Src0->getType(); |
5328 if (Ty == IceType_i64) { | 5328 if (Ty == IceType_i64) { |
5329 Src0 = legalizeUndef(Src0); | 5329 Src0 = legalizeUndef(Src0); |
5330 Variable *R0 = legalizeToReg(loOperand(Src0), RegARM32::Reg_r0); | 5330 Variable *R0 = legalizeToReg(loOperand(Src0), RegARM32::Reg_r0); |
5331 Variable *R1 = legalizeToReg(hiOperand(Src0), RegARM32::Reg_r1); | 5331 Variable *R1 = legalizeToReg(hiOperand(Src0), RegARM32::Reg_r1); |
5332 Reg = R0; | 5332 Reg = R0; |
5333 Context.insert<InstFakeUse>(R1); | 5333 Context.insert<InstFakeUse>(R1); |
5334 } else if (Ty == IceType_f32) { | 5334 } else if (Ty == IceType_f32) { |
5335 Variable *S0 = legalizeToReg(Src0, RegARM32::Reg_s0); | 5335 Variable *S0 = legalizeToReg(Src0, RegARM32::Reg_s0); |
5336 Reg = S0; | 5336 Reg = S0; |
(...skipping 16 matching lines...) Expand all Loading... |
5353 _ret(getPhysicalRegister(RegARM32::Reg_lr), Reg); | 5353 _ret(getPhysicalRegister(RegARM32::Reg_lr), Reg); |
5354 | 5354 |
5355 // Add a fake use of sp to make sure sp stays alive for the entire function. | 5355 // Add a fake use of sp to make sure sp stays alive for the entire function. |
5356 // Otherwise post-call sp adjustments get dead-code eliminated. | 5356 // Otherwise post-call sp adjustments get dead-code eliminated. |
5357 // TODO: Are there more places where the fake use should be inserted? E.g. | 5357 // TODO: Are there more places where the fake use should be inserted? E.g. |
5358 // "void f(int n){while(1) g(n);}" may not have a ret instruction. | 5358 // "void f(int n){while(1) g(n);}" may not have a ret instruction. |
5359 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); | 5359 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); |
5360 Context.insert<InstFakeUse>(SP); | 5360 Context.insert<InstFakeUse>(SP); |
5361 } | 5361 } |
5362 | 5362 |
5363 void TargetARM32::lowerSelect(const InstSelect *Inst) { | 5363 void TargetARM32::lowerSelect(const InstSelect *Instr) { |
5364 Variable *Dest = Inst->getDest(); | 5364 Variable *Dest = Instr->getDest(); |
5365 Type DestTy = Dest->getType(); | 5365 Type DestTy = Dest->getType(); |
5366 Operand *SrcT = Inst->getTrueOperand(); | 5366 Operand *SrcT = Instr->getTrueOperand(); |
5367 Operand *SrcF = Inst->getFalseOperand(); | 5367 Operand *SrcF = Instr->getFalseOperand(); |
5368 Operand *Condition = Inst->getCondition(); | 5368 Operand *Condition = Instr->getCondition(); |
5369 | 5369 |
5370 if (isVectorType(DestTy)) { | 5370 if (isVectorType(DestTy)) { |
5371 UnimplementedLoweringError(this, Inst); | 5371 UnimplementedLoweringError(this, Instr); |
5372 return; | 5372 return; |
5373 } | 5373 } |
5374 | 5374 |
5375 lowerInt1ForSelect(Dest, Condition, legalizeUndef(SrcT), legalizeUndef(SrcF)); | 5375 lowerInt1ForSelect(Dest, Condition, legalizeUndef(SrcT), legalizeUndef(SrcF)); |
5376 } | 5376 } |
5377 | 5377 |
5378 void TargetARM32::lowerStore(const InstStore *Inst) { | 5378 void TargetARM32::lowerStore(const InstStore *Instr) { |
5379 Operand *Value = Inst->getData(); | 5379 Operand *Value = Instr->getData(); |
5380 Operand *Addr = Inst->getAddr(); | 5380 Operand *Addr = Instr->getAddr(); |
5381 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType()); | 5381 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType()); |
5382 Type Ty = NewAddr->getType(); | 5382 Type Ty = NewAddr->getType(); |
5383 | 5383 |
5384 if (Ty == IceType_i64) { | 5384 if (Ty == IceType_i64) { |
5385 Value = legalizeUndef(Value); | 5385 Value = legalizeUndef(Value); |
5386 Variable *ValueHi = legalizeToReg(hiOperand(Value)); | 5386 Variable *ValueHi = legalizeToReg(hiOperand(Value)); |
5387 Variable *ValueLo = legalizeToReg(loOperand(Value)); | 5387 Variable *ValueLo = legalizeToReg(loOperand(Value)); |
5388 _str(ValueHi, llvm::cast<OperandARM32Mem>(hiOperand(NewAddr))); | 5388 _str(ValueHi, llvm::cast<OperandARM32Mem>(hiOperand(NewAddr))); |
5389 _str(ValueLo, llvm::cast<OperandARM32Mem>(loOperand(NewAddr))); | 5389 _str(ValueLo, llvm::cast<OperandARM32Mem>(loOperand(NewAddr))); |
5390 } else { | 5390 } else { |
5391 Variable *ValueR = legalizeToReg(Value); | 5391 Variable *ValueR = legalizeToReg(Value); |
5392 _str(ValueR, NewAddr); | 5392 _str(ValueR, NewAddr); |
5393 } | 5393 } |
5394 } | 5394 } |
5395 | 5395 |
5396 void TargetARM32::doAddressOptStore() { | 5396 void TargetARM32::doAddressOptStore() { |
5397 Inst *Instr = Context.getCur(); | 5397 Inst *Instr = Context.getCur(); |
5398 assert(llvm::isa<InstStore>(Instr)); | 5398 assert(llvm::isa<InstStore>(Instr)); |
5399 Operand *Src = Instr->getSrc(0); | 5399 Operand *Src = Instr->getSrc(0); |
5400 Operand *Addr = Instr->getSrc(1); | 5400 Operand *Addr = Instr->getSrc(1); |
5401 if (OperandARM32Mem *Mem = | 5401 if (OperandARM32Mem *Mem = |
5402 formAddressingMode(Src->getType(), Func, Instr, Addr)) { | 5402 formAddressingMode(Src->getType(), Func, Instr, Addr)) { |
5403 Instr->setDeleted(); | 5403 Instr->setDeleted(); |
5404 Context.insert<InstStore>(Src, Mem); | 5404 Context.insert<InstStore>(Src, Mem); |
5405 } | 5405 } |
5406 } | 5406 } |
5407 | 5407 |
5408 void TargetARM32::lowerSwitch(const InstSwitch *Inst) { | 5408 void TargetARM32::lowerSwitch(const InstSwitch *Instr) { |
5409 // This implements the most naive possible lowering. | 5409 // This implements the most naive possible lowering. |
5410 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default | 5410 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default |
5411 Operand *Src0 = Inst->getComparison(); | 5411 Operand *Src0 = Instr->getComparison(); |
5412 SizeT NumCases = Inst->getNumCases(); | 5412 SizeT NumCases = Instr->getNumCases(); |
5413 if (Src0->getType() == IceType_i64) { | 5413 if (Src0->getType() == IceType_i64) { |
5414 Src0 = legalizeUndef(Src0); | 5414 Src0 = legalizeUndef(Src0); |
5415 Variable *Src0Lo = legalizeToReg(loOperand(Src0)); | 5415 Variable *Src0Lo = legalizeToReg(loOperand(Src0)); |
5416 Variable *Src0Hi = legalizeToReg(hiOperand(Src0)); | 5416 Variable *Src0Hi = legalizeToReg(hiOperand(Src0)); |
5417 for (SizeT I = 0; I < NumCases; ++I) { | 5417 for (SizeT I = 0; I < NumCases; ++I) { |
5418 Operand *ValueLo = Ctx->getConstantInt32(Inst->getValue(I)); | 5418 Operand *ValueLo = Ctx->getConstantInt32(Instr->getValue(I)); |
5419 Operand *ValueHi = Ctx->getConstantInt32(Inst->getValue(I) >> 32); | 5419 Operand *ValueHi = Ctx->getConstantInt32(Instr->getValue(I) >> 32); |
5420 ValueLo = legalize(ValueLo, Legal_Reg | Legal_Flex); | 5420 ValueLo = legalize(ValueLo, Legal_Reg | Legal_Flex); |
5421 ValueHi = legalize(ValueHi, Legal_Reg | Legal_Flex); | 5421 ValueHi = legalize(ValueHi, Legal_Reg | Legal_Flex); |
5422 _cmp(Src0Lo, ValueLo); | 5422 _cmp(Src0Lo, ValueLo); |
5423 _cmp(Src0Hi, ValueHi, CondARM32::EQ); | 5423 _cmp(Src0Hi, ValueHi, CondARM32::EQ); |
5424 _br(Inst->getLabel(I), CondARM32::EQ); | 5424 _br(Instr->getLabel(I), CondARM32::EQ); |
5425 } | 5425 } |
5426 _br(Inst->getLabelDefault()); | 5426 _br(Instr->getLabelDefault()); |
5427 return; | 5427 return; |
5428 } | 5428 } |
5429 | 5429 |
5430 Variable *Src0Var = legalizeToReg(Src0); | 5430 Variable *Src0Var = legalizeToReg(Src0); |
5431 // If Src0 is not an i32, we left shift it -- see the icmp lowering for the | 5431 // If Src0 is not an i32, we left shift it -- see the icmp lowering for the |
5432 // reason. | 5432 // reason. |
5433 assert(Src0Var->mustHaveReg()); | 5433 assert(Src0Var->mustHaveReg()); |
5434 const size_t ShiftAmt = 32 - getScalarIntBitWidth(Src0->getType()); | 5434 const size_t ShiftAmt = 32 - getScalarIntBitWidth(Src0->getType()); |
5435 assert(ShiftAmt < 32); | 5435 assert(ShiftAmt < 32); |
5436 if (ShiftAmt > 0) { | 5436 if (ShiftAmt > 0) { |
5437 Operand *ShAmtImm = shAmtImm(ShiftAmt); | 5437 Operand *ShAmtImm = shAmtImm(ShiftAmt); |
5438 Variable *T = makeReg(IceType_i32); | 5438 Variable *T = makeReg(IceType_i32); |
5439 _lsl(T, Src0Var, ShAmtImm); | 5439 _lsl(T, Src0Var, ShAmtImm); |
5440 Src0Var = T; | 5440 Src0Var = T; |
5441 } | 5441 } |
5442 | 5442 |
5443 for (SizeT I = 0; I < NumCases; ++I) { | 5443 for (SizeT I = 0; I < NumCases; ++I) { |
5444 Operand *Value = Ctx->getConstantInt32(Inst->getValue(I) << ShiftAmt); | 5444 Operand *Value = Ctx->getConstantInt32(Instr->getValue(I) << ShiftAmt); |
5445 Value = legalize(Value, Legal_Reg | Legal_Flex); | 5445 Value = legalize(Value, Legal_Reg | Legal_Flex); |
5446 _cmp(Src0Var, Value); | 5446 _cmp(Src0Var, Value); |
5447 _br(Inst->getLabel(I), CondARM32::EQ); | 5447 _br(Instr->getLabel(I), CondARM32::EQ); |
5448 } | 5448 } |
5449 _br(Inst->getLabelDefault()); | 5449 _br(Instr->getLabelDefault()); |
5450 } | 5450 } |
5451 | 5451 |
5452 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Inst*/) { | 5452 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Instr*/) { |
5453 _trap(); | 5453 _trap(); |
5454 } | 5454 } |
5455 | 5455 |
5456 void TargetARM32::prelowerPhis() { | 5456 void TargetARM32::prelowerPhis() { |
5457 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func); | 5457 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func); |
5458 } | 5458 } |
5459 | 5459 |
5460 Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) { | 5460 Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) { |
5461 Variable *Reg = makeReg(Ty, RegNum); | 5461 Variable *Reg = makeReg(Ty, RegNum); |
5462 Context.insert<InstFakeDef>(Reg); | 5462 Context.insert<InstFakeDef>(Reg); |
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6523 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 6523 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
6524 } | 6524 } |
6525 | 6525 |
6526 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; | 6526 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; |
6527 llvm::SmallBitVector | 6527 llvm::SmallBitVector |
6528 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; | 6528 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; |
6529 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 6529 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
6530 | 6530 |
6531 } // end of namespace ARM32 | 6531 } // end of namespace ARM32 |
6532 } // end of namespace Ice | 6532 } // end of namespace Ice |
OLD | NEW |