Update lightrec 20220910 (#686)
[pcsx_rearmed.git] / deps / lightning / lib / jit_aarch64-fpu.c
CommitLineData
4a71579b
PC
1/*
2 * Copyright (C) 2013-2019 Free Software Foundation, Inc.
3 *
4 * This file is part of GNU lightning.
5 *
6 * GNU lightning is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * GNU lightning is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * Authors:
17 * Paulo Cesar Pereira de Andrade
18 */
19
20#if PROTO
21# define A64_SCVTF 0x1e220000
22# define A64_FMOVWV 0x1e260000
23# define A64_FMOVVW 0x1e270000
24# define A64_FMOVXV 0x9e260000
25# define A64_FMOVVX 0x9e270000
26# define A64_FCVTZS 0x1e380000
27# define A64_FCMPE 0x1e202010
28# define A64_FMOV 0x1e204000
29# define A64_FABS 0x1e20c000
30# define A64_FNEG 0x1e214000
31# define A64_FSQRT 0x1e21c000
32# define A64_FCVTS 0x1e224000
33# define A64_FCVTD 0x1e22c000
34# define A64_FMUL 0x1e200800
35# define A64_FDIV 0x1e201800
36# define A64_FADD 0x1e202800
37# define A64_FSUB 0x1e203800
38# define FCMPES(Rn,Rm) os_vv(A64_FCMPE,0,Rn,Rm)
39# define FCMPED(Rn,Rm) os_vv(A64_FCMPE,1,Rn,Rm)
40# define FMOVS(Rd,Rn) osvv_(A64_FMOV,0,Rd,Rn)
41# define FMOVD(Rd,Rn) osvv_(A64_FMOV,1,Rd,Rn)
42# define FMOVWS(Rd,Rn) osvv_(A64_FMOVWV,0,Rd,Rn)
43# define FMOVSW(Rd,Rn) osvv_(A64_FMOVVW,0,Rd,Rn)
44# define FMOVXD(Rd,Rn) osvv_(A64_FMOVXV,1,Rd,Rn)
45# define FMOVDX(Rd,Rn) osvv_(A64_FMOVVX,1,Rd,Rn)
46# define FCVT_SD(Rd,Rn) osvv_(A64_FCVTS,1,Rd,Rn)
47# define FCVT_DS(Rd,Rn) osvv_(A64_FCVTD,0,Rd,Rn)
48# define SCVTFS(Rd,Rn) osvv_(A64_SCVTF|XS,0,Rd,Rn)
49# define SCVTFD(Rd,Rn) osvv_(A64_SCVTF|XS,1,Rd,Rn)
50# define FCVTSZ_WS(Rd,Rn) osvv_(A64_FCVTZS,0,Rd,Rn)
51# define FCVTSZ_WD(Rd,Rn) osvv_(A64_FCVTZS,1,Rd,Rn)
52# define FCVTSZ_XS(Rd,Rn) osvv_(A64_FCVTZS|XS,0,Rd,Rn)
53# define FCVTSZ_XD(Rd,Rn) osvv_(A64_FCVTZS|XS,1,Rd,Rn)
54# define FABSS(Rd,Rn) osvv_(A64_FABS,0,Rd,Rn)
55# define FABSD(Rd,Rn) osvv_(A64_FABS,1,Rd,Rn)
56# define FNEGS(Rd,Rn) osvv_(A64_FNEG,0,Rd,Rn)
57# define FNEGD(Rd,Rn) osvv_(A64_FNEG,1,Rd,Rn)
58# define FSQRTS(Rd,Rn) osvv_(A64_FSQRT,0,Rd,Rn)
59# define FSQRTD(Rd,Rn) osvv_(A64_FSQRT,1,Rd,Rn)
60# define FADDS(Rd,Rn,Rm) osvvv(A64_FADD,0,Rd,Rn,Rm)
61# define FADDD(Rd,Rn,Rm) osvvv(A64_FADD,1,Rd,Rn,Rm)
62# define FSUBS(Rd,Rn,Rm) osvvv(A64_FSUB,0,Rd,Rn,Rm)
63# define FSUBD(Rd,Rn,Rm) osvvv(A64_FSUB,1,Rd,Rn,Rm)
64# define FMULS(Rd,Rn,Rm) osvvv(A64_FMUL,0,Rd,Rn,Rm)
65# define FMULD(Rd,Rn,Rm) osvvv(A64_FMUL,1,Rd,Rn,Rm)
66# define FDIVS(Rd,Rn,Rm) osvvv(A64_FDIV,0,Rd,Rn,Rm)
67# define FDIVD(Rd,Rn,Rm) osvvv(A64_FDIV,1,Rd,Rn,Rm)
68# define osvvv(Op,Sz,Rd,Rn,Rm) _osvvv(_jit,Op,Sz,Rd,Rn,Rm)
69static void _osvvv(jit_state_t*,jit_int32_t,jit_int32_t,
70 jit_int32_t,jit_int32_t,jit_int32_t);
71# define osvv_(Op,Sz,Rd,Rn) _osvv_(_jit,Op,Sz,Rd,Rn)
72static void _osvv_(jit_state_t*,jit_int32_t,
73 jit_int32_t,jit_int32_t,jit_int32_t);
74# define os_vv(Op,Sz,Rn,Rm) _os_vv(_jit,Op,Sz,Rn,Rm)
75static void _os_vv(jit_state_t*,jit_int32_t,
76 jit_int32_t,jit_int32_t,jit_int32_t);
77# define truncr_f_i(r0,r1) _truncr_f_i(_jit,r0,r1)
78static void _truncr_f_i(jit_state_t*,jit_int32_t,jit_int32_t);
79# define truncr_f_l(r0,r1) FCVTSZ_XS(r0,r1)
80# define truncr_d_i(r0,r1) _truncr_d_i(_jit,r0,r1)
81static void _truncr_d_i(jit_state_t*,jit_int32_t,jit_int32_t);
82# define truncr_d_l(r0,r1) FCVTSZ_XD(r0,r1)
83# define addr_f(r0,r1,r2) FADDS(r0,r1,r2)
84# define addi_f(r0,r1,i0) _addi_f(_jit,r0,r1,i0)
85static void _addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
86# define subr_f(r0,r1,r2) FSUBS(r0,r1,r2)
87# define subi_f(r0,r1,i0) _subi_f(_jit,r0,r1,i0)
88static void _subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
89# define rsbr_f(r0, r1, r2) subr_f(r0, r2, r1)
90# define rsbi_f(r0, r1, i0) _rsbi_f(_jit, r0, r1, i0)
91static void _rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
92# define mulr_f(r0,r1,r2) FMULS(r0,r1,r2)
93# define muli_f(r0,r1,i0) _muli_f(_jit,r0,r1,i0)
94static void _muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
95# define divr_f(r0,r1,r2) FDIVS(r0,r1,r2)
96# define divi_f(r0,r1,i0) _divi_f(_jit,r0,r1,i0)
97static void _divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
98# define absr_f(r0,r1) FABSS(r0,r1)
99# define negr_f(r0,r1) FNEGS(r0,r1)
100# define sqrtr_f(r0,r1) FSQRTS(r0,r1)
101# define extr_f(r0,r1) SCVTFS(r0,r1)
102# define ldr_f(r0,r1) _ldr_f(_jit,r0,r1)
103static void _ldr_f(jit_state_t*,jit_int32_t,jit_int32_t);
104# define ldi_f(r0,i0) _ldi_f(_jit,r0,i0)
105static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t);
106# define ldxr_f(r0,r1,r2) _ldxr_f(_jit,r0,r1,r2)
107static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
108# define ldxi_f(r0,r1,i0) _ldxi_f(_jit,r0,r1,i0)
109static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
110# define str_f(r0,r1) _str_f(_jit,r0,r1)
111static void _str_f(jit_state_t*,jit_int32_t,jit_int32_t);
112# define sti_f(i0,r0) _sti_f(_jit,i0,r0)
113static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t);
114# define stxr_f(r0,r1,r2) _stxr_f(_jit,r0,r1,r2)
115static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
116# define stxi_f(i0,r0,r1) _stxi_f(_jit,i0,r0,r1)
117static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
118# define movr_f(r0,r1) _movr_f(_jit,r0,r1)
119static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t);
120# define movi_f(r0,i0) _movi_f(_jit,r0,i0)
121static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t);
122# define extr_d_f(r0,r1) FCVT_SD(r0,r1)
123# define fccr(cc,r0,r1,r2) _fccr(_jit,cc,r0,r1,r2)
124static void _fccr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
125# define fcci(cc,r0,r1,i0) _fcci(_jit,cc,r0,r1,i0)
126static void _fcci(jit_state_t*,
127 jit_int32_t,jit_int32_t,jit_int32_t,jit_float32_t);
128# define ltr_f(r0,r1,r2) fccr(CC_MI,r0,r1,r2)
129# define lti_f(r0,r1,i0) fcci(CC_MI,r0,r1,i0)
130# define ler_f(r0,r1,r2) fccr(CC_LS,r0,r1,r2)
131# define lei_f(r0,r1,i0) fcci(CC_LS,r0,r1,i0)
132# define eqr_f(r0,r1,r2) fccr(CC_EQ,r0,r1,r2)
133# define eqi_f(r0,r1,i0) fcci(CC_EQ,r0,r1,i0)
134# define ger_f(r0,r1,r2) fccr(CC_GE,r0,r1,r2)
135# define gei_f(r0,r1,i0) fcci(CC_GE,r0,r1,i0)
136# define gtr_f(r0,r1,r2) fccr(CC_GT,r0,r1,r2)
137# define gti_f(r0,r1,i0) fcci(CC_GT,r0,r1,i0)
138# define ner_f(r0,r1,r2) fccr(CC_NE,r0,r1,r2)
139# define nei_f(r0,r1,i0) fcci(CC_NE,r0,r1,i0)
140# define unltr_f(r0,r1,r2) fccr(CC_LT,r0,r1,r2)
141# define unlti_f(r0,r1,i0) fcci(CC_LT,r0,r1,i0)
142# define unler_f(r0,r1,r2) fccr(CC_LE,r0,r1,r2)
143# define unlei_f(r0,r1,i0) fcci(CC_LE,r0,r1,i0)
144# define uneqr_f(r0,r1,r2) _uneqr_f(_jit,r0,r1,r2)
145static void _uneqr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
146# define uneqi_f(r0,r1,i0) _uneqi_f(_jit,r0,r1,i0)
147static void _uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
148# define unger_f(r0,r1,r2) fccr(CC_PL,r0,r1,r2)
149# define ungei_f(r0,r1,i0) fcci(CC_PL,r0,r1,i0)
150# define ungtr_f(r0,r1,r2) fccr(CC_HI,r0,r1,r2)
151# define ungti_f(r0,r1,i0) fcci(CC_HI,r0,r1,i0)
152# define ltgtr_f(r0,r1,r2) _ltgtr_f(_jit,r0,r1,r2)
153static void _ltgtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
154# define ltgti_f(r0,r1,i0) _ltgti_f(_jit,r0,r1,i0)
155static void _ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
156# define ordr_f(r0,r1,r2) fccr(CC_VC,r0,r1,r2)
157# define ordi_f(r0,r1,i0) fcci(CC_VC,r0,r1,i0)
158# define unordr_f(r0,r1,r2) fccr(CC_VS,r0,r1,r2)
159# define unordi_f(r0,r1,i0) fcci(CC_VS,r0,r1,i0)
160#define fbccr(cc,i0,r0,r1) _fbccr(_jit,cc,i0,r0,r1)
161static jit_word_t
162_fbccr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
163#define fbcci(cc,i0,r0,i1) _fbcci(_jit,cc,i0,r0,i1)
164static jit_word_t
165_fbcci(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float32_t);
166# define bltr_f(i0,r0,r1) fbccr(BCC_MI,i0,r0,r1)
167# define blti_f(i0,r0,i1) fbcci(BCC_MI,i0,r0,i1)
168# define bler_f(i0,r0,r1) fbccr(BCC_LS,i0,r0,r1)
169# define blei_f(i0,r0,i1) fbcci(BCC_LS,i0,r0,i1)
170# define beqr_f(i0,r0,r1) fbccr(BCC_EQ,i0,r0,r1)
171# define beqi_f(i0,r0,i1) fbcci(BCC_EQ,i0,r0,i1)
172# define bger_f(i0,r0,r1) fbccr(BCC_GE,i0,r0,r1)
173# define bgei_f(i0,r0,i1) fbcci(BCC_GE,i0,r0,i1)
174# define bgtr_f(i0,r0,r1) fbccr(BCC_GT,i0,r0,r1)
175# define bgti_f(i0,r0,i1) fbcci(BCC_GT,i0,r0,i1)
176# define bner_f(i0,r0,r1) fbccr(BCC_NE,i0,r0,r1)
177# define bnei_f(i0,r0,i1) fbcci(BCC_NE,i0,r0,i1)
178# define bunltr_f(i0,r0,r1) fbccr(BCC_LT,i0,r0,r1)
179# define bunlti_f(i0,r0,i1) fbcci(BCC_LT,i0,r0,i1)
180# define bunler_f(i0,r0,r1) fbccr(BCC_LE,i0,r0,r1)
181# define bunlei_f(i0,r0,i1) fbcci(BCC_LE,i0,r0,i1)
182# define buneqr_f(i0,r0,r1) _buneqr_f(_jit,i0,r0,r1)
183static jit_word_t _buneqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
184# define buneqi_f(i0,r0,i1) _buneqi_f(_jit,i0,r0,i1)
185static jit_word_t _buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
186# define bunger_f(i0,r0,r1) fbccr(BCC_PL,i0,r0,r1)
187# define bungei_f(i0,r0,i1) fbcci(BCC_PL,i0,r0,i1)
188# define bungtr_f(i0,r0,r1) fbccr(BCC_HI,i0,r0,r1)
189# define bungti_f(i0,r0,i1) fbcci(BCC_HI,i0,r0,i1)
190# define bltgtr_f(i0,r0,r1) _bltgtr_f(_jit,i0,r0,r1)
191static jit_word_t _bltgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
192# define bltgti_f(i0,r0,i1) _bltgti_f(_jit,i0,r0,i1)
193static jit_word_t _bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
194# define bordr_f(i0,r0,r1) fbccr(BCC_VC,i0,r0,r1)
195# define bordi_f(i0,r0,i1) fbcci(BCC_VC,i0,r0,i1)
196# define bunordr_f(i0,r0,r1) fbccr(BCC_VS,i0,r0,r1)
197# define bunordi_f(i0,r0,i1) fbcci(BCC_VS,i0,r0,i1)
198# define addr_d(r0,r1,r2) FADDD(r0,r1,r2)
199# define addi_d(r0,r1,i0) _addi_d(_jit,r0,r1,i0)
200static void _addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
201# define subr_d(r0,r1,r2) FSUBD(r0,r1,r2)
202# define subi_d(r0,r1,i0) _subi_d(_jit,r0,r1,i0)
203static void _subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
204# define rsbr_d(r0, r1, r2) subr_d(r0, r2, r1)
205# define rsbi_d(r0, r1, i0) _rsbi_d(_jit, r0, r1, i0)
206static void _rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
207# define mulr_d(r0,r1,r2) FMULD(r0,r1,r2)
208# define muli_d(r0,r1,i0) _muli_d(_jit,r0,r1,i0)
209static void _muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
210# define divr_d(r0,r1,r2) FDIVD(r0,r1,r2)
211# define divi_d(r0,r1,i0) _divi_d(_jit,r0,r1,i0)
212static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
213# define absr_d(r0,r1) FABSD(r0,r1)
214# define negr_d(r0,r1) FNEGD(r0,r1)
215# define sqrtr_d(r0,r1) FSQRTD(r0,r1)
216# define extr_d(r0,r1) SCVTFD(r0,r1)
217# define ldr_d(r0,r1) _ldr_d(_jit,r0,r1)
218static void _ldr_d(jit_state_t*,jit_int32_t,jit_int32_t);
219# define ldi_d(r0,i0) _ldi_d(_jit,r0,i0)
220static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t);
221# define ldxr_d(r0,r1,r2) _ldxr_d(_jit,r0,r1,r2)
222static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
223# define ldxi_d(r0,r1,i0) _ldxi_d(_jit,r0,r1,i0)
224static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
225# define str_d(r0,r1) _str_d(_jit,r0,r1)
226static void _str_d(jit_state_t*,jit_int32_t,jit_int32_t);
227# define sti_d(i0,r0) _sti_d(_jit,i0,r0)
228static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t);
229# define stxr_d(r0,r1,r2) _stxr_d(_jit,r0,r1,r2)
230static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
231# define stxi_d(i0,r0,r1) _stxi_d(_jit,i0,r0,r1)
232static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
233# define movr_d(r0,r1) _movr_d(_jit,r0,r1)
234static void _movr_d(jit_state_t*,jit_int32_t,jit_int32_t);
235# define movi_d(r0,i0) _movi_d(_jit,r0,i0)
236static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t);
237# define extr_f_d(r0,r1) FCVT_DS(r0,r1)
238# define dccr(cc,r0,r1,r2) _dccr(_jit,cc,r0,r1,r2)
239static void _dccr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
240# define dcci(cc,r0,r1,i0) _dcci(_jit,cc,r0,r1,i0)
241static void _dcci(jit_state_t*,
242 jit_int32_t,jit_int32_t,jit_int32_t,jit_float64_t);
243# define ltr_d(r0,r1,r2) dccr(CC_MI,r0,r1,r2)
244# define lti_d(r0,r1,i0) dcci(CC_MI,r0,r1,i0)
245# define ler_d(r0,r1,r2) dccr(CC_LS,r0,r1,r2)
246# define lei_d(r0,r1,i0) dcci(CC_LS,r0,r1,i0)
247# define eqr_d(r0,r1,r2) dccr(CC_EQ,r0,r1,r2)
248# define eqi_d(r0,r1,i0) dcci(CC_EQ,r0,r1,i0)
249# define ger_d(r0,r1,r2) dccr(CC_GE,r0,r1,r2)
250# define gei_d(r0,r1,i0) dcci(CC_GE,r0,r1,i0)
251# define gtr_d(r0,r1,r2) dccr(CC_GT,r0,r1,r2)
252# define gti_d(r0,r1,i0) dcci(CC_GT,r0,r1,i0)
253# define ner_d(r0,r1,r2) dccr(CC_NE,r0,r1,r2)
254# define nei_d(r0,r1,i0) dcci(CC_NE,r0,r1,i0)
255# define unltr_d(r0,r1,r2) dccr(CC_LT,r0,r1,r2)
256# define unlti_d(r0,r1,i0) dcci(CC_LT,r0,r1,i0)
257# define unler_d(r0,r1,r2) dccr(CC_LE,r0,r1,r2)
258# define unlei_d(r0,r1,i0) dcci(CC_LE,r0,r1,i0)
259# define uneqr_d(r0,r1,r2) _uneqr_d(_jit,r0,r1,r2)
260static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
261# define uneqi_d(r0,r1,i0) _uneqi_d(_jit,r0,r1,i0)
262static void _uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
263# define unger_d(r0,r1,r2) dccr(CC_PL,r0,r1,r2)
264# define ungei_d(r0,r1,i0) dcci(CC_PL,r0,r1,i0)
265# define ungtr_d(r0,r1,r2) dccr(CC_HI,r0,r1,r2)
266# define ungti_d(r0,r1,i0) dcci(CC_HI,r0,r1,i0)
267# define ltgtr_d(r0,r1,r2) _ltgtr_d(_jit,r0,r1,r2)
268static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
269# define ltgti_d(r0,r1,i0) _ltgti_d(_jit,r0,r1,i0)
270static void _ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
271# define ordr_d(r0,r1,r2) dccr(CC_VC,r0,r1,r2)
272# define ordi_d(r0,r1,i0) dcci(CC_VC,r0,r1,i0)
273# define unordr_d(r0,r1,r2) dccr(CC_VS,r0,r1,r2)
274# define unordi_d(r0,r1,i0) dcci(CC_VS,r0,r1,i0)
275#define dbccr(cc,i0,r0,r1) _dbccr(_jit,cc,i0,r0,r1)
276static jit_word_t
277_dbccr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
278#define dbcci(cc,i0,r0,i1) _dbcci(_jit,cc,i0,r0,i1)
279static jit_word_t
280_dbcci(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float64_t);
281# define bltr_d(i0,r0,r1) dbccr(BCC_MI,i0,r0,r1)
282# define blti_d(i0,r0,i1) dbcci(BCC_MI,i0,r0,i1)
283# define bler_d(i0,r0,r1) dbccr(BCC_LS,i0,r0,r1)
284# define blei_d(i0,r0,i1) dbcci(BCC_LS,i0,r0,i1)
285# define beqr_d(i0,r0,r1) dbccr(BCC_EQ,i0,r0,r1)
286# define beqi_d(i0,r0,i1) dbcci(BCC_EQ,i0,r0,i1)
287# define bger_d(i0,r0,r1) dbccr(BCC_GE,i0,r0,r1)
288# define bgei_d(i0,r0,i1) dbcci(BCC_GE,i0,r0,i1)
289# define bgtr_d(i0,r0,r1) dbccr(BCC_GT,i0,r0,r1)
290# define bgti_d(i0,r0,i1) dbcci(BCC_GT,i0,r0,i1)
291# define bner_d(i0,r0,r1) dbccr(BCC_NE,i0,r0,r1)
292# define bnei_d(i0,r0,i1) dbcci(BCC_NE,i0,r0,i1)
293# define bunltr_d(i0,r0,r1) dbccr(BCC_LT,i0,r0,r1)
294# define bunlti_d(i0,r0,i1) dbcci(BCC_LT,i0,r0,i1)
295# define bunler_d(i0,r0,r1) dbccr(BCC_LE,i0,r0,r1)
296# define bunlei_d(i0,r0,i1) dbcci(BCC_LE,i0,r0,i1)
297# define buneqr_d(i0,r0,r1) _buneqr_d(_jit,i0,r0,r1)
298static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
299# define buneqi_d(i0,r0,i1) _buneqi_d(_jit,i0,r0,i1)
300static jit_word_t _buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
301# define bunger_d(i0,r0,r1) dbccr(BCC_PL,i0,r0,r1)
302# define bungei_d(i0,r0,i1) dbcci(BCC_PL,i0,r0,i1)
303# define bungtr_d(i0,r0,r1) dbccr(BCC_HI,i0,r0,r1)
304# define bungti_d(i0,r0,i1) dbcci(BCC_HI,i0,r0,i1)
305# define bltgtr_d(i0,r0,r1) _bltgtr_d(_jit,i0,r0,r1)
306static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
307# define bltgti_d(i0,r0,i1) _bltgti_d(_jit,i0,r0,i1)
308static jit_word_t _bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
309# define bordr_d(i0,r0,r1) dbccr(BCC_VC,i0,r0,r1)
310# define bordi_d(i0,r0,i1) dbcci(BCC_VC,i0,r0,i1)
311# define bunordr_d(i0,r0,r1) dbccr(BCC_VS,i0,r0,r1)
312# define bunordi_d(i0,r0,i1) dbcci(BCC_VS,i0,r0,i1)
313# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1)
314static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t);
315#endif
316
317#if CODE
318static void
319_osvvv(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Sz,
320 jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Rm)
321{
322 instr_t i;
323 assert(!(Rd & ~0x1f));
324 assert(!(Rn & ~0x1f));
325 assert(!(Rm & ~0x1f));
326 assert(!(Sz & ~0x3));
327 assert(!(Op & ~0xffe0fc00));
328 i.w = Op;
329 i.size.b = Sz;
330 i.Rd.b = Rd;
331 i.Rn.b = Rn;
332 i.Rm.b = Rm;
333 ii(i.w);
334}
335
336static void
337_osvv_(jit_state_t *_jit, jit_int32_t Op,
338 jit_int32_t Sz, jit_int32_t Rd, jit_int32_t Rn)
339{
340 instr_t i;
341 assert(!(Rd & ~0x1f));
342 assert(!(Rn & ~0x1f));
343 assert(!(Sz & ~0x3));
344 assert(!(Op & ~0xfffffc00));
345 i.w = Op;
346 i.size.b = Sz;
347 i.Rd.b = Rd;
348 i.Rn.b = Rn;
349 ii(i.w);
350}
351
352static void
353_os_vv(jit_state_t *_jit, jit_int32_t Op,
354 jit_int32_t Sz, jit_int32_t Rn, jit_int32_t Rm)
355{
356 instr_t i;
357 assert(!(Rn & ~0x1f));
358 assert(!(Rm & ~0x1f));
359 assert(!(Sz & ~0x3));
360 assert(!(Op & ~0xff20fc1f));
361 i.w = Op;
362 i.size.b = Sz;
363 i.Rn.b = Rn;
364 i.Rm.b = Rm;
365 ii(i.w);
366}
367
368#define fopi(name) \
369static void \
370_##name##i_f(jit_state_t *_jit, \
371 jit_int32_t r0, jit_int32_t r1, jit_float32_t i0) \
372{ \
373 jit_int32_t reg = jit_get_reg(jit_class_fpr); \
374 movi_f(rn(reg), i0); \
375 name##r_f(r0, r1, rn(reg)); \
376 jit_unget_reg(reg); \
377}
378#define dopi(name) \
379static void \
380_##name##i_d(jit_state_t *_jit, \
381 jit_int32_t r0, jit_int32_t r1, jit_float64_t i0) \
382{ \
383 jit_int32_t reg = jit_get_reg(jit_class_fpr); \
384 movi_d(rn(reg), i0); \
385 name##r_d(r0, r1, rn(reg)); \
386 jit_unget_reg(reg); \
387}
388#define fbopi(name) \
389static jit_word_t \
390_b##name##i_f(jit_state_t *_jit, \
391 jit_word_t i0, jit_int32_t r0, jit_float32_t i1) \
392{ \
393 jit_word_t word; \
394 jit_int32_t reg = jit_get_reg(jit_class_fpr| \
395 jit_class_nospill); \
396 movi_f(rn(reg), i1); \
397 word = b##name##r_f(i0, r0, rn(reg)); \
398 jit_unget_reg(reg); \
399 return (word); \
400}
401#define dbopi(name) \
402static jit_word_t \
403_b##name##i_d(jit_state_t *_jit, \
404 jit_word_t i0, jit_int32_t r0, jit_float64_t i1) \
405{ \
406 jit_word_t word; \
407 jit_int32_t reg = jit_get_reg(jit_class_fpr| \
408 jit_class_nospill); \
409 movi_d(rn(reg), i1); \
410 word = b##name##r_d(i0, r0, rn(reg)); \
411 jit_unget_reg(reg); \
412 return (word); \
413}
414
415static void
416_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
417{
418 FCVTSZ_WS(r0, r1);
419 extr_i(r0, r0);
420}
421
422static void
423_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
424{
425 FCVTSZ_WD(r0, r1);
426 extr_i(r0, r0);
427}
428
429fopi(add)
430fopi(sub)
431fopi(rsb)
432fopi(mul)
433fopi(div)
434
435static void
436_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
437{
438 jit_int32_t reg;
439 reg = jit_get_reg(jit_class_gpr);
440 ldr_i(rn(reg), r1);
441 FMOVSW(r0, rn(reg));
442 jit_unget_reg(reg);
443}
444
445static void
446_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
447{
448 jit_int32_t reg;
449 reg = jit_get_reg(jit_class_gpr);
450 ldi_i(rn(reg), i0);
451 FMOVSW(r0, rn(reg));
452 jit_unget_reg(reg);
453}
454
455static void
456_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
457{
458 jit_int32_t reg;
459 reg = jit_get_reg(jit_class_gpr);
460 ldxr_i(rn(reg), r1, r2);
461 FMOVSW(r0, rn(reg));
462 jit_unget_reg(reg);
463}
464
465static void
466_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
467{
468 jit_int32_t reg;
469 reg = jit_get_reg(jit_class_gpr);
470 ldxi_i(rn(reg), r1, i0);
471 FMOVSW(r0, rn(reg));
472 jit_unget_reg(reg);
473}
474
475static void
476_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
477{
478 jit_int32_t reg;
479 reg = jit_get_reg(jit_class_gpr);
480 FMOVWS(rn(reg), r1);
481 str_i(r0, rn(reg));
482 jit_unget_reg(reg);
483}
484
485static void
486_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
487{
488 jit_int32_t reg;
489 reg = jit_get_reg(jit_class_gpr);
490 FMOVWS(rn(reg), r0);
491 sti_i(i0, rn(reg));
492 jit_unget_reg(reg);
493}
494
495static void
496_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
497{
498 jit_int32_t reg;
499 reg = jit_get_reg(jit_class_gpr);
500 FMOVWS(rn(reg), r2);
501 stxr_i(r0, r1, rn(reg));
502 jit_unget_reg(reg);
503}
504
505static void
506_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
507{
508 jit_int32_t reg;
509 reg = jit_get_reg(jit_class_gpr);
510 FMOVWS(rn(reg), r1);
511 stxi_i(i0, r0, rn(reg));
512 jit_unget_reg(reg);
513}
514
515static void
516_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
517{
518 if (r0 != r1)
519 FMOVS(r0, r1);
520}
521
522static void
523_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0)
524{
525 union {
526 jit_int32_t i;
527 jit_float32_t f;
528 } u;
529 jit_int32_t reg;
530 u.f = i0;
531 if (u.i == 0)
532 FMOVSW(r0, WZR_REGNO);
533 else {
534 reg = jit_get_reg(jit_class_gpr);
535 /* prevent generating unused top 32 bits */
536 movi(rn(reg), ((jit_word_t)u.i) & 0xffffffff);
537 FMOVSW(r0, rn(reg));
538 jit_unget_reg(reg);
539 }
540}
541
542static void
543_fccr(jit_state_t *_jit, jit_int32_t cc,
544 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
545{
546 FCMPES(r1, r2);
547 CSET(r0, cc);
548}
549
550static void
551_fcci(jit_state_t *_jit, jit_int32_t cc,
552 jit_int32_t r0, jit_int32_t r1, jit_float32_t i0)
553{
554 jit_int32_t reg;
555 reg = jit_get_reg(jit_class_fpr);
556 movi_f(rn(reg), i0);
557 fccr(cc, r0, r1, rn(reg));
558 jit_unget_reg(reg);
559}
560
561static void
562_uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
563{
564 jit_word_t w;
565 FCMPES(r1, r2);
566 CSET(r0, CC_VS);
567 w = _jit->pc.w;
568 B_C(BCC_VS, 1); /* unordered satisfies condition */
569 CSET(r0, CC_EQ); /* equal satisfies condition */
570 patch_at(w, _jit->pc.w);
571}
572fopi(uneq)
573
574static void
575_ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
576{
577 jit_word_t w;
578 FCMPES(r1, r2);
579 CSET(r0, CC_VC); /* set to 1 if ordered */
580 w = _jit->pc.w;
581 B_C(BCC_VS, 1); /* unordered does not satisfy condition */
582 CSET(r0, CC_NE); /* set to 1 if not equal */
583 patch_at(w, _jit->pc.w);
584}
585fopi(ltgt)
586
587static jit_word_t
588_fbccr(jit_state_t *_jit, jit_int32_t cc,
589 jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
590{
591 jit_word_t w, d;
592 FCMPES(r0, r1);
593 w = _jit->pc.w;
594 d = (i0 - w) >> 2;
595 B_C(cc, d);
596 return (w);
597}
598
599static jit_word_t
600_fbcci(jit_state_t *_jit, jit_int32_t cc,
601 jit_word_t i0, jit_int32_t r0, jit_float32_t i1)
602{
603 jit_word_t w;
604 jit_int32_t reg;
605 reg = jit_get_reg(jit_class_fpr|jit_class_nospill);
606 movi_f(rn(reg), i1);
607 w = fbccr(cc, i0, r0, rn(reg));
608 jit_unget_reg(reg);
609 return (w);
610}
611
612static jit_word_t
613_buneqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
614{
615 jit_word_t u, v, w;
616 FCMPES(r0, r1);
617 u = _jit->pc.w;
618 B_C(BCC_VS, 1); /* unordered satisfies condition */
619 v = _jit->pc.w;
620 B_C(BCC_NE, 1); /* not equal (or unordered) does not satisfy */
621 patch_at(u, _jit->pc.w);
622 w = _jit->pc.w;
623 B((i0 - w) >> 2);
624 patch_at(v, _jit->pc.w);
625 return (w);
626}
627fbopi(uneq)
628
629static jit_word_t
630_bltgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
631{
632 jit_word_t u, v, w;
633 FCMPES(r0, r1);
634 u = _jit->pc.w;
635 B_C(BCC_VS, 2); /* jump over if unordered */
636 v = _jit->pc.w;
637 B_C(BCC_EQ, 1); /* jump over if equal */
638 w = _jit->pc.w;
639 B((i0 - w) >> 2);
640 patch_at(u, _jit->pc.w);
641 patch_at(v, _jit->pc.w);
642 return (w);
643}
644fbopi(ltgt)
645
646dopi(add)
647dopi(sub)
648dopi(rsb)
649dopi(mul)
650dopi(div)
651
652static void
653_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
654{
655 jit_int32_t reg;
656 reg = jit_get_reg(jit_class_gpr);
657 ldr_l(rn(reg), r1);
658 FMOVDX(r0, rn(reg));
659 jit_unget_reg(reg);
660}
661
662static void
663_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
664{
665 jit_int32_t reg;
666 reg = jit_get_reg(jit_class_gpr);
667 ldi_l(rn(reg), i0);
668 FMOVDX(r0, rn(reg));
669 jit_unget_reg(reg);
670}
671
672static void
673_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
674{
675 jit_int32_t reg;
676 reg = jit_get_reg(jit_class_gpr);
677 ldxr_l(rn(reg), r1, r2);
678 FMOVDX(r0, rn(reg));
679 jit_unget_reg(reg);
680}
681
682static void
683_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
684{
685 jit_int32_t reg;
686 reg = jit_get_reg(jit_class_gpr);
687 ldxi_l(rn(reg), r1, i0);
688 FMOVDX(r0, rn(reg));
689 jit_unget_reg(reg);
690}
691
692static void
693_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
694{
695 jit_int32_t reg;
696 reg = jit_get_reg(jit_class_gpr);
697 FMOVXD(rn(reg), r1);
698 str_l(r0, rn(reg));
699 jit_unget_reg(reg);
700}
701
702static void
703_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
704{
705 jit_int32_t reg;
706 reg = jit_get_reg(jit_class_gpr);
707 FMOVXD(rn(reg), r0);
708 sti_l(i0, rn(reg));
709 jit_unget_reg(reg);
710}
711
712static void
713_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
714{
715 jit_int32_t reg;
716 reg = jit_get_reg(jit_class_gpr);
717 FMOVXD(rn(reg), r2);
718 stxr_l(r0, r1, rn(reg));
719 jit_unget_reg(reg);
720}
721
722static void
723_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
724{
725 jit_int32_t reg;
726 reg = jit_get_reg(jit_class_gpr);
727 FMOVXD(rn(reg), r1);
728 stxi_l(i0, r0, rn(reg));
729 jit_unget_reg(reg);
730}
731
732static void
733_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
734{
735 if (r0 != r1)
736 FMOVD(r0, r1);
737}
738
739static void
740_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0)
741{
742 union {
743 jit_int64_t l;
744 jit_float64_t d;
745 } u;
746 jit_int32_t reg;
747 u.d = i0;
748 if (u.l == 0)
749 FMOVDX(r0, XZR_REGNO);
750 else {
751 reg = jit_get_reg(jit_class_gpr);
752 movi(rn(reg), u.l);
753 FMOVDX(r0, rn(reg));
754 jit_unget_reg(reg);
755 }
756}
757
758static void
759_dccr(jit_state_t *_jit, jit_int32_t cc,
760 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
761{
762 FCMPED(r1, r2);
763 CSET(r0, cc);
764}
765
766static void
767_dcci(jit_state_t *_jit, jit_int32_t cc,
768 jit_int32_t r0, jit_int32_t r1, jit_float64_t i0)
769{
770 jit_int32_t reg;
771 reg = jit_get_reg(jit_class_fpr);
772 movi_d(rn(reg), i0);
773 dccr(cc, r0, r1, rn(reg));
774 jit_unget_reg(reg);
775}
776
777static void
778_uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
779{
780 jit_word_t w;
781 FCMPED(r1, r2);
782 CSET(r0, CC_VS);
783 w = _jit->pc.w;
784 B_C(BCC_VS, 1); /* unordered satisfies condition */
785 CSET(r0, CC_EQ); /* equal satisfies condition */
786 patch_at(w, _jit->pc.w);
787}
788dopi(uneq)
789
790static void
791_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
792{
793 jit_word_t w;
794 FCMPED(r1, r2);
795 CSET(r0, CC_VC); /* set to 1 if ordered */
796 w = _jit->pc.w;
797 B_C(BCC_VS, 1); /* unordered does not satisfy condition */
798 CSET(r0, CC_NE); /* set to 1 if not equal */
799 patch_at(w, _jit->pc.w);
800}
801dopi(ltgt)
802
803static jit_word_t
804_dbccr(jit_state_t *_jit, jit_int32_t cc,
805 jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
806{
807 jit_word_t w, d;
808 FCMPED(r0, r1);
809 w = _jit->pc.w;
810 d = (i0 - w) >> 2;
811 B_C(cc, d);
812 return (w);
813}
814
815static jit_word_t
816_dbcci(jit_state_t *_jit, jit_int32_t cc,
817 jit_word_t i0, jit_int32_t r0, jit_float64_t i1)
818{
819 jit_word_t w;
820 jit_int32_t reg;
821 reg = jit_get_reg(jit_class_fpr|jit_class_nospill);
822 movi_d(rn(reg), i1);
823 w = dbccr(cc, i0, r0, rn(reg));
824 jit_unget_reg(reg);
825 return (w);
826}
827
828static jit_word_t
829_buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
830{
831 jit_word_t u, v, w;
832 FCMPED(r0, r1);
833 u = _jit->pc.w;
834 B_C(BCC_VS, 1); /* unordered satisfies condition */
835 v = _jit->pc.w;
836 B_C(BCC_NE, 1); /* not equal (or unordered) does not satisfy */
837 patch_at(u, _jit->pc.w);
838 w = _jit->pc.w;
839 B((i0 - w) >> 2);
840 patch_at(v, _jit->pc.w);
841 return (w);
842}
843dbopi(uneq)
844
845static jit_word_t
846_bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
847{
848 jit_word_t u, v, w;
849 FCMPED(r0, r1);
850 u = _jit->pc.w;
851 B_C(BCC_VS, 2); /* jump over if unordered */
852 v = _jit->pc.w;
853 B_C(BCC_EQ, 1); /* jump over if equal */
854 w = _jit->pc.w;
855 B((i0 - w) >> 2);
856 patch_at(u, _jit->pc.w);
857 patch_at(v, _jit->pc.w);
858 return (w);
859}
860dbopi(ltgt)
861
862static void
863_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
864{
865 jit_word_t ge_code;
866 jit_word_t lt_code;
867 jit_int32_t rg0, rg1;
868
869 assert(_jitc->function->self.call & jit_call_varargs);
870
871 rg0 = jit_get_reg(jit_class_gpr);
872 rg1 = jit_get_reg(jit_class_gpr);
873
874 /* Load the fp offset in save area in the first temporary. */
875 ldxi_i(rn(rg0), r1, offsetof(jit_va_list_t, fpoff));
876
877 /* Jump over if there are no remaining arguments in the save area. */
878 ge_code = bgei(_jit->pc.w, rn(rg0), 0);
879
880 /* Load the gp save pointer in the second temporary. */
881 ldxi(rn(rg1), r1, offsetof(jit_va_list_t, fptop));
882
883 /* Load the vararg argument in the first argument. */
884 ldxr_d(r0, rn(rg1), rn(rg0));
885
886 /* Update the fp offset. */
887 addi(rn(rg0), rn(rg0), 16);
888 stxi_i(offsetof(jit_va_list_t, fpoff), r1, rn(rg0));
889
890 /* Will only need one temporary register below. */
891 jit_unget_reg(rg1);
892
893 /* Jump over overflow code. */
894 lt_code = jmpi_p(_jit->pc.w);
895
896 /* Where to land if argument is in overflow area. */
897 patch_at(ge_code, _jit->pc.w);
898
899 /* Load stack pointer. */
900 ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack));
901
902 /* Load argument. */
903 ldr_d(r0, rn(rg0));
904
905 /* Update stack pointer. */
906 addi(rn(rg0), rn(rg0), 8);
907 stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0));
908
909 /* Where to land if argument is in gp save area. */
910 patch_at(lt_code, _jit->pc.w);
911
912 jit_unget_reg(rg0);
913}
914#endif