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