Index: src/compiler/ia32/code-generator-ia32.cc |
diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc |
index cca42fa2fd6d6a82b65d89819f3f0e17538151b5..3ec0479a9c9bdb082594977073cce9a0f829dec5 100644 |
--- a/src/compiler/ia32/code-generator-ia32.cc |
+++ b/src/compiler/ia32/code-generator-ia32.cc |
@@ -652,7 +652,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
break; |
} |
case kArchRet: |
- AssembleReturn(); |
+ AssembleReturn(instr->InputAt(0)); |
break; |
case kArchStackPointer: |
__ mov(i.OutputRegister(), esp); |
@@ -1984,8 +1984,7 @@ void CodeGenerator::AssembleConstructFrame() { |
} |
} |
- |
-void CodeGenerator::AssembleReturn() { |
+void CodeGenerator::AssembleReturn(InstructionOperand* pop) { |
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
const RegList saves = descriptor->CalleeSavedRegisters(); |
@@ -2009,10 +2008,21 @@ void CodeGenerator::AssembleReturn() { |
AssembleDeconstructFrame(); |
} |
} |
- size_t pop_size = descriptor->StackParameterCount() * kPointerSize; |
- // Might need ecx for scratch if pop_size is too big. |
+ // Might need ecx for scratch if pop_size is too big or if there is a variable |
+ // pop count. |
DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); |
- __ Ret(static_cast<int>(pop_size), ecx); |
+ size_t pop_size = descriptor->StackParameterCount() * kPointerSize; |
+ IA32OperandConverter g(this, nullptr); |
+ if (pop->IsImmediate()) { |
+ DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type()); |
+ pop_size += g.ToConstant(pop).ToInt32() * kPointerSize; |
+ __ Ret(static_cast<int>(pop_size), ecx); |
+ } else { |
+ Register reg = g.ToRegister(pop); |
+ __ pop(ecx); |
+ __ lea(esp, Operand(esp, reg, times_4, pop_size)); |
+ __ jmp(ecx); |
+ } |
} |