Skip to content

Commit 17ae6ed

Browse files
committed
LibJS+LibJIT: Add fast path for Int32 - Int32
1 parent 56b4586 commit 17ae6ed

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

Userland/Libraries/LibJIT/Assembler.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,31 @@ struct Assembler {
664664
}
665665
}
666666

667+
void sub32(Operand dst, Operand src, Optional<Label&> overflow_label)
668+
{
669+
if (dst.is_register_or_memory() && src.type == Operand::Type::Reg) {
670+
emit_rex_for_mr(dst, src, REX_W::No);
671+
emit8(0x29);
672+
emit_modrm_mr(dst, src);
673+
} else if (dst.is_register_or_memory() && src.type == Operand::Type::Imm && src.fits_in_i8()) {
674+
emit_rex_for_slash(dst, REX_W::No);
675+
emit8(0x83);
676+
emit_modrm_slash(5, dst);
677+
emit8(src.offset_or_immediate);
678+
} else if (dst.is_register_or_memory() && src.type == Operand::Type::Imm && src.fits_in_i32()) {
679+
emit_rex_for_slash(dst, REX_W::No);
680+
emit8(0x81);
681+
emit_modrm_slash(5, dst);
682+
emit32(src.offset_or_immediate);
683+
} else {
684+
VERIFY_NOT_REACHED();
685+
}
686+
687+
if (overflow_label.has_value()) {
688+
jump_if(Condition::Overflow, *overflow_label);
689+
}
690+
}
691+
667692
// NOTE: It's up to the caller of this function to preserve registers as needed.
668693
void native_call(void* callee, Vector<Operand> const& stack_arguments = {})
669694
{

Userland/Libraries/LibJS/JIT/Compiler.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,48 @@ void Compiler::compile_add(Bytecode::Op::Add const& op)
536536
end.link(m_assembler);
537537
}
538538

539+
static Value cxx_sub(VM& vm, Value lhs, Value rhs)
540+
{
541+
return TRY_OR_SET_EXCEPTION(sub(vm, lhs, rhs));
542+
}
543+
544+
void Compiler::compile_sub(Bytecode::Op::Sub const& op)
545+
{
546+
load_vm_register(ARG1, op.lhs());
547+
load_accumulator(ARG2);
548+
549+
Assembler::Label end {};
550+
Assembler::Label slow_case {};
551+
552+
branch_if_both_int32(ARG1, ARG2, [&] {
553+
// GPR0 = ARG1 + ARG2 (32-bit)
554+
// if (overflow) goto slow_case;
555+
m_assembler.mov(
556+
Assembler::Operand::Register(GPR0),
557+
Assembler::Operand::Register(ARG1));
558+
m_assembler.sub32(
559+
Assembler::Operand::Register(GPR0),
560+
Assembler::Operand::Register(ARG2),
561+
slow_case);
562+
563+
// accumulator = GPR0 | SHIFTED_INT32_TAG;
564+
m_assembler.mov(
565+
Assembler::Operand::Register(GPR1),
566+
Assembler::Operand::Imm(SHIFTED_INT32_TAG));
567+
m_assembler.bitwise_or(
568+
Assembler::Operand::Register(GPR0),
569+
Assembler::Operand::Register(GPR1));
570+
store_accumulator(GPR0);
571+
m_assembler.jump(end);
572+
});
573+
574+
slow_case.link(m_assembler);
575+
native_call((void*)cxx_sub);
576+
store_accumulator(RET);
577+
check_exception();
578+
end.link(m_assembler);
579+
}
580+
539581
static Value cxx_less_than(VM& vm, Value lhs, Value rhs)
540582
{
541583
return TRY_OR_SET_EXCEPTION(less_than(vm, lhs, rhs));

Userland/Libraries/LibJS/JIT/Compiler.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class Compiler {
4141
# endif
4242

4343
# define JS_ENUMERATE_COMMON_BINARY_OPS_WITHOUT_FAST_PATH(O) \
44-
O(Sub, sub) \
4544
O(Mul, mul) \
4645
O(Div, div) \
4746
O(Exp, exp) \

0 commit comments

Comments
 (0)