Revision: 16246
Author: ol...@chromium.org
Date: Tue Aug 20 13:01:54 2013 UTC
Log: Add X87 implementations for Integer32ToDouble, DoubleToI,
DoubleToSmi
Additionally refactor the X87Stack tracking
BUG=
R=verwa...@chromium.org
Review URL: https://codereview.chromium.org/20781007
http://code.google.com/p/v8/source/detail?r=16246
Added:
/branches/bleeding_edge/test/mjsunit/regress/regress-x87.js
Modified:
/branches/bleeding_edge/src/ia32/assembler-ia32.cc
/branches/bleeding_edge/src/ia32/assembler-ia32.h
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
/branches/bleeding_edge/src/ia32/lithium-ia32.h
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-x87.js Tue Aug 20
13:01:54 2013 UTC
@@ -0,0 +1,48 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --noenable-sse2
+
+// Regression for register allocation.
+var x;
+var a = new Float32Array([1,2, 4, 6, 8, 11, NaN, 1/0, -3])
+var val = 2.1*a[1]*a[0]*a[1*2*3*0]*a[1*1]*1.0;
+assertEquals(8.4, val);
+
+// Regression for double-phis
+var a;
+var t = true;
+var res = [2.5, 2];
+for (var i = 0; i < 2; i++) {
+ if (t) {
+ a = 1.5;
+ } else {
+ a = true;
+ }
+ assertEquals(res[i], a+1);
+ t = false;
+}
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.cc Fri Aug 2 08:55:26
2013 UTC
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.cc Tue Aug 20 13:01:54
2013 UTC
@@ -1639,6 +1639,13 @@
EMIT(0xD9);
emit_operand(ebx, adr);
}
+
+
+void Assembler::fst_s(const Operand& adr) {
+ EnsureSpace ensure_space(this);
+ EMIT(0xD9);
+ emit_operand(edx, adr);
+}
void Assembler::fstp_d(const Operand& adr) {
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.h Thu Jul 11 13:07:04
2013 UTC
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.h Tue Aug 20 13:01:54
2013 UTC
@@ -929,6 +929,7 @@
void fld_d(const Operand& adr);
void fstp_s(const Operand& adr);
+ void fst_s(const Operand& adr);
void fstp_d(const Operand& adr);
void fst_d(const Operand& adr);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Aug 20
11:10:24 2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Aug 20
13:01:54 2013 UTC
@@ -359,10 +359,9 @@
instr->CompileToNative(this);
- if (!CpuFeatures::IsSupported(SSE2)) {
- if (FLAG_debug_code && FLAG_enable_slow_asserts) {
- __ VerifyX87StackDepth(x87_stack_depth_);
- }
+ if (!CpuFeatures::IsSupported(SSE2) &&
+ FLAG_debug_code && FLAG_enable_slow_asserts) {
+ __ VerifyX87StackDepth(x87_stack_.depth());
}
}
EnsureSpaceForLazyDeopt();
@@ -497,21 +496,21 @@
void LCodeGen::X87LoadForUsage(X87Register reg) {
- ASSERT(X87StackContains(reg));
- X87Fxch(reg);
- x87_stack_depth_--;
+ ASSERT(x87_stack_.Contains(reg));
+ x87_stack_.Fxch(reg);
+ x87_stack_.pop();
}
-void LCodeGen::X87Fxch(X87Register reg, int other_slot) {
- ASSERT(X87StackContains(reg) && x87_stack_depth_ > other_slot);
- int i = X87ArrayIndex(reg);
- int st = x87_st2idx(i);
+void LCodeGen::X87Stack::Fxch(X87Register reg, int other_slot) {
+ ASSERT(Contains(reg) && stack_depth_ > other_slot);
+ int i = ArrayIndex(reg);
+ int st = st2idx(i);
if (st != other_slot) {
- int other_i = x87_st2idx(other_slot);
- X87Register other = x87_stack_[other_i];
- x87_stack_[other_i] = reg;
- x87_stack_[i] = other;
+ int other_i = st2idx(other_slot);
+ X87Register other = stack_[other_i];
+ stack_[other_i] = reg;
+ stack_[i] = other;
if (st == 0) {
__ fxch(other_slot);
} else if (other_slot == 0) {
@@ -525,88 +524,101 @@
}
-int LCodeGen::x87_st2idx(int pos) {
- return x87_stack_depth_ - pos - 1;
+int LCodeGen::X87Stack::st2idx(int pos) {
+ return stack_depth_ - pos - 1;
}
-int LCodeGen::X87ArrayIndex(X87Register reg) {
- for (int i = 0; i < x87_stack_depth_; i++) {
- if (x87_stack_[i].is(reg)) return i;
+int LCodeGen::X87Stack::ArrayIndex(X87Register reg) {
+ for (int i = 0; i < stack_depth_; i++) {
+ if (stack_[i].is(reg)) return i;
}
UNREACHABLE();
return -1;
}
-bool LCodeGen::X87StackContains(X87Register reg) {
- for (int i = 0; i < x87_stack_depth_; i++) {
- if (x87_stack_[i].is(reg)) return true;
+bool LCodeGen::X87Stack::Contains(X87Register reg) {
+ for (int i = 0; i < stack_depth_; i++) {
+ if (stack_[i].is(reg)) return true;
}
return false;
}
-void LCodeGen::X87Free(X87Register reg) {
- ASSERT(X87StackContains(reg));
- int i = X87ArrayIndex(reg);
- int st = x87_st2idx(i);
+void LCodeGen::X87Stack::Free(X87Register reg) {
+ ASSERT(Contains(reg));
+ int i = ArrayIndex(reg);
+ int st = st2idx(i);
if (st > 0) {
// keep track of how fstp(i) changes the order of elements
- int tos_i = x87_st2idx(0);
- x87_stack_[i] = x87_stack_[tos_i];
+ int tos_i = st2idx(0);
+ stack_[i] = stack_[tos_i];
}
- x87_stack_depth_--;
+ pop();
__ fstp(st);
}
void LCodeGen::X87Mov(X87Register dst, Operand src, X87OperandType opts) {
- if (X87StackContains(dst)) {
- X87Fxch(dst);
+ if (x87_stack_.Contains(dst)) {
+ x87_stack_.Fxch(dst);
__ fstp(0);
} else {
- ASSERT(x87_stack_depth_ < X87Register::kNumAllocatableRegisters);
- x87_stack_[x87_stack_depth_] = dst;
- x87_stack_depth_++;
+ x87_stack_.push(dst);
}
X87Fld(src, opts);
}
void LCodeGen::X87Fld(Operand src, X87OperandType opts) {
- if (opts == kX87DoubleOperand) {
- __ fld_d(src);
- } else if (opts == kX87FloatOperand) {
- __ fld_s(src);
- } else if (opts == kX87IntOperand) {
- __ fild_s(src);
- } else {
- UNREACHABLE();
+ ASSERT(!src.is_reg_only());
+ switch (opts) {
+ case kX87DoubleOperand:
+ __ fld_d(src);
+ break;
+ case kX87FloatOperand:
+ __ fld_s(src);
+ break;
+ case kX87IntOperand:
+ __ fild_s(src);
+ break;
+ default:
+ UNREACHABLE();
}
}
-void LCodeGen::X87Mov(Operand dst, X87Register src) {
- X87Fxch(src);
- __ fst_d(dst);
+void LCodeGen::X87Mov(Operand dst, X87Register src, X87OperandType opts) {
+ ASSERT(!dst.is_reg_only());
+ x87_stack_.Fxch(src);
+ switch (opts) {
+ case kX87DoubleOperand:
+ __ fst_d(dst);
+ break;
+ case kX87IntOperand:
+ __ fist_s(dst);
+ break;
+ default:
+ UNREACHABLE();
+ }
}
-void LCodeGen::X87PrepareToWrite(X87Register reg) {
- if (X87StackContains(reg)) {
- X87Free(reg);
+void LCodeGen::X87Stack::PrepareToWrite(X87Register reg) {
+ if (Contains(reg)) {
+ Free(reg);
}
// Mark this register as the next register to write to
- x87_stack_[x87_stack_depth_] = reg;
+ stack_[stack_depth_] = reg;
}
-void LCodeGen::X87CommitWrite(X87Register reg) {
+void LCodeGen::X87Stack::CommitWrite(X87Register reg) {
// Assert the reg is prepared to write, but not on the virtual stack yet
- ASSERT(!X87StackContains(reg) && x87_stack_[x87_stack_depth_].is(reg) &&
- x87_stack_depth_ < X87Register::kNumAllocatableRegisters);
- x87_stack_depth_++;
+ ASSERT(!Contains(reg) && stack_[stack_depth_].is(reg) &&
+ stack_depth_ < X87Register::kNumAllocatableRegisters);
+ stack_depth_++;
}
@@ -614,38 +626,47 @@
X87Register left, X87Register right, X87Register result) {
// You need to use DefineSameAsFirst for x87 instructions
ASSERT(result.is(left));
- X87Fxch(right, 1);
- X87Fxch(left);
+ x87_stack_.Fxch(right, 1);
+ x87_stack_.Fxch(left);
}
-void LCodeGen::FlushX87StackIfNecessary(LInstruction* instr) {
- if (x87_stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) {
+void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen*
cgen) {
+ if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) {
bool double_inputs = instr->HasDoubleRegisterInput();
// Flush stack from tos down, since FreeX87() will mess with tos
- for (int i = x87_stack_depth_-1; i >= 0; i--) {
- X87Register reg = x87_stack_[i];
+ for (int i = stack_depth_-1; i >= 0; i--) {
+ X87Register reg = stack_[i];
// Skip registers which contain the inputs for the next instruction
// when flushing the stack
- if (double_inputs && instr->IsDoubleInput(reg, this)) {
+ if (double_inputs && instr->IsDoubleInput(reg, cgen)) {
continue;
}
- X87Free(reg);
- if (i < x87_stack_depth_-1) i++;
+ Free(reg);
+ if (i < stack_depth_-1) i++;
}
}
if (instr->IsReturn()) {
- while (x87_stack_depth_ > 0) {
+ while (stack_depth_ > 0) {
__ fstp(0);
- x87_stack_depth_--;
+ stack_depth_--;
}
}
}
void LCodeGen::EmitFlushX87ForDeopt() {
- for (int i = 0; i < x87_stack_depth_; i++) __ fstp(0);
+ // The deoptimizer does not support X87 Registers. But as long as we
+ // deopt from a stub its not a problem, since we will re-materialize the
+ // original stub inputs, which can't be double registers.
+ ASSERT(info()->IsStub());
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+ __ pushfd();
+ __ VerifyX87StackDepth(x87_stack_.depth());
+ __ popfd();
+ }
+ for (int i = 0; i < x87_stack_.depth(); i++) __ fstp(0);
}
@@ -1003,7 +1024,7 @@
// we can have inputs or outputs of the current instruction on the stack,
// thus we need to flush them here from the physical stack to leave it
in a
// consistent state.
- if (x87_stack_depth_ > 0) {
+ if (x87_stack_.depth() > 0) {
Label done;
if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear);
EmitFlushX87ForDeopt();
@@ -1865,15 +1886,16 @@
uint64_t int_val = BitCast<uint64_t, double>(v);
int32_t lower = static_cast<int32_t>(int_val);
int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
+ ASSERT(instr->result()->IsDoubleRegister());
if (!CpuFeatures::IsSafeForSnapshot(SSE2)) {
__ push(Immediate(upper));
__ push(Immediate(lower));
- X87Mov(ToX87Register(instr->result()), Operand(esp, 0));
+ X87Register reg = ToX87Register(instr->result());
+ X87Mov(reg, Operand(esp, 0));
__ add(Operand(esp), Immediate(kDoubleSize));
} else {
CpuFeatureScope scope1(masm(), SSE2);
- ASSERT(instr->result()->IsDoubleRegister());
XMMRegister res = ToDoubleRegister(instr->result());
if (int_val == 0) {
__ xorps(res, res);
@@ -2266,7 +2288,6 @@
void LCodeGen::DoBranch(LBranch* instr) {
Representation r = instr->hydrogen()->value()->representation();
if (r.IsSmiOrInteger32()) {
- ASSERT(!info()->IsStub());
Register reg = ToRegister(instr->value());
__ test(reg, Operand(reg));
EmitBranch(instr, not_zero);
@@ -4874,15 +4895,20 @@
void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
+ LOperand* input = instr->value();
+ LOperand* output = instr->result();
+ ASSERT(input->IsRegister() || input->IsStackSlot());
+ ASSERT(output->IsDoubleRegister());
if (CpuFeatures::IsSupported(SSE2)) {
CpuFeatureScope scope(masm(), SSE2);
- LOperand* input = instr->value();
- ASSERT(input->IsRegister() || input->IsStackSlot());
- LOperand* output = instr->result();
- ASSERT(output->IsDoubleRegister());
__ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
+ } else if (input->IsRegister()) {
+ Register input_reg = ToRegister(input);
+ __ push(input_reg);
+ X87Mov(ToX87Register(output), Operand(esp, 0), kX87IntOperand);
+ __ pop(input_reg);
} else {
- UNREACHABLE();
+ X87Mov(ToX87Register(output), ToOperand(input), kX87IntOperand);
}
}
@@ -5570,44 +5596,75 @@
ASSERT(input->IsDoubleRegister());
LOperand* result = instr->result();
ASSERT(result->IsRegister());
- CpuFeatureScope scope(masm(), SSE2);
+ Register result_reg = ToRegister(result);
- XMMRegister input_reg = ToDoubleRegister(input);
- Register result_reg = ToRegister(result);
+ Label done;
+ if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ CpuFeatureScope scope(masm(), SSE2);
+
+ XMMRegister input_reg = ToDoubleRegister(input);
- __ cvttsd2si(result_reg, Operand(input_reg));
+ __ cvttsd2si(result_reg, Operand(input_reg));
- if (instr->truncating()) {
- // Performs a truncating conversion of a floating point number as used
by
- // the JS bitwise operations.
- Label fast_case_succeeded;
- __ cmp(result_reg, 0x80000000u);
- __ j(not_equal, &fast_case_succeeded);
- __ sub(esp, Immediate(kDoubleSize));
- __ movdbl(MemOperand(esp, 0), input_reg);
- DoubleToIStub stub(esp, result_reg, 0, true);
- __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
- __ add(esp, Immediate(kDoubleSize));
- __ bind(&fast_case_succeeded);
+ if (instr->truncating()) {
+ // Performs a truncating conversion of a floating point number as
used by
+ // the JS bitwise operations.
+ Label fast_case_succeeded;
+ __ cmp(result_reg, 0x80000000u);
+ __ j(not_equal, &fast_case_succeeded);
+ __ sub(esp, Immediate(kDoubleSize));
+ __ movdbl(MemOperand(esp, 0), input_reg);
+ DoubleToIStub stub(esp, result_reg, 0, true);
+ __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
+ __ add(esp, Immediate(kDoubleSize));
+ __ bind(&fast_case_succeeded);
+ } else {
+ __ cvtsi2sd(xmm0, Operand(result_reg));
+ __ ucomisd(xmm0, input_reg);
+ DeoptimizeIf(not_equal, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment()); // NaN.
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ // The integer converted back is equal to the original. We
+ // only have to test if we got -0 as an input.
+ __ test(result_reg, Operand(result_reg));
+ __ j(not_zero, &done, Label::kNear);
+ __ movmskpd(result_reg, input_reg);
+ // Bit 0 contains the sign of the double in input_reg.
+ // If input was positive, we are ok and return 0, otherwise
+ // deoptimize.
+ __ and_(result_reg, 1);
+ DeoptimizeIf(not_zero, instr->environment());
+ }
+ __ bind(&done);
+ }
} else {
- Label done;
- __ cvtsi2sd(xmm0, Operand(result_reg));
- __ ucomisd(xmm0, input_reg);
- DeoptimizeIf(not_equal, instr->environment());
- DeoptimizeIf(parity_even, instr->environment()); // NaN.
+ X87Register input_reg = ToX87Register(input);
+ __ push(result_reg);
+ X87Mov(Operand(esp, 0), input_reg, kX87IntOperand);
+ if (instr->truncating()) {
+ __ pop(result_reg);
+ } else {
+ X87Fxch(input_reg);
+ __ fld(0);
+ __ fild_s(Operand(esp, 0));
+ __ pop(result_reg);
+ __ FCmp();
+ DeoptimizeIf(not_equal, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment()); // NaN.
+ }
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- // The integer converted back is equal to the original. We
- // only have to test if we got -0 as an input.
__ test(result_reg, Operand(result_reg));
__ j(not_zero, &done, Label::kNear);
- __ movmskpd(result_reg, input_reg);
- // Bit 0 contains the sign of the double in input_reg.
- // If input was positive, we are ok and return 0, otherwise
- // deoptimize.
- __ and_(result_reg, 1);
+ // To check for minus zero, we load the value again as float, and
check
+ // if that is still 0.
+ X87Fxch(input_reg);
+ __ push(result_reg);
+ __ fst_s(Operand(esp, 0));
+ __ pop(result_reg);
+ __ test(result_reg, Operand(result_reg));
DeoptimizeIf(not_zero, instr->environment());
+ __ bind(&done);
}
- __ bind(&done);
}
}
@@ -5617,30 +5674,56 @@
ASSERT(input->IsDoubleRegister());
LOperand* result = instr->result();
ASSERT(result->IsRegister());
- CpuFeatureScope scope(masm(), SSE2);
-
- XMMRegister input_reg = ToDoubleRegister(input);
Register result_reg = ToRegister(result);
Label done;
- __ cvttsd2si(result_reg, Operand(input_reg));
- __ cvtsi2sd(xmm0, Operand(result_reg));
- __ ucomisd(xmm0, input_reg);
- DeoptimizeIf(not_equal, instr->environment());
- DeoptimizeIf(parity_even, instr->environment()); // NaN.
+ if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
+ CpuFeatureScope scope(masm(), SSE2);
- if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- // The integer converted back is equal to the original. We
- // only have to test if we got -0 as an input.
- __ test(result_reg, Operand(result_reg));
- __ j(not_zero, &done, Label::kNear);
- __ movmskpd(result_reg, input_reg);
- // Bit 0 contains the sign of the double in input_reg.
- // If input was positive, we are ok and return 0, otherwise
- // deoptimize.
- __ and_(result_reg, 1);
- DeoptimizeIf(not_zero, instr->environment());
- __ bind(&done);
+ XMMRegister input_reg = ToDoubleRegister(input);
+
+ __ cvttsd2si(result_reg, Operand(input_reg));
+ __ cvtsi2sd(xmm0, Operand(result_reg));
+ __ ucomisd(xmm0, input_reg);
+ DeoptimizeIf(not_equal, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment()); // NaN.
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ // The integer converted back is equal to the original. We
+ // only have to test if we got -0 as an input.
+ __ test(result_reg, Operand(result_reg));
+ __ j(not_zero, &done, Label::kNear);
+ __ movmskpd(result_reg, input_reg);
+ // Bit 0 contains the sign of the double in input_reg.
+ // If input was positive, we are ok and return 0, otherwise
+ // deoptimize.
+ __ and_(result_reg, 1);
+ DeoptimizeIf(not_zero, instr->environment());
+ __ bind(&done);
+ }
+ } else {
+ X87Register input_reg = ToX87Register(input);
+ X87Fxch(input_reg);
+ __ push(result_reg);
+ X87Mov(Operand(esp, 0), input_reg, kX87IntOperand);
+ __ fld(0);
+ __ fild_s(Operand(esp, 0));
+ __ pop(result_reg);
+ __ FCmp();
+ DeoptimizeIf(not_equal, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment()); // NaN.
+
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ test(result_reg, Operand(result_reg));
+ __ j(not_zero, &done, Label::kNear);
+ // To check for minus zero, we load the value again as float, and
check
+ // if that is still 0.
+ __ push(result_reg);
+ __ fst_s(Operand(esp, 0));
+ __ pop(result_reg);
+ __ test(result_reg, Operand(result_reg));
+ DeoptimizeIf(not_zero, instr->environment());
+ __ bind(&done);
+ }
}
__ SmiTag(result_reg);
DeoptimizeIf(overflow, instr->environment());
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Tue Aug 20
11:10:24 2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Tue Aug 20
13:01:54 2013 UTC
@@ -68,7 +68,7 @@
osr_pc_offset_(-1),
last_lazy_deopt_pc_(0),
frame_is_built_(false),
- x87_stack_depth_(0),
+ x87_stack_(assembler),
safepoints_(info->zone()),
resolver_(this),
expected_safepoint_kind_(Safepoint::kSimple),
@@ -122,14 +122,23 @@
void X87Mov(X87Register reg, Operand src,
X87OperandType operand = kX87DoubleOperand);
- void X87Mov(Operand src, X87Register reg);
+ void X87Mov(Operand src, X87Register reg,
+ X87OperandType operand = kX87DoubleOperand);
void X87PrepareBinaryOp(
X87Register left, X87Register right, X87Register result);
void X87LoadForUsage(X87Register reg);
- void X87PrepareToWrite(X87Register reg);
- void X87CommitWrite(X87Register reg);
+ void X87PrepareToWrite(X87Register reg) {
x87_stack_.PrepareToWrite(reg); }
+ void X87CommitWrite(X87Register reg) { x87_stack_.CommitWrite(reg); }
+
+ void X87Fxch(X87Register reg, int other_slot = 0) {
+ x87_stack_.Fxch(reg, other_slot);
+ }
+
+ bool X87StackEmpty() {
+ return x87_stack_.depth() == 0;
+ }
Handle<Object> ToHandle(LConstantOperand* op) const;
@@ -399,15 +408,13 @@
// register, or a stack slot operand.
void EmitPushTaggedOperand(LOperand* operand);
- void X87Fxch(X87Register reg, int other_slot = 0);
void X87Fld(Operand src, X87OperandType opts);
- void X87Free(X87Register reg);
- void FlushX87StackIfNecessary(LInstruction* instr);
void EmitFlushX87ForDeopt();
- bool X87StackContains(X87Register reg);
- int X87ArrayIndex(X87Register reg);
- int x87_st2idx(int pos);
+ void FlushX87StackIfNecessary(LInstruction* instr) {
+ x87_stack_.FlushIfNecessary(instr, this);
+ }
+ friend class LGapResolver;
#ifdef _MSC_VER
// On windows, you may not access the stack more than one page below
@@ -438,8 +445,48 @@
int osr_pc_offset_;
int last_lazy_deopt_pc_;
bool frame_is_built_;
- X87Register x87_stack_[X87Register::kNumAllocatableRegisters];
- int x87_stack_depth_;
+
+ class X87Stack {
+ public:
+ explicit X87Stack(MacroAssembler* masm) : stack_depth_(0), masm_(masm)
{ }
+ explicit X87Stack(const X87Stack& other)
+ : stack_depth_(0), masm_(other.masm_) {
+ stack_depth_ = other.stack_depth_;
+ for (int i = 0; i < stack_depth_; i++) {
+ stack_[i] = other.stack_[i];
+ }
+ }
+ bool operator==(const X87Stack& other) const {
+ if (stack_depth_ != other.stack_depth_) return false;
+ for (int i = 0; i < stack_depth_; i++) {
+ if (!stack_[i].is(other.stack_[i])) return false;
+ }
+ return true;
+ }
+ bool Contains(X87Register reg);
+ void Fxch(X87Register reg, int other_slot = 0);
+ void Free(X87Register reg);
+ void PrepareToWrite(X87Register reg);
+ void CommitWrite(X87Register reg);
+ void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen);
+ int depth() const { return stack_depth_; }
+ void pop() { stack_depth_--; }
+ void push(X87Register reg) {
+ ASSERT(stack_depth_ < X87Register::kNumAllocatableRegisters);
+ stack_[stack_depth_] = reg;
+ stack_depth_++;
+ }
+
+ MacroAssembler* masm() const { return masm_; }
+
+ private:
+ int ArrayIndex(X87Register reg);
+ int st2idx(int pos);
+ X87Register stack_[X87Register::kNumAllocatableRegisters];
+ int stack_depth_;
+ MacroAssembler* const masm_;
+ };
+ X87Stack x87_stack_;
// Builder that keeps track of safepoints in the code. The table
// itself is emitted at the end of the generated code.
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue Aug 20 11:10:24
2013 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue Aug 20 13:01:54
2013 UTC
@@ -277,10 +277,9 @@
bool ClobbersRegisters() const { return IsCall(); }
virtual bool ClobbersDoubleRegisters() const {
return IsCall() ||
- (!CpuFeatures::IsSupported(SSE2) &&
- // We only have rudimentary X87Stack tracking, thus in general
- // cannot handle deoptimization nor phi-nodes.
- (HasEnvironment() || IsControl()));
+ // We only have rudimentary X87Stack tracking, thus in general
+ // cannot handle phi-nodes.
+ (!CpuFeatures::IsSafeForSnapshot(SSE2) && IsControl());
}
virtual bool HasResult() const = 0;
@@ -1541,11 +1540,6 @@
explicit LLoadNamedField(LOperand* object) {
inputs_[0] = object;
}
-
- virtual bool ClobbersDoubleRegisters() const {
- return !CpuFeatures::IsSupported(SSE2) &&
- !hydrogen()->representation().IsDouble();
- }
LOperand* object() { return inputs_[0]; }
@@ -2205,8 +2199,6 @@
LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
-
- virtual bool ClobbersDoubleRegisters() const V8_OVERRIDE { return false;
}
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
DECLARE_HYDROGEN_ACCESSOR(Change);
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.