-void JIT::emit_op_jnless(Instruction* currentInstruction)
-{
- unsigned op1 = currentInstruction[1].u.operand;
- unsigned op2 = currentInstruction[2].u.operand;
- unsigned target = currentInstruction[3].u.operand;
-
- // We generate inline code for the following cases in the fast path:
- // - int immediate to constant int immediate
- // - constant int immediate to int immediate
- // - int immediate to int immediate
-
- if (isOperandConstantImmediateChar(op1)) {
- emitGetVirtualRegister(op2, regT0);
- addSlowCase(emitJumpIfNotJSCell(regT0));
- JumpList failures;
- emitLoadCharacterString(regT0, regT0, failures);
- addSlowCase(failures);
- addJump(branch32(LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
- return;
- }
- if (isOperandConstantImmediateChar(op2)) {
- emitGetVirtualRegister(op1, regT0);
- addSlowCase(emitJumpIfNotJSCell(regT0));
- JumpList failures;
- emitLoadCharacterString(regT0, regT0, failures);
- addSlowCase(failures);
- addJump(branch32(GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
- return;
- }
- if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- int32_t op2imm = getConstantOperandImmediateInt(op2);
- addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target);
- } else if (isOperandConstantImmediateInt(op1)) {
- emitGetVirtualRegister(op2, regT1);
- emitJumpSlowCaseIfNotImmediateInteger(regT1);
- int32_t op1imm = getConstantOperandImmediateInt(op1);
- addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target);
- } else {
- emitGetVirtualRegisters(op1, regT0, op2, regT1);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT1);
-
- addJump(branch32(GreaterThanOrEqual, regT0, regT1), target);
- }
-}
-
-void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned op1 = currentInstruction[1].u.operand;
- unsigned op2 = currentInstruction[2].u.operand;
- unsigned target = currentInstruction[3].u.operand;
-
- // We generate inline code for the following cases in the slow path:
- // - floating-point number to constant int immediate
- // - constant int immediate to floating-point number
- // - floating-point number to floating-point number.
- if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_jless);
- stubCall.addArgument(op1, regT0);
- stubCall.addArgument(op2, regT1);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target);
- return;
- }
-
- if (isOperandConstantImmediateInt(op2)) {
- linkSlowCase(iter);
-
- if (supportsFloatingPoint()) {
- Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
- addPtr(tagTypeNumberRegister, regT0);
- movePtrToDouble(regT0, fpRegT0);
-
- int32_t op2imm = getConstantOperand(op2).asInt32();;
-
- move(Imm32(op2imm), regT1);
- convertInt32ToDouble(regT1, fpRegT1);
-
- emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
-
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-
- fail1.link(this);
- }
-
- JITStubCall stubCall(this, cti_op_jless);
- stubCall.addArgument(regT0);
- stubCall.addArgument(op2, regT2);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target);
-
- } else if (isOperandConstantImmediateInt(op1)) {
- linkSlowCase(iter);
-
- if (supportsFloatingPoint()) {
- Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
- addPtr(tagTypeNumberRegister, regT1);
- movePtrToDouble(regT1, fpRegT1);
-
- int32_t op1imm = getConstantOperand(op1).asInt32();;
-
- move(Imm32(op1imm), regT0);
- convertInt32ToDouble(regT0, fpRegT0);
-
- emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
-
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-
- fail1.link(this);
- }
-
- JITStubCall stubCall(this, cti_op_jless);
- stubCall.addArgument(op1, regT2);
- stubCall.addArgument(regT1);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target);
-
- } else {
- linkSlowCase(iter);
-
- if (supportsFloatingPoint()) {
- Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
- Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
- Jump fail3 = emitJumpIfImmediateInteger(regT1);
- addPtr(tagTypeNumberRegister, regT0);
- addPtr(tagTypeNumberRegister, regT1);
- movePtrToDouble(regT0, fpRegT0);
- movePtrToDouble(regT1, fpRegT1);
-
- emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
-
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-
- fail1.link(this);
- fail2.link(this);
- fail3.link(this);
- }
-
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_jless);
- stubCall.addArgument(regT0);
- stubCall.addArgument(regT1);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target);
- }
-}
-
-void JIT::emit_op_jless(Instruction* currentInstruction)
-{
- unsigned op1 = currentInstruction[1].u.operand;
- unsigned op2 = currentInstruction[2].u.operand;
- unsigned target = currentInstruction[3].u.operand;
-
- // We generate inline code for the following cases in the fast path:
- // - int immediate to constant int immediate
- // - constant int immediate to int immediate
- // - int immediate to int immediate
-
- if (isOperandConstantImmediateChar(op1)) {
- emitGetVirtualRegister(op2, regT0);
- addSlowCase(emitJumpIfNotJSCell(regT0));
- JumpList failures;
- emitLoadCharacterString(regT0, regT0, failures);
- addSlowCase(failures);
- addJump(branch32(GreaterThan, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
- return;
- }
- if (isOperandConstantImmediateChar(op2)) {
- emitGetVirtualRegister(op1, regT0);
- addSlowCase(emitJumpIfNotJSCell(regT0));
- JumpList failures;
- emitLoadCharacterString(regT0, regT0, failures);
- addSlowCase(failures);
- addJump(branch32(LessThan, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
- return;
- }
- if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- int32_t op2imm = getConstantOperandImmediateInt(op2);
- addJump(branch32(LessThan, regT0, Imm32(op2imm)), target);
- } else if (isOperandConstantImmediateInt(op1)) {
- emitGetVirtualRegister(op2, regT1);
- emitJumpSlowCaseIfNotImmediateInteger(regT1);
- int32_t op1imm = getConstantOperandImmediateInt(op1);
- addJump(branch32(GreaterThan, regT1, Imm32(op1imm)), target);
- } else {
- emitGetVirtualRegisters(op1, regT0, op2, regT1);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT1);
-
- addJump(branch32(LessThan, regT0, regT1), target);
- }
-}
-
-void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned op1 = currentInstruction[1].u.operand;
- unsigned op2 = currentInstruction[2].u.operand;
- unsigned target = currentInstruction[3].u.operand;
-
- // We generate inline code for the following cases in the slow path:
- // - floating-point number to constant int immediate
- // - constant int immediate to floating-point number
- // - floating-point number to floating-point number.
- if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_jless);
- stubCall.addArgument(op1, regT0);
- stubCall.addArgument(op2, regT1);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
- return;
- }
-
- if (isOperandConstantImmediateInt(op2)) {
- linkSlowCase(iter);
-
- if (supportsFloatingPoint()) {
- Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
- addPtr(tagTypeNumberRegister, regT0);
- movePtrToDouble(regT0, fpRegT0);
-
- int32_t op2imm = getConstantOperand(op2).asInt32();
-
- move(Imm32(op2imm), regT1);
- convertInt32ToDouble(regT1, fpRegT1);
-
- emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
-
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-
- fail1.link(this);
- }
-
- JITStubCall stubCall(this, cti_op_jless);
- stubCall.addArgument(regT0);
- stubCall.addArgument(op2, regT2);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
-
- } else if (isOperandConstantImmediateInt(op1)) {
- linkSlowCase(iter);
-
- if (supportsFloatingPoint()) {
- Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
- addPtr(tagTypeNumberRegister, regT1);
- movePtrToDouble(regT1, fpRegT1);
-
- int32_t op1imm = getConstantOperand(op1).asInt32();
-
- move(Imm32(op1imm), regT0);
- convertInt32ToDouble(regT0, fpRegT0);
-
- emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
-
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-
- fail1.link(this);
- }
-
- JITStubCall stubCall(this, cti_op_jless);
- stubCall.addArgument(op1, regT2);
- stubCall.addArgument(regT1);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
-
- } else {
- linkSlowCase(iter);
-
- if (supportsFloatingPoint()) {
- Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
- Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
- Jump fail3 = emitJumpIfImmediateInteger(regT1);
- addPtr(tagTypeNumberRegister, regT0);
- addPtr(tagTypeNumberRegister, regT1);
- movePtrToDouble(regT0, fpRegT0);
- movePtrToDouble(regT1, fpRegT1);
-
- emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
-
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-
- fail1.link(this);
- fail2.link(this);
- fail3.link(this);
- }
-
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_jless);
- stubCall.addArgument(regT0);
- stubCall.addArgument(regT1);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
- }
-}
-
-void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)