OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 | 131 |
132 // Run the native code for the Array function called as a normal function. | 132 // Run the native code for the Array function called as a normal function. |
133 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); | 133 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); |
134 __ Mov(x3, x1); | 134 __ Mov(x3, x1); |
135 ArrayConstructorStub stub(masm->isolate()); | 135 ArrayConstructorStub stub(masm->isolate()); |
136 __ TailCallStub(&stub); | 136 __ TailCallStub(&stub); |
137 } | 137 } |
138 | 138 |
139 | 139 |
140 // static | 140 // static |
141 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { | |
142 // ----------- S t a t e ------------- | |
143 // -- x0 : number of arguments | |
144 // -- lr : return address | |
145 // -- sp[(argc - n) * 8] : arg[n] (zero-based) | |
146 // -- sp[(argc + 1) * 8] : receiver | |
147 // ----------------------------------- | |
148 ASM_LOCATION("Builtins::Generate_MathMaxMin"); | |
149 | |
150 Condition const cc_done = (kind == MathMaxMinKind::kMin) ? mi : gt; | |
151 Condition const cc_swap = (kind == MathMaxMinKind::kMin) ? gt : mi; | |
152 Heap::RootListIndex const root_index = | |
153 (kind == MathMaxMinKind::kMin) ? Heap::kInfinityValueRootIndex | |
154 : Heap::kMinusInfinityValueRootIndex; | |
155 DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1; | |
156 | |
157 // Load the accumulator with the default return value (either -Infinity or | |
158 // +Infinity), with the tagged value in x1 and the double value in d1. | |
159 __ LoadRoot(x1, root_index); | |
160 __ Ldr(d1, FieldMemOperand(x1, HeapNumber::kValueOffset)); | |
161 __ Mov(x4, x0); | |
jbramley
2016/01/28 18:15:35
x4 just seems to track how much we need to drop at
| |
162 | |
163 Label done_loop, loop; | |
164 __ Bind(&loop); | |
165 { | |
166 // Check if all parameters done. | |
167 __ Subs(x0, x0, 1); | |
168 __ B(lt, &done_loop); | |
169 | |
170 // Load the next parameter tagged value into x2. | |
171 __ Peek(x2, Operand(x0, LSL, kPointerSizeLog2)); | |
172 | |
173 // Load the double value of the parameter into d2, maybe converting the | |
174 // parameter to a number first using the ToNumberStub if necessary. | |
175 Label convert, convert_smi, convert_number, done_convert; | |
176 __ Bind(&convert); | |
177 __ JumpIfSmi(x2, &convert_smi); | |
178 __ Ldr(x3, FieldMemOperand(x2, HeapObject::kMapOffset)); | |
179 __ JumpIfRoot(x3, Heap::kHeapNumberMapRootIndex, &convert_number); | |
jbramley
2016/01/28 18:15:35
Ldr + JumpIfRoot can be JumpIfHeapNumber(x2, &conv
| |
180 { | |
181 // Parameter is not a Number, use the ToNumberStub to convert it. | |
182 FrameScope scope(masm, StackFrame::INTERNAL); | |
183 __ SmiTag(x0); | |
184 __ SmiTag(x4); | |
185 __ Push(x0, x1, x4); | |
186 __ Mov(x0, x2); | |
187 ToNumberStub stub(masm->isolate()); | |
188 __ CallStub(&stub); | |
189 __ Mov(x2, x0); | |
190 __ Pop(x4, x1, x0); | |
191 { | |
192 // Restore the double accumulator value (d1). | |
193 Label restore_smi, done_restore; | |
194 __ JumpIfSmi(x1, &restore_smi); | |
195 __ Ldr(d1, FieldMemOperand(x1, HeapNumber::kValueOffset)); | |
196 __ B(&done_restore); | |
197 __ Bind(&restore_smi); | |
198 __ SmiUntagToDouble(d1, x1); | |
199 __ bind(&done_restore); | |
jbramley
2016/01/28 18:15:35
Bind
| |
200 } | |
201 __ SmiUntag(x4); | |
202 __ SmiUntag(x0); | |
203 } | |
204 __ B(&convert); | |
205 __ Bind(&convert_number); | |
206 __ Ldr(d2, FieldMemOperand(x2, HeapNumber::kValueOffset)); | |
207 __ B(&done_convert); | |
208 __ Bind(&convert_smi); | |
209 __ SmiUntagToDouble(d2, x2); | |
jbramley
2016/01/28 18:15:35
If a smi argument is the common case, we could unt
| |
210 __ Bind(&done_convert); | |
211 | |
212 // Perform the actual comparison with the accumulator value on the left hand | |
213 // side (d1) and the next parameter value on the right hand side (d2). | |
214 Label compare_nan, compare_swap; | |
215 __ Fcmp(d1, d2); | |
jbramley
2016/01/28 18:15:35
I think this whole operation could be replaced wit
| |
216 __ B(cc_done, &loop); | |
217 __ B(cc_swap, &compare_swap); | |
218 __ B(vs, &compare_nan); | |
219 | |
220 // Left and right hand side are equal, check for -0 vs. +0. | |
221 __ Fmov(x3, reg); | |
222 __ TestAndBranchIfAllClear(x3, V8_INT64_C(0x8000000000000000), &loop); | |
223 | |
224 // Result is on the right hand side. | |
225 __ Bind(&compare_swap); | |
226 __ Fmov(d1, d2); | |
227 __ Mov(x1, x2); | |
228 __ B(&loop); | |
229 | |
230 // At least one side is NaN, which means that the result will be NaN too. | |
231 __ Bind(&compare_nan); | |
232 __ LoadRoot(x1, Heap::kNanValueRootIndex); | |
233 __ Ldr(d1, FieldMemOperand(x1, HeapNumber::kValueOffset)); | |
234 __ B(&loop); | |
235 } | |
236 | |
237 __ Bind(&done_loop); | |
238 __ Mov(x0, x1); | |
239 __ Drop(x4); | |
240 __ Drop(1); | |
241 __ Ret(); | |
242 } | |
243 | |
244 // static | |
141 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { | 245 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { |
142 // ----------- S t a t e ------------- | 246 // ----------- S t a t e ------------- |
143 // -- x0 : number of arguments | 247 // -- x0 : number of arguments |
144 // -- x1 : constructor function | 248 // -- x1 : constructor function |
145 // -- lr : return address | 249 // -- lr : return address |
146 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) | 250 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) |
147 // -- sp[argc * 8] : receiver | 251 // -- sp[argc * 8] : receiver |
148 // ----------------------------------- | 252 // ----------------------------------- |
149 ASM_LOCATION("Builtins::Generate_NumberConstructor"); | 253 ASM_LOCATION("Builtins::Generate_NumberConstructor"); |
150 | 254 |
(...skipping 2593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2744 } | 2848 } |
2745 } | 2849 } |
2746 | 2850 |
2747 | 2851 |
2748 #undef __ | 2852 #undef __ |
2749 | 2853 |
2750 } // namespace internal | 2854 } // namespace internal |
2751 } // namespace v8 | 2855 } // namespace v8 |
2752 | 2856 |
2753 #endif // V8_TARGET_ARCH_ARM | 2857 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |