Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: src/x87/macro-assembler-x87.cc

Issue 293743005: Introduce x87 port (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: rebase Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/x87/macro-assembler-x87.h ('k') | src/x87/regexp-macro-assembler-x87.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x87/macro-assembler-x87.cc
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/x87/macro-assembler-x87.cc
similarity index 92%
copy from src/ia32/macro-assembler-ia32.cc
copy to src/x87/macro-assembler-x87.cc
index f96da485eb74b56f586940c9490235882129852e..04a9119023720f329ba8a6d66dbe139b2be24cec 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/x87/macro-assembler-x87.cc
@@ -4,7 +4,7 @@
#include "v8.h"
-#if V8_TARGET_ARCH_IA32
+#if V8_TARGET_ARCH_X87
#include "bootstrapper.h"
#include "codegen.h"
@@ -143,7 +143,6 @@ void MacroAssembler::RememberedSetHelper(
Register object, // Only used for debug checks.
Register addr,
Register scratch,
- SaveFPRegsMode save_fp,
MacroAssembler::RememberedSetFinalAction and_then) {
Label done;
if (emit_debug_code()) {
@@ -175,7 +174,7 @@ void MacroAssembler::RememberedSetHelper(
j(equal, &done, Label::kNear);
}
StoreBufferOverflowStub store_buffer_overflow =
- StoreBufferOverflowStub(isolate(), save_fp);
+ StoreBufferOverflowStub(isolate());
CallStub(&store_buffer_overflow);
if (and_then == kReturnAtEnd) {
ret(0);
@@ -186,31 +185,6 @@ void MacroAssembler::RememberedSetHelper(
}
-void MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg,
- XMMRegister scratch_reg,
- Register result_reg) {
- Label done;
- Label conv_failure;
- xorps(scratch_reg, scratch_reg);
- cvtsd2si(result_reg, input_reg);
- test(result_reg, Immediate(0xFFFFFF00));
- j(zero, &done, Label::kNear);
- cmp(result_reg, Immediate(0x1));
- j(overflow, &conv_failure, Label::kNear);
- mov(result_reg, Immediate(0));
- setcc(sign, result_reg);
- sub(result_reg, Immediate(1));
- and_(result_reg, Immediate(255));
- jmp(&done, Label::kNear);
- bind(&conv_failure);
- Move(result_reg, Immediate(0));
- ucomisd(input_reg, scratch_reg);
- j(below, &done, Label::kNear);
- Move(result_reg, Immediate(255));
- bind(&done);
-}
-
-
void MacroAssembler::ClampUint8(Register reg) {
Label done;
test(reg, Immediate(0xFFFFFF00));
@@ -229,47 +203,39 @@ void MacroAssembler::SlowTruncateToI(Register result_reg,
}
-void MacroAssembler::TruncateDoubleToI(Register result_reg,
- XMMRegister input_reg) {
- Label done;
- cvttsd2si(result_reg, Operand(input_reg));
- cmp(result_reg, 0x1);
- j(no_overflow, &done, Label::kNear);
-
+void MacroAssembler::TruncateX87TOSToI(Register result_reg) {
sub(esp, Immediate(kDoubleSize));
- movsd(MemOperand(esp, 0), input_reg);
+ fst_d(MemOperand(esp, 0));
SlowTruncateToI(result_reg, esp, 0);
add(esp, Immediate(kDoubleSize));
- bind(&done);
}
-void MacroAssembler::DoubleToI(Register result_reg,
- XMMRegister input_reg,
- XMMRegister scratch,
+void MacroAssembler::X87TOSToI(Register result_reg,
MinusZeroMode minus_zero_mode,
Label* conversion_failed,
Label::Distance dst) {
- ASSERT(!input_reg.is(scratch));
- cvttsd2si(result_reg, Operand(input_reg));
- Cvtsi2sd(scratch, Operand(result_reg));
- ucomisd(scratch, input_reg);
+ Label done;
+ sub(esp, Immediate(kPointerSize));
+ fld(0);
+ fist_s(MemOperand(esp, 0));
+ fild_s(MemOperand(esp, 0));
+ pop(result_reg);
+ FCmp();
j(not_equal, conversion_failed, dst);
- j(parity_even, conversion_failed, dst); // NaN.
+ j(parity_even, conversion_failed, dst);
if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
- Label done;
- // 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
- // jump to conversion_failed.
- and_(result_reg, 1);
+ // To check for minus zero, we load the value again as float, and check
+ // if that is still 0.
+ sub(esp, Immediate(kPointerSize));
+ fst_s(MemOperand(esp, 0));
+ pop(result_reg);
+ test(result_reg, Operand(result_reg));
j(not_zero, conversion_failed, dst);
- bind(&done);
}
+ bind(&done);
}
@@ -277,122 +243,76 @@ void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
Register input_reg) {
Label done, slow_case;
- if (CpuFeatures::IsSupported(SSE3)) {
- CpuFeatureScope scope(this, SSE3);
- Label convert;
- // Use more powerful conversion when sse3 is available.
- // Load x87 register with heap number.
- fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
- // Get exponent alone and check for too-big exponent.
- mov(result_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
- and_(result_reg, HeapNumber::kExponentMask);
- const uint32_t kTooBigExponent =
- (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
- cmp(Operand(result_reg), Immediate(kTooBigExponent));
- j(greater_equal, &slow_case, Label::kNear);
-
- // Reserve space for 64 bit answer.
- sub(Operand(esp), Immediate(kDoubleSize));
- // Do conversion, which cannot fail because we checked the exponent.
- fisttp_d(Operand(esp, 0));
- mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
- add(Operand(esp), Immediate(kDoubleSize));
- jmp(&done, Label::kNear);
-
- // Slow case.
- bind(&slow_case);
- if (input_reg.is(result_reg)) {
- // Input is clobbered. Restore number from fpu stack
- sub(Operand(esp), Immediate(kDoubleSize));
- fstp_d(Operand(esp, 0));
- SlowTruncateToI(result_reg, esp, 0);
- add(esp, Immediate(kDoubleSize));
- } else {
- fstp(0);
- SlowTruncateToI(result_reg, input_reg);
- }
- } else {
- movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
- cvttsd2si(result_reg, Operand(xmm0));
- cmp(result_reg, 0x1);
- j(no_overflow, &done, Label::kNear);
- // Check if the input was 0x8000000 (kMinInt).
- // If no, then we got an overflow and we deoptimize.
- ExternalReference min_int = ExternalReference::address_of_min_int();
- ucomisd(xmm0, Operand::StaticVariable(min_int));
- j(not_equal, &slow_case, Label::kNear);
- j(parity_even, &slow_case, Label::kNear); // NaN.
- jmp(&done, Label::kNear);
-
- // Slow case.
- bind(&slow_case);
- if (input_reg.is(result_reg)) {
- // Input is clobbered. Restore number from double scratch.
- sub(esp, Immediate(kDoubleSize));
- movsd(MemOperand(esp, 0), xmm0);
- SlowTruncateToI(result_reg, esp, 0);
- add(esp, Immediate(kDoubleSize));
- } else {
- SlowTruncateToI(result_reg, input_reg);
- }
- }
+ SlowTruncateToI(result_reg, input_reg);
bind(&done);
}
void MacroAssembler::TaggedToI(Register result_reg,
Register input_reg,
- XMMRegister temp,
MinusZeroMode minus_zero_mode,
Label* lost_precision) {
Label done;
- ASSERT(!temp.is(xmm0));
cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
isolate()->factory()->heap_number_map());
j(not_equal, lost_precision, Label::kNear);
- ASSERT(!temp.is(no_xmm_reg));
-
- movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
- cvttsd2si(result_reg, Operand(xmm0));
- Cvtsi2sd(temp, Operand(result_reg));
- ucomisd(xmm0, temp);
- RecordComment("Deferred TaggedToI: lost precision");
- j(not_equal, lost_precision, Label::kNear);
- RecordComment("Deferred TaggedToI: NaN");
- j(parity_even, lost_precision, Label::kNear);
+ // TODO(olivf) Converting a number on the fpu is actually quite slow. We
+ // should first try a fast conversion and then bailout to this slow case.
+ Label lost_precision_pop, zero_check;
+ Label* lost_precision_int = (minus_zero_mode == FAIL_ON_MINUS_ZERO)
+ ? &lost_precision_pop : lost_precision;
+ sub(esp, Immediate(kPointerSize));
+ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
+ if (minus_zero_mode == FAIL_ON_MINUS_ZERO) fld(0);
+ fist_s(MemOperand(esp, 0));
+ fild_s(MemOperand(esp, 0));
+ FCmp();
+ pop(result_reg);
+ j(not_equal, lost_precision_int, Label::kNear);
+ j(parity_even, lost_precision_int, Label::kNear); // NaN.
if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
test(result_reg, Operand(result_reg));
- j(not_zero, &done, Label::kNear);
- movmskpd(result_reg, xmm0);
- and_(result_reg, 1);
- RecordComment("Deferred TaggedToI: minus zero");
- j(not_zero, lost_precision, Label::kNear);
+ j(zero, &zero_check, Label::kNear);
+ fstp(0);
+ jmp(&done, Label::kNear);
+ bind(&zero_check);
+ // To check for minus zero, we load the value again as float, and check
+ // if that is still 0.
+ sub(esp, Immediate(kPointerSize));
+ fstp_s(Operand(esp, 0));
+ pop(result_reg);
+ test(result_reg, Operand(result_reg));
+ j(zero, &done, Label::kNear);
+ jmp(lost_precision, Label::kNear);
+
+ bind(&lost_precision_pop);
+ fstp(0);
+ jmp(lost_precision, Label::kNear);
}
bind(&done);
}
-void MacroAssembler::LoadUint32(XMMRegister dst,
- Register src,
- XMMRegister scratch) {
+void MacroAssembler::LoadUint32NoSSE2(Register src) {
Label done;
+ push(src);
+ fild_s(Operand(esp, 0));
cmp(src, Immediate(0));
+ j(not_sign, &done, Label::kNear);
ExternalReference uint32_bias =
ExternalReference::address_of_uint32_bias();
- movsd(scratch, Operand::StaticVariable(uint32_bias));
- Cvtsi2sd(dst, src);
- j(not_sign, &done, Label::kNear);
- addsd(dst, scratch);
+ fld_d(Operand::StaticVariable(uint32_bias));
+ faddp(1);
bind(&done);
+ add(esp, Immediate(kPointerSize));
}
void MacroAssembler::RecordWriteArray(Register object,
Register value,
Register index,
- SaveFPRegsMode save_fp,
RememberedSetAction remembered_set_action,
SmiCheck smi_check) {
// First, check if a write barrier is even needed. The tests below
@@ -414,7 +334,7 @@ void MacroAssembler::RecordWriteArray(Register object,
FixedArray::kHeaderSize - kHeapObjectTag));
RecordWrite(
- object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK);
+ object, dst, value, remembered_set_action, OMIT_SMI_CHECK);
bind(&done);
@@ -432,7 +352,6 @@ void MacroAssembler::RecordWriteField(
int offset,
Register value,
Register dst,
- SaveFPRegsMode save_fp,
RememberedSetAction remembered_set_action,
SmiCheck smi_check) {
// First, check if a write barrier is even needed. The tests below
@@ -458,7 +377,7 @@ void MacroAssembler::RecordWriteField(
}
RecordWrite(
- object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK);
+ object, dst, value, remembered_set_action, OMIT_SMI_CHECK);
bind(&done);
@@ -475,8 +394,7 @@ void MacroAssembler::RecordWriteForMap(
Register object,
Handle<Map> map,
Register scratch1,
- Register scratch2,
- SaveFPRegsMode save_fp) {
+ Register scratch2) {
Label done;
Register address = scratch1;
@@ -520,8 +438,7 @@ void MacroAssembler::RecordWriteForMap(
// them.
lea(address, FieldOperand(object, HeapObject::kMapOffset));
mov(value, Immediate(map));
- RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET,
- save_fp);
+ RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET);
CallStub(&stub);
bind(&done);
@@ -539,7 +456,6 @@ void MacroAssembler::RecordWriteForMap(
void MacroAssembler::RecordWrite(Register object,
Register address,
Register value,
- SaveFPRegsMode fp_mode,
RememberedSetAction remembered_set_action,
SmiCheck smi_check) {
ASSERT(!object.is(value));
@@ -586,8 +502,8 @@ void MacroAssembler::RecordWrite(Register object,
&done,
Label::kNear);
- RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
- fp_mode);
+ RecordWriteStub stub(isolate(), object, value, address,
+ remembered_set_action);
CallStub(&stub);
bind(&done);
@@ -609,12 +525,6 @@ void MacroAssembler::DebugBreak() {
}
-void MacroAssembler::Cvtsi2sd(XMMRegister dst, const Operand& src) {
- xorps(dst, dst);
- cvtsi2sd(dst, src);
-}
-
-
bool MacroAssembler::IsUnsafeImmediate(const Immediate& x) {
static const int kMaxImmediateBits = 17;
if (!RelocInfo::IsNone(x.rmode_)) return false;
@@ -700,8 +610,7 @@ void MacroAssembler::StoreNumberToDoubleElements(
Register maybe_number,
Register elements,
Register key,
- Register scratch1,
- XMMRegister scratch2,
+ Register scratch,
Label* fail,
int elements_offset) {
Label smi_value, done, maybe_nan, not_nan, is_nan, have_double_value;
@@ -721,11 +630,10 @@ void MacroAssembler::StoreNumberToDoubleElements(
bind(&not_nan);
ExternalReference canonical_nan_reference =
ExternalReference::address_of_canonical_non_hole_nan();
- movsd(scratch2, FieldOperand(maybe_number, HeapNumber::kValueOffset));
+ fld_d(FieldOperand(maybe_number, HeapNumber::kValueOffset));
bind(&have_double_value);
- movsd(FieldOperand(elements, key, times_4,
- FixedDoubleArray::kHeaderSize - elements_offset),
- scratch2);
+ fstp_d(FieldOperand(elements, key, times_4,
+ FixedDoubleArray::kHeaderSize - elements_offset));
jmp(&done);
bind(&maybe_nan);
@@ -735,18 +643,19 @@ void MacroAssembler::StoreNumberToDoubleElements(
cmp(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0));
j(zero, &not_nan);
bind(&is_nan);
- movsd(scratch2, Operand::StaticVariable(canonical_nan_reference));
+ fld_d(Operand::StaticVariable(canonical_nan_reference));
jmp(&have_double_value, Label::kNear);
bind(&smi_value);
// Value is a smi. Convert to a double and store.
// Preserve original value.
- mov(scratch1, maybe_number);
- SmiUntag(scratch1);
- Cvtsi2sd(scratch2, scratch1);
- movsd(FieldOperand(elements, key, times_4,
- FixedDoubleArray::kHeaderSize - elements_offset),
- scratch2);
+ mov(scratch, maybe_number);
+ SmiUntag(scratch);
+ push(scratch);
+ fild_s(Operand(esp, 0));
+ pop(scratch);
+ fstp_d(FieldOperand(elements, key, times_4,
+ FixedDoubleArray::kHeaderSize - elements_offset));
bind(&done);
}
@@ -827,8 +736,11 @@ void MacroAssembler::IsInstanceJSObjectType(Register map,
void MacroAssembler::FCmp() {
- fucomip();
- fstp(0);
+ fucompp();
+ push(eax);
+ fnstsw_ax();
+ sahf();
+ pop(eax);
}
@@ -969,20 +881,8 @@ void MacroAssembler::EnterExitFramePrologue() {
}
-void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) {
- // Optionally save all XMM registers.
- if (save_doubles) {
- int space = XMMRegister::kMaxNumRegisters * kDoubleSize +
- argc * kPointerSize;
- sub(esp, Immediate(space));
- const int offset = -2 * kPointerSize;
- for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
- XMMRegister reg = XMMRegister::from_code(i);
- movsd(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg);
- }
- } else {
- sub(esp, Immediate(argc * kPointerSize));
- }
+void MacroAssembler::EnterExitFrameEpilogue(int argc) {
+ sub(esp, Immediate(argc * kPointerSize));
// Get the required frame alignment for the OS.
const int kFrameAlignment = OS::ActivationFrameAlignment();
@@ -996,7 +896,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) {
}
-void MacroAssembler::EnterExitFrame(bool save_doubles) {
+void MacroAssembler::EnterExitFrame() {
EnterExitFramePrologue();
// Set up argc and argv in callee-saved registers.
@@ -1005,26 +905,17 @@ void MacroAssembler::EnterExitFrame(bool save_doubles) {
lea(esi, Operand(ebp, eax, times_4, offset));
// Reserve space for argc, argv and isolate.
- EnterExitFrameEpilogue(3, save_doubles);
+ EnterExitFrameEpilogue(3);
}
void MacroAssembler::EnterApiExitFrame(int argc) {
EnterExitFramePrologue();
- EnterExitFrameEpilogue(argc, false);
+ EnterExitFrameEpilogue(argc);
}
-void MacroAssembler::LeaveExitFrame(bool save_doubles) {
- // Optionally restore all XMM registers.
- if (save_doubles) {
- const int offset = -2 * kPointerSize;
- for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
- XMMRegister reg = XMMRegister::from_code(i);
- movsd(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize)));
- }
- }
-
+void MacroAssembler::LeaveExitFrame() {
// Get the return address from the stack and restore the frame pointer.
mov(ecx, Operand(ebp, 1 * kPointerSize));
mov(ebp, Operand(ebp, 0 * kPointerSize));
@@ -2077,8 +1968,7 @@ void MacroAssembler::IndexFromHash(Register hash, Register index) {
void MacroAssembler::CallRuntime(const Runtime::Function* f,
- int num_arguments,
- SaveFPRegsMode save_doubles) {
+ int num_arguments) {
// If the expected number of arguments of the runtime function is
// constant, we check that the actual number of arguments match the
// expectation.
@@ -2090,7 +1980,7 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f,
// smarter.
Move(eax, Immediate(num_arguments));
mov(ebx, Immediate(ExternalReference(f, isolate())));
- CEntryStub ces(isolate(), 1, save_doubles);
+ CEntryStub ces(isolate(), 1);
CallStub(&ces);
}
@@ -2639,6 +2529,27 @@ void MacroAssembler::Ret(int bytes_dropped, Register scratch) {
}
+void MacroAssembler::VerifyX87StackDepth(uint32_t depth) {
+ // Make sure the floating point stack is either empty or has depth items.
+ ASSERT(depth <= 7);
+ // This is very expensive.
+ ASSERT(FLAG_debug_code && FLAG_enable_slow_asserts);
+
+ // The top-of-stack (tos) is 7 if there is one item pushed.
+ int tos = (8 - depth) % 8;
+ const int kTopMask = 0x3800;
+ push(eax);
+ fwait();
+ fnstsw_ax();
+ and_(eax, kTopMask);
+ shr(eax, 11);
+ cmp(eax, Immediate(tos));
+ Check(equal, kUnexpectedFPUStackDepthAfterInstruction);
+ fnclex();
+ pop(eax);
+}
+
+
void MacroAssembler::Drop(int stack_elements) {
if (stack_elements > 0) {
add(esp, Immediate(stack_elements * kPointerSize));
@@ -2667,22 +2578,6 @@ void MacroAssembler::Move(const Operand& dst, const Immediate& x) {
}
-void MacroAssembler::Move(XMMRegister dst, double val) {
- // TODO(titzer): recognize double constants with ExternalReferences.
- uint64_t int_val = BitCast<uint64_t, double>(val);
- if (int_val == 0) {
- xorps(dst, dst);
- } else {
- int32_t lower = static_cast<int32_t>(int_val);
- int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt);
- push(Immediate(upper));
- push(Immediate(lower));
- movsd(dst, Operand(esp, 0));
- add(esp, Immediate(kDoubleSize));
- }
-}
-
-
void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
if (FLAG_native_code_counters && counter->Enabled()) {
mov(Operand::StaticVariable(ExternalReference(counter)), Immediate(value));
@@ -2870,17 +2765,6 @@ void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
}
-void MacroAssembler::LoadPowerOf2(XMMRegister dst,
- Register scratch,
- int power) {
- ASSERT(is_uintn(power + HeapNumber::kExponentBias,
- HeapNumber::kExponentBits));
- mov(scratch, Immediate(power + HeapNumber::kExponentBias));
- movd(dst, scratch);
- psllq(dst, HeapNumber::kMantissaBits);
-}
-
-
void MacroAssembler::LookupNumberStringCache(Register object,
Register result,
Register scratch1,
@@ -2928,8 +2812,9 @@ void MacroAssembler::LookupNumberStringCache(Register object,
times_twice_pointer_size,
FixedArray::kHeaderSize));
JumpIfSmi(probe, not_found);
- movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
- ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset));
+ fld_d(FieldOperand(object, HeapNumber::kValueOffset));
+ fld_d(FieldOperand(probe, HeapNumber::kValueOffset));
+ FCmp();
j(parity_even, not_found); // Bail out if NaN is involved.
j(not_equal, not_found); // The cache did not contain this value.
jmp(&load_result_from_cache, Label::kNear);
@@ -3465,4 +3350,4 @@ void MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) {
} } // namespace v8::internal
-#endif // V8_TARGET_ARCH_IA32
+#endif // V8_TARGET_ARCH_X87
« no previous file with comments | « src/x87/macro-assembler-x87.h ('k') | src/x87/regexp-macro-assembler-x87.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698