OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkMathPriv.h" | 8 #include "SkMathPriv.h" |
9 #include "SkFloatBits.h" | 9 #include "SkFloatBits.h" |
10 #include "SkFloatingPoint.h" | 10 #include "SkFloatingPoint.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 } | 38 } |
39 if (x & 0x2) { | 39 if (x & 0x2) { |
40 sub_shift(zeros, x, 1); | 40 sub_shift(zeros, x, 1); |
41 } | 41 } |
42 | 42 |
43 return zeros; | 43 return zeros; |
44 } | 44 } |
45 | 45 |
46 /////////////////////////////////////////////////////////////////////////////// | 46 /////////////////////////////////////////////////////////////////////////////// |
47 | 47 |
| 48 #define DIVBITS_ITER(n) \ |
| 49 case n: \ |
| 50 if ((numer = (numer << 1) - denom) >= 0) \ |
| 51 result |= 1 << (n - 1); else numer += denom |
48 | 52 |
49 #define DIVBITS_ITER(k) \ | 53 int32_t SkDivBits(int32_t numer, int32_t denom, int shift_bias) { |
50 case k: \ | 54 SkASSERT(denom != 0); |
51 if (numer*2 >= denom) { \ | 55 if (numer == 0) { |
52 numer = numer*2 - denom; \ | |
53 result |= 1 << (k-1); \ | |
54 } else { \ | |
55 numer *= 2; \ | |
56 } | |
57 | |
58 // NOTE: if you're thinking of editing this method, consider replacing it with | |
59 // a simple shift and divide. This legacy method predated reliable hardware div
ision. | |
60 int32_t SkDivBits(int32_t n, int32_t d, int shift_bias) { | |
61 SkASSERT(d != 0); | |
62 if (n == 0) { | |
63 return 0; | 56 return 0; |
64 } | 57 } |
65 | 58 |
66 // Make numer and denom positive, and sign hold the resulting sign | 59 // make numer and denom positive, and sign hold the resulting sign |
67 // We'll be left-shifting numer, so it's important it's a uint32_t. | 60 int32_t sign = SkExtractSign(numer ^ denom); |
68 // We put denom in a uint32_t just to keep things simple. | 61 numer = SkAbs32(numer); |
69 int32_t sign = SkExtractSign(n ^ d); | 62 denom = SkAbs32(denom); |
70 #if defined(SK_SUPPORT_LEGACY_DIVBITS_UB) | |
71 // Blink layout tests are baselined to Clang optimizing through the UB. | |
72 int32_t numer = SkAbs32(n); | |
73 int32_t denom = SkAbs32(d); | |
74 #else | |
75 uint32_t numer = SkAbs32(n); | |
76 uint32_t denom = SkAbs32(d); | |
77 #endif | |
78 | |
79 // It's probably a bug to use n or d below here. | |
80 | 63 |
81 int nbits = SkCLZ(numer) - 1; | 64 int nbits = SkCLZ(numer) - 1; |
82 int dbits = SkCLZ(denom) - 1; | 65 int dbits = SkCLZ(denom) - 1; |
83 int bits = shift_bias - nbits + dbits; | 66 int bits = shift_bias - nbits + dbits; |
84 | 67 |
85 if (bits < 0) { // answer will underflow | 68 if (bits < 0) { // answer will underflow |
86 return 0; | 69 return 0; |
87 } | 70 } |
88 if (bits > 31) { // answer will overflow | 71 if (bits > 31) { // answer will overflow |
89 return SkApplySign(SK_MaxS32, sign); | 72 return SkApplySign(SK_MaxS32, sign); |
90 } | 73 } |
91 | 74 |
92 denom <<= dbits; | 75 denom <<= dbits; |
93 numer <<= nbits; | 76 numer <<= nbits; |
94 | 77 |
95 SkFixed result = 0; | 78 SkFixed result = 0; |
96 | 79 |
97 // do the first one | 80 // do the first one |
98 if (numer >= denom) { | 81 if ((numer -= denom) >= 0) { |
99 numer -= denom; | |
100 result = 1; | 82 result = 1; |
| 83 } else { |
| 84 numer += denom; |
101 } | 85 } |
102 | 86 |
103 // Now fall into our switch statement if there are more bits to compute | 87 // Now fall into our switch statement if there are more bits to compute |
104 if (bits > 0) { | 88 if (bits > 0) { |
105 // make room for the rest of the answer bits | 89 // make room for the rest of the answer bits |
106 result <<= bits; | 90 result <<= bits; |
107 switch (bits) { | 91 switch (bits) { |
108 DIVBITS_ITER(31); DIVBITS_ITER(30); DIVBITS_ITER(29); | 92 DIVBITS_ITER(31); DIVBITS_ITER(30); DIVBITS_ITER(29); |
109 DIVBITS_ITER(28); DIVBITS_ITER(27); DIVBITS_ITER(26); | 93 DIVBITS_ITER(28); DIVBITS_ITER(27); DIVBITS_ITER(26); |
110 DIVBITS_ITER(25); DIVBITS_ITER(24); DIVBITS_ITER(23); | 94 DIVBITS_ITER(25); DIVBITS_ITER(24); DIVBITS_ITER(23); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 if (SkScalarNearlyZero(*cosValue)) { | 146 if (SkScalarNearlyZero(*cosValue)) { |
163 *cosValue = 0; | 147 *cosValue = 0; |
164 } | 148 } |
165 } | 149 } |
166 | 150 |
167 if (SkScalarNearlyZero(sinValue)) { | 151 if (SkScalarNearlyZero(sinValue)) { |
168 sinValue = 0; | 152 sinValue = 0; |
169 } | 153 } |
170 return sinValue; | 154 return sinValue; |
171 } | 155 } |
OLD | NEW |