/* * IR - Lightweight JIT Compilation Framework * (x86/x86_64 CPU specific definitions) * Copyright (C) 2022 Zend by Perforce. * Authors: Dmitry Stogov */ #ifndef IR_X86_H #define IR_X86_H #if defined(IR_TARGET_X64) # define IR_GP_REGS(_) \ _(R0, rax, eax, ax, al, ah) \ _(R1, rcx, ecx, cx, cl, ch) \ _(R2, rdx, edx, dx, dl, dh) \ _(R3, rbx, ebx, bx, bl, bh) \ _(R4, rsp, esp, __, __, __) \ _(R5, rbp, ebp, bp, r5b, __) \ _(R6, rsi, esi, si, r6b, __) \ _(R7, rdi, edi, di, r7b, __) \ _(R8, r8, r8d, r8w, r8b, __) \ _(R9, r9, r9d, r9w, r9b, __) \ _(R10, r10, r10d, r10w, r10b, __) \ _(R11, r11, r11d, r11w, r11b, __) \ _(R12, r12, r12d, r12w, r12b, __) \ _(R13, r13, r13d, r13w, r13b, __) \ _(R14, r14, r14d, r14w, r14b, __) \ _(R15, r15, r15d, r15w, r15b, __) \ # define IR_FP_REGS(_) \ _(XMM0, xmm0) \ _(XMM1, xmm1) \ _(XMM2, xmm2) \ _(XMM3, xmm3) \ _(XMM4, xmm4) \ _(XMM5, xmm5) \ _(XMM6, xmm6) \ _(XMM7, xmm7) \ _(XMM8, xmm8) \ _(XMM9, xmm9) \ _(XMM10, xmm10) \ _(XMM11, xmm11) \ _(XMM12, xmm12) \ _(XMM13, xmm13) \ _(XMM14, xmm14) \ _(XMM15, xmm15) \ #elif defined(IR_TARGET_X86) # define IR_GP_REGS(_) \ _(R0, ___, eax, ax, al, ah) \ _(R1, ___, ecx, cx, cl, ch) \ _(R2, ___, edx, dx, dl, dh) \ _(R3, ___, ebx, bx, bl, bh) \ _(R4, ___, esp, __, __, __) \ _(R5, ___, ebp, bp, __, __) \ _(R6, ___, esi, si, __, __) \ _(R7, ___, edi, di, __, __) \ # define IR_FP_REGS(_) \ _(XMM0, xmm0) \ _(XMM1, xmm1) \ _(XMM2, xmm2) \ _(XMM3, xmm3) \ _(XMM4, xmm4) \ _(XMM5, xmm5) \ _(XMM6, xmm6) \ _(XMM7, xmm7) \ #else # error "Unsupported target architecture" #endif #define IR_GP_REG_ENUM(code, name64, name32, name16, name8, name8h) \ IR_REG_ ## code, #define IR_FP_REG_ENUM(code, name) \ IR_REG_ ## code, enum _ir_reg { _IR_REG_NONE = -1, IR_GP_REGS(IR_GP_REG_ENUM) IR_FP_REGS(IR_FP_REG_ENUM) IR_REG_NUM, }; #define IR_REG_GP_FIRST IR_REG_R0 #define IR_REG_FP_FIRST IR_REG_XMM0 #define IR_REG_GP_LAST (IR_REG_FP_FIRST - 1) #define IR_REG_FP_LAST (IR_REG_NUM - 1) #define IR_REG_SCRATCH (IR_REG_NUM) /* special name for regset */ #define IR_REG_ALL (IR_REG_NUM + 1) /* special name for regset */ #define IR_REGSET_64BIT 0 #define IR_REG_STACK_POINTER \ IR_REG_RSP #define IR_REG_FRAME_POINTER \ IR_REG_RBP #define IR_REGSET_FIXED \ (IR_REGSET(IR_REG_RSP)) #define IR_REGSET_GP \ IR_REGSET_DIFFERENCE(IR_REGSET_INTERVAL(IR_REG_GP_FIRST, IR_REG_GP_LAST), IR_REGSET_FIXED) #define IR_REGSET_FP \ IR_REGSET_DIFFERENCE(IR_REGSET_INTERVAL(IR_REG_FP_FIRST, IR_REG_FP_LAST), IR_REGSET_FIXED) #define IR_REG_RAX IR_REG_R0 #define IR_REG_RCX IR_REG_R1 #define IR_REG_RDX IR_REG_R2 #define IR_REG_RBX IR_REG_R3 #define IR_REG_RSP IR_REG_R4 #define IR_REG_RBP IR_REG_R5 #define IR_REG_RSI IR_REG_R6 #define IR_REG_RDI IR_REG_R7 /* Calling Convention */ #ifdef _WIN64 # define IR_REG_INT_RET1 IR_REG_RAX # define IR_REG_FP_RET1 IR_REG_XMM0 # define IR_REG_INT_ARGS 4 # define IR_REG_FP_ARGS 4 # define IR_REG_INT_ARG1 IR_REG_RCX # define IR_REG_INT_ARG2 IR_REG_RDX # define IR_REG_INT_ARG3 IR_REG_R8 # define IR_REG_INT_ARG4 IR_REG_R9 # define IR_REG_FP_ARG1 IR_REG_XMM0 # define IR_REG_FP_ARG2 IR_REG_XMM1 # define IR_REG_FP_ARG3 IR_REG_XMM2 # define IR_REG_FP_ARG4 IR_REG_XMM3 # define IR_MAX_REG_ARGS 4 # define IR_SHADOW_ARGS 32 /* Reserved space in bytes - "home space" or "shadow store" for register arguments */ # define IR_REGSET_SCRATCH \ (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) \ | IR_REGSET_INTERVAL(IR_REG_R8, IR_REG_R11) \ | IR_REGSET_INTERVAL(IR_REG_XMM0, IR_REG_XMM5)) # define IR_REGSET_PRESERVED \ (IR_REGSET(IR_REG_RBX) \ | IR_REGSET_INTERVAL(IR_REG_RBP, IR_REG_RDI) \ | IR_REGSET_INTERVAL(IR_REG_R12, IR_REG_R15) \ | IR_REGSET_INTERVAL(IR_REG_XMM6, IR_REG_XMM15)) #elif defined(IR_TARGET_X64) # define IR_REG_INT_RET1 IR_REG_RAX # define IR_REG_FP_RET1 IR_REG_XMM0 # define IR_REG_INT_ARGS 6 # define IR_REG_FP_ARGS 8 # define IR_REG_INT_ARG1 IR_REG_RDI # define IR_REG_INT_ARG2 IR_REG_RSI # define IR_REG_INT_ARG3 IR_REG_RDX # define IR_REG_INT_ARG4 IR_REG_RCX # define IR_REG_INT_ARG5 IR_REG_R8 # define IR_REG_INT_ARG6 IR_REG_R9 # define IR_REG_FP_ARG1 IR_REG_XMM0 # define IR_REG_FP_ARG2 IR_REG_XMM1 # define IR_REG_FP_ARG3 IR_REG_XMM2 # define IR_REG_FP_ARG4 IR_REG_XMM3 # define IR_REG_FP_ARG5 IR_REG_XMM4 # define IR_REG_FP_ARG6 IR_REG_XMM5 # define IR_REG_FP_ARG7 IR_REG_XMM6 # define IR_REG_FP_ARG8 IR_REG_XMM7 # define IR_MAX_REG_ARGS 14 # define IR_SHADOW_ARGS 0 # define IR_REG_VARARG_FP_REGS IR_REG_RAX /* hidden argument to specify the number of vector registers used */ # define IR_REGSET_SCRATCH \ (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) \ | IR_REGSET_INTERVAL(IR_REG_RSI, IR_REG_RDI) \ | IR_REGSET_INTERVAL(IR_REG_R8, IR_REG_R11) \ | IR_REGSET_FP) # define IR_REGSET_PRESERVED \ (IR_REGSET(IR_REG_RBX) \ | IR_REGSET(IR_REG_RBP) \ | IR_REGSET_INTERVAL(IR_REG_R12, IR_REG_R15)) typedef struct _ir_va_list { uint32_t gp_offset; uint32_t fp_offset; void *overflow_arg_area; void *reg_save_area; } ir_va_list; #elif defined(IR_TARGET_X86) # define IR_REG_INT_RET1 IR_REG_RAX # define IR_REG_INT_RET2 IR_REG_RDX # define IR_REG_INT_ARGS 0 # define IR_REG_FP_ARGS 0 # define IR_HAVE_FASTCALL 1 # define IR_REG_INT_FCARGS 2 # define IR_REG_FP_FCARGS 0 # define IR_REG_INT_FCARG1 IR_REG_RCX # define IR_REG_INT_FCARG2 IR_REG_RDX # define IR_MAX_REG_ARGS 2 # define IR_SHADOW_ARGS 0 # define IR_REGSET_SCRATCH \ (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) | IR_REGSET_FP) # define IR_REGSET_PRESERVED \ (IR_REGSET(IR_REG_RBX) \ | IR_REGSET(IR_REG_RBP) \ | IR_REGSET_INTERVAL(IR_REG_RSI, IR_REG_RDI)) #else # error "Unsupported target architecture" #endif typedef struct _ir_tmp_reg { union { uint8_t num; int8_t reg; }; uint8_t type; uint8_t start; uint8_t end; } ir_tmp_reg; struct _ir_target_constraints { int8_t def_reg; uint8_t tmps_count; uint8_t hints_count; ir_tmp_reg tmp_regs[3]; int8_t hints[IR_MAX_REG_ARGS + 3]; }; #endif /* IR_X86_H */