Chromium Code Reviews| 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 |