Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1790)

Side by Side Diff: src/compiler/mips64/instruction-selector-mips64.cc

Issue 1552483002: MIPS: [turbofan] Improve matching for And(Shr(x, imm), mask). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 262
263 263
264 void InstructionSelector::VisitWord32And(Node* node) { 264 void InstructionSelector::VisitWord32And(Node* node) {
265 Mips64OperandGenerator g(this); 265 Mips64OperandGenerator g(this);
266 Int32BinopMatcher m(node); 266 Int32BinopMatcher m(node);
267 if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) && 267 if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) &&
268 m.right().HasValue()) { 268 m.right().HasValue()) {
269 uint32_t mask = m.right().Value(); 269 uint32_t mask = m.right().Value();
270 uint32_t mask_width = base::bits::CountPopulation32(mask); 270 uint32_t mask_width = base::bits::CountPopulation32(mask);
271 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask); 271 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
272 if ((mask_width != 0) && (mask_msb + mask_width == 32)) { 272 uint32_t mask_lsb = base::bits::CountTrailingZeros32(mask);
273 // The mask must be contiguous, and occupy the least-significant bits. 273 if ((mask_width != 0) && (mask_msb + mask_width + mask_lsb == 32)) {
274 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask)); 274 // The mask must be contiguous.
275 275 // Select Ext for And(Shr(x, imm), mask) where the mask may be in
276 // Select Ext for And(Shr(x, imm), mask) where the mask is in the least 276 // the least-significant bits or elsewhere.
277 // significant bits.
278 Int32BinopMatcher mleft(m.left().node()); 277 Int32BinopMatcher mleft(m.left().node());
279 if (mleft.right().HasValue()) { 278 if (mleft.right().HasValue()) {
280 // Any shift value can match; int32 shifts use `value % 32`. 279 // Any shift value can match; int32 shifts use `value % 32`.
281 uint32_t lsb = mleft.right().Value() & 0x1f; 280 uint32_t lsb = mleft.right().Value() & 0x1f;
282 281 lsb = lsb + mask_lsb;
283 // Ext cannot extract bits past the register size, however since 282 // Ext cannot extract bits past the register size, however since
284 // shifting the original value would have introduced some zeros we can 283 // shifting the original value would have introduced some zeros we can
285 // still use Ext with a smaller mask and the remaining bits will be 284 // still use Ext with a smaller mask and the remaining bits will be
286 // zeros. 285 // zeros.
287 if (lsb + mask_width > 32) mask_width = 32 - lsb; 286 if (lsb + mask_width > 32) mask_width = 32 - lsb;
288 287
289 Emit(kMips64Ext, g.DefineAsRegister(node), 288 Emit(kMips64Ext, g.DefineAsRegister(node),
290 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), 289 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
291 g.TempImmediate(mask_width)); 290 g.TempImmediate(mask_width));
292 return; 291 return;
(...skipping 19 matching lines...) Expand all
312 311
313 312
314 void InstructionSelector::VisitWord64And(Node* node) { 313 void InstructionSelector::VisitWord64And(Node* node) {
315 Mips64OperandGenerator g(this); 314 Mips64OperandGenerator g(this);
316 Int64BinopMatcher m(node); 315 Int64BinopMatcher m(node);
317 if (m.left().IsWord64Shr() && CanCover(node, m.left().node()) && 316 if (m.left().IsWord64Shr() && CanCover(node, m.left().node()) &&
318 m.right().HasValue()) { 317 m.right().HasValue()) {
319 uint64_t mask = m.right().Value(); 318 uint64_t mask = m.right().Value();
320 uint32_t mask_width = base::bits::CountPopulation64(mask); 319 uint32_t mask_width = base::bits::CountPopulation64(mask);
321 uint32_t mask_msb = base::bits::CountLeadingZeros64(mask); 320 uint32_t mask_msb = base::bits::CountLeadingZeros64(mask);
322 if ((mask_width != 0) && (mask_msb + mask_width == 64)) { 321 uint32_t mask_lsb = base::bits::CountTrailingZeros64(mask);
323 // The mask must be contiguous, and occupy the least-significant bits. 322 if ((mask_width != 0) && (mask_msb + mask_width + mask_lsb == 64)) {
324 DCHECK_EQ(0u, base::bits::CountTrailingZeros64(mask)); 323 // The mask must be contiguous.
325 324 // Select Dext for And(Shr(x, imm), mask) where the mask may be in
326 // Select Dext for And(Shr(x, imm), mask) where the mask is in the least 325 // the least-significant bits or elsewhere.
327 // significant bits.
328 Int64BinopMatcher mleft(m.left().node()); 326 Int64BinopMatcher mleft(m.left().node());
329 if (mleft.right().HasValue()) { 327 if (mleft.right().HasValue()) {
330 // Any shift value can match; int64 shifts use `value % 64`. 328 // Any shift value can match; int64 shifts use `value % 64`.
331 uint32_t lsb = static_cast<uint32_t>(mleft.right().Value() & 0x3f); 329 uint32_t lsb = static_cast<uint32_t>(mleft.right().Value() & 0x3f);
332 330 lsb = lsb + mask_lsb;
333 // Dext cannot extract bits past the register size, however since 331 // Dext cannot extract bits past the register size, however since
334 // shifting the original value would have introduced some zeros we can 332 // shifting the original value would have introduced some zeros we can
335 // still use Dext with a smaller mask and the remaining bits will be 333 // still use Dext with a smaller mask and the remaining bits will be
336 // zeros. 334 // zeros.
337 if (lsb + mask_width > 64) mask_width = 64 - lsb; 335 if (lsb + mask_width > 64) mask_width = 64 - lsb;
338
339 Emit(kMips64Dext, g.DefineAsRegister(node), 336 Emit(kMips64Dext, g.DefineAsRegister(node),
340 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb), 337 g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
341 g.TempImmediate(static_cast<int32_t>(mask_width))); 338 g.TempImmediate(static_cast<int32_t>(mask_width)));
342 return; 339 return;
343 } 340 }
344 // Other cases fall through to the normal And operation. 341 // Other cases fall through to the normal And operation.
345 } 342 }
346 } 343 }
347 if (m.right().HasValue()) { 344 if (m.right().HasValue()) {
348 uint64_t mask = m.right().Value(); 345 uint64_t mask = m.right().Value();
(...skipping 1484 matching lines...) Expand 10 before | Expand all | Expand 10 after
1833 MachineOperatorBuilder::kFloat32RoundUp | 1830 MachineOperatorBuilder::kFloat32RoundUp |
1834 MachineOperatorBuilder::kFloat64RoundTruncate | 1831 MachineOperatorBuilder::kFloat64RoundTruncate |
1835 MachineOperatorBuilder::kFloat32RoundTruncate | 1832 MachineOperatorBuilder::kFloat32RoundTruncate |
1836 MachineOperatorBuilder::kFloat64RoundTiesEven | 1833 MachineOperatorBuilder::kFloat64RoundTiesEven |
1837 MachineOperatorBuilder::kFloat32RoundTiesEven; 1834 MachineOperatorBuilder::kFloat32RoundTiesEven;
1838 } 1835 }
1839 1836
1840 } // namespace compiler 1837 } // namespace compiler
1841 } // namespace internal 1838 } // namespace internal
1842 } // namespace v8 1839 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698