[turbofan] Refactor code generation for calls.
authorbmeurer@chromium.org <bmeurer@chromium.org>
Wed, 27 Aug 2014 06:25:02 +0000 (06:25 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org>
Wed, 27 Aug 2014 06:25:02 +0000 (06:25 +0000)
R=jarin@chromium.org
TEST=cctest

Review URL: https://codereview.chromium.org/508863002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23429 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

13 files changed:
src/compiler/arm/code-generator-arm.cc
src/compiler/arm/instruction-codes-arm.h
src/compiler/arm/instruction-selector-arm.cc
src/compiler/arm64/code-generator-arm64.cc
src/compiler/arm64/instruction-codes-arm64.h
src/compiler/arm64/instruction-selector-arm64.cc
src/compiler/ia32/code-generator-ia32.cc
src/compiler/ia32/instruction-codes-ia32.h
src/compiler/ia32/instruction-selector-ia32.cc
src/compiler/instruction-codes.h
src/compiler/x64/code-generator-x64.cc
src/compiler/x64/instruction-codes-x64.h
src/compiler/x64/instruction-selector-x64.cc

index 169d7005b21ce57e03a3f1413282b432f9cb236e..4ae67e3ff0ab45b28ee8469d639e81e08fec92f1 100644 (file)
@@ -136,28 +136,63 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   ArmOperandConverter i(this, instr);
 
   switch (ArchOpcodeField::decode(instr->opcode())) {
-    case kArchJmp:
-      __ b(code_->GetLabel(i.InputBlock(0)));
+    case kArchCallAddress: {
+      DirectCEntryStub stub(isolate());
+      stub.GenerateCall(masm(), i.InputRegister(0));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
-    case kArchNop:
-      // don't emit code for nops.
+    }
+    case kArchCallCodeObject: {
+      if (instr->InputAt(0)->IsImmediate()) {
+        __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      } else {
+        __ add(ip, i.InputRegister(0),
+               Operand(Code::kHeaderSize - kHeapObjectTag));
+        __ Call(ip);
+      }
+      AddSafepointAndDeopt(instr);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
-    case kArchRet:
-      AssembleReturn();
+    }
+    case kArchCallJSFunction: {
+      // TODO(jarin) The load of the context should be separated from the call.
+      Register func = i.InputRegister(0);
+      __ ldr(cp, FieldMemOperand(func, JSFunction::kContextOffset));
+      __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Call(ip);
+      AddSafepointAndDeopt(instr);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
+    }
     case kArchDeoptimize: {
       int deoptimization_id = MiscField::decode(instr->opcode());
       BuildTranslation(instr, 0, deoptimization_id);
-
       Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
           isolate(), deoptimization_id, Deoptimizer::LAZY);
       __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
+    case kArchDrop: {
+      int words = MiscField::decode(instr->opcode());
+      __ Drop(words);
+      DCHECK_LT(0, words);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArchJmp:
+      __ b(code_->GetLabel(i.InputBlock(0)));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArchNop:
+      // don't emit code for nops.
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArchRet:
+      AssembleReturn();
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
     case kArchTruncateDoubleToI:
       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
@@ -236,51 +271,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
-    case kArmCallCodeObject: {
-      if (instr->InputAt(0)->IsImmediate()) {
-        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
-        __ Call(code, RelocInfo::CODE_TARGET);
-      } else {
-        Register reg = i.InputRegister(0);
-        int entry = Code::kHeaderSize - kHeapObjectTag;
-        __ ldr(reg, MemOperand(reg, entry));
-        __ Call(reg);
-      }
-
-      AddSafepointAndDeopt(instr);
-
-      DCHECK_EQ(LeaveCC, i.OutputSBit());
-      break;
-    }
-    case kArmCallJSFunction: {
-      Register func = i.InputRegister(0);
-
-      // TODO(jarin) The load of the context should be separated from the call.
-      __ ldr(cp, FieldMemOperand(func, JSFunction::kContextOffset));
-      __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
-      __ Call(ip);
-
-      AddSafepointAndDeopt(instr);
-
-      DCHECK_EQ(LeaveCC, i.OutputSBit());
-      break;
-    }
-    case kArmCallAddress: {
-      DirectCEntryStub stub(isolate());
-      stub.GenerateCall(masm(), i.InputRegister(0));
-      DCHECK_EQ(LeaveCC, i.OutputSBit());
-      break;
-    }
-    case kArmPush:
-      __ Push(i.InputRegister(0));
-      DCHECK_EQ(LeaveCC, i.OutputSBit());
-      break;
-    case kArmDrop: {
-      int words = MiscField::decode(instr->opcode());
-      __ Drop(words);
-      DCHECK_EQ(LeaveCC, i.OutputSBit());
-      break;
-    }
     case kArmCmp:
       __ cmp(i.InputRegister(0), i.InputOperand2(1));
       DCHECK_EQ(SetCC, i.OutputSBit());
@@ -442,6 +432,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
+    case kArmPush:
+      __ Push(i.InputRegister(0));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
     case kArmStoreWriteBarrier: {
       Register object = i.InputRegister(0);
       Register index = i.InputRegister(1);
index 5445d178ab7248a1bfc0f801ca4dbdf0f3718be0..41f0c09bacf5707be1aff7252f9e9239b5497875 100644 (file)
@@ -32,11 +32,6 @@ namespace compiler {
   V(ArmMvn)                        \
   V(ArmBfc)                        \
   V(ArmUbfx)                       \
-  V(ArmCallCodeObject)             \
-  V(ArmCallJSFunction)             \
-  V(ArmCallAddress)                \
-  V(ArmPush)                       \
-  V(ArmDrop)                       \
   V(ArmVcmpF64)                    \
   V(ArmVaddF64)                    \
   V(ArmVsubF64)                    \
@@ -62,6 +57,7 @@ namespace compiler {
   V(ArmStrh)                       \
   V(ArmLdr)                        \
   V(ArmStr)                        \
+  V(ArmPush)                       \
   V(ArmStoreWriteBarrier)
 
 
index 96f95e95bfa123849595d408ccfa1f50143288c1..3c999c8cd5bc65a87b4d6033dc4b519c42260bdc 100644 (file)
@@ -74,10 +74,14 @@ class ArmOperandGenerator V8_FINAL : public OperandGenerator {
       case kArmStrh:
         return value >= -255 && value <= 255;
 
+      case kArchCallAddress:
+      case kArchCallCodeObject:
+      case kArchCallJSFunction:
+      case kArchDeoptimize:
+      case kArchDrop:
       case kArchJmp:
       case kArchNop:
       case kArchRet:
-      case kArchDeoptimize:
       case kArchTruncateDoubleToI:
       case kArmMul:
       case kArmMla:
@@ -86,11 +90,6 @@ class ArmOperandGenerator V8_FINAL : public OperandGenerator {
       case kArmUdiv:
       case kArmBfc:
       case kArmUbfx:
-      case kArmCallCodeObject:
-      case kArmCallJSFunction:
-      case kArmCallAddress:
-      case kArmPush:
-      case kArmDrop:
       case kArmVcmpF64:
       case kArmVaddF64:
       case kArmVsubF64:
@@ -104,6 +103,7 @@ class ArmOperandGenerator V8_FINAL : public OperandGenerator {
       case kArmVcvtF64U32:
       case kArmVcvtS32F64:
       case kArmVcvtU32F64:
+      case kArmPush:
         return false;
     }
     UNREACHABLE();
@@ -808,14 +808,14 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
   InstructionCode opcode;
   switch (descriptor->kind()) {
     case CallDescriptor::kCallCodeObject: {
-      opcode = kArmCallCodeObject;
+      opcode = kArchCallCodeObject;
       break;
     }
     case CallDescriptor::kCallAddress:
-      opcode = kArmCallAddress;
+      opcode = kArchCallAddress;
       break;
     case CallDescriptor::kCallJSFunction:
-      opcode = kArmCallJSFunction;
+      opcode = kArchCallJSFunction;
       break;
     default:
       UNREACHABLE();
@@ -838,7 +838,7 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
   if (descriptor->kind() == CallDescriptor::kCallAddress &&
       !buffer.pushed_nodes.empty()) {
     DCHECK(deoptimization == NULL && continuation == NULL);
-    Emit(kArmDrop | MiscField::encode(buffer.pushed_nodes.size()), NULL);
+    Emit(kArchDrop | MiscField::encode(buffer.pushed_nodes.size()), NULL);
   }
 }
 
index edd023dc1838d8cf87af8c08b1cf1c9f15a0255a..51d377f89f30d6a0abe514f63f8028a346980487 100644 (file)
@@ -131,24 +131,56 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   Arm64OperandConverter i(this, instr);
   InstructionCode opcode = instr->opcode();
   switch (ArchOpcodeField::decode(opcode)) {
-    case kArchJmp:
-      __ B(code_->GetLabel(i.InputBlock(0)));
+    case kArchCallAddress: {
+      DirectCEntryStub stub(isolate());
+      stub.GenerateCall(masm(), i.InputRegister(0));
       break;
-    case kArchNop:
-      // don't emit code for nops.
+    }
+    case kArchCallCodeObject: {
+      if (instr->InputAt(0)->IsImmediate()) {
+        __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      } else {
+        Register target = i.InputRegister(0);
+        __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
+        __ Call(target);
+      }
+      AddSafepointAndDeopt(instr);
+      // Meaningless instruction for ICs to overwrite.
+      AddNopForSmiCodeInlining();
       break;
-    case kArchRet:
-      AssembleReturn();
+    }
+    case kArchCallJSFunction: {
+      // TODO(jarin) The load of the context should be separated from the call.
+      Register func = i.InputRegister(0);
+      __ Ldr(cp, FieldMemOperand(func, JSFunction::kContextOffset));
+      __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Call(x10);
+      AddSafepointAndDeopt(instr);
       break;
+    }
     case kArchDeoptimize: {
       int deoptimization_id = MiscField::decode(instr->opcode());
       BuildTranslation(instr, 0, deoptimization_id);
-
       Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
           isolate(), deoptimization_id, Deoptimizer::LAZY);
       __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
       break;
     }
+    case kArchDrop: {
+      int words = MiscField::decode(instr->opcode());
+      __ Drop(words);
+      break;
+    }
+    case kArchJmp:
+      __ B(code_->GetLabel(i.InputBlock(0)));
+      break;
+    case kArchNop:
+      // don't emit code for nops.
+      break;
+    case kArchRet:
+      AssembleReturn();
+      break;
     case kArchTruncateDoubleToI:
       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
       break;
@@ -283,38 +315,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
     case kArm64Sxtw:
       __ Sxtw(i.OutputRegister(), i.InputRegister32(0));
       break;
-    case kArm64CallCodeObject: {
-      if (instr->InputAt(0)->IsImmediate()) {
-        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
-        __ Call(code, RelocInfo::CODE_TARGET);
-      } else {
-        Register reg = i.InputRegister(0);
-        int entry = Code::kHeaderSize - kHeapObjectTag;
-        __ Ldr(reg, MemOperand(reg, entry));
-        __ Call(reg);
-      }
-
-      AddSafepointAndDeopt(instr);
-      // Meaningless instruction for ICs to overwrite.
-      AddNopForSmiCodeInlining();
-      break;
-    }
-    case kArm64CallJSFunction: {
-      Register func = i.InputRegister(0);
-
-      // TODO(jarin) The load of the context should be separated from the call.
-      __ Ldr(cp, FieldMemOperand(func, JSFunction::kContextOffset));
-      __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
-      __ Call(x10);
-
-      AddSafepointAndDeopt(instr);
-      break;
-    }
-    case kArm64CallAddress: {
-      DirectCEntryStub stub(isolate());
-      stub.GenerateCall(masm(), i.InputRegister(0));
-      break;
-    }
     case kArm64Claim: {
       int words = MiscField::decode(instr->opcode());
       __ Claim(words);
@@ -337,11 +337,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       __ PokePair(i.InputRegister(1), i.InputRegister(0), slot * kPointerSize);
       break;
     }
-    case kArm64Drop: {
-      int words = MiscField::decode(instr->opcode());
-      __ Drop(words);
-      break;
-    }
     case kArm64Cmp:
       __ Cmp(i.InputRegister(0), i.InputOperand(1));
       break;
index f0231557045032e35f3730dd999b042a93ee9555..ebc8c86cb22c7e06643bc4055915d7aeb6839834 100644 (file)
@@ -50,14 +50,10 @@ namespace compiler {
   V(Arm64Ror32)                    \
   V(Arm64Mov32)                    \
   V(Arm64Sxtw)                     \
-  V(Arm64CallCodeObject)           \
-  V(Arm64CallJSFunction)           \
-  V(Arm64CallAddress)              \
   V(Arm64Claim)                    \
   V(Arm64Poke)                     \
   V(Arm64PokePairZero)             \
   V(Arm64PokePair)                 \
-  V(Arm64Drop)                     \
   V(Arm64Float64Cmp)               \
   V(Arm64Float64Add)               \
   V(Arm64Float64Sub)               \
index 8445e9f3241b71dc5b0ed539359e8639631a5a2b..bc1985c7c34eb37af854703a53083acb03ddfeb1 100644 (file)
@@ -638,14 +638,14 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
   InstructionCode opcode;
   switch (descriptor->kind()) {
     case CallDescriptor::kCallCodeObject: {
-      opcode = kArm64CallCodeObject;
+      opcode = kArchCallCodeObject;
       break;
     }
     case CallDescriptor::kCallAddress:
-      opcode = kArm64CallAddress;
+      opcode = kArchCallAddress;
       break;
     case CallDescriptor::kCallJSFunction:
-      opcode = kArm64CallJSFunction;
+      opcode = kArchCallJSFunction;
       break;
     default:
       UNREACHABLE();
@@ -667,7 +667,7 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
   // Caller clean up of stack for C-style calls.
   if (is_c_frame && aligned_push_count > 0) {
     DCHECK(deoptimization == NULL && continuation == NULL);
-    Emit(kArm64Drop | MiscField::encode(aligned_push_count), NULL);
+    Emit(kArchDrop | MiscField::encode(aligned_push_count), NULL);
   }
 }
 
index ea641f77421bb1e3525736088b6dbe02adbcdc2b..b84e7ec64c028a9f5bd679260e6b573938384606 100644 (file)
@@ -111,15 +111,35 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   IA32OperandConverter i(this, instr);
 
   switch (ArchOpcodeField::decode(instr->opcode())) {
-    case kArchJmp:
-      __ jmp(code()->GetLabel(i.InputBlock(0)));
+    case kArchCallAddress:
+      if (HasImmediateInput(instr, 0)) {
+        // TODO(dcarney): wire up EXTERNAL_REFERENCE instead of RUNTIME_ENTRY.
+        __ call(reinterpret_cast<byte*>(i.InputInt32(0)),
+                RelocInfo::RUNTIME_ENTRY);
+      } else {
+        __ call(i.InputRegister(0));
+      }
       break;
-    case kArchNop:
-      // don't emit code for nops.
+    case kArchCallCodeObject: {
+      if (HasImmediateInput(instr, 0)) {
+        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
+        __ call(code, RelocInfo::CODE_TARGET);
+      } else {
+        Register reg = i.InputRegister(0);
+        __ call(Operand(reg, Code::kHeaderSize - kHeapObjectTag));
+      }
+      AddSafepointAndDeopt(instr);
+      AddNopForSmiCodeInlining();
       break;
-    case kArchRet:
-      AssembleReturn();
+    }
+    case kArchCallJSFunction: {
+      // TODO(jarin) The load of the context should be separated from the call.
+      Register func = i.InputRegister(0);
+      __ mov(esi, FieldOperand(func, JSFunction::kContextOffset));
+      __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
+      AddSafepointAndDeopt(instr);
       break;
+    }
     case kArchDeoptimize: {
       int deoptimization_id = MiscField::decode(instr->opcode());
       BuildTranslation(instr, 0, deoptimization_id);
@@ -129,6 +149,20 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
       break;
     }
+    case kArchDrop: {
+      int words = MiscField::decode(instr->opcode());
+      __ add(esp, Immediate(kPointerSize * words));
+      break;
+    }
+    case kArchJmp:
+      __ jmp(code()->GetLabel(i.InputBlock(0)));
+      break;
+    case kArchNop:
+      // don't emit code for nops.
+      break;
+    case kArchRet:
+      AssembleReturn();
+      break;
     case kArchTruncateDoubleToI:
       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
       break;
@@ -230,52 +264,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ ror_cl(i.OutputRegister());
       }
       break;
-    case kIA32Push:
-      if (HasImmediateInput(instr, 0)) {
-        __ push(i.InputImmediate(0));
-      } else {
-        __ push(i.InputOperand(0));
-      }
-      break;
-    case kIA32CallCodeObject: {
-      if (HasImmediateInput(instr, 0)) {
-        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
-        __ call(code, RelocInfo::CODE_TARGET);
-      } else {
-        Register reg = i.InputRegister(0);
-        int entry = Code::kHeaderSize - kHeapObjectTag;
-        __ call(Operand(reg, entry));
-      }
-
-      AddSafepointAndDeopt(instr);
-
-      AddNopForSmiCodeInlining();
-      break;
-    }
-    case kIA32CallAddress:
-      if (HasImmediateInput(instr, 0)) {
-        // TODO(dcarney): wire up EXTERNAL_REFERENCE instead of RUNTIME_ENTRY.
-        __ call(reinterpret_cast<byte*>(i.InputInt32(0)),
-                RelocInfo::RUNTIME_ENTRY);
-      } else {
-        __ call(i.InputRegister(0));
-      }
-      break;
-    case kPopStack: {
-      int words = MiscField::decode(instr->opcode());
-      __ add(esp, Immediate(kPointerSize * words));
-      break;
-    }
-    case kIA32CallJSFunction: {
-      Register func = i.InputRegister(0);
-
-      // TODO(jarin) The load of the context should be separated from the call.
-      __ mov(esi, FieldOperand(func, JSFunction::kContextOffset));
-      __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
-
-      AddSafepointAndDeopt(instr);
-      break;
-    }
     case kSSEFloat64Cmp:
       __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
       break;
@@ -400,6 +388,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ movss(operand, xmm0);
       }
       break;
+    case kIA32Push:
+      if (HasImmediateInput(instr, 0)) {
+        __ push(i.InputImmediate(0));
+      } else {
+        __ push(i.InputOperand(0));
+      }
+      break;
     case kIA32StoreWriteBarrier: {
       Register object = i.InputRegister(0);
       Register index = i.InputRegister(1);
index 50dc051b4bc1eb2ecc66415baa27080eef225c53..d8ea014a934d86aec3896976c12ba991e935bcae 100644 (file)
@@ -28,11 +28,6 @@ namespace compiler {
   V(IA32Shr)                       \
   V(IA32Sar)                       \
   V(IA32Ror)                       \
-  V(IA32Push)                      \
-  V(IA32CallCodeObject)            \
-  V(IA32CallAddress)               \
-  V(PopStack)                      \
-  V(IA32CallJSFunction)            \
   V(SSEFloat64Cmp)                 \
   V(SSEFloat64Add)                 \
   V(SSEFloat64Sub)                 \
@@ -52,6 +47,7 @@ namespace compiler {
   V(IA32Movl)                      \
   V(IA32Movss)                     \
   V(IA32Movsd)                     \
+  V(IA32Push)                      \
   V(IA32StoreWriteBarrier)
 
 
index 0b20903a1420136aac0c0d9c932f9884dc4541be..4e93b2e36db598ea8d8008a285ba9df9c38d6f9c 100644 (file)
@@ -530,14 +530,14 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
   InstructionCode opcode;
   switch (descriptor->kind()) {
     case CallDescriptor::kCallCodeObject: {
-      opcode = kIA32CallCodeObject;
+      opcode = kArchCallCodeObject;
       break;
     }
     case CallDescriptor::kCallAddress:
-      opcode = kIA32CallAddress;
+      opcode = kArchCallAddress;
       break;
     case CallDescriptor::kCallJSFunction:
-      opcode = kIA32CallJSFunction;
+      opcode = kArchCallJSFunction;
       break;
     default:
       UNREACHABLE();
@@ -560,7 +560,7 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
   if (descriptor->kind() == CallDescriptor::kCallAddress &&
       buffer.pushed_nodes.size() > 0) {
     DCHECK(deoptimization == NULL && continuation == NULL);
-    Emit(kPopStack | MiscField::encode(buffer.pushed_nodes.size()), NULL);
+    Emit(kArchDrop | MiscField::encode(buffer.pushed_nodes.size()), NULL);
   }
 }
 
index 16aa1db873527d282489a6bf04083c655bfe553f..35ba436d09ffb4614896b2df24a753cb5c1edeaa 100644 (file)
@@ -29,7 +29,11 @@ namespace compiler {
 // Target-specific opcodes that specify which assembly sequence to emit.
 // Most opcodes specify a single instruction.
 #define ARCH_OPCODE_LIST(V) \
+  V(ArchCallAddress)        \
+  V(ArchCallCodeObject)     \
+  V(ArchCallJSFunction)     \
   V(ArchDeoptimize)         \
+  V(ArchDrop)               \
   V(ArchJmp)                \
   V(ArchNop)                \
   V(ArchRet)                \
index 5743cd71389c51bcb17a112e2bfa0b130cd38727..1d86693620514a8f4bbec149c1341776551cfc66 100644 (file)
@@ -204,24 +204,58 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   X64OperandConverter i(this, instr);
 
   switch (ArchOpcodeField::decode(instr->opcode())) {
-    case kArchJmp:
-      __ jmp(code_->GetLabel(i.InputBlock(0)));
+    case kArchCallCodeObject: {
+      if (HasImmediateInput(instr, 0)) {
+        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
+        __ Call(code, RelocInfo::CODE_TARGET);
+      } else {
+        Register reg = i.InputRegister(0);
+        int entry = Code::kHeaderSize - kHeapObjectTag;
+        __ Call(Operand(reg, entry));
+      }
+      AddSafepointAndDeopt(instr);
+      AddNopForSmiCodeInlining();
       break;
-    case kArchNop:
-      // don't emit code for nops.
+    }
+    case kArchCallAddress:
+      if (HasImmediateInput(instr, 0)) {
+        Immediate64 imm = i.InputImmediate64(0);
+        DCHECK_EQ(kImm64Value, imm.type);
+        __ Call(reinterpret_cast<byte*>(imm.value), RelocInfo::NONE64);
+      } else {
+        __ call(i.InputRegister(0));
+      }
       break;
-    case kArchRet:
-      AssembleReturn();
+    case kArchCallJSFunction: {
+      // TODO(jarin) The load of the context should be separated from the call.
+      Register func = i.InputRegister(0);
+      __ movp(rsi, FieldOperand(func, JSFunction::kContextOffset));
+      __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset));
+      AddSafepointAndDeopt(instr);
       break;
+    }
     case kArchDeoptimize: {
       int deoptimization_id = MiscField::decode(instr->opcode());
       BuildTranslation(instr, 0, deoptimization_id);
-
       Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
           isolate(), deoptimization_id, Deoptimizer::LAZY);
       __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
       break;
     }
+    case kArchDrop: {
+      int words = MiscField::decode(instr->opcode());
+      __ addq(rsp, Immediate(kPointerSize * words));
+      break;
+    }
+    case kArchJmp:
+      __ jmp(code_->GetLabel(i.InputBlock(0)));
+      break;
+    case kArchNop:
+      // don't emit code for nops.
+      break;
+    case kArchRet:
+      AssembleReturn();
+      break;
     case kArchTruncateDoubleToI:
       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
       break;
@@ -379,57 +413,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
     case kX64Ror:
       ASSEMBLE_SHIFT(rorq, 6);
       break;
-    case kX64Push: {
-      RegisterOrOperand input = i.InputRegisterOrOperand(0);
-      if (input.type == kRegister) {
-        __ pushq(input.reg);
-      } else {
-        __ pushq(input.operand);
-      }
-      break;
-    }
-    case kX64PushI:
-      __ pushq(i.InputImmediate(0));
-      break;
-    case kX64CallCodeObject: {
-      if (HasImmediateInput(instr, 0)) {
-        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
-        __ Call(code, RelocInfo::CODE_TARGET);
-      } else {
-        Register reg = i.InputRegister(0);
-        int entry = Code::kHeaderSize - kHeapObjectTag;
-        __ Call(Operand(reg, entry));
-      }
-
-      AddSafepointAndDeopt(instr);
-
-      AddNopForSmiCodeInlining();
-      break;
-    }
-    case kX64CallAddress:
-      if (HasImmediateInput(instr, 0)) {
-        Immediate64 imm = i.InputImmediate64(0);
-        DCHECK_EQ(kImm64Value, imm.type);
-        __ Call(reinterpret_cast<byte*>(imm.value), RelocInfo::NONE64);
-      } else {
-        __ call(i.InputRegister(0));
-      }
-      break;
-    case kPopStack: {
-      int words = MiscField::decode(instr->opcode());
-      __ addq(rsp, Immediate(kPointerSize * words));
-      break;
-    }
-    case kX64CallJSFunction: {
-      Register func = i.InputRegister(0);
-
-      // TODO(jarin) The load of the context should be separated from the call.
-      __ movp(rsi, FieldOperand(func, JSFunction::kContextOffset));
-      __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset));
-
-      AddSafepointAndDeopt(instr);
-      break;
-    }
     case kSSEFloat64Cmp: {
       RegisterOrOperand input = i.InputRegisterOrOperand(1);
       if (input.type == kDoubleRegister) {
@@ -513,7 +496,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       __ cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
       break;
     }
-
     case kX64Movsxbl:
       __ movsxbl(i.OutputRegister(), i.MemoryOperand());
       break;
@@ -610,6 +592,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
         __ movsd(operand, i.InputDoubleRegister(index));
       }
       break;
+    case kX64Push:
+      if (HasImmediateInput(instr, 0)) {
+        __ pushq(i.InputImmediate(0));
+      } else {
+        RegisterOrOperand input = i.InputRegisterOrOperand(0);
+        if (input.type == kRegister) {
+          __ pushq(input.reg);
+        } else {
+          __ pushq(input.operand);
+        }
+      }
+      break;
     case kX64StoreWriteBarrier: {
       Register object = i.InputRegister(0);
       Register index = i.InputRegister(1);
index fab1e70bd5fce5bc33577635bba6ddc055e8d417..c54d7eef1d6c93fdf18b1290372b11a1a57018e6 100644 (file)
@@ -44,12 +44,6 @@ namespace compiler {
   V(X64Sar32)                      \
   V(X64Ror)                        \
   V(X64Ror32)                      \
-  V(X64Push)                       \
-  V(X64PushI)                      \
-  V(X64CallCodeObject)             \
-  V(X64CallAddress)                \
-  V(PopStack)                      \
-  V(X64CallJSFunction)             \
   V(SSEFloat64Cmp)                 \
   V(SSEFloat64Add)                 \
   V(SSEFloat64Sub)                 \
@@ -71,6 +65,7 @@ namespace compiler {
   V(X64Movq)                       \
   V(X64Movsd)                      \
   V(X64Movss)                      \
+  V(X64Push)                       \
   V(X64StoreWriteBarrier)
 
 
index 33349225c967bf2a10a41c1bb71244c5ed57516e..015f1afb50d798720f8734cb1689ead565afdb43 100644 (file)
@@ -686,25 +686,22 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
   for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
        input != buffer.pushed_nodes.rend(); input++) {
     // TODO(titzer): handle pushing double parameters.
-    if (g.CanBeImmediate(*input)) {
-      Emit(kX64PushI, NULL, g.UseImmediate(*input));
-    } else {
-      Emit(kX64Push, NULL, g.Use(*input));
-    }
+    Emit(kX64Push, NULL,
+         g.CanBeImmediate(*input) ? g.UseImmediate(*input) : g.Use(*input));
   }
 
   // Select the appropriate opcode based on the call type.
   InstructionCode opcode;
   switch (descriptor->kind()) {
     case CallDescriptor::kCallCodeObject: {
-      opcode = kX64CallCodeObject;
+      opcode = kArchCallCodeObject;
       break;
     }
     case CallDescriptor::kCallAddress:
-      opcode = kX64CallAddress;
+      opcode = kArchCallAddress;
       break;
     case CallDescriptor::kCallJSFunction:
-      opcode = kX64CallJSFunction;
+      opcode = kArchCallJSFunction;
       break;
     default:
       UNREACHABLE();
@@ -727,7 +724,7 @@ void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
   if (descriptor->kind() == CallDescriptor::kCallAddress &&
       !buffer.pushed_nodes.empty()) {
     DCHECK(deoptimization == NULL && continuation == NULL);
-    Emit(kPopStack |
+    Emit(kArchDrop |
              MiscField::encode(static_cast<int>(buffer.pushed_nodes.size())),
          NULL);
   }