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

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

Issue 889843003: [turbofan] Don't allocate UnallocatedOperands in Zone memory during instruction selection (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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/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.h" 7 #include "src/compiler/node-properties.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 13 matching lines...) Expand all
24 const int64_t value = OpParameter<int64_t>(node); 24 const int64_t value = OpParameter<int64_t>(node);
25 return value == static_cast<int64_t>(static_cast<int32_t>(value)); 25 return value == static_cast<int64_t>(static_cast<int32_t>(value));
26 } 26 }
27 default: 27 default:
28 return false; 28 return false;
29 } 29 }
30 } 30 }
31 31
32 AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent, 32 AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent,
33 Node* base, Node* displacement, 33 Node* base, Node* displacement,
34 InstructionOperand* inputs[], 34 InstructionOperand inputs[],
35 size_t* input_count) { 35 size_t* input_count) {
36 AddressingMode mode = kMode_MRI; 36 AddressingMode mode = kMode_MRI;
37 if (base != NULL) { 37 if (base != NULL) {
38 inputs[(*input_count)++] = UseRegister(base); 38 inputs[(*input_count)++] = UseRegister(base);
39 if (index != NULL) { 39 if (index != NULL) {
40 DCHECK(scale_exponent >= 0 && scale_exponent <= 3); 40 DCHECK(scale_exponent >= 0 && scale_exponent <= 3);
41 inputs[(*input_count)++] = UseRegister(index); 41 inputs[(*input_count)++] = UseRegister(index);
42 if (displacement != NULL) { 42 if (displacement != NULL) {
43 inputs[(*input_count)++] = UseImmediate(displacement); 43 inputs[(*input_count)++] = UseImmediate(displacement);
44 static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I, 44 static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I,
(...skipping 28 matching lines...) Expand all
73 if (mode == kMode_MR1) { 73 if (mode == kMode_MR1) {
74 // [%r1 + %r1*1] has a smaller encoding than [%r1*2+0] 74 // [%r1 + %r1*1] has a smaller encoding than [%r1*2+0]
75 inputs[(*input_count)++] = UseRegister(index); 75 inputs[(*input_count)++] = UseRegister(index);
76 } 76 }
77 } 77 }
78 } 78 }
79 return mode; 79 return mode;
80 } 80 }
81 81
82 AddressingMode GetEffectiveAddressMemoryOperand(Node* operand, 82 AddressingMode GetEffectiveAddressMemoryOperand(Node* operand,
83 InstructionOperand* inputs[], 83 InstructionOperand inputs[],
84 size_t* input_count) { 84 size_t* input_count) {
85 BaseWithIndexAndDisplacement64Matcher m(operand, true); 85 BaseWithIndexAndDisplacement64Matcher m(operand, true);
86 DCHECK(m.matches()); 86 DCHECK(m.matches());
87 if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) { 87 if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) {
88 return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(), 88 return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(),
89 m.displacement(), inputs, input_count); 89 m.displacement(), inputs, input_count);
90 } else { 90 } else {
91 inputs[(*input_count)++] = UseRegister(operand->InputAt(0)); 91 inputs[(*input_count)++] = UseRegister(operand->InputAt(0));
92 inputs[(*input_count)++] = UseRegister(operand->InputAt(1)); 92 inputs[(*input_count)++] = UseRegister(operand->InputAt(1));
93 return kMode_MR1; 93 return kMode_MR1;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 break; 125 break;
126 case kRepTagged: // Fall through. 126 case kRepTagged: // Fall through.
127 case kRepWord64: 127 case kRepWord64:
128 opcode = kX64Movq; 128 opcode = kX64Movq;
129 break; 129 break;
130 default: 130 default:
131 UNREACHABLE(); 131 UNREACHABLE();
132 return; 132 return;
133 } 133 }
134 134
135 InstructionOperand* outputs[1]; 135 InstructionOperand outputs[1];
136 outputs[0] = g.DefineAsRegister(node); 136 outputs[0] = g.DefineAsRegister(node);
137 InstructionOperand* inputs[3]; 137 InstructionOperand inputs[3];
138 size_t input_count = 0; 138 size_t input_count = 0;
139 AddressingMode mode = 139 AddressingMode mode =
140 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); 140 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
141 InstructionCode code = opcode | AddressingModeField::encode(mode); 141 InstructionCode code = opcode | AddressingModeField::encode(mode);
142 Emit(code, 1, outputs, input_count, inputs); 142 Emit(code, 1, outputs, input_count, inputs);
143 } 143 }
144 144
145 145
146 void InstructionSelector::VisitStore(Node* node) { 146 void InstructionSelector::VisitStore(Node* node) {
147 X64OperandGenerator g(this); 147 X64OperandGenerator g(this);
148 Node* base = node->InputAt(0); 148 Node* base = node->InputAt(0);
149 Node* index = node->InputAt(1); 149 Node* index = node->InputAt(1);
150 Node* value = node->InputAt(2); 150 Node* value = node->InputAt(2);
151 151
152 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); 152 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
153 MachineType rep = RepresentationOf(store_rep.machine_type()); 153 MachineType rep = RepresentationOf(store_rep.machine_type());
154 if (store_rep.write_barrier_kind() == kFullWriteBarrier) { 154 if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
155 DCHECK(rep == kRepTagged); 155 DCHECK(rep == kRepTagged);
156 // TODO(dcarney): refactor RecordWrite function to take temp registers 156 // TODO(dcarney): refactor RecordWrite function to take temp registers
157 // and pass them here instead of using fixed regs 157 // and pass them here instead of using fixed regs
158 // TODO(dcarney): handle immediate indices. 158 // TODO(dcarney): handle immediate indices.
159 InstructionOperand* temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)}; 159 InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)};
160 Emit(kX64StoreWriteBarrier, NULL, g.UseFixed(base, rbx), 160 Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx),
161 g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps), 161 g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps),
162 temps); 162 temps);
163 return; 163 return;
164 } 164 }
165 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); 165 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
166 ArchOpcode opcode; 166 ArchOpcode opcode;
167 switch (rep) { 167 switch (rep) {
168 case kRepFloat32: 168 case kRepFloat32:
169 opcode = kX64Movss; 169 opcode = kX64Movss;
170 break; 170 break;
(...skipping 11 matching lines...) Expand all
182 opcode = kX64Movl; 182 opcode = kX64Movl;
183 break; 183 break;
184 case kRepTagged: // Fall through. 184 case kRepTagged: // Fall through.
185 case kRepWord64: 185 case kRepWord64:
186 opcode = kX64Movq; 186 opcode = kX64Movq;
187 break; 187 break;
188 default: 188 default:
189 UNREACHABLE(); 189 UNREACHABLE();
190 return; 190 return;
191 } 191 }
192 InstructionOperand* inputs[4]; 192 InstructionOperand inputs[4];
193 size_t input_count = 0; 193 size_t input_count = 0;
194 AddressingMode mode = 194 AddressingMode mode =
195 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); 195 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
196 InstructionCode code = opcode | AddressingModeField::encode(mode); 196 InstructionCode code = opcode | AddressingModeField::encode(mode);
197 InstructionOperand* value_operand = 197 InstructionOperand value_operand =
198 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); 198 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
199 inputs[input_count++] = value_operand; 199 inputs[input_count++] = value_operand;
200 Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs); 200 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs);
201 } 201 }
202 202
203 203
204 void InstructionSelector::VisitCheckedLoad(Node* node) { 204 void InstructionSelector::VisitCheckedLoad(Node* node) {
205 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); 205 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
206 MachineType typ = TypeOf(OpParameter<MachineType>(node)); 206 MachineType typ = TypeOf(OpParameter<MachineType>(node));
207 X64OperandGenerator g(this); 207 X64OperandGenerator g(this);
208 Node* const buffer = node->InputAt(0); 208 Node* const buffer = node->InputAt(0);
209 Node* const offset = node->InputAt(1); 209 Node* const offset = node->InputAt(1);
210 Node* const length = node->InputAt(2); 210 Node* const length = node->InputAt(2);
(...skipping 23 matching lines...) Expand all
234 Int32BinopMatcher moffset(offset); 234 Int32BinopMatcher moffset(offset);
235 if (mlength.HasValue() && moffset.right().HasValue() && 235 if (mlength.HasValue() && moffset.right().HasValue() &&
236 moffset.right().Value() >= 0 && 236 moffset.right().Value() >= 0 &&
237 mlength.Value() >= moffset.right().Value()) { 237 mlength.Value() >= moffset.right().Value()) {
238 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), 238 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
239 g.UseRegister(moffset.left().node()), 239 g.UseRegister(moffset.left().node()),
240 g.UseImmediate(moffset.right().node()), g.UseImmediate(length)); 240 g.UseImmediate(moffset.right().node()), g.UseImmediate(length));
241 return; 241 return;
242 } 242 }
243 } 243 }
244 InstructionOperand* length_operand = 244 InstructionOperand length_operand =
245 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); 245 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
246 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), 246 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
247 g.UseRegister(offset), g.TempImmediate(0), length_operand); 247 g.UseRegister(offset), g.TempImmediate(0), length_operand);
248 } 248 }
249 249
250 250
251 void InstructionSelector::VisitCheckedStore(Node* node) { 251 void InstructionSelector::VisitCheckedStore(Node* node) {
252 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); 252 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
253 X64OperandGenerator g(this); 253 X64OperandGenerator g(this);
254 Node* const buffer = node->InputAt(0); 254 Node* const buffer = node->InputAt(0);
(...skipping 14 matching lines...) Expand all
269 case kRepFloat32: 269 case kRepFloat32:
270 opcode = kCheckedStoreFloat32; 270 opcode = kCheckedStoreFloat32;
271 break; 271 break;
272 case kRepFloat64: 272 case kRepFloat64:
273 opcode = kCheckedStoreFloat64; 273 opcode = kCheckedStoreFloat64;
274 break; 274 break;
275 default: 275 default:
276 UNREACHABLE(); 276 UNREACHABLE();
277 return; 277 return;
278 } 278 }
279 InstructionOperand* value_operand = 279 InstructionOperand value_operand =
280 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); 280 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
281 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { 281 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
282 Int32Matcher mlength(length); 282 Int32Matcher mlength(length);
283 Int32BinopMatcher moffset(offset); 283 Int32BinopMatcher moffset(offset);
284 if (mlength.HasValue() && moffset.right().HasValue() && 284 if (mlength.HasValue() && moffset.right().HasValue() &&
285 moffset.right().Value() >= 0 && 285 moffset.right().Value() >= 0 &&
286 mlength.Value() >= moffset.right().Value()) { 286 mlength.Value() >= moffset.right().Value()) {
287 Emit(opcode, nullptr, g.UseRegister(buffer), 287 Emit(opcode, g.NoOutput(), g.UseRegister(buffer),
288 g.UseRegister(moffset.left().node()), 288 g.UseRegister(moffset.left().node()),
289 g.UseImmediate(moffset.right().node()), g.UseImmediate(length), 289 g.UseImmediate(moffset.right().node()), g.UseImmediate(length),
290 value_operand); 290 value_operand);
291 return; 291 return;
292 } 292 }
293 } 293 }
294 InstructionOperand* length_operand = 294 InstructionOperand length_operand =
295 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); 295 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
296 Emit(opcode, nullptr, g.UseRegister(buffer), g.UseRegister(offset), 296 Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset),
297 g.TempImmediate(0), length_operand, value_operand); 297 g.TempImmediate(0), length_operand, value_operand);
298 } 298 }
299 299
300 300
301 // Shared routine for multiple binary operations. 301 // Shared routine for multiple binary operations.
302 static void VisitBinop(InstructionSelector* selector, Node* node, 302 static void VisitBinop(InstructionSelector* selector, Node* node,
303 InstructionCode opcode, FlagsContinuation* cont) { 303 InstructionCode opcode, FlagsContinuation* cont) {
304 X64OperandGenerator g(selector); 304 X64OperandGenerator g(selector);
305 Int32BinopMatcher m(node); 305 Int32BinopMatcher m(node);
306 Node* left = m.left().node(); 306 Node* left = m.left().node();
307 Node* right = m.right().node(); 307 Node* right = m.right().node();
308 InstructionOperand* inputs[4]; 308 InstructionOperand inputs[4];
309 size_t input_count = 0; 309 size_t input_count = 0;
310 InstructionOperand* outputs[2]; 310 InstructionOperand outputs[2];
311 size_t output_count = 0; 311 size_t output_count = 0;
312 312
313 // TODO(turbofan): match complex addressing modes. 313 // TODO(turbofan): match complex addressing modes.
314 if (left == right) { 314 if (left == right) {
315 // If both inputs refer to the same operand, enforce allocating a register 315 // If both inputs refer to the same operand, enforce allocating a register
316 // for both of them to ensure that we don't end up generating code like 316 // for both of them to ensure that we don't end up generating code like
317 // this: 317 // this:
318 // 318 //
319 // mov rax, [rbp-0x10] 319 // mov rax, [rbp-0x10]
320 // add rax, [rbp-0x10] 320 // add rax, [rbp-0x10]
321 // jo label 321 // jo label
322 InstructionOperand* const input = g.UseRegister(left); 322 InstructionOperand const input = g.UseRegister(left);
323 inputs[input_count++] = input; 323 inputs[input_count++] = input;
324 inputs[input_count++] = input; 324 inputs[input_count++] = input;
325 } else if (g.CanBeImmediate(right)) { 325 } else if (g.CanBeImmediate(right)) {
326 inputs[input_count++] = g.UseRegister(left); 326 inputs[input_count++] = g.UseRegister(left);
327 inputs[input_count++] = g.UseImmediate(right); 327 inputs[input_count++] = g.UseImmediate(right);
328 } else { 328 } else {
329 if (node->op()->HasProperty(Operator::kCommutative) && 329 if (node->op()->HasProperty(Operator::kCommutative) &&
330 g.CanBeBetterLeftOperand(right)) { 330 g.CanBeBetterLeftOperand(right)) {
331 std::swap(left, right); 331 std::swap(left, right);
332 } 332 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 g.UseFixed(right, rcx)); 449 g.UseFixed(right, rcx));
450 } 450 }
451 } 451 }
452 452
453 453
454 void EmitLea(InstructionSelector* selector, InstructionCode opcode, 454 void EmitLea(InstructionSelector* selector, InstructionCode opcode,
455 Node* result, Node* index, int scale, Node* base, 455 Node* result, Node* index, int scale, Node* base,
456 Node* displacement) { 456 Node* displacement) {
457 X64OperandGenerator g(selector); 457 X64OperandGenerator g(selector);
458 458
459 InstructionOperand* inputs[4]; 459 InstructionOperand inputs[4];
460 size_t input_count = 0; 460 size_t input_count = 0;
461 AddressingMode mode = g.GenerateMemoryOperandInputs( 461 AddressingMode mode = g.GenerateMemoryOperandInputs(
462 index, scale, base, displacement, inputs, &input_count); 462 index, scale, base, displacement, inputs, &input_count);
463 463
464 DCHECK_NE(0, static_cast<int>(input_count)); 464 DCHECK_NE(0, static_cast<int>(input_count));
465 DCHECK_GE(arraysize(inputs), input_count); 465 DCHECK_GE(arraysize(inputs), input_count);
466 466
467 InstructionOperand* outputs[1]; 467 InstructionOperand outputs[1];
468 outputs[0] = g.DefineAsRegister(result); 468 outputs[0] = g.DefineAsRegister(result);
469 469
470 opcode = AddressingModeField::encode(mode) | opcode; 470 opcode = AddressingModeField::encode(mode) | opcode;
471 471
472 selector->Emit(opcode, 1, outputs, input_count, inputs); 472 selector->Emit(opcode, 1, outputs, input_count, inputs);
473 } 473 }
474 474
475 } // namespace 475 } // namespace
476 476
477 477
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 } 627 }
628 // TODO(turbofan): We use UseUniqueRegister here to improve register 628 // TODO(turbofan): We use UseUniqueRegister here to improve register
629 // allocation. 629 // allocation.
630 selector->Emit(opcode, g.DefineAsFixed(node, rdx), g.UseFixed(left, rax), 630 selector->Emit(opcode, g.DefineAsFixed(node, rdx), g.UseFixed(left, rax),
631 g.UseUniqueRegister(right)); 631 g.UseUniqueRegister(right));
632 } 632 }
633 633
634 634
635 void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) { 635 void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
636 X64OperandGenerator g(selector); 636 X64OperandGenerator g(selector);
637 InstructionOperand* temps[] = {g.TempRegister(rdx)}; 637 InstructionOperand temps[] = {g.TempRegister(rdx)};
638 selector->Emit( 638 selector->Emit(
639 opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax), 639 opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax),
640 g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); 640 g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
641 } 641 }
642 642
643 643
644 void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { 644 void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
645 X64OperandGenerator g(selector); 645 X64OperandGenerator g(selector);
646 selector->Emit(opcode, g.DefineAsFixed(node, rdx), 646 selector->Emit(opcode, g.DefineAsFixed(node, rdx),
647 g.UseFixed(node->InputAt(0), rax), 647 g.UseFixed(node->InputAt(0), rax),
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); 863 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
864 } else { 864 } else {
865 Emit(kSSEFloat64Div, g.DefineSameAsFirst(node), 865 Emit(kSSEFloat64Div, g.DefineSameAsFirst(node),
866 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); 866 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
867 } 867 }
868 } 868 }
869 869
870 870
871 void InstructionSelector::VisitFloat64Mod(Node* node) { 871 void InstructionSelector::VisitFloat64Mod(Node* node) {
872 X64OperandGenerator g(this); 872 X64OperandGenerator g(this);
873 InstructionOperand* temps[] = {g.TempRegister(rax)}; 873 InstructionOperand temps[] = {g.TempRegister(rax)};
874 Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), 874 Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node),
875 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, 875 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1,
876 temps); 876 temps);
877 } 877 }
878 878
879 879
880 void InstructionSelector::VisitFloat64Sqrt(Node* node) { 880 void InstructionSelector::VisitFloat64Sqrt(Node* node) {
881 X64OperandGenerator g(this); 881 X64OperandGenerator g(this);
882 Emit(kSSEFloat64Sqrt, g.DefineAsRegister(node), g.Use(node->InputAt(0))); 882 Emit(kSSEFloat64Sqrt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
883 } 883 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 930
931 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); 931 CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
932 932
933 // Compute InstructionOperands for inputs and outputs. 933 // Compute InstructionOperands for inputs and outputs.
934 InitializeCallBuffer(node, &buffer, true, true); 934 InitializeCallBuffer(node, &buffer, true, true);
935 935
936 // Push any stack arguments. 936 // Push any stack arguments.
937 for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); 937 for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
938 ++i) { 938 ++i) {
939 // TODO(titzer): handle pushing double parameters. 939 // TODO(titzer): handle pushing double parameters.
940 InstructionOperand* value = 940 InstructionOperand value =
941 g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM) 941 g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM)
942 ? g.UseRegister(*i) 942 ? g.UseRegister(*i)
943 : g.Use(*i); 943 : g.Use(*i);
944 Emit(kX64Push, nullptr, value); 944 Emit(kX64Push, g.NoOutput(), value);
945 } 945 }
946 946
947 // Select the appropriate opcode based on the call type. 947 // Select the appropriate opcode based on the call type.
948 InstructionCode opcode; 948 InstructionCode opcode;
949 switch (descriptor->kind()) { 949 switch (descriptor->kind()) {
950 case CallDescriptor::kCallCodeObject: { 950 case CallDescriptor::kCallCodeObject: {
951 opcode = kArchCallCodeObject; 951 opcode = kArchCallCodeObject;
952 break; 952 break;
953 } 953 }
954 case CallDescriptor::kCallJSFunction: 954 case CallDescriptor::kCallJSFunction:
955 opcode = kArchCallJSFunction; 955 opcode = kArchCallJSFunction;
956 break; 956 break;
957 default: 957 default:
958 UNREACHABLE(); 958 UNREACHABLE();
959 return; 959 return;
960 } 960 }
961 opcode |= MiscField::encode(descriptor->flags()); 961 opcode |= MiscField::encode(descriptor->flags());
962 962
963 // Emit the call instruction. 963 // Emit the call instruction.
964 InstructionOperand** first_output = 964 InstructionOperand* first_output =
965 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; 965 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
966 Instruction* call_instr = 966 Instruction* call_instr =
967 Emit(opcode, buffer.outputs.size(), first_output, 967 Emit(opcode, buffer.outputs.size(), first_output,
968 buffer.instruction_args.size(), &buffer.instruction_args.front()); 968 buffer.instruction_args.size(), &buffer.instruction_args.front());
969 call_instr->MarkAsCall(); 969 call_instr->MarkAsCall();
970 } 970 }
971 971
972 972
973 // Shared routine for multiple compare operations. 973 // Shared routine for multiple compare operations.
974 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 974 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
975 InstructionOperand* left, InstructionOperand* right, 975 InstructionOperand left, InstructionOperand right,
976 FlagsContinuation* cont) { 976 FlagsContinuation* cont) {
977 X64OperandGenerator g(selector); 977 X64OperandGenerator g(selector);
978 opcode = cont->Encode(opcode); 978 opcode = cont->Encode(opcode);
979 if (cont->IsBranch()) { 979 if (cont->IsBranch()) {
980 selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), 980 selector->Emit(opcode, g.NoOutput(), left, right,
981 g.Label(cont->true_block()),
981 g.Label(cont->false_block()))->MarkAsControl(); 982 g.Label(cont->false_block()))->MarkAsControl();
982 } else { 983 } else {
983 DCHECK(cont->IsSet()); 984 DCHECK(cont->IsSet());
984 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); 985 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
985 } 986 }
986 } 987 }
987 988
988 989
989 // Shared routine for multiple compare operations. 990 // Shared routine for multiple compare operations.
990 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 991 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 MachineOperatorBuilder::kFloat64Ceil | 1311 MachineOperatorBuilder::kFloat64Ceil |
1311 MachineOperatorBuilder::kFloat64RoundTruncate | 1312 MachineOperatorBuilder::kFloat64RoundTruncate |
1312 MachineOperatorBuilder::kWord32ShiftIsSafe; 1313 MachineOperatorBuilder::kWord32ShiftIsSafe;
1313 } 1314 }
1314 return MachineOperatorBuilder::kNoFlags; 1315 return MachineOperatorBuilder::kNoFlags;
1315 } 1316 }
1316 1317
1317 } // namespace compiler 1318 } // namespace compiler
1318 } // namespace internal 1319 } // namespace internal
1319 } // namespace v8 1320 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/mips64/instruction-selector-mips64.cc ('k') | test/cctest/compiler/test-instruction.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698