git subrepo pull (merge) --force deps/lightning
[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 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)
98 static 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);
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
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)
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)
192 static 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)
195 #    define truncr_d(r0, r1)            truncr_d_i(r0, r1)
196 #  else
197 #    define truncr_f(r0, r1)            truncr_f_l(r0, r1)
198 #    define truncr_d(r0, r1)            truncr_d_l(r0, r1)
199 #  endif
200 #  define truncr_f_i(r0, r1)            _truncr_f_i(_jit, r0, r1)
201 static 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)
204 static 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)
210 static 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)
217 static void _movr_f(jit_state_t*, jit_int32_t, jit_int32_t);
218 #  endif
219 static void _movi_f(jit_state_t*, jit_int32_t, jit_float32_t*);
220 #  define movi_w_f(r0, i0)              _movi_w_f(_jit, r0, i0)
221 static void _movi_w_f(jit_state_t*, jit_int32_t, jit_word_t);
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)
228 static void _negr_f(jit_state_t*, jit_int32_t, jit_int32_t);
229 #    define absr_f(r0, r1)              _absr_f(_jit, r0, r1)
230 static void _absr_f(jit_state_t*, jit_int32_t, jit_int32_t);
231 #    define sqrtr_f(r0, r1)             _sqrtr_f(_jit, r0, r1)
232 static void _sqrtr_f(jit_state_t*, jit_int32_t, jit_int32_t);
233 #  endif
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)
245 static 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
256 #  define extr_d(r0, r1)                _extr_d(_jit, r0, r1)
257 static 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)
259 static 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)
262 static 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)
268 static 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)
271 static void _movi_d(jit_state_t*, jit_int32_t, jit_float64_t*);
272 #  if __WORDSIZE == 32
273 #    define movi_ww_d(r0, i0, i1)       _movi_ww_d(_jit, r0, i0, i1)
274 static 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)
276 static void _movr_d(jit_state_t*, jit_int32_t, jit_int32_t);
277 #    define negr_d(r0, r1)              _negr_d(_jit, r0, r1)
278 static void _negr_d(jit_state_t*, jit_int32_t, jit_int32_t);
279 #    define absr_d(r0, r1)              _absr_d(_jit, r0, r1)
280 static void _absr_d(jit_state_t*, jit_int32_t, jit_int32_t);
281 #  else
282 #    define movr_d(r0, r1)              FMOVD(r1, r0)
283 #    define movi_w_d(r0, i0)            _movi_w_d(_jit, r0, i0)
284 static void _movi_w_d(jit_state_t*, jit_int32_t, jit_word_t);
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)
290 static 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)
293 static 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)
296 static 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)
299 static 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)
308 static 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)
334 static 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)
336 static 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)
367 static 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)
369 static 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)
403 static 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)
406 static 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)
411 static 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)
414 static 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)
419 static 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)
422 static 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)
427 static 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)
430 static 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)
433 static 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)
436 static 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)
439 static 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)
442 static 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)
444 static 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)
447 static 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)
478 static 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)
481 static 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)
512 static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t);
513 #endif
514
515 #if CODE
516 static 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
549 static 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
588 #  if __WORDSIZE == 64
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)
605 static 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
627 static 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 {
636                 t1 = get_sng_reg(r0);
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)) {
644                 t0 = get_sng_reg(r0);
645                 FMOVS(r1, rn(t0));
646                 movr_d(r0, rn(t0));
647                 jit_unget_reg(t0);
648             }
649             else {
650                 t1 = get_sng_reg(r0);
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
660 static 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
691 static 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
722 static 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
755 static 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
771 static 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
792 static 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
802 #  if __WORDSIZE == 64
803 static 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
818 static 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
852 static 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
865 static 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
876 static 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
886 static 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 }
895 #  else
896 static 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 }
905 #  endif
906
907 #  if __WORDSIZE == 64
908 #    define single_rrr(NAME, CODE)                                      \
909 static void                                                             \
910 NAME(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
963 static 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 }
1017
1018 static 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 }
1094 #  endif
1095
1096 static 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
1141 static 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
1186 static 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
1197 static 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
1208 static 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
1230 static 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
1249 static 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
1268 static 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
1305 static 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
1336 static 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
1346 static 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
1361 static 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
1376 static 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
1401 static 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
1416 static 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
1441 static 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
1456 static 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
1481 static 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
1496 static 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
1520 static 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
1535 static 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
1554 static 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
1566 static 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
1580 static 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
1594 static 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
1608 static 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
1622 static 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
1663 static 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
1696 static 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
1708 static 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
1724 static 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. */
1730 #if __WORDSIZE == 64
1731     ldr_d(r0, r1);
1732 #else
1733     ldr_f(r0, r1);
1734     ldxi_f(r0 + 1, r1, 4);
1735 #endif
1736
1737     /* Update vararg stack pointer. */
1738     addi(r1, r1, 8);
1739 }
1740 #endif