Refactoring: Rename ScrambledPtr to Poisoned.
[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     move r1, t1 # r1 contains slotsToAdd.
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_to_object:
851     traceExecution()
852     loadisFromInstruction(2, t0)
853     loadisFromInstruction(1, t1)
854     loadConstantOrVariable(t0, t2)
855     btqnz t2, tagMask, .opToObjectSlow
856     bbb JSCell::m_type[t2], ObjectType, .opToObjectSlow
857     storeq t2, [cfr, t1, 8]
858     valueProfile(t2, 4, t0)
859     dispatch(constexpr op_to_object_length)
860
861 .opToObjectSlow:
862     callOpcodeSlowPath(_slow_path_to_object)
863     dispatch(constexpr op_to_object_length)
864
865
866 _llint_op_negate:
867     traceExecution()
868     loadisFromInstruction(2, t0)
869     loadisFromInstruction(1, t1)
870     loadConstantOrVariable(t0, t3)
871     loadisFromInstruction(3, t2)
872     bqb t3, tagTypeNumber, .opNegateNotInt
873     btiz t3, 0x7fffffff, .opNegateSlow
874     negi t3
875     ori ArithProfileInt, t2
876     orq tagTypeNumber, t3
877     storeisToInstruction(t2, 3)
878     storeq t3, [cfr, t1, 8]
879     dispatch(constexpr op_negate_length)
880 .opNegateNotInt:
881     btqz t3, tagTypeNumber, .opNegateSlow
882     xorq 0x8000000000000000, t3
883     ori ArithProfileNumber, t2
884     storeq t3, [cfr, t1, 8]
885     storeisToInstruction(t2, 3)
886     dispatch(constexpr op_negate_length)
887
888 .opNegateSlow:
889     callOpcodeSlowPath(_slow_path_negate)
890     dispatch(constexpr op_negate_length)
891
892
893 macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
894     loadisFromInstruction(3, t0)
895     loadisFromInstruction(2, t2)
896     loadConstantOrVariable(t0, t1)
897     loadConstantOrVariable(t2, t0)
898     bqb t0, tagTypeNumber, .op1NotInt
899     bqb t1, tagTypeNumber, .op2NotInt
900     loadisFromInstruction(1, t2)
901     integerOperationAndStore(t1, t0, .slow, t2)
902     loadisFromInstruction(4, t1)
903     ori ArithProfileIntInt, t1
904     storeisToInstruction(t1, 4)
905     dispatch(5)
906
907 .op1NotInt:
908     # First operand is definitely not an int, the second operand could be anything.
909     btqz t0, tagTypeNumber, .slow
910     bqaeq t1, tagTypeNumber, .op1NotIntOp2Int
911     btqz t1, tagTypeNumber, .slow
912     addq tagTypeNumber, t1
913     fq2d t1, ft1
914     loadisFromInstruction(4, t2)
915     ori ArithProfileNumberNumber, t2
916     storeisToInstruction(t2, 4)
917     jmp .op1NotIntReady
918 .op1NotIntOp2Int:
919     loadisFromInstruction(4, t2)
920     ori ArithProfileNumberInt, t2
921     storeisToInstruction(t2, 4)
922     ci2d t1, ft1
923 .op1NotIntReady:
924     loadisFromInstruction(1, t2)
925     addq tagTypeNumber, t0
926     fq2d t0, ft0
927     doubleOperation(ft1, ft0)
928     fd2q ft0, t0
929     subq tagTypeNumber, t0
930     storeq t0, [cfr, t2, 8]
931     dispatch(5)
932
933 .op2NotInt:
934     # First operand is definitely an int, the second is definitely not.
935     loadisFromInstruction(1, t2)
936     btqz t1, tagTypeNumber, .slow
937     loadisFromInstruction(4, t3)
938     ori ArithProfileIntNumber, t3
939     storeisToInstruction(t3, 4)
940     ci2d t0, ft0
941     addq tagTypeNumber, t1
942     fq2d t1, ft1
943     doubleOperation(ft1, ft0)
944     fd2q ft0, t0
945     subq tagTypeNumber, t0
946     storeq t0, [cfr, t2, 8]
947     dispatch(5)
948
949 .slow:
950     callOpcodeSlowPath(slowPath)
951     dispatch(5)
952 end
953
954 macro binaryOp(integerOperation, doubleOperation, slowPath)
955     binaryOpCustomStore(
956         macro (left, right, slow, index)
957             integerOperation(left, right, slow)
958             orq tagTypeNumber, right
959             storeq right, [cfr, index, 8]
960         end,
961         doubleOperation, slowPath)
962 end
963
964 _llint_op_add:
965     traceExecution()
966     binaryOp(
967         macro (left, right, slow) baddio left, right, slow end,
968         macro (left, right) addd left, right end,
969         _slow_path_add)
970
971
972 _llint_op_mul:
973     traceExecution()
974     binaryOpCustomStore(
975         macro (left, right, slow, index)
976             # Assume t3 is scratchable.
977             move right, t3
978             bmulio left, t3, slow
979             btinz t3, .done
980             bilt left, 0, slow
981             bilt right, 0, slow
982         .done:
983             orq tagTypeNumber, t3
984             storeq t3, [cfr, index, 8]
985         end,
986         macro (left, right) muld left, right end,
987         _slow_path_mul)
988
989
990 _llint_op_sub:
991     traceExecution()
992     binaryOp(
993         macro (left, right, slow) bsubio left, right, slow end,
994         macro (left, right) subd left, right end,
995         _slow_path_sub)
996
997
998 _llint_op_div:
999     traceExecution()
1000     if X86_64 or X86_64_WIN
1001         binaryOpCustomStore(
1002             macro (left, right, slow, index)
1003                 # Assume t3 is scratchable.
1004                 btiz left, slow
1005                 bineq left, -1, .notNeg2TwoThe31DivByNeg1
1006                 bieq right, -2147483648, .slow
1007             .notNeg2TwoThe31DivByNeg1:
1008                 btinz right, .intOK
1009                 bilt left, 0, slow
1010             .intOK:
1011                 move left, t3
1012                 move right, t0
1013                 cdqi
1014                 idivi t3
1015                 btinz t1, slow
1016                 orq tagTypeNumber, t0
1017                 storeq t0, [cfr, index, 8]
1018             end,
1019             macro (left, right) divd left, right end,
1020             _slow_path_div)
1021     else
1022         callOpcodeSlowPath(_slow_path_div)
1023         dispatch(constexpr op_div_length)
1024     end
1025
1026
1027 macro bitOp(operation, slowPath, advance)
1028     loadisFromInstruction(3, t0)
1029     loadisFromInstruction(2, t2)
1030     loadisFromInstruction(1, t3)
1031     loadConstantOrVariable(t0, t1)
1032     loadConstantOrVariable(t2, t0)
1033     bqb t0, tagTypeNumber, .slow
1034     bqb t1, tagTypeNumber, .slow
1035     operation(t1, t0)
1036     orq tagTypeNumber, t0
1037     storeq t0, [cfr, t3, 8]
1038     dispatch(advance)
1039
1040 .slow:
1041     callOpcodeSlowPath(slowPath)
1042     dispatch(advance)
1043 end
1044
1045 _llint_op_lshift:
1046     traceExecution()
1047     bitOp(
1048         macro (left, right) lshifti left, right end,
1049         _slow_path_lshift,
1050         constexpr op_lshift_length)
1051
1052
1053 _llint_op_rshift:
1054     traceExecution()
1055     bitOp(
1056         macro (left, right) rshifti left, right end,
1057         _slow_path_rshift,
1058         constexpr op_rshift_length)
1059
1060
1061 _llint_op_urshift:
1062     traceExecution()
1063     bitOp(
1064         macro (left, right) urshifti left, right end,
1065         _slow_path_urshift,
1066         constexpr op_urshift_length)
1067
1068
1069 _llint_op_unsigned:
1070     traceExecution()
1071     loadisFromInstruction(1, t0)
1072     loadisFromInstruction(2, t1)
1073     loadConstantOrVariable(t1, t2)
1074     bilt t2, 0, .opUnsignedSlow
1075     storeq t2, [cfr, t0, 8]
1076     dispatch(constexpr op_unsigned_length)
1077 .opUnsignedSlow:
1078     callOpcodeSlowPath(_slow_path_unsigned)
1079     dispatch(constexpr op_unsigned_length)
1080
1081
1082 _llint_op_bitand:
1083     traceExecution()
1084     bitOp(
1085         macro (left, right) andi left, right end,
1086         _slow_path_bitand,
1087         constexpr op_bitand_length)
1088
1089
1090 _llint_op_bitxor:
1091     traceExecution()
1092     bitOp(
1093         macro (left, right) xori left, right end,
1094         _slow_path_bitxor,
1095         constexpr op_bitxor_length)
1096
1097
1098 _llint_op_bitor:
1099     traceExecution()
1100     bitOp(
1101         macro (left, right) ori left, right end,
1102         _slow_path_bitor,
1103         constexpr op_bitor_length)
1104
1105
1106 _llint_op_overrides_has_instance:
1107     traceExecution()
1108     loadisFromStruct(OpOverridesHasInstance::m_dst, t3)
1109
1110     loadisFromStruct(OpOverridesHasInstance::m_hasInstanceValue, t1)
1111     loadConstantOrVariable(t1, t0)
1112     loadp CodeBlock[cfr], t2
1113     loadp CodeBlock::m_globalObject[t2], t2
1114     loadp JSGlobalObject::m_functionProtoHasInstanceSymbolFunction[t2], t2
1115     bqneq t0, t2, .opOverridesHasInstanceNotDefaultSymbol
1116
1117     loadisFromStruct(OpOverridesHasInstance::m_constructor, t1)
1118     loadConstantOrVariable(t1, t0)
1119     tbz JSCell::m_flags[t0], ImplementsDefaultHasInstance, t1
1120     orq ValueFalse, t1
1121     storeq t1, [cfr, t3, 8]
1122     dispatch(constexpr op_overrides_has_instance_length)
1123
1124 .opOverridesHasInstanceNotDefaultSymbol:
1125     storeq ValueTrue, [cfr, t3, 8]
1126     dispatch(constexpr op_overrides_has_instance_length)
1127
1128
1129 _llint_op_instanceof_custom:
1130     traceExecution()
1131     callOpcodeSlowPath(_llint_slow_path_instanceof_custom)
1132     dispatch(constexpr op_instanceof_custom_length)
1133
1134
1135 _llint_op_is_empty:
1136     traceExecution()
1137     loadisFromInstruction(2, t1)
1138     loadisFromInstruction(1, t2)
1139     loadConstantOrVariable(t1, t0)
1140     cqeq t0, ValueEmpty, t3
1141     orq ValueFalse, t3
1142     storeq t3, [cfr, t2, 8]
1143     dispatch(constexpr op_is_empty_length)
1144
1145
1146 _llint_op_is_undefined:
1147     traceExecution()
1148     loadisFromInstruction(2, t1)
1149     loadisFromInstruction(1, t2)
1150     loadConstantOrVariable(t1, t0)
1151     btqz t0, tagMask, .opIsUndefinedCell
1152     cqeq t0, ValueUndefined, t3
1153     orq ValueFalse, t3
1154     storeq t3, [cfr, t2, 8]
1155     dispatch(constexpr op_is_undefined_length)
1156 .opIsUndefinedCell:
1157     btbnz JSCell::m_flags[t0], MasqueradesAsUndefined, .masqueradesAsUndefined
1158     move ValueFalse, t1
1159     storeq t1, [cfr, t2, 8]
1160     dispatch(constexpr op_is_undefined_length)
1161 .masqueradesAsUndefined:
1162     loadStructureWithScratch(t0, t3, t1)
1163     loadp CodeBlock[cfr], t1
1164     loadp CodeBlock::m_globalObject[t1], t1
1165     cpeq Structure::m_globalObject[t3], t1, t0
1166     orq ValueFalse, t0
1167     storeq t0, [cfr, t2, 8]
1168     dispatch(constexpr op_is_undefined_length)
1169
1170
1171 _llint_op_is_boolean:
1172     traceExecution()
1173     loadisFromInstruction(2, t1)
1174     loadisFromInstruction(1, t2)
1175     loadConstantOrVariable(t1, t0)
1176     xorq ValueFalse, t0
1177     tqz t0, ~1, t0
1178     orq ValueFalse, t0
1179     storeq t0, [cfr, t2, 8]
1180     dispatch(constexpr op_is_boolean_length)
1181
1182
1183 _llint_op_is_number:
1184     traceExecution()
1185     loadisFromInstruction(2, t1)
1186     loadisFromInstruction(1, t2)
1187     loadConstantOrVariable(t1, t0)
1188     tqnz t0, tagTypeNumber, t1
1189     orq ValueFalse, t1
1190     storeq t1, [cfr, t2, 8]
1191     dispatch(constexpr op_is_number_length)
1192
1193
1194 _llint_op_is_cell_with_type:
1195     traceExecution()
1196     loadisFromInstruction(3, t0)
1197     loadisFromInstruction(2, t1)
1198     loadisFromInstruction(1, t2)
1199     loadConstantOrVariable(t1, t3)
1200     btqnz t3, tagMask, .notCellCase
1201     cbeq JSCell::m_type[t3], t0, t1
1202     orq ValueFalse, t1
1203     storeq t1, [cfr, t2, 8]
1204     dispatch(constexpr op_is_cell_with_type_length)
1205 .notCellCase:
1206     storeq ValueFalse, [cfr, t2, 8]
1207     dispatch(constexpr op_is_cell_with_type_length)
1208
1209
1210 _llint_op_is_object:
1211     traceExecution()
1212     loadisFromInstruction(2, t1)
1213     loadisFromInstruction(1, t2)
1214     loadConstantOrVariable(t1, t0)
1215     btqnz t0, tagMask, .opIsObjectNotCell
1216     cbaeq JSCell::m_type[t0], ObjectType, t1
1217     orq ValueFalse, t1
1218     storeq t1, [cfr, t2, 8]
1219     dispatch(constexpr op_is_object_length)
1220 .opIsObjectNotCell:
1221     storeq ValueFalse, [cfr, t2, 8]
1222     dispatch(constexpr op_is_object_length)
1223
1224
1225 macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
1226     bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
1227     loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
1228     negi propertyOffsetAsInt
1229     sxi2q propertyOffsetAsInt, propertyOffsetAsInt
1230     jmp .ready
1231 .isInline:
1232     addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage
1233 .ready:
1234     loadq (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8], value
1235 end
1236
1237
1238 macro storePropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
1239     bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
1240     loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
1241     negi propertyOffsetAsInt
1242     sxi2q propertyOffsetAsInt, propertyOffsetAsInt
1243     jmp .ready
1244 .isInline:
1245     addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage
1246 .ready:
1247     storeq value, (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8]
1248 end
1249
1250 _llint_op_get_by_id:
1251     traceExecution()
1252     loadisFromInstruction(2, t0)
1253     loadConstantOrVariableCell(t0, t3, .opGetByIdSlow)
1254     loadi JSCell::m_structureID[t3], t1
1255     loadisFromInstruction(4, t2)
1256     bineq t2, t1, .opGetByIdSlow
1257     loadisFromInstruction(5, t1)
1258     loadisFromInstruction(1, t2)
1259     loadPropertyAtVariableOffset(t1, t3, t0)
1260     storeq t0, [cfr, t2, 8]
1261     valueProfile(t0, 8, t1)
1262     dispatch(constexpr op_get_by_id_length)
1263
1264 .opGetByIdSlow:
1265     callOpcodeSlowPath(_llint_slow_path_get_by_id)
1266     dispatch(constexpr op_get_by_id_length)
1267
1268
1269 _llint_op_get_by_id_proto_load:
1270     traceExecution()
1271     loadisFromInstruction(2, t0)
1272     loadConstantOrVariableCell(t0, t3, .opGetByIdProtoSlow)
1273     loadi JSCell::m_structureID[t3], t1
1274     loadisFromInstruction(4, t2)
1275     bineq t2, t1, .opGetByIdProtoSlow
1276     loadisFromInstruction(5, t1)
1277     loadpFromInstruction(6, t3)
1278     loadisFromInstruction(1, t2)
1279     loadPropertyAtVariableOffset(t1, t3, t0)
1280     storeq t0, [cfr, t2, 8]
1281     valueProfile(t0, 8, t1)
1282     dispatch(constexpr op_get_by_id_proto_load_length)
1283
1284 .opGetByIdProtoSlow:
1285     callOpcodeSlowPath(_llint_slow_path_get_by_id)
1286     dispatch(constexpr op_get_by_id_proto_load_length)
1287
1288
1289 _llint_op_get_by_id_unset:
1290     traceExecution()
1291     loadisFromInstruction(2, t0)
1292     loadConstantOrVariableCell(t0, t3, .opGetByIdUnsetSlow)
1293     loadi JSCell::m_structureID[t3], t1
1294     loadisFromInstruction(4, t2)
1295     bineq t2, t1, .opGetByIdUnsetSlow
1296     loadisFromInstruction(1, t2)
1297     storeq ValueUndefined, [cfr, t2, 8]
1298     valueProfile(ValueUndefined, 8, t1)
1299     dispatch(constexpr op_get_by_id_unset_length)
1300
1301 .opGetByIdUnsetSlow:
1302     callOpcodeSlowPath(_llint_slow_path_get_by_id)
1303     dispatch(constexpr op_get_by_id_unset_length)
1304
1305
1306 _llint_op_get_array_length:
1307     traceExecution()
1308     loadisFromInstruction(2, t0)
1309     loadpFromInstruction(4, t1)
1310     loadConstantOrVariableCell(t0, t3, .opGetArrayLengthSlow)
1311     move t3, t2
1312     arrayProfile(t2, t1, t0)
1313     btiz t2, IsArray, .opGetArrayLengthSlow
1314     btiz t2, IndexingShapeMask, .opGetArrayLengthSlow
1315     loadisFromInstruction(1, t1)
1316     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t3], t0, t2)
1317     loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
1318     bilt t0, 0, .opGetArrayLengthSlow
1319     orq tagTypeNumber, t0
1320     valueProfile(t0, 8, t2)
1321     storeq t0, [cfr, t1, 8]
1322     dispatch(constexpr op_get_array_length_length)
1323
1324 .opGetArrayLengthSlow:
1325     callOpcodeSlowPath(_llint_slow_path_get_by_id)
1326     dispatch(constexpr op_get_array_length_length)
1327
1328
1329 _llint_op_put_by_id:
1330     traceExecution()
1331     loadisFromInstruction(1, t3)
1332     loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
1333     loadisFromInstruction(4, t2)
1334     bineq t2, JSCell::m_structureID[t0], .opPutByIdSlow
1335
1336     # At this point, we have:
1337     # t2 -> current structure ID
1338     # t0 -> object base
1339
1340     loadisFromInstruction(3, t1)
1341     loadConstantOrVariable(t1, t3)
1342
1343     loadpFromInstruction(8, t1)
1344
1345     # At this point, we have:
1346     # t0 -> object base
1347     # t1 -> put by id flags
1348     # t2 -> current structure ID
1349     # t3 -> value to put
1350
1351     btpnz t1, PutByIdPrimaryTypeMask, .opPutByIdTypeCheckObjectWithStructureOrOther
1352
1353     # We have one of the non-structure type checks. Find out which one.
1354     andp PutByIdSecondaryTypeMask, t1
1355     bplt t1, PutByIdSecondaryTypeString, .opPutByIdTypeCheckLessThanString
1356
1357     # We are one of the following: String, Symbol, Object, ObjectOrOther, Top
1358     bplt t1, PutByIdSecondaryTypeObjectOrOther, .opPutByIdTypeCheckLessThanObjectOrOther
1359
1360     # We are either ObjectOrOther or Top.
1361     bpeq t1, PutByIdSecondaryTypeTop, .opPutByIdDoneCheckingTypes
1362
1363     # Check if we are ObjectOrOther.
1364     btqz t3, tagMask, .opPutByIdTypeCheckObject
1365 .opPutByIdTypeCheckOther:
1366     andq ~TagBitUndefined, t3
1367     bqeq t3, ValueNull, .opPutByIdDoneCheckingTypes
1368     jmp .opPutByIdSlow
1369
1370 .opPutByIdTypeCheckLessThanObjectOrOther:
1371     # We are either String, Symbol or Object.
1372     btqnz t3, tagMask, .opPutByIdSlow
1373     bpeq t1, PutByIdSecondaryTypeObject, .opPutByIdTypeCheckObject
1374     bpeq t1, PutByIdSecondaryTypeSymbol, .opPutByIdTypeCheckSymbol
1375     bbeq JSCell::m_type[t3], StringType, .opPutByIdDoneCheckingTypes
1376     jmp .opPutByIdSlow
1377 .opPutByIdTypeCheckObject:
1378     bbaeq JSCell::m_type[t3], ObjectType, .opPutByIdDoneCheckingTypes
1379     jmp .opPutByIdSlow
1380 .opPutByIdTypeCheckSymbol:
1381     bbeq JSCell::m_type[t3], SymbolType, .opPutByIdDoneCheckingTypes
1382     jmp .opPutByIdSlow
1383
1384 .opPutByIdTypeCheckLessThanString:
1385     # We are one of the following: Bottom, Boolean, Other, Int32, Number
1386     bplt t1, PutByIdSecondaryTypeInt32, .opPutByIdTypeCheckLessThanInt32
1387
1388     # We are either Int32 or Number.
1389     bpeq t1, PutByIdSecondaryTypeNumber, .opPutByIdTypeCheckNumber
1390
1391     bqaeq t3, tagTypeNumber, .opPutByIdDoneCheckingTypes
1392     jmp .opPutByIdSlow
1393
1394 .opPutByIdTypeCheckNumber:
1395     btqnz t3, tagTypeNumber, .opPutByIdDoneCheckingTypes
1396     jmp .opPutByIdSlow
1397
1398 .opPutByIdTypeCheckLessThanInt32:
1399     # We are one of the following: Bottom, Boolean, Other.
1400     bpneq t1, PutByIdSecondaryTypeBoolean, .opPutByIdTypeCheckBottomOrOther
1401     xorq ValueFalse, t3
1402     btqz t3, ~1, .opPutByIdDoneCheckingTypes
1403     jmp .opPutByIdSlow
1404
1405 .opPutByIdTypeCheckBottomOrOther:
1406     bpeq t1, PutByIdSecondaryTypeOther, .opPutByIdTypeCheckOther
1407     jmp .opPutByIdSlow
1408
1409 .opPutByIdTypeCheckObjectWithStructureOrOther:
1410     btqz t3, tagMask, .opPutByIdTypeCheckObjectWithStructure
1411     btpnz t1, PutByIdPrimaryTypeObjectWithStructureOrOther, .opPutByIdTypeCheckOther
1412     jmp .opPutByIdSlow
1413
1414 .opPutByIdTypeCheckObjectWithStructure:
1415     urshiftp 3, t1
1416     bineq t1, JSCell::m_structureID[t3], .opPutByIdSlow
1417
1418 .opPutByIdDoneCheckingTypes:
1419     loadisFromInstruction(6, t1)
1420     
1421     btiz t1, .opPutByIdNotTransition
1422
1423     # This is the transition case. t1 holds the new structureID. t2 holds the old structure ID.
1424     # If we have a chain, we need to check it. t0 is the base. We may clobber t1 to use it as
1425     # scratch.
1426     loadpFromInstruction(7, t3)
1427     btpz t3, .opPutByIdTransitionDirect
1428
1429     loadp StructureChain::m_vector[t3], t3
1430     assert(macro (ok) btpnz t3, ok end)
1431
1432     structureIDToStructureWithScratch(t2, t1)
1433     loadq Structure::m_prototype[t2], t2
1434     bqeq t2, ValueNull, .opPutByIdTransitionChainDone
1435 .opPutByIdTransitionChainLoop:
1436     # At this point, t2 contains a prototye, and [t3] contains the Structure* that we want that
1437     # prototype to have. We don't want to have to load the Structure* for t2. Instead, we load
1438     # the Structure* from [t3], and then we compare its id to the id in the header of t2.
1439     loadp [t3], t1
1440     loadi JSCell::m_structureID[t2], t2
1441     # Now, t1 has the Structure* and t2 has the StructureID that we want that Structure* to have.
1442     bineq t2, Structure::m_blob + StructureIDBlob::u.fields.structureID[t1], .opPutByIdSlow
1443     addp 8, t3
1444     loadq Structure::m_prototype[t1], t2
1445     bqneq t2, ValueNull, .opPutByIdTransitionChainLoop
1446
1447 .opPutByIdTransitionChainDone:
1448     # Reload the new structure, since we clobbered it above.
1449     loadisFromInstruction(6, t1)
1450
1451 .opPutByIdTransitionDirect:
1452     storei t1, JSCell::m_structureID[t0]
1453     writeBarrierOnOperand(1)
1454     # Reload base into t0
1455     loadisFromInstruction(1, t1)
1456     loadConstantOrVariable(t1, t0)
1457
1458 .opPutByIdNotTransition:
1459     # The only thing live right now is t0, which holds the base.
1460     loadisFromInstruction(3, t1)
1461     loadConstantOrVariable(t1, t2)
1462     loadisFromInstruction(5, t1)
1463     storePropertyAtVariableOffset(t1, t0, t2)
1464     writeBarrierOnOperands(1, 3)
1465     dispatch(constexpr op_put_by_id_length)
1466
1467 .opPutByIdSlow:
1468     callOpcodeSlowPath(_llint_slow_path_put_by_id)
1469     dispatch(constexpr op_put_by_id_length)
1470
1471 macro finishGetByVal(result, scratch)
1472     loadisFromInstruction(1, scratch)
1473     storeq result, [cfr, scratch, 8]
1474     valueProfile(result, 5, scratch)
1475     dispatch(6)
1476 end
1477
1478 macro finishIntGetByVal(result, scratch)
1479     orq tagTypeNumber, result
1480     finishGetByVal(result, scratch)
1481 end
1482
1483 macro finishDoubleGetByVal(result, scratch1, scratch2)
1484     fd2q result, scratch1
1485     subq tagTypeNumber, scratch1
1486     finishGetByVal(scratch1, scratch2)
1487 end
1488
1489 _llint_op_get_by_val:
1490     traceExecution()
1491     loadisFromInstruction(2, t2)
1492     loadConstantOrVariableCell(t2, t0, .opGetByValSlow)
1493     loadpFromInstruction(4, t3)
1494     move t0, t2
1495     arrayProfile(t2, t3, t1)
1496     loadisFromInstruction(3, t3)
1497     loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
1498     sxi2q t1, t1
1499     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t0], t3, t5)
1500     andi IndexingShapeMask, t2
1501     bieq t2, Int32Shape, .opGetByValIsContiguous
1502     bineq t2, ContiguousShape, .opGetByValNotContiguous
1503 .opGetByValIsContiguous:
1504
1505     biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
1506     loadisFromInstruction(1, t0)
1507     loadq [t3, t1, 8], t2
1508     btqz t2, .opGetByValOutOfBounds
1509     jmp .opGetByValDone
1510
1511 .opGetByValNotContiguous:
1512     bineq t2, DoubleShape, .opGetByValNotDouble
1513     biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
1514     loadis 8[PB, PC, 8], t0
1515     loadd [t3, t1, 8], ft0
1516     bdnequn ft0, ft0, .opGetByValOutOfBounds
1517     fd2q ft0, t2
1518     subq tagTypeNumber, t2
1519     jmp .opGetByValDone
1520     
1521 .opGetByValNotDouble:
1522     subi ArrayStorageShape, t2
1523     bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValNotIndexedStorage
1524     biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t3], .opGetByValOutOfBounds
1525     loadisFromInstruction(1, t0)
1526     loadq ArrayStorage::m_vector[t3, t1, 8], t2
1527     btqz t2, .opGetByValOutOfBounds
1528
1529 .opGetByValDone:
1530     storeq t2, [cfr, t0, 8]
1531     valueProfile(t2, 5, t0)
1532     dispatch(constexpr op_get_by_val_length)
1533
1534 .opGetByValOutOfBounds:
1535     loadpFromInstruction(4, t0)
1536     storeb 1, ArrayProfile::m_outOfBounds[t0]
1537     jmp .opGetByValSlow
1538
1539 .opGetByValNotIndexedStorage:
1540     # First lets check if we even have a typed array. This lets us do some boilerplate up front.
1541     loadb JSCell::m_type[t0], t2
1542     subi FirstArrayType, t2
1543     bia t2, LastArrayType - FirstArrayType, .opGetByValSlow
1544     
1545     # Sweet, now we know that we have a typed array. Do some basic things now.
1546     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t5)
1547     biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow
1548     
1549     # Now bisect through the various types. Note that we can treat Uint8ArrayType and
1550     # Uint8ClampedArrayType the same.
1551     bia t2, Uint8ClampedArrayType - FirstArrayType, .opGetByValAboveUint8ClampedArray
1552     
1553     # We have one of Int8ArrayType .. Uint8ClampedArrayType.
1554     bia t2, Int16ArrayType - FirstArrayType, .opGetByValInt32ArrayOrUint8Array
1555     
1556     # We have one of Int8ArrayType or Int16ArrayType
1557     bineq t2, Int8ArrayType - FirstArrayType, .opGetByValInt16Array
1558     
1559     # We have Int8ArrayType
1560     loadbs [t3, t1], t0
1561     finishIntGetByVal(t0, t1)
1562
1563 .opGetByValInt16Array:
1564     loadhs [t3, t1, 2], t0
1565     finishIntGetByVal(t0, t1)
1566
1567 .opGetByValInt32ArrayOrUint8Array:
1568     # We have one of Int16Array, Uint8Array, or Uint8ClampedArray.
1569     bieq t2, Int32ArrayType - FirstArrayType, .opGetByValInt32Array
1570     
1571     # We have either Uint8Array or Uint8ClampedArray. They behave the same so that's cool.
1572     loadb [t3, t1], t0
1573     finishIntGetByVal(t0, t1)
1574
1575 .opGetByValInt32Array:
1576     loadi [t3, t1, 4], t0
1577     finishIntGetByVal(t0, t1)
1578
1579 .opGetByValAboveUint8ClampedArray:
1580     # We have one of Uint16ArrayType .. Float64ArrayType.
1581     bia t2, Uint32ArrayType - FirstArrayType, .opGetByValAboveUint32Array
1582     
1583     # We have either Uint16ArrayType or Uint32ArrayType.
1584     bieq t2, Uint32ArrayType - FirstArrayType, .opGetByValUint32Array
1585
1586     # We have Uint16ArrayType.
1587     loadh [t3, t1, 2], t0
1588     finishIntGetByVal(t0, t1)
1589
1590 .opGetByValUint32Array:
1591     # This is the hardest part because of large unsigned values.
1592     loadi [t3, t1, 4], t0
1593     bilt t0, 0, .opGetByValSlow # This case is still awkward to implement in LLInt.
1594     finishIntGetByVal(t0, t1)
1595
1596 .opGetByValAboveUint32Array:
1597     # We have one of Float32ArrayType or Float64ArrayType. Sadly, we cannot handle Float32Array
1598     # inline yet. That would require some offlineasm changes.
1599     bieq t2, Float32ArrayType - FirstArrayType, .opGetByValSlow
1600
1601     # We have Float64ArrayType.
1602     loadd [t3, t1, 8], ft0
1603     bdnequn ft0, ft0, .opGetByValSlow
1604     finishDoubleGetByVal(ft0, t0, t1)
1605
1606 .opGetByValSlow:
1607     callOpcodeSlowPath(_llint_slow_path_get_by_val)
1608     dispatch(constexpr op_get_by_val_length)
1609
1610
1611 macro contiguousPutByVal(storeCallback)
1612     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
1613 .storeResult:
1614     loadisFromInstruction(3, t2)
1615     storeCallback(t2, t1, [t0, t3, 8])
1616     dispatch(5)
1617
1618 .outOfBounds:
1619     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
1620     loadp 32[PB, PC, 8], t2
1621     storeb 1, ArrayProfile::m_mayStoreToHole[t2]
1622     addi 1, t3, t2
1623     storei t2, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
1624     jmp .storeResult
1625 end
1626
1627 macro putByVal(slowPath)
1628     traceExecution()
1629     loadisFromInstruction(1, t0)
1630     loadConstantOrVariableCell(t0, t1, .opPutByValSlow)
1631     loadpFromInstruction(4, t3)
1632     move t1, t2
1633     arrayProfile(t2, t3, t0)
1634     loadisFromInstruction(2, t0)
1635     loadConstantOrVariableInt32(t0, t3, .opPutByValSlow)
1636     sxi2q t3, t3
1637     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t1], t0, t5)
1638     andi IndexingShapeMask, t2
1639     bineq t2, Int32Shape, .opPutByValNotInt32
1640     contiguousPutByVal(
1641         macro (operand, scratch, address)
1642             loadConstantOrVariable(operand, scratch)
1643             bpb scratch, tagTypeNumber, .opPutByValSlow
1644             storep scratch, address
1645             writeBarrierOnOperands(1, 3)
1646         end)
1647
1648 .opPutByValNotInt32:
1649     bineq t2, DoubleShape, .opPutByValNotDouble
1650     contiguousPutByVal(
1651         macro (operand, scratch, address)
1652             loadConstantOrVariable(operand, scratch)
1653             bqb scratch, tagTypeNumber, .notInt
1654             ci2d scratch, ft0
1655             jmp .ready
1656         .notInt:
1657             addp tagTypeNumber, scratch
1658             fq2d scratch, ft0
1659             bdnequn ft0, ft0, .opPutByValSlow
1660         .ready:
1661             stored ft0, address
1662             writeBarrierOnOperands(1, 3)
1663         end)
1664
1665 .opPutByValNotDouble:
1666     bineq t2, ContiguousShape, .opPutByValNotContiguous
1667     contiguousPutByVal(
1668         macro (operand, scratch, address)
1669             loadConstantOrVariable(operand, scratch)
1670             storep scratch, address
1671             writeBarrierOnOperands(1, 3)
1672         end)
1673
1674 .opPutByValNotContiguous:
1675     bineq t2, ArrayStorageShape, .opPutByValSlow
1676     biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
1677     btqz ArrayStorage::m_vector[t0, t3, 8], .opPutByValArrayStorageEmpty
1678 .opPutByValArrayStorageStoreResult:
1679     loadisFromInstruction(3, t2)
1680     loadConstantOrVariable(t2, t1)
1681     storeq t1, ArrayStorage::m_vector[t0, t3, 8]
1682     writeBarrierOnOperands(1, 3)
1683     dispatch(5)
1684
1685 .opPutByValArrayStorageEmpty:
1686     loadpFromInstruction(4, t1)
1687     storeb 1, ArrayProfile::m_mayStoreToHole[t1]
1688     addi 1, ArrayStorage::m_numValuesInVector[t0]
1689     bib t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .opPutByValArrayStorageStoreResult
1690     addi 1, t3, t1
1691     storei t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
1692     jmp .opPutByValArrayStorageStoreResult
1693
1694 .opPutByValOutOfBounds:
1695     loadpFromInstruction(4, t0)
1696     storeb 1, ArrayProfile::m_outOfBounds[t0]
1697 .opPutByValSlow:
1698     callOpcodeSlowPath(slowPath)
1699     dispatch(5)
1700 end
1701
1702 _llint_op_put_by_val:
1703     putByVal(_llint_slow_path_put_by_val)
1704
1705 _llint_op_put_by_val_direct:
1706     putByVal(_llint_slow_path_put_by_val_direct)
1707
1708
1709 _llint_op_jmp:
1710     traceExecution()
1711     dispatchIntIndirect(1)
1712
1713
1714 macro jumpTrueOrFalse(conditionOp, slow)
1715     loadisFromInstruction(1, t1)
1716     loadConstantOrVariable(t1, t0)
1717     xorq ValueFalse, t0
1718     btqnz t0, -1, .slow
1719     conditionOp(t0, .target)
1720     dispatch(3)
1721
1722 .target:
1723     dispatchIntIndirect(2)
1724
1725 .slow:
1726     callOpcodeSlowPath(slow)
1727     dispatch(0)
1728 end
1729
1730
1731 macro equalNull(cellHandler, immediateHandler)
1732     loadisFromInstruction(1, t0)
1733     assertNotConstant(t0)
1734     loadq [cfr, t0, 8], t0
1735     btqnz t0, tagMask, .immediate
1736     loadStructureWithScratch(t0, t2, t1)
1737     cellHandler(t2, JSCell::m_flags[t0], .target)
1738     dispatch(3)
1739
1740 .target:
1741     dispatchIntIndirect(2)
1742
1743 .immediate:
1744     andq ~TagBitUndefined, t0
1745     immediateHandler(t0, .target)
1746     dispatch(3)
1747 end
1748
1749 _llint_op_jeq_null:
1750     traceExecution()
1751     equalNull(
1752         macro (structure, value, target) 
1753             btbz value, MasqueradesAsUndefined, .notMasqueradesAsUndefined
1754             loadp CodeBlock[cfr], t0
1755             loadp CodeBlock::m_globalObject[t0], t0
1756             bpeq Structure::m_globalObject[structure], t0, target
1757 .notMasqueradesAsUndefined:
1758         end,
1759         macro (value, target) bqeq value, ValueNull, target end)
1760
1761
1762 _llint_op_jneq_null:
1763     traceExecution()
1764     equalNull(
1765         macro (structure, value, target) 
1766             btbz value, MasqueradesAsUndefined, target
1767             loadp CodeBlock[cfr], t0
1768             loadp CodeBlock::m_globalObject[t0], t0
1769             bpneq Structure::m_globalObject[structure], t0, target
1770         end,
1771         macro (value, target) bqneq value, ValueNull, target end)
1772
1773
1774 _llint_op_jneq_ptr:
1775     traceExecution()
1776     loadisFromInstruction(1, t0)
1777     loadisFromInstruction(2, t1)
1778     loadp CodeBlock[cfr], t2
1779     loadp CodeBlock::m_globalObject[t2], t2
1780     loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1
1781     bpneq t1, [cfr, t0, 8], .opJneqPtrTarget
1782     dispatch(5)
1783
1784 .opJneqPtrTarget:
1785     storei 1, 32[PB, PC, 8]
1786     dispatchIntIndirect(3)
1787
1788
1789 macro compare(integerCompare, doubleCompare, slowPath)
1790     loadisFromInstruction(1, t2)
1791     loadisFromInstruction(2, t3)
1792     loadConstantOrVariable(t2, t0)
1793     loadConstantOrVariable(t3, t1)
1794     bqb t0, tagTypeNumber, .op1NotInt
1795     bqb t1, tagTypeNumber, .op2NotInt
1796     integerCompare(t0, t1, .jumpTarget)
1797     dispatch(4)
1798
1799 .op1NotInt:
1800     btqz t0, tagTypeNumber, .slow
1801     bqb t1, tagTypeNumber, .op1NotIntOp2NotInt
1802     ci2d t1, ft1
1803     jmp .op1NotIntReady
1804 .op1NotIntOp2NotInt:
1805     btqz t1, tagTypeNumber, .slow
1806     addq tagTypeNumber, t1
1807     fq2d t1, ft1
1808 .op1NotIntReady:
1809     addq tagTypeNumber, t0
1810     fq2d t0, ft0
1811     doubleCompare(ft0, ft1, .jumpTarget)
1812     dispatch(4)
1813
1814 .op2NotInt:
1815     ci2d t0, ft0
1816     btqz t1, tagTypeNumber, .slow
1817     addq tagTypeNumber, t1
1818     fq2d t1, ft1
1819     doubleCompare(ft0, ft1, .jumpTarget)
1820     dispatch(4)
1821
1822 .jumpTarget:
1823     dispatchIntIndirect(3)
1824
1825 .slow:
1826     callOpcodeSlowPath(slowPath)
1827     dispatch(0)
1828 end
1829
1830
1831 macro compareUnsignedJump(integerCompare)
1832     loadisFromInstruction(1, t2)
1833     loadisFromInstruction(2, t3)
1834     loadConstantOrVariable(t2, t0)
1835     loadConstantOrVariable(t3, t1)
1836     integerCompare(t0, t1, .jumpTarget)
1837     dispatch(4)
1838
1839 .jumpTarget:
1840     dispatchIntIndirect(3)
1841 end
1842
1843
1844 macro compareUnsigned(integerCompareAndSet)
1845     traceExecution()
1846     loadisFromInstruction(3, t0)
1847     loadisFromInstruction(2, t2)
1848     loadisFromInstruction(1, t3)
1849     loadConstantOrVariable(t0, t1)
1850     loadConstantOrVariable(t2, t0)
1851     integerCompareAndSet(t0, t1, t0)
1852     orq ValueFalse, t0
1853     storeq t0, [cfr, t3, 8]
1854     dispatch(4)
1855 end
1856
1857
1858 _llint_op_switch_imm:
1859     traceExecution()
1860     loadisFromInstruction(3, t2)
1861     loadisFromInstruction(1, t3)
1862     loadConstantOrVariable(t2, t1)
1863     loadp CodeBlock[cfr], t2
1864     loadp CodeBlock::m_rareData[t2], t2
1865     muli sizeof SimpleJumpTable, t3    # FIXME: would be nice to peephole this!
1866     loadp CodeBlock::RareData::m_switchJumpTables + VectorBufferOffset[t2], t2
1867     addp t3, t2
1868     bqb t1, tagTypeNumber, .opSwitchImmNotInt
1869     subi SimpleJumpTable::min[t2], t1
1870     biaeq t1, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
1871     loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
1872     loadis [t3, t1, 4], t1
1873     btiz t1, .opSwitchImmFallThrough
1874     dispatch(t1)
1875
1876 .opSwitchImmNotInt:
1877     btqnz t1, tagTypeNumber, .opSwitchImmSlow   # Go slow if it's a double.
1878 .opSwitchImmFallThrough:
1879     dispatchIntIndirect(2)
1880
1881 .opSwitchImmSlow:
1882     callOpcodeSlowPath(_llint_slow_path_switch_imm)
1883     dispatch(0)
1884
1885
1886 _llint_op_switch_char:
1887     traceExecution()
1888     loadisFromInstruction(3, t2)
1889     loadisFromInstruction(1, t3)
1890     loadConstantOrVariable(t2, t1)
1891     loadp CodeBlock[cfr], t2
1892     loadp CodeBlock::m_rareData[t2], t2
1893     muli sizeof SimpleJumpTable, t3
1894     loadp CodeBlock::RareData::m_switchJumpTables + VectorBufferOffset[t2], t2
1895     addp t3, t2
1896     btqnz t1, tagMask, .opSwitchCharFallThrough
1897     bbneq JSCell::m_type[t1], StringType, .opSwitchCharFallThrough
1898     bineq JSString::m_length[t1], 1, .opSwitchCharFallThrough
1899     loadp JSString::m_value[t1], t0
1900     btpz  t0, .opSwitchOnRope
1901     loadp StringImpl::m_data8[t0], t1
1902     btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
1903     loadh [t1], t0
1904     jmp .opSwitchCharReady
1905 .opSwitchChar8Bit:
1906     loadb [t1], t0
1907 .opSwitchCharReady:
1908     subi SimpleJumpTable::min[t2], t0
1909     biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
1910     loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
1911     loadis [t2, t0, 4], t1
1912     btiz t1, .opSwitchCharFallThrough
1913     dispatch(t1)
1914
1915 .opSwitchCharFallThrough:
1916     dispatchIntIndirect(2)
1917
1918 .opSwitchOnRope:
1919     callOpcodeSlowPath(_llint_slow_path_switch_char)
1920     dispatch(0)
1921
1922
1923 macro arrayProfileForCall()
1924     loadisFromInstruction(4, t3)
1925     negp t3
1926     loadq ThisArgumentOffset[cfr, t3, 8], t0
1927     btqnz t0, tagMask, .done
1928     loadpFromInstruction((CallOpCodeSize - 2), t1)
1929     loadi JSCell::m_structureID[t0], t3
1930     storei t3, ArrayProfile::m_lastSeenStructureID[t1]
1931 .done:
1932 end
1933
1934 macro doCall(slowPath, prepareCall)
1935     loadisFromInstruction(2, t0)
1936     loadpFromInstruction(5, t1)
1937     loadp LLIntCallLinkInfo::callee[t1], t2
1938     loadConstantOrVariable(t0, t3)
1939     bqneq t3, t2, .opCallSlow
1940     loadisFromInstruction(4, t3)
1941     lshifti 3, t3
1942     negp t3
1943     addp cfr, t3
1944     storeq t2, Callee[t3]
1945     loadisFromInstruction(3, t2)
1946     storei PC, ArgumentCount + TagOffset[cfr]
1947     storei t2, ArgumentCount + PayloadOffset[t3]
1948     move t3, sp
1949     if X86_64_WIN
1950         prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
1951         callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
1952     else
1953         loadp _g_masmPoison, t2
1954         xorp LLIntCallLinkInfo::machineCodeTarget[t1], t2
1955         prepareCall(t2, t1, t3, t4)
1956         callTargetFunction(t2)
1957     end
1958
1959 .opCallSlow:
1960     slowPathForCall(slowPath, prepareCall)
1961 end
1962
1963 _llint_op_ret:
1964     traceExecution()
1965     checkSwitchToJITForEpilogue()
1966     loadisFromInstruction(1, t2)
1967     loadConstantOrVariable(t2, r0)
1968     doReturn()
1969
1970
1971 _llint_op_to_primitive:
1972     traceExecution()
1973     loadisFromInstruction(2, t2)
1974     loadisFromInstruction(1, t3)
1975     loadConstantOrVariable(t2, t0)
1976     btqnz t0, tagMask, .opToPrimitiveIsImm
1977     bbaeq JSCell::m_type[t0], ObjectType, .opToPrimitiveSlowCase
1978 .opToPrimitiveIsImm:
1979     storeq t0, [cfr, t3, 8]
1980     dispatch(constexpr op_to_primitive_length)
1981
1982 .opToPrimitiveSlowCase:
1983     callOpcodeSlowPath(_slow_path_to_primitive)
1984     dispatch(constexpr op_to_primitive_length)
1985
1986
1987 _llint_op_catch:
1988     # This is where we end up from the JIT's throw trampoline (because the
1989     # machine code return address will be set to _llint_op_catch), and from
1990     # the interpreter's throw trampoline (see _llint_throw_trampoline).
1991     # The throwing code must have known that we were throwing to the interpreter,
1992     # and have set VM::targetInterpreterPCForThrow.
1993     loadp Callee[cfr], t3
1994     andp MarkedBlockMask, t3
1995     loadp MarkedBlock::m_vm[t3], t3
1996     restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0)
1997     loadp VM::callFrameForCatch[t3], cfr
1998     storep 0, VM::callFrameForCatch[t3]
1999     restoreStackPointerAfterCall()
2000
2001     loadp CodeBlock[cfr], PB
2002     loadp CodeBlock::m_instructions[PB], PB
2003     loadp VM::targetInterpreterPCForThrow[t3], PC
2004     subp PB, PC
2005     rshiftp 3, PC
2006
2007     callOpcodeSlowPath(_llint_slow_path_check_if_exception_is_uncatchable_and_notify_profiler)
2008     bpeq r1, 0, .isCatchableException
2009     jmp _llint_throw_from_slow_path_trampoline
2010
2011 .isCatchableException:
2012     loadp Callee[cfr], t3
2013     andp MarkedBlockMask, t3
2014     loadp MarkedBlock::m_vm[t3], t3
2015
2016     loadq VM::m_exception[t3], t0
2017     storeq 0, VM::m_exception[t3]
2018     loadisFromInstruction(1, t2)
2019     storeq t0, [cfr, t2, 8]
2020
2021     loadq Exception::m_value[t0], t3
2022     loadisFromInstruction(2, t2)
2023     storeq t3, [cfr, t2, 8]
2024
2025     traceExecution()
2026
2027     callOpcodeSlowPath(_llint_slow_path_profile_catch)
2028
2029     dispatch(constexpr op_catch_length)
2030
2031
2032 _llint_op_end:
2033     traceExecution()
2034     checkSwitchToJITForEpilogue()
2035     loadisFromInstruction(1, t0)
2036     assertNotConstant(t0)
2037     loadq [cfr, t0, 8], r0
2038     doReturn()
2039
2040
2041 _llint_throw_from_slow_path_trampoline:
2042     loadp Callee[cfr], t1
2043     andp MarkedBlockMask, t1
2044     loadp MarkedBlock::m_vm[t1], t1
2045     copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(t1, t2)
2046
2047     callSlowPath(_llint_slow_path_handle_exception)
2048
2049     # When throwing from the interpreter (i.e. throwing from LLIntSlowPaths), so
2050     # the throw target is not necessarily interpreted code, we come to here.
2051     # This essentially emulates the JIT's throwing protocol.
2052     loadp Callee[cfr], t1
2053     andp MarkedBlockMask, t1
2054     loadp MarkedBlock::m_vm[t1], t1
2055     jmp VM::targetMachinePCForThrow[t1]
2056
2057
2058 _llint_throw_during_call_trampoline:
2059     preserveReturnAddressAfterCall(t2)
2060     jmp _llint_throw_from_slow_path_trampoline
2061
2062
2063 macro nativeCallTrampoline(executableOffsetToFunction)
2064
2065     functionPrologue()
2066     storep 0, CodeBlock[cfr]
2067     loadp Callee[cfr], t0
2068     andp MarkedBlockMask, t0, t1
2069     loadp MarkedBlock::m_vm[t1], t1
2070     storep cfr, VM::topCallFrame[t1]
2071     if ARM64 or C_LOOP
2072         storep lr, ReturnPC[cfr]
2073     end
2074     move cfr, a0
2075     loadp Callee[cfr], t1
2076     loadp JSFunction::m_executable[t1], t1
2077     checkStackPointerAlignment(t3, 0xdead0001)
2078     if C_LOOP
2079         cloopCallNative executableOffsetToFunction[t1]
2080     else
2081         if X86_64_WIN
2082             subp 32, sp
2083         end
2084         call executableOffsetToFunction[t1]
2085         if X86_64_WIN
2086             addp 32, sp
2087         end
2088     end
2089
2090     loadp Callee[cfr], t3
2091     andp MarkedBlockMask, t3
2092     loadp MarkedBlock::m_vm[t3], t3
2093
2094     btqnz VM::m_exception[t3], .handleException
2095
2096     functionEpilogue()
2097     ret
2098
2099 .handleException:
2100     storep cfr, VM::topCallFrame[t3]
2101     jmp _llint_throw_from_slow_path_trampoline
2102 end
2103
2104 macro internalFunctionCallTrampoline(offsetOfFunction)
2105     functionPrologue()
2106     storep 0, CodeBlock[cfr]
2107     loadp Callee[cfr], t0
2108     andp MarkedBlockMask, t0, t1
2109     loadp MarkedBlock::m_vm[t1], t1
2110     storep cfr, VM::topCallFrame[t1]
2111     if ARM64 or C_LOOP
2112         storep lr, ReturnPC[cfr]
2113     end
2114     move cfr, a0
2115     loadp Callee[cfr], t1
2116     checkStackPointerAlignment(t3, 0xdead0001)
2117     if C_LOOP
2118         cloopCallNative offsetOfFunction[t1]
2119     else
2120         if X86_64_WIN
2121             subp 32, sp
2122         end
2123         call offsetOfFunction[t1]
2124         if X86_64_WIN
2125             addp 32, sp
2126         end
2127     end
2128
2129     loadp Callee[cfr], t3
2130     andp MarkedBlockMask, t3
2131     loadp MarkedBlock::m_vm[t3], t3
2132
2133     btqnz VM::m_exception[t3], .handleException
2134
2135     functionEpilogue()
2136     ret
2137
2138 .handleException:
2139     storep cfr, VM::topCallFrame[t3]
2140     jmp _llint_throw_from_slow_path_trampoline
2141 end
2142
2143 macro getConstantScope(dst)
2144     loadpFromInstruction(6, t0)
2145     loadisFromInstruction(dst, t1)
2146     storeq t0, [cfr, t1, 8]
2147 end
2148
2149 macro varInjectionCheck(slowPath)
2150     loadp CodeBlock[cfr], t0
2151     loadp CodeBlock::m_globalObject[t0], t0
2152     loadp JSGlobalObject::m_varInjectionWatchpoint[t0], t0
2153     bbeq WatchpointSet::m_state[t0], IsInvalidated, slowPath
2154 end
2155
2156 macro resolveScope()
2157     loadisFromInstruction(5, t2)
2158     loadisFromInstruction(2, t0)
2159     loadp [cfr, t0, 8], t0
2160     btiz t2, .resolveScopeLoopEnd
2161
2162 .resolveScopeLoop:
2163     loadp JSScope::m_next[t0], t0
2164     subi 1, t2
2165     btinz t2, .resolveScopeLoop
2166
2167 .resolveScopeLoopEnd:
2168     loadisFromInstruction(1, t1)
2169     storeq t0, [cfr, t1, 8]
2170 end
2171
2172
2173 _llint_op_resolve_scope:
2174     traceExecution()
2175     loadisFromInstruction(4, t0)
2176
2177 #rGlobalProperty:
2178     bineq t0, GlobalProperty, .rGlobalVar
2179     getConstantScope(1)
2180     dispatch(constexpr op_resolve_scope_length)
2181
2182 .rGlobalVar:
2183     bineq t0, GlobalVar, .rGlobalLexicalVar
2184     getConstantScope(1)
2185     dispatch(constexpr op_resolve_scope_length)
2186
2187 .rGlobalLexicalVar:
2188     bineq t0, GlobalLexicalVar, .rClosureVar
2189     getConstantScope(1)
2190     dispatch(constexpr op_resolve_scope_length)
2191
2192 .rClosureVar:
2193     bineq t0, ClosureVar, .rModuleVar
2194     resolveScope()
2195     dispatch(constexpr op_resolve_scope_length)
2196
2197 .rModuleVar:
2198     bineq t0, ModuleVar, .rGlobalPropertyWithVarInjectionChecks
2199     getConstantScope(1)
2200     dispatch(constexpr op_resolve_scope_length)
2201
2202 .rGlobalPropertyWithVarInjectionChecks:
2203     bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
2204     varInjectionCheck(.rDynamic)
2205     getConstantScope(1)
2206     dispatch(constexpr op_resolve_scope_length)
2207
2208 .rGlobalVarWithVarInjectionChecks:
2209     bineq t0, GlobalVarWithVarInjectionChecks, .rGlobalLexicalVarWithVarInjectionChecks
2210     varInjectionCheck(.rDynamic)
2211     getConstantScope(1)
2212     dispatch(constexpr op_resolve_scope_length)
2213
2214 .rGlobalLexicalVarWithVarInjectionChecks:
2215     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
2216     varInjectionCheck(.rDynamic)
2217     getConstantScope(1)
2218     dispatch(constexpr op_resolve_scope_length)
2219
2220 .rClosureVarWithVarInjectionChecks:
2221     bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
2222     varInjectionCheck(.rDynamic)
2223     resolveScope()
2224     dispatch(constexpr op_resolve_scope_length)
2225
2226 .rDynamic:
2227     callOpcodeSlowPath(_slow_path_resolve_scope)
2228     dispatch(constexpr op_resolve_scope_length)
2229
2230
2231 macro loadWithStructureCheck(operand, slowPath)
2232     loadisFromInstruction(operand, t0)
2233     loadq [cfr, t0, 8], t0
2234     loadStructureWithScratch(t0, t2, t1)
2235     loadpFromInstruction(5, t1)
2236     bpneq t2, t1, slowPath
2237 end
2238
2239 macro getProperty()
2240     loadisFromInstruction(6, t1)
2241     loadPropertyAtVariableOffset(t1, t0, t2)
2242     valueProfile(t2, 7, t0)
2243     loadisFromInstruction(1, t0)
2244     storeq t2, [cfr, t0, 8]
2245 end
2246
2247 macro getGlobalVar(tdzCheckIfNecessary)
2248     loadpFromInstruction(6, t0)
2249     loadq [t0], t0
2250     tdzCheckIfNecessary(t0)
2251     valueProfile(t0, 7, t1)
2252     loadisFromInstruction(1, t1)
2253     storeq t0, [cfr, t1, 8]
2254 end
2255
2256 macro getClosureVar()
2257     loadisFromInstruction(6, t1)
2258     loadq JSLexicalEnvironment_variables[t0, t1, 8], t0
2259     valueProfile(t0, 7, t1)
2260     loadisFromInstruction(1, t1)
2261     storeq t0, [cfr, t1, 8]
2262 end
2263
2264 _llint_op_get_from_scope:
2265     traceExecution()
2266     loadisFromInstruction(4, t0)
2267     andi ResolveTypeMask, t0
2268
2269 #gGlobalProperty:
2270     bineq t0, GlobalProperty, .gGlobalVar
2271     loadWithStructureCheck(2, .gDynamic)
2272     getProperty()
2273     dispatch(constexpr op_get_from_scope_length)
2274
2275 .gGlobalVar:
2276     bineq t0, GlobalVar, .gGlobalLexicalVar
2277     getGlobalVar(macro(v) end)
2278     dispatch(constexpr op_get_from_scope_length)
2279
2280 .gGlobalLexicalVar:
2281     bineq t0, GlobalLexicalVar, .gClosureVar
2282     getGlobalVar(
2283         macro (value)
2284             bqeq value, ValueEmpty, .gDynamic
2285         end)
2286     dispatch(constexpr op_get_from_scope_length)
2287
2288 .gClosureVar:
2289     bineq t0, ClosureVar, .gGlobalPropertyWithVarInjectionChecks
2290     loadVariable(2, t0)
2291     getClosureVar()
2292     dispatch(constexpr op_get_from_scope_length)
2293
2294 .gGlobalPropertyWithVarInjectionChecks:
2295     bineq t0, GlobalPropertyWithVarInjectionChecks, .gGlobalVarWithVarInjectionChecks
2296     loadWithStructureCheck(2, .gDynamic)
2297     getProperty()
2298     dispatch(constexpr op_get_from_scope_length)
2299
2300 .gGlobalVarWithVarInjectionChecks:
2301     bineq t0, GlobalVarWithVarInjectionChecks, .gGlobalLexicalVarWithVarInjectionChecks
2302     varInjectionCheck(.gDynamic)
2303     getGlobalVar(macro(v) end)
2304     dispatch(constexpr op_get_from_scope_length)
2305
2306 .gGlobalLexicalVarWithVarInjectionChecks:
2307     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
2308     varInjectionCheck(.gDynamic)
2309     getGlobalVar(
2310         macro (value)
2311             bqeq value, ValueEmpty, .gDynamic
2312         end)
2313     dispatch(constexpr op_get_from_scope_length)
2314
2315 .gClosureVarWithVarInjectionChecks:
2316     bineq t0, ClosureVarWithVarInjectionChecks, .gDynamic
2317     varInjectionCheck(.gDynamic)
2318     loadVariable(2, t0)
2319     getClosureVar()
2320     dispatch(constexpr op_get_from_scope_length)
2321
2322 .gDynamic:
2323     callOpcodeSlowPath(_llint_slow_path_get_from_scope)
2324     dispatch(constexpr op_get_from_scope_length)
2325
2326
2327 macro putProperty()
2328     loadisFromInstruction(3, t1)
2329     loadConstantOrVariable(t1, t2)
2330     loadisFromInstruction(6, t1)
2331     storePropertyAtVariableOffset(t1, t0, t2)
2332 end
2333
2334 macro putGlobalVariable()
2335     loadisFromInstruction(3, t0)
2336     loadConstantOrVariable(t0, t1)
2337     loadpFromInstruction(5, t2)
2338     loadpFromInstruction(6, t0)
2339     notifyWrite(t2, .pDynamic)
2340     storeq t1, [t0]
2341 end
2342
2343 macro putClosureVar()
2344     loadisFromInstruction(3, t1)
2345     loadConstantOrVariable(t1, t2)
2346     loadisFromInstruction(6, t1)
2347     storeq t2, JSLexicalEnvironment_variables[t0, t1, 8]
2348 end
2349
2350 macro putLocalClosureVar()
2351     loadisFromInstruction(3, t1)
2352     loadConstantOrVariable(t1, t2)
2353     loadpFromInstruction(5, t3)
2354     btpz t3, .noVariableWatchpointSet
2355     notifyWrite(t3, .pDynamic)
2356 .noVariableWatchpointSet:
2357     loadisFromInstruction(6, t1)
2358     storeq t2, JSLexicalEnvironment_variables[t0, t1, 8]
2359 end
2360
2361 macro checkTDZInGlobalPutToScopeIfNecessary()
2362     loadisFromInstruction(4, t0)
2363     andi InitializationModeMask, t0
2364     rshifti InitializationModeShift, t0
2365     bineq t0, NotInitialization, .noNeedForTDZCheck
2366     loadpFromInstruction(6, t0)
2367     loadq [t0], t0
2368     bqeq t0, ValueEmpty, .pDynamic
2369 .noNeedForTDZCheck:
2370 end
2371
2372
2373 _llint_op_put_to_scope:
2374     traceExecution()
2375     loadisFromInstruction(4, t0)
2376     andi ResolveTypeMask, t0
2377
2378 #pLocalClosureVar:
2379     bineq t0, LocalClosureVar, .pGlobalProperty
2380     loadVariable(1, t0)
2381     putLocalClosureVar()
2382     writeBarrierOnOperands(1, 3)
2383     dispatch(constexpr op_put_to_scope_length)
2384
2385 .pGlobalProperty:
2386     bineq t0, GlobalProperty, .pGlobalVar
2387     loadWithStructureCheck(1, .pDynamic)
2388     putProperty()
2389     writeBarrierOnOperands(1, 3)
2390     dispatch(constexpr op_put_to_scope_length)
2391
2392 .pGlobalVar:
2393     bineq t0, GlobalVar, .pGlobalLexicalVar
2394     writeBarrierOnGlobalObject(3)
2395     putGlobalVariable()
2396     dispatch(constexpr op_put_to_scope_length)
2397
2398 .pGlobalLexicalVar:
2399     bineq t0, GlobalLexicalVar, .pClosureVar
2400     writeBarrierOnGlobalLexicalEnvironment(3)
2401     checkTDZInGlobalPutToScopeIfNecessary()
2402     putGlobalVariable()
2403     dispatch(constexpr op_put_to_scope_length)
2404
2405 .pClosureVar:
2406     bineq t0, ClosureVar, .pGlobalPropertyWithVarInjectionChecks
2407     loadVariable(1, t0)
2408     putClosureVar()
2409     writeBarrierOnOperands(1, 3)
2410     dispatch(constexpr op_put_to_scope_length)
2411
2412 .pGlobalPropertyWithVarInjectionChecks:
2413     bineq t0, GlobalPropertyWithVarInjectionChecks, .pGlobalVarWithVarInjectionChecks
2414     loadWithStructureCheck(1, .pDynamic)
2415     putProperty()
2416     writeBarrierOnOperands(1, 3)
2417     dispatch(constexpr op_put_to_scope_length)
2418
2419 .pGlobalVarWithVarInjectionChecks:
2420     bineq t0, GlobalVarWithVarInjectionChecks, .pGlobalLexicalVarWithVarInjectionChecks
2421     writeBarrierOnGlobalObject(3)
2422     varInjectionCheck(.pDynamic)
2423     putGlobalVariable()
2424     dispatch(constexpr op_put_to_scope_length)
2425
2426 .pGlobalLexicalVarWithVarInjectionChecks:
2427     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks
2428     writeBarrierOnGlobalLexicalEnvironment(3)
2429     varInjectionCheck(.pDynamic)
2430     checkTDZInGlobalPutToScopeIfNecessary()
2431     putGlobalVariable()
2432     dispatch(constexpr op_put_to_scope_length)
2433
2434 .pClosureVarWithVarInjectionChecks:
2435     bineq t0, ClosureVarWithVarInjectionChecks, .pModuleVar
2436     varInjectionCheck(.pDynamic)
2437     loadVariable(1, t0)
2438     putClosureVar()
2439     writeBarrierOnOperands(1, 3)
2440     dispatch(constexpr op_put_to_scope_length)
2441
2442 .pModuleVar:
2443     bineq t0, ModuleVar, .pDynamic
2444     callOpcodeSlowPath(_slow_path_throw_strict_mode_readonly_property_write_error)
2445     dispatch(constexpr op_put_to_scope_length)
2446
2447 .pDynamic:
2448     callOpcodeSlowPath(_llint_slow_path_put_to_scope)
2449     dispatch(constexpr op_put_to_scope_length)
2450
2451
2452 _llint_op_get_from_arguments:
2453     traceExecution()
2454     loadVariable(2, t0)
2455     loadi 24[PB, PC, 8], t1
2456     loadq DirectArguments_storage[t0, t1, 8], t0
2457     valueProfile(t0, 4, t1)
2458     loadisFromInstruction(1, t1)
2459     storeq t0, [cfr, t1, 8]
2460     dispatch(constexpr op_get_from_arguments_length)
2461
2462
2463 _llint_op_put_to_arguments:
2464     traceExecution()
2465     loadVariable(1, t0)
2466     loadi 16[PB, PC, 8], t1
2467     loadisFromInstruction(3, t3)
2468     loadConstantOrVariable(t3, t2)
2469     storeq t2, DirectArguments_storage[t0, t1, 8]
2470     writeBarrierOnOperands(1, 3)
2471     dispatch(constexpr op_put_to_arguments_length)
2472
2473
2474 _llint_op_get_parent_scope:
2475     traceExecution()
2476     loadVariable(2, t0)
2477     loadp JSScope::m_next[t0], t0
2478     loadisFromInstruction(1, t1)
2479     storeq t0, [cfr, t1, 8]
2480     dispatch(constexpr op_get_parent_scope_length)
2481
2482
2483 _llint_op_profile_type:
2484     traceExecution()
2485     loadp CodeBlock[cfr], t1
2486     loadp CodeBlock::m_vm[t1], t1
2487     # t1 is holding the pointer to the typeProfilerLog.
2488     loadp VM::m_typeProfilerLog[t1], t1
2489     # t2 is holding the pointer to the current log entry.
2490     loadp TypeProfilerLog::m_currentLogEntryPtr[t1], t2
2491
2492     # t0 is holding the JSValue argument.
2493     loadisFromInstruction(1, t3)
2494     loadConstantOrVariable(t3, t0)
2495
2496     bqeq t0, ValueEmpty, .opProfileTypeDone
2497     # Store the JSValue onto the log entry.
2498     storeq t0, TypeProfilerLog::LogEntry::value[t2]
2499     
2500     # Store the TypeLocation onto the log entry.
2501     loadpFromInstruction(2, t3)
2502     storep t3, TypeProfilerLog::LogEntry::location[t2]
2503
2504     btqz t0, tagMask, .opProfileTypeIsCell
2505     storei 0, TypeProfilerLog::LogEntry::structureID[t2]
2506     jmp .opProfileTypeSkipIsCell
2507 .opProfileTypeIsCell:
2508     loadi JSCell::m_structureID[t0], t3
2509     storei t3, TypeProfilerLog::LogEntry::structureID[t2]
2510 .opProfileTypeSkipIsCell:
2511     
2512     # Increment the current log entry.
2513     addp sizeof TypeProfilerLog::LogEntry, t2
2514     storep t2, TypeProfilerLog::m_currentLogEntryPtr[t1]
2515
2516     loadp TypeProfilerLog::m_logEndPtr[t1], t1
2517     bpneq t2, t1, .opProfileTypeDone
2518     callOpcodeSlowPath(_slow_path_profile_type_clear_log)
2519
2520 .opProfileTypeDone:
2521     dispatch(constexpr op_profile_type_length)
2522
2523 _llint_op_profile_control_flow:
2524     traceExecution()
2525     loadpFromInstruction(1, t0)
2526     addq 1, BasicBlockLocation::m_executionCount[t0]
2527     dispatch(constexpr op_profile_control_flow_length)
2528
2529
2530 _llint_op_get_rest_length:
2531     traceExecution()
2532     loadi PayloadOffset + ArgumentCount[cfr], t0
2533     subi 1, t0
2534     loadisFromInstruction(2, t1)
2535     bilteq t0, t1, .storeZero
2536     subi t1, t0
2537     jmp .boxUp
2538 .storeZero:
2539     move 0, t0
2540 .boxUp:
2541     orq tagTypeNumber, t0
2542     loadisFromInstruction(1, t1)
2543     storeq t0, [cfr, t1, 8]
2544     dispatch(constexpr op_get_rest_length_length)
2545
2546
2547 _llint_op_log_shadow_chicken_prologue:
2548     traceExecution()
2549     acquireShadowChickenPacket(.opLogShadowChickenPrologueSlow)
2550     storep cfr, ShadowChicken::Packet::frame[t0]
2551     loadp CallerFrame[cfr], t1
2552     storep t1, ShadowChicken::Packet::callerFrame[t0]
2553     loadp Callee[cfr], t1
2554     storep t1, ShadowChicken::Packet::callee[t0]
2555     loadVariable(1, t1)
2556     storep t1, ShadowChicken::Packet::scope[t0]
2557     dispatch(constexpr op_log_shadow_chicken_prologue_length)
2558 .opLogShadowChickenPrologueSlow:
2559     callOpcodeSlowPath(_llint_slow_path_log_shadow_chicken_prologue)
2560     dispatch(constexpr op_log_shadow_chicken_prologue_length)
2561
2562
2563 _llint_op_log_shadow_chicken_tail:
2564     traceExecution()
2565     acquireShadowChickenPacket(.opLogShadowChickenTailSlow)
2566     storep cfr, ShadowChicken::Packet::frame[t0]
2567     storep ShadowChickenTailMarker, ShadowChicken::Packet::callee[t0]
2568     loadVariable(1, t1)
2569     storep t1, ShadowChicken::Packet::thisValue[t0]
2570     loadVariable(2, t1)
2571     storep t1, ShadowChicken::Packet::scope[t0]
2572     loadp CodeBlock[cfr], t1
2573     storep t1, ShadowChicken::Packet::codeBlock[t0]
2574     storei PC, ShadowChicken::Packet::callSiteIndex[t0]
2575     dispatch(constexpr op_log_shadow_chicken_tail_length)
2576 .opLogShadowChickenTailSlow:
2577     callOpcodeSlowPath(_llint_slow_path_log_shadow_chicken_tail)
2578     dispatch(constexpr op_log_shadow_chicken_tail_length)