git subrepo pull (merge) --force deps/lightning
[pcsx_rearmed.git] / deps / lightning / lib / jit_x86-x87.c
1 /*
2  * Copyright (C) 2012-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 __X32
22 #    define x87_address_p(i0)           1
23 #  else
24 #    if __X64_32
25 #      define x87_address_p(i0)         ((jit_word_t)(i0) >= 0)
26 #    else
27 #      define x87_address_p(i0)         can_sign_extend_int_p(i0)
28 #    endif
29 #  endif
30 #  define _ST0_REGNO                    0
31 #  define _ST1_REGNO                    1
32 #  define _ST2_REGNO                    2
33 #  define _ST3_REGNO                    3
34 #  define _ST4_REGNO                    4
35 #  define _ST5_REGNO                    5
36 #  define _ST6_REGNO                    6
37 #  define x87rx(code, md, rb, ri, ms)   _x87rx(_jit, code, md, rb, ri, ms)
38 #  define fldcwm(md, rb, ri, ms)        x87rx(015, md, rb, ri, ms)
39 #  define fstcwm(md, rb, ri, ms)        _fstcwm(_jit, md, rb, ri, ms)
40 static void
41 _fstcwm(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
42 #  define fldsm(md, rb, ri, ms)         x87rx(010, md, rb, ri, ms)
43 #  define fstsm(md, rb, ri, ms)         x87rx(012, md, rb, ri, ms)
44 #  define fldlm(md, rb, ri, ms)         x87rx(050, md, rb, ri, ms)
45 #  define fstlm(md, rb, ri, ms)         x87rx(052, md, rb, ri, ms)
46 #  define fisttplm(md, rb, ri, ms)      x87rx(031, md, rb, ri, ms)
47 #  define fistlm(md, rb, ri, ms)        x87rx(032, md, rb, ri, ms)
48 #  define fisttpqm(md, rb, ri, ms)      x87rx(071, md, rb, ri, ms)
49 #  define fildlm(md, rb, ri, ms)        x87rx(030, md, rb,ri, ms)
50 #  define fildqm(md, rb, ri, ms)        x87rx(075, md, rb,ri, ms)
51 static void
52 _x87rx(jit_state_t*, jit_int32_t, jit_int32_t,
53        jit_int32_t, jit_int32_t, jit_int32_t);
54 #  define x87ri(cc,r0)                  _x87ri(_jit,cc,r0)
55 #  define fchs_()                       x87ri(014, 0)
56 #  define fabs_()                       x87ri(014, 1)
57 #  define fld1()                        x87ri(015, 0)
58 #  define fldl2t()                      x87ri(015, 1)
59 #  define fldl2e()                      x87ri(015, 2)
60 #  define fldpi()                       x87ri(015, 3)
61 #  define fldlg2()                      x87ri(015, 4)
62 #  define fldln2()                      x87ri(015, 5)
63 #  define fldz()                        x87ri(015, 6)
64 #  define fsqrt_()                      x87ri(017, 2)
65 #  define fldr(r0)                      x87ri(010, r0)
66 #  define fxchr(r0)                     x87ri(011, r0)
67 #  define fstr(r0)                      x87ri(052, r0)
68 #  define fstpr(r0)                     x87ri(053, r0)
69 #  define fucomir(r0)                   x87ri(035, r0)
70 #  define fucomipr(r0)                  x87ri(075, r0)
71 static void _x87ri(jit_state_t*, jit_int32_t, jit_int32_t);
72 #  define faddr(r0, r1)                 x87rri(000, r0, r1)
73 #  define fmulr(r0, r1)                 x87rri(001, r0, r1)
74 #  define fsubr(r0, r1)                 x87rri(004, r0, r1)
75 #  define fsubrr(r0, r1)                x87rri(005, r0, r1)
76 #  define fdivr(r0, r1)                 x87rri(006, r0, r1)
77 #  define fdivrr(r0, r1)                x87rri(007, r0, r1)
78 #  define x87rri(cc, r0, r1)            _x87rri(_jit, cc, r0, r1)
79 static void _x87rri(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
80 #  define x87_addr_f(r0, r1, r2)        _x87_addr_d(_jit, r0, r1, r2)
81 #  define x87_addi_f(r0, r1, i0)        _x87_addi_f(_jit, r0, r1, i0)
82 static void _x87_addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
83 #  define x87_addr_d(r0, r1, r2)        _x87_addr_d(_jit, r0, r1, r2)
84 static void _x87_addr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
85 #  define x87_addi_d(r0, r1, i0)        _x87_addi_d(_jit, r0, r1, i0)
86 static void _x87_addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
87 #  define x87_subr_f(r0, r1, r2)        _x87_subr_d(_jit, r0, r1, r2)
88 #  define x87_subi_f(r0, r1, i0)        _x87_subi_f(_jit, r0, r1, i0)
89 static void _x87_subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
90 #  define x87_subr_d(r0, r1, r2)        _x87_subr_d(_jit, r0, r1, r2)
91 static void _x87_subr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
92 #  define x87_subi_d(r0, r1, i0)        _x87_subi_d(_jit, r0, r1, i0)
93 static void _x87_subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
94 #  define x87_rsbr_f(r0, r1, r2)        x87_subr_f(r0, r2, r1)
95 #  define x87_rsbi_f(r0, r1, i0)        _x87_rsbi_f(_jit, r0, r1, i0)
96 static void _x87_rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
97 #  define x87_rsbr_d(r0, r1, r2)        x87_subr_d(r0, r2, r1)
98 #  define x87_rsbi_d(r0, r1, i0)        _x87_rsbi_d(_jit, r0, r1, i0)
99 static void _x87_rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
100 #  define x87_mulr_f(r0, r1, r2)        _x87_mulr_d(_jit, r0, r1, r2)
101 #  define x87_muli_f(r0, r1, i0)        _x87_muli_f(_jit, r0, r1, i0)
102 static void _x87_muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
103 #  define x87_mulr_d(r0, r1, r2)        _x87_mulr_d(_jit, r0, r1, r2)
104 static void _x87_mulr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
105 #  define x87_muli_d(r0, r1, i0)        _x87_muli_d(_jit, r0, r1, i0)
106 static void _x87_muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
107 #  define x87_divr_f(r0, r1, r2)        _x87_divr_d(_jit, r0, r1, r2)
108 #  define x87_divi_f(r0, r1, i0)        _x87_divi_f(_jit, r0, r1, i0)
109 static void _x87_divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
110 #  define x87_divr_d(r0, r1, r2)        _x87_divr_d(_jit, r0, r1, r2)
111 static void _x87_divr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
112 #  define x87_divi_d(r0, r1, i0)        _x87_divi_d(_jit, r0, r1, i0)
113 static void _x87_divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
114 #  define x87_absr_f(r0, r1)            _x87_absr_d(_jit, r0, r1)
115 #  define x87_absr_d(r0, r1)            _x87_absr_d(_jit, r0, r1)
116 static void _x87_absr_d(jit_state_t*, jit_int32_t, jit_int32_t);
117 #  define x87_negr_f(r0, r1)            _x87_negr_d(_jit, r0, r1)
118 #  define x87_negr_d(r0, r1)            _x87_negr_d(_jit, r0, r1)
119 static void _x87_negr_d(jit_state_t*, jit_int32_t, jit_int32_t);
120 #  define x87_sqrtr_f(r0, r1)           _x87_sqrtr_d(_jit, r0, r1)
121 #  define x87_sqrtr_d(r0, r1)           _x87_sqrtr_d(_jit, r0, r1)
122 static void _x87_sqrtr_d(jit_state_t*, jit_int32_t, jit_int32_t);
123 #  define x87_fmar_f(r0, r1, r2, r3)    _x87_fmar_f(_jit, r0, r1, r2, r3)
124 static void _x87_fmar_f(jit_state_t*,
125                         jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
126 #  define x87_fmar_d(r0, r1, r2, r3)    _x87_fmar_d(_jit, r0, r1, r2, r3)
127 static void _x87_fmar_d(jit_state_t*,
128                         jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
129 #  define x87_fmsr_f(r0, r1, r2, r3)    _x87_fmsr_f(_jit, r0, r1, r2, r3)
130 static void _x87_fmsr_f(jit_state_t*,
131                         jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
132 #  define x87_fmsr_d(r0, r1, r2, r3)    _x87_fmsr_d(_jit, r0, r1, r2, r3)
133 static void _x87_fmsr_d(jit_state_t*,
134                         jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
135 #  define x87_fnmar_f(r0, r1, r2, r3)   _x87_fnmar_f(_jit, r0, r1, r2, r3)
136 static void _x87_fnmar_f(jit_state_t*,
137                          jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
138 #  define x87_fnmar_d(r0, r1, r2, r3)   _x87_fnmar_d(_jit, r0, r1, r2, r3)
139 static void _x87_fnmar_d(jit_state_t*,
140                          jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
141 #  define x87_fnmsr_f(r0, r1, r2, r3)   _x87_fnmsr_f(_jit, r0, r1, r2, r3)
142 static void _x87_fnmsr_f(jit_state_t*,
143                          jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
144 #  define x87_fnmsr_d(r0, r1, r2, r3)   _x87_fnmsr_d(_jit, r0, r1, r2, r3)
145 static void _x87_fnmsr_d(jit_state_t*,
146                          jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
147 #  define x87_truncr_f_i(r0, r1)        _x87_truncr_d_i(_jit, r0, r1)
148 #  define x87_truncr_d_i(r0, r1)        _x87_truncr_d_i(_jit, r0, r1)
149 static void _x87_truncr_d_i(jit_state_t*, jit_int32_t, jit_int32_t);
150 #  if __X64
151 #    define x87_truncr_f_l(r0, r1)      _x87_truncr_d_l(_jit, r0, r1)
152 #    define x87_truncr_d_l(r0, r1)      _x87_truncr_d_l(_jit, r0, r1)
153 static void _x87_truncr_d_l(jit_state_t*, jit_int32_t, jit_int32_t);
154 #  endif
155 #  define x87_extr_f(r0, r1)            _x87_extr_d(_jit, r0, r1)
156 #  define x87_extr_d(r0, r1)            _x87_extr_d(_jit, r0, r1)
157 #  define x87_extr_f_d(r0, r1)          x87_movr_d(r0, r1)
158 #  define x87_extr_d_f(r0, r1)          x87_movr_d(r0, r1)
159 static void _x87_extr_d(jit_state_t*, jit_int32_t, jit_int32_t);
160 #  define x87cmp(code, r0, r1, r2)      _x87cmp(_jit, code, r0, r1, r2)
161 static void
162 _x87cmp(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
163 #  define x87cmp2(code, r0, r1, r2)     _x87cmp2(_jit, code, r0, r1, r2)
164 static void
165 _x87cmp2(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
166 #  define x87jcc(code, i0, r0, r1)      _x87jcc(_jit, code, i0, r0, r1)
167 static jit_word_t
168 _x87jcc(jit_state_t*, jit_int32_t, jit_word_t, jit_int32_t, jit_int32_t);
169 #  define x87jcc2(code, i0, r0, r1)     _x87jcc2(_jit, code, i0, r0, r1)
170 static jit_word_t
171 _x87jcc2(jit_state_t*, jit_int32_t, jit_word_t, jit_int32_t, jit_int32_t);
172 #define x87_movi_f(r0,i0)               _x87_movi_f(_jit,r0,i0)
173 static void _x87_movi_f(jit_state_t*, jit_int32_t, jit_float32_t*);
174 #define x87_movr_w_f(r0,r1)             _x87_movr_w_f(_jit,r0,r1)
175 static void _x87_movr_w_f(jit_state_t*, jit_int32_t, jit_int32_t);
176 #define x87_movr_f_w(r0,r1)             _x87_movr_f_w(_jit,r0,r1)
177 static void _x87_movr_f_w(jit_state_t*, jit_int32_t, jit_int32_t);
178 #define x87_movi_w_f(r0, i0)            _x87_movi_w_f(_jit, r0, i0)
179 static void _x87_movi_w_f(jit_state_t*, jit_int32_t, jit_word_t);
180 #  define x87_ldr_f(r0, r1)             _x87_ldr_f(_jit, r0, r1)
181 static void _x87_ldr_f(jit_state_t*, jit_int32_t, jit_int32_t);
182 #  define x87_ldi_f(r0, i0)             _x87_ldi_f(_jit, r0, i0)
183 static void _x87_ldi_f(jit_state_t*, jit_int32_t, jit_word_t);
184 #  define x87_ldxr_f(r0, r1, r2)        _x87_ldxr_f(_jit, r0, r1, r2)
185 static void _x87_ldxr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
186 #  define x87_ldxi_f(r0, r1, i0)        _x87_ldxi_f(_jit, r0, r1, i0)
187 static void _x87_ldxi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
188 #  define x87_unldr_x(r0, r1, i0)       _x87_unldr_x(_jit, r0, r1, i0)
189 static void _x87_unldr_x(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
190 #  define x87_unldi_x(r0, i0, i1)       _x87_unldi_x(_jit, r0, i0, i1)
191 static void _x87_unldi_x(jit_state_t*, jit_int32_t, jit_word_t, jit_word_t);
192 #  define x87_str_f(r0, r1)             _x87_str_f(_jit, r0, r1)
193 static void _x87_str_f(jit_state_t*,jit_int32_t,jit_int32_t);
194 #  define x87_sti_f(i0, r0)             _x87_sti_f(_jit, i0, r0)
195 static void _x87_sti_f(jit_state_t*,jit_word_t, jit_int32_t);
196 #  define x87_stxr_f(r0, r1, r2)        _x87_stxr_f(_jit, r0, r1, r2)
197 static void _x87_stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
198 #  define x87_stxi_f(i0, r0, r1)        _x87_stxi_f(_jit, i0, r0, r1)
199 static void _x87_stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
200 #define x87_unstr_x(r0, r1, i0)         _x87_unstr_x(_jit, r0, r1, i0)
201 static void _x87_unstr_x(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
202 #define x87_unsti_x(i0, r0, i1)         _x87_unsti_x(_jit, i0, r0, i1)
203 static void _x87_unsti_x(jit_state_t*, jit_word_t, jit_int32_t, jit_word_t);
204 #  define x87_ltr_f(r0, r1, r2)         x87cmp(X86_CC_A, r0, r2, r1)
205 #  define x87_lti_f(r0, r1, i0)         _x87_lti_f(_jit, r0, r1, i0)
206 static void _x87_lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
207 #  define x87_ler_f(r0, r1, r2)         x87cmp(X86_CC_AE, r0, r2, r1)
208 #  define x87_lei_f(r0, r1, i0)         _x87_lei_f(_jit, r0, r1, i0)
209 static void _x87_lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
210 #  define x87_eqr_f(r0, r1, r2)         x87_eqr_d(r0, r2, r1)
211 #  define x87_eqi_f(r0, r1, i0)         _x87_eqi_f(_jit, r0, r1, i0)
212 static void _x87_eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
213 #  define x87_ger_f(r0, r1, r2)         x87cmp(X86_CC_AE, r0, r1, r2)
214 #  define x87_gei_f(r0, r1, i0)         _x87_gei_f(_jit, r0, r1, i0)
215 static void _x87_gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
216 #  define x87_gtr_f(r0, r1, r2)         x87cmp(X86_CC_A, r0, r1, r2)
217 #  define x87_gti_f(r0, r1, i0)         _x87_gti_f(_jit, r0, r1, i0)
218 static void _x87_gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
219 #  define x87_ner_f(r0, r1, r2)         x87_ner_d(r0, r2, r1)
220 #  define x87_nei_f(r0, r1, i0)         _x87_nei_f(_jit, r0, r1, i0)
221 static void _x87_nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
222 #  define x87_unltr_f(r0, r1, r2)       x87cmp(X86_CC_NAE, r0, r1, r2)
223 #  define x87_unlti_f(r0, r1, i0)       _x87_unlti_f(_jit, r0, r1, i0)
224 static void _x87_unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
225 #  define x87_unler_f(r0, r1, r2)       x87cmp(X86_CC_NA, r0, r1, r2)
226 #  define x87_unlei_f(r0, r1, i0)       _x87_unlei_f(_jit, r0, r1, i0)
227 static void _x87_unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
228 #  define x87_uneqr_f(r0, r1, r2)       x87cmp2(X86_CC_E, r0, r1, r2)
229 #  define x87_uneqi_f(r0, r1, i0)       _x87_uneqi_f(_jit, r0, r1, i0)
230 static void _x87_uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
231 #  define x87_unger_f(r0, r1, r2)       x87cmp(X86_CC_NA, r0, r2, r1)
232 #  define x87_ungei_f(r0, r1, i0)       _x87_ungei_f(_jit, r0, r1, i0)
233 static void _x87_ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
234 #  define x87_ungtr_f(r0, r1, r2)       x87cmp(X86_CC_NAE, r0, r2, r1)
235 #  define x87_ungti_f(r0, r1, i0)       _x87_ungti_f(_jit, r0, r1, i0)
236 static void _x87_ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
237 #  define x87_ltgtr_f(r0, r1, r2)       x87_ltgtr_d(r0, r1, r2)
238 #  define x87_ltgti_f(r0, r1, i0)       _x87_ltgti_f(_jit, r0, r1, i0)
239 static void _x87_ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
240 #  define x87_ordr_f(r0, r1, r2)        x87cmp2(X86_CC_NP, r0, r2, r1)
241 #  define x87_ordi_f(r0, r1, i0)        _x87_ordi_f(_jit, r0, r1, i0)
242 static void _x87_ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
243 #  define x87_unordr_f(r0, r1, r2)      x87cmp2(X86_CC_P, r0, r2, r1)
244 #  define x87_unordi_f(r0, r1, i0)      _x87_unordi_f(_jit, r0, r1, i0)
245 static void _x87_unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
246 #  define x87_ltr_d(r0, r1, r2)         x87cmp(X86_CC_A, r0, r2, r1)
247 #  define x87_lti_d(r0, r1, i0)         _x87_lti_d(_jit, r0, r1, i0)
248 static void _x87_lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
249 #  define x87_ler_d(r0, r1, r2)         x87cmp(X86_CC_AE, r0, r2, r1)
250 #  define x87_lei_d(r0, r1, i0)         _x87_lei_d(_jit, r0, r1, i0)
251 static void _x87_lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
252 #  define x87_eqr_d(r0, r1, r2)         _x87_eqr_d(_jit, r0, r2, r1)
253 static void _x87_eqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
254 #  define x87_eqi_d(r0, r1, i0)         _x87_eqi_d(_jit, r0, r1, i0)
255 static void _x87_eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
256 #  define x87_ger_d(r0, r1, r2)         x87cmp(X86_CC_AE, r0, r1, r2)
257 #  define x87_gei_d(r0, r1, i0)         _x87_gei_d(_jit, r0, r1, i0)
258 static void _x87_gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
259 #  define x87_gtr_d(r0, r1, r2)         x87cmp(X86_CC_A, r0, r1, r2)
260 #  define x87_gti_d(r0, r1, i0)         _x87_gti_d(_jit, r0, r1, i0)
261 static void _x87_gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
262 #  define x87_ner_d(r0, r1, r2)         _x87_ner_d(_jit, r0, r2, r1)
263 static void _x87_ner_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
264 #  define x87_nei_d(r0, r1, i0)         _x87_nei_d(_jit, r0, r1, i0)
265 static void _x87_nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
266 #  define x87_unltr_d(r0, r1, r2)       x87cmp(X86_CC_NAE, r0, r1, r2)
267 #  define x87_unlti_d(r0, r1, i0)       _x87_unlti_d(_jit, r0, r1, i0)
268 static void _x87_unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
269 #  define x87_unler_d(r0, r1, r2)       x87cmp(X86_CC_NA, r0, r1, r2)
270 #  define x87_unlei_d(r0, r1, i0)       _x87_unlei_d(_jit, r0, r1, i0)
271 static void _x87_unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
272 #  define x87_uneqr_d(r0, r1, r2)       x87cmp2(X86_CC_E, r0, r1, r2)
273 #  define x87_uneqi_d(r0, r1, i0)       _x87_uneqi_d(_jit, r0, r1, i0)
274 static void _x87_uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
275 #  define x87_unger_d(r0, r1, r2)       x87cmp(X86_CC_NA, r0, r2, r1)
276 #  define x87_ungei_d(r0, r1, i0)       _x87_ungei_d(_jit, r0, r1, i0)
277 static void _x87_ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
278 #  define x87_ungtr_d(r0, r1, r2)       x87cmp(X86_CC_NAE, r0, r2, r1)
279 #  define x87_ungti_d(r0, r1, i0)       _x87_ungti_d(_jit, r0, r1, i0)
280 static void _x87_ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
281 #  define x87_ltgtr_d(r0, r1, r2)       _x87_ltgtr_d(_jit, r0, r1, r2)
282 static void _x87_ltgtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
283 #  define x87_ltgti_d(r0, r1, i0)       _x87_ltgti_d(_jit, r0, r1, i0)
284 static void _x87_ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
285 #  define x87_ordr_d(r0, r1, r2)        x87cmp2(X86_CC_NP, r0, r2, r1)
286 #  define x87_ordi_d(r0, r1, i0)        _x87_ordi_d(_jit, r0, r1, i0)
287 static void _x87_ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
288 #  define x87_unordr_d(r0, r1, r2)      x87cmp2(X86_CC_P, r0, r2, r1)
289 #  define x87_unordi_d(r0, r1, i0)      _x87_unordi_d(_jit, r0, r1, i0)
290 static void _x87_unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
291 #define x87_movr_f(r0,r1)               _x87_movr_d(_jit,r0,r1)
292 #define x87_movr_d(r0,r1)               _x87_movr_d(_jit,r0,r1)
293 static void _x87_movr_d(jit_state_t*, jit_int32_t, jit_int32_t);
294 #define x87_movi_d(r0,i0)               _x87_movi_d(_jit,r0,i0)
295 static void _x87_movi_d(jit_state_t*, jit_int32_t, jit_float64_t*);
296 #if __X32 || __X64_32
297 #  define x87_movr_ww_d(r0,r1,r2)       _x87_movr_ww_d(_jit,r0,r1,r2)
298 static void _x87_movr_ww_d(jit_state_t*, jit_int32_t, jit_int32_t,jit_int32_t);
299 #  define x87_movr_d_ww(r0,r1,r2)       _x87_movr_d_ww(_jit,r0,r1,r2)
300 static void _x87_movr_d_ww(jit_state_t*, jit_int32_t, jit_int32_t,jit_int32_t);
301 #  define x87_movi_ww_d(r0, i0, i1)     _x87_movi_ww_d(_jit, r0, i0, i1)
302 static void _x87_movi_ww_d(jit_state_t*, jit_int32_t, jit_word_t, jit_word_t);
303 #else
304 #  define x87_movr_w_d(r0,r1)           _x87_movr_w_d(_jit,r0,r1)
305 static void _x87_movr_w_d(jit_state_t*, jit_int32_t, jit_int32_t);
306 #  define x87_movr_d_w(r0,r1)           _x87_movr_d_w(_jit,r0,r1)
307 static void _x87_movr_d_w(jit_state_t*, jit_int32_t, jit_int32_t);
308 #define x87_movi_w_d(r0, i0)            _x87_movi_w_d(_jit, r0, i0)
309 static void _x87_movi_w_d(jit_state_t*, jit_int32_t, jit_word_t);
310 #endif
311 #  define x87_ldr_d(r0, r1)             _x87_ldr_d(_jit, r0, r1)
312 static void _x87_ldr_d(jit_state_t*, jit_int32_t, jit_int32_t);
313 #  define x87_ldi_d(r0, i0)             _x87_ldi_d(_jit, r0, i0)
314 static void _x87_ldi_d(jit_state_t*, jit_int32_t, jit_word_t);
315 #  define x87_ldxr_d(r0, r1, r2)        _x87_ldxr_d(_jit, r0, r1, r2)
316 static void _x87_ldxr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
317 #  define x87_ldxi_d(r0, r1, i0)        _x87_ldxi_d(_jit, r0, r1, i0)
318 static void _x87_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
319 #  define x87_str_d(r0, r1)             _x87_str_d(_jit, r0, r1)
320 static void _x87_str_d(jit_state_t*,jit_int32_t,jit_int32_t);
321 #  define x87_sti_d(i0, r0)             _x87_sti_d(_jit, i0, r0)
322 static void _x87_sti_d(jit_state_t*,jit_word_t,jit_int32_t);
323 #  define x87_stxr_d(r0, r1, r2)        _x87_stxr_d(_jit, r0, r1, r2)
324 static void _x87_stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
325 #  define x87_stxi_d(i0, r0, r1)        _x87_stxi_d(_jit, i0, r0, r1)
326 static void _x87_stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
327 #  define x87_bltr_f(i0, r0, r1)        x87jcc(X86_CC_A, i0, r1, r0)
328 #  define x87_blti_f(i0, r0, i1)        _x87_blti_f(_jit, i0, r0, i1)
329 static jit_word_t
330 _x87_blti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
331 #  define x87_bler_f(i0, r0, r1)        x87jcc(X86_CC_AE, i0, r1, r0)
332 #  define x87_blei_f(i0, r0, i1)        _x87_blei_f(_jit, i0, r0, i1)
333 static jit_word_t
334 _x87_blei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
335 #  define x87_beqr_f(i0, r0, r1)        _x87_beqr_d(_jit, i0, r0, r1)
336 #  define x87_beqi_f(i0, r0, i1)        _x87_beqi_f(_jit, i0, r0, i1)
337 static jit_word_t
338 _x87_beqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
339 #  define x87_bger_f(i0, r0, r1)        x87jcc(X86_CC_AE, i0, r0, r1)
340 #  define x87_bgei_f(i0, r0, i1)        _x87_bgei_f(_jit, i0, r0, i1)
341 static jit_word_t
342 _x87_bgei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
343 #  define x87_bgtr_f(i0, r0, r1)        x87jcc(X86_CC_A, i0, r0, r1)
344 #  define x87_bgti_f(i0, r0, i1)        _x87_bgti_f(_jit, i0, r0, i1)
345 static jit_word_t
346 _x87_bgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
347 #  define x87_bner_f(i0, r0, r1)        _x87_bner_d(_jit, i0, r0, r1)
348 #  define x87_bnei_f(i0, r0, i1)        _x87_bnei_f(_jit, i0, r0, i1)
349 static jit_word_t
350 _x87_bnei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
351 #  define x87_bunltr_f(i0, r0, r1)      x87jcc(X86_CC_NAE, i0, r0, r1)
352 #  define x87_bunlti_f(i0, r0, i1)      _x87_bunlti_f(_jit, i0, r0, i1)
353 static jit_word_t
354 _x87_bunlti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
355 #  define x87_bunler_f(i0, r0, r1)      x87jcc(X86_CC_NA, i0, r0, r1)
356 #  define x87_bunlei_f(i0, r0, i1)      _x87_bunlei_f(_jit, i0, r0, i1)
357 static jit_word_t
358 _x87_bunlei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
359 #  define x87_buneqr_f(i0, r0, r1)      x87jcc2(X86_CC_E, i0, r0, r1)
360 #  define x87_buneqi_f(i0, r0, i1)      _x87_buneqi_f(_jit, i0, r0, i1)
361 static jit_word_t
362 _x87_buneqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
363 #  define x87_bunger_f(i0, r0, r1)      x87jcc(X86_CC_NA, i0, r1, r0)
364 #  define x87_bungei_f(i0, r0, i1)      _x87_bungei_f(_jit, i0, r0, i1)
365 static jit_word_t
366 _x87_bungei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
367 #  define x87_bungtr_f(i0, r0, r1)      x87jcc(X86_CC_NAE, i0, r1, r0)
368 #  define x87_bungti_f(i0, r0, i1)      _x87_bungti_f(_jit, i0, r0, i1)
369 static jit_word_t
370 _x87_bungti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
371 #  define x87_bltgtr_f(i0, r0, r1)      x87jcc2(X86_CC_NE, i0, r0, r1)
372 #  define x87_bltgti_f(i0, r0, i1)      _x87_bltgti_f(_jit, i0, r0, i1)
373 static jit_word_t
374 _x87_bltgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
375 #  define x87_bordr_f(i0, r0, r1)       x87jcc2(X86_CC_NP, i0, r0, r1)
376 #  define x87_bordi_f(i0, r0, i1)       _x87_bordi_f(_jit, i0, r0, i1)
377 static jit_word_t
378 _x87_bordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
379 #  define x87_bunordr_f(i0, r0, r1)     x87jcc2(X86_CC_P, i0, r0, r1)
380 #  define x87_bunordi_f(i0, r0, i1)     _x87_bunordi_f(_jit, i0, r0, i1)
381 static jit_word_t
382 _x87_bunordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
383 #  define x87_bltr_d(i0, r0, r1)        x87jcc(X86_CC_A, i0, r1, r0)
384 #  define x87_blti_d(i0, r0, i1)        _x87_blti_d(_jit, i0, r0, i1)
385 static jit_word_t
386 _x87_blti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
387 #  define x87_bler_d(i0, r0, r1)        x87jcc(X86_CC_AE, i0, r1, r0)
388 #  define x87_blei_d(i0, r0, i1)        _x87_blei_d(_jit, i0, r0, i1)
389 static jit_word_t
390 _x87_blei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
391 #  define x87_beqr_d(i0, r0, r1)        _x87_beqr_d(_jit, i0, r0, r1)
392 static jit_word_t
393 _x87_beqr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
394 #  define x87_beqi_d(i0, r0, i1)        _x87_beqi_d(_jit, i0, r0, i1)
395 static jit_word_t
396 _x87_beqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
397 #  define x87_bger_d(i0, r0, r1)        x87jcc(X86_CC_AE, i0, r0, r1)
398 #  define x87_bgei_d(i0, r0, i1)        _x87_bgei_d(_jit, i0, r0, i1)
399 static jit_word_t
400 _x87_bgei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
401 #  define x87_bgtr_d(i0, r0, r1)        x87jcc(X86_CC_A, i0, r0, r1)
402 #  define x87_bgti_d(i0, r0, i1)        _x87_bgti_d(_jit, i0, r0, i1)
403 static jit_word_t
404 _x87_bgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
405 #  define x87_bner_d(i0, r0, r1)        _x87_bner_d(_jit, i0, r0, r1)
406 static jit_word_t
407 _x87_bner_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
408 #  define x87_bnei_d(i0, r0, i1)        _x87_bnei_d(_jit, i0, r0, i1)
409 static jit_word_t
410 _x87_bnei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
411 #  define x87_bunltr_d(i0, r0, r1)      x87jcc(X86_CC_NAE, i0, r0, r1)
412 #  define x87_bunlti_d(i0, r0, i1)      _x87_bunlti_d(_jit, i0, r0, i1)
413 static jit_word_t
414 _x87_bunlti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
415 #  define x87_bunler_d(i0, r0, r1)      x87jcc(X86_CC_NA, i0, r0, r1)
416 #  define x87_bunlei_d(i0, r0, i1)      _x87_bunlei_d(_jit, i0, r0, i1)
417 static jit_word_t
418 _x87_bunlei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
419 #  define x87_buneqr_d(i0, r0, r1)      x87jcc2(X86_CC_E, i0, r0, r1)
420 #  define x87_buneqi_d(i0, r0, i1)      _x87_buneqi_d(_jit, i0, r0, i1)
421 static jit_word_t
422 _x87_buneqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
423 #  define x87_bunger_d(i0, r0, r1)      x87jcc(X86_CC_NA, i0, r1, r0)
424 #  define x87_bungei_d(i0, r0, i1)      _x87_bungei_d(_jit, i0, r0, i1)
425 static jit_word_t
426 _x87_bungei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
427 #  define x87_bungtr_d(i0, r0, r1)      x87jcc(X86_CC_NAE, i0, r1, r0)
428 #  define x87_bungti_d(i0, r0, i1)      _x87_bungti_d(_jit, i0, r0, i1)
429 static jit_word_t
430 _x87_bungti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
431 #  define x87_bltgtr_d(i0, r0, r1)      x87jcc2(X86_CC_NE, i0, r0, r1)
432 #  define x87_bltgti_d(i0, r0, i1)      _x87_bltgti_d(_jit, i0, r0, i1)
433 static jit_word_t
434 _x87_bltgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
435 #  define x87_bordr_d(i0, r0, r1)       x87jcc2(X86_CC_NP, i0, r0, r1)
436 #  define x87_bordi_d(i0, r0, i1)       _x87_bordi_d(_jit, i0, r0, i1)
437 static jit_word_t
438 _x87_bordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
439 #  define x87_bunordr_d(i0, r0, r1)     x87jcc2(X86_CC_P, i0, r0, r1)
440 #  define x87_bunordi_d(i0, r0, i1)     _x87_bunordi_d(_jit, i0, r0, i1)
441 static jit_word_t
442 _x87_bunordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
443 #endif
444
445 #if CODE
446 #  define fpr_opi(name, type, size)                                     \
447 static void                                                             \
448 _x87_##name##i_##type(jit_state_t *_jit,                                \
449                       jit_int32_t r0, jit_int32_t r1,                   \
450                       jit_float##size##_t *i0)                          \
451 {                                                                       \
452     jit_int32_t         reg = jit_get_reg(jit_class_fpr);               \
453     assert(jit_x87_reg_p(reg));                                         \
454     x87_movi_##type(rn(reg), i0);                                       \
455     x87_##name##r_##type(r0, r1, rn(reg));                              \
456     jit_unget_reg(reg);                                                 \
457 }
458 #  define fpr_bopi(name, type, size)                                    \
459 static jit_word_t                                                       \
460 _x87_b##name##i_##type(jit_state_t *_jit,                               \
461                        jit_word_t i0, jit_int32_t r0,                   \
462                        jit_float##size##_t *i1)                         \
463 {                                                                       \
464     jit_word_t          w;                                              \
465     jit_int32_t         reg = jit_get_reg(jit_class_fpr|                \
466                                           jit_class_nospill);           \
467     assert(jit_x87_reg_p(reg));                                         \
468     x87_movi_##type(rn(reg), i1);                                       \
469     w = x87_b##name##r_##type(i0, r0, rn(reg));                         \
470     jit_unget_reg(reg);                                                 \
471     return (w);                                                         \
472 }
473 #  define fopi(name)                    fpr_opi(name, f, 32)
474 #  define fbopi(name)                   fpr_bopi(name, f, 32)
475 #  define dopi(name)                    fpr_opi(name, d, 64)
476 #  define dbopi(name)                   fpr_bopi(name, d, 64)
477
478 static void
479 _fstcwm(jit_state_t *_jit, jit_int32_t md,
480         jit_int32_t rb, jit_int32_t ri, jit_int32_t ms)
481 {
482     ic(0x9b);
483     rex(0, 1, rb, ri, _NOREG);
484     x87rx(017, md, rb, ri, ms);
485 }
486
487 static void
488 _x87rx(jit_state_t *_jit, jit_int32_t code, jit_int32_t md,
489        jit_int32_t rb, jit_int32_t ri, jit_int32_t ms)
490 {
491     rex(0, 1, rb, ri, _NOREG);
492     ic(0xd8 | (code >> 3));
493     rx((code & 7), md, rb, ri, ms);
494 }
495
496 static void
497 _x87ri(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0)
498 {
499     ic(0xd8 | (code >> 3));
500     mrm(0x03, (code & 7), r0);
501 }
502
503 static void
504 _x87rri(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0, jit_int32_t r1)
505 {
506     if (r1 == _ST0_REGNO)
507         x87ri(code | 040, r0);
508     else {
509         assert(r0 == _ST0_REGNO);
510         x87ri(code, r1);
511     }
512 }
513
514 fopi(add)
515 fopi(sub)
516 fopi(rsb)
517 fopi(mul)
518 fopi(div)
519
520 static void
521 _x87_addr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
522 {
523     if (r0 == r1) {
524         if (r2 == _ST0_REGNO)
525             faddr(r0, _ST0_REGNO);
526         else if (r0 == _ST0_REGNO)
527             faddr(_ST0_REGNO, r2);
528         else {
529             fxchr(r0);
530             faddr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
531             fxchr(r0);
532         }
533     }
534     else if (r0 == r2) {
535         if (r1 == _ST0_REGNO)
536             faddr(r0, _ST0_REGNO);
537         else if (r0 == _ST0_REGNO)
538             faddr(_ST0_REGNO, r1);
539         else {
540             fxchr(r0);
541             faddr(_ST0_REGNO, r1);
542             fxchr(r0);
543         }
544     }
545     else {
546         fldr(r1);
547         faddr(_ST0_REGNO, r2 + 1);
548         fstpr(r0 + 1);
549     }
550 }
551
552 dopi(add)
553
554 static void
555 _x87_subr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
556 {
557     if (r0 == r1) {
558         if (r2 == _ST0_REGNO)
559             fsubrr(r0, _ST0_REGNO);
560         else if (r0 == _ST0_REGNO)
561             fsubr(_ST0_REGNO, r2);
562         else {
563             fxchr(r0);
564             fsubr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
565             fxchr(r0);
566         }
567     }
568     else if (r0 == r2) {
569         if (r1 == _ST0_REGNO)
570             fsubr(r0, _ST0_REGNO);
571         else if (r0 == _ST0_REGNO)
572             fsubrr(_ST0_REGNO, r1);
573         else {
574             fxchr(r0);
575             fsubrr(_ST0_REGNO, r1);
576             fxchr(r0);
577         }
578     }
579     else {
580         fldr(r1);
581         fsubr(_ST0_REGNO, r2 + 1);
582         fstpr(r0 + 1);
583     }
584 }
585
586 dopi(sub)
587
588 dopi(rsb)
589
590 static void
591 _x87_mulr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
592 {
593     if (r0 == r1) {
594         if (r2 == _ST0_REGNO)
595             fmulr(r0, _ST0_REGNO);
596         else if (r0 == _ST0_REGNO)
597             fmulr(_ST0_REGNO, r2);
598         else {
599             fxchr(r0);
600             fmulr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
601             fxchr(r0);
602         }
603     }
604     else if (r0 == r2) {
605         if (r1 == _ST0_REGNO)
606             fmulr(r0, _ST0_REGNO);
607         else if (r0 == _ST0_REGNO)
608             fmulr(_ST0_REGNO, r1);
609         else {
610             fxchr(r0);
611             fmulr(_ST0_REGNO, r1);
612             fxchr(r0);
613         }
614     }
615     else {
616         fldr(r1);
617         fmulr(_ST0_REGNO, r2 + 1);
618         fstpr(r0 + 1);
619     }
620 }
621
622 dopi(mul)
623
624 static void
625 _x87_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
626 {
627     if (r0 == r1) {
628         if (r2 == _ST0_REGNO)
629             fdivrr(r0, _ST0_REGNO);
630         else if (r0 == _ST0_REGNO)
631             fdivr(_ST0_REGNO, r2);
632         else {
633             fxchr(r0);
634             fdivr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
635             fxchr(r0);
636         }
637     }
638     else if (r0 == r2) {
639         if (r1 == _ST0_REGNO)
640             fdivr(r0, _ST0_REGNO);
641         else if (r0 == _ST0_REGNO)
642             fsubrr(_ST0_REGNO, r1);
643         else {
644             fxchr(r0);
645             fdivrr(_ST0_REGNO, r1);
646             fxchr(r0);
647         }
648     }
649     else {
650         fldr(r1);
651         fdivr(_ST0_REGNO, r2 + 1);
652         fstpr(r0 + 1);
653     }
654 }
655
656 dopi(div)
657
658 static void
659 _x87_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
660 {
661     if (r0 == r1) {
662         if (r1 == _ST0_REGNO)
663             fabs_();
664         else {
665             fxchr(r0);
666             fabs_();
667             fxchr(r0);
668         }
669     }
670     else {
671         fldr(r1);
672         fabs_();
673         fstpr(r0 + 1);
674     }
675 }
676
677 static void
678 _x87_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
679 {
680     if (r0 == r1) {
681         if (r1 == _ST0_REGNO)
682             fchs_();
683         else {
684             fxchr(r0);
685             fchs_();
686             fxchr(r0);
687         }
688     }
689     else {
690         fldr(r1);
691         fchs_();
692         fstpr(r0 + 1);
693     }
694 }
695
696 static void
697 _x87_sqrtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
698 {
699     if (r0 == r1) {
700         if (r1 == _ST0_REGNO)
701             fsqrt_();
702         else {
703             fxchr(r0);
704             fsqrt_();
705             fxchr(r0);
706         }
707     }
708     else {
709         fldr(r1);
710         fsqrt_();
711         fstpr(r0 + 1);
712     }
713 }
714
715 static void
716 _x87_fmar_f(jit_state_t *_jit,
717             jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
718 {
719     jit_int32_t         t0;
720     if (r0 != r3) {
721         x87_mulr_f(r0, r1, r2);
722         x87_addr_f(r0, r0, r3);
723     }
724     else {
725         t0 = jit_get_reg(jit_class_fpr);
726         assert(jit_x87_reg_p(t0));
727         x87_mulr_f(rn(t0), r1, r2);
728         x87_addr_f(r0, rn(t0), r3);
729         jit_unget_reg(t0);
730     }
731 }
732
733 static void
734 _x87_fmar_d(jit_state_t *_jit,
735             jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
736 {
737     jit_int32_t         t0;
738     if (r0 != r3) {
739         x87_mulr_d(r0, r1, r2);
740         x87_addr_d(r0, r0, r3);
741     }
742     else {
743         t0 = jit_get_reg(jit_class_fpr);
744         assert(jit_x87_reg_p(t0));
745         x87_mulr_d(rn(t0), r1, r2);
746         x87_addr_d(r0, rn(t0), r3);
747         jit_unget_reg(t0);
748     }
749 }
750
751 static void
752 _x87_fmsr_f(jit_state_t *_jit,
753             jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
754 {
755     jit_int32_t         t0;
756     if (r0 != r3) {
757         x87_mulr_f(r0, r1, r2);
758         x87_subr_f(r0, r0, r3);
759     }
760     else {
761         t0 = jit_get_reg(jit_class_fpr);
762         assert(jit_x87_reg_p(t0));
763         x87_mulr_f(rn(t0), r1, r2);
764         x87_subr_f(r0, rn(t0), r3);
765         jit_unget_reg(t0);
766     }
767 }
768
769 static void
770 _x87_fmsr_d(jit_state_t *_jit,
771             jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
772 {
773     jit_int32_t         t0;
774     if (r0 != r3) {
775         x87_mulr_d(r0, r1, r2);
776         x87_subr_d(r0, r0, r3);
777     }
778     else {
779         t0 = jit_get_reg(jit_class_fpr);
780         assert(jit_x87_reg_p(t0));
781         x87_mulr_d(rn(t0), r1, r2);
782         x87_subr_d(r0, rn(t0), r3);
783         jit_unget_reg(t0);
784     }
785 }
786
787 static void
788 _x87_fnmar_f(jit_state_t *_jit,
789              jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
790 {
791     jit_int32_t         t0;
792     t0 = jit_get_reg(jit_class_fpr);
793     x87_negr_f(rn(t0), r1);
794     x87_mulr_f(rn(t0), rn(t0), r2);
795     x87_subr_f(r0, rn(t0), r3);
796     jit_unget_reg(t0);
797 }
798
799 static void
800 _x87_fnmar_d(jit_state_t *_jit,
801              jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
802 {
803     jit_int32_t         t0;
804     t0 = jit_get_reg(jit_class_fpr);
805     x87_negr_d(rn(t0), r1);
806     x87_mulr_d(rn(t0), rn(t0), r2);
807     x87_subr_d(r0, rn(t0), r3);
808     jit_unget_reg(t0);
809 }
810
811 static void
812 _x87_fnmsr_f(jit_state_t *_jit,
813              jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
814 {
815     jit_int32_t         t0;
816     t0 = jit_get_reg(jit_class_fpr);
817     x87_negr_f(rn(t0), r1);
818     x87_mulr_f(rn(t0), rn(t0), r2);
819     x87_addr_f(r0, rn(t0), r3);
820     jit_unget_reg(t0);
821 }
822
823 static void
824 _x87_fnmsr_d(jit_state_t *_jit,
825              jit_int32_t r0, jit_int32_t r1, jit_int32_t r2, jit_int32_t r3)
826 {
827     jit_int32_t         t0;
828     t0 = jit_get_reg(jit_class_fpr);
829     x87_negr_d(rn(t0), r1);
830     x87_mulr_d(rn(t0), rn(t0), r2);
831     x87_addr_d(r0, rn(t0), r3);
832     jit_unget_reg(t0);
833 }
834
835 static void
836 _x87_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
837 {
838     CHECK_CVT_OFFSET();
839 #if defined(sun)
840     /* for the sake of passing test cases in x87 mode, otherwise only sse
841      * is supported */
842     fstcwm(-4, _RBP_REGNO, _NOREG, _SCL1);
843     ldxi_s(r0, _RBP_REGNO, -4);
844     extr_uc(r0, r0);
845 #  define FPCW_CHOP     0xc00
846     ori(r0, r0, FPCW_CHOP);
847     stxi_s(-8, _RBP_REGNO, r0);
848     fldcwm(-8, _RBP_REGNO, _NOREG, _SCL1);
849     if (r1 == _ST0_REGNO)
850         fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
851     else {
852         fxchr(r1);
853         fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
854         fxchr(r1);
855     }
856     fldcwm(-4, _RBP_REGNO, _NOREG, _SCL1);
857     ldxi(r0, _RBP_REGNO, CVT_OFFSET);
858 #else
859     fldr(r1);
860     fisttplm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
861     ldxi_i(r0, _RBP_REGNO, CVT_OFFSET);
862 #endif
863 }
864
865 #  if __X64
866 static void
867 _x87_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
868 {
869     CHECK_CVT_OFFSET();
870     fldr(r1);
871     fisttpqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
872     ldxi(r0, _RBP_REGNO, CVT_OFFSET);
873 }
874 #  endif
875
876 static void
877 _x87_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
878 {
879     CHECK_CVT_OFFSET();
880     stxi(CVT_OFFSET, _RBP_REGNO, r1);
881 #  if __X32
882     fildlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
883 #  else
884     fildqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
885 #  endif
886     fstpr(r0 + 1);
887 }
888
889 static void
890 _x87cmp(jit_state_t *_jit, jit_int32_t code,
891         jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
892 {
893     jit_bool_t          rc;
894     jit_int32_t         reg;
895     if ((rc = reg8_p(r0)))
896         reg = r0;
897     else {
898         reg = _RAX_REGNO;
899         movr(r0, reg);
900     }
901     ixorr(reg, reg);
902     if (r1 == _ST0_REGNO)
903         fucomir(r2);
904     else {
905         fldr(r1);
906         fucomipr(r2 + 1);
907     }
908     cc(code, reg);
909     if (!rc)
910         xchgr(r0, reg);
911 }
912
913 static void
914 _x87cmp2(jit_state_t *_jit, jit_int32_t code,
915          jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
916 {
917     jit_bool_t                  rc;
918     jit_int32_t                 reg;
919     jit_int32_t                 f1, f2;
920     if (r2 == _ST0_REGNO)       f1 = r2, f2 = r1;
921     else                        f1 = r1, f2 = r2;
922     if ((rc = reg8_p(r0)))
923         reg = r0;
924     else {
925         reg = _RAX_REGNO;
926         movr(r0, reg);
927     }
928     ixorr(reg, reg);
929     if (f1 == _ST0_REGNO)
930         fucomir(f2);
931     else {
932         fldr(f1);
933         fucomipr(f2 + 1);
934     }
935     cc(code, reg);
936     if (!rc)
937         xchgr(r0, reg);
938 }
939
940 static jit_word_t
941 _x87jcc(jit_state_t *_jit, jit_int32_t code,
942         jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
943 {
944     if (r0 == _ST0_REGNO)
945         fucomir(r1);
946     else {
947         fldr(r0);
948         fucomipr(r1 + 1);
949     }
950     return (jcc(code, i0));
951 }
952
953 static jit_word_t
954 _x87jcc2(jit_state_t *_jit, jit_int32_t code,
955          jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
956 {
957     jit_int32_t                 f0, f1;
958     if (r1 == _ST0_REGNO)       f0 = r1, f1 = r0;
959     else                        f0 = r0, f1 = r1;
960     if (f0 == _ST0_REGNO)
961         fucomir(f1);
962     else {
963         fldr(f0);
964         fucomipr(f1 + 1);
965     }
966     return (jcc(code, i0));
967 }
968
969 fopi(lt)
970 fopi(le)
971 fopi(eq)
972 fopi(ge)
973 fopi(gt)
974 fopi(ne)
975 fopi(unlt)
976 fopi(unle)
977 fopi(uneq)
978 fopi(unge)
979 fopi(ungt)
980 fopi(ltgt)
981 fopi(ord)
982 fopi(unord)
983 fbopi(lt)
984 fbopi(le)
985 fbopi(eq)
986 fbopi(ge)
987 fbopi(gt)
988 fbopi(ne)
989 fbopi(unlt)
990 fbopi(unle)
991 fbopi(uneq)
992 fbopi(unge)
993 fbopi(ungt)
994 fbopi(ltgt)
995 fbopi(ord)
996 fbopi(unord)
997
998 static void
999 _x87_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0)
1000 {
1001     union {
1002         jit_int32_t      i;
1003         jit_float32_t    f;
1004     } data;
1005     jit_int32_t          reg;
1006
1007     data.f = *i0;
1008     if (data.f == 0.0 && !(data.i & 0x80000000))
1009         fldz();
1010     else if (data.f == 1.0)
1011         fld1();
1012     else if (data.f == 3.3219280948873623478703195458468f)
1013         fldl2t();
1014     else if (data.f == 1.4426950408889634073599246886656f)
1015         fldl2e();
1016     else if (data.f == 3.1415926535897932384626421096161f)
1017         fldpi();
1018     else if (data.f == 0.3010299956639811952137387498515f)
1019         fldlg2();
1020     else if (data.f == 0.6931471805599453094172323683399f)
1021         fldln2();
1022     else {
1023         if (_jitc->no_data) {
1024             CHECK_CVT_OFFSET();
1025             reg = jit_get_reg(jit_class_gpr);
1026             movi(rn(reg), data.i);
1027             stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
1028             jit_unget_reg(reg);
1029             x87_ldxi_f(r0, _RBP_REGNO, CVT_OFFSET);
1030         }
1031         else
1032             x87_ldi_f(r0, (jit_word_t)i0);
1033         return;
1034     }
1035     fstpr(r0 + 1);
1036 }
1037
1038 static void
1039 _x87_movr_w_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1040 {
1041     CHECK_CVT_OFFSET();
1042     stxi_i(CVT_OFFSET, _RBP_REGNO, r1);
1043     x87_ldxi_f(r0, _RBP_REGNO, CVT_OFFSET);
1044 }
1045
1046 static void
1047 _x87_movr_f_w(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1048 {
1049     CHECK_CVT_OFFSET();
1050     x87_stxi_f(CVT_OFFSET, _RBP_REGNO, r1);
1051     ldxi_i(r0, _RBP_REGNO, CVT_OFFSET);
1052 }
1053
1054 static void
1055 _x87_movi_w_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1056 {
1057     jit_int32_t         reg;
1058     CHECK_CVT_OFFSET();
1059     reg = jit_get_reg(jit_class_gpr);
1060     movi(rn(reg), i0);
1061     stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
1062     jit_unget_reg(reg);
1063     x87_ldxi_f(r0, _RBP_REGNO, CVT_OFFSET);
1064 }
1065
1066 static void
1067 _x87_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1068 {
1069     fldsm(0, r1, _NOREG, _SCL1);
1070     fstpr(r0 + 1);
1071 }
1072
1073 static void
1074 _x87_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1075 {
1076     jit_int32_t         reg;
1077     if (x87_address_p(i0)) {
1078         fldsm(i0, _NOREG, _NOREG, _SCL1);
1079         fstpr(r0 + 1);
1080     }
1081     else {
1082         reg = jit_get_reg(jit_class_gpr);
1083         movi(rn(reg), i0);
1084         x87_ldr_f(r0, rn(reg));
1085         jit_unget_reg(reg);
1086     }
1087 }
1088
1089 static void
1090 _x87_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1091 {
1092 #if __X64_32
1093     jit_int32_t         reg;
1094     reg = jit_get_reg(jit_class_gpr);
1095     addr(rn(reg), r1, r2);
1096     x87_ldr_f(r0, rn(reg));
1097     jit_unget_reg(reg);
1098 #else
1099     fldsm(0, r1, r2, _SCL1);
1100     fstpr(r0 + 1);
1101 #endif
1102 }
1103
1104 static void
1105 _x87_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1106 {
1107     jit_int32_t         reg;
1108     if (can_sign_extend_int_p(i0)) {
1109         fldsm(i0, r1, _NOREG, _SCL1);
1110         fstpr(r0 + 1);
1111     }
1112     else {
1113         reg = jit_get_reg(jit_class_gpr);
1114 #if __X64_32
1115         addi(rn(reg), r1, i0);
1116         x87_ldr_f(r0, rn(reg));
1117 #else
1118         movi(rn(reg), i0);
1119         x87_ldxr_f(r0, r1, rn(reg));
1120 #endif
1121         jit_unget_reg(reg);
1122     }
1123 }
1124
1125 static void
1126 _x87_unldr_x(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1127 {
1128     assert(i0 == 4 || i0 == 8);
1129     if (i0 == 4)
1130         x87_ldr_f(r0, r1);
1131     else
1132         x87_ldr_d(r0, r1);
1133 }
1134
1135 static void
1136 _x87_unldi_x(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0, jit_word_t i1)
1137 {
1138     assert(i1 == 4 || i1 == 8);
1139     if (i1 == 4)
1140         x87_ldi_f(r0, i0);
1141     else
1142         x87_ldi_d(r0, i0);
1143 }
1144
1145 static void
1146 _x87_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1147 {
1148     if (r1 == _ST0_REGNO)
1149         fstsm(0, r0, _NOREG, _SCL1);
1150     else {
1151         fxchr(r1);
1152         fstsm(0, r0, _NOREG, _SCL1);
1153         fxchr(r1);
1154     }
1155 }
1156
1157 static void
1158 _x87_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1159 {
1160     jit_int32_t         reg;
1161     if (!x87_address_p(i0)) {
1162         reg = jit_get_reg(jit_class_gpr);
1163         movi(rn(reg), i0);
1164         x87_str_f(rn(reg), r0);
1165         jit_unget_reg(reg);
1166     }
1167     else if (r0 == _ST0_REGNO)
1168         fstsm(i0, _NOREG, _NOREG, _SCL1);
1169     else {
1170         fxchr(r0);
1171         fstsm(i0, _NOREG, _NOREG, _SCL1);
1172         fxchr(r0);
1173     }
1174 }
1175
1176 static void
1177 _x87_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1178 {
1179 #if __X64_32
1180     jit_int32_t         reg;
1181     reg = jit_get_reg(jit_class_gpr);
1182     addr(rn(reg), r0, r1);
1183     x87_str_f(rn(reg), r2);
1184     jit_unget_reg(reg);
1185 #else
1186     if (r2 == _ST0_REGNO)
1187         fstsm(0, r0, r1, _SCL1);
1188     else {
1189         fxchr(r2);
1190         fstsm(0, r0, r1, _SCL1);
1191         fxchr(r2);
1192     }
1193 #endif
1194 }
1195
1196 static void
1197 _x87_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1198 {
1199     jit_int32_t         reg;
1200     if (!can_sign_extend_int_p(i0)) {
1201         reg = jit_get_reg(jit_class_gpr);
1202 #if __X64_32
1203         addi(rn(reg), r0, i0);
1204         x87_str_f(rn(reg), r1);
1205 #else
1206         movi(rn(reg), i0);
1207         x87_stxr_f(rn(reg), r0, r1);
1208 #endif
1209         jit_unget_reg(reg);
1210     }
1211     else if (r1 == _ST0_REGNO)
1212         fstsm(i0, r0, _NOREG, _SCL1);
1213     else {
1214         fxchr(r1);
1215         fstsm(i0, r0, _NOREG, _SCL1);
1216         fxchr(r1);
1217     }
1218 }
1219
1220 static void
1221 _x87_unstr_x(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1222 {
1223     assert(i0 == 4 || i0 == 8);
1224     if (i0 == 4)
1225         x87_str_f(r0, r1);
1226     else
1227         x87_str_d(r0, r1);
1228 }
1229
1230 static void
1231 _x87_unsti_x(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_word_t i1)
1232 {
1233     assert(i1 == 4 || i1 == 8);
1234     if (i1 == 4)
1235         x87_sti_f(i0, r0);
1236     else
1237         x87_sti_d(i0, r0);
1238 }
1239
1240 static void
1241 _x87_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1242 {
1243     if (r0 != r1) {
1244         if (r1 == _ST0)
1245             fstr(r0);
1246         else if (r0 == _ST0) {
1247             fxchr(r1);
1248             fstr(r1);
1249         }
1250         else {
1251             fldr(r1);
1252             fstpr(r0 + 1);
1253         }
1254     }
1255 }
1256
1257 static void
1258 _x87_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
1259 {
1260     union {
1261         jit_int32_t      ii[2];
1262         jit_word_t       w;
1263         jit_float64_t    d;
1264     } data;
1265     jit_int32_t          reg;
1266
1267     data.d = *i0;
1268     if (data.d == 0.0 && !(data.ii[1] & 0x80000000))
1269         fldz();
1270     else if (data.d == 1.0)
1271         fld1();
1272     else if (data.d == 3.3219280948873623478703195458468)
1273         fldl2t();
1274     else if (data.d == 1.4426950408889634073599246886656)
1275         fldl2e();
1276     else if (data.d == 3.1415926535897932384626421096161)
1277         fldpi();
1278     else if (data.d == 0.3010299956639811952137387498515)
1279         fldlg2();
1280     else if (data.d == 0.6931471805599453094172323683399)
1281         fldln2();
1282     else {
1283         if (_jitc->no_data) {
1284             CHECK_CVT_OFFSET();
1285             reg = jit_get_reg(jit_class_gpr);
1286 #if __X32 || __X64_32
1287             movi(rn(reg), data.ii[0]);
1288             stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
1289             movi(rn(reg), data.ii[1]);
1290             stxi_i(CVT_OFFSET + 4, _RBP_REGNO, rn(reg));
1291 #else
1292             movi(rn(reg), data.w);
1293             stxi_l(CVT_OFFSET, _RBP_REGNO, rn(reg));
1294 #endif
1295             jit_unget_reg(reg);
1296             x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET);
1297         }
1298         else
1299             x87_ldi_d(r0, (jit_word_t)i0);
1300         return;
1301     }
1302     fstpr(r0 + 1);
1303 }
1304
1305 #if __X32 || __X64_32
1306 static void
1307 _x87_movr_ww_d(jit_state_t *_jit,
1308                jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1309 {
1310     CHECK_CVT_OFFSET();
1311     stxi_i(CVT_OFFSET, _RBP_REGNO, r1);
1312     stxi_i(CVT_OFFSET + 4, _RBP_REGNO, r2);
1313     x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET);
1314 }
1315
1316 static void
1317 _x87_movr_d_ww(jit_state_t *_jit,
1318                jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1319 {
1320     CHECK_CVT_OFFSET();
1321     x87_stxi_d(CVT_OFFSET, _RBP_REGNO, r2);
1322     ldxi_i(r0, _RBP_REGNO, CVT_OFFSET);
1323     ldxi_i(r1, _RBP_REGNO, CVT_OFFSET + 4);
1324 }
1325
1326 static void
1327 _x87_movi_ww_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0, jit_word_t i1)
1328 {
1329     jit_int32_t         reg;
1330     CHECK_CVT_OFFSET();
1331     reg = jit_get_reg(jit_class_gpr);
1332     movi(rn(reg), i0);
1333     stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
1334     movi(rn(reg), i1);
1335     stxi_i(CVT_OFFSET + 4, _RBP_REGNO, rn(reg));
1336     jit_unget_reg(reg);
1337     x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET);
1338 }
1339 #else
1340
1341 static void
1342 _x87_movr_w_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1343 {
1344     CHECK_CVT_OFFSET();
1345     stxi_l(CVT_OFFSET, _RBP_REGNO, r1);
1346     x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET);
1347 }
1348
1349 static void
1350 _x87_movr_d_w(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1351 {
1352     CHECK_CVT_OFFSET();
1353     x87_stxi_d(CVT_OFFSET, _RBP_REGNO, r1);
1354     ldxi_l(r0, _RBP_REGNO, CVT_OFFSET);
1355 }
1356
1357 static void
1358 _x87_movi_w_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1359 {
1360     jit_int32_t         reg;
1361     CHECK_CVT_OFFSET();
1362     reg = jit_get_reg(jit_class_gpr);
1363     movi(rn(reg), i0);
1364     stxi(CVT_OFFSET, _RBP_REGNO, rn(reg));
1365     jit_unget_reg(reg);
1366     x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET);
1367 }
1368 #endif
1369
1370 dopi(lt)
1371 dopi(le)
1372
1373 static void
1374 _x87_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1375 {
1376     jit_bool_t                  rc;
1377     jit_word_t                  jp_code;
1378     jit_int32_t                 reg, f1, f2;
1379     if (r2 == _ST0_REGNO)       f1 = r2, f2 = r1;
1380     else                        f1 = r1, f2 = r2;
1381     if ((rc = reg8_p(r0)))
1382         reg = r0;
1383     else {
1384         reg = _RAX_REGNO;
1385         movr(r0, reg);
1386     }
1387     ixorr(reg, reg);
1388     if (f1 == _ST0_REGNO)
1389         fucomir(f2);
1390     else {
1391         fldr(f1);
1392         fucomipr(f2 + 1);
1393     }
1394     jp_code = jpes(0);
1395     cc(X86_CC_E, reg);
1396     patch_at(jp_code, _jit->pc.w);
1397     if (!rc)
1398         xchgr(r0, reg);
1399 }
1400
1401 dopi(eq)
1402 dopi(ge)
1403 dopi(gt)
1404
1405 static void
1406 _x87_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1407 {
1408     jit_bool_t                  rc;
1409     jit_word_t                  jp_code;
1410     jit_int32_t                 reg, f1, f2;
1411     if (r2 == _ST0_REGNO)       f1 = r2, f2 = r1;
1412     else                        f1 = r1, f2 = r2;
1413     if ((rc = reg8_p(r0)))
1414         reg = r0;
1415     else {
1416         reg = _RAX_REGNO;
1417         movr(r0, reg);
1418     }
1419     imovi(reg, 1);
1420     if (f1 == _ST0_REGNO)
1421         fucomir(f2);
1422     else {
1423         fldr(f1);
1424         fucomipr(f2 + 1);
1425     }
1426     jp_code = jpes(0);
1427     cc(X86_CC_NE, reg);
1428     patch_at(jp_code, _jit->pc.w);
1429     if (!rc)
1430         xchgr(r0, reg);
1431 }
1432
1433 dopi(ne)
1434 dopi(unlt)
1435 dopi(unle)
1436 dopi(uneq)
1437 dopi(unge)
1438 dopi(ungt)
1439
1440 static void
1441 _x87_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1442 {
1443     if (r1 == r2)
1444         movi(r0, 1);
1445     else
1446         x87cmp2(X86_CC_NE, r0, r1, r2);
1447 }
1448
1449 dopi(ltgt)
1450 dopi(ord)
1451 dopi(unord)
1452
1453 static void
1454 _x87_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1455 {
1456     fldlm(0, r1, _NOREG, _SCL1);
1457     fstpr(r0 + 1);
1458 }
1459
1460 static void
1461 _x87_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1462 {
1463     jit_int32_t         reg;
1464     if (x87_address_p(i0)) {
1465         fldlm(i0, _NOREG, _NOREG, _SCL1);
1466         fstpr(r0 + 1);
1467     }
1468     else {
1469         reg = jit_get_reg(jit_class_gpr);
1470         movi(rn(reg), i0);
1471         x87_ldr_d(r0, rn(reg));
1472         jit_unget_reg(reg);
1473     }
1474 }
1475
1476 static void
1477 _x87_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1478 {
1479 #if __X64_32
1480     jit_int32_t         reg;
1481     reg = jit_get_reg(jit_class_gpr);
1482     addr(rn(reg), r1, r2);
1483     x87_ldr_d(r0, rn(reg));
1484     jit_unget_reg(reg);
1485 #else
1486     fldlm(0, r1, r2, _SCL1);
1487     fstpr(r0 + 1);
1488 #endif
1489 }
1490
1491 static void
1492 _x87_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1493 {
1494     jit_int32_t         reg;
1495     if (can_sign_extend_int_p(i0)) {
1496         fldlm(i0, r1, _NOREG, _SCL1);
1497         fstpr(r0 + 1);
1498     }
1499     else {
1500         reg = jit_get_reg(jit_class_gpr);
1501 #if __X64_32
1502         addi(rn(reg), r1, i0);
1503         x87_ldr_d(r0, rn(reg));
1504 #else
1505         movi(rn(reg), i0);
1506         x87_ldxr_d(r0, r1, rn(reg));
1507 #endif
1508         jit_unget_reg(reg);
1509     }
1510 }
1511
1512 static void
1513 _x87_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1514 {
1515     if (r1 == _ST0_REGNO)
1516         fstlm(0, r0, _NOREG, _SCL1);
1517     else {
1518         fxchr(r1);
1519         fstlm(0, r0, _NOREG, _SCL1);
1520         fxchr(r1);
1521     }
1522 }
1523
1524 static void
1525 _x87_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1526 {
1527     jit_int32_t         reg;
1528     if (!x87_address_p(i0)) {
1529         reg = jit_get_reg(jit_class_gpr);
1530         movi(rn(reg), i0);
1531         x87_str_d(rn(reg), r0);
1532         jit_unget_reg(reg);
1533     }
1534     else if (r0 == _ST0_REGNO)
1535         fstlm(i0, _NOREG, _NOREG, _SCL1);
1536     else {
1537         fxchr(r0);
1538         fstlm(i0, _NOREG, _NOREG, _SCL1);
1539         fxchr(r0);
1540     }
1541 }
1542
1543 static void
1544 _x87_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1545 {
1546 #if __X64_32
1547     jit_int32_t         reg;
1548     reg = jit_get_reg(jit_class_gpr);
1549     addr(rn(reg), r0, r1);
1550     x87_str_d(rn(reg), r2);
1551     jit_unget_reg(reg);
1552 #else
1553     if (r2 == _ST0_REGNO)
1554         fstlm(0, r0, r1, _SCL1);
1555     else {
1556         fxchr(r2);
1557         fstlm(0, r0, r1, _SCL1);
1558         fxchr(r2);
1559     }
1560 #endif
1561 }
1562
1563 static void
1564 _x87_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1565 {
1566     jit_int32_t         reg;
1567     if (!can_sign_extend_int_p(i0)) {
1568         reg = jit_get_reg(jit_class_gpr);
1569 #if __X64_32
1570         addi(rn(reg), r0, i0);
1571         x87_str_d(rn(reg), r1);
1572 #else
1573         movi(rn(reg), i0);
1574         x87_stxr_d(rn(reg), r0, r1);
1575 #endif
1576         jit_unget_reg(reg);
1577     }
1578     else if (r1 == _ST0_REGNO)
1579         fstlm(i0, r0, _NOREG, _SCL1);
1580     else {
1581         fxchr(r1);
1582         fstlm(i0, r0, _NOREG, _SCL1);
1583         fxchr(r1);
1584     }
1585 }
1586
1587 dbopi(lt)
1588 dbopi(le)
1589
1590 static jit_word_t
1591 _x87_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1592 {
1593     jit_word_t                  w;
1594     jit_int32_t                 f0, f1;
1595     jit_word_t                  jp_code;
1596     if (r1 == _ST0_REGNO)       f0 = r1, f1 = r0;
1597     else                        f0 = r0, f1 = r1;
1598     if (f0 == _ST0_REGNO)
1599         fucomir(f1);
1600     else {
1601         fldr(f0);
1602         fucomipr(f1 + 1);
1603     }
1604     jp_code = jpes(0);
1605     w = jcc(X86_CC_E, i0);
1606     patch_at(jp_code, _jit->pc.w);
1607     return (w);
1608 }
1609 dbopi(eq)
1610 dbopi(ge)
1611 dbopi(gt)
1612
1613 static jit_word_t
1614 _x87_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1615 {
1616     jit_word_t                  w;
1617     jit_int32_t                 f0, f1;
1618     jit_word_t                  jp_code;
1619     jit_word_t                  jz_code;
1620     if (r1 == _ST0_REGNO)       f0 = r1, f1 = r0;
1621     else                        f0 = r0, f1 = r1;
1622     if (f0 == _ST0_REGNO)
1623         fucomir(f1);
1624     else {
1625         fldr(f0);
1626         fucomipr(f1 + 1);
1627     }
1628     jp_code = jpes(0);
1629     jz_code = jzs(0);
1630     patch_at(jp_code, _jit->pc.w);
1631     w = jmpi(i0);
1632     patch_at(jz_code, _jit->pc.w);
1633     return (w);
1634 }
1635 dbopi(ne)
1636 dbopi(unlt)
1637 dbopi(unle)
1638 dbopi(uneq)
1639 dbopi(unge)
1640 dbopi(ungt)
1641 dbopi(ltgt)
1642 dbopi(ord)
1643 dbopi(unord)
1644 #  undef fopi
1645 #  undef fbopi
1646 #  undef dopi
1647 #  undef dbopi
1648 #  undef fpr_bopi
1649 #  undef fpr_opi
1650 #endif