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_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 // Load the double value of the parameter into f2, maybe converting the | 160 // Load the double value of the parameter into f2, maybe converting the |
161 // parameter to a number first using the ToNumber builtin if necessary. | 161 // parameter to a number first using the ToNumber builtin if necessary. |
162 Label convert, convert_smi, convert_number, done_convert; | 162 Label convert, convert_smi, convert_number, done_convert; |
163 __ bind(&convert); | 163 __ bind(&convert); |
164 __ JumpIfSmi(a2, &convert_smi); | 164 __ JumpIfSmi(a2, &convert_smi); |
165 __ ld(a4, FieldMemOperand(a2, HeapObject::kMapOffset)); | 165 __ ld(a4, FieldMemOperand(a2, HeapObject::kMapOffset)); |
166 __ JumpIfRoot(a4, Heap::kHeapNumberMapRootIndex, &convert_number); | 166 __ JumpIfRoot(a4, Heap::kHeapNumberMapRootIndex, &convert_number); |
167 { | 167 { |
168 // Parameter is not a Number, use the ToNumber builtin to convert it. | 168 // Parameter is not a Number, use the ToNumber builtin to convert it. |
169 FrameScope scope(masm, StackFrame::MANUAL); | 169 FrameScope scope(masm, StackFrame::MANUAL); |
170 __ Push(ra, fp); | |
171 __ Move(fp, sp); | |
172 __ Push(cp, a1); | |
173 __ SmiTag(a0); | 170 __ SmiTag(a0); |
174 __ SmiTag(a3); | 171 __ SmiTag(a3); |
175 __ Push(a0, t1, a3); | 172 __ EnterBuiltinFrame(cp, a1, a0); |
| 173 __ Push(t1, a3); |
176 __ mov(a0, a2); | 174 __ mov(a0, a2); |
177 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); | 175 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); |
178 __ mov(a2, v0); | 176 __ mov(a2, v0); |
179 __ Pop(a0, t1, a3); | 177 __ Pop(t1, a3); |
| 178 __ LeaveBuiltinFrame(cp, a1, a0); |
| 179 __ SmiUntag(a3); |
| 180 __ SmiUntag(a0); |
180 { | 181 { |
181 // Restore the double accumulator value (f0). | 182 // Restore the double accumulator value (f0). |
182 Label restore_smi, done_restore; | 183 Label restore_smi, done_restore; |
183 __ JumpIfSmi(t1, &restore_smi); | 184 __ JumpIfSmi(t1, &restore_smi); |
184 __ ldc1(f0, FieldMemOperand(t1, HeapNumber::kValueOffset)); | 185 __ ldc1(f0, FieldMemOperand(t1, HeapNumber::kValueOffset)); |
185 __ jmp(&done_restore); | 186 __ jmp(&done_restore); |
186 __ bind(&restore_smi); | 187 __ bind(&restore_smi); |
187 __ SmiToDoubleFPURegister(t1, f0, a4); | 188 __ SmiToDoubleFPURegister(t1, f0, a4); |
188 __ bind(&done_restore); | 189 __ bind(&done_restore); |
189 } | 190 } |
190 __ SmiUntag(a3); | |
191 __ SmiUntag(a0); | |
192 __ Pop(cp, a1); | |
193 __ Pop(ra, fp); | |
194 } | 191 } |
195 __ jmp(&convert); | 192 __ jmp(&convert); |
196 __ bind(&convert_number); | 193 __ bind(&convert_number); |
197 __ ldc1(f2, FieldMemOperand(a2, HeapNumber::kValueOffset)); | 194 __ ldc1(f2, FieldMemOperand(a2, HeapNumber::kValueOffset)); |
198 __ jmp(&done_convert); | 195 __ jmp(&done_convert); |
199 __ bind(&convert_smi); | 196 __ bind(&convert_smi); |
200 __ SmiToDoubleFPURegister(a2, f2, a4); | 197 __ SmiToDoubleFPURegister(a2, f2, a4); |
201 __ bind(&done_convert); | 198 __ bind(&done_convert); |
202 | 199 |
203 // Perform the actual comparison with using Min/Max macro instructions the | 200 // Perform the actual comparison with using Min/Max macro instructions the |
(...skipping 27 matching lines...) Expand all Loading... |
231 __ Dlsa(sp, sp, a0, kPointerSizeLog2); | 228 __ Dlsa(sp, sp, a0, kPointerSizeLog2); |
232 __ Ret(USE_DELAY_SLOT); | 229 __ Ret(USE_DELAY_SLOT); |
233 __ mov(v0, t1); // In delay slot. | 230 __ mov(v0, t1); // In delay slot. |
234 } | 231 } |
235 | 232 |
236 // static | 233 // static |
237 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { | 234 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { |
238 // ----------- S t a t e ------------- | 235 // ----------- S t a t e ------------- |
239 // -- a0 : number of arguments | 236 // -- a0 : number of arguments |
240 // -- a1 : constructor function | 237 // -- a1 : constructor function |
| 238 // -- cp : context |
241 // -- ra : return address | 239 // -- ra : return address |
242 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) | 240 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) |
243 // -- sp[argc * 8] : receiver | 241 // -- sp[argc * 8] : receiver |
244 // ----------------------------------- | 242 // ----------------------------------- |
245 | 243 |
246 // 1. Load the first argument into a0 and get rid of the rest (including the | 244 // 1. Load the first argument into a0 and get rid of the rest (including the |
247 // receiver). | 245 // receiver). |
248 Label no_arguments; | 246 Label no_arguments; |
249 { | 247 { |
250 __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg)); | 248 __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg)); |
251 __ Dsubu(a0, a0, Operand(1)); | 249 __ Dsubu(t1, a0, Operand(1)); // In delay slot. |
252 __ Dlsa(sp, sp, a0, kPointerSizeLog2); | 250 __ mov(t0, a0); // Store argc in t0. |
253 __ ld(a0, MemOperand(sp)); | 251 __ Dlsa(at, sp, t1, kPointerSizeLog2); |
254 __ Drop(2); | 252 __ ld(a0, MemOperand(at)); |
255 } | 253 } |
256 | 254 |
257 // 2a. Convert first argument to number. | 255 // 2a. Convert first argument to number. |
258 __ Jump(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); | 256 { |
| 257 FrameScope scope(masm, StackFrame::MANUAL); |
| 258 __ SmiTag(t0); |
| 259 __ EnterBuiltinFrame(cp, a1, t0); |
| 260 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); |
| 261 __ LeaveBuiltinFrame(cp, a1, t0); |
| 262 __ SmiUntag(t0); |
| 263 } |
| 264 |
| 265 { |
| 266 // Drop all arguments including the receiver. |
| 267 __ Dlsa(sp, sp, t0, kPointerSizeLog2); |
| 268 __ DropAndRet(1); |
| 269 } |
259 | 270 |
260 // 2b. No arguments, return +0. | 271 // 2b. No arguments, return +0. |
261 __ bind(&no_arguments); | 272 __ bind(&no_arguments); |
262 __ Move(v0, Smi::FromInt(0)); | 273 __ Move(v0, Smi::FromInt(0)); |
263 __ DropAndRet(1); | 274 __ DropAndRet(1); |
264 } | 275 } |
265 | 276 |
266 | 277 |
267 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { | 278 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { |
268 // ----------- S t a t e ------------- | 279 // ----------- S t a t e ------------- |
269 // -- a0 : number of arguments | 280 // -- a0 : number of arguments |
270 // -- a1 : constructor function | 281 // -- a1 : constructor function |
271 // -- a3 : new target | 282 // -- a3 : new target |
| 283 // -- cp : context |
272 // -- ra : return address | 284 // -- ra : return address |
273 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) | 285 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) |
274 // -- sp[argc * 8] : receiver | 286 // -- sp[argc * 8] : receiver |
275 // ----------------------------------- | 287 // ----------------------------------- |
276 | 288 |
277 // 1. Make sure we operate in the context of the called function. | 289 // 1. Make sure we operate in the context of the called function. |
278 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 290 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
279 | 291 |
280 // 2. Load the first argument into a0 and get rid of the rest (including the | 292 // 2. Load the first argument into a0 and get rid of the rest (including the |
281 // receiver). | 293 // receiver). |
282 { | 294 { |
283 Label no_arguments, done; | 295 Label no_arguments, done; |
| 296 __ mov(t0, a0); // Store argc in t0. |
284 __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg)); | 297 __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg)); |
285 __ Dsubu(a0, a0, Operand(1)); | 298 __ Dsubu(a0, a0, Operand(1)); // In delay slot. |
286 __ Dlsa(sp, sp, a0, kPointerSizeLog2); | 299 __ Dlsa(at, sp, a0, kPointerSizeLog2); |
287 __ ld(a0, MemOperand(sp)); | 300 __ ld(a0, MemOperand(at)); |
288 __ Drop(2); | |
289 __ jmp(&done); | 301 __ jmp(&done); |
290 __ bind(&no_arguments); | 302 __ bind(&no_arguments); |
291 __ Move(a0, Smi::FromInt(0)); | 303 __ Move(a0, Smi::FromInt(0)); |
292 __ Drop(1); | |
293 __ bind(&done); | 304 __ bind(&done); |
294 } | 305 } |
295 | 306 |
296 // 3. Make sure a0 is a number. | 307 // 3. Make sure a0 is a number. |
297 { | 308 { |
298 Label done_convert; | 309 Label done_convert; |
299 __ JumpIfSmi(a0, &done_convert); | 310 __ JumpIfSmi(a0, &done_convert); |
300 __ GetObjectType(a0, a2, a2); | 311 __ GetObjectType(a0, a2, a2); |
301 __ Branch(&done_convert, eq, t0, Operand(HEAP_NUMBER_TYPE)); | 312 __ Branch(&done_convert, eq, a2, Operand(HEAP_NUMBER_TYPE)); |
302 { | 313 { |
303 FrameScope scope(masm, StackFrame::INTERNAL); | 314 FrameScope scope(masm, StackFrame::MANUAL); |
304 __ Push(a1, a3); | 315 __ SmiTag(t0); |
| 316 __ EnterBuiltinFrame(cp, a1, t0); |
| 317 __ Push(a3); |
305 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); | 318 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); |
306 __ Move(a0, v0); | 319 __ Move(a0, v0); |
307 __ Pop(a1, a3); | 320 __ Pop(a3); |
| 321 __ LeaveBuiltinFrame(cp, a1, t0); |
| 322 __ SmiUntag(t0); |
308 } | 323 } |
309 __ bind(&done_convert); | 324 __ bind(&done_convert); |
310 } | 325 } |
311 | 326 |
312 // 4. Check if new target and constructor differ. | 327 // 4. Check if new target and constructor differ. |
313 Label new_object; | 328 Label drop_frame_and_ret, new_object; |
314 __ Branch(&new_object, ne, a1, Operand(a3)); | 329 __ Branch(&new_object, ne, a1, Operand(a3)); |
315 | 330 |
316 // 5. Allocate a JSValue wrapper for the number. | 331 // 5. Allocate a JSValue wrapper for the number. |
317 __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object); | 332 __ AllocateJSValue(v0, a1, a0, a2, t1, &new_object); |
318 __ Ret(); | 333 __ jmp(&drop_frame_and_ret); |
319 | 334 |
320 // 6. Fallback to the runtime to create new object. | 335 // 6. Fallback to the runtime to create new object. |
321 __ bind(&new_object); | 336 __ bind(&new_object); |
322 { | 337 { |
323 FrameScope scope(masm, StackFrame::INTERNAL); | 338 FrameScope scope(masm, StackFrame::MANUAL); |
| 339 FastNewObjectStub stub(masm->isolate()); |
| 340 __ SmiTag(t0); |
| 341 __ EnterBuiltinFrame(cp, a1, t0); |
324 __ Push(a0); | 342 __ Push(a0); |
325 FastNewObjectStub stub(masm->isolate()); | |
326 __ CallStub(&stub); | 343 __ CallStub(&stub); |
327 __ Pop(a0); | 344 __ Pop(a0); |
| 345 __ LeaveBuiltinFrame(cp, a1, t0); |
| 346 __ SmiUntag(t0); |
328 } | 347 } |
329 __ Ret(USE_DELAY_SLOT); | 348 __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset)); |
330 __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot. | 349 |
| 350 __ bind(&drop_frame_and_ret); |
| 351 { |
| 352 __ Dlsa(sp, sp, t0, kPointerSizeLog2); |
| 353 __ DropAndRet(1); |
| 354 } |
331 } | 355 } |
332 | 356 |
333 | 357 |
334 // static | 358 // static |
335 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 359 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
336 // ----------- S t a t e ------------- | 360 // ----------- S t a t e ------------- |
337 // -- a0 : number of arguments | 361 // -- a0 : number of arguments |
338 // -- a1 : constructor function | 362 // -- a1 : constructor function |
| 363 // -- cp : context |
339 // -- ra : return address | 364 // -- ra : return address |
340 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) | 365 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) |
341 // -- sp[argc * 8] : receiver | 366 // -- sp[argc * 8] : receiver |
342 // ----------------------------------- | 367 // ----------------------------------- |
343 | 368 |
344 // 1. Load the first argument into a0 and get rid of the rest (including the | 369 // 1. Load the first argument into a0 and get rid of the rest (including the |
345 // receiver). | 370 // receiver). |
346 Label no_arguments; | 371 Label no_arguments; |
347 { | 372 { |
348 __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg)); | 373 __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg)); |
349 __ Dsubu(a0, a0, Operand(1)); | 374 __ Dsubu(t1, a0, Operand(1)); // In delay slot. |
350 __ Dlsa(sp, sp, a0, kPointerSizeLog2); | 375 __ mov(t0, a0); // Store argc in t0. |
351 __ ld(a0, MemOperand(sp)); | 376 __ Dlsa(at, sp, t1, kPointerSizeLog2); |
352 __ Drop(2); | 377 __ ld(a0, MemOperand(at)); |
353 } | 378 } |
354 | 379 |
355 // 2a. At least one argument, return a0 if it's a string, otherwise | 380 // 2a. At least one argument, return a0 if it's a string, otherwise |
356 // dispatch to appropriate conversion. | 381 // dispatch to appropriate conversion. |
357 Label to_string, symbol_descriptive_string; | 382 Label drop_frame_and_ret, to_string, symbol_descriptive_string; |
358 { | 383 { |
359 __ JumpIfSmi(a0, &to_string); | 384 __ JumpIfSmi(a0, &to_string); |
360 __ GetObjectType(a0, a1, a1); | 385 __ GetObjectType(a0, t1, t1); |
361 STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE); | 386 STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE); |
362 __ Subu(a1, a1, Operand(FIRST_NONSTRING_TYPE)); | 387 __ Subu(t1, t1, Operand(FIRST_NONSTRING_TYPE)); |
363 __ Branch(&symbol_descriptive_string, eq, a1, Operand(zero_reg)); | 388 __ Branch(&symbol_descriptive_string, eq, t1, Operand(zero_reg)); |
364 __ Branch(&to_string, gt, a1, Operand(zero_reg)); | 389 __ Branch(&to_string, gt, t1, Operand(zero_reg)); |
365 __ Ret(USE_DELAY_SLOT); | |
366 __ mov(v0, a0); | 390 __ mov(v0, a0); |
| 391 __ jmp(&drop_frame_and_ret); |
367 } | 392 } |
368 | 393 |
369 // 2b. No arguments, return the empty string (and pop the receiver). | 394 // 2b. No arguments, return the empty string (and pop the receiver). |
370 __ bind(&no_arguments); | 395 __ bind(&no_arguments); |
371 { | 396 { |
372 __ LoadRoot(v0, Heap::kempty_stringRootIndex); | 397 __ LoadRoot(v0, Heap::kempty_stringRootIndex); |
373 __ DropAndRet(1); | 398 __ DropAndRet(1); |
374 } | 399 } |
375 | 400 |
376 // 3a. Convert a0 to a string. | 401 // 3a. Convert a0 to a string. |
377 __ bind(&to_string); | 402 __ bind(&to_string); |
378 { | 403 { |
| 404 FrameScope scope(masm, StackFrame::MANUAL); |
379 ToStringStub stub(masm->isolate()); | 405 ToStringStub stub(masm->isolate()); |
380 __ TailCallStub(&stub); | 406 __ SmiTag(t0); |
| 407 __ EnterBuiltinFrame(cp, a1, t0); |
| 408 __ CallStub(&stub); |
| 409 __ LeaveBuiltinFrame(cp, a1, t0); |
| 410 __ SmiUntag(t0); |
381 } | 411 } |
| 412 __ jmp(&drop_frame_and_ret); |
382 | 413 |
383 // 3b. Convert symbol in a0 to a string. | 414 // 3b. Convert symbol in a0 to a string. |
384 __ bind(&symbol_descriptive_string); | 415 __ bind(&symbol_descriptive_string); |
385 { | 416 { |
| 417 __ Dlsa(sp, sp, t0, kPointerSizeLog2); |
| 418 __ Drop(1); |
386 __ Push(a0); | 419 __ Push(a0); |
387 __ TailCallRuntime(Runtime::kSymbolDescriptiveString); | 420 __ TailCallRuntime(Runtime::kSymbolDescriptiveString); |
388 } | 421 } |
| 422 |
| 423 __ bind(&drop_frame_and_ret); |
| 424 { |
| 425 __ Dlsa(sp, sp, t0, kPointerSizeLog2); |
| 426 __ DropAndRet(1); |
| 427 } |
389 } | 428 } |
390 | 429 |
391 | 430 |
392 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 431 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
393 // ----------- S t a t e ------------- | 432 // ----------- S t a t e ------------- |
394 // -- a0 : number of arguments | 433 // -- a0 : number of arguments |
395 // -- a1 : constructor function | 434 // -- a1 : constructor function |
396 // -- a3 : new target | 435 // -- a3 : new target |
| 436 // -- cp : context |
397 // -- ra : return address | 437 // -- ra : return address |
398 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) | 438 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) |
399 // -- sp[argc * 8] : receiver | 439 // -- sp[argc * 8] : receiver |
400 // ----------------------------------- | 440 // ----------------------------------- |
401 | 441 |
402 // 1. Make sure we operate in the context of the called function. | 442 // 1. Make sure we operate in the context of the called function. |
403 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 443 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
404 | 444 |
405 // 2. Load the first argument into a0 and get rid of the rest (including the | 445 // 2. Load the first argument into a0 and get rid of the rest (including the |
406 // receiver). | 446 // receiver). |
407 { | 447 { |
408 Label no_arguments, done; | 448 Label no_arguments, done; |
| 449 __ mov(t0, a0); // Store argc in t0. |
409 __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg)); | 450 __ Branch(USE_DELAY_SLOT, &no_arguments, eq, a0, Operand(zero_reg)); |
410 __ Dsubu(a0, a0, Operand(1)); | 451 __ Dsubu(a0, a0, Operand(1)); |
411 __ Dlsa(sp, sp, a0, kPointerSizeLog2); | 452 __ Dlsa(at, sp, a0, kPointerSizeLog2); |
412 __ ld(a0, MemOperand(sp)); | 453 __ ld(a0, MemOperand(at)); |
413 __ Drop(2); | |
414 __ jmp(&done); | 454 __ jmp(&done); |
415 __ bind(&no_arguments); | 455 __ bind(&no_arguments); |
416 __ LoadRoot(a0, Heap::kempty_stringRootIndex); | 456 __ LoadRoot(a0, Heap::kempty_stringRootIndex); |
417 __ Drop(1); | |
418 __ bind(&done); | 457 __ bind(&done); |
419 } | 458 } |
420 | 459 |
421 // 3. Make sure a0 is a string. | 460 // 3. Make sure a0 is a string. |
422 { | 461 { |
423 Label convert, done_convert; | 462 Label convert, done_convert; |
424 __ JumpIfSmi(a0, &convert); | 463 __ JumpIfSmi(a0, &convert); |
425 __ GetObjectType(a0, a2, a2); | 464 __ GetObjectType(a0, a2, a2); |
426 __ And(t0, a2, Operand(kIsNotStringMask)); | 465 __ And(t1, a2, Operand(kIsNotStringMask)); |
427 __ Branch(&done_convert, eq, t0, Operand(zero_reg)); | 466 __ Branch(&done_convert, eq, t1, Operand(zero_reg)); |
428 __ bind(&convert); | 467 __ bind(&convert); |
429 { | 468 { |
430 FrameScope scope(masm, StackFrame::INTERNAL); | 469 FrameScope scope(masm, StackFrame::MANUAL); |
431 ToStringStub stub(masm->isolate()); | 470 ToStringStub stub(masm->isolate()); |
432 __ Push(a1, a3); | 471 __ SmiTag(t0); |
| 472 __ EnterBuiltinFrame(cp, a1, t0); |
| 473 __ Push(a3); |
433 __ CallStub(&stub); | 474 __ CallStub(&stub); |
434 __ Move(a0, v0); | 475 __ Move(a0, v0); |
435 __ Pop(a1, a3); | 476 __ Pop(a3); |
| 477 __ LeaveBuiltinFrame(cp, a1, t0); |
| 478 __ SmiUntag(t0); |
436 } | 479 } |
437 __ bind(&done_convert); | 480 __ bind(&done_convert); |
438 } | 481 } |
439 | 482 |
440 // 4. Check if new target and constructor differ. | 483 // 4. Check if new target and constructor differ. |
441 Label new_object; | 484 Label drop_frame_and_ret, new_object; |
442 __ Branch(&new_object, ne, a1, Operand(a3)); | 485 __ Branch(&new_object, ne, a1, Operand(a3)); |
443 | 486 |
444 // 5. Allocate a JSValue wrapper for the string. | 487 // 5. Allocate a JSValue wrapper for the string. |
445 __ AllocateJSValue(v0, a1, a0, a2, t0, &new_object); | 488 __ AllocateJSValue(v0, a1, a0, a2, t1, &new_object); |
446 __ Ret(); | 489 __ jmp(&drop_frame_and_ret); |
447 | 490 |
448 // 6. Fallback to the runtime to create new object. | 491 // 6. Fallback to the runtime to create new object. |
449 __ bind(&new_object); | 492 __ bind(&new_object); |
450 { | 493 { |
451 FrameScope scope(masm, StackFrame::INTERNAL); | 494 FrameScope scope(masm, StackFrame::MANUAL); |
| 495 FastNewObjectStub stub(masm->isolate()); |
| 496 __ SmiTag(t0); |
| 497 __ EnterBuiltinFrame(cp, a1, t0); |
452 __ Push(a0); | 498 __ Push(a0); |
453 FastNewObjectStub stub(masm->isolate()); | |
454 __ CallStub(&stub); | 499 __ CallStub(&stub); |
455 __ Pop(a0); | 500 __ Pop(a0); |
| 501 __ LeaveBuiltinFrame(cp, a1, t0); |
| 502 __ SmiUntag(t0); |
456 } | 503 } |
457 __ Ret(USE_DELAY_SLOT); | 504 __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset)); |
458 __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset)); // In delay slot. | 505 |
| 506 __ bind(&drop_frame_and_ret); |
| 507 { |
| 508 __ Dlsa(sp, sp, t0, kPointerSizeLog2); |
| 509 __ DropAndRet(1); |
| 510 } |
459 } | 511 } |
460 | 512 |
461 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 513 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
462 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 514 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
463 __ ld(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); | 515 __ ld(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); |
464 __ Daddu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); | 516 __ Daddu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); |
465 __ Jump(at); | 517 __ Jump(at); |
466 } | 518 } |
467 | 519 |
468 static void GenerateTailCallToReturnedCode(MacroAssembler* masm, | 520 static void GenerateTailCallToReturnedCode(MacroAssembler* masm, |
(...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1781 __ li(a1, Operand(Smi::FromInt(field_index))); | 1833 __ li(a1, Operand(Smi::FromInt(field_index))); |
1782 __ CallCFunction( | 1834 __ CallCFunction( |
1783 ExternalReference::get_date_field_function(masm->isolate()), 2); | 1835 ExternalReference::get_date_field_function(masm->isolate()), 2); |
1784 } | 1836 } |
1785 __ Ret(); | 1837 __ Ret(); |
1786 | 1838 |
1787 // 3. Raise a TypeError if the receiver is not a date. | 1839 // 3. Raise a TypeError if the receiver is not a date. |
1788 __ bind(&receiver_not_date); | 1840 __ bind(&receiver_not_date); |
1789 { | 1841 { |
1790 FrameScope scope(masm, StackFrame::MANUAL); | 1842 FrameScope scope(masm, StackFrame::MANUAL); |
1791 __ Push(a0, ra, fp); | 1843 __ Push(a0); |
1792 __ Move(fp, sp); | 1844 __ Move(a0, Smi::FromInt(0)); |
1793 __ Push(cp, a1); | 1845 __ EnterBuiltinFrame(cp, a1, a0); |
1794 __ Push(Smi::FromInt(0)); | |
1795 __ CallRuntime(Runtime::kThrowNotDateError); | 1846 __ CallRuntime(Runtime::kThrowNotDateError); |
1796 } | 1847 } |
1797 } | 1848 } |
1798 | 1849 |
1799 // static | 1850 // static |
1800 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { | 1851 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { |
1801 // ----------- S t a t e ------------- | 1852 // ----------- S t a t e ------------- |
1802 // -- a0 : argc | 1853 // -- a0 : argc |
1803 // -- sp[0] : argArray | 1854 // -- sp[0] : argArray |
1804 // -- sp[4] : thisArg | 1855 // -- sp[4] : thisArg |
(...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3000 } | 3051 } |
3001 } | 3052 } |
3002 | 3053 |
3003 | 3054 |
3004 #undef __ | 3055 #undef __ |
3005 | 3056 |
3006 } // namespace internal | 3057 } // namespace internal |
3007 } // namespace v8 | 3058 } // namespace v8 |
3008 | 3059 |
3009 #endif // V8_TARGET_ARCH_MIPS64 | 3060 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |