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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
8 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 } | 101 } |
102 } | 102 } |
103 | 103 |
104 bool CanBeBetterLeftOperand(Node* node) const { | 104 bool CanBeBetterLeftOperand(Node* node) const { |
105 return !selector()->IsLive(node); | 105 return !selector()->IsLive(node); |
106 } | 106 } |
107 }; | 107 }; |
108 | 108 |
109 | 109 |
110 void InstructionSelector::VisitLoad(Node* node) { | 110 void InstructionSelector::VisitLoad(Node* node) { |
111 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 111 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
112 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
113 X64OperandGenerator g(this); | 112 X64OperandGenerator g(this); |
114 | 113 |
115 ArchOpcode opcode; | 114 ArchOpcode opcode; |
116 switch (rep) { | 115 switch (load_rep.representation()) { |
117 case kRepFloat32: | 116 case MachineRepresentation::kFloat32: |
118 opcode = kX64Movss; | 117 opcode = kX64Movss; |
119 break; | 118 break; |
120 case kRepFloat64: | 119 case MachineRepresentation::kFloat64: |
121 opcode = kX64Movsd; | 120 opcode = kX64Movsd; |
122 break; | 121 break; |
123 case kRepBit: // Fall through. | 122 case MachineRepresentation::kBit: // Fall through. |
124 case kRepWord8: | 123 case MachineRepresentation::kWord8: |
125 opcode = typ == kTypeInt32 ? kX64Movsxbl : kX64Movzxbl; | 124 opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl; |
126 break; | 125 break; |
127 case kRepWord16: | 126 case MachineRepresentation::kWord16: |
128 opcode = typ == kTypeInt32 ? kX64Movsxwl : kX64Movzxwl; | 127 opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl; |
129 break; | 128 break; |
130 case kRepWord32: | 129 case MachineRepresentation::kWord32: |
131 opcode = kX64Movl; | 130 opcode = kX64Movl; |
132 break; | 131 break; |
133 case kRepTagged: // Fall through. | 132 case MachineRepresentation::kTagged: // Fall through. |
134 case kRepWord64: | 133 case MachineRepresentation::kWord64: |
135 opcode = kX64Movq; | 134 opcode = kX64Movq; |
136 break; | 135 break; |
137 default: | 136 default: |
138 UNREACHABLE(); | 137 UNREACHABLE(); |
139 return; | 138 return; |
140 } | 139 } |
141 | 140 |
142 InstructionOperand outputs[1]; | 141 InstructionOperand outputs[1]; |
143 outputs[0] = g.DefineAsRegister(node); | 142 outputs[0] = g.DefineAsRegister(node); |
144 InstructionOperand inputs[3]; | 143 InstructionOperand inputs[3]; |
145 size_t input_count = 0; | 144 size_t input_count = 0; |
146 AddressingMode mode = | 145 AddressingMode mode = |
147 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 146 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
148 InstructionCode code = opcode | AddressingModeField::encode(mode); | 147 InstructionCode code = opcode | AddressingModeField::encode(mode); |
149 Emit(code, 1, outputs, input_count, inputs); | 148 Emit(code, 1, outputs, input_count, inputs); |
150 } | 149 } |
151 | 150 |
152 | 151 |
153 void InstructionSelector::VisitStore(Node* node) { | 152 void InstructionSelector::VisitStore(Node* node) { |
154 X64OperandGenerator g(this); | 153 X64OperandGenerator g(this); |
155 Node* base = node->InputAt(0); | 154 Node* base = node->InputAt(0); |
156 Node* index = node->InputAt(1); | 155 Node* index = node->InputAt(1); |
157 Node* value = node->InputAt(2); | 156 Node* value = node->InputAt(2); |
158 | 157 |
159 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 158 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
160 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 159 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
161 MachineType rep = RepresentationOf(store_rep.machine_type()); | 160 MachineRepresentation rep = store_rep.machine_type().representation(); |
162 | 161 |
163 if (write_barrier_kind != kNoWriteBarrier) { | 162 if (write_barrier_kind != kNoWriteBarrier) { |
164 DCHECK_EQ(kRepTagged, rep); | 163 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
165 AddressingMode addressing_mode; | 164 AddressingMode addressing_mode; |
166 InstructionOperand inputs[3]; | 165 InstructionOperand inputs[3]; |
167 size_t input_count = 0; | 166 size_t input_count = 0; |
168 inputs[input_count++] = g.UseUniqueRegister(base); | 167 inputs[input_count++] = g.UseUniqueRegister(base); |
169 if (g.CanBeImmediate(index)) { | 168 if (g.CanBeImmediate(index)) { |
170 inputs[input_count++] = g.UseImmediate(index); | 169 inputs[input_count++] = g.UseImmediate(index); |
171 addressing_mode = kMode_MRI; | 170 addressing_mode = kMode_MRI; |
172 } else { | 171 } else { |
173 inputs[input_count++] = g.UseUniqueRegister(index); | 172 inputs[input_count++] = g.UseUniqueRegister(index); |
174 addressing_mode = kMode_MR1; | 173 addressing_mode = kMode_MR1; |
(...skipping 18 matching lines...) Expand all Loading... |
193 } | 192 } |
194 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 193 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
195 size_t const temp_count = arraysize(temps); | 194 size_t const temp_count = arraysize(temps); |
196 InstructionCode code = kArchStoreWithWriteBarrier; | 195 InstructionCode code = kArchStoreWithWriteBarrier; |
197 code |= AddressingModeField::encode(addressing_mode); | 196 code |= AddressingModeField::encode(addressing_mode); |
198 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 197 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
199 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 198 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
200 } else { | 199 } else { |
201 ArchOpcode opcode; | 200 ArchOpcode opcode; |
202 switch (rep) { | 201 switch (rep) { |
203 case kRepFloat32: | 202 case MachineRepresentation::kFloat32: |
204 opcode = kX64Movss; | 203 opcode = kX64Movss; |
205 break; | 204 break; |
206 case kRepFloat64: | 205 case MachineRepresentation::kFloat64: |
207 opcode = kX64Movsd; | 206 opcode = kX64Movsd; |
208 break; | 207 break; |
209 case kRepBit: // Fall through. | 208 case MachineRepresentation::kBit: // Fall through. |
210 case kRepWord8: | 209 case MachineRepresentation::kWord8: |
211 opcode = kX64Movb; | 210 opcode = kX64Movb; |
212 break; | 211 break; |
213 case kRepWord16: | 212 case MachineRepresentation::kWord16: |
214 opcode = kX64Movw; | 213 opcode = kX64Movw; |
215 break; | 214 break; |
216 case kRepWord32: | 215 case MachineRepresentation::kWord32: |
217 opcode = kX64Movl; | 216 opcode = kX64Movl; |
218 break; | 217 break; |
219 case kRepTagged: // Fall through. | 218 case MachineRepresentation::kTagged: // Fall through. |
220 case kRepWord64: | 219 case MachineRepresentation::kWord64: |
221 opcode = kX64Movq; | 220 opcode = kX64Movq; |
222 break; | 221 break; |
223 default: | 222 default: |
224 UNREACHABLE(); | 223 UNREACHABLE(); |
225 return; | 224 return; |
226 } | 225 } |
227 InstructionOperand inputs[4]; | 226 InstructionOperand inputs[4]; |
228 size_t input_count = 0; | 227 size_t input_count = 0; |
229 AddressingMode addressing_mode = | 228 AddressingMode addressing_mode = |
230 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 229 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
231 InstructionCode code = | 230 InstructionCode code = |
232 opcode | AddressingModeField::encode(addressing_mode); | 231 opcode | AddressingModeField::encode(addressing_mode); |
233 InstructionOperand value_operand = | 232 InstructionOperand value_operand = |
234 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); | 233 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); |
235 inputs[input_count++] = value_operand; | 234 inputs[input_count++] = value_operand; |
236 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); | 235 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); |
237 } | 236 } |
238 } | 237 } |
239 | 238 |
240 | 239 |
241 void InstructionSelector::VisitCheckedLoad(Node* node) { | 240 void InstructionSelector::VisitCheckedLoad(Node* node) { |
242 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 241 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
243 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
244 X64OperandGenerator g(this); | 242 X64OperandGenerator g(this); |
245 Node* const buffer = node->InputAt(0); | 243 Node* const buffer = node->InputAt(0); |
246 Node* const offset = node->InputAt(1); | 244 Node* const offset = node->InputAt(1); |
247 Node* const length = node->InputAt(2); | 245 Node* const length = node->InputAt(2); |
248 ArchOpcode opcode; | 246 ArchOpcode opcode; |
249 switch (rep) { | 247 switch (load_rep.representation()) { |
250 case kRepWord8: | 248 case MachineRepresentation::kWord8: |
251 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 249 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
252 break; | 250 break; |
253 case kRepWord16: | 251 case MachineRepresentation::kWord16: |
254 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 252 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
255 break; | 253 break; |
256 case kRepWord32: | 254 case MachineRepresentation::kWord32: |
257 opcode = kCheckedLoadWord32; | 255 opcode = kCheckedLoadWord32; |
258 break; | 256 break; |
259 case kRepWord64: | 257 case MachineRepresentation::kWord64: |
260 opcode = kCheckedLoadWord64; | 258 opcode = kCheckedLoadWord64; |
261 break; | 259 break; |
262 case kRepFloat32: | 260 case MachineRepresentation::kFloat32: |
263 opcode = kCheckedLoadFloat32; | 261 opcode = kCheckedLoadFloat32; |
264 break; | 262 break; |
265 case kRepFloat64: | 263 case MachineRepresentation::kFloat64: |
266 opcode = kCheckedLoadFloat64; | 264 opcode = kCheckedLoadFloat64; |
267 break; | 265 break; |
268 default: | 266 default: |
269 UNREACHABLE(); | 267 UNREACHABLE(); |
270 return; | 268 return; |
271 } | 269 } |
272 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { | 270 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { |
273 Int32Matcher mlength(length); | 271 Int32Matcher mlength(length); |
274 Int32BinopMatcher moffset(offset); | 272 Int32BinopMatcher moffset(offset); |
275 if (mlength.HasValue() && moffset.right().HasValue() && | 273 if (mlength.HasValue() && moffset.right().HasValue() && |
276 moffset.right().Value() >= 0 && | 274 moffset.right().Value() >= 0 && |
277 mlength.Value() >= moffset.right().Value()) { | 275 mlength.Value() >= moffset.right().Value()) { |
278 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), | 276 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), |
279 g.UseRegister(moffset.left().node()), | 277 g.UseRegister(moffset.left().node()), |
280 g.UseImmediate(moffset.right().node()), g.UseImmediate(length)); | 278 g.UseImmediate(moffset.right().node()), g.UseImmediate(length)); |
281 return; | 279 return; |
282 } | 280 } |
283 } | 281 } |
284 InstructionOperand length_operand = | 282 InstructionOperand length_operand = |
285 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 283 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
286 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), | 284 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), |
287 g.UseRegister(offset), g.TempImmediate(0), length_operand); | 285 g.UseRegister(offset), g.TempImmediate(0), length_operand); |
288 } | 286 } |
289 | 287 |
290 | 288 |
291 void InstructionSelector::VisitCheckedStore(Node* node) { | 289 void InstructionSelector::VisitCheckedStore(Node* node) { |
292 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 290 MachineRepresentation rep = |
| 291 CheckedStoreRepresentationOf(node->op()).representation(); |
293 X64OperandGenerator g(this); | 292 X64OperandGenerator g(this); |
294 Node* const buffer = node->InputAt(0); | 293 Node* const buffer = node->InputAt(0); |
295 Node* const offset = node->InputAt(1); | 294 Node* const offset = node->InputAt(1); |
296 Node* const length = node->InputAt(2); | 295 Node* const length = node->InputAt(2); |
297 Node* const value = node->InputAt(3); | 296 Node* const value = node->InputAt(3); |
298 ArchOpcode opcode; | 297 ArchOpcode opcode; |
299 switch (rep) { | 298 switch (rep) { |
300 case kRepWord8: | 299 case MachineRepresentation::kWord8: |
301 opcode = kCheckedStoreWord8; | 300 opcode = kCheckedStoreWord8; |
302 break; | 301 break; |
303 case kRepWord16: | 302 case MachineRepresentation::kWord16: |
304 opcode = kCheckedStoreWord16; | 303 opcode = kCheckedStoreWord16; |
305 break; | 304 break; |
306 case kRepWord32: | 305 case MachineRepresentation::kWord32: |
307 opcode = kCheckedStoreWord32; | 306 opcode = kCheckedStoreWord32; |
308 break; | 307 break; |
309 case kRepWord64: | 308 case MachineRepresentation::kWord64: |
310 opcode = kCheckedStoreWord64; | 309 opcode = kCheckedStoreWord64; |
311 break; | 310 break; |
312 case kRepFloat32: | 311 case MachineRepresentation::kFloat32: |
313 opcode = kCheckedStoreFloat32; | 312 opcode = kCheckedStoreFloat32; |
314 break; | 313 break; |
315 case kRepFloat64: | 314 case MachineRepresentation::kFloat64: |
316 opcode = kCheckedStoreFloat64; | 315 opcode = kCheckedStoreFloat64; |
317 break; | 316 break; |
318 default: | 317 default: |
319 UNREACHABLE(); | 318 UNREACHABLE(); |
320 return; | 319 return; |
321 } | 320 } |
322 InstructionOperand value_operand = | 321 InstructionOperand value_operand = |
323 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); | 322 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); |
324 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { | 323 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { |
325 Int32Matcher mlength(length); | 324 Int32Matcher mlength(length); |
(...skipping 1435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1761 MachineOperatorBuilder::kFloat64RoundTruncate | | 1760 MachineOperatorBuilder::kFloat64RoundTruncate | |
1762 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1761 MachineOperatorBuilder::kFloat32RoundTiesEven | |
1763 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1762 MachineOperatorBuilder::kFloat64RoundTiesEven; |
1764 } | 1763 } |
1765 return flags; | 1764 return flags; |
1766 } | 1765 } |
1767 | 1766 |
1768 } // namespace compiler | 1767 } // namespace compiler |
1769 } // namespace internal | 1768 } // namespace internal |
1770 } // namespace v8 | 1769 } // namespace v8 |
OLD | NEW |