[ia32/x64] Smaller instruction to check NaN
substract 1 and test for overflow BUG= R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/202083002 Patch from Weiliang Lin <weiliang.lin@intel.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20185 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8b8fb30e7f
commit
b7c3cd5e37
@ -2568,7 +2568,7 @@ void Assembler::RecordComment(const char* msg, bool force) {
|
||||
|
||||
|
||||
void Assembler::GrowBuffer() {
|
||||
ASSERT(overflow());
|
||||
ASSERT(buffer_overflow());
|
||||
if (!own_buffer_) FATAL("external code buffer is too small");
|
||||
|
||||
// Compute new buffer size.
|
||||
@ -2627,7 +2627,7 @@ void Assembler::GrowBuffer() {
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(!overflow());
|
||||
ASSERT(!buffer_overflow());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1170,7 +1170,9 @@ class Assembler : public AssemblerBase {
|
||||
// Check if there is less than kGap bytes available in the buffer.
|
||||
// If this is the case, we need to grow the buffer before emitting
|
||||
// an instruction or relocation information.
|
||||
inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; }
|
||||
inline bool buffer_overflow() const {
|
||||
return pc_ >= reloc_info_writer.pos() - kGap;
|
||||
}
|
||||
|
||||
// Get the number of bytes available in the buffer.
|
||||
inline int available_space() const { return reloc_info_writer.pos() - pc_; }
|
||||
@ -1272,7 +1274,7 @@ class Assembler : public AssemblerBase {
|
||||
class EnsureSpace BASE_EMBEDDED {
|
||||
public:
|
||||
explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
|
||||
if (assembler_->overflow()) assembler_->GrowBuffer();
|
||||
if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
|
||||
#ifdef DEBUG
|
||||
space_before_ = assembler_->available_space();
|
||||
#endif
|
||||
|
@ -845,8 +845,8 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(&try_arithmetic_simplification);
|
||||
// Skip to runtime if possibly NaN (indicated by the indefinite integer).
|
||||
__ cvttsd2si(exponent, Operand(double_exponent));
|
||||
__ cmp(exponent, Immediate(0x80000000u));
|
||||
__ j(equal, &call_runtime);
|
||||
__ cmp(exponent, Immediate(0x1));
|
||||
__ j(overflow, &call_runtime);
|
||||
|
||||
if (exponent_type_ == ON_STACK) {
|
||||
// Detect square root case. Crankshaft detects constant +/-0.5 at
|
||||
|
@ -3135,9 +3135,11 @@ void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
|
||||
|
||||
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
|
||||
__ CheckMap(eax, map, if_false, DO_SMI_CHECK);
|
||||
__ cmp(FieldOperand(eax, HeapNumber::kExponentOffset), Immediate(0x80000000));
|
||||
__ j(not_equal, if_false);
|
||||
__ cmp(FieldOperand(eax, HeapNumber::kMantissaOffset), Immediate(0x00000000));
|
||||
// Check if the exponent half is 0x80000000. Comparing against 1 and
|
||||
// checking for overflow is the shortest possible encoding.
|
||||
__ cmp(FieldOperand(eax, HeapNumber::kExponentOffset), Immediate(0x1));
|
||||
__ j(no_overflow, if_false);
|
||||
__ cmp(FieldOperand(eax, HeapNumber::kMantissaOffset), Immediate(0x0));
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
||||
|
@ -2654,8 +2654,8 @@ void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
|
||||
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
|
||||
__ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
|
||||
__ cmp(FieldOperand(value, HeapNumber::kExponentOffset),
|
||||
Immediate(0x80000000));
|
||||
EmitFalseBranch(instr, not_equal);
|
||||
Immediate(0x1));
|
||||
EmitFalseBranch(instr, no_overflow);
|
||||
__ cmp(FieldOperand(value, HeapNumber::kMantissaOffset),
|
||||
Immediate(0x00000000));
|
||||
EmitBranch(instr, equal);
|
||||
@ -3955,8 +3955,8 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) {
|
||||
__ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
|
||||
__ cvttsd2si(output_reg, Operand(xmm_scratch));
|
||||
// Overflow is signalled with minint.
|
||||
__ cmp(output_reg, 0x80000000u);
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
__ cmp(output_reg, 0x1);
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
} else {
|
||||
Label negative_sign, done;
|
||||
// Deoptimize on unordered.
|
||||
@ -3980,8 +3980,8 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) {
|
||||
// Use truncating instruction (OK because input is positive).
|
||||
__ cvttsd2si(output_reg, Operand(input_reg));
|
||||
// Overflow is signalled with minint.
|
||||
__ cmp(output_reg, 0x80000000u);
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
__ cmp(output_reg, 0x1);
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
__ jmp(&done, Label::kNear);
|
||||
|
||||
// Non-zero negative reaches here.
|
||||
@ -4020,9 +4020,9 @@ void LCodeGen::DoMathRound(LMathRound* instr) {
|
||||
__ addsd(xmm_scratch, input_reg);
|
||||
__ cvttsd2si(output_reg, Operand(xmm_scratch));
|
||||
// Overflow is signalled with minint.
|
||||
__ cmp(output_reg, 0x80000000u);
|
||||
__ cmp(output_reg, 0x1);
|
||||
__ RecordComment("D2I conversion overflow");
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
__ jmp(&done, dist);
|
||||
|
||||
__ bind(&below_one_half);
|
||||
@ -4036,9 +4036,9 @@ void LCodeGen::DoMathRound(LMathRound* instr) {
|
||||
__ subsd(input_temp, xmm_scratch);
|
||||
__ cvttsd2si(output_reg, Operand(input_temp));
|
||||
// Catch minint due to overflow, and to prevent overflow when compensating.
|
||||
__ cmp(output_reg, 0x80000000u);
|
||||
__ cmp(output_reg, 0x1);
|
||||
__ RecordComment("D2I conversion overflow");
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
|
||||
__ Cvtsi2sd(xmm_scratch, output_reg);
|
||||
__ ucomisd(xmm_scratch, input_temp);
|
||||
|
@ -214,14 +214,14 @@ void MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg,
|
||||
Register result_reg) {
|
||||
Label done;
|
||||
Label conv_failure;
|
||||
pxor(scratch_reg, scratch_reg);
|
||||
xorps(scratch_reg, scratch_reg);
|
||||
cvtsd2si(result_reg, input_reg);
|
||||
test(result_reg, Immediate(0xFFFFFF00));
|
||||
j(zero, &done, Label::kNear);
|
||||
cmp(result_reg, Immediate(0x80000000));
|
||||
j(equal, &conv_failure, Label::kNear);
|
||||
cmp(result_reg, Immediate(0x1));
|
||||
j(overflow, &conv_failure, Label::kNear);
|
||||
mov(result_reg, Immediate(0));
|
||||
setcc(above, result_reg);
|
||||
setcc(sign, result_reg);
|
||||
sub(result_reg, Immediate(1));
|
||||
and_(result_reg, Immediate(255));
|
||||
jmp(&done, Label::kNear);
|
||||
@ -256,8 +256,8 @@ void MacroAssembler::TruncateDoubleToI(Register result_reg,
|
||||
XMMRegister input_reg) {
|
||||
Label done;
|
||||
cvttsd2si(result_reg, Operand(input_reg));
|
||||
cmp(result_reg, 0x80000000u);
|
||||
j(not_equal, &done, Label::kNear);
|
||||
cmp(result_reg, 0x1);
|
||||
j(no_overflow, &done, Label::kNear);
|
||||
|
||||
sub(esp, Immediate(kDoubleSize));
|
||||
movsd(MemOperand(esp, 0), input_reg);
|
||||
@ -374,8 +374,8 @@ void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
|
||||
CpuFeatureScope scope(this, SSE2);
|
||||
movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
cvttsd2si(result_reg, Operand(xmm0));
|
||||
cmp(result_reg, 0x80000000u);
|
||||
j(not_equal, &done, Label::kNear);
|
||||
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();
|
||||
|
@ -709,8 +709,8 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(&try_arithmetic_simplification);
|
||||
__ cvttsd2si(exponent, double_exponent);
|
||||
// Skip to runtime if possibly NaN (indicated by the indefinite integer).
|
||||
__ cmpl(exponent, Immediate(0x80000000u));
|
||||
__ j(equal, &call_runtime);
|
||||
__ cmpl(exponent, Immediate(0x1));
|
||||
__ j(overflow, &call_runtime);
|
||||
|
||||
if (exponent_type_ == ON_STACK) {
|
||||
// Detect square root case. Crankshaft detects constant +/-0.5 at
|
||||
|
@ -3116,8 +3116,8 @@ void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
|
||||
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
|
||||
__ CheckMap(rax, map, if_false, DO_SMI_CHECK);
|
||||
__ cmpl(FieldOperand(rax, HeapNumber::kExponentOffset),
|
||||
Immediate(0x80000000));
|
||||
__ j(not_equal, if_false);
|
||||
Immediate(0x1));
|
||||
__ j(no_overflow, if_false);
|
||||
__ cmpl(FieldOperand(rax, HeapNumber::kMantissaOffset),
|
||||
Immediate(0x00000000));
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
|
@ -2261,8 +2261,8 @@ void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
|
||||
Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
|
||||
__ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
|
||||
__ cmpl(FieldOperand(value, HeapNumber::kExponentOffset),
|
||||
Immediate(0x80000000));
|
||||
EmitFalseBranch(instr, not_equal);
|
||||
Immediate(0x1));
|
||||
EmitFalseBranch(instr, no_overflow);
|
||||
__ cmpl(FieldOperand(value, HeapNumber::kMantissaOffset),
|
||||
Immediate(0x00000000));
|
||||
EmitBranch(instr, equal);
|
||||
@ -3577,8 +3577,8 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) {
|
||||
}
|
||||
__ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
|
||||
__ cvttsd2si(output_reg, xmm_scratch);
|
||||
__ cmpl(output_reg, Immediate(0x80000000));
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
__ cmpl(output_reg, Immediate(0x1));
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
} else {
|
||||
Label negative_sign, done;
|
||||
// Deoptimize on unordered.
|
||||
@ -3602,8 +3602,8 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) {
|
||||
// Use truncating instruction (OK because input is positive).
|
||||
__ cvttsd2si(output_reg, input_reg);
|
||||
// Overflow is signalled with minint.
|
||||
__ cmpl(output_reg, Immediate(0x80000000));
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
__ cmpl(output_reg, Immediate(0x1));
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
__ jmp(&done, Label::kNear);
|
||||
|
||||
// Non-zero negative reaches here.
|
||||
@ -3640,9 +3640,9 @@ void LCodeGen::DoMathRound(LMathRound* instr) {
|
||||
__ addsd(xmm_scratch, input_reg);
|
||||
__ cvttsd2si(output_reg, xmm_scratch);
|
||||
// Overflow is signalled with minint.
|
||||
__ cmpl(output_reg, Immediate(0x80000000));
|
||||
__ cmpl(output_reg, Immediate(0x1));
|
||||
__ RecordComment("D2I conversion overflow");
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
__ jmp(&done, dist);
|
||||
|
||||
__ bind(&below_one_half);
|
||||
@ -3657,9 +3657,9 @@ void LCodeGen::DoMathRound(LMathRound* instr) {
|
||||
__ subsd(input_temp, xmm_scratch);
|
||||
__ cvttsd2si(output_reg, input_temp);
|
||||
// Catch minint due to overflow, and to prevent overflow when compensating.
|
||||
__ cmpl(output_reg, Immediate(0x80000000));
|
||||
__ cmpl(output_reg, Immediate(0x1));
|
||||
__ RecordComment("D2I conversion overflow");
|
||||
DeoptimizeIf(equal, instr->environment());
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
|
||||
__ Cvtlsi2sd(xmm_scratch, output_reg);
|
||||
__ ucomisd(xmm_scratch, input_temp);
|
||||
@ -4691,8 +4691,8 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) {
|
||||
Register output = ToRegister(instr->result());
|
||||
if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
||||
hchange->value()->CheckFlag(HValue::kUint32)) {
|
||||
__ testl(input, Immediate(0x80000000));
|
||||
DeoptimizeIf(not_zero, instr->environment());
|
||||
__ testl(input, input);
|
||||
DeoptimizeIf(sign, instr->environment());
|
||||
}
|
||||
__ Integer32ToSmi(output, input);
|
||||
if (hchange->CheckFlag(HValue::kCanOverflow) &&
|
||||
@ -5087,7 +5087,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
|
||||
// conversions.
|
||||
__ Cmp(input_reg, factory()->undefined_value());
|
||||
DeoptimizeIf(not_equal, instr->environment());
|
||||
__ movp(input_reg, Immediate(0));
|
||||
__ xorl(input_reg, input_reg);
|
||||
__ jmp(&done, Label::kNear);
|
||||
|
||||
// Heap number
|
||||
|
@ -3154,10 +3154,10 @@ void MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg,
|
||||
cvtsd2si(result_reg, input_reg);
|
||||
testl(result_reg, Immediate(0xFFFFFF00));
|
||||
j(zero, &done, Label::kNear);
|
||||
cmpl(result_reg, Immediate(0x80000000));
|
||||
j(equal, &conv_failure, Label::kNear);
|
||||
cmpl(result_reg, Immediate(1));
|
||||
j(overflow, &conv_failure, Label::kNear);
|
||||
movl(result_reg, Immediate(0));
|
||||
setcc(above, result_reg);
|
||||
setcc(sign, result_reg);
|
||||
subl(result_reg, Immediate(1));
|
||||
andl(result_reg, Immediate(255));
|
||||
jmp(&done, Label::kNear);
|
||||
@ -3194,9 +3194,8 @@ void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
|
||||
Label done;
|
||||
movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
||||
cvttsd2siq(result_reg, xmm0);
|
||||
Set(kScratchRegister, V8_UINT64_C(0x8000000000000000));
|
||||
cmpq(result_reg, kScratchRegister);
|
||||
j(not_equal, &done, Label::kNear);
|
||||
cmpq(result_reg, Immediate(1));
|
||||
j(no_overflow, &done, Label::kNear);
|
||||
|
||||
// Slow case.
|
||||
if (input_reg.is(result_reg)) {
|
||||
@ -3216,9 +3215,8 @@ void MacroAssembler::TruncateDoubleToI(Register result_reg,
|
||||
XMMRegister input_reg) {
|
||||
Label done;
|
||||
cvttsd2siq(result_reg, input_reg);
|
||||
movq(kScratchRegister, V8_INT64_C(0x8000000000000000));
|
||||
cmpq(result_reg, kScratchRegister);
|
||||
j(not_equal, &done, Label::kNear);
|
||||
cmpq(result_reg, Immediate(1));
|
||||
j(no_overflow, &done, Label::kNear);
|
||||
|
||||
subp(rsp, Immediate(kDoubleSize));
|
||||
movsd(MemOperand(rsp, 0), input_reg);
|
||||
|
Loading…
Reference in New Issue
Block a user