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