Przeglądaj źródła

LibJS/JIT: Use the x86_64 setcc instruction to remove a branch

Bastiaan van der Plaat 1 rok temu
rodzic
commit
d3b3e49e19

+ 8 - 0
Userland/Libraries/LibJIT/X86_64/Assembler.h

@@ -569,6 +569,14 @@ struct X86_64Assembler {
         jump_if(condition, label);
         jump_if(condition, label);
     }
     }
 
 
+    void set_if(Condition condition, Operand dst)
+    {
+        emit_rex_for_slash(dst, REX_W::No);
+        emit8(0x0f);
+        emit8(0x90 | to_underlying(condition));
+        emit_modrm_slash(0, dst);
+    }
+
     void sign_extend_32_to_64_bits(Reg reg)
     void sign_extend_32_to_64_bits(Reg reg)
     {
     {
         mov32(Operand::Register(reg), Operand::Register(reg), Extension::SignExtend);
         mov32(Operand::Register(reg), Operand::Register(reg), Extension::SignExtend);

+ 8 - 16
Userland/Libraries/LibJS/JIT/Compiler.cpp

@@ -1098,27 +1098,19 @@ void Compiler::compile_mul(Bytecode::Op::Mul const& op)
             Assembler::Label end {};                                                     \
             Assembler::Label end {};                                                     \
                                                                                          \
                                                                                          \
             branch_if_both_int32(ARG1, ARG2, [&] {                                       \
             branch_if_both_int32(ARG1, ARG2, [&] {                                       \
-                Assembler::Label true_case {};                                           \
-                                                                                         \
                 m_assembler.sign_extend_32_to_64_bits(ARG1);                             \
                 m_assembler.sign_extend_32_to_64_bits(ARG1);                             \
                 m_assembler.sign_extend_32_to_64_bits(ARG2);                             \
                 m_assembler.sign_extend_32_to_64_bits(ARG2);                             \
                                                                                          \
                                                                                          \
-                m_assembler.jump_if(                                                     \
-                    Assembler::Operand::Register(ARG1),                                  \
-                    Assembler::Condition::AssemblerCondition,                            \
-                    Assembler::Operand::Register(ARG2),                                  \
-                    true_case);                                                          \
-                                                                                         \
+                /* accumulator = SHIFTED_BOOLEAN_TAG | (arg1 condition arg2) */          \
                 m_assembler.mov(                                                         \
                 m_assembler.mov(                                                         \
                     Assembler::Operand::Register(GPR0),                                  \
                     Assembler::Operand::Register(GPR0),                                  \
-                    Assembler::Operand::Imm(Value(false).encoded()));                    \
-                store_accumulator(GPR0);                                                 \
-                m_assembler.jump(end);                                                   \
-                                                                                         \
-                true_case.link(m_assembler);                                             \
-                m_assembler.mov(                                                         \
-                    Assembler::Operand::Register(GPR0),                                  \
-                    Assembler::Operand::Imm(Value(true).encoded()));                     \
+                    Assembler::Operand::Imm(SHIFTED_BOOLEAN_TAG));                       \
+                m_assembler.cmp(                                                         \
+                    Assembler::Operand::Register(ARG1),                                  \
+                    Assembler::Operand::Register(ARG2));                                 \
+                m_assembler.set_if(                                                      \
+                    Assembler::Condition::AssemblerCondition,                            \
+                    Assembler::Operand::Register(GPR0)); /* sets only first byte */      \
                 store_accumulator(GPR0);                                                 \
                 store_accumulator(GPR0);                                                 \
                                                                                          \
                                                                                          \
                 m_assembler.jump(end);                                                   \
                 m_assembler.jump(end);                                                   \

+ 1 - 0
Userland/Libraries/LibJS/Runtime/Value.h

@@ -104,6 +104,7 @@ static_assert((EMPTY_TAG & IS_NULLISH_EXTRACT_PATTERN) != IS_NULLISH_PATTERN);
 
 
 static constexpr u64 TAG_EXTRACTION = 0xFFFF000000000000;
 static constexpr u64 TAG_EXTRACTION = 0xFFFF000000000000;
 static constexpr u64 TAG_SHIFT = 48;
 static constexpr u64 TAG_SHIFT = 48;
+static constexpr u64 SHIFTED_BOOLEAN_TAG = BOOLEAN_TAG << TAG_SHIFT;
 static constexpr u64 SHIFTED_INT32_TAG = INT32_TAG << TAG_SHIFT;
 static constexpr u64 SHIFTED_INT32_TAG = INT32_TAG << TAG_SHIFT;
 static constexpr u64 SHIFTED_IS_CELL_PATTERN = IS_CELL_PATTERN << TAG_SHIFT;
 static constexpr u64 SHIFTED_IS_CELL_PATTERN = IS_CELL_PATTERN << TAG_SHIFT;