Affix

 view release on metacpan or  search on metacpan

infix/src/arch/x64/abi_x64_emitters.c  view on Meta::CPAN

 * @internal
 * @brief Emits `cmp r64, r64` to compare two registers.
 * @details Opcode format: REX.W + 39 /r
 */
INFIX_INTERNAL void emit_cmp_reg_reg(code_buffer * buf, x64_gpr reg1, x64_gpr reg2) {
    emit_rex_prefix(buf, 1, reg2 >= R8_REG, 0, reg1 >= R8_REG);
    emit_byte(buf, 0x39);
    emit_modrm(buf, 3, reg2 % 8, reg1 % 8);
}
/**
 * @internal
 * @brief Emits `test r64, r64` to test if a register is zero.
 * @details Opcode format: REX.W + 85 /r
 */
INFIX_INTERNAL void emit_test_reg_reg(code_buffer * buf, x64_gpr reg1, x64_gpr reg2) {
    emit_rex_prefix(buf, 1, reg2 >= R8_REG, 0, reg1 >= R8_REG);
    emit_byte(buf, 0x85);
    emit_modrm(buf, 3, reg2 % 8, reg1 % 8);
}
/**
 * @internal
 * @brief Emits `jnz rel8` for a short conditional jump if not zero.
 * @details Opcode format: 75 rel8
 */
INFIX_INTERNAL void emit_jnz_short(code_buffer * buf, int8_t offset) { EMIT_BYTES(buf, 0x75, (uint8_t)offset); }
/**
 * @internal
 * @brief Emits `je rel8` for a short conditional jump if equal.
 * @details Opcode format: 74 rel8
 */
INFIX_INTERNAL void emit_je_short(code_buffer * buf, int8_t offset) { EMIT_BYTES(buf, 0x74, (uint8_t)offset); }
/**
 * @internal
 * @brief Emits a `jmp r64` instruction.
 * @details This instruction performs an indirect jump to the address contained in the
 * specified 64-bit register. Opcode format: [REX.B] FF /4
 */
INFIX_INTERNAL void emit_jmp_reg(code_buffer * buf, x64_gpr reg) {
    uint8_t rex = 0;
    if (reg >= R8_REG)
        rex = 0x40 | REX_B;
    if (rex)
        emit_byte(buf, rex);
    emit_byte(buf, 0xFF);
    emit_modrm(buf, 3, 4, reg % 8);  // mod=11 (register), reg=/4 for JMP
}
/**
 * @internal
 * @brief Emits `ud2`, an undefined instruction that causes an invalid opcode exception.
 * @details Opcode format: 0F 0B
 */
INFIX_INTERNAL void emit_ud2(code_buffer * buf) { EMIT_BYTES(buf, 0x0F, 0x0B); }
/**
 * @internal
 * @brief Emits the two-byte `syscall` instruction.
 * @details Opcode: 0F 05
 */
INFIX_INTERNAL void emit_syscall(code_buffer * buf) { EMIT_BYTES(buf, 0x0F, 0x05); }
/**
 * @internal
 * @brief Emits the `leave` instruction to tear down a stack frame.
 * @details This is equivalent to `mov rsp, rbp` followed by `pop rbp`.
 *          Opcode: C9
 */
INFIX_INTERNAL void emit_leave(code_buffer * buf) { emit_byte(buf, 0xC9); }



( run in 0.583 second using v1.01-cache-2.11-cpan-df04353d9ac )