+macro getPutToBaseOperationField(scratch, scratch1, fieldOffset, fieldGetter)
+ loadpFromInstruction(4, scratch)
+ fieldGetter(fieldOffset[scratch])
+end
+
+macro moveJSValueFromRegisterWithoutProfiling(value, destBuffer, destOffsetReg)
+ storeq value, [destBuffer, destOffsetReg, 8]
+end
+
+
+macro moveJSValueFromRegistersWithoutProfiling(tag, payload, destBuffer, destOffsetReg)
+ storei tag, TagOffset[destBuffer, destOffsetReg, 8]
+ storei payload, PayloadOffset[destBuffer, destOffsetReg, 8]
+end
+
+macro putToBaseVariableBody(variableOffset, scratch1, scratch2, scratch3)
+ loadisFromInstruction(1, scratch1)
+ loadp PayloadOffset[cfr, scratch1, 8], scratch1
+ loadp JSVariableObject::m_registers[scratch1], scratch1
+ loadisFromInstruction(3, scratch2)
+ if JSVALUE64
+ loadConstantOrVariable(scratch2, scratch3)
+ moveJSValueFromRegisterWithoutProfiling(scratch3, scratch1, variableOffset)
+ else
+ loadConstantOrVariable2Reg(scratch2, scratch3, scratch2) # scratch3=tag, scratch2=payload
+ moveJSValueFromRegistersWithoutProfiling(scratch3, scratch2, scratch1, variableOffset)
+ end
+end
+
+_llint_op_put_to_base_variable:
+ traceExecution()
+ getPutToBaseOperationField(t0, t1, PutToBaseOperation::m_offset, macro(addr)
+ loadis addr, t0
+ end)
+ putToBaseVariableBody(t0, t1, t2, t3)
+ dispatch(5)
+
+_llint_op_put_to_base:
+ traceExecution()
+ getPutToBaseOperationField(t0, t1, 0, macro(addr)
+ leap addr, t0
+ bbneq PutToBaseOperation::m_kindAsUint8[t0], PutToBaseOperationKindVariablePut, .notPutToBaseVariable
+ loadis PutToBaseOperation::m_offset[t0], t0
+ putToBaseVariableBody(t0, t1, t2, t3)
+ dispatch(5)
+ .notPutToBaseVariable:
+ end)
+ callSlowPath(_llint_slow_path_put_to_base)
+ dispatch(5)
+
+macro getResolveOperation(resolveOperationIndex, dest)
+ loadpFromInstruction(resolveOperationIndex, dest)
+ loadp VectorBufferOffset[dest], dest
+end
+
+macro getScope(loadInitialScope, scopeCount, dest, scratch)
+ loadInitialScope(dest)
+ loadi scopeCount, scratch
+
+ btiz scratch, .done
+.loop:
+ loadp JSScope::m_next[dest], dest
+ subi 1, scratch
+ btinz scratch, .loop
+
+.done:
+end
+
+macro moveJSValue(sourceBuffer, sourceOffsetReg, destBuffer, destOffsetReg, profileOffset, scratchRegister)
+ if JSVALUE64
+ loadq [sourceBuffer, sourceOffsetReg, 8], scratchRegister
+ storeq scratchRegister, [destBuffer, destOffsetReg, 8]
+ loadpFromInstruction(profileOffset, destOffsetReg)
+ valueProfile(scratchRegister, destOffsetReg)
+ else
+ loadi PayloadOffset[sourceBuffer, sourceOffsetReg, 8], scratchRegister
+ storei scratchRegister, PayloadOffset[destBuffer, destOffsetReg, 8]
+ loadi TagOffset[sourceBuffer, sourceOffsetReg, 8], sourceOffsetReg
+ storei sourceOffsetReg, TagOffset[destBuffer, destOffsetReg, 8]
+ loadpFromInstruction(profileOffset, destOffsetReg)
+ valueProfile(sourceOffsetReg, scratchRegister, destOffsetReg)
+ end
+end
+
+macro moveJSValueFromSlot(slot, destBuffer, destOffsetReg, profileOffset, scratchRegister)
+ if JSVALUE64
+ loadq [slot], scratchRegister
+ storeq scratchRegister, [destBuffer, destOffsetReg, 8]
+ loadpFromInstruction(profileOffset, destOffsetReg)
+ valueProfile(scratchRegister, destOffsetReg)
+ else
+ loadi PayloadOffset[slot], scratchRegister
+ storei scratchRegister, PayloadOffset[destBuffer, destOffsetReg, 8]
+ loadi TagOffset[slot], slot
+ storei slot, TagOffset[destBuffer, destOffsetReg, 8]
+ loadpFromInstruction(profileOffset, destOffsetReg)
+ valueProfile(slot, scratchRegister, destOffsetReg)
+ end
+end
+
+macro moveJSValueFromRegister(value, destBuffer, destOffsetReg, profileOffset)
+ storeq value, [destBuffer, destOffsetReg, 8]
+ loadpFromInstruction(profileOffset, destOffsetReg)
+ valueProfile(value, destOffsetReg)
+end
+
+macro moveJSValueFromRegisters(tag, payload, destBuffer, destOffsetReg, profileOffset)
+ storei tag, TagOffset[destBuffer, destOffsetReg, 8]
+ storei payload, PayloadOffset[destBuffer, destOffsetReg, 8]
+ loadpFromInstruction(profileOffset, destOffsetReg)
+ valueProfile(tag, payload, destOffsetReg)
+end
+
+_llint_op_resolve_global_property:
+ traceExecution()
+ getResolveOperation(3, t0)
+ loadp CodeBlock[cfr], t1
+ loadp CodeBlock::m_globalObject[t1], t1
+ loadp ResolveOperation::m_structure[t0], t2
+ bpneq JSCell::m_structure[t1], t2, .llint_op_resolve_local
+ loadis ResolveOperation::m_offset[t0], t0
+ if JSVALUE64
+ loadPropertyAtVariableOffsetKnownNotInline(t0, t1, t2)
+ loadisFromInstruction(1, t0)
+ moveJSValueFromRegister(t2, cfr, t0, 4)
+ else
+ loadPropertyAtVariableOffsetKnownNotInline(t0, t1, t2, t3)
+ loadisFromInstruction(1, t0)
+ moveJSValueFromRegisters(t2, t3, cfr, t0, 4)
+ end
+ dispatch(5)
+
+_llint_op_resolve_global_var:
+ traceExecution()
+ getResolveOperation(3, t0)
+ loadp ResolveOperation::m_registerAddress[t0], t0
+ loadisFromInstruction(1, t1)
+ moveJSValueFromSlot(t0, cfr, t1, 4, t3)
+ dispatch(5)
+
+macro resolveScopedVarBody(resolveOperations)
+ # First ResolveOperation is to skip scope chain nodes
+ getScope(macro(dest)
+ loadp ScopeChain + PayloadOffset[cfr], dest
+ end,
+ ResolveOperation::m_scopesToSkip[resolveOperations], t1, t2)
+ loadp JSVariableObject::m_registers[t1], t1 # t1 now contains the activation registers
+
+ # Second ResolveOperation tells us what offset to use
+ loadis ResolveOperation::m_offset + sizeof ResolveOperation[resolveOperations], t2
+ loadisFromInstruction(1, t3)
+ moveJSValue(t1, t2, cfr, t3, 4, t0)
+end
+
+_llint_op_resolve_scoped_var:
+ traceExecution()
+ getResolveOperation(3, t0)
+ resolveScopedVarBody(t0)
+ dispatch(5)
+
+_llint_op_resolve_scoped_var_on_top_scope:
+ traceExecution()
+ getResolveOperation(3, t0)
+
+ # Load destination index
+ loadisFromInstruction(1, t3)
+
+ # We know we want the top scope chain entry
+ loadp ScopeChain + PayloadOffset[cfr], t1
+ loadp JSVariableObject::m_registers[t1], t1 # t1 now contains the activation registers
+
+ # Second ResolveOperation tells us what offset to use
+ loadis ResolveOperation::m_offset + sizeof ResolveOperation[t0], t2
+
+ moveJSValue(t1, t2, cfr, t3, 4, t0)
+ dispatch(5)
+
+_llint_op_resolve_scoped_var_with_top_scope_check:
+ traceExecution()
+ getResolveOperation(3, t0)
+ # First ResolveOperation tells us what register to check
+ loadis ResolveOperation::m_activationRegister[t0], t1
+
+ loadp PayloadOffset[cfr, t1, 8], t1
+
+ getScope(macro(dest)
+ btpz t1, .scopeChainNotCreated
+ loadp JSScope::m_next[t1], dest
+ jmp .done
+ .scopeChainNotCreated:
+ loadp ScopeChain + PayloadOffset[cfr], dest
+ .done:
+ end,
+ # Second ResolveOperation tells us how many more nodes to skip
+ ResolveOperation::m_scopesToSkip + sizeof ResolveOperation[t0], t1, t2)
+ loadp JSVariableObject::m_registers[t1], t1 # t1 now contains the activation registers
+
+ # Third operation tells us what offset to use
+ loadis ResolveOperation::m_offset + 2 * sizeof ResolveOperation[t0], t2
+ loadisFromInstruction(1, t3)
+ moveJSValue(t1, t2, cfr, t3, 4, t0)
+ dispatch(5)