17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file.
47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/v8.h"
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "test/cctest/cctest.h"
77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/code-generator.h"
97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/common-operator.h"
107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/graph.h"
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/instruction.h"
12b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org#include "src/compiler/linkage.h"
137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/machine-operator.h"
147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node.h"
157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/operator.h"
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/schedule.h"
177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/scheduler.h"
187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/lithium.h"
197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgusing namespace v8::internal;
217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgusing namespace v8::internal::compiler;
227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtypedef v8::internal::compiler::Instruction TestInstr;
247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtypedef v8::internal::compiler::InstructionSequence TestInstrSeq;
257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A testing helper for the register code abstraction.
277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass InstructionTester : public HandleAndZoneScope {
287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:  // We're all friends here.
295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  InstructionTester()
307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      : isolate(main_isolate()),
317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        graph(zone()),
327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        schedule(zone()),
337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        info(static_cast<HydrogenCodeStub*>(NULL), main_isolate()),
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        linkage(&info),
357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        common(zone()),
367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        code(NULL) {}
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ~InstructionTester() { delete code; }
397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Isolate* isolate;
417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Graph graph;
427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Schedule schedule;
437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CompilationInfoWithZone info;
447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Linkage linkage;
457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CommonOperatorBuilder common;
467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  MachineOperatorBuilder machine;
477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  TestInstrSeq* code;
487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Zone* zone() { return main_zone(); }
507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void allocCode() {
527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (schedule.rpo_order()->size() == 0) {
537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // Compute the RPO order.
5431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org      Scheduler::ComputeSpecialRPO(&schedule);
55e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(schedule.rpo_order()->size() > 0);
567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    code = new TestInstrSeq(&linkage, &graph, &schedule);
587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* Int32Constant(int32_t val) {
617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* node = graph.NewNode(common.Int32Constant(val));
625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    schedule.AddNode(schedule.start(), node);
637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return node;
647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* Float64Constant(double val) {
677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* node = graph.NewNode(common.Float64Constant(val));
685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    schedule.AddNode(schedule.start(), node);
697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return node;
707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* Parameter(int32_t which) {
737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* node = graph.NewNode(common.Parameter(which));
745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    schedule.AddNode(schedule.start(), node);
757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return node;
767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* NewNode(BasicBlock* block) {
797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* node = graph.NewNode(common.Int32Constant(111));
807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    schedule.AddNode(block, node);
817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return node;
827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int NewInstr(BasicBlock* block) {
857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    InstructionCode opcode = static_cast<InstructionCode>(110);
867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    TestInstr* instr = TestInstr::New(zone(), opcode);
877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return code->AddInstruction(instr, block);
887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  UnallocatedOperand* NewUnallocated(int vreg) {
917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    UnallocatedOperand* unallocated =
927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        new (zone()) UnallocatedOperand(UnallocatedOperand::ANY);
937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    unallocated->set_virtual_register(vreg);
947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return unallocated;
957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(InstructionBasic) {
1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionTester R;
1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (int i = 0; i < 10; i++) {
1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    R.Int32Constant(i);  // Add some nodes to the graph.
1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  BasicBlock* last = R.schedule.start();
1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (int i = 0; i < 5; i++) {
1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    BasicBlock* block = R.schedule.NewBasicBlock();
1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    R.schedule.AddGoto(last, block);
1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    last = block;
1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.allocCode();
1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(R.graph.NodeCount(), R.code->ValueCount());
1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BasicBlockVector* blocks = R.schedule.rpo_order();
1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(static_cast<int>(blocks->size()), R.code->BasicBlockCount());
1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int index = 0;
1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end();
1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org       i++, index++) {
1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    BasicBlock* block = *i;
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_EQ(block, R.code->BlockAt(index));
1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_EQ(-1, R.code->GetLoopEnd(block));
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(InstructionGetBasicBlock) {
1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionTester R;
1327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  BasicBlock* b0 = R.schedule.start();
1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BasicBlock* b1 = R.schedule.NewBasicBlock();
1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BasicBlock* b2 = R.schedule.NewBasicBlock();
1365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  BasicBlock* b3 = R.schedule.end();
1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.schedule.AddGoto(b0, b1);
1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.schedule.AddGoto(b1, b2);
1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.schedule.AddGoto(b2, b3);
1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.allocCode();
1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->StartBlock(b0);
1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int i0 = R.NewInstr(b0);
1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int i1 = R.NewInstr(b0);
1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->EndBlock(b0);
1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->StartBlock(b1);
1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int i2 = R.NewInstr(b1);
1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int i3 = R.NewInstr(b1);
1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int i4 = R.NewInstr(b1);
1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int i5 = R.NewInstr(b1);
1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->EndBlock(b1);
1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->StartBlock(b2);
1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int i6 = R.NewInstr(b2);
1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int i7 = R.NewInstr(b2);
1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int i8 = R.NewInstr(b2);
1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->EndBlock(b2);
1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->StartBlock(b3);
1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->EndBlock(b3);
1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b0, R.code->GetBasicBlock(i0));
1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b0, R.code->GetBasicBlock(i1));
1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b1, R.code->GetBasicBlock(i2));
1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b1, R.code->GetBasicBlock(i3));
1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b1, R.code->GetBasicBlock(i4));
1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b1, R.code->GetBasicBlock(i5));
1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b2, R.code->GetBasicBlock(i6));
1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b2, R.code->GetBasicBlock(i7));
1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b2, R.code->GetBasicBlock(i8));
1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b0, R.code->GetBasicBlock(b0->first_instruction_index()));
1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b0, R.code->GetBasicBlock(b0->last_instruction_index()));
1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b1, R.code->GetBasicBlock(b1->first_instruction_index()));
1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b1, R.code->GetBasicBlock(b1->last_instruction_index()));
1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b2, R.code->GetBasicBlock(b2->first_instruction_index()));
1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b2, R.code->GetBasicBlock(b2->last_instruction_index()));
1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b3, R.code->GetBasicBlock(b3->first_instruction_index()));
1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(b3, R.code->GetBasicBlock(b3->last_instruction_index()));
1857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(InstructionIsGapAt) {
1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionTester R;
1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  BasicBlock* b0 = R.schedule.start();
1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.schedule.AddReturn(b0, R.Int32Constant(1));
1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.allocCode();
1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  TestInstr* i0 = TestInstr::New(R.zone(), 100);
1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
1977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->StartBlock(b0);
1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->AddInstruction(i0, b0);
1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->AddInstruction(g, b0);
2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->EndBlock(b0);
2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(0));   // Label
2057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(1));   // Gap
2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(false, R.code->IsGapAt(2));  // i0
2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(3));   // Gap
2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(4));   // Gap
2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(false, R.code->IsGapAt(5));  // g
2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(InstructionIsGapAt2) {
2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionTester R;
2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  BasicBlock* b0 = R.schedule.start();
2175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  BasicBlock* b1 = R.schedule.end();
2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.schedule.AddGoto(b0, b1);
2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.schedule.AddReturn(b1, R.Int32Constant(1));
2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.allocCode();
2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  TestInstr* i0 = TestInstr::New(R.zone(), 100);
2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->StartBlock(b0);
2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->AddInstruction(i0, b0);
2267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->AddInstruction(g, b0);
2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->EndBlock(b0);
2287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  TestInstr* i1 = TestInstr::New(R.zone(), 102);
2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  TestInstr* g1 = TestInstr::New(R.zone(), 104)->MarkAsControl();
2317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->StartBlock(b1);
2327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->AddInstruction(i1, b1);
2337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->AddInstruction(g1, b1);
2347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->EndBlock(b1);
2357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
2377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(0));   // Label
2397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(1));   // Gap
2407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(false, R.code->IsGapAt(2));  // i0
2417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(3));   // Gap
2427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(4));   // Gap
2437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(false, R.code->IsGapAt(5));  // g
2447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->InstructionAt(6)->IsBlockStart());
2467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(6));    // Label
2487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(7));    // Gap
2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(false, R.code->IsGapAt(8));   // i1
2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(9));    // Gap
2517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(10));   // Gap
2527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(false, R.code->IsGapAt(11));  // g1
2537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(InstructionAddGapMove) {
2577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionTester R;
2587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  BasicBlock* b0 = R.schedule.start();
2607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.schedule.AddReturn(b0, R.Int32Constant(1));
2617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.allocCode();
2637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  TestInstr* i0 = TestInstr::New(R.zone(), 100);
2647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
2657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->StartBlock(b0);
2667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->AddInstruction(i0, b0);
2677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->AddInstruction(g, b0);
2687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  R.code->EndBlock(b0);
2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
2717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(0));   // Label
2737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(1));   // Gap
2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(false, R.code->IsGapAt(2));  // i0
2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(3));   // Gap
2767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(true, R.code->IsGapAt(4));   // Gap
2777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CHECK_EQ(false, R.code->IsGapAt(5));  // g
2787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int indexes[] = {0, 1, 3, 4, -1};
2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (int i = 0; indexes[i] >= 0; i++) {
2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    int index = indexes[i];
2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    UnallocatedOperand* op1 = R.NewUnallocated(index + 6);
2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    UnallocatedOperand* op2 = R.NewUnallocated(index + 12);
2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    R.code->AddGapMove(index, op1, op2);
2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    GapInstruction* gap = R.code->GapAt(index);
2887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    ParallelMove* move = gap->GetParallelMove(GapInstruction::START);
2897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_NE(NULL, move);
2907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    const ZoneList<MoveOperands>* move_operands = move->move_operands();
2917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_EQ(1, move_operands->length());
2927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    MoveOperands* cur = &move_operands->at(0);
2937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_EQ(op1, cur->source());
2947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_EQ(op2, cur->destination());
2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgTEST(InstructionOperands) {
3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Zone zone(CcTest::InitIsolateOnce());
3017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  {
3037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    TestInstr* i = TestInstr::New(&zone, 101);
3047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_EQ(0, static_cast<int>(i->OutputCount()));
3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_EQ(0, static_cast<int>(i->InputCount()));
3067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_EQ(0, static_cast<int>(i->TempCount()));
3077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
3087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionOperand* outputs[] = {
3107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
3117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
3127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
3137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
3147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionOperand* inputs[] = {
3167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
3177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
3187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
3197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
3207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionOperand* temps[] = {
3227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
3237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
3247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
3257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
3267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
327fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  for (size_t i = 0; i < arraysize(outputs); i++) {
328fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    for (size_t j = 0; j < arraysize(inputs); j++) {
329fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      for (size_t k = 0; k < arraysize(temps); k++) {
3307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        TestInstr* m =
3317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org            TestInstr::New(&zone, 101, i, outputs, j, inputs, k, temps);
3327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        CHECK(i == m->OutputCount());
3337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        CHECK(j == m->InputCount());
3347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        CHECK(k == m->TempCount());
3357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        for (size_t z = 0; z < i; z++) {
3377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          CHECK_EQ(outputs[z], m->OutputAt(z));
3387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        }
3397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        for (size_t z = 0; z < j; z++) {
3417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          CHECK_EQ(inputs[z], m->InputAt(z));
3427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        }
3437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        for (size_t z = 0; z < k; z++) {
3457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          CHECK_EQ(temps[z], m->TempAt(z));
3467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        }
3477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
3497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
3507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
351