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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 | 99 |
100 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 100 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
101 MachineType rep = RepresentationOf(store_rep.machine_type); | 101 MachineType rep = RepresentationOf(store_rep.machine_type); |
102 if (store_rep.write_barrier_kind == kFullWriteBarrier) { | 102 if (store_rep.write_barrier_kind == kFullWriteBarrier) { |
103 DCHECK_EQ(kRepTagged, rep); | 103 DCHECK_EQ(kRepTagged, rep); |
104 // TODO(dcarney): refactor RecordWrite function to take temp registers | 104 // TODO(dcarney): refactor RecordWrite function to take temp registers |
105 // and pass them here instead of using fixed regs | 105 // and pass them here instead of using fixed regs |
106 // TODO(dcarney): handle immediate indices. | 106 // TODO(dcarney): handle immediate indices. |
107 InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; | 107 InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; |
108 Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx), | 108 Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx), |
109 g.UseFixed(index, ecx), g.UseFixed(value, edx), ARRAY_SIZE(temps), | 109 g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps), |
110 temps); | 110 temps); |
111 return; | 111 return; |
112 } | 112 } |
113 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); | 113 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); |
114 InstructionOperand* val; | 114 InstructionOperand* val; |
115 if (g.CanBeImmediate(value)) { | 115 if (g.CanBeImmediate(value)) { |
116 val = g.UseImmediate(value); | 116 val = g.UseImmediate(value); |
117 } else if (rep == kRepWord8 || rep == kRepBit) { | 117 } else if (rep == kRepWord8 || rep == kRepBit) { |
118 val = g.UseByteRegister(value); | 118 val = g.UseByteRegister(value); |
119 } else { | 119 } else { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 } | 188 } |
189 | 189 |
190 outputs[output_count++] = g.DefineSameAsFirst(node); | 190 outputs[output_count++] = g.DefineSameAsFirst(node); |
191 if (cont->IsSet()) { | 191 if (cont->IsSet()) { |
192 // TODO(turbofan): Use byte register here. | 192 // TODO(turbofan): Use byte register here. |
193 outputs[output_count++] = g.DefineAsRegister(cont->result()); | 193 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
194 } | 194 } |
195 | 195 |
196 DCHECK_NE(0, input_count); | 196 DCHECK_NE(0, input_count); |
197 DCHECK_NE(0, output_count); | 197 DCHECK_NE(0, output_count); |
198 DCHECK_GE(ARRAY_SIZE(inputs), input_count); | 198 DCHECK_GE(arraysize(inputs), input_count); |
199 DCHECK_GE(ARRAY_SIZE(outputs), output_count); | 199 DCHECK_GE(arraysize(outputs), output_count); |
200 | 200 |
201 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, | 201 Instruction* instr = selector->Emit(cont->Encode(opcode), output_count, |
202 outputs, input_count, inputs); | 202 outputs, input_count, inputs); |
203 if (cont->IsBranch()) instr->MarkAsControl(); | 203 if (cont->IsBranch()) instr->MarkAsControl(); |
204 } | 204 } |
205 | 205 |
206 | 206 |
207 // Shared routine for multiple binary operations. | 207 // Shared routine for multiple binary operations. |
208 static void VisitBinop(InstructionSelector* selector, Node* node, | 208 static void VisitBinop(InstructionSelector* selector, Node* node, |
209 InstructionCode opcode) { | 209 InstructionCode opcode) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left), | 309 Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left), |
310 g.Use(right)); | 310 g.Use(right)); |
311 } | 311 } |
312 } | 312 } |
313 | 313 |
314 | 314 |
315 static inline void VisitDiv(InstructionSelector* selector, Node* node, | 315 static inline void VisitDiv(InstructionSelector* selector, Node* node, |
316 ArchOpcode opcode) { | 316 ArchOpcode opcode) { |
317 IA32OperandGenerator g(selector); | 317 IA32OperandGenerator g(selector); |
318 InstructionOperand* temps[] = {g.TempRegister(edx)}; | 318 InstructionOperand* temps[] = {g.TempRegister(edx)}; |
319 size_t temp_count = ARRAY_SIZE(temps); | 319 size_t temp_count = arraysize(temps); |
320 selector->Emit(opcode, g.DefineAsFixed(node, eax), | 320 selector->Emit(opcode, g.DefineAsFixed(node, eax), |
321 g.UseFixed(node->InputAt(0), eax), | 321 g.UseFixed(node->InputAt(0), eax), |
322 g.UseUnique(node->InputAt(1)), temp_count, temps); | 322 g.UseUnique(node->InputAt(1)), temp_count, temps); |
323 } | 323 } |
324 | 324 |
325 | 325 |
326 void InstructionSelector::VisitInt32Div(Node* node) { | 326 void InstructionSelector::VisitInt32Div(Node* node) { |
327 VisitDiv(this, node, kIA32Idiv); | 327 VisitDiv(this, node, kIA32Idiv); |
328 } | 328 } |
329 | 329 |
330 | 330 |
331 void InstructionSelector::VisitInt32UDiv(Node* node) { | 331 void InstructionSelector::VisitInt32UDiv(Node* node) { |
332 VisitDiv(this, node, kIA32Udiv); | 332 VisitDiv(this, node, kIA32Udiv); |
333 } | 333 } |
334 | 334 |
335 | 335 |
336 static inline void VisitMod(InstructionSelector* selector, Node* node, | 336 static inline void VisitMod(InstructionSelector* selector, Node* node, |
337 ArchOpcode opcode) { | 337 ArchOpcode opcode) { |
338 IA32OperandGenerator g(selector); | 338 IA32OperandGenerator g(selector); |
339 InstructionOperand* temps[] = {g.TempRegister(eax), g.TempRegister(edx)}; | 339 InstructionOperand* temps[] = {g.TempRegister(eax), g.TempRegister(edx)}; |
340 size_t temp_count = ARRAY_SIZE(temps); | 340 size_t temp_count = arraysize(temps); |
341 selector->Emit(opcode, g.DefineAsFixed(node, edx), | 341 selector->Emit(opcode, g.DefineAsFixed(node, edx), |
342 g.UseFixed(node->InputAt(0), eax), | 342 g.UseFixed(node->InputAt(0), eax), |
343 g.UseUnique(node->InputAt(1)), temp_count, temps); | 343 g.UseUnique(node->InputAt(1)), temp_count, temps); |
344 } | 344 } |
345 | 345 |
346 | 346 |
347 void InstructionSelector::VisitInt32Mod(Node* node) { | 347 void InstructionSelector::VisitInt32Mod(Node* node) { |
348 VisitMod(this, node, kIA32Idiv); | 348 VisitMod(this, node, kIA32Idiv); |
349 } | 349 } |
350 | 350 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 if (descriptor->kind() == CallDescriptor::kCallAddress && | 560 if (descriptor->kind() == CallDescriptor::kCallAddress && |
561 buffer.pushed_nodes.size() > 0) { | 561 buffer.pushed_nodes.size() > 0) { |
562 DCHECK(deoptimization == NULL && continuation == NULL); | 562 DCHECK(deoptimization == NULL && continuation == NULL); |
563 Emit(kPopStack | MiscField::encode(buffer.pushed_nodes.size()), NULL); | 563 Emit(kPopStack | MiscField::encode(buffer.pushed_nodes.size()), NULL); |
564 } | 564 } |
565 } | 565 } |
566 | 566 |
567 } // namespace compiler | 567 } // namespace compiler |
568 } // namespace internal | 568 } // namespace internal |
569 } // namespace v8 | 569 } // namespace v8 |
OLD | NEW |