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:
parent
65e4a08793
commit
7560fa903b
@ -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_;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user