op_add/ValueAdd should be an IC in all JIT tiers
[WebKit.git] / Source / JavaScriptCore / llint / LowLevelInterpreter64.asm
1 # Copyright (C) 2011-2016 Apple Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1. Redistributions of source code must retain the above copyright
7 #    notice, this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright
9 #    notice, this list of conditions and the following disclaimer in the
10 #    documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22 # THE POSSIBILITY OF SUCH DAMAGE.
23
24
25 # Utilities.
26 macro jumpToInstruction()
27     jmp [PB, PC, 8]
28 end
29
30 macro dispatch(advance)
31     addp advance, PC
32     jumpToInstruction()
33 end
34
35 macro dispatchInt(advance)
36     addi advance, PC
37     jumpToInstruction()
38 end
39
40 macro dispatchIntIndirect(offset)
41     dispatchInt(offset * 8[PB, PC, 8])
42 end
43
44 macro dispatchAfterCall()
45     loadi ArgumentCount + TagOffset[cfr], PC
46     loadp CodeBlock[cfr], PB
47     loadp CodeBlock::m_instructions[PB], PB
48     loadisFromInstruction(1, t1)
49     storeq r0, [cfr, t1, 8]
50     valueProfile(r0, (CallOpCodeSize - 1), t3)
51     dispatch(CallOpCodeSize)
52 end
53
54 macro cCall2(function)
55     checkStackPointerAlignment(t4, 0xbad0c002)
56     if X86_64 or ARM64
57         call function
58     elsif X86_64_WIN
59         # Note: this implementation is only correct if the return type size is > 8 bytes.
60         # See macro cCall2Void for an implementation when the return type <= 8 bytes.
61         # On Win64, when the return type is larger than 8 bytes, we need to allocate space on the stack for the return value.
62         # On entry rcx (a0), should contain a pointer to this stack space. The other parameters are shifted to the right,
63         # rdx (a1) should contain the first argument, and r8 (a2) should contain the second argument.
64         # On return, rax contains a pointer to this stack value, and we then need to copy the 16 byte return value into rax (r0) and rdx (r1)
65         # since the return value is expected to be split between the two.
66         # See http://msdn.microsoft.com/en-us/library/7572ztz4.aspx
67         move a1, a2
68         move a0, a1
69         subp 48, sp
70         move sp, a0
71         addp 32, a0
72         call function
73         addp 48, sp
74         move 8[r0], r1
75         move [r0], r0
76     elsif C_LOOP
77         cloopCallSlowPath function, a0, a1
78     else
79         error
80     end
81 end
82
83 macro cCall2Void(function)
84     if C_LOOP
85         cloopCallSlowPathVoid function, a0, a1
86     elsif X86_64_WIN
87         # Note: we cannot use the cCall2 macro for Win64 in this case,
88         # as the Win64 cCall2 implemenation is only correct when the return type size is > 8 bytes.
89         # On Win64, rcx and rdx are used for passing the first two parameters.
90         # We also need to make room on the stack for all four parameter registers.
91         # See http://msdn.microsoft.com/en-us/library/ms235286.aspx
92         subp 32, sp 
93         call function
94         addp 32, sp 
95     else
96         cCall2(function)
97     end
98 end
99
100 # This barely works. arg3 and arg4 should probably be immediates.
101 macro cCall4(function)
102     checkStackPointerAlignment(t4, 0xbad0c004)
103     if X86_64 or ARM64
104         call function
105     elsif X86_64_WIN
106         # On Win64, rcx, rdx, r8, and r9 are used for passing the first four parameters.
107         # We also need to make room on the stack for all four parameter registers.
108         # See http://msdn.microsoft.com/en-us/library/ms235286.aspx
109         subp 64, sp
110         call function
111         addp 64, sp
112     else
113         error
114     end
115 end
116
117 macro doVMEntry(makeCall)
118     functionPrologue()
119     pushCalleeSaves()
120
121     const entry = a0
122     const vm = a1
123     const protoCallFrame = a2
124
125     vmEntryRecord(cfr, sp)
126
127     checkStackPointerAlignment(t4, 0xbad0dc01)
128
129     storep vm, VMEntryRecord::m_vm[sp]
130     loadp VM::topCallFrame[vm], t4
131     storep t4, VMEntryRecord::m_prevTopCallFrame[sp]
132     loadp VM::topVMEntryFrame[vm], t4
133     storep t4, VMEntryRecord::m_prevTopVMEntryFrame[sp]
134
135     loadi ProtoCallFrame::paddedArgCount[protoCallFrame], t4
136     addp CallFrameHeaderSlots, t4, t4
137     lshiftp 3, t4
138     subp sp, t4, t3
139
140     # Ensure that we have enough additional stack capacity for the incoming args,
141     # and the frame for the JS code we're executing. We need to do this check
142     # before we start copying the args from the protoCallFrame below.
143     if C_LOOP
144         bpaeq t3, VM::m_cloopStackLimit[vm], .stackHeightOK
145     else
146         bpaeq t3, VM::m_softStackLimit[vm], .stackHeightOK
147     end
148
149     if C_LOOP
150         move entry, t4
151         move vm, t5
152         cloopCallSlowPath _llint_stack_check_at_vm_entry, vm, t3
153         bpeq t0, 0, .stackCheckFailed
154         move t4, entry
155         move t5, vm
156         jmp .stackHeightOK
157
158 .stackCheckFailed:
159         move t4, entry
160         move t5, vm
161     end
162
163     move vm, a0
164     move protoCallFrame, a1
165     cCall2(_llint_throw_stack_overflow_error)
166
167     vmEntryRecord(cfr, t4)
168
169     loadp VMEntryRecord::m_vm[t4], vm
170     loadp VMEntryRecord::m_prevTopCallFrame[t4], extraTempReg
171     storep extraTempReg, VM::topCallFrame[vm]
172     loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], extraTempReg
173     storep extraTempReg, VM::topVMEntryFrame[vm]
174
175     subp cfr, CalleeRegisterSaveSize, sp
176
177     popCalleeSaves()
178     functionEpilogue()
179     ret
180
181 .stackHeightOK:
182     move t3, sp
183     move 4, t3
184
185 .copyHeaderLoop:
186     subi 1, t3
187     loadq [protoCallFrame, t3, 8], extraTempReg
188     storeq extraTempReg, CodeBlock[sp, t3, 8]
189     btinz t3, .copyHeaderLoop
190
191     loadi PayloadOffset + ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], t4
192     subi 1, t4
193     loadi ProtoCallFrame::paddedArgCount[protoCallFrame], extraTempReg
194     subi 1, extraTempReg
195
196     bieq t4, extraTempReg, .copyArgs
197     move ValueUndefined, t3
198 .fillExtraArgsLoop:
199     subi 1, extraTempReg
200     storeq t3, ThisArgumentOffset + 8[sp, extraTempReg, 8]
201     bineq t4, extraTempReg, .fillExtraArgsLoop
202
203 .copyArgs:
204     loadp ProtoCallFrame::args[protoCallFrame], t3
205
206 .copyArgsLoop:
207     btiz t4, .copyArgsDone
208     subi 1, t4
209     loadq [t3, t4, 8], extraTempReg
210     storeq extraTempReg, ThisArgumentOffset + 8[sp, t4, 8]
211     jmp .copyArgsLoop
212
213 .copyArgsDone:
214     if ARM64
215         move sp, t4
216         storep t4, VM::topCallFrame[vm]
217     else
218         storep sp, VM::topCallFrame[vm]
219     end
220     storep cfr, VM::topVMEntryFrame[vm]
221
222     checkStackPointerAlignment(extraTempReg, 0xbad0dc02)
223
224     makeCall(entry, t3)
225
226     # We may have just made a call into a JS function, so we can't rely on sp
227     # for anything but the fact that our own locals (ie the VMEntryRecord) are
228     # not below it. It also still has to be aligned, though.
229     checkStackPointerAlignment(t2, 0xbad0dc03)
230
231     vmEntryRecord(cfr, t4)
232
233     loadp VMEntryRecord::m_vm[t4], vm
234     loadp VMEntryRecord::m_prevTopCallFrame[t4], t2
235     storep t2, VM::topCallFrame[vm]
236     loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], t2
237     storep t2, VM::topVMEntryFrame[vm]
238
239     subp cfr, CalleeRegisterSaveSize, sp
240
241     popCalleeSaves()
242     functionEpilogue()
243
244     ret
245 end
246
247
248 macro makeJavaScriptCall(entry, temp)
249     addp 16, sp
250     if C_LOOP
251         cloopCallJSFunction entry
252     else
253         call entry
254     end
255     subp 16, sp
256 end
257
258
259 macro makeHostFunctionCall(entry, temp)
260     move entry, temp
261     storep cfr, [sp]
262     move sp, a0
263     if C_LOOP
264         storep lr, 8[sp]
265         cloopCallNative temp
266     elsif X86_64_WIN
267         # We need to allocate 32 bytes on the stack for the shadow space.
268         subp 32, sp
269         call temp
270         addp 32, sp
271     else
272         call temp
273     end
274 end
275
276
277 _handleUncaughtException:
278     loadp Callee[cfr], t3
279     andp MarkedBlockMask, t3
280     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
281     restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0)
282     loadp VM::callFrameForCatch[t3], cfr
283     storep 0, VM::callFrameForCatch[t3]
284
285     loadp CallerFrame[cfr], cfr
286     vmEntryRecord(cfr, t2)
287
288     loadp VMEntryRecord::m_vm[t2], t3
289     loadp VMEntryRecord::m_prevTopCallFrame[t2], extraTempReg
290     storep extraTempReg, VM::topCallFrame[t3]
291     loadp VMEntryRecord::m_prevTopVMEntryFrame[t2], extraTempReg
292     storep extraTempReg, VM::topVMEntryFrame[t3]
293
294     subp cfr, CalleeRegisterSaveSize, sp
295
296     popCalleeSaves()
297     functionEpilogue()
298     ret
299
300
301 macro prepareStateForCCall()
302     leap [PB, PC, 8], PC
303 end
304
305 macro restoreStateAfterCCall()
306     move r0, PC
307     subp PB, PC
308     rshiftp 3, PC
309 end
310
311 macro callSlowPath(slowPath)
312     prepareStateForCCall()
313     move cfr, a0
314     move PC, a1
315     cCall2(slowPath)
316     restoreStateAfterCCall()
317 end
318
319 macro traceOperand(fromWhere, operand)
320     prepareStateForCCall()
321     move fromWhere, a2
322     move operand, a3
323     move cfr, a0
324     move PC, a1
325     cCall4(_llint_trace_operand)
326     restoreStateAfterCCall()
327 end
328
329 macro traceValue(fromWhere, operand)
330     prepareStateForCCall()
331     move fromWhere, a2
332     move operand, a3
333     move cfr, a0
334     move PC, a1
335     cCall4(_llint_trace_value)
336     restoreStateAfterCCall()
337 end
338
339 # Call a slow path for call call opcodes.
340 macro callCallSlowPath(slowPath, action)
341     storei PC, ArgumentCount + TagOffset[cfr]
342     prepareStateForCCall()
343     move cfr, a0
344     move PC, a1
345     cCall2(slowPath)
346     action(r0, r1)
347 end
348
349 macro callWatchdogTimerHandler(throwHandler)
350     storei PC, ArgumentCount + TagOffset[cfr]
351     prepareStateForCCall()
352     move cfr, a0
353     move PC, a1
354     cCall2(_llint_slow_path_handle_watchdog_timer)
355     btpnz r0, throwHandler
356     loadi ArgumentCount + TagOffset[cfr], PC
357 end
358
359 macro checkSwitchToJITForLoop()
360     checkSwitchToJIT(
361         1,
362         macro()
363             storei PC, ArgumentCount + TagOffset[cfr]
364             prepareStateForCCall()
365             move cfr, a0
366             move PC, a1
367             cCall2(_llint_loop_osr)
368             btpz r0, .recover
369             move r1, sp
370             jmp r0
371         .recover:
372             loadi ArgumentCount + TagOffset[cfr], PC
373         end)
374 end
375
376 macro loadVariable(operand, value)
377     loadisFromInstruction(operand, value)
378     loadq [cfr, value, 8], value
379 end
380
381 # Index and value must be different registers. Index may be clobbered.
382 macro loadConstantOrVariable(index, value)
383     bpgteq index, FirstConstantRegisterIndex, .constant
384     loadq [cfr, index, 8], value
385     jmp .done
386 .constant:
387     loadp CodeBlock[cfr], value
388     loadp CodeBlock::m_constantRegisters + VectorBufferOffset[value], value
389     subp FirstConstantRegisterIndex, index
390     loadq [value, index, 8], value
391 .done:
392 end
393
394 macro loadConstantOrVariableInt32(index, value, slow)
395     loadConstantOrVariable(index, value)
396     bqb value, tagTypeNumber, slow
397 end
398
399 macro loadConstantOrVariableCell(index, value, slow)
400     loadConstantOrVariable(index, value)
401     btqnz value, tagMask, slow
402 end
403
404 macro writeBarrierOnOperand(cellOperand)
405     loadisFromInstruction(cellOperand, t1)
406     loadConstantOrVariableCell(t1, t2, .writeBarrierDone)
407     skipIfIsRememberedOrInEden(t2, t1, t3, 
408         macro(cellState)
409             btbnz cellState, .writeBarrierDone
410             push PB, PC
411             move t2, a1 # t2 can be a0 (not on 64 bits, but better safe than sorry)
412             move cfr, a0
413             cCall2Void(_llint_write_barrier_slow)
414             pop PC, PB
415         end
416     )
417 .writeBarrierDone:
418 end
419
420 macro writeBarrierOnOperands(cellOperand, valueOperand)
421     loadisFromInstruction(valueOperand, t1)
422     loadConstantOrVariableCell(t1, t0, .writeBarrierDone)
423     btpz t0, .writeBarrierDone
424
425     writeBarrierOnOperand(cellOperand)
426 .writeBarrierDone:
427 end
428
429 macro writeBarrierOnGlobal(valueOperand, loadHelper)
430     loadisFromInstruction(valueOperand, t1)
431     loadConstantOrVariableCell(t1, t0, .writeBarrierDone)
432     btpz t0, .writeBarrierDone
433
434     loadHelper(t3)
435     skipIfIsRememberedOrInEden(t3, t1, t2,
436         macro(gcData)
437             btbnz gcData, .writeBarrierDone
438             push PB, PC
439             move cfr, a0
440             move t3, a1
441             cCall2Void(_llint_write_barrier_slow)
442             pop PC, PB
443         end
444     )
445 .writeBarrierDone:
446 end
447
448 macro writeBarrierOnGlobalObject(valueOperand)
449     writeBarrierOnGlobal(valueOperand,
450         macro(registerToStoreGlobal)
451             loadp CodeBlock[cfr], registerToStoreGlobal
452             loadp CodeBlock::m_globalObject[registerToStoreGlobal], registerToStoreGlobal
453         end)
454 end
455
456 macro writeBarrierOnGlobalLexicalEnvironment(valueOperand)
457     writeBarrierOnGlobal(valueOperand,
458         macro(registerToStoreGlobal)
459             loadp CodeBlock[cfr], registerToStoreGlobal
460             loadp CodeBlock::m_globalObject[registerToStoreGlobal], registerToStoreGlobal
461             loadp JSGlobalObject::m_globalLexicalEnvironment[registerToStoreGlobal], registerToStoreGlobal
462         end)
463 end
464
465 macro valueProfile(value, operand, scratch)
466     loadpFromInstruction(operand, scratch)
467     storeq value, ValueProfile::m_buckets[scratch]
468 end
469
470 macro structureIDToStructureWithScratch(structureIDThenStructure, scratch)
471     loadp CodeBlock[cfr], scratch
472     loadp CodeBlock::m_vm[scratch], scratch
473     loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[scratch], scratch
474     loadp [scratch, structureIDThenStructure, 8], structureIDThenStructure
475 end
476
477 macro loadStructureWithScratch(cell, structure, scratch)
478     loadi JSCell::m_structureID[cell], structure
479     structureIDToStructureWithScratch(structure, scratch)
480 end
481
482 macro loadStructureAndClobberFirstArg(cell, structure)
483     loadi JSCell::m_structureID[cell], structure
484     loadp CodeBlock[cfr], cell
485     loadp CodeBlock::m_vm[cell], cell
486     loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[cell], cell
487     loadp [cell, structure, 8], structure
488 end
489
490 macro storeStructureWithTypeInfo(cell, structure, scratch)
491     loadq Structure::m_blob + StructureIDBlob::u.doubleWord[structure], scratch
492     storeq scratch, JSCell::m_structureID[cell]
493 end
494
495 # Entrypoints into the interpreter.
496
497 # Expects that CodeBlock is in t1, which is what prologue() leaves behind.
498 macro functionArityCheck(doneLabel, slowPath)
499     loadi PayloadOffset + ArgumentCount[cfr], t0
500     biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
501     prepareStateForCCall()
502     move cfr, a0
503     move PC, a1
504     cCall2(slowPath)   # This slowPath has the protocol: r0 = 0 => no error, r0 != 0 => error
505     btiz r0, .noError
506     move r1, cfr   # r1 contains caller frame
507     jmp _llint_throw_from_slow_path_trampoline
508
509 .noError:
510     loadi CommonSlowPaths::ArityCheckData::paddedStackSpace[r1], t1
511     btiz t1, .continue
512     loadi PayloadOffset + ArgumentCount[cfr], t2
513     addi CallFrameHeaderSlots, t2
514
515     // Check if there are some unaligned slots we can use
516     move t1, t3
517     andi StackAlignmentSlots - 1, t3
518     btiz t3, .noExtraSlot
519     move ValueUndefined, t0
520 .fillExtraSlots:
521     storeq t0, [cfr, t2, 8]
522     addi 1, t2
523     bsubinz 1, t3, .fillExtraSlots
524     andi ~(StackAlignmentSlots - 1), t1
525     btiz t1, .continue
526
527 .noExtraSlot:
528     // Move frame up t1 slots
529     negq t1
530     move cfr, t3
531     subp CalleeSaveSpaceAsVirtualRegisters * 8, t3
532     addi CalleeSaveSpaceAsVirtualRegisters, t2
533 .copyLoop:
534     loadq [t3], t0
535     storeq t0, [t3, t1, 8]
536     addp 8, t3
537     bsubinz 1, t2, .copyLoop
538
539     // Fill new slots with JSUndefined
540     move t1, t2
541     move ValueUndefined, t0
542 .fillLoop:
543     storeq t0, [t3, t1, 8]
544     addp 8, t3
545     baddinz 1, t2, .fillLoop
546
547     lshiftp 3, t1
548     addp t1, cfr
549     addp t1, sp
550
551 .continue:
552     # Reload CodeBlock and reset PC, since the slow_path clobbered them.
553     loadp CodeBlock[cfr], t1
554     loadp CodeBlock::m_instructions[t1], PB
555     move 0, PC
556     jmp doneLabel
557 end
558
559 macro branchIfException(label)
560     loadp Callee[cfr], t3
561     andp MarkedBlockMask, t3
562     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
563     btqz VM::m_exception[t3], .noException
564     jmp label
565 .noException:
566 end
567
568
569 # Instruction implementations
570 _llint_op_enter:
571     traceExecution()
572     checkStackPointerAlignment(t2, 0xdead00e1)
573     loadp CodeBlock[cfr], t2                // t2<CodeBlock> = cfr.CodeBlock
574     loadi CodeBlock::m_numVars[t2], t2      // t2<size_t> = t2<CodeBlock>.m_numVars
575     subq CalleeSaveSpaceAsVirtualRegisters, t2
576     move cfr, t1
577     subq CalleeSaveSpaceAsVirtualRegisters * 8, t1
578     btiz t2, .opEnterDone
579     move ValueUndefined, t0
580     negi t2
581     sxi2q t2, t2
582 .opEnterLoop:
583     storeq t0, [t1, t2, 8]
584     addq 1, t2
585     btqnz t2, .opEnterLoop
586 .opEnterDone:
587     callOpcodeSlowPath(_slow_path_enter)
588     dispatch(1)
589
590
591 _llint_op_argument_count:
592     traceExecution()
593     loadisFromInstruction(1, t1)
594     loadi PayloadOffset + ArgumentCount[cfr], t0
595     subi 1, t0
596     orq TagTypeNumber, t0
597     storeq t0, [cfr, t1, 8]
598     dispatch(2)
599
600
601 _llint_op_get_scope:
602     traceExecution()
603     loadp Callee[cfr], t0
604     loadp JSCallee::m_scope[t0], t0
605     loadisFromInstruction(1, t1)
606     storeq t0, [cfr, t1, 8]
607     dispatch(2)
608
609
610 _llint_op_create_this:
611     traceExecution()
612     loadisFromInstruction(2, t0)
613     loadp [cfr, t0, 8], t0
614     bbneq JSCell::m_type[t0], JSFunctionType, .opCreateThisSlow
615     loadp JSFunction::m_rareData[t0], t3
616     btpz t3, .opCreateThisSlow
617     loadp FunctionRareData::m_objectAllocationProfile + ObjectAllocationProfile::m_allocator[t3], t1
618     loadp FunctionRareData::m_objectAllocationProfile + ObjectAllocationProfile::m_structure[t3], t2
619     btpz t1, .opCreateThisSlow
620     loadpFromInstruction(4, t3)
621     bpeq t3, 1, .hasSeenMultipleCallee
622     bpneq t3, t0, .opCreateThisSlow
623 .hasSeenMultipleCallee:
624     allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
625     loadisFromInstruction(1, t1)
626     storeq t0, [cfr, t1, 8]
627     dispatch(5)
628
629 .opCreateThisSlow:
630     callOpcodeSlowPath(_slow_path_create_this)
631     dispatch(5)
632
633
634 _llint_op_to_this:
635     traceExecution()
636     loadisFromInstruction(1, t0)
637     loadq [cfr, t0, 8], t0
638     btqnz t0, tagMask, .opToThisSlow
639     bbneq JSCell::m_type[t0], FinalObjectType, .opToThisSlow
640     loadStructureWithScratch(t0, t1, t2)
641     loadpFromInstruction(2, t2)
642     bpneq t1, t2, .opToThisSlow
643     dispatch(4)
644
645 .opToThisSlow:
646     callOpcodeSlowPath(_slow_path_to_this)
647     dispatch(4)
648
649
650 _llint_op_new_object:
651     traceExecution()
652     loadpFromInstruction(3, t0)
653     loadp ObjectAllocationProfile::m_allocator[t0], t1
654     loadp ObjectAllocationProfile::m_structure[t0], t2
655     allocateJSObject(t1, t2, t0, t3, .opNewObjectSlow)
656     loadisFromInstruction(1, t1)
657     storeq t0, [cfr, t1, 8]
658     dispatch(4)
659
660 .opNewObjectSlow:
661     callOpcodeSlowPath(_llint_slow_path_new_object)
662     dispatch(4)
663
664
665 _llint_op_check_tdz:
666     traceExecution()
667     loadisFromInstruction(1, t0)
668     loadConstantOrVariable(t0, t1)
669     bqneq t1, ValueEmpty, .opNotTDZ
670     callOpcodeSlowPath(_slow_path_throw_tdz_error)
671
672 .opNotTDZ:
673     dispatch(2)
674
675
676 _llint_op_mov:
677     traceExecution()
678     loadisFromInstruction(2, t1)
679     loadisFromInstruction(1, t0)
680     loadConstantOrVariable(t1, t2)
681     storeq t2, [cfr, t0, 8]
682     dispatch(3)
683
684
685 _llint_op_not:
686     traceExecution()
687     loadisFromInstruction(2, t0)
688     loadisFromInstruction(1, t1)
689     loadConstantOrVariable(t0, t2)
690     xorq ValueFalse, t2
691     btqnz t2, ~1, .opNotSlow
692     xorq ValueTrue, t2
693     storeq t2, [cfr, t1, 8]
694     dispatch(3)
695
696 .opNotSlow:
697     callOpcodeSlowPath(_slow_path_not)
698     dispatch(3)
699
700
701 macro equalityComparison(integerComparison, slowPath)
702     traceExecution()
703     loadisFromInstruction(3, t0)
704     loadisFromInstruction(2, t2)
705     loadisFromInstruction(1, t3)
706     loadConstantOrVariableInt32(t0, t1, .slow)
707     loadConstantOrVariableInt32(t2, t0, .slow)
708     integerComparison(t0, t1, t0)
709     orq ValueFalse, t0
710     storeq t0, [cfr, t3, 8]
711     dispatch(4)
712
713 .slow:
714     callOpcodeSlowPath(slowPath)
715     dispatch(4)
716 end
717
718 _llint_op_eq:
719     equalityComparison(
720         macro (left, right, result) cieq left, right, result end,
721         _slow_path_eq)
722
723
724 _llint_op_neq:
725     equalityComparison(
726         macro (left, right, result) cineq left, right, result end,
727         _slow_path_neq)
728
729
730 macro equalNullComparison()
731     loadisFromInstruction(2, t0)
732     loadq [cfr, t0, 8], t0
733     btqnz t0, tagMask, .immediate
734     btbnz JSCell::m_flags[t0], MasqueradesAsUndefined, .masqueradesAsUndefined
735     move 0, t0
736     jmp .done
737 .masqueradesAsUndefined:
738     loadStructureWithScratch(t0, t2, t1)
739     loadp CodeBlock[cfr], t0
740     loadp CodeBlock::m_globalObject[t0], t0
741     cpeq Structure::m_globalObject[t2], t0, t0
742     jmp .done
743 .immediate:
744     andq ~TagBitUndefined, t0
745     cqeq t0, ValueNull, t0
746 .done:
747 end
748
749 _llint_op_eq_null:
750     traceExecution()
751     equalNullComparison()
752     loadisFromInstruction(1, t1)
753     orq ValueFalse, t0
754     storeq t0, [cfr, t1, 8]
755     dispatch(3)
756
757
758 _llint_op_neq_null:
759     traceExecution()
760     equalNullComparison()
761     loadisFromInstruction(1, t1)
762     xorq ValueTrue, t0
763     storeq t0, [cfr, t1, 8]
764     dispatch(3)
765
766
767 macro strictEq(equalityOperation, slowPath)
768     traceExecution()
769     loadisFromInstruction(3, t0)
770     loadisFromInstruction(2, t2)
771     loadConstantOrVariable(t0, t1)
772     loadConstantOrVariable(t2, t0)
773     move t0, t2
774     orq t1, t2
775     btqz t2, tagMask, .slow
776     bqaeq t0, tagTypeNumber, .leftOK
777     btqnz t0, tagTypeNumber, .slow
778 .leftOK:
779     bqaeq t1, tagTypeNumber, .rightOK
780     btqnz t1, tagTypeNumber, .slow
781 .rightOK:
782     equalityOperation(t0, t1, t0)
783     loadisFromInstruction(1, t1)
784     orq ValueFalse, t0
785     storeq t0, [cfr, t1, 8]
786     dispatch(4)
787
788 .slow:
789     callOpcodeSlowPath(slowPath)
790     dispatch(4)
791 end
792
793 _llint_op_stricteq:
794     strictEq(
795         macro (left, right, result) cqeq left, right, result end,
796         _slow_path_stricteq)
797
798
799 _llint_op_nstricteq:
800     strictEq(
801         macro (left, right, result) cqneq left, right, result end,
802         _slow_path_nstricteq)
803
804
805 macro preOp(arithmeticOperation, slowPath)
806     traceExecution()
807     loadisFromInstruction(1, t0)
808     loadq [cfr, t0, 8], t1
809     bqb t1, tagTypeNumber, .slow
810     arithmeticOperation(t1, .slow)
811     orq tagTypeNumber, t1
812     storeq t1, [cfr, t0, 8]
813     dispatch(2)
814
815 .slow:
816     callOpcodeSlowPath(slowPath)
817     dispatch(2)
818 end
819
820 _llint_op_inc:
821     preOp(
822         macro (value, slow) baddio 1, value, slow end,
823         _slow_path_inc)
824
825
826 _llint_op_dec:
827     preOp(
828         macro (value, slow) bsubio 1, value, slow end,
829         _slow_path_dec)
830
831
832 _llint_op_to_number:
833     traceExecution()
834     loadisFromInstruction(2, t0)
835     loadisFromInstruction(1, t1)
836     loadConstantOrVariable(t0, t2)
837     bqaeq t2, tagTypeNumber, .opToNumberIsImmediate
838     btqz t2, tagTypeNumber, .opToNumberSlow
839 .opToNumberIsImmediate:
840     storeq t2, [cfr, t1, 8]
841     valueProfile(t2, 3, t0)
842     dispatch(4)
843
844 .opToNumberSlow:
845     callOpcodeSlowPath(_slow_path_to_number)
846     dispatch(4)
847
848
849 _llint_op_to_string:
850     traceExecution()
851     loadisFromInstruction(2, t1)
852     loadisFromInstruction(1, t2)
853     loadConstantOrVariable(t1, t0)
854     btqnz t0, tagMask, .opToStringSlow
855     bbneq JSCell::m_type[t0], StringType, .opToStringSlow
856 .opToStringIsString:
857     storeq t0, [cfr, t2, 8]
858     dispatch(3)
859
860 .opToStringSlow:
861     callOpcodeSlowPath(_slow_path_to_string)
862     dispatch(3)
863
864
865 _llint_op_negate:
866     traceExecution()
867     loadisFromInstruction(2, t0)
868     loadisFromInstruction(1, t1)
869     loadConstantOrVariable(t0, t2)
870     bqb t2, tagTypeNumber, .opNegateNotInt
871     btiz t2, 0x7fffffff, .opNegateSlow
872     negi t2
873     orq tagTypeNumber, t2
874     storeq t2, [cfr, t1, 8]
875     dispatch(3)
876 .opNegateNotInt:
877     btqz t2, tagTypeNumber, .opNegateSlow
878     xorq 0x8000000000000000, t2
879     storeq t2, [cfr, t1, 8]
880     dispatch(3)
881
882 .opNegateSlow:
883     callOpcodeSlowPath(_slow_path_negate)
884     dispatch(3)
885
886
887 macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
888     loadisFromInstruction(3, t0)
889     loadisFromInstruction(2, t2)
890     loadConstantOrVariable(t0, t1)
891     loadConstantOrVariable(t2, t0)
892     bqb t0, tagTypeNumber, .op1NotInt
893     bqb t1, tagTypeNumber, .op2NotInt
894     loadisFromInstruction(1, t2)
895     integerOperationAndStore(t1, t0, .slow, t2)
896     loadisFromInstruction(4, t1)
897     ori ArithProfileIntInt, t1
898     storeisToInstruction(t1, 4)
899     dispatch(5)
900
901 .op1NotInt:
902     # First operand is definitely not an int, the second operand could be anything.
903     btqz t0, tagTypeNumber, .slow
904     bqaeq t1, tagTypeNumber, .op1NotIntOp2Int
905     btqz t1, tagTypeNumber, .slow
906     addq tagTypeNumber, t1
907     fq2d t1, ft1
908     loadisFromInstruction(4, t2)
909     ori ArithProfileNumberNumber, t2
910     storeisToInstruction(t2, 4)
911     jmp .op1NotIntReady
912 .op1NotIntOp2Int:
913     loadisFromInstruction(4, t2)
914     ori ArithProfileNumberInt, t2
915     storeisToInstruction(t2, 4)
916     ci2d t1, ft1
917 .op1NotIntReady:
918     loadisFromInstruction(1, t2)
919     addq tagTypeNumber, t0
920     fq2d t0, ft0
921     doubleOperation(ft1, ft0)
922     fd2q ft0, t0
923     subq tagTypeNumber, t0
924     storeq t0, [cfr, t2, 8]
925     dispatch(5)
926
927 .op2NotInt:
928     # First operand is definitely an int, the second is definitely not.
929     loadisFromInstruction(1, t2)
930     btqz t1, tagTypeNumber, .slow
931     loadisFromInstruction(4, t3)
932     ori ArithProfileIntNumber, t3
933     storeisToInstruction(t3, 4)
934     ci2d t0, ft0
935     addq tagTypeNumber, t1
936     fq2d t1, ft1
937     doubleOperation(ft1, ft0)
938     fd2q ft0, t0
939     subq tagTypeNumber, t0
940     storeq t0, [cfr, t2, 8]
941     dispatch(5)
942
943 .slow:
944     callOpcodeSlowPath(slowPath)
945     dispatch(5)
946 end
947
948 macro binaryOp(integerOperation, doubleOperation, slowPath)
949     binaryOpCustomStore(
950         macro (left, right, slow, index)
951             integerOperation(left, right, slow)
952             orq tagTypeNumber, right
953             storeq right, [cfr, index, 8]
954         end,
955         doubleOperation, slowPath)
956 end
957
958 _llint_op_add:
959     traceExecution()
960     binaryOp(
961         macro (left, right, slow) baddio left, right, slow end,
962         macro (left, right) addd left, right end,
963         _slow_path_add)
964
965
966 _llint_op_mul:
967     traceExecution()
968     binaryOpCustomStore(
969         macro (left, right, slow, index)
970             # Assume t3 is scratchable.
971             move right, t3
972             bmulio left, t3, slow
973             btinz t3, .done
974             bilt left, 0, slow
975             bilt right, 0, slow
976         .done:
977             orq tagTypeNumber, t3
978             storeq t3, [cfr, index, 8]
979         end,
980         macro (left, right) muld left, right end,
981         _slow_path_mul)
982
983
984 _llint_op_sub:
985     traceExecution()
986     binaryOp(
987         macro (left, right, slow) bsubio left, right, slow end,
988         macro (left, right) subd left, right end,
989         _slow_path_sub)
990
991
992 _llint_op_div:
993     traceExecution()
994     if X86_64 or X86_64_WIN
995         binaryOpCustomStore(
996             macro (left, right, slow, index)
997                 # Assume t3 is scratchable.
998                 btiz left, slow
999                 bineq left, -1, .notNeg2TwoThe31DivByNeg1
1000                 bieq right, -2147483648, .slow
1001             .notNeg2TwoThe31DivByNeg1:
1002                 btinz right, .intOK
1003                 bilt left, 0, slow
1004             .intOK:
1005                 move left, t3
1006                 move right, t0
1007                 cdqi
1008                 idivi t3
1009                 btinz t1, slow
1010                 orq tagTypeNumber, t0
1011                 storeq t0, [cfr, index, 8]
1012             end,
1013             macro (left, right) divd left, right end,
1014             _slow_path_div)
1015     else
1016         callOpcodeSlowPath(_slow_path_div)
1017         dispatch(5)
1018     end
1019
1020
1021 macro bitOp(operation, slowPath, advance)
1022     loadisFromInstruction(3, t0)
1023     loadisFromInstruction(2, t2)
1024     loadisFromInstruction(1, t3)
1025     loadConstantOrVariable(t0, t1)
1026     loadConstantOrVariable(t2, t0)
1027     bqb t0, tagTypeNumber, .slow
1028     bqb t1, tagTypeNumber, .slow
1029     operation(t1, t0)
1030     orq tagTypeNumber, t0
1031     storeq t0, [cfr, t3, 8]
1032     dispatch(advance)
1033
1034 .slow:
1035     callOpcodeSlowPath(slowPath)
1036     dispatch(advance)
1037 end
1038
1039 _llint_op_lshift:
1040     traceExecution()
1041     bitOp(
1042         macro (left, right) lshifti left, right end,
1043         _slow_path_lshift,
1044         4)
1045
1046
1047 _llint_op_rshift:
1048     traceExecution()
1049     bitOp(
1050         macro (left, right) rshifti left, right end,
1051         _slow_path_rshift,
1052         4)
1053
1054
1055 _llint_op_urshift:
1056     traceExecution()
1057     bitOp(
1058         macro (left, right) urshifti left, right end,
1059         _slow_path_urshift,
1060         4)
1061
1062
1063 _llint_op_unsigned:
1064     traceExecution()
1065     loadisFromInstruction(1, t0)
1066     loadisFromInstruction(2, t1)
1067     loadConstantOrVariable(t1, t2)
1068     bilt t2, 0, .opUnsignedSlow
1069     storeq t2, [cfr, t0, 8]
1070     dispatch(3)
1071 .opUnsignedSlow:
1072     callOpcodeSlowPath(_slow_path_unsigned)
1073     dispatch(3)
1074
1075
1076 _llint_op_bitand:
1077     traceExecution()
1078     bitOp(
1079         macro (left, right) andi left, right end,
1080         _slow_path_bitand,
1081         5)
1082
1083
1084 _llint_op_bitxor:
1085     traceExecution()
1086     bitOp(
1087         macro (left, right) xori left, right end,
1088         _slow_path_bitxor,
1089         5)
1090
1091
1092 _llint_op_bitor:
1093     traceExecution()
1094     bitOp(
1095         macro (left, right) ori left, right end,
1096         _slow_path_bitor,
1097         5)
1098
1099
1100 _llint_op_overrides_has_instance:
1101     traceExecution()
1102     loadisFromInstruction(1, t3)
1103
1104     loadisFromInstruction(3, t1)
1105     loadConstantOrVariable(t1, t0)
1106     loadp CodeBlock[cfr], t2
1107     loadp CodeBlock::m_globalObject[t2], t2
1108     loadp JSGlobalObject::m_functionProtoHasInstanceSymbolFunction[t2], t2
1109     bqneq t0, t2, .opOverridesHasInstanceNotDefaultSymbol
1110
1111     loadisFromInstruction(2, t1)
1112     loadConstantOrVariable(t1, t0)
1113     tbz JSCell::m_flags[t0], ImplementsDefaultHasInstance, t1
1114     orq ValueFalse, t1
1115     storeq t1, [cfr, t3, 8]
1116     dispatch(4)
1117
1118 .opOverridesHasInstanceNotDefaultSymbol:
1119     storeq ValueTrue, [cfr, t3, 8]
1120     dispatch(4)
1121
1122
1123 _llint_op_instanceof_custom:
1124     traceExecution()
1125     callOpcodeSlowPath(_llint_slow_path_instanceof_custom)
1126     dispatch(5)
1127
1128
1129 _llint_op_is_empty:
1130     traceExecution()
1131     loadisFromInstruction(2, t1)
1132     loadisFromInstruction(1, t2)
1133     loadConstantOrVariable(t1, t0)
1134     cqeq t0, ValueEmpty, t3
1135     orq ValueFalse, t3
1136     storeq t3, [cfr, t2, 8]
1137     dispatch(3)
1138
1139
1140 _llint_op_is_undefined:
1141     traceExecution()
1142     loadisFromInstruction(2, t1)
1143     loadisFromInstruction(1, t2)
1144     loadConstantOrVariable(t1, t0)
1145     btqz t0, tagMask, .opIsUndefinedCell
1146     cqeq t0, ValueUndefined, t3
1147     orq ValueFalse, t3
1148     storeq t3, [cfr, t2, 8]
1149     dispatch(3)
1150 .opIsUndefinedCell:
1151     btbnz JSCell::m_flags[t0], MasqueradesAsUndefined, .masqueradesAsUndefined
1152     move ValueFalse, t1
1153     storeq t1, [cfr, t2, 8]
1154     dispatch(3)
1155 .masqueradesAsUndefined:
1156     loadStructureWithScratch(t0, t3, t1)
1157     loadp CodeBlock[cfr], t1
1158     loadp CodeBlock::m_globalObject[t1], t1
1159     cpeq Structure::m_globalObject[t3], t1, t0
1160     orq ValueFalse, t0
1161     storeq t0, [cfr, t2, 8]
1162     dispatch(3)
1163
1164
1165 _llint_op_is_boolean:
1166     traceExecution()
1167     loadisFromInstruction(2, t1)
1168     loadisFromInstruction(1, t2)
1169     loadConstantOrVariable(t1, t0)
1170     xorq ValueFalse, t0
1171     tqz t0, ~1, t0
1172     orq ValueFalse, t0
1173     storeq t0, [cfr, t2, 8]
1174     dispatch(3)
1175
1176
1177 _llint_op_is_number:
1178     traceExecution()
1179     loadisFromInstruction(2, t1)
1180     loadisFromInstruction(1, t2)
1181     loadConstantOrVariable(t1, t0)
1182     tqnz t0, tagTypeNumber, t1
1183     orq ValueFalse, t1
1184     storeq t1, [cfr, t2, 8]
1185     dispatch(3)
1186
1187
1188 _llint_op_is_string:
1189     traceExecution()
1190     loadisFromInstruction(2, t1)
1191     loadisFromInstruction(1, t2)
1192     loadConstantOrVariable(t1, t0)
1193     btqnz t0, tagMask, .opIsStringNotCell
1194     cbeq JSCell::m_type[t0], StringType, t1
1195     orq ValueFalse, t1
1196     storeq t1, [cfr, t2, 8]
1197     dispatch(3)
1198 .opIsStringNotCell:
1199     storeq ValueFalse, [cfr, t2, 8]
1200     dispatch(3)
1201
1202
1203 _llint_op_is_jsarray:
1204     traceExecution()
1205     loadisFromInstruction(2, t1)
1206     loadisFromInstruction(1, t2)
1207     loadConstantOrVariable(t1, t0)
1208     btqnz t0, tagMask, .opIsJSArrayNotCell
1209     cbeq JSCell::m_type[t0], ArrayType, t1
1210     orq ValueFalse, t1
1211     storeq t1, [cfr, t2, 8]
1212     dispatch(3)
1213 .opIsJSArrayNotCell:
1214     storeq ValueFalse, [cfr, t2, 8]
1215     dispatch(3)
1216
1217
1218 _llint_op_is_object:
1219     traceExecution()
1220     loadisFromInstruction(2, t1)
1221     loadisFromInstruction(1, t2)
1222     loadConstantOrVariable(t1, t0)
1223     btqnz t0, tagMask, .opIsObjectNotCell
1224     cbaeq JSCell::m_type[t0], ObjectType, t1
1225     orq ValueFalse, t1
1226     storeq t1, [cfr, t2, 8]
1227     dispatch(3)
1228 .opIsObjectNotCell:
1229     storeq ValueFalse, [cfr, t2, 8]
1230     dispatch(3)
1231
1232
1233 macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
1234     bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
1235     loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
1236     negi propertyOffsetAsInt
1237     sxi2q propertyOffsetAsInt, propertyOffsetAsInt
1238     jmp .ready
1239 .isInline:
1240     addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage
1241 .ready:
1242     loadq (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8], value
1243 end
1244
1245
1246 macro storePropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
1247     bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
1248     loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
1249     negi propertyOffsetAsInt
1250     sxi2q propertyOffsetAsInt, propertyOffsetAsInt
1251     jmp .ready
1252 .isInline:
1253     addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage
1254 .ready:
1255     storeq value, (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8]
1256 end
1257
1258 _llint_op_get_by_id:
1259     traceExecution()
1260     loadisFromInstruction(2, t0)
1261     loadConstantOrVariableCell(t0, t3, .opGetByIdSlow)
1262     loadi JSCell::m_structureID[t3], t1
1263     loadisFromInstruction(4, t2)
1264     bineq t2, t1, .opGetByIdSlow
1265     loadisFromInstruction(5, t1)
1266     loadisFromInstruction(1, t2)
1267     loadPropertyAtVariableOffset(t1, t3, t0)
1268     storeq t0, [cfr, t2, 8]
1269     valueProfile(t0, 8, t1)
1270     dispatch(9)
1271
1272 .opGetByIdSlow:
1273     callOpcodeSlowPath(_llint_slow_path_get_by_id)
1274     dispatch(9)
1275
1276
1277 _llint_op_get_by_id_proto_load:
1278     traceExecution()
1279     loadisFromInstruction(2, t0)
1280     loadConstantOrVariableCell(t0, t3, .opGetByIdProtoSlow)
1281     loadi JSCell::m_structureID[t3], t1
1282     loadisFromInstruction(4, t2)
1283     bineq t2, t1, .opGetByIdProtoSlow
1284     loadisFromInstruction(5, t1)
1285     loadpFromInstruction(6, t3)
1286     loadisFromInstruction(1, t2)
1287     loadPropertyAtVariableOffset(t1, t3, t0)
1288     storeq t0, [cfr, t2, 8]
1289     valueProfile(t0, 8, t1)
1290     dispatch(9)
1291
1292 .opGetByIdProtoSlow:
1293     callOpcodeSlowPath(_llint_slow_path_get_by_id)
1294     dispatch(9)
1295
1296
1297 _llint_op_get_by_id_unset:
1298     traceExecution()
1299     loadisFromInstruction(2, t0)
1300     loadConstantOrVariableCell(t0, t3, .opGetByIdUnsetSlow)
1301     loadi JSCell::m_structureID[t3], t1
1302     loadisFromInstruction(4, t2)
1303     bineq t2, t1, .opGetByIdUnsetSlow
1304     loadisFromInstruction(1, t2)
1305     storeq ValueUndefined, [cfr, t2, 8]
1306     valueProfile(ValueUndefined, 8, t1)
1307     dispatch(9)
1308
1309 .opGetByIdUnsetSlow:
1310     callOpcodeSlowPath(_llint_slow_path_get_by_id)
1311     dispatch(9)
1312
1313
1314 _llint_op_get_array_length:
1315     traceExecution()
1316     loadisFromInstruction(2, t0)
1317     loadpFromInstruction(4, t1)
1318     loadConstantOrVariableCell(t0, t3, .opGetArrayLengthSlow)
1319     move t3, t2
1320     arrayProfile(t2, t1, t0)
1321     btiz t2, IsArray, .opGetArrayLengthSlow
1322     btiz t2, IndexingShapeMask, .opGetArrayLengthSlow
1323     loadisFromInstruction(1, t1)
1324     loadp JSObject::m_butterfly[t3], t0
1325     loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
1326     bilt t0, 0, .opGetArrayLengthSlow
1327     orq tagTypeNumber, t0
1328     valueProfile(t0, 8, t2)
1329     storeq t0, [cfr, t1, 8]
1330     dispatch(9)
1331
1332 .opGetArrayLengthSlow:
1333     callOpcodeSlowPath(_llint_slow_path_get_by_id)
1334     dispatch(9)
1335
1336
1337 _llint_op_put_by_id:
1338     traceExecution()
1339     writeBarrierOnOperands(1, 3)
1340     loadisFromInstruction(1, t3)
1341     loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
1342     loadisFromInstruction(4, t2)
1343     bineq t2, JSCell::m_structureID[t0], .opPutByIdSlow
1344
1345     # At this point, we have:
1346     # t2 -> current structure ID
1347     # t0 -> object base
1348
1349     loadisFromInstruction(3, t1)
1350     loadConstantOrVariable(t1, t3)
1351
1352     loadpFromInstruction(8, t1)
1353
1354     # At this point, we have:
1355     # t0 -> object base
1356     # t1 -> put by id flags
1357     # t2 -> current structure ID
1358     # t3 -> value to put
1359
1360     btpnz t1, PutByIdPrimaryTypeMask, .opPutByIdTypeCheckObjectWithStructureOrOther
1361
1362     # We have one of the non-structure type checks. Find out which one.
1363     andp PutByIdSecondaryTypeMask, t1
1364     bplt t1, PutByIdSecondaryTypeString, .opPutByIdTypeCheckLessThanString
1365
1366     # We are one of the following: String, Symbol, Object, ObjectOrOther, Top
1367     bplt t1, PutByIdSecondaryTypeObjectOrOther, .opPutByIdTypeCheckLessThanObjectOrOther
1368
1369     # We are either ObjectOrOther or Top.
1370     bpeq t1, PutByIdSecondaryTypeTop, .opPutByIdDoneCheckingTypes
1371
1372     # Check if we are ObjectOrOther.
1373     btqz t3, tagMask, .opPutByIdTypeCheckObject
1374 .opPutByIdTypeCheckOther:
1375     andq ~TagBitUndefined, t3
1376     bqeq t3, ValueNull, .opPutByIdDoneCheckingTypes
1377     jmp .opPutByIdSlow
1378
1379 .opPutByIdTypeCheckLessThanObjectOrOther:
1380     # We are either String, Symbol or Object.
1381     btqnz t3, tagMask, .opPutByIdSlow
1382     bpeq t1, PutByIdSecondaryTypeObject, .opPutByIdTypeCheckObject
1383     bpeq t1, PutByIdSecondaryTypeSymbol, .opPutByIdTypeCheckSymbol
1384     bbeq JSCell::m_type[t3], StringType, .opPutByIdDoneCheckingTypes
1385     jmp .opPutByIdSlow
1386 .opPutByIdTypeCheckObject:
1387     bbaeq JSCell::m_type[t3], ObjectType, .opPutByIdDoneCheckingTypes
1388     jmp .opPutByIdSlow
1389 .opPutByIdTypeCheckSymbol:
1390     bbeq JSCell::m_type[t3], SymbolType, .opPutByIdDoneCheckingTypes
1391     jmp .opPutByIdSlow
1392
1393 .opPutByIdTypeCheckLessThanString:
1394     # We are one of the following: Bottom, Boolean, Other, Int32, Number
1395     bplt t1, PutByIdSecondaryTypeInt32, .opPutByIdTypeCheckLessThanInt32
1396
1397     # We are either Int32 or Number.
1398     bpeq t1, PutByIdSecondaryTypeNumber, .opPutByIdTypeCheckNumber
1399
1400     bqaeq t3, tagTypeNumber, .opPutByIdDoneCheckingTypes
1401     jmp .opPutByIdSlow
1402
1403 .opPutByIdTypeCheckNumber:
1404     btqnz t3, tagTypeNumber, .opPutByIdDoneCheckingTypes
1405     jmp .opPutByIdSlow
1406
1407 .opPutByIdTypeCheckLessThanInt32:
1408     # We are one of the following: Bottom, Boolean, Other.
1409     bpneq t1, PutByIdSecondaryTypeBoolean, .opPutByIdTypeCheckBottomOrOther
1410     xorq ValueFalse, t3
1411     btqz t3, ~1, .opPutByIdDoneCheckingTypes
1412     jmp .opPutByIdSlow
1413
1414 .opPutByIdTypeCheckBottomOrOther:
1415     bpeq t1, PutByIdSecondaryTypeOther, .opPutByIdTypeCheckOther
1416     jmp .opPutByIdSlow
1417
1418 .opPutByIdTypeCheckObjectWithStructureOrOther:
1419     btqz t3, tagMask, .opPutByIdTypeCheckObjectWithStructure
1420     btpnz t1, PutByIdPrimaryTypeObjectWithStructureOrOther, .opPutByIdTypeCheckOther
1421     jmp .opPutByIdSlow
1422
1423 .opPutByIdTypeCheckObjectWithStructure:
1424     urshiftp 3, t1
1425     bineq t1, JSCell::m_structureID[t3], .opPutByIdSlow
1426
1427 .opPutByIdDoneCheckingTypes:
1428     loadisFromInstruction(6, t1)
1429     
1430     btiz t1, .opPutByIdNotTransition
1431
1432     # This is the transition case. t1 holds the new structureID. t2 holds the old structure ID.
1433     # If we have a chain, we need to check it. t0 is the base. We may clobber t1 to use it as
1434     # scratch.
1435     loadpFromInstruction(7, t3)
1436     btpz t3, .opPutByIdTransitionDirect
1437
1438     loadp StructureChain::m_vector[t3], t3
1439     assert(macro (ok) btpnz t3, ok end)
1440
1441     structureIDToStructureWithScratch(t2, t1)
1442     loadq Structure::m_prototype[t2], t2
1443     bqeq t2, ValueNull, .opPutByIdTransitionChainDone
1444 .opPutByIdTransitionChainLoop:
1445     # At this point, t2 contains a prototye, and [t3] contains the Structure* that we want that
1446     # prototype to have. We don't want to have to load the Structure* for t2. Instead, we load
1447     # the Structure* from [t3], and then we compare its id to the id in the header of t2.
1448     loadp [t3], t1
1449     loadi JSCell::m_structureID[t2], t2
1450     # Now, t1 has the Structure* and t2 has the StructureID that we want that Structure* to have.
1451     bineq t2, Structure::m_blob + StructureIDBlob::u.fields.structureID[t1], .opPutByIdSlow
1452     addp 8, t3
1453     loadq Structure::m_prototype[t1], t2
1454     bqneq t2, ValueNull, .opPutByIdTransitionChainLoop
1455
1456 .opPutByIdTransitionChainDone:
1457     # Reload the new structure, since we clobbered it above.
1458     loadisFromInstruction(6, t1)
1459
1460 .opPutByIdTransitionDirect:
1461     storei t1, JSCell::m_structureID[t0]
1462
1463 .opPutByIdNotTransition:
1464     # The only thing live right now is t0, which holds the base.
1465     loadisFromInstruction(3, t1)
1466     loadConstantOrVariable(t1, t2)
1467     loadisFromInstruction(5, t1)
1468     storePropertyAtVariableOffset(t1, t0, t2)
1469     dispatch(9)
1470
1471 .opPutByIdSlow:
1472     callOpcodeSlowPath(_llint_slow_path_put_by_id)
1473     dispatch(9)
1474
1475 macro finishGetByVal(result, scratch)
1476     loadisFromInstruction(1, scratch)
1477     storeq result, [cfr, scratch, 8]
1478     valueProfile(result, 5, scratch)
1479     dispatch(6)
1480 end
1481
1482 macro finishIntGetByVal(result, scratch)
1483     orq tagTypeNumber, result
1484     finishGetByVal(result, scratch)
1485 end
1486
1487 macro finishDoubleGetByVal(result, scratch1, scratch2)
1488     fd2q result, scratch1
1489     subq tagTypeNumber, scratch1
1490     finishGetByVal(scratch1, scratch2)
1491 end
1492
1493 _llint_op_get_by_val:
1494     traceExecution()
1495     loadisFromInstruction(2, t2)
1496     loadConstantOrVariableCell(t2, t0, .opGetByValSlow)
1497     loadpFromInstruction(4, t3)
1498     move t0, t2
1499     arrayProfile(t2, t3, t1)
1500     loadisFromInstruction(3, t3)
1501     loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
1502     sxi2q t1, t1
1503     loadp JSObject::m_butterfly[t0], t3
1504     andi IndexingShapeMask, t2
1505     bieq t2, Int32Shape, .opGetByValIsContiguous
1506     bineq t2, ContiguousShape, .opGetByValNotContiguous
1507 .opGetByValIsContiguous:
1508
1509     biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
1510     loadisFromInstruction(1, t0)
1511     loadq [t3, t1, 8], t2
1512     btqz t2, .opGetByValOutOfBounds
1513     jmp .opGetByValDone
1514
1515 .opGetByValNotContiguous:
1516     bineq t2, DoubleShape, .opGetByValNotDouble
1517     biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
1518     loadis 8[PB, PC, 8], t0
1519     loadd [t3, t1, 8], ft0
1520     bdnequn ft0, ft0, .opGetByValOutOfBounds
1521     fd2q ft0, t2
1522     subq tagTypeNumber, t2
1523     jmp .opGetByValDone
1524     
1525 .opGetByValNotDouble:
1526     subi ArrayStorageShape, t2
1527     bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValNotIndexedStorage
1528     biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t3], .opGetByValOutOfBounds
1529     loadisFromInstruction(1, t0)
1530     loadq ArrayStorage::m_vector[t3, t1, 8], t2
1531     btqz t2, .opGetByValOutOfBounds
1532
1533 .opGetByValDone:
1534     storeq t2, [cfr, t0, 8]
1535     valueProfile(t2, 5, t0)
1536     dispatch(6)
1537
1538 .opGetByValOutOfBounds:
1539     loadpFromInstruction(4, t0)
1540     storeb 1, ArrayProfile::m_outOfBounds[t0]
1541
1542 .opGetByValNotIndexedStorage:
1543     # First lets check if we even have a typed array. This lets us do some boilerplate up front.
1544     loadb JSCell::m_type[t0], t2
1545     subi FirstArrayType, t2
1546     bia t2, LastArrayType - FirstArrayType, .opGetByValSlow
1547     
1548     # Sweet, now we know that we have a typed array. Do some basic things now.
1549     loadp JSArrayBufferView::m_vector[t0], t3
1550     biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow
1551     
1552     # Now bisect through the various types. Note that we can treat Uint8ArrayType and
1553     # Uint8ClampedArrayType the same.
1554     bia t2, Uint8ClampedArrayType - FirstArrayType, .opGetByValAboveUint8ClampedArray
1555     
1556     # We have one of Int8ArrayType .. Uint8ClampedArrayType.
1557     bia t2, Int16ArrayType - FirstArrayType, .opGetByValInt32ArrayOrUint8Array
1558     
1559     # We have one of Int8ArrayType or Int16ArrayType
1560     bineq t2, Int8ArrayType - FirstArrayType, .opGetByValInt16Array
1561     
1562     # We have Int8ArrayType
1563     loadbs [t3, t1], t0
1564     finishIntGetByVal(t0, t1)
1565
1566 .opGetByValInt16Array:
1567     loadhs [t3, t1, 2], t0
1568     finishIntGetByVal(t0, t1)
1569
1570 .opGetByValInt32ArrayOrUint8Array:
1571     # We have one of Int16Array, Uint8Array, or Uint8ClampedArray.
1572     bieq t2, Int32ArrayType - FirstArrayType, .opGetByValInt32Array
1573     
1574     # We have either Uint8Array or Uint8ClampedArray. They behave the same so that's cool.
1575     loadb [t3, t1], t0
1576     finishIntGetByVal(t0, t1)
1577
1578 .opGetByValInt32Array:
1579     loadi [t3, t1, 4], t0
1580     finishIntGetByVal(t0, t1)
1581
1582 .opGetByValAboveUint8ClampedArray:
1583     # We have one of Uint16ArrayType .. Float64ArrayType.
1584     bia t2, Uint32ArrayType - FirstArrayType, .opGetByValAboveUint32Array
1585     
1586     # We have either Uint16ArrayType or Uint32ArrayType.
1587     bieq t2, Uint32ArrayType - FirstArrayType, .opGetByValUint32Array
1588
1589     # We have Uint16ArrayType.
1590     loadh [t3, t1, 2], t0
1591     finishIntGetByVal(t0, t1)
1592
1593 .opGetByValUint32Array:
1594     # This is the hardest part because of large unsigned values.
1595     loadi [t3, t1, 4], t0
1596     bilt t0, 0, .opGetByValSlow # This case is still awkward to implement in LLInt.
1597     finishIntGetByVal(t0, t1)
1598
1599 .opGetByValAboveUint32Array:
1600     # We have one of Float32ArrayType or Float64ArrayType. Sadly, we cannot handle Float32Array
1601     # inline yet. That would require some offlineasm changes.
1602     bieq t2, Float32ArrayType - FirstArrayType, .opGetByValSlow
1603
1604     # We have Float64ArrayType.
1605     loadd [t3, t1, 8], ft0
1606     bdnequn ft0, ft0, .opGetByValSlow
1607     finishDoubleGetByVal(ft0, t0, t1)
1608
1609 .opGetByValSlow:
1610     callOpcodeSlowPath(_llint_slow_path_get_by_val)
1611     dispatch(6)
1612
1613
1614 macro contiguousPutByVal(storeCallback)
1615     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
1616 .storeResult:
1617     loadisFromInstruction(3, t2)
1618     storeCallback(t2, t1, [t0, t3, 8])
1619     dispatch(5)
1620
1621 .outOfBounds:
1622     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
1623     loadp 32[PB, PC, 8], t2
1624     storeb 1, ArrayProfile::m_mayStoreToHole[t2]
1625     addi 1, t3, t2
1626     storei t2, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
1627     jmp .storeResult
1628 end
1629
1630 macro putByVal(slowPath)
1631     traceExecution()
1632     writeBarrierOnOperands(1, 3)
1633     loadisFromInstruction(1, t0)
1634     loadConstantOrVariableCell(t0, t1, .opPutByValSlow)
1635     loadpFromInstruction(4, t3)
1636     move t1, t2
1637     arrayProfile(t2, t3, t0)
1638     loadisFromInstruction(2, t0)
1639     loadConstantOrVariableInt32(t0, t3, .opPutByValSlow)
1640     sxi2q t3, t3
1641     loadp JSObject::m_butterfly[t1], t0
1642     andi IndexingShapeMask, t2
1643     bineq t2, Int32Shape, .opPutByValNotInt32
1644     contiguousPutByVal(
1645         macro (operand, scratch, address)
1646             loadConstantOrVariable(operand, scratch)
1647             bpb scratch, tagTypeNumber, .opPutByValSlow
1648             storep scratch, address
1649         end)
1650
1651 .opPutByValNotInt32:
1652     bineq t2, DoubleShape, .opPutByValNotDouble
1653     contiguousPutByVal(
1654         macro (operand, scratch, address)
1655             loadConstantOrVariable(operand, scratch)
1656             bqb scratch, tagTypeNumber, .notInt
1657             ci2d scratch, ft0
1658             jmp .ready
1659         .notInt:
1660             addp tagTypeNumber, scratch
1661             fq2d scratch, ft0
1662             bdnequn ft0, ft0, .opPutByValSlow
1663         .ready:
1664             stored ft0, address
1665         end)
1666
1667 .opPutByValNotDouble:
1668     bineq t2, ContiguousShape, .opPutByValNotContiguous
1669     contiguousPutByVal(
1670         macro (operand, scratch, address)
1671             loadConstantOrVariable(operand, scratch)
1672             storep scratch, address
1673         end)
1674
1675 .opPutByValNotContiguous:
1676     bineq t2, ArrayStorageShape, .opPutByValSlow
1677     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
1678     btqz ArrayStorage::m_vector[t0, t3, 8], .opPutByValArrayStorageEmpty
1679 .opPutByValArrayStorageStoreResult:
1680     loadisFromInstruction(3, t2)
1681     loadConstantOrVariable(t2, t1)
1682     storeq t1, ArrayStorage::m_vector[t0, t3, 8]
1683     dispatch(5)
1684
1685 .opPutByValArrayStorageEmpty:
1686     loadpFromInstruction(4, t1)
1687     storeb 1, ArrayProfile::m_mayStoreToHole[t1]
1688     addi 1, ArrayStorage::m_numValuesInVector[t0]
1689     bib t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .opPutByValArrayStorageStoreResult
1690     addi 1, t3, t1
1691     storei t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
1692     jmp .opPutByValArrayStorageStoreResult
1693
1694 .opPutByValOutOfBounds:
1695     loadpFromInstruction(4, t0)
1696     storeb 1, ArrayProfile::m_outOfBounds[t0]
1697 .opPutByValSlow:
1698     callOpcodeSlowPath(slowPath)
1699     dispatch(5)
1700 end
1701
1702 _llint_op_put_by_val:
1703     putByVal(_llint_slow_path_put_by_val)
1704
1705 _llint_op_put_by_val_direct:
1706     putByVal(_llint_slow_path_put_by_val_direct)
1707
1708
1709 _llint_op_jmp:
1710     traceExecution()
1711     dispatchIntIndirect(1)
1712
1713
1714 macro jumpTrueOrFalse(conditionOp, slow)
1715     loadisFromInstruction(1, t1)
1716     loadConstantOrVariable(t1, t0)
1717     xorq ValueFalse, t0
1718     btqnz t0, -1, .slow
1719     conditionOp(t0, .target)
1720     dispatch(3)
1721
1722 .target:
1723     dispatchIntIndirect(2)
1724
1725 .slow:
1726     callOpcodeSlowPath(slow)
1727     dispatch(0)
1728 end
1729
1730
1731 macro equalNull(cellHandler, immediateHandler)
1732     loadisFromInstruction(1, t0)
1733     assertNotConstant(t0)
1734     loadq [cfr, t0, 8], t0
1735     btqnz t0, tagMask, .immediate
1736     loadStructureWithScratch(t0, t2, t1)
1737     cellHandler(t2, JSCell::m_flags[t0], .target)
1738     dispatch(3)
1739
1740 .target:
1741     dispatchIntIndirect(2)
1742
1743 .immediate:
1744     andq ~TagBitUndefined, t0
1745     immediateHandler(t0, .target)
1746     dispatch(3)
1747 end
1748
1749 _llint_op_jeq_null:
1750     traceExecution()
1751     equalNull(
1752         macro (structure, value, target) 
1753             btbz value, MasqueradesAsUndefined, .notMasqueradesAsUndefined
1754             loadp CodeBlock[cfr], t0
1755             loadp CodeBlock::m_globalObject[t0], t0
1756             bpeq Structure::m_globalObject[structure], t0, target
1757 .notMasqueradesAsUndefined:
1758         end,
1759         macro (value, target) bqeq value, ValueNull, target end)
1760
1761
1762 _llint_op_jneq_null:
1763     traceExecution()
1764     equalNull(
1765         macro (structure, value, target) 
1766             btbz value, MasqueradesAsUndefined, target
1767             loadp CodeBlock[cfr], t0
1768             loadp CodeBlock::m_globalObject[t0], t0
1769             bpneq Structure::m_globalObject[structure], t0, target
1770         end,
1771         macro (value, target) bqneq value, ValueNull, target end)
1772
1773
1774 _llint_op_jneq_ptr:
1775     traceExecution()
1776     loadisFromInstruction(1, t0)
1777     loadisFromInstruction(2, t1)
1778     loadp CodeBlock[cfr], t2
1779     loadp CodeBlock::m_globalObject[t2], t2
1780     loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1
1781     bpneq t1, [cfr, t0, 8], .opJneqPtrTarget
1782     dispatch(5)
1783
1784 .opJneqPtrTarget:
1785     storei 1, 32[PB, PC, 8]
1786     dispatchIntIndirect(3)
1787
1788
1789 macro compare(integerCompare, doubleCompare, slowPath)
1790     loadisFromInstruction(1, t2)
1791     loadisFromInstruction(2, t3)
1792     loadConstantOrVariable(t2, t0)
1793     loadConstantOrVariable(t3, t1)
1794     bqb t0, tagTypeNumber, .op1NotInt
1795     bqb t1, tagTypeNumber, .op2NotInt
1796     integerCompare(t0, t1, .jumpTarget)
1797     dispatch(4)
1798
1799 .op1NotInt:
1800     btqz t0, tagTypeNumber, .slow
1801     bqb t1, tagTypeNumber, .op1NotIntOp2NotInt
1802     ci2d t1, ft1
1803     jmp .op1NotIntReady
1804 .op1NotIntOp2NotInt:
1805     btqz t1, tagTypeNumber, .slow
1806     addq tagTypeNumber, t1
1807     fq2d t1, ft1
1808 .op1NotIntReady:
1809     addq tagTypeNumber, t0
1810     fq2d t0, ft0
1811     doubleCompare(ft0, ft1, .jumpTarget)
1812     dispatch(4)
1813
1814 .op2NotInt:
1815     ci2d t0, ft0
1816     btqz t1, tagTypeNumber, .slow
1817     addq tagTypeNumber, t1
1818     fq2d t1, ft1
1819     doubleCompare(ft0, ft1, .jumpTarget)
1820     dispatch(4)
1821
1822 .jumpTarget:
1823     dispatchIntIndirect(3)
1824
1825 .slow:
1826     callOpcodeSlowPath(slowPath)
1827     dispatch(0)
1828 end
1829
1830
1831 _llint_op_switch_imm:
1832     traceExecution()
1833     loadisFromInstruction(3, t2)
1834     loadisFromInstruction(1, t3)
1835     loadConstantOrVariable(t2, t1)
1836     loadp CodeBlock[cfr], t2
1837     loadp CodeBlock::m_rareData[t2], t2
1838     muli sizeof SimpleJumpTable, t3    # FIXME: would be nice to peephole this!
1839     loadp CodeBlock::RareData::m_switchJumpTables + VectorBufferOffset[t2], t2
1840     addp t3, t2
1841     bqb t1, tagTypeNumber, .opSwitchImmNotInt
1842     subi SimpleJumpTable::min[t2], t1
1843     biaeq t1, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
1844     loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
1845     loadis [t3, t1, 4], t1
1846     btiz t1, .opSwitchImmFallThrough
1847     dispatch(t1)
1848
1849 .opSwitchImmNotInt:
1850     btqnz t1, tagTypeNumber, .opSwitchImmSlow   # Go slow if it's a double.
1851 .opSwitchImmFallThrough:
1852     dispatchIntIndirect(2)
1853
1854 .opSwitchImmSlow:
1855     callOpcodeSlowPath(_llint_slow_path_switch_imm)
1856     dispatch(0)
1857
1858
1859 _llint_op_switch_char:
1860     traceExecution()
1861     loadisFromInstruction(3, t2)
1862     loadisFromInstruction(1, t3)
1863     loadConstantOrVariable(t2, t1)
1864     loadp CodeBlock[cfr], t2
1865     loadp CodeBlock::m_rareData[t2], t2
1866     muli sizeof SimpleJumpTable, t3
1867     loadp CodeBlock::RareData::m_switchJumpTables + VectorBufferOffset[t2], t2
1868     addp t3, t2
1869     btqnz t1, tagMask, .opSwitchCharFallThrough
1870     bbneq JSCell::m_type[t1], StringType, .opSwitchCharFallThrough
1871     bineq JSString::m_length[t1], 1, .opSwitchCharFallThrough
1872     loadp JSString::m_value[t1], t0
1873     btpz  t0, .opSwitchOnRope
1874     loadp StringImpl::m_data8[t0], t1
1875     btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
1876     loadh [t1], t0
1877     jmp .opSwitchCharReady
1878 .opSwitchChar8Bit:
1879     loadb [t1], t0
1880 .opSwitchCharReady:
1881     subi SimpleJumpTable::min[t2], t0
1882     biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
1883     loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
1884     loadis [t2, t0, 4], t1
1885     btiz t1, .opSwitchCharFallThrough
1886     dispatch(t1)
1887
1888 .opSwitchCharFallThrough:
1889     dispatchIntIndirect(2)
1890
1891 .opSwitchOnRope:
1892     callOpcodeSlowPath(_llint_slow_path_switch_char)
1893     dispatch(0)
1894
1895
1896 macro arrayProfileForCall()
1897     loadisFromInstruction(4, t3)
1898     negp t3
1899     loadq ThisArgumentOffset[cfr, t3, 8], t0
1900     btqnz t0, tagMask, .done
1901     loadpFromInstruction((CallOpCodeSize - 2), t1)
1902     loadi JSCell::m_structureID[t0], t3
1903     storei t3, ArrayProfile::m_lastSeenStructureID[t1]
1904 .done:
1905 end
1906
1907 macro doCall(slowPath, prepareCall)
1908     loadisFromInstruction(2, t0)
1909     loadpFromInstruction(5, t1)
1910     loadp LLIntCallLinkInfo::callee[t1], t2
1911     loadConstantOrVariable(t0, t3)
1912     bqneq t3, t2, .opCallSlow
1913     loadisFromInstruction(4, t3)
1914     lshifti 3, t3
1915     negp t3
1916     addp cfr, t3
1917     storeq t2, Callee[t3]
1918     loadisFromInstruction(3, t2)
1919     storei PC, ArgumentCount + TagOffset[cfr]
1920     storei t2, ArgumentCount + PayloadOffset[t3]
1921     move t3, sp
1922     prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
1923     callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
1924
1925 .opCallSlow:
1926     slowPathForCall(slowPath, prepareCall)
1927 end
1928
1929 _llint_op_ret:
1930     traceExecution()
1931     checkSwitchToJITForEpilogue()
1932     loadisFromInstruction(1, t2)
1933     loadConstantOrVariable(t2, r0)
1934     doReturn()
1935
1936
1937 _llint_op_to_primitive:
1938     traceExecution()
1939     loadisFromInstruction(2, t2)
1940     loadisFromInstruction(1, t3)
1941     loadConstantOrVariable(t2, t0)
1942     btqnz t0, tagMask, .opToPrimitiveIsImm
1943     bbaeq JSCell::m_type[t0], ObjectType, .opToPrimitiveSlowCase
1944 .opToPrimitiveIsImm:
1945     storeq t0, [cfr, t3, 8]
1946     dispatch(3)
1947
1948 .opToPrimitiveSlowCase:
1949     callOpcodeSlowPath(_slow_path_to_primitive)
1950     dispatch(3)
1951
1952
1953 _llint_op_catch:
1954     # This is where we end up from the JIT's throw trampoline (because the
1955     # machine code return address will be set to _llint_op_catch), and from
1956     # the interpreter's throw trampoline (see _llint_throw_trampoline).
1957     # The throwing code must have known that we were throwing to the interpreter,
1958     # and have set VM::targetInterpreterPCForThrow.
1959     loadp Callee[cfr], t3
1960     andp MarkedBlockMask, t3
1961     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
1962     restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0)
1963     loadp VM::callFrameForCatch[t3], cfr
1964     storep 0, VM::callFrameForCatch[t3]
1965     restoreStackPointerAfterCall()
1966
1967     loadp CodeBlock[cfr], PB
1968     loadp CodeBlock::m_instructions[PB], PB
1969     loadp VM::targetInterpreterPCForThrow[t3], PC
1970     subp PB, PC
1971     rshiftp 3, PC
1972
1973     callOpcodeSlowPath(_llint_slow_path_check_if_exception_is_uncatchable_and_notify_profiler)
1974     bpeq r1, 0, .isCatchableException
1975     jmp _llint_throw_from_slow_path_trampoline
1976
1977 .isCatchableException:
1978     loadp Callee[cfr], t3
1979     andp MarkedBlockMask, t3
1980     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
1981
1982     loadq VM::m_exception[t3], t0
1983     storeq 0, VM::m_exception[t3]
1984     loadisFromInstruction(1, t2)
1985     storeq t0, [cfr, t2, 8]
1986
1987     loadq Exception::m_value[t0], t3
1988     loadisFromInstruction(2, t2)
1989     storeq t3, [cfr, t2, 8]
1990
1991     traceExecution()
1992     dispatch(3)
1993
1994
1995 _llint_op_end:
1996     traceExecution()
1997     checkSwitchToJITForEpilogue()
1998     loadisFromInstruction(1, t0)
1999     assertNotConstant(t0)
2000     loadq [cfr, t0, 8], r0
2001     doReturn()
2002
2003
2004 _llint_throw_from_slow_path_trampoline:
2005     loadp Callee[cfr], t1
2006     andp MarkedBlockMask, t1
2007     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
2008     copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(t1, t2)
2009
2010     callSlowPath(_llint_slow_path_handle_exception)
2011
2012     # When throwing from the interpreter (i.e. throwing from LLIntSlowPaths), so
2013     # the throw target is not necessarily interpreted code, we come to here.
2014     # This essentially emulates the JIT's throwing protocol.
2015     loadp Callee[cfr], t1
2016     andp MarkedBlockMask, t1
2017     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
2018     jmp VM::targetMachinePCForThrow[t1]
2019
2020
2021 _llint_throw_during_call_trampoline:
2022     preserveReturnAddressAfterCall(t2)
2023     jmp _llint_throw_from_slow_path_trampoline
2024
2025
2026 macro nativeCallTrampoline(executableOffsetToFunction)
2027
2028     functionPrologue()
2029     storep 0, CodeBlock[cfr]
2030     loadp Callee[cfr], t0
2031     andp MarkedBlockMask, t0, t1
2032     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
2033     storep cfr, VM::topCallFrame[t1]
2034     if ARM64 or C_LOOP
2035         storep lr, ReturnPC[cfr]
2036     end
2037     move cfr, a0
2038     loadp Callee[cfr], t1
2039     loadp JSFunction::m_executable[t1], t1
2040     checkStackPointerAlignment(t3, 0xdead0001)
2041     if C_LOOP
2042         cloopCallNative executableOffsetToFunction[t1]
2043     else
2044         if X86_64_WIN
2045             subp 32, sp
2046         end
2047         call executableOffsetToFunction[t1]
2048         if X86_64_WIN
2049             addp 32, sp
2050         end
2051     end
2052     loadp Callee[cfr], t3
2053     andp MarkedBlockMask, t3
2054     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
2055
2056     functionEpilogue()
2057
2058     btqnz VM::m_exception[t3], .handleException
2059     ret
2060
2061 .handleException:
2062     storep cfr, VM::topCallFrame[t3]
2063     restoreStackPointerAfterCall()
2064     jmp _llint_throw_from_slow_path_trampoline
2065 end
2066
2067 macro getConstantScope(dst)
2068     loadpFromInstruction(6, t0)
2069     loadisFromInstruction(dst, t1)
2070     storeq t0, [cfr, t1, 8]
2071 end
2072
2073 macro varInjectionCheck(slowPath)
2074     loadp CodeBlock[cfr], t0
2075     loadp CodeBlock::m_globalObject[t0], t0
2076     loadp JSGlobalObject::m_varInjectionWatchpoint[t0], t0
2077     bbeq WatchpointSet::m_state[t0], IsInvalidated, slowPath
2078 end
2079
2080 macro resolveScope()
2081     loadisFromInstruction(5, t2)
2082     loadisFromInstruction(2, t0)
2083     loadp [cfr, t0, 8], t0
2084     btiz t2, .resolveScopeLoopEnd
2085
2086 .resolveScopeLoop:
2087     loadp JSScope::m_next[t0], t0
2088     subi 1, t2
2089     btinz t2, .resolveScopeLoop
2090
2091 .resolveScopeLoopEnd:
2092     loadisFromInstruction(1, t1)
2093     storeq t0, [cfr, t1, 8]
2094 end
2095
2096
2097 _llint_op_resolve_scope:
2098     traceExecution()
2099     loadisFromInstruction(4, t0)
2100
2101 #rGlobalProperty:
2102     bineq t0, GlobalProperty, .rGlobalVar
2103     getConstantScope(1)
2104     dispatch(7)
2105
2106 .rGlobalVar:
2107     bineq t0, GlobalVar, .rGlobalLexicalVar
2108     getConstantScope(1)
2109     dispatch(7)
2110
2111 .rGlobalLexicalVar:
2112     bineq t0, GlobalLexicalVar, .rClosureVar
2113     getConstantScope(1)
2114     dispatch(7)
2115
2116 .rClosureVar:
2117     bineq t0, ClosureVar, .rModuleVar
2118     resolveScope()
2119     dispatch(7)
2120
2121 .rModuleVar:
2122     bineq t0, ModuleVar, .rGlobalPropertyWithVarInjectionChecks
2123     getConstantScope(1)
2124     dispatch(7)
2125
2126 .rGlobalPropertyWithVarInjectionChecks:
2127     bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
2128     varInjectionCheck(.rDynamic)
2129     getConstantScope(1)
2130     dispatch(7)
2131
2132 .rGlobalVarWithVarInjectionChecks:
2133     bineq t0, GlobalVarWithVarInjectionChecks, .rGlobalLexicalVarWithVarInjectionChecks
2134     varInjectionCheck(.rDynamic)
2135     getConstantScope(1)
2136     dispatch(7)
2137
2138 .rGlobalLexicalVarWithVarInjectionChecks:
2139     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
2140     varInjectionCheck(.rDynamic)
2141     getConstantScope(1)
2142     dispatch(7)
2143
2144 .rClosureVarWithVarInjectionChecks:
2145     bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
2146     varInjectionCheck(.rDynamic)
2147     resolveScope()
2148     dispatch(7)
2149
2150 .rDynamic:
2151     callOpcodeSlowPath(_slow_path_resolve_scope)
2152     dispatch(7)
2153
2154
2155 macro loadWithStructureCheck(operand, slowPath)
2156     loadisFromInstruction(operand, t0)
2157     loadq [cfr, t0, 8], t0
2158     loadStructureWithScratch(t0, t2, t1)
2159     loadpFromInstruction(5, t1)
2160     bpneq t2, t1, slowPath
2161 end
2162
2163 macro getProperty()
2164     loadisFromInstruction(6, t1)
2165     loadPropertyAtVariableOffset(t1, t0, t2)
2166     valueProfile(t2, 7, t0)
2167     loadisFromInstruction(1, t0)
2168     storeq t2, [cfr, t0, 8]
2169 end
2170
2171 macro getGlobalVar(tdzCheckIfNecessary)
2172     loadpFromInstruction(6, t0)
2173     loadq [t0], t0
2174     tdzCheckIfNecessary(t0)
2175     valueProfile(t0, 7, t1)
2176     loadisFromInstruction(1, t1)
2177     storeq t0, [cfr, t1, 8]
2178 end
2179
2180 macro getClosureVar()
2181     loadisFromInstruction(6, t1)
2182     loadq JSEnvironmentRecord_variables[t0, t1, 8], t0
2183     valueProfile(t0, 7, t1)
2184     loadisFromInstruction(1, t1)
2185     storeq t0, [cfr, t1, 8]
2186 end
2187
2188 _llint_op_get_from_scope:
2189     traceExecution()
2190     loadisFromInstruction(4, t0)
2191     andi ResolveTypeMask, t0
2192
2193 #gGlobalProperty:
2194     bineq t0, GlobalProperty, .gGlobalVar
2195     loadWithStructureCheck(2, .gDynamic)
2196     getProperty()
2197     dispatch(8)
2198
2199 .gGlobalVar:
2200     bineq t0, GlobalVar, .gGlobalLexicalVar
2201     getGlobalVar(macro(v) end)
2202     dispatch(8)
2203
2204 .gGlobalLexicalVar:
2205     bineq t0, GlobalLexicalVar, .gClosureVar
2206     getGlobalVar(
2207         macro (value)
2208             bqeq value, ValueEmpty, .gDynamic
2209         end)
2210     dispatch(8)
2211
2212 .gClosureVar:
2213     bineq t0, ClosureVar, .gGlobalPropertyWithVarInjectionChecks
2214     loadVariable(2, t0)
2215     getClosureVar()
2216     dispatch(8)
2217
2218 .gGlobalPropertyWithVarInjectionChecks:
2219     bineq t0, GlobalPropertyWithVarInjectionChecks, .gGlobalVarWithVarInjectionChecks
2220     loadWithStructureCheck(2, .gDynamic)
2221     getProperty()
2222     dispatch(8)
2223
2224 .gGlobalVarWithVarInjectionChecks:
2225     bineq t0, GlobalVarWithVarInjectionChecks, .gGlobalLexicalVarWithVarInjectionChecks
2226     varInjectionCheck(.gDynamic)
2227     getGlobalVar(macro(v) end)
2228     dispatch(8)
2229
2230 .gGlobalLexicalVarWithVarInjectionChecks:
2231     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
2232     varInjectionCheck(.gDynamic)
2233     getGlobalVar(
2234         macro (value)
2235             bqeq value, ValueEmpty, .gDynamic
2236         end)
2237     dispatch(8)
2238
2239 .gClosureVarWithVarInjectionChecks:
2240     bineq t0, ClosureVarWithVarInjectionChecks, .gDynamic
2241     varInjectionCheck(.gDynamic)
2242     loadVariable(2, t0)
2243     getClosureVar()
2244     dispatch(8)
2245
2246 .gDynamic:
2247     callOpcodeSlowPath(_llint_slow_path_get_from_scope)
2248     dispatch(8)
2249
2250
2251 macro putProperty()
2252     loadisFromInstruction(3, t1)
2253     loadConstantOrVariable(t1, t2)
2254     loadisFromInstruction(6, t1)
2255     storePropertyAtVariableOffset(t1, t0, t2)
2256 end
2257
2258 macro putGlobalVariable()
2259     loadisFromInstruction(3, t0)
2260     loadConstantOrVariable(t0, t1)
2261     loadpFromInstruction(5, t2)
2262     loadpFromInstruction(6, t0)
2263     notifyWrite(t2, .pDynamic)
2264     storeq t1, [t0]
2265 end
2266
2267 macro putClosureVar()
2268     loadisFromInstruction(3, t1)
2269     loadConstantOrVariable(t1, t2)
2270     loadisFromInstruction(6, t1)
2271     storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
2272 end
2273
2274 macro putLocalClosureVar()
2275     loadisFromInstruction(3, t1)
2276     loadConstantOrVariable(t1, t2)
2277     loadpFromInstruction(5, t3)
2278     btpz t3, .noVariableWatchpointSet
2279     notifyWrite(t3, .pDynamic)
2280 .noVariableWatchpointSet:
2281     loadisFromInstruction(6, t1)
2282     storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
2283 end
2284
2285 macro checkTDZInGlobalPutToScopeIfNecessary()
2286     loadisFromInstruction(4, t0)
2287     andi InitializationModeMask, t0
2288     rshifti InitializationModeShift, t0
2289     bineq t0, NotInitialization, .noNeedForTDZCheck
2290     loadpFromInstruction(6, t0)
2291     loadq [t0], t0
2292     bqeq t0, ValueEmpty, .pDynamic
2293 .noNeedForTDZCheck:
2294 end
2295
2296
2297 _llint_op_put_to_scope:
2298     traceExecution()
2299     loadisFromInstruction(4, t0)
2300     andi ResolveTypeMask, t0
2301
2302 #pLocalClosureVar:
2303     bineq t0, LocalClosureVar, .pGlobalProperty
2304     writeBarrierOnOperands(1, 3)
2305     loadVariable(1, t0)
2306     putLocalClosureVar()
2307     dispatch(7)
2308
2309 .pGlobalProperty:
2310     bineq t0, GlobalProperty, .pGlobalVar
2311     writeBarrierOnOperands(1, 3)
2312     loadWithStructureCheck(1, .pDynamic)
2313     putProperty()
2314     dispatch(7)
2315
2316 .pGlobalVar:
2317     bineq t0, GlobalVar, .pGlobalLexicalVar
2318     writeBarrierOnGlobalObject(3)
2319     putGlobalVariable()
2320     dispatch(7)
2321
2322 .pGlobalLexicalVar:
2323     bineq t0, GlobalLexicalVar, .pClosureVar
2324     writeBarrierOnGlobalLexicalEnvironment(3)
2325     checkTDZInGlobalPutToScopeIfNecessary()
2326     putGlobalVariable()
2327     dispatch(7)
2328
2329 .pClosureVar:
2330     bineq t0, ClosureVar, .pGlobalPropertyWithVarInjectionChecks
2331     writeBarrierOnOperands(1, 3)
2332     loadVariable(1, t0)
2333     putClosureVar()
2334     dispatch(7)
2335
2336 .pGlobalPropertyWithVarInjectionChecks:
2337     bineq t0, GlobalPropertyWithVarInjectionChecks, .pGlobalVarWithVarInjectionChecks
2338     writeBarrierOnOperands(1, 3)
2339     loadWithStructureCheck(1, .pDynamic)
2340     putProperty()
2341     dispatch(7)
2342
2343 .pGlobalVarWithVarInjectionChecks:
2344     bineq t0, GlobalVarWithVarInjectionChecks, .pGlobalLexicalVarWithVarInjectionChecks
2345     writeBarrierOnGlobalObject(3)
2346     varInjectionCheck(.pDynamic)
2347     putGlobalVariable()
2348     dispatch(7)
2349
2350 .pGlobalLexicalVarWithVarInjectionChecks:
2351     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks
2352     writeBarrierOnGlobalLexicalEnvironment(3)
2353     varInjectionCheck(.pDynamic)
2354     checkTDZInGlobalPutToScopeIfNecessary()
2355     putGlobalVariable()
2356     dispatch(7)
2357
2358 .pClosureVarWithVarInjectionChecks:
2359     bineq t0, ClosureVarWithVarInjectionChecks, .pModuleVar
2360     writeBarrierOnOperands(1, 3)
2361     varInjectionCheck(.pDynamic)
2362     loadVariable(1, t0)
2363     putClosureVar()
2364     dispatch(7)
2365
2366 .pModuleVar:
2367     bineq t0, ModuleVar, .pDynamic
2368     callOpcodeSlowPath(_slow_path_throw_strict_mode_readonly_property_write_error)
2369     dispatch(7)
2370
2371 .pDynamic:
2372     callOpcodeSlowPath(_llint_slow_path_put_to_scope)
2373     dispatch(7)
2374
2375
2376 _llint_op_get_from_arguments:
2377     traceExecution()
2378     loadVariable(2, t0)
2379     loadi 24[PB, PC, 8], t1
2380     loadq DirectArguments_storage[t0, t1, 8], t0
2381     valueProfile(t0, 4, t1)
2382     loadisFromInstruction(1, t1)
2383     storeq t0, [cfr, t1, 8]
2384     dispatch(5)
2385
2386
2387 _llint_op_put_to_arguments:
2388     traceExecution()
2389     writeBarrierOnOperands(1, 3)
2390     loadVariable(1, t0)
2391     loadi 16[PB, PC, 8], t1
2392     loadisFromInstruction(3, t3)
2393     loadConstantOrVariable(t3, t2)
2394     storeq t2, DirectArguments_storage[t0, t1, 8]
2395     dispatch(4)
2396
2397
2398 _llint_op_get_parent_scope:
2399     traceExecution()
2400     loadVariable(2, t0)
2401     loadp JSScope::m_next[t0], t0
2402     loadisFromInstruction(1, t1)
2403     storeq t0, [cfr, t1, 8]
2404     dispatch(3)
2405
2406
2407 _llint_op_profile_type:
2408     traceExecution()
2409     loadp CodeBlock[cfr], t1
2410     loadp CodeBlock::m_vm[t1], t1
2411     # t1 is holding the pointer to the typeProfilerLog.
2412     loadp VM::m_typeProfilerLog[t1], t1
2413     # t2 is holding the pointer to the current log entry.
2414     loadp TypeProfilerLog::m_currentLogEntryPtr[t1], t2
2415
2416     # t0 is holding the JSValue argument.
2417     loadisFromInstruction(1, t3)
2418     loadConstantOrVariable(t3, t0)
2419
2420     bqeq t0, ValueEmpty, .opProfileTypeDone
2421     # Store the JSValue onto the log entry.
2422     storeq t0, TypeProfilerLog::LogEntry::value[t2]
2423     
2424     # Store the TypeLocation onto the log entry.
2425     loadpFromInstruction(2, t3)
2426     storep t3, TypeProfilerLog::LogEntry::location[t2]
2427
2428     btqz t0, tagMask, .opProfileTypeIsCell
2429     storei 0, TypeProfilerLog::LogEntry::structureID[t2]
2430     jmp .opProfileTypeSkipIsCell
2431 .opProfileTypeIsCell:
2432     loadi JSCell::m_structureID[t0], t3
2433     storei t3, TypeProfilerLog::LogEntry::structureID[t2]
2434 .opProfileTypeSkipIsCell:
2435     
2436     # Increment the current log entry.
2437     addp sizeof TypeProfilerLog::LogEntry, t2
2438     storep t2, TypeProfilerLog::m_currentLogEntryPtr[t1]
2439
2440     loadp TypeProfilerLog::m_logEndPtr[t1], t1
2441     bpneq t2, t1, .opProfileTypeDone
2442     callOpcodeSlowPath(_slow_path_profile_type_clear_log)
2443
2444 .opProfileTypeDone:
2445     dispatch(6)
2446
2447 _llint_op_profile_control_flow:
2448     traceExecution()
2449     loadpFromInstruction(1, t0)
2450     addq 1, BasicBlockLocation::m_executionCount[t0]
2451     dispatch(2)
2452
2453
2454 _llint_op_get_rest_length:
2455     traceExecution()
2456     loadi PayloadOffset + ArgumentCount[cfr], t0
2457     subi 1, t0
2458     loadisFromInstruction(2, t1)
2459     bilteq t0, t1, .storeZero
2460     subi t1, t0
2461     jmp .boxUp
2462 .storeZero:
2463     move 0, t0
2464 .boxUp:
2465     orq tagTypeNumber, t0
2466     loadisFromInstruction(1, t1)
2467     storeq t0, [cfr, t1, 8]
2468     dispatch(3)
2469
2470
2471 _llint_op_log_shadow_chicken_prologue:
2472     traceExecution()
2473     acquireShadowChickenPacket(.opLogShadowChickenPrologueSlow)
2474     storep cfr, ShadowChicken::Packet::frame[t0]
2475     loadp CallerFrame[cfr], t1
2476     storep t1, ShadowChicken::Packet::callerFrame[t0]
2477     loadp Callee[cfr], t1
2478     storep t1, ShadowChicken::Packet::callee[t0]
2479     loadVariable(1, t1)
2480     storep t1, ShadowChicken::Packet::scope[t0]
2481     dispatch(2)
2482 .opLogShadowChickenPrologueSlow:
2483     callOpcodeSlowPath(_llint_slow_path_log_shadow_chicken_prologue)
2484     dispatch(2)
2485
2486
2487 _llint_op_log_shadow_chicken_tail:
2488     traceExecution()
2489     acquireShadowChickenPacket(.opLogShadowChickenTailSlow)
2490     storep cfr, ShadowChicken::Packet::frame[t0]
2491     storep ShadowChickenTailMarker, ShadowChicken::Packet::callee[t0]
2492     loadVariable(1, t1)
2493     storep t1, ShadowChicken::Packet::thisValue[t0]
2494     loadVariable(2, t1)
2495     storep t1, ShadowChicken::Packet::scope[t0]
2496     loadp CodeBlock[cfr], t1
2497     storep t1, ShadowChicken::Packet::codeBlock[t0]
2498     storei PC, ShadowChicken::Packet::callSiteIndex[t0]
2499     dispatch(3)
2500 .opLogShadowChickenTailSlow:
2501     callOpcodeSlowPath(_llint_slow_path_log_shadow_chicken_tail)
2502     dispatch(3)