 Chromium Code Reviews
 Chromium Code Reviews Issue 1552483002:
  MIPS: [turbofan] Improve matching for And(Shr(x, imm), mask).  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1552483002:
  MIPS: [turbofan] Improve matching for And(Shr(x, imm), mask).  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| 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 |