121939df44de1705786c545cd1bf519d47250322dBen Murdoch/* 221939df44de1705786c545cd1bf519d47250322dBen Murdoch* Copyright (C) 2008 Apple Inc. All rights reserved. 321939df44de1705786c545cd1bf519d47250322dBen Murdoch* 421939df44de1705786c545cd1bf519d47250322dBen Murdoch* Redistribution and use in source and binary forms, with or without 521939df44de1705786c545cd1bf519d47250322dBen Murdoch* modification, are permitted provided that the following conditions 621939df44de1705786c545cd1bf519d47250322dBen Murdoch* are met: 721939df44de1705786c545cd1bf519d47250322dBen Murdoch* 1. Redistributions of source code must retain the above copyright 821939df44de1705786c545cd1bf519d47250322dBen Murdoch* notice, this list of conditions and the following disclaimer. 921939df44de1705786c545cd1bf519d47250322dBen Murdoch* 2. Redistributions in binary form must reproduce the above copyright 1021939df44de1705786c545cd1bf519d47250322dBen Murdoch* notice, this list of conditions and the following disclaimer in the 1121939df44de1705786c545cd1bf519d47250322dBen Murdoch* documentation and/or other materials provided with the distribution. 1221939df44de1705786c545cd1bf519d47250322dBen Murdoch* 1321939df44de1705786c545cd1bf519d47250322dBen Murdoch* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 1421939df44de1705786c545cd1bf519d47250322dBen Murdoch* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1521939df44de1705786c545cd1bf519d47250322dBen Murdoch* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1621939df44de1705786c545cd1bf519d47250322dBen Murdoch* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 1721939df44de1705786c545cd1bf519d47250322dBen Murdoch* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1821939df44de1705786c545cd1bf519d47250322dBen Murdoch* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1921939df44de1705786c545cd1bf519d47250322dBen Murdoch* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2021939df44de1705786c545cd1bf519d47250322dBen Murdoch* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 2121939df44de1705786c545cd1bf519d47250322dBen Murdoch* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2221939df44de1705786c545cd1bf519d47250322dBen Murdoch* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2321939df44de1705786c545cd1bf519d47250322dBen Murdoch* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2421939df44de1705786c545cd1bf519d47250322dBen Murdoch*/ 2521939df44de1705786c545cd1bf519d47250322dBen Murdoch 2621939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "config.h" 2721939df44de1705786c545cd1bf519d47250322dBen Murdoch 2821939df44de1705786c545cd1bf519d47250322dBen Murdoch#if ENABLE(JIT) 29e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#if USE(JSVALUE32_64) 30e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "JIT.h" 3121939df44de1705786c545cd1bf519d47250322dBen Murdoch 3221939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "CodeBlock.h" 3321939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "JITInlineMethods.h" 3421939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "JITStubCall.h" 3521939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "JITStubs.h" 3621939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "JSArray.h" 3721939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "JSFunction.h" 3821939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "Interpreter.h" 3921939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "ResultType.h" 4021939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "SamplingTool.h" 4121939df44de1705786c545cd1bf519d47250322dBen Murdoch 4221939df44de1705786c545cd1bf519d47250322dBen Murdoch#ifndef NDEBUG 4321939df44de1705786c545cd1bf519d47250322dBen Murdoch#include <stdio.h> 4421939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif 4521939df44de1705786c545cd1bf519d47250322dBen Murdoch 4621939df44de1705786c545cd1bf519d47250322dBen Murdochusing namespace std; 4721939df44de1705786c545cd1bf519d47250322dBen Murdoch 4821939df44de1705786c545cd1bf519d47250322dBen Murdochnamespace JSC { 4921939df44de1705786c545cd1bf519d47250322dBen Murdoch 5021939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_negate(Instruction* currentInstruction) 5121939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 5221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 5321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned src = currentInstruction[2].u.operand; 5421939df44de1705786c545cd1bf519d47250322dBen Murdoch 5521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(src, regT1, regT0); 5621939df44de1705786c545cd1bf519d47250322dBen Murdoch 572bde8e466a4451c7319e3a072d118917957d6554Steve Block Jump srcNotInt = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)); 582bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branchTest32(Zero, regT0, TrustedImm32(0x7fffffff))); 5921939df44de1705786c545cd1bf519d47250322dBen Murdoch neg32(regT0); 6021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (dst == src)); 6121939df44de1705786c545cd1bf519d47250322dBen Murdoch 6221939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 6321939df44de1705786c545cd1bf519d47250322dBen Murdoch 6421939df44de1705786c545cd1bf519d47250322dBen Murdoch srcNotInt.link(this); 652bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag))); 6621939df44de1705786c545cd1bf519d47250322dBen Murdoch 672bde8e466a4451c7319e3a072d118917957d6554Steve Block xor32(TrustedImm32(1 << 31), regT1); 6821939df44de1705786c545cd1bf519d47250322dBen Murdoch store32(regT1, tagFor(dst)); 6921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (dst != src) 7021939df44de1705786c545cd1bf519d47250322dBen Murdoch store32(regT0, payloadFor(dst)); 7121939df44de1705786c545cd1bf519d47250322dBen Murdoch 7221939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 7321939df44de1705786c545cd1bf519d47250322dBen Murdoch} 7421939df44de1705786c545cd1bf519d47250322dBen Murdoch 7521939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_negate(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 7621939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 7721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 7821939df44de1705786c545cd1bf519d47250322dBen Murdoch 7921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // 0x7fffffff check 8021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 8121939df44de1705786c545cd1bf519d47250322dBen Murdoch 8221939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_negate); 8321939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(regT1, regT0); 8421939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 8521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 8621939df44de1705786c545cd1bf519d47250322dBen Murdoch 8721939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_jnless(Instruction* currentInstruction) 8821939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 8921939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[1].u.operand; 9021939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[2].u.operand; 9121939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned target = currentInstruction[3].u.operand; 9221939df44de1705786c545cd1bf519d47250322dBen Murdoch 9321939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op1; 9421939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op2; 9521939df44de1705786c545cd1bf519d47250322dBen Murdoch 9621939df44de1705786c545cd1bf519d47250322dBen Murdoch // Character less. 9721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateChar(op1)) { 9821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op2, regT1, regT0); 992bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 10021939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList failures; 10121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadCharacterString(regT0, regT0, failures); 10221939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(failures); 10321939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target); 10421939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 10521939df44de1705786c545cd1bf519d47250322dBen Murdoch } 10621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateChar(op2)) { 10721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op1, regT1, regT0); 1082bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 10921939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList failures; 11021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadCharacterString(regT0, regT0, failures); 11121939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(failures); 11221939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target); 11321939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 11421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 11521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op1)) { 11621939df44de1705786c545cd1bf519d47250322dBen Murdoch // Int32 less. 11721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op2, regT3, regT2); 1182bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 11921939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target); 12021939df44de1705786c545cd1bf519d47250322dBen Murdoch } else if (isOperandConstantImmediateInt(op2)) { 12121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op1, regT1, regT0); 1222bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 12321939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target); 12421939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 12521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 1262bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 1272bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 12821939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(GreaterThanOrEqual, regT0, regT2), target); 12921939df44de1705786c545cd1bf519d47250322dBen Murdoch } 13021939df44de1705786c545cd1bf519d47250322dBen Murdoch 13121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 13221939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op1); 13321939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op2); 13421939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 13521939df44de1705786c545cd1bf519d47250322dBen Murdoch } 13621939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 13721939df44de1705786c545cd1bf519d47250322dBen Murdoch 13821939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double less. 13921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitBinaryDoubleOp(op_jnless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)); 14021939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 14121939df44de1705786c545cd1bf519d47250322dBen Murdoch} 14221939df44de1705786c545cd1bf519d47250322dBen Murdoch 14321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 14421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 14521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[1].u.operand; 14621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[2].u.operand; 14721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned target = currentInstruction[3].u.operand; 14821939df44de1705786c545cd1bf519d47250322dBen Murdoch 14921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) { 15021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 15121939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 15221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 15321939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 15421939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 15521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 15621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) 15721939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 15821939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 15921939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 16021939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1)) { 16121939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 16221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 16321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 16421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)) 16521939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 16621939df44de1705786c545cd1bf519d47250322dBen Murdoch } 16721939df44de1705786c545cd1bf519d47250322dBen Murdoch } 16821939df44de1705786c545cd1bf519d47250322dBen Murdoch 16921939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_jless); 17021939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 17121939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 17221939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(); 17321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitJumpSlowToHot(branchTest32(Zero, regT0), target); 17421939df44de1705786c545cd1bf519d47250322dBen Murdoch} 17521939df44de1705786c545cd1bf519d47250322dBen Murdoch 17621939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_jless(Instruction* currentInstruction) 17721939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 17821939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[1].u.operand; 17921939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[2].u.operand; 18021939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned target = currentInstruction[3].u.operand; 18121939df44de1705786c545cd1bf519d47250322dBen Murdoch 18221939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op1; 18321939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op2; 18421939df44de1705786c545cd1bf519d47250322dBen Murdoch 18521939df44de1705786c545cd1bf519d47250322dBen Murdoch // Character less. 18621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateChar(op1)) { 18721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op2, regT1, regT0); 1882bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 18921939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList failures; 19021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadCharacterString(regT0, regT0, failures); 19121939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(failures); 19221939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(GreaterThan, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target); 19321939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 19421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 19521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateChar(op2)) { 19621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op1, regT1, regT0); 1972bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 19821939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList failures; 19921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadCharacterString(regT0, regT0, failures); 20021939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(failures); 20121939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(LessThan, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target); 20221939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 20321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 20421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op1)) { 20521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op2, regT3, regT2); 2062bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 20721939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(GreaterThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target); 20821939df44de1705786c545cd1bf519d47250322dBen Murdoch } else if (isOperandConstantImmediateInt(op2)) { 20921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op1, regT1, regT0); 2102bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 21121939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target); 21221939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 21321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 2142bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 2152bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 21621939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(LessThan, regT0, regT2), target); 21721939df44de1705786c545cd1bf519d47250322dBen Murdoch } 21821939df44de1705786c545cd1bf519d47250322dBen Murdoch 21921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 22021939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op1); 22121939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op2); 22221939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 22321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 22421939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 22521939df44de1705786c545cd1bf519d47250322dBen Murdoch 22621939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double less. 22721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitBinaryDoubleOp(op_jless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)); 22821939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 22921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 23021939df44de1705786c545cd1bf519d47250322dBen Murdoch 23121939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 23221939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 23321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[1].u.operand; 23421939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[2].u.operand; 23521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned target = currentInstruction[3].u.operand; 23621939df44de1705786c545cd1bf519d47250322dBen Murdoch 23721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) { 23821939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 23921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 24021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 24121939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 24221939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 24321939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 24421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) 24521939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 24621939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 24721939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 24821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1)) { 24921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 25021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 25121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 25221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)) 25321939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 25421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 25521939df44de1705786c545cd1bf519d47250322dBen Murdoch } 25621939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_jless); 25721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 25821939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 25921939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(); 26021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitJumpSlowToHot(branchTest32(NonZero, regT0), target); 26121939df44de1705786c545cd1bf519d47250322dBen Murdoch} 26221939df44de1705786c545cd1bf519d47250322dBen Murdoch 26321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert) 26421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 26521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[1].u.operand; 26621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[2].u.operand; 26721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned target = currentInstruction[3].u.operand; 26821939df44de1705786c545cd1bf519d47250322dBen Murdoch 26921939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op1; 27021939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op2; 27121939df44de1705786c545cd1bf519d47250322dBen Murdoch 27221939df44de1705786c545cd1bf519d47250322dBen Murdoch // Character less. 27321939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateChar(op1)) { 27421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op2, regT1, regT0); 2752bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 27621939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList failures; 27721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadCharacterString(regT0, regT0, failures); 27821939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(failures); 27921939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target); 28021939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 28121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 28221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateChar(op2)) { 28321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op1, regT1, regT0); 2842bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 28521939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList failures; 28621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadCharacterString(regT0, regT0, failures); 28721939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(failures); 28821939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target); 28921939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 29021939df44de1705786c545cd1bf519d47250322dBen Murdoch } 29121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op1)) { 29221939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op2, regT3, regT2); 2932bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 2946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target); 29521939df44de1705786c545cd1bf519d47250322dBen Murdoch } else if (isOperandConstantImmediateInt(op2)) { 29621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op1, regT1, regT0); 2972bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 29821939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target); 29921939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 30021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 3012bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 3022bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 30321939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, regT2), target); 30421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 30521939df44de1705786c545cd1bf519d47250322dBen Murdoch 30621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 30721939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op1); 30821939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op2); 30921939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 31021939df44de1705786c545cd1bf519d47250322dBen Murdoch } 31121939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 31221939df44de1705786c545cd1bf519d47250322dBen Murdoch 31321939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double less. 31421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitBinaryDoubleOp(invert ? op_jnlesseq : op_jlesseq, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)); 31521939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 31621939df44de1705786c545cd1bf519d47250322dBen Murdoch} 31721939df44de1705786c545cd1bf519d47250322dBen Murdoch 31821939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool invert) 31921939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 32021939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[1].u.operand; 32121939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[2].u.operand; 32221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned target = currentInstruction[3].u.operand; 32321939df44de1705786c545cd1bf519d47250322dBen Murdoch 32421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) { 32521939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 32621939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 32721939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 32821939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 32921939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 33021939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 33121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) 33221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 33321939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 33421939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 33521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1)) { 33621939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 33721939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 33821939df44de1705786c545cd1bf519d47250322dBen Murdoch } 33921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)) 34021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 34121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 34221939df44de1705786c545cd1bf519d47250322dBen Murdoch } 34321939df44de1705786c545cd1bf519d47250322dBen Murdoch 34421939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_jlesseq); 34521939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 34621939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 34721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(); 34821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 34921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 35021939df44de1705786c545cd1bf519d47250322dBen Murdoch 35121939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_jnlesseq(Instruction* currentInstruction) 35221939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 35321939df44de1705786c545cd1bf519d47250322dBen Murdoch emit_op_jlesseq(currentInstruction, true); 35421939df44de1705786c545cd1bf519d47250322dBen Murdoch} 35521939df44de1705786c545cd1bf519d47250322dBen Murdoch 35621939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 35721939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 35821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitSlow_op_jlesseq(currentInstruction, iter, true); 35921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 36021939df44de1705786c545cd1bf519d47250322dBen Murdoch 36121939df44de1705786c545cd1bf519d47250322dBen Murdoch// LeftShift (<<) 36221939df44de1705786c545cd1bf519d47250322dBen Murdoch 36321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_lshift(Instruction* currentInstruction) 36421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 36521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 36621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 36721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 36821939df44de1705786c545cd1bf519d47250322dBen Murdoch 36921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op2)) { 37021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op1, regT1, regT0); 3712bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 37221939df44de1705786c545cd1bf519d47250322dBen Murdoch lshift32(Imm32(getConstantOperand(op2).asInt32()), regT0); 37321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, dst == op1); 37421939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 37521939df44de1705786c545cd1bf519d47250322dBen Murdoch } 37621939df44de1705786c545cd1bf519d47250322dBen Murdoch 37721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 37821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1)) 3792bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 3802bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 38121939df44de1705786c545cd1bf519d47250322dBen Murdoch lshift32(regT2, regT0); 38221939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, dst == op1 || dst == op2); 38321939df44de1705786c545cd1bf519d47250322dBen Murdoch} 38421939df44de1705786c545cd1bf519d47250322dBen Murdoch 38521939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 38621939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 38721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 38821939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 38921939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 39021939df44de1705786c545cd1bf519d47250322dBen Murdoch 39121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) 39221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 39321939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 39421939df44de1705786c545cd1bf519d47250322dBen Murdoch 39521939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_lshift); 39621939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 39721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 39821939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 39921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 40021939df44de1705786c545cd1bf519d47250322dBen Murdoch 40121939df44de1705786c545cd1bf519d47250322dBen Murdoch// RightShift (>>) and UnsignedRightShift (>>>) helper 40221939df44de1705786c545cd1bf519d47250322dBen Murdoch 40321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitRightShift(Instruction* currentInstruction, bool isUnsigned) 40421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 40521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 40621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 40721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 40821939df44de1705786c545cd1bf519d47250322dBen Murdoch 40921939df44de1705786c545cd1bf519d47250322dBen Murdoch // Slow case of rshift makes assumptions about what registers hold the 41021939df44de1705786c545cd1bf519d47250322dBen Murdoch // shift arguments, so any changes must be updated there as well. 41121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op2)) { 41221939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op1, regT1, regT0); 4132bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 41421939df44de1705786c545cd1bf519d47250322dBen Murdoch int shift = getConstantOperand(op2).asInt32(); 41521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isUnsigned) { 41621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (shift) 41721939df44de1705786c545cd1bf519d47250322dBen Murdoch urshift32(Imm32(shift & 0x1f), regT0); 41821939df44de1705786c545cd1bf519d47250322dBen Murdoch // unsigned shift < 0 or shift = k*2^32 may result in (essentially) 41921939df44de1705786c545cd1bf519d47250322dBen Murdoch // a toUint conversion, which can result in a value we can represent 42021939df44de1705786c545cd1bf519d47250322dBen Murdoch // as an immediate int. 42121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (shift < 0 || !(shift & 31)) 4222bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(LessThan, regT0, TrustedImm32(0))); 42321939df44de1705786c545cd1bf519d47250322dBen Murdoch } else if (shift) { // signed right shift by zero is simply toInt conversion 42421939df44de1705786c545cd1bf519d47250322dBen Murdoch rshift32(Imm32(shift & 0x1f), regT0); 42521939df44de1705786c545cd1bf519d47250322dBen Murdoch } 42621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, dst == op1); 42721939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 42821939df44de1705786c545cd1bf519d47250322dBen Murdoch } 42921939df44de1705786c545cd1bf519d47250322dBen Murdoch 43021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 43121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1)) 4322bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 4332bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 43421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isUnsigned) { 43521939df44de1705786c545cd1bf519d47250322dBen Murdoch urshift32(regT2, regT0); 4362bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(LessThan, regT0, TrustedImm32(0))); 43721939df44de1705786c545cd1bf519d47250322dBen Murdoch } else 43821939df44de1705786c545cd1bf519d47250322dBen Murdoch rshift32(regT2, regT0); 43921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, dst == op1 || dst == op2); 44021939df44de1705786c545cd1bf519d47250322dBen Murdoch} 44121939df44de1705786c545cd1bf519d47250322dBen Murdoch 44221939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitRightShiftSlowCase(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool isUnsigned) 44321939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 44421939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 44521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 44621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 44721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op2)) { 44821939df44de1705786c545cd1bf519d47250322dBen Murdoch int shift = getConstantOperand(op2).asInt32(); 44921939df44de1705786c545cd1bf519d47250322dBen Murdoch // op1 = regT1:regT0 45021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 45121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (supportsFloatingPointTruncate()) { 45221939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList failures; 4532bde8e466a4451c7319e3a072d118917957d6554Steve Block failures.append(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag))); 45421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT0); 45521939df44de1705786c545cd1bf519d47250322dBen Murdoch failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0)); 45621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isUnsigned) { 45721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (shift) 45821939df44de1705786c545cd1bf519d47250322dBen Murdoch urshift32(Imm32(shift & 0x1f), regT0); 45921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (shift < 0 || !(shift & 31)) 4602bde8e466a4451c7319e3a072d118917957d6554Steve Block failures.append(branch32(LessThan, regT0, TrustedImm32(0))); 46121939df44de1705786c545cd1bf519d47250322dBen Murdoch } else if (shift) 46221939df44de1705786c545cd1bf519d47250322dBen Murdoch rshift32(Imm32(shift & 0x1f), regT0); 463545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch emitStoreInt32(dst, regT0, false); 46421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift)); 46521939df44de1705786c545cd1bf519d47250322dBen Murdoch failures.link(this); 46621939df44de1705786c545cd1bf519d47250322dBen Murdoch } 46721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isUnsigned && (shift < 0 || !(shift & 31))) 46821939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // failed to box in hot path 46921939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 47021939df44de1705786c545cd1bf519d47250322dBen Murdoch // op1 = regT1:regT0 47121939df44de1705786c545cd1bf519d47250322dBen Murdoch // op2 = regT3:regT2 47221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1)) { 47321939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check -- op1 is not an int 47421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (supportsFloatingPointTruncate()) { 4752bde8e466a4451c7319e3a072d118917957d6554Steve Block Jump notDouble = branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)); // op1 is not a double 47621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT0); 4772bde8e466a4451c7319e3a072d118917957d6554Steve Block Jump notInt = branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)); // op2 is not an int 47821939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump cantTruncate = branchTruncateDoubleToInt32(fpRegT0, regT0); 47921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isUnsigned) 48021939df44de1705786c545cd1bf519d47250322dBen Murdoch urshift32(regT2, regT0); 48121939df44de1705786c545cd1bf519d47250322dBen Murdoch else 48221939df44de1705786c545cd1bf519d47250322dBen Murdoch rshift32(regT2, regT0); 483545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch emitStoreInt32(dst, regT0, false); 48421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift)); 48521939df44de1705786c545cd1bf519d47250322dBen Murdoch notDouble.link(this); 48621939df44de1705786c545cd1bf519d47250322dBen Murdoch notInt.link(this); 48721939df44de1705786c545cd1bf519d47250322dBen Murdoch cantTruncate.link(this); 48821939df44de1705786c545cd1bf519d47250322dBen Murdoch } 48921939df44de1705786c545cd1bf519d47250322dBen Murdoch } 49021939df44de1705786c545cd1bf519d47250322dBen Murdoch 49121939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check - op2 is not an int 49221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isUnsigned) 49321939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // Can't represent unsigned result as an immediate 49421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 49521939df44de1705786c545cd1bf519d47250322dBen Murdoch 49621939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, isUnsigned ? cti_op_urshift : cti_op_rshift); 49721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 49821939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 49921939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 50021939df44de1705786c545cd1bf519d47250322dBen Murdoch} 50121939df44de1705786c545cd1bf519d47250322dBen Murdoch 50221939df44de1705786c545cd1bf519d47250322dBen Murdoch// RightShift (>>) 50321939df44de1705786c545cd1bf519d47250322dBen Murdoch 50421939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_rshift(Instruction* currentInstruction) 50521939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 50621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitRightShift(currentInstruction, false); 50721939df44de1705786c545cd1bf519d47250322dBen Murdoch} 50821939df44de1705786c545cd1bf519d47250322dBen Murdoch 50921939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 51021939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 51121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitRightShiftSlowCase(currentInstruction, iter, false); 51221939df44de1705786c545cd1bf519d47250322dBen Murdoch} 51321939df44de1705786c545cd1bf519d47250322dBen Murdoch 51421939df44de1705786c545cd1bf519d47250322dBen Murdoch// UnsignedRightShift (>>>) 51521939df44de1705786c545cd1bf519d47250322dBen Murdoch 51621939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_urshift(Instruction* currentInstruction) 51721939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 51821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitRightShift(currentInstruction, true); 51921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 52021939df44de1705786c545cd1bf519d47250322dBen Murdoch 52121939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 52221939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 52321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitRightShiftSlowCase(currentInstruction, iter, true); 52421939df44de1705786c545cd1bf519d47250322dBen Murdoch} 52521939df44de1705786c545cd1bf519d47250322dBen Murdoch 52621939df44de1705786c545cd1bf519d47250322dBen Murdoch// BitAnd (&) 52721939df44de1705786c545cd1bf519d47250322dBen Murdoch 52821939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_bitand(Instruction* currentInstruction) 52921939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 53021939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 53121939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 53221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 53321939df44de1705786c545cd1bf519d47250322dBen Murdoch 53421939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op; 53521939df44de1705786c545cd1bf519d47250322dBen Murdoch int32_t constant; 53621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (getOperandConstantImmediateInt(op1, op2, op, constant)) { 53721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op, regT1, regT0); 5382bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 53921939df44de1705786c545cd1bf519d47250322dBen Murdoch and32(Imm32(constant), regT0); 54021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op == dst)); 54121939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 54221939df44de1705786c545cd1bf519d47250322dBen Murdoch } 54321939df44de1705786c545cd1bf519d47250322dBen Murdoch 54421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 5452bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 5462bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 54721939df44de1705786c545cd1bf519d47250322dBen Murdoch and32(regT2, regT0); 54821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); 54921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 55021939df44de1705786c545cd1bf519d47250322dBen Murdoch 55121939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 55221939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 55321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 55421939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 55521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 55621939df44de1705786c545cd1bf519d47250322dBen Murdoch 55721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) 55821939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 55921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 56021939df44de1705786c545cd1bf519d47250322dBen Murdoch 56121939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_bitand); 56221939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 56321939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 56421939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 56521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 56621939df44de1705786c545cd1bf519d47250322dBen Murdoch 56721939df44de1705786c545cd1bf519d47250322dBen Murdoch// BitOr (|) 56821939df44de1705786c545cd1bf519d47250322dBen Murdoch 56921939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_bitor(Instruction* currentInstruction) 57021939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 57121939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 57221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 57321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 57421939df44de1705786c545cd1bf519d47250322dBen Murdoch 57521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op; 57621939df44de1705786c545cd1bf519d47250322dBen Murdoch int32_t constant; 57721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (getOperandConstantImmediateInt(op1, op2, op, constant)) { 57821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op, regT1, regT0); 5792bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 58021939df44de1705786c545cd1bf519d47250322dBen Murdoch or32(Imm32(constant), regT0); 58121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op == dst)); 58221939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 58321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 58421939df44de1705786c545cd1bf519d47250322dBen Murdoch 58521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 5862bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 5872bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 58821939df44de1705786c545cd1bf519d47250322dBen Murdoch or32(regT2, regT0); 58921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); 59021939df44de1705786c545cd1bf519d47250322dBen Murdoch} 59121939df44de1705786c545cd1bf519d47250322dBen Murdoch 59221939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 59321939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 59421939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 59521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 59621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 59721939df44de1705786c545cd1bf519d47250322dBen Murdoch 59821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) 59921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 60021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 60121939df44de1705786c545cd1bf519d47250322dBen Murdoch 60221939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_bitor); 60321939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 60421939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 60521939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 60621939df44de1705786c545cd1bf519d47250322dBen Murdoch} 60721939df44de1705786c545cd1bf519d47250322dBen Murdoch 60821939df44de1705786c545cd1bf519d47250322dBen Murdoch// BitXor (^) 60921939df44de1705786c545cd1bf519d47250322dBen Murdoch 61021939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_bitxor(Instruction* currentInstruction) 61121939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 61221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 61321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 61421939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 61521939df44de1705786c545cd1bf519d47250322dBen Murdoch 61621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op; 61721939df44de1705786c545cd1bf519d47250322dBen Murdoch int32_t constant; 61821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (getOperandConstantImmediateInt(op1, op2, op, constant)) { 61921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op, regT1, regT0); 6202bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 62121939df44de1705786c545cd1bf519d47250322dBen Murdoch xor32(Imm32(constant), regT0); 62221939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op == dst)); 62321939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 62421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 62521939df44de1705786c545cd1bf519d47250322dBen Murdoch 62621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 6272bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 6282bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 62921939df44de1705786c545cd1bf519d47250322dBen Murdoch xor32(regT2, regT0); 63021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); 63121939df44de1705786c545cd1bf519d47250322dBen Murdoch} 63221939df44de1705786c545cd1bf519d47250322dBen Murdoch 63321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 63421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 63521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 63621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 63721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 63821939df44de1705786c545cd1bf519d47250322dBen Murdoch 63921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) 64021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 64121939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 64221939df44de1705786c545cd1bf519d47250322dBen Murdoch 64321939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_bitxor); 64421939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 64521939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 64621939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 64721939df44de1705786c545cd1bf519d47250322dBen Murdoch} 64821939df44de1705786c545cd1bf519d47250322dBen Murdoch 64921939df44de1705786c545cd1bf519d47250322dBen Murdoch// BitNot (~) 65021939df44de1705786c545cd1bf519d47250322dBen Murdoch 65121939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_bitnot(Instruction* currentInstruction) 65221939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 65321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 65421939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned src = currentInstruction[2].u.operand; 65521939df44de1705786c545cd1bf519d47250322dBen Murdoch 65621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(src, regT1, regT0); 6572bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 65821939df44de1705786c545cd1bf519d47250322dBen Murdoch 65921939df44de1705786c545cd1bf519d47250322dBen Murdoch not32(regT0); 66021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (dst == src)); 66121939df44de1705786c545cd1bf519d47250322dBen Murdoch} 66221939df44de1705786c545cd1bf519d47250322dBen Murdoch 66321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 66421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 66521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 66621939df44de1705786c545cd1bf519d47250322dBen Murdoch 66721939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 66821939df44de1705786c545cd1bf519d47250322dBen Murdoch 66921939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_bitnot); 67021939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(regT1, regT0); 67121939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 67221939df44de1705786c545cd1bf519d47250322dBen Murdoch} 67321939df44de1705786c545cd1bf519d47250322dBen Murdoch 67421939df44de1705786c545cd1bf519d47250322dBen Murdoch// PostInc (i++) 67521939df44de1705786c545cd1bf519d47250322dBen Murdoch 67621939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_post_inc(Instruction* currentInstruction) 67721939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 67821939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 67921939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned srcDst = currentInstruction[2].u.operand; 68021939df44de1705786c545cd1bf519d47250322dBen Murdoch 68121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(srcDst, regT1, regT0); 6822bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 68321939df44de1705786c545cd1bf519d47250322dBen Murdoch 68421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (dst == srcDst) // x = x++ is a noop for ints. 68521939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 68621939df44de1705786c545cd1bf519d47250322dBen Murdoch 68721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0); 68821939df44de1705786c545cd1bf519d47250322dBen Murdoch 6892bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT0)); 69021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(srcDst, regT0, true); 69121939df44de1705786c545cd1bf519d47250322dBen Murdoch} 69221939df44de1705786c545cd1bf519d47250322dBen Murdoch 69321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 69421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 69521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 69621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned srcDst = currentInstruction[2].u.operand; 69721939df44de1705786c545cd1bf519d47250322dBen Murdoch 69821939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 69921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (dst != srcDst) 70021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // overflow check 70121939df44de1705786c545cd1bf519d47250322dBen Murdoch 70221939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_post_inc); 70321939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(srcDst); 70421939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(Imm32(srcDst)); 70521939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 70621939df44de1705786c545cd1bf519d47250322dBen Murdoch} 70721939df44de1705786c545cd1bf519d47250322dBen Murdoch 70821939df44de1705786c545cd1bf519d47250322dBen Murdoch// PostDec (i--) 70921939df44de1705786c545cd1bf519d47250322dBen Murdoch 71021939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_post_dec(Instruction* currentInstruction) 71121939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 71221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 71321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned srcDst = currentInstruction[2].u.operand; 71421939df44de1705786c545cd1bf519d47250322dBen Murdoch 71521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(srcDst, regT1, regT0); 7162bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 71721939df44de1705786c545cd1bf519d47250322dBen Murdoch 71821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (dst == srcDst) // x = x-- is a noop for ints. 71921939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 72021939df44de1705786c545cd1bf519d47250322dBen Murdoch 72121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0); 72221939df44de1705786c545cd1bf519d47250322dBen Murdoch 7232bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT0)); 72421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(srcDst, regT0, true); 72521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 72621939df44de1705786c545cd1bf519d47250322dBen Murdoch 72721939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 72821939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 72921939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 73021939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned srcDst = currentInstruction[2].u.operand; 73121939df44de1705786c545cd1bf519d47250322dBen Murdoch 73221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 73321939df44de1705786c545cd1bf519d47250322dBen Murdoch if (dst != srcDst) 73421939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // overflow check 73521939df44de1705786c545cd1bf519d47250322dBen Murdoch 73621939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_post_dec); 73721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(srcDst); 7382bde8e466a4451c7319e3a072d118917957d6554Steve Block stubCall.addArgument(TrustedImm32(srcDst)); 73921939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 74021939df44de1705786c545cd1bf519d47250322dBen Murdoch} 74121939df44de1705786c545cd1bf519d47250322dBen Murdoch 74221939df44de1705786c545cd1bf519d47250322dBen Murdoch// PreInc (++i) 74321939df44de1705786c545cd1bf519d47250322dBen Murdoch 74421939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_pre_inc(Instruction* currentInstruction) 74521939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 74621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned srcDst = currentInstruction[1].u.operand; 74721939df44de1705786c545cd1bf519d47250322dBen Murdoch 74821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(srcDst, regT1, regT0); 74921939df44de1705786c545cd1bf519d47250322dBen Murdoch 7502bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 7512bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT0)); 75221939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(srcDst, regT0, true); 75321939df44de1705786c545cd1bf519d47250322dBen Murdoch} 75421939df44de1705786c545cd1bf519d47250322dBen Murdoch 75521939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 75621939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 75721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned srcDst = currentInstruction[1].u.operand; 75821939df44de1705786c545cd1bf519d47250322dBen Murdoch 75921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 76021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // overflow check 76121939df44de1705786c545cd1bf519d47250322dBen Murdoch 76221939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_pre_inc); 76321939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(srcDst); 76421939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(srcDst); 76521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 76621939df44de1705786c545cd1bf519d47250322dBen Murdoch 76721939df44de1705786c545cd1bf519d47250322dBen Murdoch// PreDec (--i) 76821939df44de1705786c545cd1bf519d47250322dBen Murdoch 76921939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_pre_dec(Instruction* currentInstruction) 77021939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 77121939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned srcDst = currentInstruction[1].u.operand; 77221939df44de1705786c545cd1bf519d47250322dBen Murdoch 77321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(srcDst, regT1, regT0); 77421939df44de1705786c545cd1bf519d47250322dBen Murdoch 7752bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 7762bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT0)); 77721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(srcDst, regT0, true); 77821939df44de1705786c545cd1bf519d47250322dBen Murdoch} 77921939df44de1705786c545cd1bf519d47250322dBen Murdoch 78021939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 78121939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 78221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned srcDst = currentInstruction[1].u.operand; 78321939df44de1705786c545cd1bf519d47250322dBen Murdoch 78421939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 78521939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // overflow check 78621939df44de1705786c545cd1bf519d47250322dBen Murdoch 78721939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_pre_dec); 78821939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(srcDst); 78921939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(srcDst); 79021939df44de1705786c545cd1bf519d47250322dBen Murdoch} 79121939df44de1705786c545cd1bf519d47250322dBen Murdoch 79221939df44de1705786c545cd1bf519d47250322dBen Murdoch// Addition (+) 79321939df44de1705786c545cd1bf519d47250322dBen Murdoch 79421939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_add(Instruction* currentInstruction) 79521939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 79621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 79721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 79821939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 79921939df44de1705786c545cd1bf519d47250322dBen Murdoch OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 80021939df44de1705786c545cd1bf519d47250322dBen Murdoch 80121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) { 80221939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_add); 80321939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 80421939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 80521939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 80621939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 80721939df44de1705786c545cd1bf519d47250322dBen Murdoch } 80821939df44de1705786c545cd1bf519d47250322dBen Murdoch 80921939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op1; 81021939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op2; 81121939df44de1705786c545cd1bf519d47250322dBen Murdoch 81221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op; 81321939df44de1705786c545cd1bf519d47250322dBen Murdoch int32_t constant; 81421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (getOperandConstantImmediateInt(op1, op2, op, constant)) { 81521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitAdd32Constant(dst, op, constant, op == op1 ? types.first() : types.second()); 81621939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 81721939df44de1705786c545cd1bf519d47250322dBen Murdoch } 81821939df44de1705786c545cd1bf519d47250322dBen Murdoch 81921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 8202bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 8212bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 82221939df44de1705786c545cd1bf519d47250322dBen Murdoch 82321939df44de1705786c545cd1bf519d47250322dBen Murdoch // Int32 case. 82421939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(branchAdd32(Overflow, regT2, regT0)); 82521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); 82621939df44de1705786c545cd1bf519d47250322dBen Murdoch 82721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 82821939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op1); 82921939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op2); 83021939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 83121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 83221939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 83321939df44de1705786c545cd1bf519d47250322dBen Murdoch 83421939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double case. 83521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitBinaryDoubleOp(op_add, dst, op1, op2, types, notInt32Op1, notInt32Op2); 83621939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 83721939df44de1705786c545cd1bf519d47250322dBen Murdoch} 83821939df44de1705786c545cd1bf519d47250322dBen Murdoch 83921939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType) 84021939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 84121939df44de1705786c545cd1bf519d47250322dBen Murdoch // Int32 case. 84221939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op, regT1, regT0); 8432bde8e466a4451c7319e3a072d118917957d6554Steve Block Jump notInt32 = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)); 84421939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(branchAdd32(Overflow, Imm32(constant), regT0)); 84521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op == dst)); 84621939df44de1705786c545cd1bf519d47250322dBen Murdoch 84721939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double case. 84821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 84921939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32); 85021939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 85121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 85221939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 85321939df44de1705786c545cd1bf519d47250322dBen Murdoch 85421939df44de1705786c545cd1bf519d47250322dBen Murdoch notInt32.link(this); 85521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!opType.definitelyIsNumber()) 8562bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag))); 85721939df44de1705786c545cd1bf519d47250322dBen Murdoch move(Imm32(constant), regT2); 85821939df44de1705786c545cd1bf519d47250322dBen Murdoch convertInt32ToDouble(regT2, fpRegT0); 85921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op, fpRegT1); 86021939df44de1705786c545cd1bf519d47250322dBen Murdoch addDouble(fpRegT1, fpRegT0); 86121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT0); 86221939df44de1705786c545cd1bf519d47250322dBen Murdoch 86321939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 86421939df44de1705786c545cd1bf519d47250322dBen Murdoch} 86521939df44de1705786c545cd1bf519d47250322dBen Murdoch 86621939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 86721939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 86821939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 86921939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 87021939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 87121939df44de1705786c545cd1bf519d47250322dBen Murdoch OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 87221939df44de1705786c545cd1bf519d47250322dBen Murdoch 87321939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) 87421939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 87521939df44de1705786c545cd1bf519d47250322dBen Murdoch 87621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op; 87721939df44de1705786c545cd1bf519d47250322dBen Murdoch int32_t constant; 87821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (getOperandConstantImmediateInt(op1, op2, op, constant)) { 87921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // overflow check 88021939df44de1705786c545cd1bf519d47250322dBen Murdoch 88121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) 88221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // non-sse case 88321939df44de1705786c545cd1bf519d47250322dBen Murdoch else { 88421939df44de1705786c545cd1bf519d47250322dBen Murdoch ResultType opType = op == op1 ? types.first() : types.second(); 88521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!opType.definitelyIsNumber()) 88621939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 88721939df44de1705786c545cd1bf519d47250322dBen Murdoch } 88821939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 88921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // overflow check 89021939df44de1705786c545cd1bf519d47250322dBen Murdoch 89121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 89221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 89321939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 89421939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 89521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.first().definitelyIsNumber()) 89621939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 89721939df44de1705786c545cd1bf519d47250322dBen Murdoch 89821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.second().definitelyIsNumber()) { 89921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 90021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 90121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 90221939df44de1705786c545cd1bf519d47250322dBen Murdoch } 90321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 90421939df44de1705786c545cd1bf519d47250322dBen Murdoch 90521939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_add); 90621939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 90721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 90821939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 90921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 91021939df44de1705786c545cd1bf519d47250322dBen Murdoch 91121939df44de1705786c545cd1bf519d47250322dBen Murdoch// Subtraction (-) 91221939df44de1705786c545cd1bf519d47250322dBen Murdoch 91321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_sub(Instruction* currentInstruction) 91421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 91521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 91621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 91721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 91821939df44de1705786c545cd1bf519d47250322dBen Murdoch OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 91921939df44de1705786c545cd1bf519d47250322dBen Murdoch 92021939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op1; 92121939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op2; 92221939df44de1705786c545cd1bf519d47250322dBen Murdoch 92321939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op2)) { 92421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitSub32Constant(dst, op1, getConstantOperand(op2).asInt32(), types.first()); 92521939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 92621939df44de1705786c545cd1bf519d47250322dBen Murdoch } 92721939df44de1705786c545cd1bf519d47250322dBen Murdoch 92821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 9292bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 9302bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 93121939df44de1705786c545cd1bf519d47250322dBen Murdoch 93221939df44de1705786c545cd1bf519d47250322dBen Murdoch // Int32 case. 93321939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(branchSub32(Overflow, regT2, regT0)); 93421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); 93521939df44de1705786c545cd1bf519d47250322dBen Murdoch 93621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 93721939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op1); 93821939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op2); 93921939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 94021939df44de1705786c545cd1bf519d47250322dBen Murdoch } 94121939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 94221939df44de1705786c545cd1bf519d47250322dBen Murdoch 94321939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double case. 94421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitBinaryDoubleOp(op_sub, dst, op1, op2, types, notInt32Op1, notInt32Op2); 94521939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 94621939df44de1705786c545cd1bf519d47250322dBen Murdoch} 94721939df44de1705786c545cd1bf519d47250322dBen Murdoch 94821939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType) 94921939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 95021939df44de1705786c545cd1bf519d47250322dBen Murdoch // Int32 case. 95121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op, regT1, regT0); 9522bde8e466a4451c7319e3a072d118917957d6554Steve Block Jump notInt32 = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)); 95321939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(branchSub32(Overflow, Imm32(constant), regT0)); 95421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op == dst)); 95521939df44de1705786c545cd1bf519d47250322dBen Murdoch 95621939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double case. 95721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 95821939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32); 95921939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 96021939df44de1705786c545cd1bf519d47250322dBen Murdoch } 96121939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 96221939df44de1705786c545cd1bf519d47250322dBen Murdoch 96321939df44de1705786c545cd1bf519d47250322dBen Murdoch notInt32.link(this); 96421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!opType.definitelyIsNumber()) 9652bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag))); 96621939df44de1705786c545cd1bf519d47250322dBen Murdoch move(Imm32(constant), regT2); 96721939df44de1705786c545cd1bf519d47250322dBen Murdoch convertInt32ToDouble(regT2, fpRegT0); 96821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op, fpRegT1); 96921939df44de1705786c545cd1bf519d47250322dBen Murdoch subDouble(fpRegT0, fpRegT1); 97021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT1); 97121939df44de1705786c545cd1bf519d47250322dBen Murdoch 97221939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 97321939df44de1705786c545cd1bf519d47250322dBen Murdoch} 97421939df44de1705786c545cd1bf519d47250322dBen Murdoch 97521939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 97621939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 97721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 97821939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 97921939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 98021939df44de1705786c545cd1bf519d47250322dBen Murdoch OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 98121939df44de1705786c545cd1bf519d47250322dBen Murdoch 98221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op2)) { 98321939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // overflow check 98421939df44de1705786c545cd1bf519d47250322dBen Murdoch 98521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint() || !types.first().definitelyIsNumber()) 98621939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 or double check 98721939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 98821939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // overflow check 98921939df44de1705786c545cd1bf519d47250322dBen Murdoch 99021939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 99121939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 99221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 99321939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 99421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.first().definitelyIsNumber()) 99521939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 99621939df44de1705786c545cd1bf519d47250322dBen Murdoch 99721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.second().definitelyIsNumber()) { 99821939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 99921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 100021939df44de1705786c545cd1bf519d47250322dBen Murdoch } 100121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 100221939df44de1705786c545cd1bf519d47250322dBen Murdoch } 100321939df44de1705786c545cd1bf519d47250322dBen Murdoch 100421939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_sub); 100521939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 100621939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 100721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 100821939df44de1705786c545cd1bf519d47250322dBen Murdoch} 100921939df44de1705786c545cd1bf519d47250322dBen Murdoch 101021939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes types, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters, bool op2IsInRegisters) 101121939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 101221939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList end; 101321939df44de1705786c545cd1bf519d47250322dBen Murdoch 101421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!notInt32Op1.empty()) { 101521939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double case 1: Op1 is not int32; Op2 is unknown. 101621939df44de1705786c545cd1bf519d47250322dBen Murdoch notInt32Op1.link(this); 101721939df44de1705786c545cd1bf519d47250322dBen Murdoch 101821939df44de1705786c545cd1bf519d47250322dBen Murdoch ASSERT(op1IsInRegisters); 101921939df44de1705786c545cd1bf519d47250322dBen Murdoch 102021939df44de1705786c545cd1bf519d47250322dBen Murdoch // Verify Op1 is double. 102121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.first().definitelyIsNumber()) 10222bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag))); 102321939df44de1705786c545cd1bf519d47250322dBen Murdoch 102421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!op2IsInRegisters) 102521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad(op2, regT3, regT2); 102621939df44de1705786c545cd1bf519d47250322dBen Murdoch 10272bde8e466a4451c7319e3a072d118917957d6554Steve Block Jump doubleOp2 = branch32(Below, regT3, TrustedImm32(JSValue::LowestTag)); 102821939df44de1705786c545cd1bf519d47250322dBen Murdoch 102921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.second().definitelyIsNumber()) 10302bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 103121939df44de1705786c545cd1bf519d47250322dBen Murdoch 103221939df44de1705786c545cd1bf519d47250322dBen Murdoch convertInt32ToDouble(regT2, fpRegT0); 103321939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump doTheMath = jump(); 103421939df44de1705786c545cd1bf519d47250322dBen Murdoch 103521939df44de1705786c545cd1bf519d47250322dBen Murdoch // Load Op2 as double into double register. 103621939df44de1705786c545cd1bf519d47250322dBen Murdoch doubleOp2.link(this); 103721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op2, fpRegT0); 103821939df44de1705786c545cd1bf519d47250322dBen Murdoch 103921939df44de1705786c545cd1bf519d47250322dBen Murdoch // Do the math. 104021939df44de1705786c545cd1bf519d47250322dBen Murdoch doTheMath.link(this); 104121939df44de1705786c545cd1bf519d47250322dBen Murdoch switch (opcodeID) { 104221939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_mul: 104321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT2); 104421939df44de1705786c545cd1bf519d47250322dBen Murdoch mulDouble(fpRegT2, fpRegT0); 104521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT0); 104621939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 104721939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_add: 104821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT2); 104921939df44de1705786c545cd1bf519d47250322dBen Murdoch addDouble(fpRegT2, fpRegT0); 105021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT0); 105121939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 105221939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_sub: 105321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT1); 105421939df44de1705786c545cd1bf519d47250322dBen Murdoch subDouble(fpRegT0, fpRegT1); 105521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT1); 105621939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 105721939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_div: 105821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT1); 105921939df44de1705786c545cd1bf519d47250322dBen Murdoch divDouble(fpRegT0, fpRegT1); 106021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT1); 106121939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 106221939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_jnless: 106321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT2); 106421939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT0, fpRegT2), dst); 106521939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 106621939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_jless: 106721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT2); 106821939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branchDouble(DoubleLessThan, fpRegT2, fpRegT0), dst); 106921939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 107021939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_jlesseq: 107121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT2); 107221939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branchDouble(DoubleLessThanOrEqual, fpRegT2, fpRegT0), dst); 107321939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 107421939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_jnlesseq: 107521939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op1, fpRegT2); 107621939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT0, fpRegT2), dst); 107721939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 107821939df44de1705786c545cd1bf519d47250322dBen Murdoch default: 107921939df44de1705786c545cd1bf519d47250322dBen Murdoch ASSERT_NOT_REACHED(); 108021939df44de1705786c545cd1bf519d47250322dBen Murdoch } 108121939df44de1705786c545cd1bf519d47250322dBen Murdoch 108221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!notInt32Op2.empty()) 108321939df44de1705786c545cd1bf519d47250322dBen Murdoch end.append(jump()); 108421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 108521939df44de1705786c545cd1bf519d47250322dBen Murdoch 108621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!notInt32Op2.empty()) { 108721939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double case 2: Op1 is int32; Op2 is not int32. 108821939df44de1705786c545cd1bf519d47250322dBen Murdoch notInt32Op2.link(this); 108921939df44de1705786c545cd1bf519d47250322dBen Murdoch 109021939df44de1705786c545cd1bf519d47250322dBen Murdoch ASSERT(op2IsInRegisters); 109121939df44de1705786c545cd1bf519d47250322dBen Murdoch 109221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!op1IsInRegisters) 109321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadPayload(op1, regT0); 109421939df44de1705786c545cd1bf519d47250322dBen Murdoch 109521939df44de1705786c545cd1bf519d47250322dBen Murdoch convertInt32ToDouble(regT0, fpRegT0); 109621939df44de1705786c545cd1bf519d47250322dBen Murdoch 109721939df44de1705786c545cd1bf519d47250322dBen Murdoch // Verify op2 is double. 109821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.second().definitelyIsNumber()) 10992bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(Above, regT3, TrustedImm32(JSValue::LowestTag))); 110021939df44de1705786c545cd1bf519d47250322dBen Murdoch 110121939df44de1705786c545cd1bf519d47250322dBen Murdoch // Do the math. 110221939df44de1705786c545cd1bf519d47250322dBen Murdoch switch (opcodeID) { 110321939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_mul: 110421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op2, fpRegT2); 110521939df44de1705786c545cd1bf519d47250322dBen Murdoch mulDouble(fpRegT2, fpRegT0); 110621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT0); 110721939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 110821939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_add: 110921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op2, fpRegT2); 111021939df44de1705786c545cd1bf519d47250322dBen Murdoch addDouble(fpRegT2, fpRegT0); 111121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT0); 111221939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 111321939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_sub: 111421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op2, fpRegT2); 111521939df44de1705786c545cd1bf519d47250322dBen Murdoch subDouble(fpRegT2, fpRegT0); 111621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT0); 111721939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 111821939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_div: 111921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op2, fpRegT2); 112021939df44de1705786c545cd1bf519d47250322dBen Murdoch divDouble(fpRegT2, fpRegT0); 112121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT0); 112221939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 112321939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_jnless: 112421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op2, fpRegT1); 112521939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), dst); 112621939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 112721939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_jless: 112821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op2, fpRegT1); 112921939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), dst); 113021939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 113121939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_jnlesseq: 113221939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op2, fpRegT1); 113321939df44de1705786c545cd1bf519d47250322dBen Murdoch addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), dst); 113421939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 113521939df44de1705786c545cd1bf519d47250322dBen Murdoch case op_jlesseq: 113621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoadDouble(op2, fpRegT1); 11376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT1), dst); 113821939df44de1705786c545cd1bf519d47250322dBen Murdoch break; 113921939df44de1705786c545cd1bf519d47250322dBen Murdoch default: 114021939df44de1705786c545cd1bf519d47250322dBen Murdoch ASSERT_NOT_REACHED(); 114121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 114221939df44de1705786c545cd1bf519d47250322dBen Murdoch } 114321939df44de1705786c545cd1bf519d47250322dBen Murdoch 114421939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 114521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 114621939df44de1705786c545cd1bf519d47250322dBen Murdoch 114721939df44de1705786c545cd1bf519d47250322dBen Murdoch// Multiplication (*) 114821939df44de1705786c545cd1bf519d47250322dBen Murdoch 114921939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_mul(Instruction* currentInstruction) 115021939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 115121939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 115221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 115321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 115421939df44de1705786c545cd1bf519d47250322dBen Murdoch OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 115521939df44de1705786c545cd1bf519d47250322dBen Murdoch 115621939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op1; 115721939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op2; 115821939df44de1705786c545cd1bf519d47250322dBen Murdoch 115921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 11602bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 11612bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 116221939df44de1705786c545cd1bf519d47250322dBen Murdoch 116321939df44de1705786c545cd1bf519d47250322dBen Murdoch // Int32 case. 116421939df44de1705786c545cd1bf519d47250322dBen Murdoch move(regT0, regT3); 116521939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(branchMul32(Overflow, regT2, regT0)); 116621939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(branchTest32(Zero, regT0)); 116721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); 116821939df44de1705786c545cd1bf519d47250322dBen Murdoch 116921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 117021939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op1); 117121939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(notInt32Op2); 117221939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 117321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 117421939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 117521939df44de1705786c545cd1bf519d47250322dBen Murdoch 117621939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double case. 117721939df44de1705786c545cd1bf519d47250322dBen Murdoch emitBinaryDoubleOp(op_mul, dst, op1, op2, types, notInt32Op1, notInt32Op2); 117821939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 117921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 118021939df44de1705786c545cd1bf519d47250322dBen Murdoch 118121939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 118221939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 118321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 118421939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 118521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 118621939df44de1705786c545cd1bf519d47250322dBen Murdoch OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 118721939df44de1705786c545cd1bf519d47250322dBen Murdoch 118821939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump overflow = getSlowCase(iter); // overflow check 118921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // zero result check 119021939df44de1705786c545cd1bf519d47250322dBen Murdoch 119121939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump negZero = branchOr32(Signed, regT2, regT3); 11922bde8e466a4451c7319e3a072d118917957d6554Steve Block emitStoreInt32(dst, TrustedImm32(0), (op1 == dst || op2 == dst)); 119321939df44de1705786c545cd1bf519d47250322dBen Murdoch 119421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_mul)); 119521939df44de1705786c545cd1bf519d47250322dBen Murdoch 119621939df44de1705786c545cd1bf519d47250322dBen Murdoch negZero.link(this); 119721939df44de1705786c545cd1bf519d47250322dBen Murdoch overflow.link(this); 119821939df44de1705786c545cd1bf519d47250322dBen Murdoch 119921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 120021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 120121939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 120221939df44de1705786c545cd1bf519d47250322dBen Murdoch } 120321939df44de1705786c545cd1bf519d47250322dBen Murdoch 120421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (supportsFloatingPoint()) { 120521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.first().definitelyIsNumber()) 120621939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 120721939df44de1705786c545cd1bf519d47250322dBen Murdoch 120821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.second().definitelyIsNumber()) { 120921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 121021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 121121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 121221939df44de1705786c545cd1bf519d47250322dBen Murdoch } 121321939df44de1705786c545cd1bf519d47250322dBen Murdoch 121421939df44de1705786c545cd1bf519d47250322dBen Murdoch Label jitStubCall(this); 121521939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_mul); 121621939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 121721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 121821939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 121921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 122021939df44de1705786c545cd1bf519d47250322dBen Murdoch 122121939df44de1705786c545cd1bf519d47250322dBen Murdoch// Division (/) 122221939df44de1705786c545cd1bf519d47250322dBen Murdoch 122321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_div(Instruction* currentInstruction) 122421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 122521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 122621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 122721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 122821939df44de1705786c545cd1bf519d47250322dBen Murdoch OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 122921939df44de1705786c545cd1bf519d47250322dBen Murdoch 123021939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) { 123121939df44de1705786c545cd1bf519d47250322dBen Murdoch addSlowCase(jump()); 123221939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 123321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 123421939df44de1705786c545cd1bf519d47250322dBen Murdoch 123521939df44de1705786c545cd1bf519d47250322dBen Murdoch // Int32 divide. 123621939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op1; 123721939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList notInt32Op2; 123821939df44de1705786c545cd1bf519d47250322dBen Murdoch 123921939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList end; 124021939df44de1705786c545cd1bf519d47250322dBen Murdoch 124121939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 124221939df44de1705786c545cd1bf519d47250322dBen Murdoch 12432bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 12442bde8e466a4451c7319e3a072d118917957d6554Steve Block notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 124521939df44de1705786c545cd1bf519d47250322dBen Murdoch 124621939df44de1705786c545cd1bf519d47250322dBen Murdoch convertInt32ToDouble(regT0, fpRegT0); 124721939df44de1705786c545cd1bf519d47250322dBen Murdoch convertInt32ToDouble(regT2, fpRegT1); 124821939df44de1705786c545cd1bf519d47250322dBen Murdoch divDouble(fpRegT1, fpRegT0); 124921939df44de1705786c545cd1bf519d47250322dBen Murdoch 125021939df44de1705786c545cd1bf519d47250322dBen Murdoch JumpList doubleResult; 125121939df44de1705786c545cd1bf519d47250322dBen Murdoch branchConvertDoubleToInt32(fpRegT0, regT0, doubleResult, fpRegT1); 125221939df44de1705786c545cd1bf519d47250322dBen Murdoch 125321939df44de1705786c545cd1bf519d47250322dBen Murdoch // Int32 result. 125421939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); 125521939df44de1705786c545cd1bf519d47250322dBen Murdoch end.append(jump()); 125621939df44de1705786c545cd1bf519d47250322dBen Murdoch 125721939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double result. 125821939df44de1705786c545cd1bf519d47250322dBen Murdoch doubleResult.link(this); 125921939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreDouble(dst, fpRegT0); 126021939df44de1705786c545cd1bf519d47250322dBen Murdoch end.append(jump()); 126121939df44de1705786c545cd1bf519d47250322dBen Murdoch 126221939df44de1705786c545cd1bf519d47250322dBen Murdoch // Double divide. 126321939df44de1705786c545cd1bf519d47250322dBen Murdoch emitBinaryDoubleOp(op_div, dst, op1, op2, types, notInt32Op1, notInt32Op2); 126421939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 126521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 126621939df44de1705786c545cd1bf519d47250322dBen Murdoch 126721939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 126821939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 126921939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 127021939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 127121939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 127221939df44de1705786c545cd1bf519d47250322dBen Murdoch OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 127321939df44de1705786c545cd1bf519d47250322dBen Murdoch 127421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!supportsFloatingPoint()) 127521939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 127621939df44de1705786c545cd1bf519d47250322dBen Murdoch else { 127721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.first().definitelyIsNumber()) 127821939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 127921939df44de1705786c545cd1bf519d47250322dBen Murdoch 128021939df44de1705786c545cd1bf519d47250322dBen Murdoch if (!types.second().definitelyIsNumber()) { 128121939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 128221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // double check 128321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 128421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 128521939df44de1705786c545cd1bf519d47250322dBen Murdoch 128621939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_div); 128721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 128821939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 128921939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 129021939df44de1705786c545cd1bf519d47250322dBen Murdoch} 129121939df44de1705786c545cd1bf519d47250322dBen Murdoch 129221939df44de1705786c545cd1bf519d47250322dBen Murdoch// Mod (%) 129321939df44de1705786c545cd1bf519d47250322dBen Murdoch 129421939df44de1705786c545cd1bf519d47250322dBen Murdoch/* ------------------------------ BEGIN: OP_MOD ------------------------------ */ 129521939df44de1705786c545cd1bf519d47250322dBen Murdoch 1296e14391e94c850b8bd03680c23b38978db68687a8John Reck#if CPU(X86) || CPU(X86_64) || CPU(MIPS) 129721939df44de1705786c545cd1bf519d47250322dBen Murdoch 129821939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_mod(Instruction* currentInstruction) 129921939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 130021939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 130121939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 130221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 130321939df44de1705786c545cd1bf519d47250322dBen Murdoch 1304e14391e94c850b8bd03680c23b38978db68687a8John Reck#if CPU(X86) || CPU(X86_64) 1305e14391e94c850b8bd03680c23b38978db68687a8John Reck // Make sure registers are correct for x86 IDIV instructions. 1306e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(regT0 == X86Registers::eax); 1307e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(regT1 == X86Registers::edx); 1308e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(regT2 == X86Registers::ecx); 1309e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(regT3 == X86Registers::ebx); 1310e14391e94c850b8bd03680c23b38978db68687a8John Reck#endif 1311e14391e94c850b8bd03680c23b38978db68687a8John Reck 131221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op2) && getConstantOperand(op2).asInt32() != 0) { 1313e14391e94c850b8bd03680c23b38978db68687a8John Reck emitLoad(op1, regT1, regT0); 1314e14391e94c850b8bd03680c23b38978db68687a8John Reck move(Imm32(getConstantOperand(op2).asInt32()), regT2); 13152bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 131621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (getConstantOperand(op2).asInt32() == -1) 13172bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(Equal, regT0, TrustedImm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC 131821939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 1319e14391e94c850b8bd03680c23b38978db68687a8John Reck emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 13202bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 13212bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 132221939df44de1705786c545cd1bf519d47250322dBen Murdoch 13232bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(Equal, regT0, TrustedImm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC 13242bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(Equal, regT2, TrustedImm32(0))); // divide by 0 132521939df44de1705786c545cd1bf519d47250322dBen Murdoch } 132621939df44de1705786c545cd1bf519d47250322dBen Murdoch 1327e14391e94c850b8bd03680c23b38978db68687a8John Reck move(regT0, regT3); // Save dividend payload, in case of 0. 1328e14391e94c850b8bd03680c23b38978db68687a8John Reck#if CPU(X86) || CPU(X86_64) 132921939df44de1705786c545cd1bf519d47250322dBen Murdoch m_assembler.cdq(); 1330e14391e94c850b8bd03680c23b38978db68687a8John Reck m_assembler.idivl_r(regT2); 1331e14391e94c850b8bd03680c23b38978db68687a8John Reck#elif CPU(MIPS) 1332e14391e94c850b8bd03680c23b38978db68687a8John Reck m_assembler.div(regT0, regT2); 1333e14391e94c850b8bd03680c23b38978db68687a8John Reck m_assembler.mfhi(regT1); 1334e14391e94c850b8bd03680c23b38978db68687a8John Reck#endif 133521939df44de1705786c545cd1bf519d47250322dBen Murdoch 133621939df44de1705786c545cd1bf519d47250322dBen Murdoch // If the remainder is zero and the dividend is negative, the result is -0. 1337e14391e94c850b8bd03680c23b38978db68687a8John Reck Jump storeResult1 = branchTest32(NonZero, regT1); 13382bde8e466a4451c7319e3a072d118917957d6554Steve Block Jump storeResult2 = branchTest32(Zero, regT3, TrustedImm32(0x80000000)); // not negative 1339e14391e94c850b8bd03680c23b38978db68687a8John Reck emitStore(dst, jsNumber(-0.0)); 134021939df44de1705786c545cd1bf519d47250322dBen Murdoch Jump end = jump(); 134121939df44de1705786c545cd1bf519d47250322dBen Murdoch 134221939df44de1705786c545cd1bf519d47250322dBen Murdoch storeResult1.link(this); 134321939df44de1705786c545cd1bf519d47250322dBen Murdoch storeResult2.link(this); 1344e14391e94c850b8bd03680c23b38978db68687a8John Reck emitStoreInt32(dst, regT1, (op1 == dst || op2 == dst)); 134521939df44de1705786c545cd1bf519d47250322dBen Murdoch end.link(this); 134621939df44de1705786c545cd1bf519d47250322dBen Murdoch} 134721939df44de1705786c545cd1bf519d47250322dBen Murdoch 134821939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 134921939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 135021939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 135121939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 135221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 135321939df44de1705786c545cd1bf519d47250322dBen Murdoch 135421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isOperandConstantImmediateInt(op2) && getConstantOperand(op2).asInt32() != 0) { 135521939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 135621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (getConstantOperand(op2).asInt32() == -1) 135721939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // 0x80000000 check 135821939df44de1705786c545cd1bf519d47250322dBen Murdoch } else { 135921939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 136021939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // int32 check 136121939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // 0 check 136221939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); // 0x80000000 check 136321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 136421939df44de1705786c545cd1bf519d47250322dBen Murdoch 136521939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_mod); 136621939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 136721939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 136821939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 136921939df44de1705786c545cd1bf519d47250322dBen Murdoch} 137021939df44de1705786c545cd1bf519d47250322dBen Murdoch 1371e14391e94c850b8bd03680c23b38978db68687a8John Reck#else // CPU(X86) || CPU(X86_64) || CPU(MIPS) 137221939df44de1705786c545cd1bf519d47250322dBen Murdoch 137321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emit_op_mod(Instruction* currentInstruction) 137421939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 137521939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned dst = currentInstruction[1].u.operand; 137621939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 137721939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 137821939df44de1705786c545cd1bf519d47250322dBen Murdoch 13790617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#if ENABLE(JIT_USE_SOFT_MODULO) 138021939df44de1705786c545cd1bf519d47250322dBen Murdoch emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 13812bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 13822bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 138321939df44de1705786c545cd1bf519d47250322dBen Murdoch 13842bde8e466a4451c7319e3a072d118917957d6554Steve Block addSlowCase(branch32(Equal, regT2, TrustedImm32(0))); 138521939df44de1705786c545cd1bf519d47250322dBen Murdoch 1386967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch emitNakedCall(m_globalData->jitStubs->ctiSoftModulo()); 138721939df44de1705786c545cd1bf519d47250322dBen Murdoch 138821939df44de1705786c545cd1bf519d47250322dBen Murdoch emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst)); 138921939df44de1705786c545cd1bf519d47250322dBen Murdoch#else 139021939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_mod); 139121939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 139221939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 139321939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(dst); 139421939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif 139521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 139621939df44de1705786c545cd1bf519d47250322dBen Murdoch 139721939df44de1705786c545cd1bf519d47250322dBen Murdochvoid JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 139821939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 1399dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch UNUSED_PARAM(currentInstruction); 1400dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch UNUSED_PARAM(iter); 14010617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#if ENABLE(JIT_USE_SOFT_MODULO) 140221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned result = currentInstruction[1].u.operand; 140321939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op1 = currentInstruction[2].u.operand; 140421939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned op2 = currentInstruction[3].u.operand; 140521939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 140621939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 140721939df44de1705786c545cd1bf519d47250322dBen Murdoch linkSlowCase(iter); 140821939df44de1705786c545cd1bf519d47250322dBen Murdoch JITStubCall stubCall(this, cti_op_mod); 140921939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op1); 141021939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.addArgument(op2); 141121939df44de1705786c545cd1bf519d47250322dBen Murdoch stubCall.call(result); 141221939df44de1705786c545cd1bf519d47250322dBen Murdoch#else 141321939df44de1705786c545cd1bf519d47250322dBen Murdoch ASSERT_NOT_REACHED(); 141421939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif 141521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 141621939df44de1705786c545cd1bf519d47250322dBen Murdoch 141721939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif // CPU(X86) || CPU(X86_64) 141821939df44de1705786c545cd1bf519d47250322dBen Murdoch 141921939df44de1705786c545cd1bf519d47250322dBen Murdoch/* ------------------------------ END: OP_MOD ------------------------------ */ 142021939df44de1705786c545cd1bf519d47250322dBen Murdoch 1421e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} // namespace JSC 142221939df44de1705786c545cd1bf519d47250322dBen Murdoch 1423e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#endif // USE(JSVALUE32_64) 142421939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif // ENABLE(JIT) 1425