Revision: 6936
Author: [email protected]
Date: Thu Feb 24 07:21:30 2011
Log: X64 Crankshaft: Implement Math.abs on x64 lithium.
Review URL: http://codereview.chromium.org/6576030
http://code.google.com/p/v8/source/detail?r=6936
Modified:
/branches/bleeding_edge/src/x64/assembler-x64.cc
/branches/bleeding_edge/src/x64/assembler-x64.h
/branches/bleeding_edge/src/x64/disasm-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.h
/branches/bleeding_edge/src/x64/macro-assembler-x64.cc
/branches/bleeding_edge/src/x64/macro-assembler-x64.h
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.cc Mon Feb 21 03:29:45
2011
+++ /branches/bleeding_edge/src/x64/assembler-x64.cc Thu Feb 24 07:21:30
2011
@@ -2993,6 +2993,28 @@
emit(0x5E);
emit_sse_operand(dst, src);
}
+
+
+void Assembler::andpd(XMMRegister dst, XMMRegister src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit(0x66);
+ emit_optional_rex_32(dst, src);
+ emit(0x0F);
+ emit(0x54);
+ emit_sse_operand(dst, src);
+}
+
+
+void Assembler::orpd(XMMRegister dst, XMMRegister src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit(0x66);
+ emit_optional_rex_32(dst, src);
+ emit(0x0F);
+ emit(0x56);
+ emit_sse_operand(dst, src);
+}
void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h Mon Feb 21 03:29:45 2011
+++ /branches/bleeding_edge/src/x64/assembler-x64.h Thu Feb 24 07:21:30 2011
@@ -1284,6 +1284,8 @@
void mulsd(XMMRegister dst, XMMRegister src);
void divsd(XMMRegister dst, XMMRegister src);
+ void andpd(XMMRegister dst, XMMRegister src);
+ void orpd(XMMRegister dst, XMMRegister src);
void xorpd(XMMRegister dst, XMMRegister src);
void sqrtsd(XMMRegister dst, XMMRegister src);
=======================================
--- /branches/bleeding_edge/src/x64/disasm-x64.cc Fri Feb 4 05:16:51 2011
+++ /branches/bleeding_edge/src/x64/disasm-x64.cc Thu Feb 24 07:21:30 2011
@@ -1040,14 +1040,18 @@
AppendToBuffer(", %s", NameOfXMMRegister(regop));
} else {
const char* mnemonic = "?";
- if (opcode == 0x57) {
+ if (opcode == 0x50) {
+ mnemonic = "movmskpd";
+ } else if (opcode == 0x54) {
+ mnemonic = "andpd";
+ } else if (opcode == 0x56) {
+ mnemonic = "orpd";
+ } else if (opcode == 0x57) {
mnemonic = "xorpd";
} else if (opcode == 0x2E) {
mnemonic = "ucomisd";
} else if (opcode == 0x2F) {
mnemonic = "comisd";
- } else if (opcode == 0x50) {
- mnemonic = "movmskpd";
} else {
UnimplementedInstruction();
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Feb 23
05:52:11 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu Feb 24
07:21:30 2011
@@ -2271,12 +2271,105 @@
void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation*
instr) {
- Abort("Unimplemented: %s", "DoDeferredMathAbsTaggedHeapNumber");
+ Register input_reg = ToRegister(instr->InputAt(0));
+ __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
+ Heap::kHeapNumberMapRootIndex);
+ DeoptimizeIf(not_equal, instr->environment());
+
+ Label done;
+ Register tmp = input_reg.is(rax) ? rcx : rax;
+ Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
+
+ // Preserve the value of all registers.
+ __ PushSafepointRegisters();
+
+ Label negative;
+ __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset));
+ // Check the sign of the argument. If the argument is positive, just
+ // return it. We do not need to patch the stack since |input| and
+ // |result| are the same register and |input| will be restored
+ // unchanged by popping safepoint registers.
+ __ testl(tmp, Immediate(HeapNumber::kSignMask));
+ __ j(not_zero, &negative);
+ __ jmp(&done);
+
+ __ bind(&negative);
+
+ Label allocated, slow;
+ __ AllocateHeapNumber(tmp, tmp2, &slow);
+ __ jmp(&allocated);
+
+ // Slow case: Call the runtime system to do the number allocation.
+ __ bind(&slow);
+
+ __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
+ RecordSafepointWithRegisters(
+ instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
+ // Set the pointer to the new heap number in tmp.
+ if (!tmp.is(rax)) {
+ __ movq(tmp, rax);
+ }
+
+ // Restore input_reg after call to runtime.
+ __ LoadFromSafepointRegisterSlot(input_reg, input_reg);
+
+ __ bind(&allocated);
+ __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
+ __ shl(tmp2, Immediate(1));
+ __ shr(tmp2, Immediate(1));
+ __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
+ __ StoreToSafepointRegisterSlot(input_reg, tmp);
+
+ __ bind(&done);
+ __ PopSafepointRegisters();
+}
+
+
+void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
+ Register input_reg = ToRegister(instr->InputAt(0));
+ __ testl(input_reg, input_reg);
+ Label is_positive;
+ __ j(not_sign, &is_positive);
+ __ negl(input_reg); // Sets flags.
+ DeoptimizeIf(negative, instr->environment());
+ __ bind(&is_positive);
}
void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
- Abort("Unimplemented: %s", "DoMathAbs");
+ // Class for deferred case.
+ class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
+ public:
+ DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
+ LUnaryMathOperation* instr)
+ : LDeferredCode(codegen), instr_(instr) { }
+ virtual void Generate() {
+ codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
+ }
+ private:
+ LUnaryMathOperation* instr_;
+ };
+
+ ASSERT(instr->InputAt(0)->Equals(instr->result()));
+ Representation r = instr->hydrogen()->value()->representation();
+
+ if (r.IsDouble()) {
+ XMMRegister scratch = xmm0;
+ XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
+ __ xorpd(scratch, scratch);
+ __ subsd(scratch, input_reg);
+ __ andpd(input_reg, scratch);
+ } else if (r.IsInteger32()) {
+ EmitIntegerMathAbs(instr);
+ } else { // Tagged case.
+ DeferredMathAbsTaggedHeapNumber* deferred =
+ new DeferredMathAbsTaggedHeapNumber(this, instr);
+ Register input_reg = ToRegister(instr->InputAt(0));
+ // Smi check.
+ __ JumpIfNotSmi(input_reg, deferred->entry());
+ EmitIntegerMathAbs(instr);
+ __ bind(deferred->exit());
+ }
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Wed Feb 23
02:10:47 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Thu Feb 24
07:21:30 2011
@@ -186,6 +186,7 @@
XMMRegister ToDoubleRegister(int index) const;
// Specific math operations - used from DoUnaryMathOperation.
+ void EmitIntegerMathAbs(LUnaryMathOperation* instr);
void DoMathAbs(LUnaryMathOperation* instr);
void DoMathFloor(LUnaryMathOperation* instr);
void DoMathRound(LUnaryMathOperation* instr);
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu Feb 24
03:36:14 2011
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Thu Feb 24
07:21:30 2011
@@ -1501,6 +1501,11 @@
void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register
src) {
movq(SafepointRegisterSlot(dst), src);
}
+
+
+void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register
src) {
+ movq(dst, SafepointRegisterSlot(src));
+}
Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.h Mon Feb 21
03:29:45 2011
+++ /branches/bleeding_edge/src/x64/macro-assembler-x64.h Thu Feb 24
07:21:30 2011
@@ -174,7 +174,7 @@
// Store the value in register src in the safepoint register stack
// slot for register dst.
void StoreToSafepointRegisterSlot(Register dst, Register src);
-
+ void LoadFromSafepointRegisterSlot(Register dst, Register src);
//
---------------------------------------------------------------------------
// JavaScript invokes
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev