mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			384 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			384 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#ifndef YJIT_ASM_H
 | 
						|
#define YJIT_ASM_H 1
 | 
						|
 | 
						|
#include <stdint.h>
 | 
						|
#include <stddef.h>
 | 
						|
#include <stdbool.h>
 | 
						|
 | 
						|
// Maximum number of labels to link
 | 
						|
#define MAX_LABELS 32
 | 
						|
 | 
						|
// Maximum number of label references
 | 
						|
#define MAX_LABEL_REFS 32
 | 
						|
 | 
						|
// Reference to an ASM label
 | 
						|
typedef struct LabelRef
 | 
						|
{
 | 
						|
    // Position in the code block where the label reference exists
 | 
						|
    uint32_t pos;
 | 
						|
 | 
						|
    // Label which this refers to
 | 
						|
    uint32_t label_idx;
 | 
						|
 | 
						|
} labelref_t;
 | 
						|
 | 
						|
// Block of executable memory into which instructions can be written
 | 
						|
typedef struct CodeBlock
 | 
						|
{
 | 
						|
    // Memory block
 | 
						|
    uint8_t* mem_block;
 | 
						|
 | 
						|
    // Memory block size
 | 
						|
    uint32_t mem_size;
 | 
						|
 | 
						|
    /// Current writing position
 | 
						|
    uint32_t write_pos;
 | 
						|
 | 
						|
    // Table of registered label addresses
 | 
						|
    uint32_t label_addrs[MAX_LABELS];
 | 
						|
 | 
						|
    // Table of registered label names
 | 
						|
    // Note that these should be constant strings only
 | 
						|
    const char* label_names[MAX_LABELS];
 | 
						|
 | 
						|
    // References to labels
 | 
						|
    labelref_t label_refs[MAX_LABEL_REFS];
 | 
						|
 | 
						|
    // Number of labels registeered
 | 
						|
    uint32_t num_labels;
 | 
						|
 | 
						|
    // Number of references to labels
 | 
						|
    uint32_t num_refs;
 | 
						|
 | 
						|
    // TODO: system for disassembly/comment strings, indexed by position
 | 
						|
 | 
						|
    // Flag to enable or disable comments
 | 
						|
    bool has_asm;
 | 
						|
 | 
						|
} codeblock_t;
 | 
						|
 | 
						|
enum OpndType
 | 
						|
{
 | 
						|
    OPND_NONE,
 | 
						|
    OPND_REG,
 | 
						|
    OPND_IMM,
 | 
						|
    OPND_MEM
 | 
						|
};
 | 
						|
 | 
						|
enum RegType
 | 
						|
{
 | 
						|
    REG_GP,
 | 
						|
    REG_FP,
 | 
						|
    REG_XMM,
 | 
						|
    REG_IP
 | 
						|
};
 | 
						|
 | 
						|
typedef struct X86Reg
 | 
						|
{
 | 
						|
    // Register type
 | 
						|
    uint8_t reg_type;
 | 
						|
 | 
						|
    // Register index number
 | 
						|
    uint8_t reg_no;
 | 
						|
 | 
						|
} x86reg_t;
 | 
						|
 | 
						|
typedef struct X86Mem
 | 
						|
{
 | 
						|
    /// Base register number
 | 
						|
    uint8_t base_reg_no;
 | 
						|
 | 
						|
    /// Index register number
 | 
						|
    uint8_t idx_reg_no;
 | 
						|
 | 
						|
    /// SIB scale exponent value (power of two, two bits)
 | 
						|
    uint8_t scale_exp;
 | 
						|
 | 
						|
    /// Has index register flag
 | 
						|
    bool has_idx;
 | 
						|
 | 
						|
    // TODO: should this be here, or should we have an extra operand type?
 | 
						|
    /// IP-relative addressing flag
 | 
						|
    bool is_iprel;
 | 
						|
 | 
						|
    /// Constant displacement from the base, not scaled
 | 
						|
    int32_t disp;
 | 
						|
 | 
						|
} x86mem_t;
 | 
						|
 | 
						|
typedef struct X86Opnd
 | 
						|
{
 | 
						|
    // Operand type
 | 
						|
    uint8_t type;
 | 
						|
 | 
						|
    // Size in bits
 | 
						|
    uint16_t num_bits;
 | 
						|
 | 
						|
    union
 | 
						|
    {
 | 
						|
        // Register operand
 | 
						|
        x86reg_t reg;
 | 
						|
 | 
						|
        // Memory operand
 | 
						|
        x86mem_t mem;
 | 
						|
 | 
						|
        // Signed immediate value
 | 
						|
        int64_t imm;
 | 
						|
 | 
						|
        // Unsigned immediate value
 | 
						|
        uint64_t unsig_imm;
 | 
						|
    } as;
 | 
						|
 | 
						|
} x86opnd_t;
 | 
						|
 | 
						|
// Dummy none/null operand
 | 
						|
static const x86opnd_t NO_OPND = { OPND_NONE, 0, .as.imm = 0 };
 | 
						|
 | 
						|
// Instruction pointer
 | 
						|
static const x86opnd_t RIP = { OPND_REG, 64, .as.reg = { REG_IP, 5 }};
 | 
						|
 | 
						|
// 64-bit GP registers
 | 
						|
static const x86opnd_t RAX = { OPND_REG, 64, .as.reg = { REG_GP, 0 }};
 | 
						|
static const x86opnd_t RCX = { OPND_REG, 64, .as.reg = { REG_GP, 1 }};
 | 
						|
static const x86opnd_t RDX = { OPND_REG, 64, .as.reg = { REG_GP, 2 }};
 | 
						|
static const x86opnd_t RBX = { OPND_REG, 64, .as.reg = { REG_GP, 3 }};
 | 
						|
static const x86opnd_t RSP = { OPND_REG, 64, .as.reg = { REG_GP, 4 }};
 | 
						|
static const x86opnd_t RBP = { OPND_REG, 64, .as.reg = { REG_GP, 5 }};
 | 
						|
static const x86opnd_t RSI = { OPND_REG, 64, .as.reg = { REG_GP, 6 }};
 | 
						|
static const x86opnd_t RDI = { OPND_REG, 64, .as.reg = { REG_GP, 7 }};
 | 
						|
static const x86opnd_t R8  = { OPND_REG, 64, .as.reg = { REG_GP, 8 }};
 | 
						|
static const x86opnd_t R9  = { OPND_REG, 64, .as.reg = { REG_GP, 9 }};
 | 
						|
static const x86opnd_t R10 = { OPND_REG, 64, .as.reg = { REG_GP, 10 }};
 | 
						|
static const x86opnd_t R11 = { OPND_REG, 64, .as.reg = { REG_GP, 11 }};
 | 
						|
static const x86opnd_t R12 = { OPND_REG, 64, .as.reg = { REG_GP, 12 }};
 | 
						|
static const x86opnd_t R13 = { OPND_REG, 64, .as.reg = { REG_GP, 13 }};
 | 
						|
static const x86opnd_t R14 = { OPND_REG, 64, .as.reg = { REG_GP, 14 }};
 | 
						|
static const x86opnd_t R15 = { OPND_REG, 64, .as.reg = { REG_GP, 15 }};
 | 
						|
 | 
						|
// 32-bit GP registers
 | 
						|
static const x86opnd_t EAX  = { OPND_REG, 32, .as.reg = { REG_GP, 0 }};
 | 
						|
static const x86opnd_t ECX  = { OPND_REG, 32, .as.reg = { REG_GP, 1 }};
 | 
						|
static const x86opnd_t EDX  = { OPND_REG, 32, .as.reg = { REG_GP, 2 }};
 | 
						|
static const x86opnd_t EBX  = { OPND_REG, 32, .as.reg = { REG_GP, 3 }};
 | 
						|
static const x86opnd_t ESP  = { OPND_REG, 32, .as.reg = { REG_GP, 4 }};
 | 
						|
static const x86opnd_t EBP  = { OPND_REG, 32, .as.reg = { REG_GP, 5 }};
 | 
						|
static const x86opnd_t ESI  = { OPND_REG, 32, .as.reg = { REG_GP, 6 }};
 | 
						|
static const x86opnd_t EDI  = { OPND_REG, 32, .as.reg = { REG_GP, 7 }};
 | 
						|
static const x86opnd_t R8D  = { OPND_REG, 32, .as.reg = { REG_GP, 8 }};
 | 
						|
static const x86opnd_t R9D  = { OPND_REG, 32, .as.reg = { REG_GP, 9 }};
 | 
						|
static const x86opnd_t R10D = { OPND_REG, 32, .as.reg = { REG_GP, 10 }};
 | 
						|
static const x86opnd_t R11D = { OPND_REG, 32, .as.reg = { REG_GP, 11 }};
 | 
						|
static const x86opnd_t R12D = { OPND_REG, 32, .as.reg = { REG_GP, 12 }};
 | 
						|
static const x86opnd_t R13D = { OPND_REG, 32, .as.reg = { REG_GP, 13 }};
 | 
						|
static const x86opnd_t R14D = { OPND_REG, 32, .as.reg = { REG_GP, 14 }};
 | 
						|
static const x86opnd_t R15D = { OPND_REG, 32, .as.reg = { REG_GP, 15 }};
 | 
						|
 | 
						|
// 16-bit GP registers
 | 
						|
static const x86opnd_t AX   = { OPND_REG, 16, .as.reg = { REG_GP, 0 }};
 | 
						|
static const x86opnd_t CX   = { OPND_REG, 16, .as.reg = { REG_GP, 1 }};
 | 
						|
static const x86opnd_t DX   = { OPND_REG, 16, .as.reg = { REG_GP, 2 }};
 | 
						|
static const x86opnd_t BX   = { OPND_REG, 16, .as.reg = { REG_GP, 3 }};
 | 
						|
static const x86opnd_t SP   = { OPND_REG, 16, .as.reg = { REG_GP, 4 }};
 | 
						|
static const x86opnd_t BP   = { OPND_REG, 16, .as.reg = { REG_GP, 5 }};
 | 
						|
static const x86opnd_t SI   = { OPND_REG, 16, .as.reg = { REG_GP, 6 }};
 | 
						|
static const x86opnd_t DI   = { OPND_REG, 16, .as.reg = { REG_GP, 7 }};
 | 
						|
static const x86opnd_t R8W  = { OPND_REG, 16, .as.reg = { REG_GP, 8 }};
 | 
						|
static const x86opnd_t R9W  = { OPND_REG, 16, .as.reg = { REG_GP, 9 }};
 | 
						|
static const x86opnd_t R10W = { OPND_REG, 16, .as.reg = { REG_GP, 10 }};
 | 
						|
static const x86opnd_t R11W = { OPND_REG, 16, .as.reg = { REG_GP, 11 }};
 | 
						|
static const x86opnd_t R12W = { OPND_REG, 16, .as.reg = { REG_GP, 12 }};
 | 
						|
static const x86opnd_t R13W = { OPND_REG, 16, .as.reg = { REG_GP, 13 }};
 | 
						|
static const x86opnd_t R14W = { OPND_REG, 16, .as.reg = { REG_GP, 14 }};
 | 
						|
static const x86opnd_t R15W = { OPND_REG, 16, .as.reg = { REG_GP, 15 }};
 | 
						|
 | 
						|
// 8-bit GP registers
 | 
						|
static const x86opnd_t AL   = { OPND_REG, 8, .as.reg = { REG_GP, 0 }};
 | 
						|
static const x86opnd_t CL   = { OPND_REG, 8, .as.reg = { REG_GP, 1 }};
 | 
						|
static const x86opnd_t DL   = { OPND_REG, 8, .as.reg = { REG_GP, 2 }};
 | 
						|
static const x86opnd_t BL   = { OPND_REG, 8, .as.reg = { REG_GP, 3 }};
 | 
						|
static const x86opnd_t SPL  = { OPND_REG, 8, .as.reg = { REG_GP, 4 }};
 | 
						|
static const x86opnd_t BPL  = { OPND_REG, 8, .as.reg = { REG_GP, 5 }};
 | 
						|
static const x86opnd_t SIL  = { OPND_REG, 8, .as.reg = { REG_GP, 6 }};
 | 
						|
static const x86opnd_t DIL  = { OPND_REG, 8, .as.reg = { REG_GP, 7 }};
 | 
						|
static const x86opnd_t R8B  = { OPND_REG, 8, .as.reg = { REG_GP, 8 }};
 | 
						|
static const x86opnd_t R9B  = { OPND_REG, 8, .as.reg = { REG_GP, 9 }};
 | 
						|
static const x86opnd_t R10B = { OPND_REG, 8, .as.reg = { REG_GP, 10 }};
 | 
						|
static const x86opnd_t R11B = { OPND_REG, 8, .as.reg = { REG_GP, 11 }};
 | 
						|
static const x86opnd_t R12B = { OPND_REG, 8, .as.reg = { REG_GP, 12 }};
 | 
						|
static const x86opnd_t R13B = { OPND_REG, 8, .as.reg = { REG_GP, 13 }};
 | 
						|
static const x86opnd_t R14B = { OPND_REG, 8, .as.reg = { REG_GP, 14 }};
 | 
						|
static const x86opnd_t R15B = { OPND_REG, 8, .as.reg = { REG_GP, 15 }};
 | 
						|
 | 
						|
// C argument registers
 | 
						|
#define NUM_C_ARG_REGS 6
 | 
						|
#define C_ARG_REGS ( (x86opnd_t[]){ RDI, RSI, RDX, RCX, R8, R9 } )
 | 
						|
 | 
						|
// Memory operand with base register and displacement/offset
 | 
						|
x86opnd_t mem_opnd(uint32_t num_bits, x86opnd_t base_reg, int32_t disp);
 | 
						|
 | 
						|
// Scale-index-base memory operand
 | 
						|
x86opnd_t mem_opnd_sib(uint32_t num_bits, x86opnd_t base_reg, x86opnd_t index_reg, int32_t scale, int32_t disp);
 | 
						|
 | 
						|
// Immediate number operand
 | 
						|
x86opnd_t imm_opnd(int64_t val);
 | 
						|
 | 
						|
// Constant pointer operand
 | 
						|
x86opnd_t const_ptr_opnd(const void *ptr);
 | 
						|
 | 
						|
// Struct member operand
 | 
						|
#define member_opnd(base_reg, struct_type, member_name) mem_opnd( \
 | 
						|
    8 * sizeof(((struct_type*)0)->member_name), \
 | 
						|
    base_reg,                                   \
 | 
						|
    offsetof(struct_type, member_name)          \
 | 
						|
)
 | 
						|
 | 
						|
// Struct member operand with an array index
 | 
						|
#define member_opnd_idx(base_reg, struct_type, member_name, idx) mem_opnd( \
 | 
						|
    8 * sizeof(((struct_type*)0)->member_name[0]),     \
 | 
						|
    base_reg,                                       \
 | 
						|
    (offsetof(struct_type, member_name) +           \
 | 
						|
     sizeof(((struct_type*)0)->member_name[0]) * idx)  \
 | 
						|
)
 | 
						|
 | 
						|
// Code block methods
 | 
						|
uint8_t* alloc_exec_mem(uint32_t mem_size);
 | 
						|
void cb_init(codeblock_t* cb, uint8_t* mem_block, uint32_t mem_size);
 | 
						|
void cb_align_pos(codeblock_t* cb, uint32_t multiple);
 | 
						|
void cb_set_pos(codeblock_t* cb, uint32_t pos);
 | 
						|
uint8_t* cb_get_ptr(codeblock_t* cb, uint32_t index);
 | 
						|
void cb_write_byte(codeblock_t* cb, uint8_t byte);
 | 
						|
void cb_write_bytes(codeblock_t* cb, uint32_t num_bytes, ...);
 | 
						|
void cb_write_int(codeblock_t* cb, uint64_t val, uint32_t num_bits);
 | 
						|
uint32_t cb_new_label(codeblock_t* cb, const char* name);
 | 
						|
void cb_write_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void cb_label_ref(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void cb_link_labels(codeblock_t* cb);
 | 
						|
 | 
						|
// Encode individual instructions into a code block
 | 
						|
void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
void and(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
void call_ptr(codeblock_t* cb, x86opnd_t scratch_reg, uint8_t* dst_ptr);
 | 
						|
void call_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void call(codeblock_t* cb, x86opnd_t opnd);
 | 
						|
void cmova(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovae(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovb(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovbe(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovc(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmove(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovg(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovge(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovl(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovle(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovna(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovnae(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovnb(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovnbe(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovnc(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovne(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovng(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovnge(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovnl(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovnle(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovno(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovnp(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovns(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovnz(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovo(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovp(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovpe(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovpo(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovs(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmovz(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void cmp(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
void cdq(codeblock_t* cb);
 | 
						|
void cqo(codeblock_t* cb);
 | 
						|
void int3(codeblock_t* cb);
 | 
						|
void ja_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jae_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jb_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jbe_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jc_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void je_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jg_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jge_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jl_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jle_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jna_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jnae_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jnb_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jnbe_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jnc_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jne_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jng_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jnge_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jnl_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jnle_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jno_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jnp_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jns_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jnz_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jo_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jp_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jpe_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jpo_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void js_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jz_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void ja_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jae_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jb_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jbe_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jc_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void je_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jg_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jge_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jl_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jle_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jna_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jnae_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jnb_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jnbe_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jnc_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jne_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jng_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jnge_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jnl_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jnle_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jno_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jnp_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jns_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jnz_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jo_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jp_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jpe_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jpo_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void js_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jz_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jmp_label(codeblock_t* cb, uint32_t label_idx);
 | 
						|
void jmp_ptr(codeblock_t* cb, uint8_t* ptr);
 | 
						|
void jmp_rm(codeblock_t* cb, x86opnd_t opnd);
 | 
						|
void jmp32(codeblock_t* cb, int32_t offset);
 | 
						|
void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void movsx(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
 | 
						|
void neg(codeblock_t* cb, x86opnd_t opnd);
 | 
						|
void nop(codeblock_t* cb, uint32_t length);
 | 
						|
void not(codeblock_t* cb, x86opnd_t opnd);
 | 
						|
void or(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
void pop(codeblock_t* cb, x86opnd_t reg);
 | 
						|
void popfq(codeblock_t* cb);
 | 
						|
void push(codeblock_t* cb, x86opnd_t opnd);
 | 
						|
void pushfq(codeblock_t* cb);
 | 
						|
void ret(codeblock_t* cb);
 | 
						|
void sal(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
void sar(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
void shl(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
void shr(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
void test(codeblock_t* cb, x86opnd_t rm_opnd, x86opnd_t test_opnd);
 | 
						|
void ud2(codeblock_t* cb);
 | 
						|
void xor(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 | 
						|
 | 
						|
void cb_write_lock_prefix(codeblock_t* cb);
 | 
						|
 | 
						|
#endif
 |