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