OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 | 253 |
254 | 254 |
255 void InstructionSelector::VisitWord32And(Node* node) { | 255 void InstructionSelector::VisitWord32And(Node* node) { |
256 MipsOperandGenerator g(this); | 256 MipsOperandGenerator g(this); |
257 Int32BinopMatcher m(node); | 257 Int32BinopMatcher m(node); |
258 if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) && | 258 if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) && |
259 m.right().HasValue()) { | 259 m.right().HasValue()) { |
260 uint32_t mask = m.right().Value(); | 260 uint32_t mask = m.right().Value(); |
261 uint32_t mask_width = base::bits::CountPopulation32(mask); | 261 uint32_t mask_width = base::bits::CountPopulation32(mask); |
262 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask); | 262 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask); |
263 if ((mask_width != 0) && (mask_msb + mask_width == 32)) { | 263 uint32_t mask_lsb = base::bits::CountTrailingZeros32(mask); |
264 // The mask must be contiguous, and occupy the least-significant bits. | 264 if ((mask_width != 0) && (mask_msb + mask_width + mask_lsb == 32)) { |
265 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask)); | 265 // The mask must be contiguous. |
266 | 266 // Select Ext for And(Shr(x, imm), mask) where the mask may be in |
267 // Select Ext for And(Shr(x, imm), mask) where the mask is in the least | 267 // the least-significant bits or elsewhere. |
268 // significant bits. | |
269 Int32BinopMatcher mleft(m.left().node()); | 268 Int32BinopMatcher mleft(m.left().node()); |
270 if (mleft.right().HasValue()) { | 269 if (mleft.right().HasValue()) { |
271 // Any shift value can match; int32 shifts use `value % 32`. | 270 // Any shift value can match; int32 shifts use `value % 32`. |
272 uint32_t lsb = mleft.right().Value() & 0x1f; | 271 uint32_t lsb = mleft.right().Value() & 0x1f; |
273 | 272 lsb = lsb + mask_lsb; |
274 // Ext cannot extract bits past the register size, however since | 273 // Ext cannot extract bits past the register size, however since |
275 // shifting the original value would have introduced some zeros we can | 274 // shifting the original value would have introduced some zeros we can |
276 // still use Ext with a smaller mask and the remaining bits will be | 275 // still use Ext with a smaller mask and the remaining bits will be |
277 // zeros. | 276 // zeros. |
278 if (lsb + mask_width > 32) mask_width = 32 - lsb; | 277 if (lsb + mask_width > 32) mask_width = 32 - lsb; |
279 | 278 |
280 Emit(kMipsExt, g.DefineAsRegister(node), | 279 Emit(kMipsExt, g.DefineAsRegister(node), |
281 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), | 280 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), |
282 g.TempImmediate(mask_width)); | 281 g.TempImmediate(mask_width)); |
akos.palfi.imgtec
2015/12/30 00:32:53
When the mask_lsb > 0, the result will be incorrec
| |
283 return; | 282 return; |
284 } | 283 } |
285 // Other cases fall through to the normal And operation. | 284 // Other cases fall through to the normal And operation. |
286 } | 285 } |
287 } | 286 } |
288 if (m.right().HasValue()) { | 287 if (m.right().HasValue()) { |
289 uint32_t mask = m.right().Value(); | 288 uint32_t mask = m.right().Value(); |
290 uint32_t shift = base::bits::CountPopulation32(~mask); | 289 uint32_t shift = base::bits::CountPopulation32(~mask); |
291 uint32_t msb = base::bits::CountLeadingZeros32(~mask); | 290 uint32_t msb = base::bits::CountLeadingZeros32(~mask); |
292 if (shift != 0 && shift != 32 && msb + shift == 32) { | 291 if (shift != 0 && shift != 32 && msb + shift == 32) { |
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1327 MachineOperatorBuilder::kFloat32Max | | 1326 MachineOperatorBuilder::kFloat32Max | |
1328 MachineOperatorBuilder::kFloat32RoundDown | | 1327 MachineOperatorBuilder::kFloat32RoundDown | |
1329 MachineOperatorBuilder::kFloat32RoundUp | | 1328 MachineOperatorBuilder::kFloat32RoundUp | |
1330 MachineOperatorBuilder::kFloat32RoundTruncate | | 1329 MachineOperatorBuilder::kFloat32RoundTruncate | |
1331 MachineOperatorBuilder::kFloat32RoundTiesEven; | 1330 MachineOperatorBuilder::kFloat32RoundTiesEven; |
1332 } | 1331 } |
1333 | 1332 |
1334 } // namespace compiler | 1333 } // namespace compiler |
1335 } // namespace internal | 1334 } // namespace internal |
1336 } // namespace v8 | 1335 } // namespace v8 |
OLD | NEW |