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 14 matching lines...) Expand all Loading... |
25 #include "IceInstVarIter.h" | 25 #include "IceInstVarIter.h" |
26 #include "IceLiveness.h" | 26 #include "IceLiveness.h" |
27 #include "IceOperand.h" | 27 #include "IceOperand.h" |
28 #include "IcePhiLoweringImpl.h" | 28 #include "IcePhiLoweringImpl.h" |
29 #include "IceRegistersARM32.h" | 29 #include "IceRegistersARM32.h" |
30 #include "IceTargetLoweringARM32.def" | 30 #include "IceTargetLoweringARM32.def" |
31 #include "IceUtils.h" | 31 #include "IceUtils.h" |
32 #include "llvm/Support/MathExtras.h" | 32 #include "llvm/Support/MathExtras.h" |
33 | 33 |
34 #include <algorithm> | 34 #include <algorithm> |
| 35 #include <array> |
35 #include <utility> | 36 #include <utility> |
36 | 37 |
37 namespace Ice { | 38 namespace Ice { |
38 | 39 |
39 namespace { | 40 namespace { |
40 | 41 |
41 // The following table summarizes the logic for lowering the icmp instruction | 42 // The following table summarizes the logic for lowering the icmp instruction |
42 // for i32 and narrower types. Each icmp condition has a clear mapping to an | 43 // for i32 and narrower types. Each icmp condition has a clear mapping to an |
43 // ARM32 conditional move instruction. | 44 // ARM32 conditional move instruction. |
44 | 45 |
(...skipping 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2029 case InstArithmetic::Udiv: | 2030 case InstArithmetic::Udiv: |
2030 case InstArithmetic::Sdiv: | 2031 case InstArithmetic::Sdiv: |
2031 case InstArithmetic::Urem: | 2032 case InstArithmetic::Urem: |
2032 case InstArithmetic::Srem: | 2033 case InstArithmetic::Srem: |
2033 llvm::report_fatal_error("Call-helper-involved instruction for i64 type " | 2034 llvm::report_fatal_error("Call-helper-involved instruction for i64 type " |
2034 "should have already been handled before"); | 2035 "should have already been handled before"); |
2035 return; | 2036 return; |
2036 } | 2037 } |
2037 } | 2038 } |
2038 | 2039 |
| 2040 namespace { |
| 2041 // StrengthReduction is a namespace with the strength reduction machinery. The |
| 2042 // entry point is the StrengthReduction::tryToOptimize method. It returns true |
| 2043 // if the optimization can be performed, and false otherwise. |
| 2044 // |
| 2045 // If the optimization can be performed, tryToOptimize sets its NumOperations |
| 2046 // parameter to the number of shifts that are needed to perform the |
| 2047 // multiplication; and it sets the Operations parameter with <ShAmt, AddOrSub> |
| 2048 // tuples that describe how to materialize the multiplication. |
| 2049 // |
| 2050 // The algorithm finds contiguous 1s in the Multiplication source, and uses one |
| 2051 // or two shifts to materialize it. A sequence of 1s, e.g., |
| 2052 // |
| 2053 // M N |
| 2054 // ...00000000000011111...111110000000... |
| 2055 // |
| 2056 // is materializable with (1 << (M + 1)) - (1 << N): |
| 2057 // |
| 2058 // ...00000000000100000...000000000000... [1 << (M + 1)] |
| 2059 // ...00000000000000000...000010000000... (-) [1 << N] |
| 2060 // -------------------------------------- |
| 2061 // ...00000000000011111...111110000000... |
| 2062 // |
| 2063 // And a single bit set, which is just a left shift. |
| 2064 namespace StrengthReduction { |
| 2065 enum AggregationOperation { |
| 2066 AO_Invalid, |
| 2067 AO_Add, |
| 2068 AO_Sub, |
| 2069 }; |
| 2070 |
| 2071 // AggregateElement is a glorified <ShAmt, AddOrSub> tuple. |
| 2072 class AggregationElement { |
| 2073 AggregationElement(const AggregationElement &) = delete; |
| 2074 |
| 2075 public: |
| 2076 AggregationElement() = default; |
| 2077 AggregationElement &operator=(const AggregationElement &) = default; |
| 2078 AggregationElement(AggregationOperation Op, uint32_t ShAmt) |
| 2079 : Op(Op), ShAmt(ShAmt) {} |
| 2080 |
| 2081 Operand *createShiftedOperand(Cfg *Func, Variable *OpR) const { |
| 2082 assert(OpR->mustHaveReg()); |
| 2083 if (ShAmt == 0) { |
| 2084 return OpR; |
| 2085 } |
| 2086 return OperandARM32FlexReg::create( |
| 2087 Func, IceType_i32, OpR, OperandARM32::LSL, |
| 2088 OperandARM32ShAmtImm::create( |
| 2089 Func, llvm::cast<ConstantInteger32>( |
| 2090 Func->getContext()->getConstantInt32(ShAmt)))); |
| 2091 } |
| 2092 |
| 2093 bool aggregateWithAdd() const { |
| 2094 switch (Op) { |
| 2095 case AO_Invalid: |
| 2096 llvm::report_fatal_error("Invalid Strength Reduction Operations."); |
| 2097 case AO_Add: |
| 2098 return true; |
| 2099 case AO_Sub: |
| 2100 return false; |
| 2101 } |
| 2102 } |
| 2103 |
| 2104 uint32_t shAmt() const { return ShAmt; } |
| 2105 |
| 2106 private: |
| 2107 AggregationOperation Op = AO_Invalid; |
| 2108 uint32_t ShAmt; |
| 2109 }; |
| 2110 |
| 2111 // [RangeStart, RangeEnd] is a range of 1s in Src. |
| 2112 template <std::size_t N> |
| 2113 bool addOperations(uint32_t RangeStart, uint32_t RangeEnd, SizeT *NumOperations, |
| 2114 std::array<AggregationElement, N> *Operations) { |
| 2115 assert(*NumOperations < N); |
| 2116 if (RangeStart == RangeEnd) { |
| 2117 // Single bit set: |
| 2118 // Src : 0...00010... |
| 2119 // RangeStart : ^ |
| 2120 // RangeEnd : ^ |
| 2121 // NegSrc : 0...00001... |
| 2122 (*Operations)[*NumOperations] = AggregationElement(AO_Add, RangeStart); |
| 2123 ++(*NumOperations); |
| 2124 return true; |
| 2125 } |
| 2126 |
| 2127 // Sequence of 1s: (two operations required.) |
| 2128 // Src : 0...00011...110... |
| 2129 // RangeStart : ^ |
| 2130 // RangeEnd : ^ |
| 2131 // NegSrc : 0...00000...001... |
| 2132 if (*NumOperations + 1 >= N) { |
| 2133 return false; |
| 2134 } |
| 2135 (*Operations)[*NumOperations] = AggregationElement(AO_Add, RangeStart + 1); |
| 2136 ++(*NumOperations); |
| 2137 (*Operations)[*NumOperations] = AggregationElement(AO_Sub, RangeEnd); |
| 2138 ++(*NumOperations); |
| 2139 return true; |
| 2140 } |
| 2141 |
| 2142 // tryToOptmize scans Src looking for sequences of 1s (including the unitary bit |
| 2143 // 1 surrounded by zeroes. |
| 2144 template <std::size_t N> |
| 2145 bool tryToOptimize(uint32_t Src, SizeT *NumOperations, |
| 2146 std::array<AggregationElement, N> *Operations) { |
| 2147 constexpr uint32_t SrcSizeBits = sizeof(Src) * CHAR_BIT; |
| 2148 uint32_t NegSrc = ~Src; |
| 2149 |
| 2150 *NumOperations = 0; |
| 2151 while (Src != 0 && *NumOperations < N) { |
| 2152 // Each step of the algorithm: |
| 2153 // * finds L, the last bit set in Src; |
| 2154 // * clears all the upper bits in NegSrc up to bit L; |
| 2155 // * finds nL, the last bit set in NegSrc; |
| 2156 // * clears all the upper bits in Src up to bit nL; |
| 2157 // |
| 2158 // if L == nL + 1, then a unitary 1 was found in Src. Otherwise, a sequence |
| 2159 // of 1s starting at L, and ending at nL + 1, was found. |
| 2160 const uint32_t SrcLastBitSet = llvm::findLastSet(Src); |
| 2161 const uint32_t NegSrcClearMask = |
| 2162 (SrcLastBitSet == 0) ? 0 |
| 2163 : (0xFFFFFFFFu) >> (SrcSizeBits - SrcLastBitSet); |
| 2164 NegSrc &= NegSrcClearMask; |
| 2165 if (NegSrc == 0) { |
| 2166 if (addOperations(SrcLastBitSet, 0, NumOperations, Operations)) { |
| 2167 return true; |
| 2168 } |
| 2169 return false; |
| 2170 } |
| 2171 const uint32_t NegSrcLastBitSet = llvm::findLastSet(NegSrc); |
| 2172 assert(NegSrcLastBitSet < SrcLastBitSet); |
| 2173 const uint32_t SrcClearMask = |
| 2174 (NegSrcLastBitSet == 0) ? 0 : (0xFFFFFFFFu) >> |
| 2175 (SrcSizeBits - NegSrcLastBitSet); |
| 2176 Src &= SrcClearMask; |
| 2177 if (!addOperations(SrcLastBitSet, NegSrcLastBitSet + 1, NumOperations, |
| 2178 Operations)) { |
| 2179 return false; |
| 2180 } |
| 2181 } |
| 2182 |
| 2183 return Src == 0; |
| 2184 } |
| 2185 } // end of namespace StrengthReduction |
| 2186 } // end of anonymous namespace |
| 2187 |
2039 void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) { | 2188 void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) { |
2040 Variable *Dest = Inst->getDest(); | 2189 Variable *Dest = Inst->getDest(); |
2041 | 2190 |
2042 if (Dest->isRematerializable()) { | 2191 if (Dest->isRematerializable()) { |
2043 Context.insert(InstFakeDef::create(Func, Dest)); | 2192 Context.insert(InstFakeDef::create(Func, Dest)); |
2044 return; | 2193 return; |
2045 } | 2194 } |
2046 | 2195 |
2047 if (Dest->getType() == IceType_i1) { | 2196 Type DestTy = Dest->getType(); |
| 2197 if (DestTy == IceType_i1) { |
2048 lowerInt1Arithmetic(Inst); | 2198 lowerInt1Arithmetic(Inst); |
2049 return; | 2199 return; |
2050 } | 2200 } |
2051 | 2201 |
2052 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); | 2202 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); |
2053 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); | 2203 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); |
2054 if (Dest->getType() == IceType_i64) { | 2204 if (DestTy == IceType_i64) { |
2055 lowerInt64Arithmetic(Inst->getOp(), Inst->getDest(), Src0, Src1); | 2205 lowerInt64Arithmetic(Inst->getOp(), Inst->getDest(), Src0, Src1); |
2056 return; | 2206 return; |
2057 } | 2207 } |
2058 | 2208 |
2059 if (isVectorType(Dest->getType())) { | 2209 if (isVectorType(DestTy)) { |
2060 // Add a fake def to keep liveness consistent in the meantime. | 2210 // Add a fake def to keep liveness consistent in the meantime. |
2061 Variable *T = makeReg(Dest->getType()); | 2211 Variable *T = makeReg(DestTy); |
2062 Context.insert(InstFakeDef::create(Func, T)); | 2212 Context.insert(InstFakeDef::create(Func, T)); |
2063 _mov(Dest, T); | 2213 _mov(Dest, T); |
2064 UnimplementedError(Func->getContext()->getFlags()); | 2214 UnimplementedError(Func->getContext()->getFlags()); |
2065 return; | 2215 return; |
2066 } | 2216 } |
2067 | 2217 |
2068 // Dest->getType() is a non-i64 scalar. | 2218 // DestTy is a non-i64 scalar. |
2069 Variable *T = makeReg(Dest->getType()); | 2219 Variable *T = makeReg(DestTy); |
2070 | 2220 |
2071 // * Handle div/rem separately. They require a non-legalized Src1 to inspect | 2221 // * Handle div/rem separately. They require a non-legalized Src1 to inspect |
2072 // whether or not Src1 is a non-zero constant. Once legalized it is more | 2222 // whether or not Src1 is a non-zero constant. Once legalized it is more |
2073 // difficult to determine (constant may be moved to a register). | 2223 // difficult to determine (constant may be moved to a register). |
2074 // * Handle floating point arithmetic separately: they require Src1 to be | 2224 // * Handle floating point arithmetic separately: they require Src1 to be |
2075 // legalized to a register. | 2225 // legalized to a register. |
2076 switch (Inst->getOp()) { | 2226 switch (Inst->getOp()) { |
2077 default: | 2227 default: |
2078 break; | 2228 break; |
2079 case InstArithmetic::Udiv: { | 2229 case InstArithmetic::Udiv: { |
(...skipping 20 matching lines...) Expand all Loading... |
2100 case InstArithmetic::Srem: { | 2250 case InstArithmetic::Srem: { |
2101 constexpr bool IsRemainder = true; | 2251 constexpr bool IsRemainder = true; |
2102 Variable *Src0R = legalizeToReg(Src0); | 2252 Variable *Src0R = legalizeToReg(Src0); |
2103 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_sxt, &TargetARM32::_sdiv, | 2253 lowerIDivRem(Dest, T, Src0R, Src1, &TargetARM32::_sxt, &TargetARM32::_sdiv, |
2104 H_srem_i32, IsRemainder); | 2254 H_srem_i32, IsRemainder); |
2105 return; | 2255 return; |
2106 } | 2256 } |
2107 case InstArithmetic::Frem: { | 2257 case InstArithmetic::Frem: { |
2108 constexpr SizeT MaxSrcs = 2; | 2258 constexpr SizeT MaxSrcs = 2; |
2109 Variable *Src0R = legalizeToReg(Src0); | 2259 Variable *Src0R = legalizeToReg(Src0); |
2110 Type Ty = Dest->getType(); | 2260 Type Ty = DestTy; |
2111 InstCall *Call = makeHelperCall( | 2261 InstCall *Call = makeHelperCall( |
2112 isFloat32Asserting32Or64(Ty) ? H_frem_f32 : H_frem_f64, Dest, MaxSrcs); | 2262 isFloat32Asserting32Or64(Ty) ? H_frem_f32 : H_frem_f64, Dest, MaxSrcs); |
2113 Call->addArg(Src0R); | 2263 Call->addArg(Src0R); |
2114 Call->addArg(Src1); | 2264 Call->addArg(Src1); |
2115 lowerCall(Call); | 2265 lowerCall(Call); |
2116 return; | 2266 return; |
2117 } | 2267 } |
2118 case InstArithmetic::Fadd: { | 2268 case InstArithmetic::Fadd: { |
2119 Variable *Src0R = legalizeToReg(Src0); | 2269 Variable *Src0R = legalizeToReg(Src0); |
2120 Variable *Src1R = legalizeToReg(Src1); | 2270 Variable *Src1R = legalizeToReg(Src1); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2198 } | 2348 } |
2199 case InstArithmetic::Xor: { | 2349 case InstArithmetic::Xor: { |
2200 Variable *Src0R = Srcs.src0R(this); | 2350 Variable *Src0R = Srcs.src0R(this); |
2201 Operand *Src1RF = Srcs.src1RF(this); | 2351 Operand *Src1RF = Srcs.src1RF(this); |
2202 _eor(T, Src0R, Src1RF); | 2352 _eor(T, Src0R, Src1RF); |
2203 _mov(Dest, T); | 2353 _mov(Dest, T); |
2204 return; | 2354 return; |
2205 } | 2355 } |
2206 case InstArithmetic::Sub: { | 2356 case InstArithmetic::Sub: { |
2207 if (Srcs.hasConstOperand()) { | 2357 if (Srcs.hasConstOperand()) { |
2208 // TODO(jpp): lowering Src0R here is wrong -- Src0R it is not guaranteed | |
2209 // to be used. | |
2210 if (Srcs.immediateIsFlexEncodable()) { | 2358 if (Srcs.immediateIsFlexEncodable()) { |
2211 Variable *Src0R = Srcs.src0R(this); | 2359 Variable *Src0R = Srcs.src0R(this); |
2212 Operand *Src1RF = Srcs.src1RF(this); | 2360 Operand *Src1RF = Srcs.src1RF(this); |
2213 if (Srcs.swappedOperands()) { | 2361 if (Srcs.swappedOperands()) { |
2214 _rsb(T, Src0R, Src1RF); | 2362 _rsb(T, Src0R, Src1RF); |
2215 } else { | 2363 } else { |
2216 _sub(T, Src0R, Src1RF); | 2364 _sub(T, Src0R, Src1RF); |
2217 } | 2365 } |
2218 _mov(Dest, T); | 2366 _mov(Dest, T); |
2219 return; | 2367 return; |
2220 } | 2368 } |
2221 if (!Srcs.swappedOperands() && Srcs.negatedImmediateIsFlexEncodable()) { | 2369 if (!Srcs.swappedOperands() && Srcs.negatedImmediateIsFlexEncodable()) { |
2222 Variable *Src0R = Srcs.src0R(this); | 2370 Variable *Src0R = Srcs.src0R(this); |
2223 Operand *Src1F = Srcs.negatedSrc1F(this); | 2371 Operand *Src1F = Srcs.negatedSrc1F(this); |
2224 _add(T, Src0R, Src1F); | 2372 _add(T, Src0R, Src1F); |
2225 _mov(Dest, T); | 2373 _mov(Dest, T); |
2226 return; | 2374 return; |
2227 } | 2375 } |
2228 } | 2376 } |
2229 Variable *Src0R = Srcs.unswappedSrc0R(this); | 2377 Variable *Src0R = Srcs.unswappedSrc0R(this); |
2230 Variable *Src1R = Srcs.unswappedSrc1R(this); | 2378 Variable *Src1R = Srcs.unswappedSrc1R(this); |
2231 _sub(T, Src0R, Src1R); | 2379 _sub(T, Src0R, Src1R); |
2232 _mov(Dest, T); | 2380 _mov(Dest, T); |
2233 return; | 2381 return; |
2234 } | 2382 } |
2235 case InstArithmetic::Mul: { | 2383 case InstArithmetic::Mul: { |
| 2384 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; |
| 2385 if (!OptM1 && Srcs.hasConstOperand()) { |
| 2386 constexpr std::size_t MaxShifts = 4; |
| 2387 std::array<StrengthReduction::AggregationElement, MaxShifts> Shifts; |
| 2388 SizeT NumOperations; |
| 2389 int32_t Const = Srcs.getConstantValue(); |
| 2390 const bool Invert = Const < 0; |
| 2391 const bool MultiplyByZero = Const == 0; |
| 2392 Operand *_0 = |
| 2393 legalize(Ctx->getConstantZero(DestTy), Legal_Reg | Legal_Flex); |
| 2394 |
| 2395 if (MultiplyByZero) { |
| 2396 _mov(T, _0); |
| 2397 _mov(Dest, T); |
| 2398 return; |
| 2399 } |
| 2400 |
| 2401 if (Invert) { |
| 2402 Const = -Const; |
| 2403 } |
| 2404 |
| 2405 if (StrengthReduction::tryToOptimize(Const, &NumOperations, &Shifts)) { |
| 2406 assert(NumOperations >= 1); |
| 2407 Variable *Src0R = Srcs.src0R(this); |
| 2408 int32_t Start; |
| 2409 int32_t End; |
| 2410 if (NumOperations == 1 || Shifts[NumOperations - 1].shAmt() != 0) { |
| 2411 // Multiplication by a power of 2 (NumOperations == 1); or |
| 2412 // Multiplication by a even number not a power of 2. |
| 2413 Start = 1; |
| 2414 End = NumOperations; |
| 2415 assert(Shifts[0].aggregateWithAdd()); |
| 2416 _lsl(T, Src0R, shAmtImm(Shifts[0].shAmt())); |
| 2417 } else { |
| 2418 // Multiplication by an odd number. Put the free barrel shifter to a |
| 2419 // good use. |
| 2420 Start = 0; |
| 2421 End = NumOperations - 2; |
| 2422 const StrengthReduction::AggregationElement &Last = |
| 2423 Shifts[NumOperations - 1]; |
| 2424 const StrengthReduction::AggregationElement &SecondToLast = |
| 2425 Shifts[NumOperations - 2]; |
| 2426 if (!Last.aggregateWithAdd()) { |
| 2427 assert(SecondToLast.aggregateWithAdd()); |
| 2428 _rsb(T, Src0R, SecondToLast.createShiftedOperand(Func, Src0R)); |
| 2429 } else if (!SecondToLast.aggregateWithAdd()) { |
| 2430 assert(Last.aggregateWithAdd()); |
| 2431 _sub(T, Src0R, SecondToLast.createShiftedOperand(Func, Src0R)); |
| 2432 } else { |
| 2433 _add(T, Src0R, SecondToLast.createShiftedOperand(Func, Src0R)); |
| 2434 } |
| 2435 } |
| 2436 |
| 2437 // Odd numbers : S E I I |
| 2438 // +---+---+---+---+---+---+ ... +---+---+---+---+ |
| 2439 // Shifts = | | | | | | | ... | | | | | |
| 2440 // +---+---+---+---+---+---+ ... +---+---+---+---+ |
| 2441 // Even numbers: I S E |
| 2442 // |
| 2443 // S: Start; E: End; I: Init |
| 2444 for (int32_t I = Start; I < End; ++I) { |
| 2445 const StrengthReduction::AggregationElement &Current = Shifts[I]; |
| 2446 Operand *SrcF = Current.createShiftedOperand(Func, Src0R); |
| 2447 if (Current.aggregateWithAdd()) { |
| 2448 _add(T, T, SrcF); |
| 2449 } else { |
| 2450 _sub(T, T, SrcF); |
| 2451 } |
| 2452 } |
| 2453 |
| 2454 if (Invert) { |
| 2455 // T = 0 - T. |
| 2456 _rsb(T, T, _0); |
| 2457 } |
| 2458 |
| 2459 _mov(Dest, T); |
| 2460 return; |
| 2461 } |
| 2462 } |
2236 Variable *Src0R = Srcs.unswappedSrc0R(this); | 2463 Variable *Src0R = Srcs.unswappedSrc0R(this); |
2237 Variable *Src1R = Srcs.unswappedSrc1R(this); | 2464 Variable *Src1R = Srcs.unswappedSrc1R(this); |
2238 _mul(T, Src0R, Src1R); | 2465 _mul(T, Src0R, Src1R); |
2239 _mov(Dest, T); | 2466 _mov(Dest, T); |
2240 return; | 2467 return; |
2241 } | 2468 } |
2242 case InstArithmetic::Shl: { | 2469 case InstArithmetic::Shl: { |
2243 Variable *Src0R = Srcs.unswappedSrc0R(this); | 2470 Variable *Src0R = Srcs.unswappedSrc0R(this); |
2244 Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this); | 2471 Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this); |
2245 _lsl(T, Src0R, Src1R); | 2472 _lsl(T, Src0R, Src1R); |
2246 _mov(Dest, T); | 2473 _mov(Dest, T); |
2247 return; | 2474 return; |
2248 } | 2475 } |
2249 case InstArithmetic::Lshr: { | 2476 case InstArithmetic::Lshr: { |
2250 Variable *Src0R = Srcs.unswappedSrc0R(this); | 2477 Variable *Src0R = Srcs.unswappedSrc0R(this); |
2251 if (Dest->getType() != IceType_i32) { | 2478 if (DestTy != IceType_i32) { |
2252 _uxt(Src0R, Src0R); | 2479 _uxt(Src0R, Src0R); |
2253 } | 2480 } |
2254 _lsr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); | 2481 _lsr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); |
2255 _mov(Dest, T); | 2482 _mov(Dest, T); |
2256 return; | 2483 return; |
2257 } | 2484 } |
2258 case InstArithmetic::Ashr: { | 2485 case InstArithmetic::Ashr: { |
2259 Variable *Src0R = Srcs.unswappedSrc0R(this); | 2486 Variable *Src0R = Srcs.unswappedSrc0R(this); |
2260 if (Dest->getType() != IceType_i32) { | 2487 if (DestTy != IceType_i32) { |
2261 _sxt(Src0R, Src0R); | 2488 _sxt(Src0R, Src0R); |
2262 } | 2489 } |
2263 _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); | 2490 _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); |
2264 _mov(Dest, T); | 2491 _mov(Dest, T); |
2265 return; | 2492 return; |
2266 } | 2493 } |
2267 case InstArithmetic::Udiv: | 2494 case InstArithmetic::Udiv: |
2268 case InstArithmetic::Sdiv: | 2495 case InstArithmetic::Sdiv: |
2269 case InstArithmetic::Urem: | 2496 case InstArithmetic::Urem: |
2270 case InstArithmetic::Srem: | 2497 case InstArithmetic::Srem: |
(...skipping 3232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5503 // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 5730 // Technically R9 is used for TLS with Sandboxing, and we reserve it. |
5504 // However, for compatibility with current NaCl LLVM, don't claim that. | 5731 // However, for compatibility with current NaCl LLVM, don't claim that. |
5505 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 5732 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
5506 } | 5733 } |
5507 | 5734 |
5508 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM]; | 5735 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM]; |
5509 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 5736 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
5510 llvm::SmallBitVector TargetARM32::ScratchRegs; | 5737 llvm::SmallBitVector TargetARM32::ScratchRegs; |
5511 | 5738 |
5512 } // end of namespace Ice | 5739 } // end of namespace Ice |
OLD | NEW |