#ifndef AMAL_EXECUTOR_X86_64_ASM_H #define AMAL_EXECUTOR_X86_64_ASM_H #include "../../include/std/misc.h" #include "../../include/std/types.h" typedef struct { void *code; u8 *code_it; usize allocated_size; } Asm; typedef enum { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI } Reg32; typedef enum { RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI } Reg64; typedef struct { Reg64 base; Reg64 index; i32 disp; u8 scale; } AsmPtr; void asm_ptr_init(AsmPtr *self, Reg64 base); void asm_ptr_init_index(AsmPtr *self, Reg64 base, Reg64 index); void asm_ptr_init_disp(AsmPtr *self, Reg64 base, i32 disp); void asm_ptr_init_index_disp(AsmPtr *self, Reg64 base, Reg64 index, i32 disp); CHECK_RESULT int asm_init(Asm *self); void asm_deinit(Asm *self); usize asm_get_size(Asm *self); CHECK_RESULT int asm_execute(Asm *self); CHECK_RESULT int asm_nop(Asm *self); CHECK_RESULT int asm_mov_mi(Asm *self, AsmPtr *dst, i32 immediate); CHECK_RESULT int asm_mov_mr(Asm *self, AsmPtr *dst, Reg64 src); CHECK_RESULT int asm_mov_rm(Asm *self, Reg64 dst, AsmPtr *src); CHECK_RESULT int asm_mov_ri(Asm *self, Reg64 dst, i64 immediate); CHECK_RESULT int asm_mov_rr(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_add_rr(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_sub_rr(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_imul_rr(Asm *self, Reg64 dst, Reg64 src); /* Sign extend RAX into RDX, this is needed for some operations, such as idiv */ CHECK_RESULT int asm_cqo(Asm *self); /* Divide RDX:RAX by @src. Store the quotient in RAX and the remainder in RDX. @asm_cqo should be called before this, since RAX needs to be sign extended into RDX */ CHECK_RESULT int asm_idiv_rr(Asm *self, Reg64 src); CHECK_RESULT int asm_pushr(Asm *self, Reg64 reg); CHECK_RESULT int asm_popr(Asm *self, Reg64 reg); CHECK_RESULT int asm_callr(Asm *self, Reg64 reg); /* In x86 assembly, the @relative position starts from the next instruction. This offset shouldn't be calculated by the caller and is instead managed by this asm library itself. */ CHECK_RESULT int asm_call_rel32(Asm *self, i32 relative); void asm_override_call_rel32(Asm *self, u32 asm_index, i32 new_relative); CHECK_RESULT int asm_mov_rm32(Asm *self, Reg32 dst, Reg32 src); CHECK_RESULT int asm_add_rm32(Asm *self, Reg32 dst, Reg32 src); CHECK_RESULT int asm_sub_rm32(Asm *self, Reg32 dst, Reg32 src); CHECK_RESULT int asm_and_rm32(Asm *self, Reg32 dst, Reg32 src); CHECK_RESULT int asm_or_rm32(Asm *self, Reg32 dst, Reg32 src); CHECK_RESULT int asm_xor_rm32(Asm *self, Reg32 dst, Reg32 src); CHECK_RESULT int asm_cmp_rm32(Asm *self, Reg32 dst, Reg32 src); CHECK_RESULT int asm_add_rm32_imm(Asm *self, Reg32 reg, i32 immediate); CHECK_RESULT int asm_or_rm32_imm(Asm *self, Reg32 reg, i32 immediate); CHECK_RESULT int asm_adc_rm32_imm(Asm *self, Reg32 reg, i32 immediate); CHECK_RESULT int asm_sbb_rm32_imm(Asm *self, Reg32 reg, i32 immediate); CHECK_RESULT int asm_and_rm32_imm(Asm *self, Reg32 reg, i32 immediate); CHECK_RESULT int asm_sub_rm32_imm(Asm *self, Reg32 reg, i32 immediate); CHECK_RESULT int asm_xor_rm32_imm(Asm *self, Reg32 reg, i32 immediate); CHECK_RESULT int asm_cmp_rm32_imm(Asm *self, Reg32 reg, i32 immediate); CHECK_RESULT int asm_rol_rm32_imm(Asm *self, Reg32 reg, i8 immediate); CHECK_RESULT int asm_ror_rm32_imm(Asm *self, Reg32 reg, i8 immediate); CHECK_RESULT int asm_rcl_rm32_imm(Asm *self, Reg32 reg, i8 immediate); CHECK_RESULT int asm_rcr_rm32_imm(Asm *self, Reg32 reg, i8 immediate); CHECK_RESULT int asm_shl_rm32_imm(Asm *self, Reg32 reg, i8 immediate); CHECK_RESULT int asm_shr_rm32_imm(Asm *self, Reg32 reg, i8 immediate); CHECK_RESULT int asm_sar_rm32_imm(Asm *self, Reg32 reg, i8 immediate); CHECK_RESULT int asm_mov_rm64(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_add_rm64(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_sub_rm64(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_and_rm64(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_or_rm64(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_xor_rm64(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_cmp_rm64(Asm *self, Reg64 dst, Reg64 src); CHECK_RESULT int asm_add_rm64_imm(Asm *self, Reg64 reg, i32 immediate); CHECK_RESULT int asm_or_rm64_imm(Asm *self, Reg64 reg, i32 immediate); CHECK_RESULT int asm_adc_rm64_imm(Asm *self, Reg64 reg, i32 immediate); CHECK_RESULT int asm_sbb_rm64_imm(Asm *self, Reg64 reg, i32 immediate); CHECK_RESULT int asm_and_rm64_imm(Asm *self, Reg64 reg, i32 immediate); CHECK_RESULT int asm_sub_rm64_imm(Asm *self, Reg64 reg, i32 immediate); CHECK_RESULT int asm_xor_rm64_imm(Asm *self, Reg64 reg, i32 immediate); CHECK_RESULT int asm_cmp_rm64_imm(Asm *self, Reg64 reg, i32 immediate); CHECK_RESULT int asm_rol_rm64_imm(Asm *self, Reg64 reg, i8 immediate); CHECK_RESULT int asm_ror_rm64_imm(Asm *self, Reg64 reg, i8 immediate); CHECK_RESULT int asm_rcl_rm64_imm(Asm *self, Reg64 reg, i8 immediate); CHECK_RESULT int asm_rcr_rm64_imm(Asm *self, Reg64 reg, i8 immediate); CHECK_RESULT int asm_shl_rm64_imm(Asm *self, Reg64 reg, i8 immediate); CHECK_RESULT int asm_shr_rm64_imm(Asm *self, Reg64 reg, i8 immediate); CHECK_RESULT int asm_sar_rm64_imm(Asm *self, Reg64 reg, i8 immediate); CHECK_RESULT int asm_ret(Asm *self, u16 bytes); #endif