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/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
7 #include "src/compiler/node-properties-inl.h" | 7 #include "src/compiler/node-properties-inl.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 | 46 |
47 // Get the AddressingMode of scale factor N from the AddressingMode of scale | 47 // Get the AddressingMode of scale factor N from the AddressingMode of scale |
48 // factor 1. | 48 // factor 1. |
49 static AddressingMode AdjustAddressingMode(AddressingMode base_mode, | 49 static AddressingMode AdjustAddressingMode(AddressingMode base_mode, |
50 int power) { | 50 int power) { |
51 DCHECK(0 <= power && power < 4); | 51 DCHECK(0 <= power && power < 4); |
52 return static_cast<AddressingMode>(static_cast<int>(base_mode) + power); | 52 return static_cast<AddressingMode>(static_cast<int>(base_mode) + power); |
53 } | 53 } |
54 | 54 |
55 | 55 |
| 56 // Fairly intel-specify node matcher used for matching scale factors in |
| 57 // addressing modes. |
| 58 // Matches nodes of form [x * N] for N in {1,2,4,8} |
| 59 class ScaleFactorMatcher : public NodeMatcher { |
| 60 public: |
| 61 static const int kMatchedFactors[4]; |
| 62 |
| 63 explicit ScaleFactorMatcher(Node* node); |
| 64 |
| 65 bool Matches() const { return left_ != NULL; } |
| 66 int Power() const { |
| 67 DCHECK(Matches()); |
| 68 return power_; |
| 69 } |
| 70 Node* Left() const { |
| 71 DCHECK(Matches()); |
| 72 return left_; |
| 73 } |
| 74 |
| 75 private: |
| 76 Node* left_; |
| 77 int power_; |
| 78 }; |
| 79 |
| 80 |
| 81 // Fairly intel-specify node matcher used for matching index and displacement |
| 82 // operands in addressing modes. |
| 83 // Matches nodes of form: |
| 84 // [x * N] |
| 85 // [x * N + K] |
| 86 // [x + K] |
| 87 // [x] -- fallback case |
| 88 // for N in {1,2,4,8} and K int32_t |
| 89 class IndexAndDisplacementMatcher : public NodeMatcher { |
| 90 public: |
| 91 explicit IndexAndDisplacementMatcher(Node* node); |
| 92 |
| 93 Node* index_node() const { return index_node_; } |
| 94 int displacement() const { return displacement_; } |
| 95 int power() const { return power_; } |
| 96 |
| 97 private: |
| 98 Node* index_node_; |
| 99 int displacement_; |
| 100 int power_; |
| 101 }; |
| 102 |
| 103 |
| 104 // Fairly intel-specify node matcher used for matching multiplies that can be |
| 105 // transformed to lea instructions. |
| 106 // Matches nodes of form: |
| 107 // [x * N] |
| 108 // for N in {1,2,3,4,5,8,9} |
| 109 class LeaMultiplyMatcher : public NodeMatcher { |
| 110 public: |
| 111 static const int kMatchedFactors[7]; |
| 112 |
| 113 explicit LeaMultiplyMatcher(Node* node); |
| 114 |
| 115 bool Matches() const { return left_ != NULL; } |
| 116 int Power() const { |
| 117 DCHECK(Matches()); |
| 118 return power_; |
| 119 } |
| 120 Node* Left() const { |
| 121 DCHECK(Matches()); |
| 122 return left_; |
| 123 } |
| 124 // Displacement will be either 0 or 1. |
| 125 int32_t Displacement() const { |
| 126 DCHECK(Matches()); |
| 127 return displacement_; |
| 128 } |
| 129 |
| 130 private: |
| 131 Node* left_; |
| 132 int power_; |
| 133 int displacement_; |
| 134 }; |
| 135 |
| 136 |
| 137 const int ScaleFactorMatcher::kMatchedFactors[] = {1, 2, 4, 8}; |
| 138 |
| 139 |
| 140 ScaleFactorMatcher::ScaleFactorMatcher(Node* node) |
| 141 : NodeMatcher(node), left_(NULL), power_(0) { |
| 142 if (opcode() != IrOpcode::kInt32Mul) return; |
| 143 // TODO(dcarney): should test 64 bit ints as well. |
| 144 Int32BinopMatcher m(this->node()); |
| 145 if (!m.right().HasValue()) return; |
| 146 int32_t value = m.right().Value(); |
| 147 switch (value) { |
| 148 case 8: |
| 149 power_++; // Fall through. |
| 150 case 4: |
| 151 power_++; // Fall through. |
| 152 case 2: |
| 153 power_++; // Fall through. |
| 154 case 1: |
| 155 break; |
| 156 default: |
| 157 return; |
| 158 } |
| 159 left_ = m.left().node(); |
| 160 } |
| 161 |
| 162 |
| 163 IndexAndDisplacementMatcher::IndexAndDisplacementMatcher(Node* node) |
| 164 : NodeMatcher(node), index_node_(node), displacement_(0), power_(0) { |
| 165 if (opcode() == IrOpcode::kInt32Add) { |
| 166 Int32BinopMatcher m(this->node()); |
| 167 if (m.right().HasValue()) { |
| 168 displacement_ = m.right().Value(); |
| 169 index_node_ = m.left().node(); |
| 170 } |
| 171 } |
| 172 // Test scale factor. |
| 173 ScaleFactorMatcher scale_matcher(index_node_); |
| 174 if (scale_matcher.Matches()) { |
| 175 index_node_ = scale_matcher.Left(); |
| 176 power_ = scale_matcher.Power(); |
| 177 } |
| 178 } |
| 179 |
| 180 |
| 181 const int LeaMultiplyMatcher::kMatchedFactors[7] = {1, 2, 3, 4, 5, 8, 9}; |
| 182 |
| 183 |
| 184 LeaMultiplyMatcher::LeaMultiplyMatcher(Node* node) |
| 185 : NodeMatcher(node), left_(NULL), power_(0), displacement_(0) { |
| 186 if (opcode() != IrOpcode::kInt32Mul && opcode() != IrOpcode::kInt64Mul) { |
| 187 return; |
| 188 } |
| 189 int64_t value; |
| 190 Node* left = NULL; |
| 191 { |
| 192 Int32BinopMatcher m(this->node()); |
| 193 if (m.right().HasValue()) { |
| 194 value = m.right().Value(); |
| 195 left = m.left().node(); |
| 196 } else { |
| 197 Int64BinopMatcher m(this->node()); |
| 198 if (m.right().HasValue()) { |
| 199 value = m.right().Value(); |
| 200 left = m.left().node(); |
| 201 } else { |
| 202 return; |
| 203 } |
| 204 } |
| 205 } |
| 206 switch (value) { |
| 207 case 9: |
| 208 case 8: |
| 209 power_++; // Fall through. |
| 210 case 5: |
| 211 case 4: |
| 212 power_++; // Fall through. |
| 213 case 3: |
| 214 case 2: |
| 215 power_++; // Fall through. |
| 216 case 1: |
| 217 break; |
| 218 default: |
| 219 return; |
| 220 } |
| 221 if (!base::bits::IsPowerOfTwo64(value)) { |
| 222 displacement_ = 1; |
| 223 } |
| 224 left_ = left; |
| 225 } |
| 226 |
| 227 |
56 class AddressingModeMatcher { | 228 class AddressingModeMatcher { |
57 public: | 229 public: |
58 AddressingModeMatcher(IA32OperandGenerator* g, Node* base, Node* index) | 230 AddressingModeMatcher(IA32OperandGenerator* g, Node* base, Node* index) |
59 : base_operand_(NULL), | 231 : base_operand_(NULL), |
60 index_operand_(NULL), | 232 index_operand_(NULL), |
61 displacement_operand_(NULL), | 233 displacement_operand_(NULL), |
62 mode_(kMode_None) { | 234 mode_(kMode_None) { |
63 Int32Matcher index_imm(index); | 235 Int32Matcher index_imm(index); |
64 if (index_imm.HasValue()) { | 236 if (index_imm.HasValue()) { |
65 int32_t displacement = index_imm.Value(); | 237 int32_t displacement = index_imm.Value(); |
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 if (CpuFeatures::IsSupported(SSE4_1)) { | 1087 if (CpuFeatures::IsSupported(SSE4_1)) { |
916 return MachineOperatorBuilder::kFloat64Floor | | 1088 return MachineOperatorBuilder::kFloat64Floor | |
917 MachineOperatorBuilder::kFloat64Ceil | | 1089 MachineOperatorBuilder::kFloat64Ceil | |
918 MachineOperatorBuilder::kFloat64RoundTruncate; | 1090 MachineOperatorBuilder::kFloat64RoundTruncate; |
919 } | 1091 } |
920 return MachineOperatorBuilder::Flag::kNoFlags; | 1092 return MachineOperatorBuilder::Flag::kNoFlags; |
921 } | 1093 } |
922 } // namespace compiler | 1094 } // namespace compiler |
923 } // namespace internal | 1095 } // namespace internal |
924 } // namespace v8 | 1096 } // namespace v8 |
OLD | NEW |