void JIT::compileLoadVarargs(Instruction* instruction) { int thisValue = instruction[2].u.operand; int arguments = instruction[3].u.operand; int firstFreeRegister = instruction[4].u.operand; killLastResultRegister(); JumpList slowCase; JumpList end; if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) { emitGetVirtualRegister(arguments, regT0); slowCase.append(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(JSValue())))); emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1))); // regT0: argumentCountIncludingThis move(regT0, regT1); add32(TrustedImm32(firstFreeRegister + RegisterFile::CallFrameHeaderSize), regT1); lshift32(TrustedImm32(3), regT1); addPtr(callFrameRegister, regT1); // regT1: newCallFrame slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT1)); // Initialize ArgumentCount. emitFastArithReTagImmediate(regT0, regT2); storePtr(regT2, Address(regT1, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)))); // Initialize 'this'. emitGetVirtualRegister(thisValue, regT2); storePtr(regT2, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))); // Copy arguments. neg32(regT0); signExtend32ToPtr(regT0, regT0); end.append(branchAddPtr(Zero, Imm32(1), regT0)); // regT0: -argumentCount Label copyLoop = label(); loadPtr(BaseIndex(callFrameRegister, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT2); storePtr(regT2, BaseIndex(regT1, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))); branchAddPtr(NonZero, Imm32(1), regT0).linkTo(copyLoop, this); end.append(jump()); } if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) slowCase.link(this); JITStubCall stubCall(this, cti_op_load_varargs); stubCall.addArgument(thisValue, regT0); stubCall.addArgument(arguments, regT0); stubCall.addArgument(Imm32(firstFreeRegister)); stubCall.call(regT1); if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) end.link(this); }
void JIT::compileLoadVarargs(Instruction* instruction) { int thisValue = instruction[2].u.operand; int arguments = instruction[3].u.operand; int firstFreeRegister = instruction[4].u.operand; JumpList slowCase; JumpList end; if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) { emitLoadTag(arguments, regT1); slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag))); load32(payloadFor(RegisterFile::ArgumentCount), regT2); slowCase.append(branch32(Above, regT2, TrustedImm32(Arguments::MaxArguments + 1))); // regT2: argumentCountIncludingThis move(regT2, regT3); add32(TrustedImm32(firstFreeRegister + RegisterFile::CallFrameHeaderSize), regT3); lshift32(TrustedImm32(3), regT3); addPtr(callFrameRegister, regT3); // regT3: newCallFrame slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT3)); // Initialize ArgumentCount. store32(regT2, payloadFor(RegisterFile::ArgumentCount, regT3)); // Initialize 'this'. emitLoad(thisValue, regT1, regT0); store32(regT0, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))))); store32(regT1, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))))); // Copy arguments. neg32(regT2); end.append(branchAdd32(Zero, TrustedImm32(1), regT2)); // regT2: -argumentCount; Label copyLoop = label(); load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))), regT0); load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))), regT1); store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))))); store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))))); branchAdd32(NonZero, TrustedImm32(1), regT2).linkTo(copyLoop, this); end.append(jump()); } if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) slowCase.link(this); JITStubCall stubCall(this, cti_op_load_varargs); stubCall.addArgument(thisValue); stubCall.addArgument(arguments); stubCall.addArgument(Imm32(firstFreeRegister)); stubCall.call(regT3); if (m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister()) end.link(this); }
void main() { struct long32 first, second, working; char s[20]; while (TRUE) { printf ("\r\n\r\nEnter the first number: "); get_string (s,20); atol32 (s,&first); printf ("\r\nEnter the second number: "); get_string (s,20); atol32 (s,&second); printf ("\r\n\r\nA: "); print_long32 (&first); printf ("\r\nB: "); print_long32 (&second); working.hi = first.hi; working.lo = first.lo; add32 (&working, &second); printf ("\r\na + b = "); print_long32 (&working); working.hi = first.hi; working.lo = first.lo; sub32 (&working, &second); printf ("\r\na - b = "); print_long32 (&working); working.hi = first.hi; working.lo = first.lo; mul32 (&working, &second); printf ("\r\na * b = "); print_long32 (&working); working.hi = first.hi; working.lo = first.lo; div32 (&working, &second); printf ("\r\na / b = "); print_long32 (&working); rem32 (&first, &second, &working); printf ("\r\na modulus b = "); print_long32 (&working); } }
void JIT::compileLoadVarargs(Instruction* instruction) { int thisValue = instruction[3].u.operand; int arguments = instruction[4].u.operand; int firstFreeRegister = instruction[5].u.operand; JumpList slowCase; JumpList end; bool canOptimize = m_codeBlock->usesArguments() && VirtualRegister(arguments) == m_codeBlock->argumentsRegister() && !m_codeBlock->symbolTable()->slowArguments(); if (canOptimize) { emitLoadTag(arguments, regT1); slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag))); load32(payloadFor(JSStack::ArgumentCount), regT2); slowCase.append(branch32(Above, regT2, TrustedImm32(Arguments::MaxArguments + 1))); // regT2: argumentCountIncludingThis move(regT2, regT3); neg32(regT3); add32(TrustedImm32(firstFreeRegister - JSStack::CallFrameHeaderSize), regT3); lshift32(TrustedImm32(3), regT3); addPtr(callFrameRegister, regT3); // regT3: newCallFrame slowCase.append(branchPtr(Above, AbsoluteAddress(m_vm->interpreter->stack().addressOfEnd()), regT3)); // Initialize ArgumentCount. store32(regT2, payloadFor(JSStack::ArgumentCount, regT3)); // Initialize 'this'. emitLoad(thisValue, regT1, regT0); store32(regT0, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))))); store32(regT1, Address(regT3, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))))); // Copy arguments. end.append(branchSub32(Zero, TrustedImm32(1), regT2)); // regT2: argumentCount; Label copyLoop = label(); load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))), regT0); load32(BaseIndex(callFrameRegister, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))), regT1); store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))))); store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) +(CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))))); branchSub32(NonZero, TrustedImm32(1), regT2).linkTo(copyLoop, this); end.append(jump()); } if (canOptimize) slowCase.link(this); emitLoad(thisValue, regT1, regT0); emitLoad(arguments, regT3, regT2); callOperation(operationLoadVarargs, regT1, regT0, regT3, regT2, firstFreeRegister); move(returnValueRegister, regT3); if (canOptimize) end.link(this); }
void JITCompiler::emitCount(AbstractSamplingCounter& counter, uint32_t increment) { intptr_t hiWord = reinterpret_cast<intptr_t>(counter.addressOfCounter()) + sizeof(int32_t); add32(TrustedImm32(increment), AbsoluteAddress(counter.addressOfCounter())); addWithCarry32(TrustedImm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord))); }
void JIT::compileLoadVarargs(Instruction* instruction) { int thisValue = instruction[2].u.operand; int arguments = instruction[3].u.operand; int firstFreeRegister = instruction[4].u.operand; killLastResultRegister(); JumpList slowCase; JumpList end; bool canOptimize = m_codeBlock->usesArguments() && arguments == m_codeBlock->argumentsRegister() && !m_codeBlock->symbolTable()->slowArguments(); if (canOptimize) { emitGetVirtualRegister(arguments, regT0); slowCase.append(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(JSValue())))); emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0); slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1))); // regT0: argumentCountIncludingThis move(regT0, regT1); add32(TrustedImm32(firstFreeRegister + JSStack::CallFrameHeaderSize), regT1); lshift32(TrustedImm32(3), regT1); addPtr(callFrameRegister, regT1); // regT1: newCallFrame slowCase.append(branchPtr(Below, AbsoluteAddress(m_vm->interpreter->stack().addressOfEnd()), regT1)); // Initialize ArgumentCount. store32(regT0, Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); // Initialize 'this'. emitGetVirtualRegister(thisValue, regT2); store64(regT2, Address(regT1, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))); // Copy arguments. neg32(regT0); signExtend32ToPtr(regT0, regT0); end.append(branchAdd64(Zero, TrustedImm32(1), regT0)); // regT0: -argumentCount Label copyLoop = label(); load64(BaseIndex(callFrameRegister, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register))), regT2); store64(regT2, BaseIndex(regT1, regT0, TimesEight, CallFrame::thisArgumentOffset() * static_cast<int>(sizeof(Register)))); branchAdd64(NonZero, TrustedImm32(1), regT0).linkTo(copyLoop, this); end.append(jump()); } if (canOptimize) slowCase.link(this); JITStubCall stubCall(this, cti_op_load_varargs); stubCall.addArgument(thisValue, regT0); stubCall.addArgument(arguments, regT0); stubCall.addArgument(Imm32(firstFreeRegister)); stubCall.call(regT1); if (canOptimize) end.link(this); }
void test32 (void) { if (add32 (arr32) != arr32[0] + arr32[1] + arr32[2]) __builtin_abort(); }