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