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 { |