OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 Condition const cc_swap = (kind == MathMaxMinKind::kMin) ? gt : mi; | 148 Condition const cc_swap = (kind == MathMaxMinKind::kMin) ? gt : mi; |
149 Heap::RootListIndex const root_index = | 149 Heap::RootListIndex const root_index = |
150 (kind == MathMaxMinKind::kMin) ? Heap::kInfinityValueRootIndex | 150 (kind == MathMaxMinKind::kMin) ? Heap::kInfinityValueRootIndex |
151 : Heap::kMinusInfinityValueRootIndex; | 151 : Heap::kMinusInfinityValueRootIndex; |
152 DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1; | 152 DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1; |
153 | 153 |
154 // Load the accumulator with the default return value (either -Infinity or | 154 // Load the accumulator with the default return value (either -Infinity or |
155 // +Infinity), with the tagged value in r1 and the double value in d1. | 155 // +Infinity), with the tagged value in r1 and the double value in d1. |
156 __ LoadRoot(r1, root_index); | 156 __ LoadRoot(r1, root_index); |
157 __ vldr(d1, FieldMemOperand(r1, HeapNumber::kValueOffset)); | 157 __ vldr(d1, FieldMemOperand(r1, HeapNumber::kValueOffset)); |
158 __ mov(r4, r0); | 158 |
| 159 // Remember how many slots to drop (including the receiver). |
| 160 __ add(r4, r0, Operand(1)); |
159 | 161 |
160 Label done_loop, loop; | 162 Label done_loop, loop; |
161 __ bind(&loop); | 163 __ bind(&loop); |
162 { | 164 { |
163 // Check if all parameters done. | 165 // Check if all parameters done. |
164 __ sub(r0, r0, Operand(1), SetCC); | 166 __ sub(r0, r0, Operand(1), SetCC); |
165 __ b(lt, &done_loop); | 167 __ b(lt, &done_loop); |
166 | 168 |
167 // Load the next parameter tagged value into r2. | 169 // Load the next parameter tagged value into r2. |
168 __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | 170 __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
169 | 171 |
170 // Load the double value of the parameter into d2, maybe converting the | 172 // Load the double value of the parameter into d2, maybe converting the |
171 // parameter to a number first using the ToNumberStub if necessary. | 173 // parameter to a number first using the ToNumberStub if necessary. |
172 Label convert, convert_smi, convert_number, done_convert; | 174 Label convert, convert_smi, convert_number, done_convert; |
173 __ bind(&convert); | 175 __ bind(&convert); |
174 __ JumpIfSmi(r2, &convert_smi); | 176 __ JumpIfSmi(r2, &convert_smi); |
175 __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | 177 __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); |
176 __ JumpIfRoot(r3, Heap::kHeapNumberMapRootIndex, &convert_number); | 178 __ JumpIfRoot(r3, Heap::kHeapNumberMapRootIndex, &convert_number); |
177 { | 179 { |
178 // Parameter is not a Number, use the ToNumberStub to convert it. | 180 // Parameter is not a Number, use the ToNumberStub to convert it. |
179 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 181 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
180 __ SmiTag(r0, r0); | 182 __ SmiTag(r0); |
181 __ SmiTag(r4, r4); | 183 __ SmiTag(r4); |
182 __ Push(r0, r1, r4); | 184 __ Push(r0, r1, r4); |
183 __ mov(r0, r2); | 185 __ mov(r0, r2); |
184 ToNumberStub stub(masm->isolate()); | 186 ToNumberStub stub(masm->isolate()); |
185 __ CallStub(&stub); | 187 __ CallStub(&stub); |
186 __ mov(r2, r0); | 188 __ mov(r2, r0); |
187 __ Pop(r0, r1, r4); | 189 __ Pop(r0, r1, r4); |
188 { | 190 { |
189 // Restore the double accumulator value (d1). | 191 // Restore the double accumulator value (d1). |
190 Label restore_smi, done_restore; | 192 Label done_restore; |
191 __ JumpIfSmi(r1, &restore_smi); | 193 __ SmiToDouble(d1, r1); |
| 194 __ JumpIfSmi(r1, &done_restore); |
192 __ vldr(d1, FieldMemOperand(r1, HeapNumber::kValueOffset)); | 195 __ vldr(d1, FieldMemOperand(r1, HeapNumber::kValueOffset)); |
193 __ b(&done_restore); | |
194 __ bind(&restore_smi); | |
195 __ SmiToDouble(d1, r1); | |
196 __ bind(&done_restore); | 196 __ bind(&done_restore); |
197 } | 197 } |
198 __ SmiUntag(r4); | 198 __ SmiUntag(r4); |
199 __ SmiUntag(r0); | 199 __ SmiUntag(r0); |
200 } | 200 } |
201 __ b(&convert); | 201 __ b(&convert); |
202 __ bind(&convert_number); | 202 __ bind(&convert_number); |
203 __ vldr(d2, FieldMemOperand(r2, HeapNumber::kValueOffset)); | 203 __ vldr(d2, FieldMemOperand(r2, HeapNumber::kValueOffset)); |
204 __ b(&done_convert); | 204 __ b(&done_convert); |
205 __ bind(&convert_smi); | 205 __ bind(&convert_smi); |
(...skipping 22 matching lines...) Expand all Loading... |
228 // At least one side is NaN, which means that the result will be NaN too. | 228 // At least one side is NaN, which means that the result will be NaN too. |
229 __ bind(&compare_nan); | 229 __ bind(&compare_nan); |
230 __ LoadRoot(r1, Heap::kNanValueRootIndex); | 230 __ LoadRoot(r1, Heap::kNanValueRootIndex); |
231 __ vldr(d1, FieldMemOperand(r1, HeapNumber::kValueOffset)); | 231 __ vldr(d1, FieldMemOperand(r1, HeapNumber::kValueOffset)); |
232 __ b(&loop); | 232 __ b(&loop); |
233 } | 233 } |
234 | 234 |
235 __ bind(&done_loop); | 235 __ bind(&done_loop); |
236 __ mov(r0, r1); | 236 __ mov(r0, r1); |
237 __ Drop(r4); | 237 __ Drop(r4); |
238 __ Ret(1); | 238 __ Ret(); |
239 } | 239 } |
240 | 240 |
241 // static | 241 // static |
242 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { | 242 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { |
243 // ----------- S t a t e ------------- | 243 // ----------- S t a t e ------------- |
244 // -- r0 : number of arguments | 244 // -- r0 : number of arguments |
245 // -- r1 : constructor function | 245 // -- r1 : constructor function |
246 // -- lr : return address | 246 // -- lr : return address |
247 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) | 247 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) |
248 // -- sp[argc * 4] : receiver | 248 // -- sp[argc * 4] : receiver |
(...skipping 2451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2700 } | 2700 } |
2701 } | 2701 } |
2702 | 2702 |
2703 | 2703 |
2704 #undef __ | 2704 #undef __ |
2705 | 2705 |
2706 } // namespace internal | 2706 } // namespace internal |
2707 } // namespace v8 | 2707 } // namespace v8 |
2708 | 2708 |
2709 #endif // V8_TARGET_ARCH_ARM | 2709 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |