forked from dstogov/ir
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ir_x86.h
233 lines (200 loc) · 6.13 KB
/
ir_x86.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
* IR - Lightweight JIT Compilation Framework
* (x86/x86_64 CPU specific definitions)
* Copyright (C) 2022 Zend by Perforce.
* Authors: Dmitry Stogov <[email protected]>
*/
#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 */