Skip to content

Commit 7adaec1

Browse files
committed
Move system independent code out from x86 specific header
1 parent c290de1 commit 7adaec1

File tree

3 files changed

+204
-190
lines changed

3 files changed

+204
-190
lines changed

ext/opcache/jit/zend_jit_internal.h

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,191 @@
2020
#ifndef ZEND_JIT_INTERNAL_H
2121
#define ZEND_JIT_INTERNAL_H
2222

23+
/* Register Set */
24+
#define ZEND_REGSET_EMPTY 0
25+
26+
#define ZEND_REGSET_IS_EMPTY(regset) \
27+
(regset == ZEND_REGSET_EMPTY)
28+
29+
#define ZEND_REGSET(reg) \
30+
(1u << (reg))
31+
32+
#define ZEND_REGSET_INTERVAL(reg1, reg2) \
33+
(((1u << ((reg2) - (reg1) + 1)) - 1) << (reg1))
34+
35+
#define ZEND_REGSET_IN(regset, reg) \
36+
(((regset) & ZEND_REGSET(reg)) != 0)
37+
38+
#define ZEND_REGSET_INCL(regset, reg) \
39+
(regset) |= ZEND_REGSET(reg)
40+
41+
#define ZEND_REGSET_EXCL(regset, reg) \
42+
(regset) &= ~ZEND_REGSET(reg)
43+
44+
#define ZEND_REGSET_UNION(set1, set2) \
45+
((set1) | (set2))
46+
47+
#define ZEND_REGSET_INTERSECTION(set1, set2) \
48+
((set1) & (set2))
49+
50+
#define ZEND_REGSET_DIFFERENCE(set1, set2) \
51+
((set1) & ~(set2))
52+
53+
#ifndef _WIN32
54+
# if (ZREG_NUM <= 32)
55+
# define ZEND_REGSET_FIRST(set) ((zend_reg)__builtin_ctz(set))
56+
# define ZEND_REGSET_LAST(set) ((zend_reg)(__builtin_clz(set)^31)))
57+
# elif(ZREG_NUM <= 64)
58+
# define ZEND_REGSET_FIRST(set) ((zend_reg)__builtin_ctzll(set))
59+
# define ZEND_REGSET_LAST(set) ((zend_reg)(__builtin_clzll(set)^63)))
60+
# else
61+
# errir "Too many registers"
62+
# endif
63+
#else
64+
# include <intrin.h>
65+
uint32_t __inline __zend_jit_ctz(uint32_t value) {
66+
DWORD trailing_zero = 0;
67+
if (_BitScanForward(&trailing_zero, value)) {
68+
return trailing_zero;
69+
}
70+
return 32;
71+
}
72+
uint32_t __inline __zend_jit_clz(uint32_t value) {
73+
DWORD leading_zero = 0;
74+
if (_BitScanReverse(&leading_zero, value)) {
75+
return 31 - leading_zero;
76+
}
77+
return 32;
78+
}
79+
# define ZEND_REGSET_FIRST(set) ((zend_reg)__zend_jit_ctz(set))
80+
# define ZEND_REGSET_LAST(set) ((zend_reg)(__zend_jit_clz(set)^31)))
81+
#endif
82+
83+
#define ZEND_REGSET_FOREACH(set, reg) \
84+
do { \
85+
zend_regset _tmp = (set); \
86+
while (!ZEND_REGSET_IS_EMPTY(_tmp)) { \
87+
zend_reg _reg = ZEND_REGSET_FIRST(_tmp); \
88+
ZEND_REGSET_EXCL(_tmp, _reg); \
89+
reg = _reg; \
90+
91+
#define ZEND_REGSET_FOREACH_END() \
92+
} \
93+
} while (0)
94+
95+
/* Register Names */
96+
extern const char *zend_reg_name[];
97+
98+
/* Address Encoding */
99+
typedef uintptr_t zend_jit_addr;
100+
101+
#define IS_CONST_ZVAL 0
102+
#define IS_MEM_ZVAL 1
103+
#define IS_REG 2
104+
105+
#define _ZEND_ADDR_MODE_MASK 0x3
106+
#define _ZEND_ADDR_REG_SHIFT 2
107+
#define _ZEND_ADDR_REG_MASK 0x3f /* no more than 64 registers */
108+
#define _ZEND_ADDR_OFFSET_SHIFT 8
109+
#define _ZEND_ADDR_REG_STORE_BIT 8
110+
#define _ZEND_ADDR_REG_LOAD_BIT 9
111+
#define _ZEND_ADDR_REG_LAST_USE_BIT 10
112+
113+
#define ZEND_ADDR_CONST_ZVAL(zv) \
114+
(((zend_jit_addr)(uintptr_t)(zv)) | IS_CONST_ZVAL)
115+
#define ZEND_ADDR_MEM_ZVAL(reg, offset) \
116+
((((zend_jit_addr)(uintptr_t)(offset)) << _ZEND_ADDR_OFFSET_SHIFT) | \
117+
(((zend_jit_addr)(uintptr_t)(reg)) << _ZEND_ADDR_REG_SHIFT) | \
118+
IS_MEM_ZVAL)
119+
#define ZEND_ADDR_REG(reg) \
120+
((((zend_jit_addr)(uintptr_t)(reg)) << _ZEND_ADDR_REG_SHIFT) | \
121+
IS_REG)
122+
123+
#define Z_MODE(addr) (((addr) & _ZEND_ADDR_MODE_MASK))
124+
#define Z_ZV(addr) ((zval*)(addr))
125+
#define Z_OFFSET(addr) ((uint32_t)((addr)>>_ZEND_ADDR_OFFSET_SHIFT))
126+
#define Z_REG(addr) ((zend_reg)(((addr)>>_ZEND_ADDR_REG_SHIFT) & _ZEND_ADDR_REG_MASK))
127+
#define Z_STORE(addr) ((zend_reg)(((addr)>>_ZEND_ADDR_REG_STORE_BIT) & 1))
128+
#define Z_LOAD(addr) ((zend_reg)(((addr)>>_ZEND_ADDR_REG_LOAD_BIT) & 1))
129+
#define Z_LAST_USE(addr) ((zend_reg)(((addr)>>_ZEND_ADDR_REG_LAST_USE_BIT) & 1))
130+
131+
#define OP_REG_EX(reg, store, load, last_use) \
132+
((reg) | \
133+
((store) ? (1 << (_ZEND_ADDR_REG_STORE_BIT-_ZEND_ADDR_REG_SHIFT)) : 0) | \
134+
((load) ? (1 << (_ZEND_ADDR_REG_LOAD_BIT-_ZEND_ADDR_REG_SHIFT)) : 0) | \
135+
((last_use) ? (1 << (_ZEND_ADDR_REG_LAST_USE_BIT-_ZEND_ADDR_REG_SHIFT)) : 0) \
136+
)
137+
138+
#define OP_REG(ssa_op, op) \
139+
(ra && ssa_op->op >= 0 && ra[ssa_op->op] ? \
140+
OP_REG_EX(ra[ssa_op->op]->reg, \
141+
(ra[ssa_op->op]->flags & ZREG_STORE), \
142+
(ra[ssa_op->op]->flags & ZREG_LOAD), \
143+
zend_ival_is_last_use(ra[ssa_op->op], ssa_op - ssa->ops) \
144+
) : ZREG_NONE)
145+
146+
static zend_always_inline zend_jit_addr _zend_jit_decode_op(zend_uchar op_type, znode_op op, const zend_op *opline, zend_reg reg)
147+
{
148+
if (op_type == IS_CONST) {
149+
#if ZEND_USE_ABS_CONST_ADDR
150+
return ZEND_ADDR_CONST_ZVAL(op.zv);
151+
#else
152+
return ZEND_ADDR_CONST_ZVAL(RT_CONSTANT(opline, op));
153+
#endif
154+
} else {
155+
ZEND_ASSERT(op_type & (IS_CV|IS_TMP_VAR|IS_VAR));
156+
if (reg != ZREG_NONE) {
157+
return ZEND_ADDR_REG(reg);
158+
} else {
159+
return ZEND_ADDR_MEM_ZVAL(ZREG_FP, op.var);
160+
}
161+
}
162+
}
163+
164+
#define OP_ADDR(opline, type, op) \
165+
_zend_jit_decode_op((opline)->type, (opline)->op, opline, ZREG_NONE)
166+
167+
#define OP1_ADDR() \
168+
OP_ADDR(opline, op1_type, op1)
169+
#define OP2_ADDR() \
170+
OP_ADDR(opline, op2_type, op2)
171+
#define RES_ADDR() \
172+
OP_ADDR(opline, result_type, result)
173+
#define OP1_DATA_ADDR() \
174+
OP_ADDR(opline + 1, op1_type, op1)
175+
176+
#define OP_REG_ADDR(opline, type, _op, _ssa_op) \
177+
_zend_jit_decode_op((opline)->type, (opline)->_op, opline, \
178+
OP_REG(ssa_op, _ssa_op))
179+
180+
#define OP1_REG_ADDR() \
181+
OP_REG_ADDR(opline, op1_type, op1, op1_use)
182+
#define OP2_REG_ADDR() \
183+
OP_REG_ADDR(opline, op2_type, op2, op2_use)
184+
#define RES_REG_ADDR() \
185+
OP_REG_ADDR(opline, result_type, result, result_def)
186+
#define OP1_DATA_REG_ADDR() \
187+
OP_REG_ADDR(opline + 1, op1_type, op1, op1_use)
188+
189+
#define OP1_DEF_REG_ADDR() \
190+
OP_REG_ADDR(opline, op1_type, op1, op1_def)
191+
#define OP2_DEF_REG_ADDR() \
192+
OP_REG_ADDR(opline, op2_type, op2, op2_def)
193+
#define RES_USE_REG_ADDR() \
194+
OP_REG_ADDR(opline, result_type, result, result_use)
195+
#define OP1_DATA_DEF_REG_ADDR() \
196+
OP_REG_ADDR(opline + 1, op1_type, op1, op1_def)
197+
198+
static zend_always_inline bool zend_jit_same_addr(zend_jit_addr addr1, zend_jit_addr addr2)
199+
{
200+
if (addr1 == addr2) {
201+
return 1;
202+
} else if (Z_MODE(addr1) == IS_REG && Z_MODE(addr2) == IS_REG) {
203+
return Z_REG(addr1) == Z_REG(addr2);
204+
}
205+
return 0;
206+
}
207+
23208
typedef struct _zend_jit_op_array_extension {
24209
zend_func_info func_info;
25210
const void *orig_handler;

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@
110110
*/
111111

112112
#include "Zend/zend_cpuinfo.h"
113-
#include "jit/zend_jit_x86.h"
114113

115114
#ifdef HAVE_VALGRIND
116115
# include <valgrind/valgrind.h>
@@ -141,6 +140,18 @@ const char* zend_reg_name[] = {
141140
# define GCC_GLOBAL_REGS 0
142141
#endif
143142

143+
/* Simulate x86 fastcall */
144+
#ifdef _WIN64
145+
# define ZREG_FCARG1a ZREG_RCX
146+
# define ZREG_FCARG2a ZREG_RDX
147+
#elif defined(__x86_64__)
148+
# define ZREG_FCARG1a ZREG_RDI
149+
# define ZREG_FCARG2a ZREG_RSI
150+
#else
151+
# define ZREG_FCARG1a ZREG_RCX
152+
# define ZREG_FCARG2a ZREG_RDX
153+
#endif
154+
144155
#if ZTS
145156
static size_t tsrm_ls_cache_tcb_offset = 0;
146157
static size_t tsrm_tls_index;

0 commit comments

Comments
 (0)