Author: [email protected]
Date: Mon Dec 29 05:58:09 2008
New Revision: 1021
Modified:
branches/experimental/toiger/src/assembler-ia32.cc
branches/experimental/toiger/src/assembler-ia32.h
branches/experimental/toiger/src/codegen-ia32.cc
branches/experimental/toiger/src/disasm-ia32.cc
branches/experimental/toiger/src/jump-target-ia32.cc
branches/experimental/toiger/src/jump-target.h
branches/experimental/toiger/src/virtual-frame-ia32.cc
Log:
Copy of changelist from issue 16450. Converts compare operation
to use virtual frames, adds xchg instruction to assembler.
Review URL: http://codereview.chromium.org/16481
Modified: branches/experimental/toiger/src/assembler-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/assembler-ia32.cc (original)
+++ branches/experimental/toiger/src/assembler-ia32.cc Mon Dec 29 05:58:09
2008
@@ -743,6 +743,18 @@
}
+void Assembler::xchg(Register dst, Register src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ if (src.is(eax) || dst.is(eax)) { // Single-byte encoding
+ EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
+ } else {
+ EMIT(0x87);
+ EMIT(0xC0 | src.code() << 3 | dst.code());
+ }
+}
+
+
void Assembler::adc(Register dst, int32_t imm32) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
Modified: branches/experimental/toiger/src/assembler-ia32.h
==============================================================================
--- branches/experimental/toiger/src/assembler-ia32.h (original)
+++ branches/experimental/toiger/src/assembler-ia32.h Mon Dec 29 05:58:09
2008
@@ -499,6 +499,9 @@
void cmov(Condition cc, Register dst, Handle<Object> handle);
void cmov(Condition cc, Register dst, const Operand& src);
+ // Exchange two registers
+ void xchg(Register dst, Register src);
+
// Arithmetics
void adc(Register dst, int32_t imm32);
void adc(Register dst, const Operand& src);
Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc Mon Dec 29 05:58:09
2008
@@ -1185,38 +1185,64 @@
// Strict only makes sense for equality comparisons.
ASSERT(!strict || cc == equal);
+ Result left_side(this);
+ Result right_side(this);
// Implement '>' and '<=' by reversal to obtain ECMA-262 conversion
order.
if (cc == greater || cc == less_equal) {
cc = ReverseCondition(cc);
- frame_->EmitPop(edx);
- frame_->EmitPop(eax);
+ left_side = frame_->Pop();
+ right_side = frame_->Pop();
} else {
- frame_->EmitPop(eax);
- frame_->EmitPop(edx);
+ right_side = frame_->Pop();
+ left_side = frame_->Pop();
}
-
+ left_side.ToRegister();
+ right_side.ToRegister();
+ ASSERT(left_side.is_valid());
+ ASSERT(right_side.is_valid());
// Check for the smi case.
JumpTarget is_smi(this);
JumpTarget done(this);
- __ mov(ecx, Operand(eax));
- __ or_(ecx, Operand(edx));
- __ test(ecx, Immediate(kSmiTagMask));
- is_smi.Branch(zero, taken);
+ Result temp = allocator_->Allocate();
+ ASSERT(temp.is_valid());
+ __ mov(temp.reg(), left_side.reg());
+ __ or_(temp.reg(), Operand(right_side.reg()));
+ __ test(temp.reg(), Immediate(kSmiTagMask));
+ temp.Unuse();
+ is_smi.Branch(zero, &left_side, &right_side, taken);
// When non-smi, call out to the compare stub. "parameters" setup by
// calling code in edx and eax and "result" is returned in the flags.
+ if (!left_side.reg().is(eax)) {
+ right_side.ToRegister(eax);
+ left_side.ToRegister(edx);
+ } else if (!right_side.reg().is(edx)) {
+ left_side.ToRegister(edx);
+ right_side.ToRegister(eax);
+ } else {
+ frame_->Spill(eax); // Can be multiply referenced, even now.
+ frame_->Spill(edx);
+ __ xchg(eax, edx);
+ // If left_side and right_side become real (non-dummy) arguments
+ // to CallStub, they need to be swapped in this case.
+ }
CompareStub stub(cc, strict);
- frame_->CallStub(&stub, 0);
+ Result answer = frame_->CallStub(&stub, &right_side, &left_side, 0);
if (cc == equal) {
- __ test(eax, Operand(eax));
+ __ test(answer.reg(), Operand(answer.reg()));
} else {
- __ cmp(eax, 0);
+ __ cmp(answer.reg(), 0);
}
+ answer.Unuse();
+ // The expected frame at JumpTarget "done" is bound to the current frame.
+ // This current frame is spilled, due to the call to CallStub.
+ // It would be better if the fast SMI case controlled the expected frame.
done.Jump();
- // Test smi equality by pointer comparison.
- is_smi.Bind();
- __ cmp(edx, Operand(eax));
+ is_smi.Bind(&left_side, &right_side);
+ __ cmp(left_side.reg(), Operand(right_side.reg()));
+ right_side.Unuse();
+ left_side.Unuse();
// Fall through to |done|.
done.Bind();
@@ -4172,17 +4198,15 @@
cc = greater_equal;
break;
case Token::IN: {
- VirtualFrame::SpilledScope spilled_scope(this);
- LoadAndSpill(left);
- LoadAndSpill(right);
+ Load(left);
+ Load(right);
frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2);
- frame_->EmitPush(eax); // push the result
+ frame_->Push(eax); // push the result
return;
}
case Token::INSTANCEOF: {
- VirtualFrame::SpilledScope spilled_scope(this);
- LoadAndSpill(left);
- LoadAndSpill(right);
+ Load(left);
+ Load(right);
InstanceofStub stub;
frame_->CallStub(&stub, 2);
__ test(eax, Operand(eax));
@@ -4206,9 +4230,8 @@
return;
}
- VirtualFrame::SpilledScope spilled_scope(this);
- LoadAndSpill(left);
- LoadAndSpill(right);
+ Load(left);
+ Load(right);
Comparison(cc, strict);
}
Modified: branches/experimental/toiger/src/disasm-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/disasm-ia32.cc (original)
+++ branches/experimental/toiger/src/disasm-ia32.cc Mon Dec 29 05:58:09 2008
@@ -65,6 +65,7 @@
{0x85, "test", REG_OPER_OP_ORDER},
{0x31, "xor", OPER_REG_OP_ORDER},
{0x33, "xor", REG_OPER_OP_ORDER},
+ {0x87, "xchg", REG_OPER_OP_ORDER},
{0x8A, "mov_b", REG_OPER_OP_ORDER},
{0x8B, "mov", REG_OPER_OP_ORDER},
{-1, "", UNSET_OP_ORDER}
@@ -177,6 +178,7 @@
SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec");
SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push");
SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop");
+ SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop.
SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov");
}
Modified: branches/experimental/toiger/src/jump-target-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/jump-target-ia32.cc (original)
+++ branches/experimental/toiger/src/jump-target-ia32.cc Mon Dec 29
05:58:09 2008
@@ -168,6 +168,32 @@
}
+void JumpTarget::Branch(Condition cc, Result* arg0, Result* arg1, Hint
hint) {
+ ASSERT(cgen_ != NULL);
+ ASSERT(cgen_->frame() != NULL);
+
+#ifdef DEBUG
+ // We want register results at the call site to stay in the same
registers
+ // on the fall-through branch.
+ Result::Type arg0_type = arg0->type();
+ Register arg0_reg = arg0->is_register() ? arg0->reg() : no_reg;
+ Result::Type arg1_type = arg1->type();
+ Register arg1_reg = arg1->is_register() ? arg1->reg() : no_reg;
+#endif
+
+ cgen_->frame()->Push(arg0);
+ cgen_->frame()->Push(arg1);
+ Branch(cc, hint);
+ *arg1 = cgen_->frame()->Pop();
+ *arg0 = cgen_->frame()->Pop();
+
+ ASSERT(arg0->type() == arg0_type);
+ ASSERT(!arg0->is_register() || arg0->reg().is(arg0_reg));
+ ASSERT(arg1->type() == arg1_type);
+ ASSERT(!arg1->is_register() || arg1->reg().is(arg1_reg));
+}
+
+
void JumpTarget::Call() {
// Precondition: there is a current frame, and there is no expected frame
// at the label.
@@ -258,6 +284,45 @@
ASSERT(!had_entry_frame || arg->type() == arg_type);
ASSERT(!had_entry_frame || !arg->is_register() ||
arg->reg().is(arg_reg));
+}
+
+
+void JumpTarget::Bind(Result* arg0, Result* arg1) {
+ ASSERT(cgen_ != NULL);
+
+#ifdef DEBUG
+ // We want register results at the call site to stay in the same
+ // registers.
+ bool had_entry_frame = false;
+ Result::Type arg0_type;
+ Register arg0_reg;
+ Result::Type arg1_type;
+ Register arg1_reg;
+#endif
+
+ if (cgen_->frame() != NULL) {
+#ifdef DEBUG
+ had_entry_frame = true;
+ arg0_type = arg0->type();
+ arg0_reg = arg0->is_register() ? arg0->reg() : no_reg;
+ arg1_type = arg1->type();
+ arg1_reg = arg1->is_register() ? arg1->reg() : no_reg;
+#endif
+ cgen_->frame()->Push(arg0);
+ cgen_->frame()->Push(arg1);
+ }
+ Bind();
+ *arg1 = cgen_->frame()->Pop();
+ *arg0 = cgen_->frame()->Pop();
+
+ ASSERT(!had_entry_frame || arg0->type() == arg0_type);
+ ASSERT(!had_entry_frame ||
+ !arg0->is_register() ||
+ arg0->reg().is(arg0_reg));
+ ASSERT(!had_entry_frame || arg1->type() == arg1_type);
+ ASSERT(!had_entry_frame ||
+ !arg1->is_register() ||
+ arg1->reg().is(arg1_reg));
}
Modified: branches/experimental/toiger/src/jump-target.h
==============================================================================
--- branches/experimental/toiger/src/jump-target.h (original)
+++ branches/experimental/toiger/src/jump-target.h Mon Dec 29 05:58:09 2008
@@ -98,11 +98,13 @@
// there must be one expected at the target.
void Branch(Condition cc, Hint hint = no_hint);
void Branch(Condition cc, Result* arg, Hint hint = no_hint);
+ void Branch(Condition cc, Result* arg0, Result* arg1, Hint hint =
no_hint);
// Bind a jump target. There must be a current frame and no expected
// frame at the target (targets are only bound once).
void Bind();
void Bind(Result* arg);
+ void Bind(Result* arg0, Result* arg1);
// Emit a call to a jump target. There must be a current frame. The
// frame at the target is the same as the current frame except for an
Modified: branches/experimental/toiger/src/virtual-frame-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.cc (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.cc Mon Dec 29
05:58:09 2008
@@ -132,6 +132,7 @@
void VirtualFrame::Spill(Register target) {
+ if (!frame_registers_.is_used(target)) return;
for (int i = 0; i < elements_.length(); i++) {
if (elements_[i].is_register() && elements_[i].reg().is(target)) {
SpillElementAt(i);
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---