X64 Crankshaft: Implement Math.abs on x64 lithium.

Review URL: http://codereview.chromium.org/6576030

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6936 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
whesse@chromium.org 2011-02-24 15:21:30 +00:00
parent 65e4a08793
commit 7560fa903b
7 changed files with 133 additions and 6 deletions

View File

@ -2995,6 +2995,28 @@ void Assembler::divsd(XMMRegister dst, XMMRegister 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) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;

View File

@ -1284,6 +1284,8 @@ class Assembler : public Malloced {
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);

View File

@ -1040,14 +1040,18 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
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();
}

View File

@ -2271,12 +2271,105 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
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());
}
}

View File

@ -186,6 +186,7 @@ class LCodeGen BASE_EMBEDDED {
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);

View File

@ -1503,6 +1503,11 @@ void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) {
}
void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
movq(dst, SafepointRegisterSlot(src));
}
Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
}

View File

@ -174,7 +174,7 @@ class MacroAssembler: public Assembler {
// 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