| 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 |