update libchdr
[pcsx_rearmed.git] / deps / lightning / lib / jit_sparc-fpu.c
CommitLineData
4a71579b 1/*
79bfeef6 2 * Copyright (C) 2013-2023 Free Software Foundation, Inc.
4a71579b
PC
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# if __WORDSIZE == 32
22# define FPR(r) (r)
23# define CLASS_SNG jit_class_fpr
24# define CLASS_DBL jit_class_fpr
25# else
26# define single_precision_p(r) ((r) >= 0 && (r) <= 31)
27# define FPR(r) ((r) > 31 ? (r) - 31 : (r))
28# define CLASS_SNG (jit_class_fpr | jit_class_sng)
29# define CLASS_DBL (jit_class_fpr | jit_class_dbl)
30# endif
31# define LDF(rs1, rs2, rd) f3r(3, FPR(rd), 32, FPR(rs1), FPR(rs2))
32# define LDFI(rs1, imm, rd) f3i(3, FPR(rd), 32, FPR(rs1), imm)
33# define LDDF(rs1, rs2, rd) f3r(3, FPR(rd), 35, FPR(rs1), FPR(rs2))
34# define LDDFI(rs1, imm, rd) f3i(3, FPR(rd), 35, FPR(rs1), imm)
35# define LDFSR(rs1, rs2, rd) f3r(3, FPR(rd), 33, FPR(rs1), FPR(rs2))
36# define LDFSRI(rs1, imm, rd) f3i(3, FPR(rd), 33, FPR(rs1), imm)
37# define STF(rd, rs1, rs2) f3r(3, FPR(rd), 36, FPR(rs1), FPR(rs2))
38# define STFI(rd, rs1, imm) f3i(3, FPR(rd), 36, FPR(rs1), imm)
39# define STDF(rd, rs1, rs2) f3r(3, FPR(rd), 39, FPR(rs1), FPR(rs2))
40# define STDFI(rd, rs1, imm) f3i(3, FPR(rd), 39, FPR(rs1), imm)
41# define STFSR(rd, rs1, rs2) f3r(3, FPR(rd), 37, FPR(rs1), FPR(rs2))
42# define STFSRI(rd, rs1, imm) f3i(3, FPR(rd), 37, FPR(rs1), imm)
43# define STDFQ(rd, rs1, rs2) f3r(3, FPR(rd), 38, FPR(rs1), FPR(rs2))
44# define STFDFQ(rd, rs1, imm) f3i(3, FPR(rd), 38, FPR(rs1), imm)
45# define SPARC_FBA 8 /* always - 1 */
46# define SPARC_FBN 0 /* never - 0 */
47# define SPARC_FBU 7 /* unordered - U */
48# define SPARC_FBG 6 /* greater - G */
49# define SPARC_FBUG 5 /* unordered or greater - G or U */
50# define SPARC_FBL 4 /* less - L */
51# define SPARC_FBUL 3 /* unordered or less - L or U */
52# define SPARC_FBLG 2 /* less or greater - L or G */
53# define SPARC_FBNE 1 /* not equal - L or G or U */
54# define SPARC_FBNZ SPARC_FBNE
55# define SPARC_FBE 9 /* equal - E */
56# define SPARC_FBZ SPARC_FBE
57# define SPARC_FBUE 10 /* unordered or equal - E or U */
58# define SPARC_FBGE 11 /* greater or equal - E or G */
59# define SPARC_FBUGE 12 /* unordered or greater or equal - E or G or U */
60# define SPARC_FBLE 13 /* less or equal - E or L */
61# define SPARC_FBULE 14 /* unordered or less or equal - E or L or U */
62# define SPARC_FBO 15 /* ordered - E or L or G */
63# define FB(cc, imm) f2b(0, 0, cc, 6, imm)
64# define FBa(cc, imm) f2b(0, 1, cc, 6, imm)
65# define FBA(imm) FB(SPARC_FBA, imm)
66# define FBAa(imm) FBa(SPARC_FBA, imm)
67# define FBN(imm) FB(SPARC_FBN, imm)
68# define FBNa(imm) FBa(SPARC_FBN, imm)
69# define FBU(imm) FB(SPARC_FBU, imm)
70# define FBUa(imm) FBa(SPARC_FBU, imm)
71# define FBG(imm) FB(SPARC_FBG, imm)
72# define FBGa(imm) FBa(SPARC_FBG, imm)
73# define FBUG(imm) FB(SPARC_FBUG, imm)
74# define FBUGa(imm) FBa(SPARC_FBUG, imm)
75# define FBL(imm) FB(SPARC_FBL, imm)
76# define FBLa(imm) FBa(SPARC_FBL, imm)
77# define FBUL(imm) FB(SPARC_FBUL, imm)
78# define FBULa(imm) FBa(SPARC_FBUL, imm)
79# define FBLG(imm) FB(SPARC_FBLG, imm)
80# define FBLGa(imm) FBa(SPARC_FBLG, imm)
81# define FBNE(imm) FB(SPARC_FBNE, imm)
82# define FBNEa(imm) FBa(SPARC_FBNE, imm)
83# define FBE(imm) FB(SPARC_FBE, imm)
84# define FBEa(imm) FBa(SPARC_FBE, imm)
85# define FBUE(imm) FB(SPARC_FBUE, imm)
86# define FBUEa(imm) FBa(SPARC_FBUE, imm)
87# define FBLE(imm) FB(SPARC_FBLE, imm)
88# define FBLEa(imm) FBa(SPARC_FBLE, imm)
89# define FBO(imm) FB(SPARC_FBO, imm)
90# define FBOa(imm) FBa(SPARC_FBO, imm)
91# define FPop1(rd, rs1, opf, rs2) f3f(rd, 52, rs1, opf, rs2)
92# define FPop2(rd, rs1, opf, rs2) f3f(rd, 53, rs1, opf, rs2)
93# define f3f(rd, op3, rs1, opf, rs2) _f3f(_jit, rd, op3, rs1, opf, rs2)
94static void
95_f3f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t, jit_int32_t,jit_int32_t);
96# define FITOS(rs2, rd) FPop1(rd, 0, 196, rs2)
97# define FITOD(rs2, rd) FPop1(rd, 0, 200, rs2)
98# define FITOQ(rs2, rd) FPop1(rd, 0, 204, rs2)
99# if __WORDSIZE == 64
100# define FXTOS(rs2, rd) FPop1(rd, 0, 132, rs2)
101# define FXTOD(rs2, rd) FPop1(rd, 0, 136, rs2)
102# define FxTOQ(rs2, rd) FPop1(rd, 0, 140, rs2)
103# endif
104# define FSTOI(rs2, rd) FPop1(rd, 0, 209, rs2)
105# define FDTOI(rs2, rd) FPop1(rd, 0, 210, rs2)
106# define FQTOI(rs2, rd) FPop1(rd, 0, 211, rs2)
107# define FSTOX(rs2, rd) FPop1(rd, 0, 129, rs2)
108# define FDTOX(rs2, rd) FPop1(rd, 0, 130, rs2)
109# define FQTOX(rs2, rd) FPop1(rd, 0, 131, rs2)
110# define FSTOD(rs2, rd) FPop1(rd, 0, 201, rs2)
111# define FSTOQ(rs2, rd) FPop1(rd, 0, 205, rs2)
112# define FDTOS(rs2, rd) FPop1(rd, 0, 198, rs2)
113# define FDTOQ(rs2, rd) FPop1(rd, 0, 206, rs2)
114# define FQTOS(rs2, rd) FPop1(rd, 0, 199, rs2)
115# define FQTOD(rs2, rd) FPop1(rd, 0, 203, rs2)
116# define FMOVS(rs2, rd) FPop1(rd, 0, 1, rs2)
117# define FMOVD(rs2, rd) FPop1(rd, 0, 2, rs2)
118# define FMOVQ(rs2, rd) FPop1(rd, 0, 3, rs2)
119# define FNEGS(rs2, rd) FPop1(rd, 0, 5, rs2)
120# define FNEGD(rs2, rd) FPop1(rd, 0, 6, rs2)
121# define FNEGQ(rs2, rd) FPop1(rd, 0, 7, rs2)
122# define FABSS(rs2, rd) FPop1(rd, 0, 9, rs2)
123# define FABSD(rs2, rd) FPop1(rd, 0, 10, rs2)
124# define FABSQ(rs2, rd) FPop1(rd, 0, 11, rs2)
125# define FSQRTS(rs2, rd) FPop1(rd, 0, 41, rs2)
126# define FSQRTD(rs2, rd) FPop1(rd, 0, 42, rs2)
127# define FSQRTQ(rs2, rd) FPop1(rd, 0, 43, rs2)
128# define SPARC_FADDS 65
129# define SPARC_FADDD 66
130# define SPARC_FADDQ 67
131# define SPARC_FSUBS 69
132# define SPARC_FSUBD 70
133# define SPARC_FSUBQ 71
134# define SPARC_FMULS 73
135# define SPARC_FMULD 74
136# define SPARC_FMULQ 75
137# define SPARC_FSMULD 105
138# define SPARC_FDMULQ 110
139# define SPARC_FDIVS 77
140# define SPARC_FDIVD 78
141# define SPARC_FDIVQ 79
142# define FADDS(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FADDS, rs2)
143# define FADDD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FADDD, rs2)
144# define FADDQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FADDQ, rs2)
145# define FSUBS(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FSUBS, rs2)
146# define FSUBD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FSUBD, rs2)
147# define FSUBQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FSUBQ, rs2)
148# define FMULS(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FMULS, rs2)
149# define FMULD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FMULD, rs2)
150# define FMULQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FMULQ, rs2)
151# define FSMULD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FSMULD, rs2)
152# define FDMULQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FDMULQ, rs2)
153# define FDIVS(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FDIVS, rs2)
154# define FDIVD(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FDIVD, rs2)
155# define FDIVQ(rs1, rs2, rd) FPop1(rd, rs1, SPARC_FDIVQ, rs2)
156# define SPARC_FCMPS 81
157# define SPARC_FCMPD 82
158# define SPARC_FCMPQ 83
159# define SPARC_FCMPES 85
160# define SPARC_FCMPED 86
161# define SPARC_FCMPEQ 87
162# define FCMPS(rs1, rs2) FPop2(0, rs1, SPARC_FCMPS, rs2)
163# define FCMPD(rs1, rs2) FPop2(0, rs1, SPARC_FCMPD, rs2)
164# define FCMPQ(rs1, rs2) FPop2(0, rs1, SPARC_FCMPQ, rs2)
165# define FCMPES(rs1, rs2) FPop2(0, rs1, SPARC_FCMPES, rs2)
166# define FCMPED(rs1, rs2) FPop2(0, rs1, SPARC_FCMPED, rs2)
167# define FCMPEQ(rs1, rs2) FPop2(0, rs1, SPARC_FCMPEQ, rs2)
168# define CPop1(rd, rs1, opc, rs2) f3f(rd, 54, rs1, opf, rs2)
169# define CPop2(rd, rs1, opc, rs2) f3f(rd, 55, rs1, opf, rs2)
170# define extr_f(r0, r1) _extr_f(_jit, r0, r1)
171static void _extr_f(jit_state_t*, jit_int32_t, jit_int32_t);
172# if __WORDSIZSE == 32
173# define truncr_f(r0, r1) truncr_f_i(r0, r1)
174# define truncr_d(r0, r1) truncr_d_i(r0, r1)
175# else
176# define truncr_f(r0, r1) truncr_f_l(r0, r1)
177# define truncr_d(r0, r1) truncr_d_l(r0, r1)
178# endif
179# define truncr_f_i(r0, r1) _truncr_f_i(_jit, r0, r1)
180static void _truncr_f_i(jit_state_t*, jit_int32_t, jit_int32_t);
181# if __WORDSIZE == 64
182# define truncr_f_l(r0, r1) _truncr_f_l(_jit, r0, r1)
183static void _truncr_f_l(jit_state_t*, jit_int32_t, jit_int32_t);
184# endif
185# if __WORDSIZE == 32
186# define extr_d_f(r0, r1) FDTOS(r1, r0)
187# else
188# define extr_d_f(r0, r1) _extr_d_f(_jit, r0, r1)
189static void _extr_d_f(jit_state_t*, jit_int32_t, jit_int32_t);
190# endif
191# define movi_f(r0, i0) _movi_f(_jit, r0, i0)
192# if __WORDSIZE == 32
193# define movr_f(r0, r1) FMOVS(r1, r0)
194# else
195# define movr_f(r0, r1) _movr_f(_jit, r0, r1)
196static void _movr_f(jit_state_t*, jit_int32_t, jit_int32_t);
197# endif
198static void _movi_f(jit_state_t*, jit_int32_t, jit_float32_t*);
199# if __WORDSIZE == 32
200# define negr_f(r0, r1) FNEGS(r1, r0)
201# define absr_f(r0, r1) FABSS(r1, r0)
202# define sqrtr_f(r0, r1) FSQRTS(r1, r0)
203# else
204# define negr_f(r0, r1) _negr_f(_jit, r0, r1)
205static void _negr_f(jit_state_t*, jit_int32_t, jit_int32_t);
206# define absr_f(r0, r1) _absr_f(_jit, r0, r1)
207static void _absr_f(jit_state_t*, jit_int32_t, jit_int32_t);
208# define sqrtr_f(r0, r1) _sqrtr_f(_jit, r0, r1)
209static void _sqrtr_f(jit_state_t*, jit_int32_t, jit_int32_t);
210# endif
211# define extr_d(r0, r1) _extr_d(_jit, r0, r1)
212static void _extr_d(jit_state_t*, jit_int32_t, jit_int32_t);
213# define truncr_d_i(r0, r1) _truncr_d_i(_jit, r0, r1)
214static void _truncr_d_i(jit_state_t*, jit_int32_t, jit_int32_t);
215# if __WORDSIZE == 64
216# define truncr_d_l(r0, r1) _truncr_d_l(_jit, r0, r1)
217static void _truncr_d_l(jit_state_t*, jit_int32_t, jit_int32_t);
218# endif
219# if __WORDSIZE == 32
220# define extr_f_d(r0, r1) FSTOD(r1, r0)
221# else
222# define extr_f_d(r0, r1) _extr_f_d(_jit, r0, r1)
223static void _extr_f_d(jit_state_t*, jit_int32_t, jit_int32_t);
224# endif
225# define movi_d(r0, i0) _movi_d(_jit, r0, i0)
226static void _movi_d(jit_state_t*, jit_int32_t, jit_float64_t*);
227# if __WORDSIZE == 32
228# define movr_d(r0, r1) _movr_d(_jit, r0, r1)
229static void _movr_d(jit_state_t*, jit_int32_t, jit_int32_t);
230# define negr_d(r0, r1) _negr_d(_jit, r0, r1)
231static void _negr_d(jit_state_t*, jit_int32_t, jit_int32_t);
232# define absr_d(r0, r1) _absr_d(_jit, r0, r1)
233static void _absr_d(jit_state_t*, jit_int32_t, jit_int32_t);
234# else
235# define movr_d(r0, r1) FMOVD(r1, r0)
236# define negr_d(r0, r1) FNEGD(r1, r0)
237# define absr_d(r0, r1) FABSD(r1, r0)
238# endif
239# define sqrtr_d(r0, r1) FSQRTD(r1, r0)
240# define fop1f(op, r0, r1, i0) _fop1f(_jit, op, r0, r1, i0)
241static void _fop1f(jit_state_t*,jit_int32_t,
242 jit_int32_t,jit_int32_t,jit_float32_t*);
243# define rfop1f(op, r0, r1, i0) _rfop1f(_jit, op, r0, r1, i0)
244static void _rfop1f(jit_state_t*,jit_int32_t,
245 jit_int32_t,jit_int32_t,jit_float32_t*);
246# define fop1d(op, r0, r1, i0) _fop1d(_jit, op, r0, r1, i0)
247static void _fop1d(jit_state_t*,jit_int32_t,
248 jit_int32_t,jit_int32_t,jit_float64_t*);
249# define rfop1d(op, r0, r1, i0) _rfop1d(_jit, op, r0, r1, i0)
250static void _rfop1d(jit_state_t*,jit_int32_t,
251 jit_int32_t,jit_int32_t,jit_float64_t*);
252# if __WORDSIZE == 32
253# define addr_f(r0, r1, r2) FADDS(r1, r2, r0)
254# define subr_f(r0, r1, r2) FSUBS(r1, r2, r0)
255# define mulr_f(r0, r1, r2) FMULS(r1, r2, r0)
256# define divr_f(r0, r1, r2) FDIVS(r1, r2, r0)
257# else
258# define fop2f(op, r0, r1, r2) _fop2f(_jit, op, r0, r1, r2)
259static void _fop2f(jit_state_t*, jit_int32_t,
260 jit_int32_t, jit_int32_t, jit_int32_t);
261# define addr_f(r0, r1, r2) fop2f(SPARC_FADDS, r0, r1, r2)
262# define subr_f(r0, r1, r2) fop2f(SPARC_FSUBS, r0, r1, r2)
263# define mulr_f(r0, r1, r2) fop2f(SPARC_FMULS, r0, r1, r2)
264# define divr_f(r0, r1, r2) fop2f(SPARC_FDIVS, r0, r1, r2)
265# endif
266# define addi_f(r0, r1, i0) fop1f(SPARC_FADDS, r0, r1, i0)
267# define subi_f(r0, r1, i0) fop1f(SPARC_FSUBS, r0, r1, i0)
268# define rsbr_f(r0, r1, r2) subr_f(r0, r2, r1)
269# define rsbi_f(r0, r1, i0) rfop1f(SPARC_FSUBS, r0, r1, i0)
270# define rsbr_d(r0, r1, r2) subr_d(r0, r2, r1)
271# define rsbi_d(r0, r1, i0) rfop1d(SPARC_FSUBD, r0, r1, i0)
272# define muli_f(r0, r1, i0) fop1f(SPARC_FMULS, r0, r1, i0)
273# define divi_f(r0, r1, i0) fop1f(SPARC_FDIVS, r0, r1, i0)
274# define addr_d(r0, r1, r2) FADDD(r1, r2, r0)
275# define addi_d(r0, r1, i0) fop1d(SPARC_FADDD, r0, r1, i0)
276# define subr_d(r0, r1, r2) FSUBD(r1, r2, r0)
277# define subi_d(r0, r1, i0) fop1d(SPARC_FSUBD, r0, r1, i0)
278# define rsbr_d(r0, r1, r2) subr_d(r0, r2, r1)
279# define rsbi_d(r0, r1, i0) rfop1d(SPARC_FSUBD, r0, r1, i0)
280# define mulr_d(r0, r1, r2) FMULD(r1, r2, r0)
281# define muli_d(r0, r1, i0) fop1d(SPARC_FMULD, r0, r1, i0)
282# define divr_d(r0, r1, r2) FDIVD(r1, r2, r0)
283# define divi_d(r0, r1, i0) fop1d(SPARC_FDIVD, r0, r1, i0)
284#define fcr(cc, r0, r1, r2) _fcr(_jit, cc, r0, r1, r2)
285static void _fcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
286#define fcw(cc, r0, r1, i0) _fcw(_jit, cc, r0, r1, i0)
287static void
288_fcw(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_float32_t*);
289# define ltr_f(r0, r1, r2) fcr(SPARC_FBL, r0, r1, r2)
290# define lti_f(r0, r1, i0) fcw(SPARC_FBL, r0, r1, i0)
291# define ler_f(r0, r1, r2) fcr(SPARC_FBLE, r0, r1, r2)
292# define lei_f(r0, r1, i0) fcw(SPARC_FBLE, r0, r1, i0)
293# define eqr_f(r0, r1, r2) fcr(SPARC_FBE, r0, r1, r2)
294# define eqi_f(r0, r1, i0) fcw(SPARC_FBE, r0, r1, i0)
295# define ger_f(r0, r1, r2) fcr(SPARC_FBGE, r0, r1, r2)
296# define gei_f(r0, r1, i0) fcw(SPARC_FBGE, r0, r1, i0)
297# define gtr_f(r0, r1, r2) fcr(SPARC_FBG, r0, r1, r2)
298# define gti_f(r0, r1, i0) fcw(SPARC_FBG, r0, r1, i0)
299# define ner_f(r0, r1, r2) fcr(SPARC_FBNE, r0, r1, r2)
300# define nei_f(r0, r1, i0) fcw(SPARC_FBNE, r0, r1, i0)
301# define unltr_f(r0, r1, r2) fcr(SPARC_FBUL, r0, r1, r2)
302# define unlti_f(r0, r1, i0) fcw(SPARC_FBUL, r0, r1, i0)
303# define unler_f(r0, r1, r2) fcr(SPARC_FBULE, r0, r1, r2)
304# define unlei_f(r0, r1, i0) fcw(SPARC_FBULE, r0, r1, i0)
305# define uneqr_f(r0, r1, r2) fcr(SPARC_FBUE, r0, r1, r2)
306# define uneqi_f(r0, r1, i0) fcw(SPARC_FBUE, r0, r1, i0)
307# define unger_f(r0, r1, r2) fcr(SPARC_FBUGE, r0, r1, r2)
308# define ungei_f(r0, r1, i0) fcw(SPARC_FBUGE, r0, r1, i0)
309# define ungtr_f(r0, r1, r2) fcr(SPARC_FBUG, r0, r1, r2)
310# define ungti_f(r0, r1, i0) fcw(SPARC_FBUG, r0, r1, i0)
311# define ltgtr_f(r0, r1, r2) fcr(SPARC_FBLG, r0, r1, r2)
312# define ltgti_f(r0, r1, i0) fcw(SPARC_FBLG, r0, r1, i0)
313# define ordr_f(r0, r1, r2) fcr(SPARC_FBO, r0, r1, r2)
314# define ordi_f(r0, r1, i0) fcw(SPARC_FBO, r0, r1, i0)
315# define unordr_f(r0, r1, r2) fcr(SPARC_FBU, r0, r1, r2)
316# define unordi_f(r0, r1, i0) fcw(SPARC_FBU, r0, r1, i0)
317#define dcr(cc, r0, r1, r2) _dcr(_jit, cc, r0, r1, r2)
318static void _dcr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
319#define dcw(cc, r0, r1, i0) _dcw(_jit, cc, r0, r1, i0)
320static void
321_dcw(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_float64_t*);
322# define ltr_d(r0, r1, r2) dcr(SPARC_FBL, r0, r1, r2)
323# define lti_d(r0, r1, i0) dcw(SPARC_FBL, r0, r1, i0)
324# define ler_d(r0, r1, r2) dcr(SPARC_FBLE, r0, r1, r2)
325# define lei_d(r0, r1, i0) dcw(SPARC_FBLE, r0, r1, i0)
326# define eqr_d(r0, r1, r2) dcr(SPARC_FBE, r0, r1, r2)
327# define eqi_d(r0, r1, i0) dcw(SPARC_FBE, r0, r1, i0)
328# define ger_d(r0, r1, r2) dcr(SPARC_FBGE, r0, r1, r2)
329# define gei_d(r0, r1, i0) dcw(SPARC_FBGE, r0, r1, i0)
330# define gtr_d(r0, r1, r2) dcr(SPARC_FBG, r0, r1, r2)
331# define gti_d(r0, r1, i0) dcw(SPARC_FBG, r0, r1, i0)
332# define ner_d(r0, r1, r2) dcr(SPARC_FBNE, r0, r1, r2)
333# define nei_d(r0, r1, i0) dcw(SPARC_FBNE, r0, r1, i0)
334# define unltr_d(r0, r1, r2) dcr(SPARC_FBUL, r0, r1, r2)
335# define unlti_d(r0, r1, i0) dcw(SPARC_FBUL, r0, r1, i0)
336# define unler_d(r0, r1, r2) dcr(SPARC_FBULE, r0, r1, r2)
337# define unlei_d(r0, r1, i0) dcw(SPARC_FBULE, r0, r1, i0)
338# define uneqr_d(r0, r1, r2) dcr(SPARC_FBUE, r0, r1, r2)
339# define uneqi_d(r0, r1, i0) dcw(SPARC_FBUE, r0, r1, i0)
340# define unger_d(r0, r1, r2) dcr(SPARC_FBUGE, r0, r1, r2)
341# define ungei_d(r0, r1, i0) dcw(SPARC_FBUGE, r0, r1, i0)
342# define ungtr_d(r0, r1, r2) dcr(SPARC_FBUG, r0, r1, r2)
343# define ungti_d(r0, r1, i0) dcw(SPARC_FBUG, r0, r1, i0)
344# define ltgtr_d(r0, r1, r2) dcr(SPARC_FBLG, r0, r1, r2)
345# define ltgti_d(r0, r1, i0) dcw(SPARC_FBLG, r0, r1, i0)
346# define ordr_d(r0, r1, r2) dcr(SPARC_FBO, r0, r1, r2)
347# define ordi_d(r0, r1, i0) dcw(SPARC_FBO, r0, r1, i0)
348# define unordr_d(r0, r1, r2) dcr(SPARC_FBU, r0, r1, r2)
349# define unordi_d(r0, r1, i0) dcw(SPARC_FBU, r0, r1, i0)
350# if __WORDSIZE == 32
351# define ldr_f(r0, r1) LDF(r1, 0, r0)
352# else
353# define ldr_f(r0, r1) _ldr_f(_jit, r0, r1)
354static void _ldr_f(jit_state_t*,jit_int32_t,jit_int32_t);
355# endif
356# define ldi_f(r0, i0) _ldi_f(_jit, r0, i0)
357static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t);
358# if __WORDSIZE == 32
359# define ldxr_f(r0, r1, r2) LDF(r1, r2, r0)
360# else
361# define ldxr_f(r0, r1, r2) _ldxr_f(_jit, r0, r1, r2)
362static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
363# endif
364# define ldxi_f(r0, r1, i0) _ldxi_f(_jit, r0, r1, i0)
365static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
366# if __WORDSIZE == 32
367# define str_f(r0, r1) STF(r1, r0, 0)
368# else
369# define str_f(r0, r1) _str_f(_jit, r0, r1)
370static void _str_f(jit_state_t*,jit_int32_t,jit_int32_t);
371# endif
372# define sti_f(r0, i0) _sti_f(_jit, r0, i0)
373static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t);
374# if __WORDSIZE == 32
375# define stxr_f(r0, r1, r2) STF(r2, r1, r0)
376# else
377# define stxr_f(r0, r1, r2) _stxr_f(_jit, r0, r1, r2)
378static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
379# endif
380# define stxi_f(r0, r1, i0) _stxi_f(_jit, r0, r1, i0)
381static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
382# define ldr_d(r0, r1) LDDF(r1, 0, r0)
383# define ldi_d(r0, i0) _ldi_d(_jit, r0, i0)
384static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t);
385# define ldxr_d(r0, r1, r2) LDDF(r1, r2, r0)
386# define ldxi_d(r0, r1, i0) _ldxi_d(_jit, r0, r1, i0)
387static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
388# define str_d(r0, r1) STDF(r1, r0, 0)
389# define sti_d(r0, i0) _sti_d(_jit, r0, i0)
390static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t);
391# define stxr_d(r0, r1, r2) STDF(r2, r1, r0)
392# define stxi_d(r0, r1, i0) _stxi_d(_jit, r0, r1, i0)
393static void _stxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
394# define fbr(cc, i0, r0, r1) _fbr(_jit, cc, i0, r0, r1)
395static jit_word_t
396_fbr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
397# define fbw(cc, i0, r0, i1) _fbw(_jit, cc, i0, r0, i1)
398static jit_word_t
399_fbw(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float32_t*);
400# define bltr_f(i0, r0, r1) fbr(SPARC_FBL, i0, r0, r1)
401# define blti_f(i0, r0, i1) fbw(SPARC_FBL, i0, r0, i1)
402# define bler_f(i0, r0, r1) fbr(SPARC_FBLE, i0, r0, r1)
403# define blei_f(i0, r0, i1) fbw(SPARC_FBLE, i0, r0, i1)
404# define beqr_f(i0, r0, r1) fbr(SPARC_FBE, i0, r0, r1)
405# define beqi_f(i0, r0, i1) fbw(SPARC_FBE, i0, r0, i1)
406# define bger_f(i0, r0, r1) fbr(SPARC_FBGE, i0, r0, r1)
407# define bgei_f(i0, r0, i1) fbw(SPARC_FBGE, i0, r0, i1)
408# define bgtr_f(i0, r0, r1) fbr(SPARC_FBG, i0, r0, r1)
409# define bgti_f(i0, r0, i1) fbw(SPARC_FBG, i0, r0, i1)
410# define bner_f(i0, r0, r1) fbr(SPARC_FBNE, i0, r0, r1)
411# define bnei_f(i0, r0, i1) fbw(SPARC_FBNE, i0, r0, i1)
412# define bunltr_f(i0, r0, r1) fbr(SPARC_FBUL, i0, r0, r1)
413# define bunlti_f(i0, r0, i1) fbw(SPARC_FBUL, i0, r0, i1)
414# define bunler_f(i0, r0, r1) fbr(SPARC_FBULE, i0, r0, r1)
415# define bunlei_f(i0, r0, i1) fbw(SPARC_FBULE, i0, r0, i1)
416# define buneqr_f(i0, r0, r1) fbr(SPARC_FBUE, i0, r0, r1)
417# define buneqi_f(i0, r0, i1) fbw(SPARC_FBUE, i0, r0, i1)
418# define bunger_f(i0, r0, r1) fbr(SPARC_FBUGE, i0, r0, r1)
419# define bungei_f(i0, r0, i1) fbw(SPARC_FBUGE, i0, r0, i1)
420# define bungtr_f(i0, r0, r1) fbr(SPARC_FBUG, i0, r0, r1)
421# define bungti_f(i0, r0, i1) fbw(SPARC_FBUG, i0, r0, i1)
422# define bltgtr_f(i0, r0, r1) fbr(SPARC_FBLG, i0, r0, r1)
423# define bltgti_f(i0, r0, i1) fbw(SPARC_FBLG, i0, r0, i1)
424# define bordr_f(i0, r0, r1) fbr(SPARC_FBO, i0, r0, r1)
425# define bordi_f(i0, r0, i1) fbw(SPARC_FBO, i0, r0, i1)
426# define bunordr_f(i0, r0, r1) fbr(SPARC_FBU, i0, r0, r1)
427# define bunordi_f(i0, r0, i1) fbw(SPARC_FBU, i0, r0, i1)
428# define dbr(cc, i0, r0, r1) _dbr(_jit, cc, i0, r0, r1)
429static jit_word_t
430_dbr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
431# define dbw(cc, i0, r0, i1) _dbw(_jit, cc, i0, r0, i1)
432static jit_word_t
433_dbw(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float64_t*);
434# define bltr_d(i0, r0, r1) dbr(SPARC_FBL, i0, r0, r1)
435# define blti_d(i0, r0, i1) dbw(SPARC_FBL, i0, r0, i1)
436# define bler_d(i0, r0, r1) dbr(SPARC_FBLE, i0, r0, r1)
437# define blei_d(i0, r0, i1) dbw(SPARC_FBLE, i0, r0, i1)
438# define beqr_d(i0, r0, r1) dbr(SPARC_FBE, i0, r0, r1)
439# define beqi_d(i0, r0, i1) dbw(SPARC_FBE, i0, r0, i1)
440# define bger_d(i0, r0, r1) dbr(SPARC_FBGE, i0, r0, r1)
441# define bgei_d(i0, r0, i1) dbw(SPARC_FBGE, i0, r0, i1)
442# define bgtr_d(i0, r0, r1) dbr(SPARC_FBG, i0, r0, r1)
443# define bgti_d(i0, r0, i1) dbw(SPARC_FBG, i0, r0, i1)
444# define bner_d(i0, r0, r1) dbr(SPARC_FBNE, i0, r0, r1)
445# define bnei_d(i0, r0, i1) dbw(SPARC_FBNE, i0, r0, i1)
446# define bunltr_d(i0, r0, r1) dbr(SPARC_FBUL, i0, r0, r1)
447# define bunlti_d(i0, r0, i1) dbw(SPARC_FBUL, i0, r0, i1)
448# define bunler_d(i0, r0, r1) dbr(SPARC_FBULE, i0, r0, r1)
449# define bunlei_d(i0, r0, i1) dbw(SPARC_FBULE, i0, r0, i1)
450# define buneqr_d(i0, r0, r1) dbr(SPARC_FBUE, i0, r0, r1)
451# define buneqi_d(i0, r0, i1) dbw(SPARC_FBUE, i0, r0, i1)
452# define bunger_d(i0, r0, r1) dbr(SPARC_FBUGE, i0, r0, r1)
453# define bungei_d(i0, r0, i1) dbw(SPARC_FBUGE, i0, r0, i1)
454# define bungtr_d(i0, r0, r1) dbr(SPARC_FBUG, i0, r0, r1)
455# define bungti_d(i0, r0, i1) dbw(SPARC_FBUG, i0, r0, i1)
456# define bltgtr_d(i0, r0, r1) dbr(SPARC_FBLG, i0, r0, r1)
457# define bltgti_d(i0, r0, i1) dbw(SPARC_FBLG, i0, r0, i1)
458# define bordr_d(i0, r0, r1) dbr(SPARC_FBO, i0, r0, r1)
459# define bordi_d(i0, r0, i1) dbw(SPARC_FBO, i0, r0, i1)
460# define bunordr_d(i0, r0, r1) dbr(SPARC_FBU, i0, r0, r1)
461# define bunordi_d(i0, r0, i1) dbw(SPARC_FBU, i0, r0, i1)
462# define vaarg_d(r0, r1) _vaarg_d(_jit, r0, r1)
463static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t);
464#endif
465
466#if CODE
467static void
468_f3f(jit_state_t *_jit, jit_int32_t rd,
469 jit_int32_t op3, jit_int32_t rs1, jit_int32_t opf, jit_int32_t rs2)
470{
471 jit_instr_t v;
472# if __WORDSIZE == 64
473 if (rd > 31) {
474 assert(rd <= 63 && (rd & 1) == 0);
475 rd -= 31;
476 }
477 if (rs1 > 31) {
478 assert(rs1 <= 63 && (rs1 & 1) == 0);
479 rs1 -= 31;
480 }
481 if (rs2 > 31) {
482 assert(rs2 <= 63 && (rs2 & 1) == 0);
483 rs2 -= 31;
484 }
485# endif
486 assert(!(rd & 0xffffffe0));
487 assert(!(op3 & 0xffffffc0));
488 assert(!(rs1 & 0xffffffe0));
489 assert(!(opf & 0xfffffe00));
490 assert(!(rs2 & 0xffffffe0));
491 v.op.b = 2;
492 v.rd.b = rd;
493 v.op3.b = op3;
494 v.rs1.b = rs1;
495 v.opf.b = opf;
496 v.rs2.b = rs2;
497 ii(v.v);
498}
499
500# if __WORDSIZE == 64
79bfeef6
PC
501/* Handle the special case of using all float registers, as exercised
502 * in check/carg.c.
503 * For example:
504 * putargr_f JIT_F0 $ARG
505 * where JIT_F0 is %f32 and $ARG is %f31 and if %f30 (the mapping for %f31)
506 * is live, the jit_get_reg() call might return %f30, but, because it is
507 * live, will spill/reload it, generating assembly:
508 *
509 * std %f30, [ %fp + OFFS ]
510 * fmovd %f32, %f30
511 * fmovs %f30, %f31
512 * ldd [ %fp + OFFS ], %f30
513 *
514 * what basically becomes a noop as it restores the old value.
515 */
516#define get_sng_reg(u) _get_sng_reg(_jit, u)
517static jit_int32_t
518_get_sng_reg(jit_state_t *_jit, jit_int32_t r0)
519{
520 jit_int32_t reg, tmp;
521 /* Attempt to get a nospill register */
522 reg = jit_get_reg(CLASS_SNG | jit_class_nospill | jit_class_chk);
523 if (reg == JIT_NOREG) {
524 /* Will need to spill, so allow spilling it. */
525 reg = jit_get_reg(CLASS_SNG);
526 /* If the special condition happens, allocate another one.
527 * This will generate uglier machine code (code for floats
528 * is already ugly), but will work, but doing a double
529 * spill/reload; the first one being a noop. */
530 if (rn(reg) == r0 - 1) {
531 tmp = reg;
532 reg = jit_get_reg(CLASS_SNG);
533 jit_unget_reg(tmp);
534 }
535 }
536 return (reg);
537}
538
4a71579b
PC
539static void
540_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
541{
542 jit_int32_t t0, t1;
543 if (r0 != r1) {
544 if (single_precision_p(r0)) {
545 if (single_precision_p(r1))
546 FMOVS(r1, r0);
547 else {
79bfeef6 548 t1 = get_sng_reg(r0);
4a71579b
PC
549 movr_d(rn(t1), r1);
550 FMOVS(rn(t1), r0);
551 jit_unget_reg(t1);
552 }
553 }
554 else {
555 if (single_precision_p(r1)) {
79bfeef6 556 t0 = get_sng_reg(r0);
4a71579b
PC
557 FMOVS(r1, rn(t0));
558 movr_d(r0, rn(t0));
559 jit_unget_reg(t0);
560 }
561 else {
79bfeef6 562 t1 = get_sng_reg(r0);
4a71579b
PC
563 movr_d(rn(t1), r1);
564 FMOVS(rn(t1), rn(t1));
565 movr_d(r0, rn(t1));
566 jit_unget_reg(t1);
567 }
568 }
569 }
570}
571
572static void
573_negr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
574{
575 jit_int32_t t0, t1;
576 if (single_precision_p(r0)) {
577 if (single_precision_p(r1))
578 FNEGS(r1, r0);
579 else {
580 t1 = jit_get_reg(CLASS_SNG);
581 movr_d(rn(t1), r1);
582 FNEGS(rn(t1), r0);
583 jit_unget_reg(t1);
584 }
585 }
586 else {
587 if (single_precision_p(r1)) {
588 t0 = jit_get_reg(CLASS_SNG);
589 FNEGS(r1, rn(t0));
590 movr_d(r0, rn(t0));
591 jit_unget_reg(t0);
592 }
593 else {
594 t1 = jit_get_reg(CLASS_SNG);
595 movr_d(rn(t1), r1);
596 FNEGS(rn(t1), rn(t1));
597 movr_d(r0, rn(t1));
598 jit_unget_reg(t1);
599 }
600 }
601}
602
603static void
604_absr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
605{
606 jit_int32_t t0, t1;
607 if (single_precision_p(r0)) {
608 if (single_precision_p(r1))
609 FABSS(r1, r0);
610 else {
611 t1 = jit_get_reg(CLASS_SNG);
612 movr_d(rn(t1), r1);
613 FABSS(rn(t1), r0);
614 jit_unget_reg(t1);
615 }
616 }
617 else {
618 if (single_precision_p(r1)) {
619 t0 = jit_get_reg(CLASS_SNG);
620 FABSS(r1, rn(t0));
621 movr_d(r0, rn(t0));
622 jit_unget_reg(t0);
623 }
624 else {
625 t1 = jit_get_reg(CLASS_SNG);
626 movr_d(rn(t1), r1);
627 FABSS(rn(t1), rn(t1));
628 movr_d(r0, rn(t1));
629 jit_unget_reg(t1);
630 }
631 }
632}
633
634static void
635_sqrtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
636{
637 jit_int32_t t0, t1;
638 if (single_precision_p(r0)) {
639 if (single_precision_p(r1))
640 FSQRTS(r1, r0);
641 else {
642 t1 = jit_get_reg(CLASS_SNG);
643 movr_d(rn(t1), r1);
644 FSQRTS(rn(t1), r0);
645 jit_unget_reg(t1);
646 }
647 }
648 else {
649 if (single_precision_p(r1)) {
650 t0 = jit_get_reg(CLASS_SNG);
651 FSQRTS(r1, rn(t0));
652 movr_d(r0, rn(t0));
653 jit_unget_reg(t0);
654 }
655 else {
656 t1 = jit_get_reg(CLASS_SNG);
657 movr_d(rn(t1), r1);
658 FSQRTS(rn(t1), rn(t1));
659 movr_d(r0, rn(t1));
660 jit_unget_reg(t1);
661 }
662 }
663}
664# endif
665
666# if __WORDSIZE == 64
667static void
668_extr_d_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
669{
670 jit_int32_t reg;
671 if (!single_precision_p(r0)) {
672 reg = jit_get_reg(CLASS_SNG);
673 movr_d(rn(reg), r0);
674 FDTOS(r1, rn(reg));
675 movr_d(r0, rn(reg));
676 jit_unget_reg(reg);
677 }
678 else
679 FDTOS(r1, r0);
680}
681# endif
682
683static void
684_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0)
685{
686 union {
687 jit_int32_t i;
688 jit_float32_t f;
689 } data;
690 jit_int32_t reg;
691
692 if (_jitc->no_data) {
693 data.f = *i0;
694 reg = jit_get_reg(jit_class_gpr);
695 movi(rn(reg), data.i & 0xffffffff);
696 stxi_i(BIAS(-8), _FP_REGNO, rn(reg));
697 jit_unget_reg(reg);
698 ldxi_f(r0, _FP_REGNO, BIAS(-8));
699 }
700 else
701 ldi_f(r0, (jit_word_t)i0);
702}
703
704# if __WORDSIZE == 64
705static void
706_extr_f_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
707{
708 jit_int32_t reg;
709 if (!single_precision_p(r1)) {
710 reg = jit_get_reg(CLASS_SNG);
711 movr_d(rn(reg), r1);
712 FSTOD(rn(reg), r0);
713 jit_unget_reg(reg);
714 }
715 else
716 FSTOD(r1, r0);
717}
718# endif
719
720static void
721_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
722{
723 union {
724# if __WORDSIZE == 32
725 jit_int32_t i[2];
726# else
727 jit_word_t w;
728# endif
729 jit_float64_t d;
730 } data;
731 jit_int32_t reg;
732
733 if (_jitc->no_data) {
734 data.d = *i0;
735 reg = jit_get_reg(jit_class_gpr);
736# if __WORDSIZE == 32
737 movi(rn(reg), data.i[0]);
738# else
739 movi(rn(reg), data.w);
740# endif
741 stxi(BIAS(-8), _FP_REGNO, rn(reg));
742# if __WORDSIZE == 32
743 movi(rn(reg), data.i[1]);
744 stxi_i(BIAS(-4), _FP_REGNO, rn(reg));
745# endif
746 jit_unget_reg(reg);
747 ldxi_d(r0, _FP_REGNO, BIAS(-8));
748 }
749 else
750 ldi_d(r0, (jit_word_t)i0);
751}
752
753# if __WORDSIZE == 32
754static void
755_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
756{
757 assert(!(r0 & 1));
758 assert(!(r1 & 1));
759 if (r0 != r1) {
760 FMOVS(r1, r0);
761 FMOVS(r1 + 1, r0 + 1);
762 }
763}
764
765static void
766_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
767{
768 assert(!(r0 & 1));
769 assert(!(r1 & 1));
770 FNEGS(r1, r0);
771 if (r0 != r1)
772 FMOVS(r1 + 1, r0 + 1);
773}
774
775static void
776_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
777{
778 assert(!(r0 & 1));
779 assert(!(r1 & 1));
780 FABSS(r1, r0);
781 if (r0 != r1)
782 FMOVS(r1 + 1, r0 + 1);
783}
784# endif
785
786# if __WORDSIZE == 64
787# define single_rrr(NAME, CODE) \
788static void \
789NAME(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) \
790{ \
791 jit_int32_t x0, t0, x1, t1, x2, t2, mask = 0; \
792 if (!single_precision_p(r0)) { \
793 mask |= 1; \
794 t0 = jit_get_reg(CLASS_SNG); \
795 x0 = rn(t0); \
796 if (r0 == r1) { \
797 x1 = x0; \
798 movr_d(x1, r1); \
799 if (r0 == r2) \
800 x2 = x0; \
801 } \
802 else if (r0 == r2) { \
803 x2 = x0; \
804 movr_d(x2, r2); \
805 } \
806 } \
807 else \
808 x0 = r0; \
809 if (!single_precision_p(r1)) { \
810 if (r0 != r1) { \
811 mask |= 2; \
812 t1 = jit_get_reg(CLASS_SNG); \
813 x1 = rn(t1); \
814 movr_d(x1, r1); \
815 if (r1 == r2) \
816 x2 = x1; \
817 } \
818 } \
819 else \
820 x1 = r1; \
821 if (!single_precision_p(r2)) { \
822 if (r0 != r2 && r1 != r2) { \
823 mask |= 4; \
824 t2 = jit_get_reg(CLASS_SNG); \
825 x2 = rn(t2); \
826 movr_d(x2, r2); \
827 } \
828 } \
829 else \
830 x2 = r2; \
831 CODE(x1, x2, x0); \
832 if (mask & 1) { \
833 movr_d(r0, x0); \
834 jit_unget_reg(t0); \
835 } \
836 if (mask & 2) \
837 jit_unget_reg(t1); \
838 if (mask & 4) \
839 jit_unget_reg(t2); \
840}
841
842static void
843_fop2f(jit_state_t *_jit, jit_int32_t op,
844 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
845{
846 jit_int32_t x0, t0, x1, t1, x2, t2, mask = 0;
847 if (!single_precision_p(r0)) {
848 mask |= 1;
849 t0 = jit_get_reg(CLASS_SNG);
850 x0 = rn(t0);
851 if (r0 == r1) {
852 x1 = x0;
853 movr_d(x1, r1);
854 if (r0 == r2)
855 x2 = x0;
856 }
857 else if (r0 == r2) {
858 x2 = x0;
859 movr_d(x2, r2);
860 }
861 }
862 else
863 x0 = r0;
864 if (!single_precision_p(r1)) {
865 if (r0 != r1) {
866 mask |= 2;
867 t1 = jit_get_reg(CLASS_SNG);
868 x1 = rn(t1);
869 movr_d(x1, r1);
870 if (r1 == r2)
871 x2 = x1;
872 }
873 }
874 else
875 x1 = r1;
876 if (!single_precision_p(r2)) {
877 if (r0 != r2 && r1 != r2) {
878 mask |= 4;
879 t2 = jit_get_reg(CLASS_SNG);
880 x2 = rn(t2);
881 movr_d(x2, r2);
882 }
883 }
884 else
885 x2 = r2;
886 FPop1(x0, x1, op, x2);
887 if (mask & 1) {
888 movr_d(r0, x0);
889 jit_unget_reg(t0);
890 }
891 if (mask & 2)
892 jit_unget_reg(t1);
893 if (mask & 4)
894 jit_unget_reg(t2);
895}
896# endif
897
898static void
899_fop1f(jit_state_t *_jit, jit_int32_t op,
900 jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0)
901{
902 jit_int32_t reg;
903# if __WORDSIZE == 64
904 jit_int32_t x0, t0, x1, t1, mask = 0;
905# endif
906 reg = jit_get_reg(CLASS_SNG);
907 movi_f(rn(reg), i0);
908# if __WORDSIZE == 64
909 if (!single_precision_p(r0)) {
910 mask |= 1;
911 t0 = jit_get_reg(CLASS_SNG);
912 x0 = rn(t0);
913 if (r0 == r1) {
914 x1 = x0;
915 movr_d(x1, r1);
916 }
917 }
918 else
919 x0 = r0;
920 if (!single_precision_p(r1)) {
921 if (r0 != r1) {
922 mask |= 2;
923 t1 = jit_get_reg(CLASS_SNG);
924 x1 = rn(t1);
925 movr_d(x1, r1);
926 }
927 }
928 else
929 x1 = r1;
930 FPop1(x0, x1, op, rn(reg));
931 if (mask & 1) {
932 movr_d(r0, x0);
933 jit_unget_reg(t0);
934 }
935 if (mask & 2)
936 jit_unget_reg(t1);
937# else
938 FPop1(r0, r1, op, rn(reg));
939# endif
940 jit_unget_reg(reg);
941}
942
943static void
944_rfop1f(jit_state_t *_jit, jit_int32_t op,
945 jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0)
946{
947 jit_int32_t reg;
948# if __WORDSIZE == 64
949 jit_int32_t x0, t0, x1, t1, mask = 0;
950# endif
951 reg = jit_get_reg(CLASS_SNG);
952 movi_f(rn(reg), i0);
953# if __WORDSIZE == 64
954 if (!single_precision_p(r0)) {
955 mask |= 1;
956 t0 = jit_get_reg(CLASS_SNG);
957 x0 = rn(t0);
958 if (r0 == r1) {
959 x1 = x0;
960 movr_d(x1, r1);
961 }
962 }
963 else
964 x0 = r0;
965 if (!single_precision_p(r1)) {
966 if (r0 != r1) {
967 mask |= 2;
968 t1 = jit_get_reg(CLASS_SNG);
969 x1 = rn(t1);
970 movr_d(x1, r1);
971 }
972 }
973 else
974 x1 = r1;
975 FPop1(x0, rn(reg), op, x1);
976 if (mask & 1) {
977 movr_d(r0, x0);
978 jit_unget_reg(t0);
979 }
980 if (mask & 2)
981 jit_unget_reg(t1);
982# else
983 FPop1(r0, rn(reg), op, r1);
984# endif
985 jit_unget_reg(reg);
986}
987
988static void
989_fop1d(jit_state_t *_jit, jit_int32_t op,
990 jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0)
991{
992 jit_int32_t reg;
993 reg = jit_get_reg(CLASS_DBL);
994 movi_d(rn(reg), i0);
995 FPop1(r0, r1, op, rn(reg));
996 jit_unget_reg(reg);
997}
998
999static void
1000_rfop1d(jit_state_t *_jit, jit_int32_t op,
1001 jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0)
1002{
1003 jit_int32_t reg;
1004 reg = jit_get_reg(CLASS_DBL);
1005 movi_d(rn(reg), i0);
1006 FPop1(r0, rn(reg), op, r1);
1007 jit_unget_reg(reg);
1008}
1009
1010static void
1011_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1012{
1013 stxi(BIAS(-8), _FP_REGNO, r1);
1014# if __WORDSIZE == 32
1015 ldxi_f(r0, _FP_REGNO, BIAS(-8));
1016 FITOS(r0, r0);
1017# else
1018 ldxi_d(r0, _FP_REGNO, BIAS(-8));
1019 if (!single_precision_p(r0)) {
1020 jit_int32_t reg;
1021 reg = jit_get_reg(CLASS_SNG);
1022 movr_d(rn(reg), r0);
1023 FXTOS(rn(reg), rn(reg));
1024 movr_d(r0, rn(reg));
1025 jit_unget_reg(reg);
1026 }
1027 else
1028 FXTOS(r0, r0);
1029# endif
1030}
1031
1032static void
1033_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1034{
1035 jit_int32_t reg;
1036 reg = jit_get_reg(CLASS_SNG);
1037# if __WORDSIZE == 64
1038 if (!single_precision_p(r1)) {
1039 movr_d(rn(reg), r1);
1040 FSTOI(rn(reg), rn(reg));
1041 }
1042 else
1043# endif
1044 FSTOI(r1, rn(reg));
1045 stxi_f(BIAS(-8), _FP_REGNO, rn(reg));
1046 ldxi_i(r0, _FP_REGNO, BIAS(-8));
1047 jit_unget_reg(reg);
1048}
1049
1050# if __WORDSIZE == 64
1051static void
1052_truncr_f_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1053{
1054 jit_int32_t reg;
1055 reg = jit_get_reg(CLASS_SNG);
1056# if __WORDSIZE == 64
1057 if (!single_precision_p(r1)) {
1058 movr_d(rn(reg), r1);
1059 FSTOX(rn(reg), rn(reg));
1060 }
1061 else
1062# endif
1063 FSTOX(r1, rn(reg));
1064 stxi_d(BIAS(-8), _FP_REGNO, rn(reg));
1065 ldxi_l(r0, _FP_REGNO, BIAS(-8));
1066 jit_unget_reg(reg);
1067}
1068# endif
1069
1070static void
1071_fcr(jit_state_t *_jit, jit_int32_t cc,
1072 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1073{
1074# if __WORDSIZE == 64
1075 jit_int32_t x0, t0, x1, t1, mask = 0;
1076 if (!single_precision_p(r1)) {
1077 mask |= 1;
1078 t0 = jit_get_reg(CLASS_SNG);
1079 x0 = rn(t0);
1080 movr_d(x0, r1);
1081 }
1082 else
1083 x0 = r1;
1084 if (r1 == r2)
1085 x1 = x0;
1086 else if (!single_precision_p(r2)) {
1087 mask |= 2;
1088 t1 = jit_get_reg(CLASS_SNG);
1089 x1 = rn(t1);
1090 movr_d(x1, r2);
1091 }
1092 else
1093 x1 = r2;
1094 FCMPS(x0, x1);
1095 if (mask & 1)
1096 jit_unget_reg(t0);
1097 if (mask & 2)
1098 jit_unget_reg(t1);
1099# else
1100 FCMPS(r1, r2);
1101# endif
1102 FBa(cc, 3);
1103 movi(r0, 1);
1104 movi(r0, 0);
1105}
1106
1107static void
1108_fcw(jit_state_t *_jit, jit_int32_t cc,
1109 jit_int32_t r0, jit_int32_t r1, jit_float32_t *i0)
1110{
1111 jit_int32_t reg;
1112# if __WORDSIZE == 64
1113 jit_int32_t x0, t0, mask = 0;
1114 if (!single_precision_p(r1)) {
1115 mask |= 1;
1116 t0 = jit_get_reg(CLASS_SNG);
1117 x0 = rn(t0);
1118 movr_d(x0, r1);
1119 }
1120 else
1121 x0 = r1;
1122# endif
1123 reg = jit_get_reg(CLASS_SNG);
1124 movi_f(rn(reg), i0);
1125# if __WORDSIZE == 64
1126 FCMPS(x0, rn(reg));
1127 if (mask & 1)
1128 jit_unget_reg(t0);
1129# else
1130 FCMPS(r1, rn(reg));
1131# endif
1132 jit_unget_reg(reg);
1133 FBa(cc, 3);
1134 movi(r0, 1);
1135 movi(r0, 0);
1136}
1137
1138static void
1139_dcr(jit_state_t *_jit, jit_int32_t cc,
1140 jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1141{
1142 FCMPD(r1, r2);
1143 FBa(cc, 3);
1144 movi(r0, 1);
1145 movi(r0, 0);
1146}
1147
1148static void
1149_dcw(jit_state_t *_jit, jit_int32_t cc,
1150 jit_int32_t r0, jit_int32_t r1, jit_float64_t *i0)
1151{
1152 jit_int32_t reg;
1153 reg = jit_get_reg(CLASS_DBL);
1154 movi_d(rn(reg), i0);
1155 FCMPD(r1, rn(reg));
1156 jit_unget_reg(reg);
1157 FBa(cc, 3);
1158 movi(r0, 1);
1159 movi(r0, 0);
1160}
1161
1162# if __WORDSIZE == 64
1163static void
1164_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1165{
1166 jit_int32_t reg;
1167 if (!single_precision_p(r0)) {
1168 reg = jit_get_reg(CLASS_SNG);
1169 LDF(r1, 0, rn(reg));
1170 movr_d(r0, rn(reg));
1171 jit_unget_reg(reg);
1172 }
1173 else
1174 LDF(r1, 0, r0);
1175}
1176# endif
1177
1178static void
1179_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1180{
1181 jit_int32_t reg;
1182 if (s13_p(i0)) {
1183# if __WORDSIZE == 64
1184 if (!single_precision_p(r0)) {
1185 reg = jit_get_reg(CLASS_SNG);
1186 LDFI(0, i0, rn(reg));
1187 movr_d(r0, rn(reg));
1188 jit_unget_reg(reg);
1189 }
1190 else
1191# endif
1192 LDFI(0, i0, r0);
1193 }
1194 else {
1195 reg = jit_get_reg(jit_class_gpr);
1196 movi(rn(reg), i0);
1197 ldr_f(r0, rn(reg));
1198 jit_unget_reg(reg);
1199 }
1200}
1201
1202# if __WORDSIZE == 64
1203static void
1204_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1205{
1206 jit_int32_t reg;
1207 if (!single_precision_p(r0)) {
1208 reg = jit_get_reg(CLASS_SNG);
1209 LDF(r1, r2, rn(reg));
1210 movr_d(r0, rn(reg));
1211 jit_unget_reg(reg);
1212 }
1213 else
1214 LDF(r1, r2, r0);
1215}
1216# endif
1217
1218static void
1219_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1220{
1221 jit_int32_t reg;
1222 if (s13_p(i0)) {
1223# if __WORDSIZE == 64
1224 if (!single_precision_p(r0)) {
1225 reg = jit_get_reg(CLASS_SNG);
1226 LDFI(r1, i0, rn(reg));
1227 movr_d(r0, rn(reg));
1228 jit_unget_reg(reg);
1229 }
1230 else
1231# endif
1232 LDFI(r1, i0, r0);
1233 }
1234 else {
1235 reg = jit_get_reg(jit_class_gpr);
1236 movi(rn(reg), i0);
1237 ldxr_f(r0, r1, rn(reg));
1238 jit_unget_reg(reg);
1239 }
1240}
1241
1242# if __WORDSIZE == 64
1243static void
1244_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1245{
1246 jit_int32_t reg;
1247 if (!single_precision_p(r1)) {
1248 reg = jit_get_reg(CLASS_SNG);
1249 movr_d(rn(reg), r1);
1250 STF(rn(reg), r0, 0);
1251 jit_unget_reg(reg);
1252 }
1253 else
1254 STF(r1, r0, 0);
1255}
1256# endif
1257
1258static void
1259_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1260{
1261 jit_int32_t reg;
1262 if (s13_p(i0)) {
1263# if __WORDSIZE == 64
1264 if (!single_precision_p(r0)) {
1265 reg = jit_get_reg(CLASS_SNG);
1266 movr_d(rn(reg), r0);
1267 STFI(rn(reg), 0, i0);
1268 jit_unget_reg(reg);
1269 }
1270 else
1271# endif
1272 STFI(r0, 0, i0);
1273 }
1274 else {
1275 reg = jit_get_reg(jit_class_gpr);
1276 movi(rn(reg), i0);
1277 str_f(rn(reg), r0);
1278 jit_unget_reg(reg);
1279 }
1280}
1281
1282# if __WORDSIZE == 64
1283static void
1284_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1285{
1286 jit_int32_t reg;
1287 if (!single_precision_p(r2)) {
1288 reg = jit_get_reg(CLASS_SNG);
1289 movr_d(rn(reg), r2);
1290 STF(rn(reg), r1, r0);
1291 jit_unget_reg(reg);
1292 }
1293 else
1294 STF(r2, r1, r0);
1295}
1296# endif
1297
1298static void
1299_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1300{
1301 jit_int32_t reg;
1302 if (s13_p(i0)) {
1303# if __WORDSIZE == 64
1304 if (!single_precision_p(r1)) {
1305 reg = jit_get_reg(CLASS_SNG);
1306 movr_d(rn(reg), r1);
1307 STFI(rn(reg), r0, i0);
1308 jit_unget_reg(reg);
1309 }
1310 else
1311# endif
1312 STFI(r1, r0, i0);
1313 }
1314 else {
1315 reg = jit_get_reg(jit_class_gpr);
1316 movi(rn(reg), i0);
1317 stxr_f(rn(reg), r0, r1);
1318 jit_unget_reg(reg);
1319 }
1320}
1321
1322static void
1323_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1324{
1325 stxi(BIAS(-8), _FP_REGNO, r1);
1326# if __WORDSIZE == 32
1327 stxi(BIAS(-4), _FP_REGNO, 0);
1328# endif
1329 ldxi_d(r0, _FP_REGNO, BIAS(-8));
1330# if __WORDSIZE == 32
1331 FITOD(r0, r0);
1332# else
1333 FXTOD(r0, r0);
1334# endif
1335}
1336
1337static void
1338_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1339{
1340 jit_int32_t reg;
1341 reg = jit_get_reg(CLASS_SNG);
1342# if __WORDSIZE == 64
1343 if (!single_precision_p(r1)) {
1344 movr_d(rn(reg), r1);
1345 FDTOI(rn(reg), rn(reg));
1346 }
1347 else
1348# endif
1349 FDTOI(r1, rn(reg));
1350 stxi_d(BIAS(-8), _FP_REGNO, rn(reg));
1351 ldxi_i(r0, _FP_REGNO, BIAS(-8));
1352 jit_unget_reg(reg);
1353}
1354
1355# if __WORDSIZE == 64
1356static void
1357_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1358{
1359 jit_int32_t reg;
1360 reg = jit_get_reg(CLASS_DBL);
1361 FDTOX(r1, rn(reg));
1362 stxi_d(BIAS(-8), _FP_REGNO, rn(reg));
1363 ldxi_l(r0, _FP_REGNO, BIAS(-8));
1364 jit_unget_reg(reg);
1365}
1366# endif
1367
1368static void
1369_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1370{
1371 jit_int32_t reg;
1372 if (s13_p(i0))
1373 LDDFI(0, i0, r0);
1374 else {
1375 reg = jit_get_reg(jit_class_gpr);
1376 movi(rn(reg), i0);
1377 ldr_d(r0, rn(reg));
1378 jit_unget_reg(reg);
1379 }
1380}
1381
1382static void
1383_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t i0)
1384{
1385 jit_int32_t reg;
1386 if (s13_p(i0))
1387 LDDFI(r1, i0, r0);
1388 else {
1389 reg = jit_get_reg(jit_class_gpr);
1390 movi(rn(reg), i0);
1391 ldxr_d(r0, r1, rn(reg));
1392 jit_unget_reg(reg);
1393 }
1394}
1395
1396static void
1397_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1398{
1399 jit_int32_t reg;
1400 if (s13_p(i0))
1401 STDFI(r0, 0, i0);
1402 else {
1403 reg = jit_get_reg(jit_class_gpr);
1404 movi(rn(reg), i0);
1405 str_d(rn(reg), r0);
1406 jit_unget_reg(reg);
1407 }
1408}
1409
1410static void
1411_stxi_d(jit_state_t *_jit, jit_int32_t i0, jit_int32_t r0, jit_int32_t r1)
1412{
1413 jit_int32_t reg;
1414 if (s13_p(i0))
1415 STDFI(r1, r0, i0);
1416 else {
1417 reg = jit_get_reg(jit_class_gpr);
1418 movi(rn(reg), i0);
1419 stxr_d(rn(reg), r0, r1);
1420 jit_unget_reg(reg);
1421 }
1422}
1423
1424static jit_word_t
1425_fbr(jit_state_t *_jit, jit_int32_t cc,
1426 jit_word_t i0, jit_int32_t r0,jit_int32_t r1)
1427{
1428# if __WORDSIZE == 64
1429 jit_int32_t x0, t0, x1, t1, mask = 0;
1430# endif
1431 jit_word_t w;
1432# if __WORDSIZE == 64
1433 if (!single_precision_p(r0)) {
1434 mask |= 1;
1435 t0 = jit_get_reg(CLASS_SNG);
1436 x0 = rn(t0);
1437 movr_d(x0, r0);
1438 }
1439 else
1440 x0 = r0;
1441 if (r0 == r1)
1442 x1 = x0;
1443 else if (!single_precision_p(r1)) {
1444 mask |= 2;
1445 t1 = jit_get_reg(CLASS_SNG);
1446 x1 = rn(t1);
1447 movr_d(x1, r1);
1448 }
1449 else
1450 x1 = r1;
1451 FCMPS(x0, x1);
1452 if (mask & 1)
1453 jit_unget_reg(t0);
1454 if (mask & 2)
1455 jit_unget_reg(t1);
1456# else
1457 FCMPS(r0, r1);
1458# endif
1459 w = _jit->pc.w;
1460 FB(cc, (i0 - w) >> 2);
1461 NOP();
1462 return (w);
1463}
1464
1465static jit_word_t
1466_fbw(jit_state_t *_jit, jit_int32_t cc,
1467 jit_word_t i0, jit_int32_t r0, jit_float32_t *i1)
1468{
1469 jit_word_t w;
1470 jit_int32_t reg;
1471# if __WORDSIZE == 64
1472 jit_int32_t x0, t0, mask = 0;
1473 if (!single_precision_p(r0)) {
1474 mask |= 1;
1475 t0 = jit_get_reg(CLASS_SNG);
1476 x0 = rn(t0);
1477 movr_d(x0, r0);
1478 }
1479 else
1480 x0 = r0;
1481# endif
1482 reg = jit_get_reg(CLASS_SNG);
1483 movi_f(rn(reg), i1);
1484# if __WORDSIZE == 64
1485 FCMPS(x0, rn(reg));
1486 if (mask & 1)
1487 jit_unget_reg(t0);
1488# else
1489 FCMPS(r0, rn(reg));
1490# endif
1491 jit_unget_reg(reg);
1492 w = _jit->pc.w;
1493 FB(cc, (i0 - w) >> 2);
1494 NOP();
1495 return (w);
1496}
1497
1498static jit_word_t
1499_dbr(jit_state_t *_jit, jit_int32_t cc,
1500 jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1501{
1502 jit_word_t w;
1503 FCMPD(r0, r1);
1504 w = _jit->pc.w;
1505 FB(cc, (i0 - w) >> 2);
1506 NOP();
1507 return (w);
1508}
1509
1510static jit_word_t
1511_dbw(jit_state_t *_jit, jit_int32_t cc,
1512 jit_word_t i0, jit_int32_t r0, jit_float64_t *i1)
1513{
1514 jit_word_t w;
1515 jit_int32_t reg;
1516 reg = jit_get_reg(CLASS_DBL);
1517 movi_d(rn(reg), i1);
1518 FCMPD(r0, rn(reg));
1519 jit_unget_reg(reg);
1520 w = _jit->pc.w;
1521 FB(cc, (i0 - w) >> 2);
1522 NOP();
1523 return (w);
1524}
1525
1526static void
1527_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1528{
1529 assert(_jitc->function->self.call & jit_call_varargs);
1530
1531 /* Load argument. */
79bfeef6 1532#if __WORDSIZE == 64
4a71579b 1533 ldr_d(r0, r1);
79bfeef6
PC
1534#else
1535 ldr_f(r0, r1);
1536 ldxi_f(r0 + 1, r1, 4);
1537#endif
4a71579b
PC
1538
1539 /* Update vararg stack pointer. */
1540 addi(r1, r1, 8);
1541}
1542#endif