allow debug build (make DEBUG=1)
[pcsx_rearmed.git] / deps / lightning / lib / jit_fallback.c
CommitLineData
ba3814c1
PC
1#if PROTO
2#define fallback_save(r0) _fallback_save(_jit, r0)
3static void _fallback_save(jit_state_t*, jit_int32_t);
4#define fallback_load(r0) _fallback_load(_jit, r0)
5static void _fallback_load(jit_state_t*, jit_int32_t);
6#define fallback_save_regs(r0) _fallback_save_regs(_jit, r0)
7static void _fallback_save_regs(jit_state_t*, jit_int32_t);
8#define fallback_load_regs(r0) _fallback_load_regs(_jit, r0)
9static void _fallback_load_regs(jit_state_t*, jit_int32_t);
10#define fallback_calli(i0, i1) _fallback_calli(_jit, i0, i1)
11static void _fallback_calli(jit_state_t*, jit_word_t, jit_word_t);
12#define fallback_casx(r0,r1,r2,r3,im) _fallback_casx(_jit,r0,r1,r2,r3,im)
13static void _fallback_casx(jit_state_t *, jit_int32_t, jit_int32_t,
14 jit_int32_t, jit_int32_t, jit_word_t);
15#endif
16
17#if CODE
18static void
19_fallback_save(jit_state_t *_jit, jit_int32_t r0)
20{
21 jit_int32_t offset, regno, spec;
22 for (offset = 0; offset < JIT_R_NUM; offset++) {
23 spec = _rvs[offset].spec;
24 regno = jit_regno(spec);
25 if (regno == r0) {
26 if (!(spec & jit_class_sav))
27 stxi(_jitc->function->regoff[offset], rn(JIT_FP), regno);
28 break;
29 }
30 }
31}
32
33static void
34_fallback_load(jit_state_t *_jit, jit_int32_t r0)
35{
36 jit_int32_t offset, regno, spec;
37 for (offset = 0; offset < JIT_R_NUM; offset++) {
38 spec = _rvs[offset].spec;
39 regno = jit_regno(spec);
40 if (regno == r0) {
41 if (!(spec & jit_class_sav))
42 ldxi(regno, rn(JIT_FP), _jitc->function->regoff[offset]);
43 break;
44 }
45 }
46}
47
48static void
49_fallback_save_regs(jit_state_t *_jit, jit_int32_t r0)
50{
51 jit_int32_t offset, regno, spec;
52 for (offset = 0; offset < JIT_R_NUM; offset++) {
53 regno = JIT_R(offset);
54 spec = _rvs[regno].spec;
55 if ((spec & jit_class_gpr) && regno == r0)
56 continue;
57 if (!(spec & jit_class_sav)) {
58 if (!_jitc->function->regoff[regno]) {
59 _jitc->function->regoff[regno] =
60 jit_allocai(sizeof(jit_word_t));
61 _jitc->again = 1;
62 }
63 jit_regset_setbit(&_jitc->regsav, regno);
64 emit_stxi(_jitc->function->regoff[regno], JIT_FP, regno);
65 }
66 }
67 /* If knew for certain float registers are not used by
68 * pthread_mutex_lock and pthread_mutex_unlock, could skip this */
69 for (offset = 0; offset < JIT_F_NUM; offset++) {
70 regno = JIT_F(offset);
71 spec = _rvs[regno].spec;
72 if (!(spec & jit_class_sav)) {
73 if (!_jitc->function->regoff[regno]) {
74 _jitc->function->regoff[regno] =
75 jit_allocai(sizeof(jit_word_t));
76 _jitc->again = 1;
77 }
78 jit_regset_setbit(&_jitc->regsav, regno);
79 emit_stxi_d(_jitc->function->regoff[regno], JIT_FP, regno);
80 }
81 }
82}
83
84static void
85_fallback_load_regs(jit_state_t *_jit, jit_int32_t r0)
86{
87 jit_int32_t offset, regno, spec;
88 for (offset = 0; offset < JIT_R_NUM; offset++) {
89 regno = JIT_R(offset);
90 spec = _rvs[regno].spec;
91 if ((spec & jit_class_gpr) && regno == r0)
92 continue;
93 if (!(spec & jit_class_sav)) {
94 jit_regset_clrbit(&_jitc->regsav, regno);
95 emit_ldxi(regno, JIT_FP, _jitc->function->regoff[regno]);
96 }
97 }
98 /* If knew for certain float registers are not used by
99 * pthread_mutex_lock and pthread_mutex_unlock, could skip this */
100 for (offset = 0; offset < JIT_F_NUM; offset++) {
101 regno = JIT_F(offset);
102 spec = _rvs[regno].spec;
103 if (!(spec & jit_class_sav)) {
104 jit_regset_clrbit(&_jitc->regsav, regno);
105 emit_ldxi_d(regno, JIT_FP, _jitc->function->regoff[regno]);
106 }
107 }
108}
109
110static void
111_fallback_calli(jit_state_t *_jit, jit_word_t i0, jit_word_t i1)
112{
113# if defined(__mips__)
114 movi(rn(_A0), i1);
115# elif defined(__arm__)
116 movi(rn(_R0), i1);
117# elif defined(__sparc__)
118 movi(rn(_O0), i1);
119# elif defined(__ia64__)
120 /* avoid confusion with pushargi patching */
121 if (i1 >= -2097152 && i1 <= 2097151)
122 MOVI(_jitc->rout, i1);
123 else
124 MOVL(_jitc->rout, i1);
125# elif defined(__hppa__)
126 movi(_R26_REGNO, i1);
127# elif defined(__s390__) || defined(__s390x__)
128 movi(rn(_R2), i1);
129# elif defined(__alpha__)
130 movi(rn(_A0), i1);
131# elif defined(__riscv__)
132 movi(rn(JIT_RA0), i1);
133# endif
134 calli(i0);
135}
136
137static void
138_fallback_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
139 jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
140{
141 jit_int32_t r1_reg, iscasi;
142 jit_word_t jump, done;
143 /* XXX only attempts to fallback cas for lightning jit code */
144 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
145 if ((iscasi = r1 == _NOREG)) {
146 r1_reg = jit_get_reg(jit_class_gpr);
147 r1 = rn(r1_reg);
148 movi(r1, i0);
149 }
150 fallback_save_regs(r0);
151 fallback_calli((jit_word_t)pthread_mutex_lock, (jit_word_t)&mutex);
152 fallback_load(r1);
153 ldr(r0, r1);
154 fallback_load(r2);
155 eqr(r0, r0, r2);
156 fallback_save(r0);
157 jump = bnei(_jit->pc.w, r0, 1);
158 fallback_load(r3);
159# if __WORDSIZE == 32
160 str_i(r1, r3);
161# else
162 str_l(r1, r3);
163# endif
164 /* done: */
165 done = _jit->pc.w;
166 fallback_calli((jit_word_t)pthread_mutex_unlock, (jit_word_t)&mutex);
167 fallback_load(r0);
168# if defined(__arm__)
169 patch_at(arm_patch_jump, jump, done);
170# else
171 patch_at(jump, done);
172# endif
173 fallback_load_regs(r0);
174 if (iscasi)
175 jit_unget_reg(r1_reg);
176}
177#endif