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