d0e7e813060ce42b7f932433f1c02a0c11a5daf7
[pcsx_rearmed.git] / deps / lightning / lib / jit_sparc-fpu.c
1 /*
2  * Copyright (C) 2013-2023  Free Software Foundation, Inc.
3  *
4  * This file is part of GNU lightning.
5  *
6  * GNU lightning is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * GNU lightning is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14  * License for more details.
15  *
16  * Authors:
17  *      Paulo Cesar Pereira de Andrade
18  */
19
20 #if PROTO
21 #  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)
94 static 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)
171 static 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)
180 static 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)
183 static 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)
189 static 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)
196 static void _movr_f(jit_state_t*, jit_int32_t, jit_int32_t);
197 #  endif
198 static 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)
205 static void _negr_f(jit_state_t*, jit_int32_t, jit_int32_t);
206 #    define absr_f(r0, r1)              _absr_f(_jit, r0, r1)
207 static void _absr_f(jit_state_t*, jit_int32_t, jit_int32_t);
208 #    define sqrtr_f(r0, r1)             _sqrtr_f(_jit, r0, r1)
209 static 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)
212 static 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)
214 static 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)
217 static 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)
223 static 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)
226 static 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)
229 static void _movr_d(jit_state_t*, jit_int32_t, jit_int32_t);
230 #  define negr_d(r0, r1)                _negr_d(_jit, r0, r1)
231 static void _negr_d(jit_state_t*, jit_int32_t, jit_int32_t);
232 #  define absr_d(r0, r1)                _absr_d(_jit, r0, r1)
233 static 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)
241 static 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)
244 static 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)
247 static 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)
250 static 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)
259 static 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)
285 static 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)
287 static 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)
318 static 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)
320 static 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)
354 static 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)
357 static 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)
362 static 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)
365 static 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)
370 static 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)
373 static 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)
378 static 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)
381 static 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)
384 static 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)
387 static 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)
390 static 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)
393 static 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)
395 static 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)
398 static 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)
429 static 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)
432 static 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)
463 static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t);
464 #endif
465
466 #if CODE
467 static 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
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)
517 static 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
539 static 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 {
548                 t1 = get_sng_reg(r0);
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)) {
556                 t0 = get_sng_reg(r0);
557                 FMOVS(r1, rn(t0));
558                 movr_d(r0, rn(t0));
559                 jit_unget_reg(t0);
560             }
561             else {
562                 t1 = get_sng_reg(r0);
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
572 static 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
603 static 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
634 static 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
667 static 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
683 static 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
705 static 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
720 static 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
754 static 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
765 static 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
775 static 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)                                      \
788 static void                                                             \
789 NAME(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
842 static 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
898 static 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
943 static 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
988 static 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
999 static 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
1010 static 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
1032 static 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
1051 static 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
1070 static 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
1107 static 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
1138 static 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
1148 static 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
1163 static 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
1178 static 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
1203 static 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
1218 static 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
1243 static 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
1258 static 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
1283 static 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
1298 static 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
1322 static 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
1337 static 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
1356 static 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
1368 static 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
1382 static 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
1396 static 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
1410 static 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
1424 static 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
1465 static 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
1498 static 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
1510 static 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
1526 static 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. */
1532 #if __WORDSIZE == 64
1533     ldr_d(r0, r1);
1534 #else
1535     ldr_f(r0, r1);
1536     ldxi_f(r0 + 1, r1, 4);
1537 #endif
1538
1539     /* Update vararg stack pointer. */
1540     addi(r1, r1, 8);
1541 }
1542 #endif