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

Side by Side Diff: src/compiler/mips64/instruction-selector-mips64.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/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 #include "src/compiler/node-properties.h" 8 #include "src/compiler/node-properties.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 namespace compiler { 12 namespace compiler {
13 13
14 #define TRACE_UNIMPL() \ 14 #define TRACE_UNIMPL() \
15 PrintF("UNIMPLEMENTED instr_sel: %s at line %d\n", __FUNCTION__, __LINE__) 15 PrintF("UNIMPLEMENTED instr_sel: %s at line %d\n", __FUNCTION__, __LINE__)
16 16
17 #define TRACE() PrintF("instr_sel: %s at line %d\n", __FUNCTION__, __LINE__) 17 #define TRACE() PrintF("instr_sel: %s at line %d\n", __FUNCTION__, __LINE__)
18 18
19 19
20 // Adds Mips-specific methods for generating InstructionOperands. 20 // Adds Mips-specific methods for generating InstructionOperands.
21 class Mips64OperandGenerator FINAL : public OperandGenerator { 21 class Mips64OperandGenerator FINAL : public OperandGenerator {
22 public: 22 public:
23 explicit Mips64OperandGenerator(InstructionSelector* selector) 23 explicit Mips64OperandGenerator(InstructionSelector* selector)
24 : OperandGenerator(selector) {} 24 : OperandGenerator(selector) {}
25 25
26 InstructionOperand* UseOperand(Node* node, InstructionCode opcode) { 26 InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
27 if (CanBeImmediate(node, opcode)) { 27 if (CanBeImmediate(node, opcode)) {
28 return UseImmediate(node); 28 return UseImmediate(node);
29 } 29 }
30 return UseRegister(node); 30 return UseRegister(node);
31 } 31 }
32 32
33 bool CanBeImmediate(Node* node, InstructionCode opcode) { 33 bool CanBeImmediate(Node* node, InstructionCode opcode) {
34 int64_t value; 34 int64_t value;
35 if (node->opcode() == IrOpcode::kInt32Constant) 35 if (node->opcode() == IrOpcode::kInt32Constant)
36 value = OpParameter<int32_t>(node); 36 value = OpParameter<int32_t>(node);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 selector->Emit(opcode, g.DefineAsRegister(node), 117 selector->Emit(opcode, g.DefineAsRegister(node),
118 g.UseRegister(node->InputAt(0)), 118 g.UseRegister(node->InputAt(0)),
119 g.UseOperand(node->InputAt(1), opcode)); 119 g.UseOperand(node->InputAt(1), opcode));
120 } 120 }
121 121
122 122
123 static void VisitBinop(InstructionSelector* selector, Node* node, 123 static void VisitBinop(InstructionSelector* selector, Node* node,
124 InstructionCode opcode, FlagsContinuation* cont) { 124 InstructionCode opcode, FlagsContinuation* cont) {
125 Mips64OperandGenerator g(selector); 125 Mips64OperandGenerator g(selector);
126 Int32BinopMatcher m(node); 126 Int32BinopMatcher m(node);
127 InstructionOperand* inputs[4]; 127 InstructionOperand inputs[4];
128 size_t input_count = 0; 128 size_t input_count = 0;
129 InstructionOperand* outputs[2]; 129 InstructionOperand outputs[2];
130 size_t output_count = 0; 130 size_t output_count = 0;
131 131
132 inputs[input_count++] = g.UseRegister(m.left().node()); 132 inputs[input_count++] = g.UseRegister(m.left().node());
133 inputs[input_count++] = g.UseOperand(m.right().node(), opcode); 133 inputs[input_count++] = g.UseOperand(m.right().node(), opcode);
134 134
135 if (cont->IsBranch()) { 135 if (cont->IsBranch()) {
136 inputs[input_count++] = g.Label(cont->true_block()); 136 inputs[input_count++] = g.Label(cont->true_block());
137 inputs[input_count++] = g.Label(cont->false_block()); 137 inputs[input_count++] = g.Label(cont->false_block());
138 } 138 }
139 139
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 break; 191 break;
192 default: 192 default:
193 UNREACHABLE(); 193 UNREACHABLE();
194 return; 194 return;
195 } 195 }
196 196
197 if (g.CanBeImmediate(index, opcode)) { 197 if (g.CanBeImmediate(index, opcode)) {
198 Emit(opcode | AddressingModeField::encode(kMode_MRI), 198 Emit(opcode | AddressingModeField::encode(kMode_MRI),
199 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); 199 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
200 } else { 200 } else {
201 InstructionOperand* addr_reg = g.TempRegister(); 201 InstructionOperand addr_reg = g.TempRegister();
202 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, 202 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
203 g.UseRegister(index), g.UseRegister(base)); 203 g.UseRegister(index), g.UseRegister(base));
204 // Emit desired load opcode, using temp addr_reg. 204 // Emit desired load opcode, using temp addr_reg.
205 Emit(opcode | AddressingModeField::encode(kMode_MRI), 205 Emit(opcode | AddressingModeField::encode(kMode_MRI),
206 g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); 206 g.DefineAsRegister(node), addr_reg, g.TempImmediate(0));
207 } 207 }
208 } 208 }
209 209
210 210
211 void InstructionSelector::VisitStore(Node* node) { 211 void InstructionSelector::VisitStore(Node* node) {
212 Mips64OperandGenerator g(this); 212 Mips64OperandGenerator g(this);
213 Node* base = node->InputAt(0); 213 Node* base = node->InputAt(0);
214 Node* index = node->InputAt(1); 214 Node* index = node->InputAt(1);
215 Node* value = node->InputAt(2); 215 Node* value = node->InputAt(2);
216 216
217 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); 217 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
218 MachineType rep = RepresentationOf(store_rep.machine_type()); 218 MachineType rep = RepresentationOf(store_rep.machine_type());
219 if (store_rep.write_barrier_kind() == kFullWriteBarrier) { 219 if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
220 DCHECK(rep == kRepTagged); 220 DCHECK(rep == kRepTagged);
221 // TODO(dcarney): refactor RecordWrite function to take temp registers 221 // TODO(dcarney): refactor RecordWrite function to take temp registers
222 // and pass them here instead of using fixed regs 222 // and pass them here instead of using fixed regs
223 // TODO(dcarney): handle immediate indices. 223 // TODO(dcarney): handle immediate indices.
224 InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)}; 224 InstructionOperand temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
225 Emit(kMips64StoreWriteBarrier, NULL, g.UseFixed(base, t0), 225 Emit(kMips64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, t0),
226 g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps); 226 g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps);
227 return; 227 return;
228 } 228 }
229 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); 229 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
230 230
231 ArchOpcode opcode; 231 ArchOpcode opcode;
232 switch (rep) { 232 switch (rep) {
233 case kRepFloat32: 233 case kRepFloat32:
234 opcode = kMips64Swc1; 234 opcode = kMips64Swc1;
235 break; 235 break;
(...skipping 13 matching lines...) Expand all
249 case kRepTagged: // Fall through. 249 case kRepTagged: // Fall through.
250 case kRepWord64: 250 case kRepWord64:
251 opcode = kMips64Sd; 251 opcode = kMips64Sd;
252 break; 252 break;
253 default: 253 default:
254 UNREACHABLE(); 254 UNREACHABLE();
255 return; 255 return;
256 } 256 }
257 257
258 if (g.CanBeImmediate(index, opcode)) { 258 if (g.CanBeImmediate(index, opcode)) {
259 Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, 259 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
260 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); 260 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
261 } else { 261 } else {
262 InstructionOperand* addr_reg = g.TempRegister(); 262 InstructionOperand addr_reg = g.TempRegister();
263 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, 263 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
264 g.UseRegister(index), g.UseRegister(base)); 264 g.UseRegister(index), g.UseRegister(base));
265 // Emit desired store opcode, using temp addr_reg. 265 // Emit desired store opcode, using temp addr_reg.
266 Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg, 266 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
267 g.TempImmediate(0), g.UseRegister(value)); 267 addr_reg, g.TempImmediate(0), g.UseRegister(value));
268 } 268 }
269 } 269 }
270 270
271 271
272 void InstructionSelector::VisitWord32And(Node* node) { 272 void InstructionSelector::VisitWord32And(Node* node) {
273 VisitBinop(this, node, kMips64And); 273 VisitBinop(this, node, kMips64And);
274 } 274 }
275 275
276 276
277 void InstructionSelector::VisitWord64And(Node* node) { 277 void InstructionSelector::VisitWord64And(Node* node) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 Int32BinopMatcher m(node); 368 Int32BinopMatcher m(node);
369 if (m.right().HasValue() && m.right().Value() > 0) { 369 if (m.right().HasValue() && m.right().Value() > 0) {
370 int32_t value = m.right().Value(); 370 int32_t value = m.right().Value();
371 if (base::bits::IsPowerOfTwo32(value)) { 371 if (base::bits::IsPowerOfTwo32(value)) {
372 Emit(kMips64Shl | AddressingModeField::encode(kMode_None), 372 Emit(kMips64Shl | AddressingModeField::encode(kMode_None),
373 g.DefineAsRegister(node), g.UseRegister(m.left().node()), 373 g.DefineAsRegister(node), g.UseRegister(m.left().node()),
374 g.TempImmediate(WhichPowerOf2(value))); 374 g.TempImmediate(WhichPowerOf2(value)));
375 return; 375 return;
376 } 376 }
377 if (base::bits::IsPowerOfTwo32(value - 1)) { 377 if (base::bits::IsPowerOfTwo32(value - 1)) {
378 InstructionOperand* temp = g.TempRegister(); 378 InstructionOperand temp = g.TempRegister();
379 Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp, 379 Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
380 g.UseRegister(m.left().node()), 380 g.UseRegister(m.left().node()),
381 g.TempImmediate(WhichPowerOf2(value - 1))); 381 g.TempImmediate(WhichPowerOf2(value - 1)));
382 Emit(kMips64Add | AddressingModeField::encode(kMode_None), 382 Emit(kMips64Add | AddressingModeField::encode(kMode_None),
383 g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp); 383 g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
384 return; 384 return;
385 } 385 }
386 if (base::bits::IsPowerOfTwo32(value + 1)) { 386 if (base::bits::IsPowerOfTwo32(value + 1)) {
387 InstructionOperand* temp = g.TempRegister(); 387 InstructionOperand temp = g.TempRegister();
388 Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp, 388 Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
389 g.UseRegister(m.left().node()), 389 g.UseRegister(m.left().node()),
390 g.TempImmediate(WhichPowerOf2(value + 1))); 390 g.TempImmediate(WhichPowerOf2(value + 1)));
391 Emit(kMips64Sub | AddressingModeField::encode(kMode_None), 391 Emit(kMips64Sub | AddressingModeField::encode(kMode_None),
392 g.DefineAsRegister(node), temp, g.UseRegister(m.left().node())); 392 g.DefineAsRegister(node), temp, g.UseRegister(m.left().node()));
393 return; 393 return;
394 } 394 }
395 } 395 }
396 Emit(kMips64Mul, g.DefineAsRegister(node), g.UseRegister(m.left().node()), 396 Emit(kMips64Mul, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
397 g.UseRegister(m.right().node())); 397 g.UseRegister(m.right().node()));
398 } 398 }
399 399
400 400
401 void InstructionSelector::VisitInt32MulHigh(Node* node) { 401 void InstructionSelector::VisitInt32MulHigh(Node* node) {
402 Mips64OperandGenerator g(this); 402 Mips64OperandGenerator g(this);
403 Emit(kMips64MulHigh, g.DefineAsRegister(node), 403 Emit(kMips64MulHigh, g.DefineAsRegister(node),
404 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); 404 g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
405 } 405 }
406 406
407 407
408 void InstructionSelector::VisitUint32MulHigh(Node* node) { 408 void InstructionSelector::VisitUint32MulHigh(Node* node) {
409 Mips64OperandGenerator g(this); 409 Mips64OperandGenerator g(this);
410 InstructionOperand* const dmul_operand = g.TempRegister(); 410 InstructionOperand const dmul_operand = g.TempRegister();
411 Emit(kMips64MulHighU, dmul_operand, g.UseRegister(node->InputAt(0)), 411 Emit(kMips64MulHighU, dmul_operand, g.UseRegister(node->InputAt(0)),
412 g.UseRegister(node->InputAt(1))); 412 g.UseRegister(node->InputAt(1)));
413 Emit(kMips64Ext, g.DefineAsRegister(node), dmul_operand, g.TempImmediate(0), 413 Emit(kMips64Ext, g.DefineAsRegister(node), dmul_operand, g.TempImmediate(0),
414 g.TempImmediate(32)); 414 g.TempImmediate(32));
415 } 415 }
416 416
417 417
418 void InstructionSelector::VisitInt64Mul(Node* node) { 418 void InstructionSelector::VisitInt64Mul(Node* node) {
419 Mips64OperandGenerator g(this); 419 Mips64OperandGenerator g(this);
420 Int64BinopMatcher m(node); 420 Int64BinopMatcher m(node);
421 // TODO(dusmil): Add optimization for shifts larger than 32. 421 // TODO(dusmil): Add optimization for shifts larger than 32.
422 if (m.right().HasValue() && m.right().Value() > 0) { 422 if (m.right().HasValue() && m.right().Value() > 0) {
423 int64_t value = m.right().Value(); 423 int64_t value = m.right().Value();
424 if (base::bits::IsPowerOfTwo32(value)) { 424 if (base::bits::IsPowerOfTwo32(value)) {
425 Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), 425 Emit(kMips64Dshl | AddressingModeField::encode(kMode_None),
426 g.DefineAsRegister(node), g.UseRegister(m.left().node()), 426 g.DefineAsRegister(node), g.UseRegister(m.left().node()),
427 g.TempImmediate(WhichPowerOf2(value))); 427 g.TempImmediate(WhichPowerOf2(value)));
428 return; 428 return;
429 } 429 }
430 if (base::bits::IsPowerOfTwo32(value - 1)) { 430 if (base::bits::IsPowerOfTwo32(value - 1)) {
431 InstructionOperand* temp = g.TempRegister(); 431 InstructionOperand temp = g.TempRegister();
432 Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp, 432 Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
433 g.UseRegister(m.left().node()), 433 g.UseRegister(m.left().node()),
434 g.TempImmediate(WhichPowerOf2(value - 1))); 434 g.TempImmediate(WhichPowerOf2(value - 1)));
435 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), 435 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None),
436 g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp); 436 g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
437 return; 437 return;
438 } 438 }
439 if (base::bits::IsPowerOfTwo32(value + 1)) { 439 if (base::bits::IsPowerOfTwo32(value + 1)) {
440 InstructionOperand* temp = g.TempRegister(); 440 InstructionOperand temp = g.TempRegister();
441 Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp, 441 Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
442 g.UseRegister(m.left().node()), 442 g.UseRegister(m.left().node()),
443 g.TempImmediate(WhichPowerOf2(value + 1))); 443 g.TempImmediate(WhichPowerOf2(value + 1)));
444 Emit(kMips64Dsub | AddressingModeField::encode(kMode_None), 444 Emit(kMips64Dsub | AddressingModeField::encode(kMode_None),
445 g.DefineAsRegister(node), temp, g.UseRegister(m.left().node())); 445 g.DefineAsRegister(node), temp, g.UseRegister(m.left().node()));
446 return; 446 return;
447 } 447 }
448 } 448 }
449 Emit(kMips64Dmul, g.DefineAsRegister(node), g.UseRegister(m.left().node()), 449 Emit(kMips64Dmul, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
450 g.UseRegister(m.right().node())); 450 g.UseRegister(m.right().node()));
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); 639 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
640 } 640 }
641 641
642 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); 642 CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
643 643
644 // Compute InstructionOperands for inputs and outputs. 644 // Compute InstructionOperands for inputs and outputs.
645 InitializeCallBuffer(node, &buffer, true, false); 645 InitializeCallBuffer(node, &buffer, true, false);
646 646
647 int push_count = buffer.pushed_nodes.size(); 647 int push_count = buffer.pushed_nodes.size();
648 if (push_count > 0) { 648 if (push_count > 0) {
649 Emit(kMips64StackClaim | MiscField::encode(push_count), NULL); 649 Emit(kMips64StackClaim | MiscField::encode(push_count), g.NoOutput());
650 } 650 }
651 int slot = buffer.pushed_nodes.size() - 1; 651 int slot = buffer.pushed_nodes.size() - 1;
652 for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); 652 for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
653 ++i) { 653 ++i) {
654 Emit(kMips64StoreToStackSlot | MiscField::encode(slot), nullptr, 654 Emit(kMips64StoreToStackSlot | MiscField::encode(slot), g.NoOutput(),
655 g.UseRegister(*i)); 655 g.UseRegister(*i));
656 slot--; 656 slot--;
657 } 657 }
658 658
659 // Select the appropriate opcode based on the call type. 659 // Select the appropriate opcode based on the call type.
660 InstructionCode opcode; 660 InstructionCode opcode;
661 switch (descriptor->kind()) { 661 switch (descriptor->kind()) {
662 case CallDescriptor::kCallCodeObject: { 662 case CallDescriptor::kCallCodeObject: {
663 opcode = kArchCallCodeObject; 663 opcode = kArchCallCodeObject;
664 break; 664 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 case kRepFloat32: 702 case kRepFloat32:
703 opcode = kCheckedLoadFloat32; 703 opcode = kCheckedLoadFloat32;
704 break; 704 break;
705 case kRepFloat64: 705 case kRepFloat64:
706 opcode = kCheckedLoadFloat64; 706 opcode = kCheckedLoadFloat64;
707 break; 707 break;
708 default: 708 default:
709 UNREACHABLE(); 709 UNREACHABLE();
710 return; 710 return;
711 } 711 }
712 InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) 712 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
713 ? g.UseImmediate(offset) 713 ? g.UseImmediate(offset)
714 : g.UseRegister(offset); 714 : g.UseRegister(offset);
715 715
716 InstructionOperand* length_operand = 716 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
717 (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) 717 ? g.CanBeImmediate(length, opcode)
718 ? g.UseImmediate(length) 718 ? g.UseImmediate(length)
719 : g.UseRegister(length) 719 : g.UseRegister(length)
720 : g.UseRegister(length); 720 : g.UseRegister(length);
721 721
722 Emit(opcode | AddressingModeField::encode(kMode_MRI), 722 Emit(opcode | AddressingModeField::encode(kMode_MRI),
723 g.DefineAsRegister(node), offset_operand, length_operand, 723 g.DefineAsRegister(node), offset_operand, length_operand,
724 g.UseRegister(buffer)); 724 g.UseRegister(buffer));
725 } 725 }
726 726
727 727
728 void InstructionSelector::VisitCheckedStore(Node* node) { 728 void InstructionSelector::VisitCheckedStore(Node* node) {
729 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); 729 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
730 Mips64OperandGenerator g(this); 730 Mips64OperandGenerator g(this);
(...skipping 15 matching lines...) Expand all
746 case kRepFloat32: 746 case kRepFloat32:
747 opcode = kCheckedStoreFloat32; 747 opcode = kCheckedStoreFloat32;
748 break; 748 break;
749 case kRepFloat64: 749 case kRepFloat64:
750 opcode = kCheckedStoreFloat64; 750 opcode = kCheckedStoreFloat64;
751 break; 751 break;
752 default: 752 default:
753 UNREACHABLE(); 753 UNREACHABLE();
754 return; 754 return;
755 } 755 }
756 InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) 756 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
757 ? g.UseImmediate(offset) 757 ? g.UseImmediate(offset)
758 : g.UseRegister(offset); 758 : g.UseRegister(offset);
759 759
760 InstructionOperand* length_operand = 760 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
761 (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) 761 ? g.CanBeImmediate(length, opcode)
762 ? g.UseImmediate(length) 762 ? g.UseImmediate(length)
763 : g.UseRegister(length) 763 : g.UseRegister(length)
764 : g.UseRegister(length); 764 : g.UseRegister(length);
765 765
766 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand, 766 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
767 length_operand, g.UseRegister(value), g.UseRegister(buffer)); 767 offset_operand, length_operand, g.UseRegister(value),
768 g.UseRegister(buffer));
768 } 769 }
769 770
770 771
771 namespace { 772 namespace {
772 773
773 // Shared routine for multiple compare operations. 774 // Shared routine for multiple compare operations.
774 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 775 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
775 InstructionOperand* left, InstructionOperand* right, 776 InstructionOperand left, InstructionOperand right,
776 FlagsContinuation* cont) { 777 FlagsContinuation* cont) {
777 Mips64OperandGenerator g(selector); 778 Mips64OperandGenerator g(selector);
778 opcode = cont->Encode(opcode); 779 opcode = cont->Encode(opcode);
779 if (cont->IsBranch()) { 780 if (cont->IsBranch()) {
780 selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), 781 selector->Emit(opcode, g.NoOutput(), left, right,
782 g.Label(cont->true_block()),
781 g.Label(cont->false_block()))->MarkAsControl(); 783 g.Label(cont->false_block()))->MarkAsControl();
782 } else { 784 } else {
783 DCHECK(cont->IsSet()); 785 DCHECK(cont->IsSet());
784 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); 786 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
785 } 787 }
786 } 788 }
787 789
788 790
789 // Shared routine for multiple float compare operations. 791 // Shared routine for multiple float compare operations.
790 void VisitFloat64Compare(InstructionSelector* selector, Node* node, 792 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 VisitWordCompare(selector, node, kMips64Cmp, cont, false); 833 VisitWordCompare(selector, node, kMips64Cmp, cont, false);
832 } 834 }
833 835
834 } // namespace 836 } // namespace
835 837
836 838
837 void EmitWordCompareZero(InstructionSelector* selector, InstructionCode opcode, 839 void EmitWordCompareZero(InstructionSelector* selector, InstructionCode opcode,
838 Node* value, FlagsContinuation* cont) { 840 Node* value, FlagsContinuation* cont) {
839 Mips64OperandGenerator g(selector); 841 Mips64OperandGenerator g(selector);
840 opcode = cont->Encode(opcode); 842 opcode = cont->Encode(opcode);
841 InstructionOperand* const value_operand = g.UseRegister(value); 843 InstructionOperand const value_operand = g.UseRegister(value);
842 if (cont->IsBranch()) { 844 if (cont->IsBranch()) {
843 selector->Emit(opcode, nullptr, value_operand, g.TempImmediate(0), 845 selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0),
844 g.Label(cont->true_block()), 846 g.Label(cont->true_block()),
845 g.Label(cont->false_block()))->MarkAsControl(); 847 g.Label(cont->false_block()))->MarkAsControl();
846 } else { 848 } else {
847 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, 849 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
848 g.TempImmediate(0)); 850 g.TempImmediate(0));
849 } 851 }
850 } 852 }
851 853
852 854
853 // Shared routine for word comparisons against zero. 855 // Shared routine for word comparisons against zero.
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 MachineOperatorBuilder::Flags 1073 MachineOperatorBuilder::Flags
1072 InstructionSelector::SupportedMachineOperatorFlags() { 1074 InstructionSelector::SupportedMachineOperatorFlags() {
1073 return MachineOperatorBuilder::kFloat64Floor | 1075 return MachineOperatorBuilder::kFloat64Floor |
1074 MachineOperatorBuilder::kFloat64Ceil | 1076 MachineOperatorBuilder::kFloat64Ceil |
1075 MachineOperatorBuilder::kFloat64RoundTruncate; 1077 MachineOperatorBuilder::kFloat64RoundTruncate;
1076 } 1078 }
1077 1079
1078 } // namespace compiler 1080 } // namespace compiler
1079 } // namespace internal 1081 } // namespace internal
1080 } // namespace v8 1082 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/mips/instruction-selector-mips.cc ('k') | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698