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