1 /* 2 * IR - Lightweight JIT Compilation Framework 3 * (x86/x86_64 CPU specific definitions) 4 * Copyright (C) 2022 Zend by Perforce. 5 * Authors: Dmitry Stogov <dmitry@php.net> 6 */ 7 8 #ifndef IR_X86_H 9 #define IR_X86_H 10 11 #if defined(IR_TARGET_X64) 12 # define IR_GP_REGS(_) \ 13 _(R0, rax, eax, ax, al, ah) \ 14 _(R1, rcx, ecx, cx, cl, ch) \ 15 _(R2, rdx, edx, dx, dl, dh) \ 16 _(R3, rbx, ebx, bx, bl, bh) \ 17 _(R4, rsp, esp, __, __, __) \ 18 _(R5, rbp, ebp, bp, r5b, __) \ 19 _(R6, rsi, esi, si, r6b, __) \ 20 _(R7, rdi, edi, di, r7b, __) \ 21 _(R8, r8, r8d, r8w, r8b, __) \ 22 _(R9, r9, r9d, r9w, r9b, __) \ 23 _(R10, r10, r10d, r10w, r10b, __) \ 24 _(R11, r11, r11d, r11w, r11b, __) \ 25 _(R12, r12, r12d, r12w, r12b, __) \ 26 _(R13, r13, r13d, r13w, r13b, __) \ 27 _(R14, r14, r14d, r14w, r14b, __) \ 28 _(R15, r15, r15d, r15w, r15b, __) \ 29 30 # define IR_FP_REGS(_) \ 31 _(XMM0, xmm0) \ 32 _(XMM1, xmm1) \ 33 _(XMM2, xmm2) \ 34 _(XMM3, xmm3) \ 35 _(XMM4, xmm4) \ 36 _(XMM5, xmm5) \ 37 _(XMM6, xmm6) \ 38 _(XMM7, xmm7) \ 39 _(XMM8, xmm8) \ 40 _(XMM9, xmm9) \ 41 _(XMM10, xmm10) \ 42 _(XMM11, xmm11) \ 43 _(XMM12, xmm12) \ 44 _(XMM13, xmm13) \ 45 _(XMM14, xmm14) \ 46 _(XMM15, xmm15) \ 47 48 #elif defined(IR_TARGET_X86) 49 50 # define IR_GP_REGS(_) \ 51 _(R0, ___, eax, ax, al, ah) \ 52 _(R1, ___, ecx, cx, cl, ch) \ 53 _(R2, ___, edx, dx, dl, dh) \ 54 _(R3, ___, ebx, bx, bl, bh) \ 55 _(R4, ___, esp, __, __, __) \ 56 _(R5, ___, ebp, bp, __, __) \ 57 _(R6, ___, esi, si, __, __) \ 58 _(R7, ___, edi, di, __, __) \ 59 60 # define IR_FP_REGS(_) \ 61 _(XMM0, xmm0) \ 62 _(XMM1, xmm1) \ 63 _(XMM2, xmm2) \ 64 _(XMM3, xmm3) \ 65 _(XMM4, xmm4) \ 66 _(XMM5, xmm5) \ 67 _(XMM6, xmm6) \ 68 _(XMM7, xmm7) \ 69 70 #else 71 # error "Unsupported target architecture" 72 #endif 73 74 #define IR_GP_REG_ENUM(code, name64, name32, name16, name8, name8h) \ 75 IR_REG_ ## code, 76 77 #define IR_FP_REG_ENUM(code, name) \ 78 IR_REG_ ## code, 79 80 enum _ir_reg { 81 _IR_REG_NONE = -1, 82 IR_GP_REGS(IR_GP_REG_ENUM) 83 IR_FP_REGS(IR_FP_REG_ENUM) 84 IR_REG_NUM, 85 }; 86 87 #define IR_REG_GP_FIRST IR_REG_R0 88 #define IR_REG_FP_FIRST IR_REG_XMM0 89 #define IR_REG_GP_LAST (IR_REG_FP_FIRST - 1) 90 #define IR_REG_FP_LAST (IR_REG_NUM - 1) 91 #define IR_REG_SCRATCH (IR_REG_NUM) /* special name for regset */ 92 #define IR_REG_ALL (IR_REG_NUM + 1) /* special name for regset */ 93 94 #define IR_REGSET_64BIT 0 95 96 #define IR_REG_STACK_POINTER \ 97 IR_REG_RSP 98 #define IR_REG_FRAME_POINTER \ 99 IR_REG_RBP 100 #define IR_REGSET_FIXED \ 101 (IR_REGSET(IR_REG_RSP)) 102 #define IR_REGSET_GP \ 103 IR_REGSET_DIFFERENCE(IR_REGSET_INTERVAL(IR_REG_GP_FIRST, IR_REG_GP_LAST), IR_REGSET_FIXED) 104 #define IR_REGSET_FP \ 105 IR_REGSET_DIFFERENCE(IR_REGSET_INTERVAL(IR_REG_FP_FIRST, IR_REG_FP_LAST), IR_REGSET_FIXED) 106 107 #define IR_REG_RAX IR_REG_R0 108 #define IR_REG_RCX IR_REG_R1 109 #define IR_REG_RDX IR_REG_R2 110 #define IR_REG_RBX IR_REG_R3 111 #define IR_REG_RSP IR_REG_R4 112 #define IR_REG_RBP IR_REG_R5 113 #define IR_REG_RSI IR_REG_R6 114 #define IR_REG_RDI IR_REG_R7 115 116 /* Calling Convention */ 117 #ifdef _WIN64 118 119 # define IR_REG_INT_RET1 IR_REG_RAX 120 # define IR_REG_FP_RET1 IR_REG_XMM0 121 # define IR_REG_INT_ARGS 4 122 # define IR_REG_FP_ARGS 4 123 # define IR_REG_INT_ARG1 IR_REG_RCX 124 # define IR_REG_INT_ARG2 IR_REG_RDX 125 # define IR_REG_INT_ARG3 IR_REG_R8 126 # define IR_REG_INT_ARG4 IR_REG_R9 127 # define IR_REG_FP_ARG1 IR_REG_XMM0 128 # define IR_REG_FP_ARG2 IR_REG_XMM1 129 # define IR_REG_FP_ARG3 IR_REG_XMM2 130 # define IR_REG_FP_ARG4 IR_REG_XMM3 131 # define IR_MAX_REG_ARGS 4 132 # define IR_SHADOW_ARGS 32 /* Reserved space in bytes - "home space" or "shadow store" for register arguments */ 133 134 # define IR_REGSET_SCRATCH \ 135 (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) \ 136 | IR_REGSET_INTERVAL(IR_REG_R8, IR_REG_R11) \ 137 | IR_REGSET_INTERVAL(IR_REG_XMM0, IR_REG_XMM5)) 138 139 # define IR_REGSET_PRESERVED \ 140 (IR_REGSET(IR_REG_RBX) \ 141 | IR_REGSET_INTERVAL(IR_REG_RBP, IR_REG_RDI) \ 142 | IR_REGSET_INTERVAL(IR_REG_R12, IR_REG_R15) \ 143 | IR_REGSET_INTERVAL(IR_REG_XMM6, IR_REG_XMM15)) 144 145 #elif defined(IR_TARGET_X64) 146 147 # define IR_REG_INT_RET1 IR_REG_RAX 148 # define IR_REG_FP_RET1 IR_REG_XMM0 149 # define IR_REG_INT_ARGS 6 150 # define IR_REG_FP_ARGS 8 151 # define IR_REG_INT_ARG1 IR_REG_RDI 152 # define IR_REG_INT_ARG2 IR_REG_RSI 153 # define IR_REG_INT_ARG3 IR_REG_RDX 154 # define IR_REG_INT_ARG4 IR_REG_RCX 155 # define IR_REG_INT_ARG5 IR_REG_R8 156 # define IR_REG_INT_ARG6 IR_REG_R9 157 # define IR_REG_FP_ARG1 IR_REG_XMM0 158 # define IR_REG_FP_ARG2 IR_REG_XMM1 159 # define IR_REG_FP_ARG3 IR_REG_XMM2 160 # define IR_REG_FP_ARG4 IR_REG_XMM3 161 # define IR_REG_FP_ARG5 IR_REG_XMM4 162 # define IR_REG_FP_ARG6 IR_REG_XMM5 163 # define IR_REG_FP_ARG7 IR_REG_XMM6 164 # define IR_REG_FP_ARG8 IR_REG_XMM7 165 # define IR_MAX_REG_ARGS 14 166 # define IR_SHADOW_ARGS 0 167 168 # define IR_REG_VARARG_FP_REGS IR_REG_RAX /* hidden argument to specify the number of vector registers used */ 169 170 # define IR_REGSET_SCRATCH \ 171 (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) \ 172 | IR_REGSET_INTERVAL(IR_REG_RSI, IR_REG_RDI) \ 173 | IR_REGSET_INTERVAL(IR_REG_R8, IR_REG_R11) \ 174 | IR_REGSET_FP) 175 176 # define IR_REGSET_PRESERVED \ 177 (IR_REGSET(IR_REG_RBX) \ 178 | IR_REGSET(IR_REG_RBP) \ 179 | IR_REGSET_INTERVAL(IR_REG_R12, IR_REG_R15)) 180 181 typedef struct _ir_va_list { 182 uint32_t gp_offset; 183 uint32_t fp_offset; 184 void *overflow_arg_area; 185 void *reg_save_area; 186 } ir_va_list; 187 188 #elif defined(IR_TARGET_X86) 189 190 # define IR_REG_INT_RET1 IR_REG_RAX 191 # define IR_REG_INT_RET2 IR_REG_RDX 192 # define IR_REG_INT_ARGS 0 193 # define IR_REG_FP_ARGS 0 194 195 # define IR_HAVE_FASTCALL 1 196 # define IR_REG_INT_FCARGS 2 197 # define IR_REG_FP_FCARGS 0 198 # define IR_REG_INT_FCARG1 IR_REG_RCX 199 # define IR_REG_INT_FCARG2 IR_REG_RDX 200 # define IR_MAX_REG_ARGS 2 201 # define IR_SHADOW_ARGS 0 202 203 # define IR_REGSET_SCRATCH \ 204 (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) | IR_REGSET_FP) 205 206 # define IR_REGSET_PRESERVED \ 207 (IR_REGSET(IR_REG_RBX) \ 208 | IR_REGSET(IR_REG_RBP) \ 209 | IR_REGSET_INTERVAL(IR_REG_RSI, IR_REG_RDI)) 210 211 #else 212 # error "Unsupported target architecture" 213 #endif 214 215 typedef struct _ir_tmp_reg { 216 union { 217 uint8_t num; 218 int8_t reg; 219 }; 220 uint8_t type; 221 uint8_t start; 222 uint8_t end; 223 } ir_tmp_reg; 224 225 struct _ir_target_constraints { 226 int8_t def_reg; 227 uint8_t tmps_count; 228 uint8_t hints_count; 229 ir_tmp_reg tmp_regs[3]; 230 int8_t hints[IR_MAX_REG_ARGS + 3]; 231 }; 232 233 #endif /* IR_X86_H */ 234