Revision: 3708
Author: [email protected]
Date: Tue Jan 26 02:27:27 2010
Log: Support register arguments in more cases.
1. MUL and DIV on SMIs.
2. When calling GenericBinaryOpStub from a virtual frame.
3. When generating code for a loop counter.
Overall performance gain is about 0.6%.
Review URL: http://codereview.chromium.org/555098
http://code.google.com/p/v8/source/detail?r=3708
Modified:
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/ia32/codegen-ia32.h
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Jan 25 09:47:53
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Tue Jan 26 02:27:27
2010
@@ -763,10 +763,8 @@
ArgLocation arg_location = ARGS_ON_STACK);
// Similar to LoadFloatOperand but assumes that both operands are smis.
- // Accepts operands on stack or in eax, ebx.
- static void LoadFloatSmis(MacroAssembler* masm,
- Register scratch,
- ArgLocation arg_location);
+ // Accepts operands in eax, ebx.
+ static void LoadFloatSmis(MacroAssembler* masm, Register scratch);
// Test if operands are smi or number objects (fp). Requirements:
// operand_1 in eax, operand_2 in edx; falls through on float
@@ -786,10 +784,8 @@
static void LoadSse2Operands(MacroAssembler* masm, Label* not_numbers);
// Similar to LoadSse2Operands but assumes that both operands are smis.
- // Accepts operands on stack or in eax, ebx.
- static void LoadSse2Smis(MacroAssembler* masm,
- Register scratch,
- ArgLocation arg_location);
+ // Accepts operands in eax, ebx.
+ static void LoadSse2Smis(MacroAssembler* masm, Register scratch);
};
@@ -978,10 +974,8 @@
Result answer;
if (left_is_non_smi || right_is_non_smi) {
// Go straight to the slow case, with no smi code.
- frame_->Push(&left);
- frame_->Push(&right);
GenericBinaryOpStub stub(op, overwrite_mode, NO_SMI_CODE_IN_STUB);
- answer = frame_->CallStub(&stub, 2);
+ answer = stub.GenerateCall(masm_, frame_, &left, &right);
} else if (right_is_smi) {
answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
type, false, overwrite_mode);
@@ -997,10 +991,8 @@
if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi()))
{
answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
} else {
- frame_->Push(&left);
- frame_->Push(&right);
GenericBinaryOpStub stub(op, overwrite_mode,
NO_GENERIC_BINARY_FLAGS);
- answer = frame_->CallStub(&stub, 2);
+ answer = stub.GenerateCall(masm_, frame_, &left, &right);
}
}
frame_->Push(&answer);
@@ -7074,6 +7066,21 @@
// Call the stub.
__ CallStub(this);
}
+
+
+Result GenericBinaryOpStub::GenerateCall(MacroAssembler* masm,
+ VirtualFrame* frame,
+ Result* left,
+ Result* right) {
+ if (ArgsInRegistersSupported()) {
+ SetArgsInRegisters();
+ return frame->CallStub(this, left, right);
+ } else {
+ frame->Push(left);
+ frame->Push(right);
+ return frame->CallStub(this, 2);
+ }
+}
void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label*
slow) {
@@ -7107,7 +7114,13 @@
__ j(overflow, ¬_smis_or_overflow, not_taken);
break;
+ case Token::MUL:
+ __ mov(edi, eax); // Backup the left operand.
+ break;
+
case Token::DIV:
+ __ mov(edi, eax); // Backup the left operand.
+ // Fall through.
case Token::MOD:
// Sign extend eax into edx:eax.
__ cdq();
@@ -7243,28 +7256,18 @@
__ bind(&use_fp_on_smis);
// Both operands are known to be SMIs but the result does not fit into a
SMI.
switch (op_) {
- case Token::ADD:
- case Token::SUB:
case Token::MUL:
- case Token::DIV: {
+ case Token::DIV:
+ __ mov(eax, edi); // Restore the left operand.
+ // Fall through.
+ case Token::ADD:
+ case Token::SUB: {
Label after_alloc_failure;
-
- FloatingPointHelper::ArgLocation arg_location =
- (op_ == Token::ADD || op_ == Token::SUB) ?
- FloatingPointHelper::ARGS_IN_REGISTERS :
- FloatingPointHelper::ARGS_ON_STACK;
-
- __ AllocateHeapNumber(
- edx,
- ecx,
- no_reg,
- arg_location == FloatingPointHelper::ARGS_IN_REGISTERS ?
- &after_alloc_failure :
- slow);
+ __ AllocateHeapNumber(edx, ecx, no_reg, &after_alloc_failure);
if (CpuFeatures::IsSupported(SSE2)) {
CpuFeatures::Scope use_sse2(SSE2);
- FloatingPointHelper::LoadSse2Smis(masm, ecx, arg_location);
+ FloatingPointHelper::LoadSse2Smis(masm, ecx);
switch (op_) {
case Token::ADD: __ addsd(xmm0, xmm1); break;
case Token::SUB: __ subsd(xmm0, xmm1); break;
@@ -7274,7 +7277,7 @@
}
__ movdbl(FieldOperand(edx, HeapNumber::kValueOffset), xmm0);
} else { // SSE2 not available, use FPU.
- FloatingPointHelper::LoadFloatSmis(masm, ecx, arg_location);
+ FloatingPointHelper::LoadFloatSmis(masm, ecx);
switch (op_) {
case Token::ADD: __ faddp(1); break;
case Token::SUB: __ fsubp(1); break;
@@ -7287,12 +7290,10 @@
__ mov(eax, edx);
GenerateReturn(masm);
- if (arg_location == FloatingPointHelper::ARGS_IN_REGISTERS) {
- __ bind(&after_alloc_failure);
- __ mov(edx, eax);
- __ mov(eax, ebx);
- __ jmp(slow);
- }
+ __ bind(&after_alloc_failure);
+ __ mov(edx, eax);
+ __ mov(eax, ebx);
+ __ jmp(slow);
break;
}
@@ -7438,7 +7439,7 @@
__ bind(&non_smi_result);
// Allocate a heap number if needed.
__ mov(ebx, Operand(eax)); // ebx: result
- Label skip_allocation;
+ Label skip_allocation;
switch (mode_) {
case OVERWRITE_LEFT:
case OVERWRITE_RIGHT:
@@ -7881,22 +7882,12 @@
void FloatingPointHelper::LoadSse2Smis(MacroAssembler* masm,
- Register scratch,
- ArgLocation arg_location) {
- if (arg_location == ARGS_IN_REGISTERS) {
- __ mov(scratch, eax);
- } else {
- __ mov(scratch, Operand(esp, 2 * kPointerSize));
- }
+ Register scratch) {
+ __ mov(scratch, eax);
__ SmiUntag(scratch); // Untag smi before converting to float.
__ cvtsi2sd(xmm0, Operand(scratch));
-
- if (arg_location == ARGS_IN_REGISTERS) {
- __ mov(scratch, ebx);
- } else {
- __ mov(scratch, Operand(esp, 1 * kPointerSize));
- }
+ __ mov(scratch, ebx);
__ SmiUntag(scratch); // Untag smi before converting to float.
__ cvtsi2sd(xmm1, Operand(scratch));
}
@@ -7944,23 +7935,14 @@
void FloatingPointHelper::LoadFloatSmis(MacroAssembler* masm,
- Register scratch,
- ArgLocation arg_location) {
- if (arg_location == ARGS_IN_REGISTERS) {
- __ mov(scratch, eax);
- } else {
- __ mov(scratch, Operand(esp, 2 * kPointerSize));
- }
+ Register scratch) {
+ __ mov(scratch, eax);
__ SmiUntag(scratch);
__ push(scratch);
__ fild_s(Operand(esp, 0));
__ pop(scratch);
- if (arg_location == ARGS_IN_REGISTERS) {
- __ mov(scratch, ebx);
- } else {
- __ mov(scratch, Operand(esp, 1 * kPointerSize));
- }
+ __ mov(scratch, ebx);
__ SmiUntag(scratch);
__ push(scratch);
__ fild_s(Operand(esp, 0));
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h Mon Jan 25 09:47:53 2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h Tue Jan 26 02:27:27 2010
@@ -652,6 +652,11 @@
void GenerateCall(MacroAssembler* masm, Register left, Smi* right);
void GenerateCall(MacroAssembler* masm, Smi* left, Register right);
+ Result GenerateCall(MacroAssembler* masm,
+ VirtualFrame* frame,
+ Result* left,
+ Result* right);
+
private:
Token::Value op_;
OverwriteMode mode_;
@@ -700,15 +705,9 @@
void GenerateReturn(MacroAssembler* masm);
void GenerateHeapResultAllocation(MacroAssembler* masm, Label*
alloc_failure);
- // Args in registers are always OK for ADD and SUB. Floating-point MUL
and DIV
- // are also OK. Though MUL and DIV on SMIs modify the original registers
so
- // we need to push args on stack anyway.
bool ArgsInRegistersSupported() {
- if (op_ == Token::ADD || op_ == Token::SUB) return true;
- if (op_ == Token::MUL || op_ == Token::DIV) {
- return flags_ == NO_SMI_CODE_IN_STUB;
- }
- return false;
+ return op_ == Token::ADD || op_ == Token::SUB
+ || op_ == Token::MUL || op_ == Token::DIV;
}
bool IsOperationCommutative() {
return (op_ == Token::ADD) || (op_ == Token::MUL);
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Jan 22
06:07:25 2010
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Tue Jan 26
02:27:27 2010
@@ -1560,12 +1560,10 @@
}
}
// Call stub for +1/-1.
- __ push(eax);
- __ push(Immediate(Smi::FromInt(1)));
GenericBinaryOpStub stub(expr->binary_op(),
NO_OVERWRITE,
NO_GENERIC_BINARY_FLAGS);
- __ CallStub(&stub);
+ stub.GenerateCall(masm(), eax, Smi::FromInt(1));
__ bind(&done);
// Store the value returned in eax.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev