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

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

Issue 658283003: [arm] Prefer BIC over BFC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/asm/word32and.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/bits.h" 5 #include "src/base/bits.h"
6 #include "src/compiler/instruction-selector-impl.h" 6 #include "src/compiler/instruction-selector-impl.h"
7 #include "src/compiler/node-matchers.h" 7 #include "src/compiler/node-matchers.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
11 namespace compiler { 11 namespace compiler {
12 12
13 // Adds Arm-specific methods for generating InstructionOperands. 13 // Adds Arm-specific methods for generating InstructionOperands.
14 class ArmOperandGenerator : public OperandGenerator { 14 class ArmOperandGenerator : public OperandGenerator {
15 public: 15 public:
16 explicit ArmOperandGenerator(InstructionSelector* selector) 16 explicit ArmOperandGenerator(InstructionSelector* selector)
17 : OperandGenerator(selector) {} 17 : OperandGenerator(selector) {}
18 18
19 InstructionOperand* UseOperand(Node* node, InstructionCode opcode) { 19 InstructionOperand* UseOperand(Node* node, InstructionCode opcode) {
20 if (CanBeImmediate(node, opcode)) { 20 if (CanBeImmediate(node, opcode)) {
21 return UseImmediate(node); 21 return UseImmediate(node);
22 } 22 }
23 return UseRegister(node); 23 return UseRegister(node);
24 } 24 }
25 25
26 bool CanBeImmediate(int32_t value) const {
27 return Assembler::ImmediateFitsAddrMode1Instruction(value);
28 }
29
30 bool CanBeImmediate(uint32_t value) const {
31 return CanBeImmediate(bit_cast<int32_t>(value));
32 }
33
26 bool CanBeImmediate(Node* node, InstructionCode opcode) { 34 bool CanBeImmediate(Node* node, InstructionCode opcode) {
27 Int32Matcher m(node); 35 Int32Matcher m(node);
28 if (!m.HasValue()) return false; 36 if (!m.HasValue()) return false;
29 int32_t value = m.Value(); 37 int32_t value = m.Value();
30 switch (ArchOpcodeField::decode(opcode)) { 38 switch (ArchOpcodeField::decode(opcode)) {
31 case kArmAnd: 39 case kArmAnd:
32 case kArmMov: 40 case kArmMov:
33 case kArmMvn: 41 case kArmMvn:
34 case kArmBic: 42 case kArmBic:
35 return ImmediateFitsAddrMode1Instruction(value) || 43 return CanBeImmediate(value) || CanBeImmediate(~value);
36 ImmediateFitsAddrMode1Instruction(~value);
37 44
38 case kArmAdd: 45 case kArmAdd:
39 case kArmSub: 46 case kArmSub:
40 case kArmCmp: 47 case kArmCmp:
41 case kArmCmn: 48 case kArmCmn:
42 return ImmediateFitsAddrMode1Instruction(value) || 49 return CanBeImmediate(value) || CanBeImmediate(-value);
43 ImmediateFitsAddrMode1Instruction(-value);
44 50
45 case kArmTst: 51 case kArmTst:
46 case kArmTeq: 52 case kArmTeq:
47 case kArmOrr: 53 case kArmOrr:
48 case kArmEor: 54 case kArmEor:
49 case kArmRsb: 55 case kArmRsb:
50 return ImmediateFitsAddrMode1Instruction(value); 56 return CanBeImmediate(value);
51 57
52 case kArmVldrF32: 58 case kArmVldrF32:
53 case kArmVstrF32: 59 case kArmVstrF32:
54 case kArmVldrF64: 60 case kArmVldrF64:
55 case kArmVstrF64: 61 case kArmVstrF64:
56 return value >= -1020 && value <= 1020 && (value % 4) == 0; 62 return value >= -1020 && value <= 1020 && (value % 4) == 0;
57 63
58 case kArmLdrb: 64 case kArmLdrb:
59 case kArmLdrsb: 65 case kArmLdrsb:
60 case kArmStrb: 66 case kArmStrb:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 case kArmVcvtF64S32: 105 case kArmVcvtF64S32:
100 case kArmVcvtF64U32: 106 case kArmVcvtF64U32:
101 case kArmVcvtS32F64: 107 case kArmVcvtS32F64:
102 case kArmVcvtU32F64: 108 case kArmVcvtU32F64:
103 case kArmPush: 109 case kArmPush:
104 return false; 110 return false;
105 } 111 }
106 UNREACHABLE(); 112 UNREACHABLE();
107 return false; 113 return false;
108 } 114 }
109
110 private:
111 bool ImmediateFitsAddrMode1Instruction(int32_t imm) const {
112 return Assembler::ImmediateFitsAddrMode1Instruction(imm);
113 }
114 }; 115 };
115 116
116 117
117 static void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode, 118 static void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
118 Node* node) { 119 Node* node) {
119 ArmOperandGenerator g(selector); 120 ArmOperandGenerator g(selector);
120 selector->Emit(opcode, g.DefineAsRegister(node), 121 selector->Emit(opcode, g.DefineAsRegister(node),
121 g.UseRegister(node->InputAt(0)), 122 g.UseRegister(node->InputAt(0)),
122 g.UseRegister(node->InputAt(1))); 123 g.UseRegister(node->InputAt(1)));
123 } 124 }
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 } 411 }
411 } 412 }
412 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) { 413 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) {
413 Int32BinopMatcher mright(m.right().node()); 414 Int32BinopMatcher mright(m.right().node());
414 if (mright.right().Is(-1)) { 415 if (mright.right().Is(-1)) {
415 EmitBic(this, node, m.left().node(), mright.left().node()); 416 EmitBic(this, node, m.left().node(), mright.left().node());
416 return; 417 return;
417 } 418 }
418 } 419 }
419 if (IsSupported(ARMv7) && m.right().HasValue()) { 420 if (IsSupported(ARMv7) && m.right().HasValue()) {
420 uint32_t value = m.right().Value(); 421 // Try to interpret this AND as UBFX.
422 uint32_t const value = m.right().Value();
421 uint32_t width = base::bits::CountPopulation32(value); 423 uint32_t width = base::bits::CountPopulation32(value);
422 uint32_t msb = base::bits::CountLeadingZeros32(value); 424 uint32_t msb = base::bits::CountLeadingZeros32(value);
423 if (width != 0 && msb + width == 32) { 425 if (width != 0 && msb + width == 32) {
424 DCHECK_EQ(0, base::bits::CountTrailingZeros32(value)); 426 DCHECK_EQ(0, base::bits::CountTrailingZeros32(value));
425 if (m.left().IsWord32Shr()) { 427 if (m.left().IsWord32Shr()) {
426 Int32BinopMatcher mleft(m.left().node()); 428 Int32BinopMatcher mleft(m.left().node());
427 if (mleft.right().IsInRange(0, 31)) { 429 if (mleft.right().IsInRange(0, 31)) {
428 Emit(kArmUbfx, g.DefineAsRegister(node), 430 Emit(kArmUbfx, g.DefineAsRegister(node),
429 g.UseRegister(mleft.left().node()), 431 g.UseRegister(mleft.left().node()),
430 g.UseImmediate(mleft.right().node()), g.TempImmediate(width)); 432 g.UseImmediate(mleft.right().node()), g.TempImmediate(width));
431 return; 433 return;
432 } 434 }
433 } 435 }
434 Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(m.left().node()), 436 Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
435 g.TempImmediate(0), g.TempImmediate(width)); 437 g.TempImmediate(0), g.TempImmediate(width));
436 return; 438 return;
437 } 439 }
440
441 // Try to interpret this AND as BIC.
442 if (g.CanBeImmediate(~value)) {
443 Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I),
444 g.DefineAsRegister(node), g.UseRegister(m.left().node()),
445 g.TempImmediate(~value));
446 return;
447 }
448
438 // Try to interpret this AND as BFC. 449 // Try to interpret this AND as BFC.
439 width = 32 - width; 450 width = 32 - width;
440 msb = base::bits::CountLeadingZeros32(~value); 451 msb = base::bits::CountLeadingZeros32(~value);
441 uint32_t lsb = base::bits::CountTrailingZeros32(~value); 452 uint32_t lsb = base::bits::CountTrailingZeros32(~value);
442 if (msb + width + lsb == 32) { 453 if (msb + width + lsb == 32) {
443 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 454 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
444 g.TempImmediate(lsb), g.TempImmediate(width)); 455 g.TempImmediate(lsb), g.TempImmediate(width));
445 return; 456 return;
446 } 457 }
447 } 458 }
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 1163
1153 1164
1154 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { 1165 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
1155 FlagsContinuation cont(kUnorderedLessThanOrEqual, node); 1166 FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
1156 VisitFloat64Compare(this, node, &cont); 1167 VisitFloat64Compare(this, node, &cont);
1157 } 1168 }
1158 1169
1159 } // namespace compiler 1170 } // namespace compiler
1160 } // namespace internal 1171 } // namespace internal
1161 } // namespace v8 1172 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/asm/word32and.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698