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 2092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2103 // t3.fp = vcvt.{fp}.s32 @ fp is either f32 or f64 | 2103 // t3.fp = vcvt.{fp}.s32 @ fp is either f32 or f64 |
2104 // uitofp: | 2104 // uitofp: |
2105 // t1.i32 = zext src.int @ zero-extends src0 if needed. | 2105 // t1.i32 = zext src.int @ zero-extends src0 if needed. |
2106 // t2.fp32 = vmov t1.i32 | 2106 // t2.fp32 = vmov t1.i32 |
2107 // t3.fp = vcvt.{fp}.s32 @ fp is either f32 or f64 | 2107 // t3.fp = vcvt.{fp}.s32 @ fp is either f32 or f64 |
2108 if (isVectorType(Dest->getType())) { | 2108 if (isVectorType(Dest->getType())) { |
2109 UnimplementedError(Func->getContext()->getFlags()); | 2109 UnimplementedError(Func->getContext()->getFlags()); |
2110 break; | 2110 break; |
2111 } | 2111 } |
2112 if (Src0->getType() == IceType_i64) { | 2112 if (Src0->getType() == IceType_i64) { |
2113 // avoid cryptic liveness errors | 2113 // avoid liveness errors |
2114 Context.insert(InstFakeDef::create(Func, Dest)); | 2114 Context.insert(InstFakeDef::create(Func, Dest)); |
2115 UnimplementedError(Func->getContext()->getFlags()); | 2115 UnimplementedError(Func->getContext()->getFlags()); |
2116 break; | 2116 break; |
2117 } | 2117 } |
2118 const bool SourceIsSigned = CastKind == InstCast::Sitofp; | 2118 const bool SourceIsSigned = CastKind == InstCast::Sitofp; |
2119 if (Src0->getType() != IceType_i32) { | 2119 if (Src0->getType() != IceType_i32) { |
2120 Variable *Src0R_32 = makeReg(IceType_i32); | 2120 Variable *Src0R_32 = makeReg(IceType_i32); |
2121 lowerCast(InstCast::create(Func, SourceIsSigned ? InstCast::Sext | 2121 lowerCast(InstCast::create(Func, SourceIsSigned ? InstCast::Sext |
2122 : InstCast::Zext, | 2122 : InstCast::Zext, |
2123 Src0R_32, Src0)); | 2123 Src0R_32, Src0)); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2203 case IceType_v16i1: | 2203 case IceType_v16i1: |
2204 UnimplementedError(Func->getContext()->getFlags()); | 2204 UnimplementedError(Func->getContext()->getFlags()); |
2205 break; | 2205 break; |
2206 case IceType_v8i16: | 2206 case IceType_v8i16: |
2207 UnimplementedError(Func->getContext()->getFlags()); | 2207 UnimplementedError(Func->getContext()->getFlags()); |
2208 break; | 2208 break; |
2209 case IceType_v16i8: | 2209 case IceType_v16i8: |
2210 UnimplementedError(Func->getContext()->getFlags()); | 2210 UnimplementedError(Func->getContext()->getFlags()); |
2211 break; | 2211 break; |
2212 case IceType_v4i32: | 2212 case IceType_v4i32: |
2213 // avoid cryptic liveness errors | 2213 // avoid liveness errors |
2214 Context.insert(InstFakeDef::create(Func, Dest)); | 2214 Context.insert(InstFakeDef::create(Func, Dest)); |
2215 UnimplementedError(Func->getContext()->getFlags()); | 2215 UnimplementedError(Func->getContext()->getFlags()); |
2216 break; | 2216 break; |
2217 case IceType_v4f32: | 2217 case IceType_v4f32: |
2218 UnimplementedError(Func->getContext()->getFlags()); | 2218 UnimplementedError(Func->getContext()->getFlags()); |
2219 break; | 2219 break; |
2220 } | 2220 } |
2221 break; | 2221 break; |
2222 } | 2222 } |
2223 } | 2223 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2280 _mov(T, Ctx->getConstantZero(IceType_i32)); | 2280 _mov(T, Ctx->getConstantZero(IceType_i32)); |
2281 _vmrs(); | 2281 _vmrs(); |
2282 Operand *One = Ctx->getConstantInt32(1); | 2282 Operand *One = Ctx->getConstantInt32(1); |
2283 InstFcmp::FCond Condition = Inst->getCondition(); | 2283 InstFcmp::FCond Condition = Inst->getCondition(); |
2284 assert(Condition < llvm::array_lengthof(TableFcmp)); | 2284 assert(Condition < llvm::array_lengthof(TableFcmp)); |
2285 CondARM32::Cond CC0 = TableFcmp[Condition].CC0; | 2285 CondARM32::Cond CC0 = TableFcmp[Condition].CC0; |
2286 CondARM32::Cond CC1 = TableFcmp[Condition].CC1; | 2286 CondARM32::Cond CC1 = TableFcmp[Condition].CC1; |
2287 if (CC0 != CondARM32::kNone) { | 2287 if (CC0 != CondARM32::kNone) { |
2288 _mov(T, One, CC0); | 2288 _mov(T, One, CC0); |
2289 // If this mov is not a maybe mov, but an actual mov (i.e., CC0 == AL), we | 2289 // If this mov is not a maybe mov, but an actual mov (i.e., CC0 == AL), we |
2290 // don't want to set_dest_nonkillable so that liveness + dead-code | 2290 // don't want to _set_dest_redefined so that liveness + dead-code |
2291 // elimination will get rid of the previous assignment (i.e., T = 0) above. | 2291 // elimination will get rid of the previous assignment (i.e., T = 0) above. |
| 2292 // TODO(stichnot,jpp): We should be able to conditionally create the "T=0" |
| 2293 // instruction based on CC0, instead of relying on DCE to remove it. |
2292 if (CC0 != CondARM32::AL) | 2294 if (CC0 != CondARM32::AL) |
2293 _set_dest_nonkillable(); | 2295 _set_dest_redefined(); |
2294 } | 2296 } |
2295 if (CC1 != CondARM32::kNone) { | 2297 if (CC1 != CondARM32::kNone) { |
2296 assert(CC0 != CondARM32::kNone); | 2298 assert(CC0 != CondARM32::kNone); |
2297 assert(CC1 != CondARM32::AL); | 2299 assert(CC1 != CondARM32::AL); |
2298 _mov_nonkillable(T, One, CC1); | 2300 _mov_redefined(T, One, CC1); |
2299 } | 2301 } |
2300 _mov(Dest, T); | 2302 _mov(Dest, T); |
2301 } | 2303 } |
2302 | 2304 |
2303 void TargetARM32::lowerIcmp(const InstIcmp *Inst) { | 2305 void TargetARM32::lowerIcmp(const InstIcmp *Inst) { |
2304 Variable *Dest = Inst->getDest(); | 2306 Variable *Dest = Inst->getDest(); |
2305 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); | 2307 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); |
2306 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); | 2308 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); |
2307 | 2309 |
2308 if (isVectorType(Dest->getType())) { | 2310 if (isVectorType(Dest->getType())) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2364 _cmp(Src0Lo, Src1LoRF); | 2366 _cmp(Src0Lo, Src1LoRF); |
2365 _sbcs(ScratchReg, Src0Hi, Src1HiRF); | 2367 _sbcs(ScratchReg, Src0Hi, Src1HiRF); |
2366 // ScratchReg isn't going to be used, but we need the side-effect of | 2368 // ScratchReg isn't going to be used, but we need the side-effect of |
2367 // setting flags from this operation. | 2369 // setting flags from this operation. |
2368 Context.insert(InstFakeUse::create(Func, ScratchReg)); | 2370 Context.insert(InstFakeUse::create(Func, ScratchReg)); |
2369 } else { | 2371 } else { |
2370 _cmp(Src0Hi, Src1HiRF); | 2372 _cmp(Src0Hi, Src1HiRF); |
2371 _cmp(Src0Lo, Src1LoRF, CondARM32::EQ); | 2373 _cmp(Src0Lo, Src1LoRF, CondARM32::EQ); |
2372 } | 2374 } |
2373 _mov(T, One, TableIcmp64[Index].C1); | 2375 _mov(T, One, TableIcmp64[Index].C1); |
2374 _mov_nonkillable(T, Zero, TableIcmp64[Index].C2); | 2376 _mov_redefined(T, Zero, TableIcmp64[Index].C2); |
2375 _mov(Dest, T); | 2377 _mov(Dest, T); |
2376 return; | 2378 return; |
2377 } | 2379 } |
2378 | 2380 |
2379 // a=icmp cond b, c ==> | 2381 // a=icmp cond b, c ==> |
2380 // GCC does: | 2382 // GCC does: |
2381 // <u/s>xtb tb, b | 2383 // <u/s>xtb tb, b |
2382 // <u/s>xtb tc, c | 2384 // <u/s>xtb tc, c |
2383 // cmp tb, tc | 2385 // cmp tb, tc |
2384 // mov.C1 t, #0 | 2386 // mov.C1 t, #0 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2420 _mov(T, Zero); | 2422 _mov(T, Zero); |
2421 if (ShiftAmt) { | 2423 if (ShiftAmt) { |
2422 Variable *Src1R = legalizeToReg(Src1); | 2424 Variable *Src1R = legalizeToReg(Src1); |
2423 OperandARM32FlexReg *Src1RShifted = OperandARM32FlexReg::create( | 2425 OperandARM32FlexReg *Src1RShifted = OperandARM32FlexReg::create( |
2424 Func, IceType_i32, Src1R, OperandARM32::LSL, ShiftConst); | 2426 Func, IceType_i32, Src1R, OperandARM32::LSL, ShiftConst); |
2425 _cmp(Src0R, Src1RShifted); | 2427 _cmp(Src0R, Src1RShifted); |
2426 } else { | 2428 } else { |
2427 Operand *Src1RF = legalize(Src1, Legal_Reg | Legal_Flex); | 2429 Operand *Src1RF = legalize(Src1, Legal_Reg | Legal_Flex); |
2428 _cmp(Src0R, Src1RF); | 2430 _cmp(Src0R, Src1RF); |
2429 } | 2431 } |
2430 _mov_nonkillable(T, One, getIcmp32Mapping(Inst->getCondition())); | 2432 _mov_redefined(T, One, getIcmp32Mapping(Inst->getCondition())); |
2431 _mov(Dest, T); | 2433 _mov(Dest, T); |
2432 return; | 2434 return; |
2433 } | 2435 } |
2434 | 2436 |
2435 void TargetARM32::lowerInsertElement(const InstInsertElement *Inst) { | 2437 void TargetARM32::lowerInsertElement(const InstInsertElement *Inst) { |
2436 (void)Inst; | 2438 (void)Inst; |
2437 UnimplementedError(Func->getContext()->getFlags()); | 2439 UnimplementedError(Func->getContext()->getFlags()); |
2438 } | 2440 } |
2439 | 2441 |
2440 void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { | 2442 void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2633 } | 2635 } |
2634 case Intrinsics::Stacksave: { | 2636 case Intrinsics::Stacksave: { |
2635 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); | 2637 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); |
2636 Variable *Dest = Instr->getDest(); | 2638 Variable *Dest = Instr->getDest(); |
2637 _mov(Dest, SP); | 2639 _mov(Dest, SP); |
2638 return; | 2640 return; |
2639 } | 2641 } |
2640 case Intrinsics::Stackrestore: { | 2642 case Intrinsics::Stackrestore: { |
2641 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); | 2643 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); |
2642 Operand *Val = legalize(Instr->getArg(0), Legal_Reg | Legal_Flex); | 2644 Operand *Val = legalize(Instr->getArg(0), Legal_Reg | Legal_Flex); |
2643 _mov_nonkillable(SP, Val); | 2645 _mov_redefined(SP, Val); |
2644 return; | 2646 return; |
2645 } | 2647 } |
2646 case Intrinsics::Trap: | 2648 case Intrinsics::Trap: |
2647 _trap(); | 2649 _trap(); |
2648 return; | 2650 return; |
2649 case Intrinsics::UnknownIntrinsic: | 2651 case Intrinsics::UnknownIntrinsic: |
2650 Func->setError("Should not be lowering UnknownIntrinsic"); | 2652 Func->setError("Should not be lowering UnknownIntrinsic"); |
2651 return; | 2653 return; |
2652 } | 2654 } |
2653 return; | 2655 return; |
2654 } | 2656 } |
2655 | 2657 |
2656 void TargetARM32::lowerCLZ(Variable *Dest, Variable *ValLoR, Variable *ValHiR) { | 2658 void TargetARM32::lowerCLZ(Variable *Dest, Variable *ValLoR, Variable *ValHiR) { |
2657 Type Ty = Dest->getType(); | 2659 Type Ty = Dest->getType(); |
2658 assert(Ty == IceType_i32 || Ty == IceType_i64); | 2660 assert(Ty == IceType_i32 || Ty == IceType_i64); |
2659 Variable *T = makeReg(IceType_i32); | 2661 Variable *T = makeReg(IceType_i32); |
2660 _clz(T, ValLoR); | 2662 _clz(T, ValLoR); |
2661 if (Ty == IceType_i64) { | 2663 if (Ty == IceType_i64) { |
2662 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 2664 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
2663 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 2665 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
2664 Operand *Zero = | 2666 Operand *Zero = |
2665 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); | 2667 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); |
2666 Operand *ThirtyTwo = | 2668 Operand *ThirtyTwo = |
2667 legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex); | 2669 legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex); |
2668 _cmp(ValHiR, Zero); | 2670 _cmp(ValHiR, Zero); |
2669 Variable *T2 = makeReg(IceType_i32); | 2671 Variable *T2 = makeReg(IceType_i32); |
2670 _add(T2, T, ThirtyTwo); | 2672 _add(T2, T, ThirtyTwo); |
2671 _clz(T2, ValHiR, CondARM32::NE); | 2673 _clz(T2, ValHiR, CondARM32::NE); |
2672 // T2 is actually a source as well when the predicate is not AL (since it | 2674 // T2 is actually a source as well when the predicate is not AL (since it |
2673 // may leave T2 alone). We use set_dest_nonkillable to prolong the liveness | 2675 // may leave T2 alone). We use _set_dest_redefined to prolong the liveness |
2674 // of T2 as if it was used as a source. | 2676 // of T2 as if it was used as a source. |
2675 _set_dest_nonkillable(); | 2677 _set_dest_redefined(); |
2676 _mov(DestLo, T2); | 2678 _mov(DestLo, T2); |
2677 Variable *T3 = nullptr; | 2679 Variable *T3 = nullptr; |
2678 _mov(T3, Zero); | 2680 _mov(T3, Zero); |
2679 _mov(DestHi, T3); | 2681 _mov(DestHi, T3); |
2680 return; | 2682 return; |
2681 } | 2683 } |
2682 _mov(Dest, T); | 2684 _mov(Dest, T); |
2683 return; | 2685 return; |
2684 } | 2686 } |
2685 | 2687 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2769 static constexpr CondARM32::Cond Cond = CondARM32::NE; | 2771 static constexpr CondARM32::Cond Cond = CondARM32::NE; |
2770 if (DestTy == IceType_i64) { | 2772 if (DestTy == IceType_i64) { |
2771 SrcT = legalizeUndef(SrcT); | 2773 SrcT = legalizeUndef(SrcT); |
2772 SrcF = legalizeUndef(SrcF); | 2774 SrcF = legalizeUndef(SrcF); |
2773 // Set the low portion. | 2775 // Set the low portion. |
2774 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 2776 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
2775 Variable *TLo = nullptr; | 2777 Variable *TLo = nullptr; |
2776 Operand *SrcFLo = legalize(loOperand(SrcF), Legal_Reg | Legal_Flex); | 2778 Operand *SrcFLo = legalize(loOperand(SrcF), Legal_Reg | Legal_Flex); |
2777 _mov(TLo, SrcFLo); | 2779 _mov(TLo, SrcFLo); |
2778 Operand *SrcTLo = legalize(loOperand(SrcT), Legal_Reg | Legal_Flex); | 2780 Operand *SrcTLo = legalize(loOperand(SrcT), Legal_Reg | Legal_Flex); |
2779 _mov_nonkillable(TLo, SrcTLo, Cond); | 2781 _mov_redefined(TLo, SrcTLo, Cond); |
2780 _mov(DestLo, TLo); | 2782 _mov(DestLo, TLo); |
2781 // Set the high portion. | 2783 // Set the high portion. |
2782 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 2784 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
2783 Variable *THi = nullptr; | 2785 Variable *THi = nullptr; |
2784 Operand *SrcFHi = legalize(hiOperand(SrcF), Legal_Reg | Legal_Flex); | 2786 Operand *SrcFHi = legalize(hiOperand(SrcF), Legal_Reg | Legal_Flex); |
2785 _mov(THi, SrcFHi); | 2787 _mov(THi, SrcFHi); |
2786 Operand *SrcTHi = legalize(hiOperand(SrcT), Legal_Reg | Legal_Flex); | 2788 Operand *SrcTHi = legalize(hiOperand(SrcT), Legal_Reg | Legal_Flex); |
2787 _mov_nonkillable(THi, SrcTHi, Cond); | 2789 _mov_redefined(THi, SrcTHi, Cond); |
2788 _mov(DestHi, THi); | 2790 _mov(DestHi, THi); |
2789 return; | 2791 return; |
2790 } | 2792 } |
2791 | 2793 |
2792 if (isFloatingType(DestTy)) { | 2794 if (isFloatingType(DestTy)) { |
2793 Variable *T = makeReg(DestTy); | 2795 Variable *T = makeReg(DestTy); |
2794 SrcF = legalizeToReg(SrcF); | 2796 SrcF = legalizeToReg(SrcF); |
2795 assert(DestTy == SrcF->getType()); | 2797 assert(DestTy == SrcF->getType()); |
2796 _vmov(T, SrcF); | 2798 _vmov(T, SrcF); |
2797 SrcT = legalizeToReg(SrcT); | 2799 SrcT = legalizeToReg(SrcT); |
2798 assert(DestTy == SrcT->getType()); | 2800 assert(DestTy == SrcT->getType()); |
2799 _vmov(T, SrcT, Cond); | 2801 _vmov(T, SrcT, Cond); |
2800 _set_dest_nonkillable(); | 2802 _set_dest_redefined(); |
2801 _vmov(Dest, T); | 2803 _vmov(Dest, T); |
2802 return; | 2804 return; |
2803 } | 2805 } |
2804 | 2806 |
2805 Variable *T = nullptr; | 2807 Variable *T = nullptr; |
2806 SrcF = legalize(SrcF, Legal_Reg | Legal_Flex); | 2808 SrcF = legalize(SrcF, Legal_Reg | Legal_Flex); |
2807 _mov(T, SrcF); | 2809 _mov(T, SrcF); |
2808 SrcT = legalize(SrcT, Legal_Reg | Legal_Flex); | 2810 SrcT = legalize(SrcT, Legal_Reg | Legal_Flex); |
2809 _mov_nonkillable(T, SrcT, Cond); | 2811 _mov_redefined(T, SrcT, Cond); |
2810 _mov(Dest, T); | 2812 _mov(Dest, T); |
2811 } | 2813 } |
2812 | 2814 |
2813 void TargetARM32::lowerStore(const InstStore *Inst) { | 2815 void TargetARM32::lowerStore(const InstStore *Inst) { |
2814 Operand *Value = Inst->getData(); | 2816 Operand *Value = Inst->getData(); |
2815 Operand *Addr = Inst->getAddr(); | 2817 Operand *Addr = Inst->getAddr(); |
2816 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType()); | 2818 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType()); |
2817 Type Ty = NewAddr->getType(); | 2819 Type Ty = NewAddr->getType(); |
2818 | 2820 |
2819 if (Ty == IceType_i64) { | 2821 if (Ty == IceType_i64) { |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3123 _bic(Reg, Reg, Mask); | 3125 _bic(Reg, Reg, Mask); |
3124 } else { | 3126 } else { |
3125 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex); | 3127 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex); |
3126 _and(Reg, Reg, Mask); | 3128 _and(Reg, Reg, Mask); |
3127 } | 3129 } |
3128 } | 3130 } |
3129 | 3131 |
3130 void TargetARM32::postLower() { | 3132 void TargetARM32::postLower() { |
3131 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 3133 if (Ctx->getFlags().getOptLevel() == Opt_m1) |
3132 return; | 3134 return; |
3133 inferTwoAddress(); | 3135 inferRedefinition(); |
3134 } | 3136 } |
3135 | 3137 |
3136 void TargetARM32::makeRandomRegisterPermutation( | 3138 void TargetARM32::makeRandomRegisterPermutation( |
3137 llvm::SmallVectorImpl<int32_t> &Permutation, | 3139 llvm::SmallVectorImpl<int32_t> &Permutation, |
3138 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { | 3140 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { |
3139 (void)Permutation; | 3141 (void)Permutation; |
3140 (void)ExcludeRegisters; | 3142 (void)ExcludeRegisters; |
3141 (void)Salt; | 3143 (void)Salt; |
3142 UnimplementedError(Func->getContext()->getFlags()); | 3144 UnimplementedError(Func->getContext()->getFlags()); |
3143 } | 3145 } |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3354 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; | 3356 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; |
3355 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { | 3357 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { |
3356 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; | 3358 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; |
3357 } | 3359 } |
3358 // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 3360 // Technically R9 is used for TLS with Sandboxing, and we reserve it. |
3359 // However, for compatibility with current NaCl LLVM, don't claim that. | 3361 // However, for compatibility with current NaCl LLVM, don't claim that. |
3360 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 3362 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
3361 } | 3363 } |
3362 | 3364 |
3363 } // end of namespace Ice | 3365 } // end of namespace Ice |
OLD | NEW |