X64 Crankshaft: Port TaggedToI to X64.
Review URL: http://codereview.chromium.org/6368097 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6637 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8a7889182e
commit
f1acd1299d
@ -3012,6 +3012,16 @@ void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
|
||||
}
|
||||
|
||||
|
||||
void Assembler::movmskpd(Register dst, XMMRegister src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
last_pc_ = pc_;
|
||||
emit(0x66);
|
||||
emit_optional_rex_32(dst, src);
|
||||
emit(0x0f);
|
||||
emit(0x50);
|
||||
emit_sse_operand(dst, src);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
|
||||
Register ireg = { reg.code() };
|
||||
|
@ -1270,6 +1270,8 @@ class Assembler : public Malloced {
|
||||
void ucomisd(XMMRegister dst, XMMRegister src);
|
||||
void ucomisd(XMMRegister dst, const Operand& src);
|
||||
|
||||
void movmskpd(Register dst, XMMRegister src);
|
||||
|
||||
// The first argument is the reg field, the second argument is the r/m field.
|
||||
void emit_sse_operand(XMMRegister dst, XMMRegister src);
|
||||
void emit_sse_operand(XMMRegister reg, const Operand& adr);
|
||||
|
@ -1046,6 +1046,8 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
|
||||
mnemonic = "ucomisd";
|
||||
} else if (opcode == 0x2F) {
|
||||
mnemonic = "comisd";
|
||||
} else if (opcode == 0x50) {
|
||||
mnemonic = "movmskpd";
|
||||
} else {
|
||||
UnimplementedInstruction();
|
||||
}
|
||||
|
@ -1954,13 +1954,73 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
|
||||
}
|
||||
|
||||
|
||||
class DeferredTaggedToI: public LDeferredCode {
|
||||
public:
|
||||
DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
|
||||
: LDeferredCode(codegen), instr_(instr) { }
|
||||
virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
|
||||
private:
|
||||
LTaggedToI* instr_;
|
||||
};
|
||||
|
||||
|
||||
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
|
||||
Abort("Unimplemented: %s", "DoDeferredTaggedToI");
|
||||
NearLabel done, heap_number;
|
||||
Register input_reg = ToRegister(instr->InputAt(0));
|
||||
|
||||
// Heap number map check.
|
||||
__ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
|
||||
Heap::kHeapNumberMapRootIndex);
|
||||
|
||||
if (instr->truncating()) {
|
||||
__ j(equal, &heap_number);
|
||||
// Check for undefined. Undefined is converted to zero for truncating
|
||||
// conversions.
|
||||
__ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ movl(input_reg, Immediate(0));
|
||||
__ jmp(&done);
|
||||
|
||||
__ bind(&heap_number);
|
||||
|
||||
__ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
__ cvttsd2siq(input_reg, xmm0);
|
||||
__ Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
|
||||
__ cmpl(input_reg, kScratchRegister);
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
} else {
|
||||
// Deoptimize if we don't have a heap number.
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
|
||||
XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
|
||||
__ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
__ cvttsd2si(input_reg, xmm0);
|
||||
__ cvtlsi2sd(xmm_temp, input_reg);
|
||||
__ ucomisd(xmm0, xmm_temp);
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
DeoptimizeIf(parity_even, instr->environment()); // NaN.
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
__ testl(input_reg, input_reg);
|
||||
__ j(not_zero, &done);
|
||||
__ movmskpd(input_reg, xmm0);
|
||||
__ andl(input_reg, Immediate(1));
|
||||
DeoptimizeIf(not_zero, instr->environment());
|
||||
}
|
||||
}
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
|
||||
Abort("Unimplemented: %s", "DoTaggedToI");
|
||||
LOperand* input = instr->InputAt(0);
|
||||
ASSERT(input->IsRegister());
|
||||
ASSERT(input->Equals(instr->result()));
|
||||
|
||||
Register input_reg = ToRegister(input);
|
||||
DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr);
|
||||
__ JumpIfNotSmi(input_reg, deferred->entry());
|
||||
__ SmiToInteger32(input_reg, input_reg);
|
||||
__ bind(deferred->exit());
|
||||
}
|
||||
|
||||
|
||||
@ -2217,7 +2277,6 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
|
||||
void LCodeGen::DoStackCheck(LStackCheck* instr) {
|
||||
// Perform stack overflow check.
|
||||
NearLabel done;
|
||||
ExternalReference stack_limit = ExternalReference::address_of_stack_limit();
|
||||
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
|
||||
__ j(above_equal, &done);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user