| Index: src/arm/macro-assembler-arm.cc
|
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
|
| index 616d02d867f015696dc2d8e65b2884f04ca7299b..ff72e3bba8fed90004092e9ab7b0a7ab31bab0fe 100644
|
| --- a/src/arm/macro-assembler-arm.cc
|
| +++ b/src/arm/macro-assembler-arm.cc
|
| @@ -790,6 +790,116 @@ void MacroAssembler::Vmov(const DwVfpRegister dst,
|
| }
|
|
|
|
|
| +void MacroAssembler::ConvertNumberToInt32(Register object,
|
| + Register dst,
|
| + Register heap_number_map,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Register scratch3,
|
| + DwVfpRegister double_scratch1,
|
| + DwVfpRegister double_scratch2,
|
| + Label* not_number) {
|
| + Label done;
|
| + UntagAndJumpIfSmi(dst, object, &done);
|
| + JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
|
| + vldr(double_scratch1, FieldMemOperand(object, HeapNumber::kValueOffset));
|
| + ECMAToInt32(dst, double_scratch1,
|
| + scratch1, scratch2, scratch3, double_scratch2);
|
| +
|
| + bind(&done);
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::LoadNumber(Register object,
|
| + DwVfpRegister dst,
|
| + Register heap_number_map,
|
| + Register scratch,
|
| + Label* not_number) {
|
| + Label is_smi, done;
|
| +
|
| + UntagAndJumpIfSmi(scratch, object, &is_smi);
|
| + JumpIfNotHeapNumber(object, heap_number_map, scratch, not_number);
|
| +
|
| + vldr(dst, FieldMemOperand(object, HeapNumber::kValueOffset));
|
| + b(&done);
|
| +
|
| + // Handle loading a double from a smi.
|
| + bind(&is_smi);
|
| + vmov(dst.high(), scratch);
|
| + vcvt_f64_s32(dst, dst.high());
|
| +
|
| + bind(&done);
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::LoadNumberAsInt32Double(Register object,
|
| + DwVfpRegister double_dst,
|
| + Register heap_number_map,
|
| + Register scratch,
|
| + DwVfpRegister double_scratch,
|
| + Label* not_int32) {
|
| + ASSERT(!scratch.is(object));
|
| + ASSERT(!heap_number_map.is(object) && !heap_number_map.is(scratch));
|
| +
|
| + Label done, obj_is_not_smi;
|
| +
|
| + UntagAndJumpIfNotSmi(scratch, object, &obj_is_not_smi);
|
| + vmov(double_scratch.low(), scratch);
|
| + vcvt_f64_s32(double_dst, double_scratch.low());
|
| + b(&done);
|
| +
|
| + bind(&obj_is_not_smi);
|
| + JumpIfNotHeapNumber(object, heap_number_map, scratch, not_int32);
|
| +
|
| + // Load the number.
|
| + // Load the double value.
|
| + vldr(double_dst, FieldMemOperand(object, HeapNumber::kValueOffset));
|
| +
|
| + TestDoubleIsInt32(double_dst, double_scratch);
|
| + // Jump to not_int32 if the operation did not succeed.
|
| + b(ne, not_int32);
|
| +
|
| + bind(&done);
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::LoadNumberAsInt32(Register object,
|
| + Register dst,
|
| + Register heap_number_map,
|
| + Register scratch,
|
| + DwVfpRegister double_scratch0,
|
| + DwVfpRegister double_scratch1,
|
| + Label* not_int32) {
|
| + ASSERT(!dst.is(object));
|
| + ASSERT(!scratch.is(object));
|
| +
|
| + Label done, maybe_undefined;
|
| +
|
| + UntagAndJumpIfSmi(dst, object, &done);
|
| +
|
| + JumpIfNotHeapNumber(object, heap_number_map, scratch, &maybe_undefined);
|
| +
|
| + // Object is a heap number.
|
| + // Convert the floating point value to a 32-bit integer.
|
| + // Load the double value.
|
| + vldr(double_scratch0, FieldMemOperand(object, HeapNumber::kValueOffset));
|
| +
|
| + TryDoubleToInt32Exact(dst, double_scratch0, double_scratch1);
|
| + // Jump to not_int32 if the operation did not succeed.
|
| + b(ne, not_int32);
|
| + b(&done);
|
| +
|
| + bind(&maybe_undefined);
|
| + CompareRoot(object, Heap::kUndefinedValueRootIndex);
|
| + b(ne, not_int32);
|
| + // |undefined| is truncated to 0.
|
| + mov(dst, Operand(Smi::FromInt(0)));
|
| + // Fall through.
|
| +
|
| + bind(&done);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::EnterFrame(StackFrame::Type type) {
|
| // r0-r3: preserved
|
| stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
|
| @@ -1945,14 +2055,9 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
|
| Register key_reg,
|
| Register elements_reg,
|
| Register scratch1,
|
| - Register scratch2,
|
| - Register scratch3,
|
| - Register scratch4,
|
| Label* fail,
|
| int elements_offset) {
|
| Label smi_value, store;
|
| - Register mantissa_reg = scratch2;
|
| - Register exponent_reg = scratch3;
|
|
|
| // Handle smi values specially.
|
| JumpIfSmi(value_reg, &smi_value);
|
| @@ -1977,9 +2082,8 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
|
| bind(&smi_value);
|
| Register untagged_value = scratch1;
|
| SmiUntag(untagged_value, value_reg);
|
| - FloatingPointHelper::ConvertIntToDouble(
|
| - this, untagged_value, FloatingPointHelper::kVFPRegisters, d0,
|
| - mantissa_reg, exponent_reg, scratch4, s2);
|
| + vmov(s2, untagged_value);
|
| + vcvt_f64_s32(d0, s2);
|
|
|
| bind(&store);
|
| add(scratch1, elements_reg,
|
| @@ -2401,34 +2505,21 @@ void MacroAssembler::TryInt32Floor(Register result,
|
| }
|
|
|
|
|
| -void MacroAssembler::ECMAConvertNumberToInt32(Register source,
|
| - Register result,
|
| - Register input_low,
|
| - Register input_high,
|
| - Register scratch,
|
| - DwVfpRegister double_scratch1,
|
| - DwVfpRegister double_scratch2) {
|
| - vldr(double_scratch1, FieldMemOperand(source, HeapNumber::kValueOffset));
|
| - ECMAToInt32(result, double_scratch1, double_scratch2,
|
| - scratch, input_high, input_low);
|
| -}
|
| -
|
| -
|
| void MacroAssembler::ECMAToInt32(Register result,
|
| DwVfpRegister double_input,
|
| - DwVfpRegister double_scratch,
|
| Register scratch,
|
| - Register input_high,
|
| - Register input_low) {
|
| - ASSERT(!input_high.is(result));
|
| - ASSERT(!input_low.is(result));
|
| - ASSERT(!input_low.is(input_high));
|
| + Register scratch_high,
|
| + Register scratch_low,
|
| + DwVfpRegister double_scratch) {
|
| + ASSERT(!scratch_high.is(result));
|
| + ASSERT(!scratch_low.is(result));
|
| + ASSERT(!scratch_low.is(scratch_high));
|
| ASSERT(!scratch.is(result) &&
|
| - !scratch.is(input_high) &&
|
| - !scratch.is(input_low));
|
| + !scratch.is(scratch_high) &&
|
| + !scratch.is(scratch_low));
|
| ASSERT(!double_input.is(double_scratch));
|
|
|
| - Label out_of_range, negate, done;
|
| + Label out_of_range, only_low, negate, done;
|
|
|
| vcvt_s32_f64(double_scratch.low(), double_input);
|
| vmov(result, double_scratch.low());
|
| @@ -2438,8 +2529,8 @@ void MacroAssembler::ECMAToInt32(Register result,
|
| cmp(scratch, Operand(0x7ffffffe));
|
| b(lt, &done);
|
|
|
| - vmov(input_low, input_high, double_input);
|
| - Ubfx(scratch, input_high,
|
| + vmov(scratch_low, scratch_high, double_input);
|
| + Ubfx(scratch, scratch_high,
|
| HeapNumber::kExponentShift, HeapNumber::kExponentBits);
|
| // Load scratch with exponent - 1. This is faster than loading
|
| // with exponent because Bias + 1 = 1024 which is an *ARM* immediate value.
|
| @@ -2454,59 +2545,45 @@ void MacroAssembler::ECMAToInt32(Register result,
|
| // If we reach this code, 31 <= exponent <= 83.
|
| // So, we don't have to handle cases where 0 <= exponent <= 20 for
|
| // which we would need to shift right the high part of the mantissa.
|
| - ECMAToInt32Tail(result, scratch, input_high, input_low,
|
| - &out_of_range, &negate, &done);
|
| -}
|
| -
|
| -
|
| -void MacroAssembler::ECMAToInt32Tail(Register result,
|
| - Register scratch,
|
| - Register input_high,
|
| - Register input_low,
|
| - Label* out_of_range,
|
| - Label* negate,
|
| - Label* done) {
|
| - Label only_low;
|
| -
|
| - // On entry, scratch contains exponent - 1.
|
| + // Scratch contains exponent - 1.
|
| // Load scratch with 52 - exponent (load with 51 - (exponent - 1)).
|
| rsb(scratch, scratch, Operand(51), SetCC);
|
| b(ls, &only_low);
|
| - // 21 <= exponent <= 51, shift input_low and input_high
|
| + // 21 <= exponent <= 51, shift scratch_low and scratch_high
|
| // to generate the result.
|
| - mov(input_low, Operand(input_low, LSR, scratch));
|
| + mov(scratch_low, Operand(scratch_low, LSR, scratch));
|
| // Scratch contains: 52 - exponent.
|
| // We needs: exponent - 20.
|
| // So we use: 32 - scratch = 32 - 52 + exponent = exponent - 20.
|
| rsb(scratch, scratch, Operand(32));
|
| - Ubfx(result, input_high,
|
| + Ubfx(result, scratch_high,
|
| 0, HeapNumber::kMantissaBitsInTopWord);
|
| - // Set the implicit 1 before the mantissa part in input_high.
|
| + // Set the implicit 1 before the mantissa part in scratch_high.
|
| orr(result, result, Operand(1 << HeapNumber::kMantissaBitsInTopWord));
|
| - orr(result, input_low, Operand(result, LSL, scratch));
|
| - b(negate);
|
| + orr(result, scratch_low, Operand(result, LSL, scratch));
|
| + b(&negate);
|
|
|
| - bind(out_of_range);
|
| + bind(&out_of_range);
|
| mov(result, Operand::Zero());
|
| - b(done);
|
| + b(&done);
|
|
|
| bind(&only_low);
|
| - // 52 <= exponent <= 83, shift only input_low.
|
| + // 52 <= exponent <= 83, shift only scratch_low.
|
| // On entry, scratch contains: 52 - exponent.
|
| rsb(scratch, scratch, Operand::Zero());
|
| - mov(result, Operand(input_low, LSL, scratch));
|
| + mov(result, Operand(scratch_low, LSL, scratch));
|
|
|
| - bind(negate);
|
| - // If input was positive, input_high ASR 31 equals 0 and
|
| - // input_high LSR 31 equals zero.
|
| + bind(&negate);
|
| + // If input was positive, scratch_high ASR 31 equals 0 and
|
| + // scratch_high LSR 31 equals zero.
|
| // New result = (result eor 0) + 0 = result.
|
| // If the input was negative, we have to negate the result.
|
| - // Input_high ASR 31 equals 0xffffffff and input_high LSR 31 equals 1.
|
| + // Input_high ASR 31 equals 0xffffffff and scratch_high LSR 31 equals 1.
|
| // New result = (result eor 0xffffffff) + 1 = 0 - result.
|
| - eor(result, result, Operand(input_high, ASR, 31));
|
| - add(result, result, Operand(input_high, LSR, 31));
|
| + eor(result, result, Operand(scratch_high, ASR, 31));
|
| + add(result, result, Operand(scratch_high, LSR, 31));
|
|
|
| - bind(done);
|
| + bind(&done);
|
| }
|
|
|
|
|
| @@ -2688,16 +2765,6 @@ void MacroAssembler::Assert(Condition cond, const char* msg) {
|
| }
|
|
|
|
|
| -void MacroAssembler::AssertRegisterIsRoot(Register reg,
|
| - Heap::RootListIndex index) {
|
| - if (emit_debug_code()) {
|
| - LoadRoot(ip, index);
|
| - cmp(reg, ip);
|
| - Check(eq, "Register did not match expected root");
|
| - }
|
| -}
|
| -
|
| -
|
| void MacroAssembler::AssertFastElements(Register elements) {
|
| if (emit_debug_code()) {
|
| ASSERT(!elements.is(ip));
|
| @@ -2991,12 +3058,10 @@ void MacroAssembler::AssertName(Register object) {
|
|
|
|
|
|
|
| -void MacroAssembler::AssertRootValue(Register src,
|
| - Heap::RootListIndex root_value_index,
|
| - const char* message) {
|
| +void MacroAssembler::AssertIsRoot(Register reg, Heap::RootListIndex index) {
|
| if (emit_debug_code()) {
|
| - CompareRoot(src, root_value_index);
|
| - Check(eq, message);
|
| + CompareRoot(reg, index);
|
| + Check(eq, "HeapNumberMap register clobbered.");
|
| }
|
| }
|
|
|
| @@ -3006,7 +3071,7 @@ void MacroAssembler::JumpIfNotHeapNumber(Register object,
|
| Register scratch,
|
| Label* on_not_heap_number) {
|
| ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
|
| - AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
| + AssertIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
| cmp(scratch, heap_number_map);
|
| b(ne, on_not_heap_number);
|
| }
|
| @@ -3063,7 +3128,7 @@ void MacroAssembler::AllocateHeapNumber(Register result,
|
| tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS);
|
|
|
| // Store heap number map in the allocated object.
|
| - AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
| + AssertIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
| if (tagging_mode == TAG_RESULT) {
|
| str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset));
|
| } else {
|
|
|