update libchdr
[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_truncr_f_i(r0, r1)        _x87_truncr_d_i(_jit, r0, r1)
124 #  define x87_truncr_d_i(r0, r1)        _x87_truncr_d_i(_jit, r0, r1)
125 static void _x87_truncr_d_i(jit_state_t*, jit_int32_t, jit_int32_t);
126 #  if __X64
127 #    define x87_truncr_f_l(r0, r1)      _x87_truncr_d_l(_jit, r0, r1)
128 #    define x87_truncr_d_l(r0, r1)      _x87_truncr_d_l(_jit, r0, r1)
129 static void _x87_truncr_d_l(jit_state_t*, jit_int32_t, jit_int32_t);
130 #  endif
131 #  define x87_extr_f(r0, r1)            _x87_extr_d(_jit, r0, r1)
132 #  define x87_extr_d(r0, r1)            _x87_extr_d(_jit, r0, r1)
133 #  define x87_extr_f_d(r0, r1)          x87_movr_d(r0, r1)
134 #  define x87_extr_d_f(r0, r1)          x87_movr_d(r0, r1)
135 static void _x87_extr_d(jit_state_t*, jit_int32_t, jit_int32_t);
136 #  define x87cmp(code, r0, r1, r2)      _x87cmp(_jit, code, r0, r1, r2)
137 static void
138 _x87cmp(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
139 #  define x87cmp2(code, r0, r1, r2)     _x87cmp2(_jit, code, r0, r1, r2)
140 static void
141 _x87cmp2(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
142 #  define x87jcc(code, i0, r0, r1)      _x87jcc(_jit, code, i0, r0, r1)
143 static jit_word_t
144 _x87jcc(jit_state_t*, jit_int32_t, jit_word_t, jit_int32_t, jit_int32_t);
145 #  define x87jcc2(code, i0, r0, r1)     _x87jcc2(_jit, code, i0, r0, r1)
146 static jit_word_t
147 _x87jcc2(jit_state_t*, jit_int32_t, jit_word_t, jit_int32_t, jit_int32_t);
148 #define x87_movi_f(r0,i0)               _x87_movi_f(_jit,r0,i0)
149 static void _x87_movi_f(jit_state_t*, jit_int32_t, jit_float32_t*);
150 #  define x87_ldr_f(r0, r1)             _x87_ldr_f(_jit, r0, r1)
151 static void _x87_ldr_f(jit_state_t*, jit_int32_t, jit_int32_t);
152 #  define x87_ldi_f(r0, i0)             _x87_ldi_f(_jit, r0, i0)
153 static void _x87_ldi_f(jit_state_t*, jit_int32_t, jit_word_t);
154 #  define x87_ldxr_f(r0, r1, r2)        _x87_ldxr_f(_jit, r0, r1, r2)
155 static void _x87_ldxr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
156 #  define x87_ldxi_f(r0, r1, i0)        _x87_ldxi_f(_jit, r0, r1, i0)
157 static void _x87_ldxi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
158 #  define x87_str_f(r0, r1)             _x87_str_f(_jit, r0, r1)
159 static void _x87_str_f(jit_state_t*,jit_int32_t,jit_int32_t);
160 #  define x87_sti_f(i0, r0)             _x87_sti_f(_jit, i0, r0)
161 static void _x87_sti_f(jit_state_t*,jit_word_t, jit_int32_t);
162 #  define x87_stxr_f(r0, r1, r2)        _x87_stxr_f(_jit, r0, r1, r2)
163 static void _x87_stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
164 #  define x87_stxi_f(i0, r0, r1)        _x87_stxi_f(_jit, i0, r0, r1)
165 static void _x87_stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
166 #  define x87_ltr_f(r0, r1, r2)         x87cmp(X86_CC_A, r0, r2, r1)
167 #  define x87_lti_f(r0, r1, i0)         _x87_lti_f(_jit, r0, r1, i0)
168 static void _x87_lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
169 #  define x87_ler_f(r0, r1, r2)         x87cmp(X86_CC_AE, r0, r2, r1)
170 #  define x87_lei_f(r0, r1, i0)         _x87_lei_f(_jit, r0, r1, i0)
171 static void _x87_lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
172 #  define x87_eqr_f(r0, r1, r2)         x87_eqr_d(r0, r2, r1)
173 #  define x87_eqi_f(r0, r1, i0)         _x87_eqi_f(_jit, r0, r1, i0)
174 static void _x87_eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
175 #  define x87_ger_f(r0, r1, r2)         x87cmp(X86_CC_AE, r0, r1, r2)
176 #  define x87_gei_f(r0, r1, i0)         _x87_gei_f(_jit, r0, r1, i0)
177 static void _x87_gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
178 #  define x87_gtr_f(r0, r1, r2)         x87cmp(X86_CC_A, r0, r1, r2)
179 #  define x87_gti_f(r0, r1, i0)         _x87_gti_f(_jit, r0, r1, i0)
180 static void _x87_gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
181 #  define x87_ner_f(r0, r1, r2)         x87_ner_d(r0, r2, r1)
182 #  define x87_nei_f(r0, r1, i0)         _x87_nei_f(_jit, r0, r1, i0)
183 static void _x87_nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
184 #  define x87_unltr_f(r0, r1, r2)       x87cmp(X86_CC_NAE, r0, r1, r2)
185 #  define x87_unlti_f(r0, r1, i0)       _x87_unlti_f(_jit, r0, r1, i0)
186 static void _x87_unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
187 #  define x87_unler_f(r0, r1, r2)       x87cmp(X86_CC_NA, r0, r1, r2)
188 #  define x87_unlei_f(r0, r1, i0)       _x87_unlei_f(_jit, r0, r1, i0)
189 static void _x87_unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
190 #  define x87_uneqr_f(r0, r1, r2)       x87cmp2(X86_CC_E, r0, r1, r2)
191 #  define x87_uneqi_f(r0, r1, i0)       _x87_uneqi_f(_jit, r0, r1, i0)
192 static void _x87_uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
193 #  define x87_unger_f(r0, r1, r2)       x87cmp(X86_CC_NA, r0, r2, r1)
194 #  define x87_ungei_f(r0, r1, i0)       _x87_ungei_f(_jit, r0, r1, i0)
195 static void _x87_ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
196 #  define x87_ungtr_f(r0, r1, r2)       x87cmp(X86_CC_NAE, r0, r2, r1)
197 #  define x87_ungti_f(r0, r1, i0)       _x87_ungti_f(_jit, r0, r1, i0)
198 static void _x87_ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
199 #  define x87_ltgtr_f(r0, r1, r2)       x87_ltgtr_d(r0, r1, r2)
200 #  define x87_ltgti_f(r0, r1, i0)       _x87_ltgti_f(_jit, r0, r1, i0)
201 static void _x87_ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
202 #  define x87_ordr_f(r0, r1, r2)        x87cmp2(X86_CC_NP, r0, r2, r1)
203 #  define x87_ordi_f(r0, r1, i0)        _x87_ordi_f(_jit, r0, r1, i0)
204 static void _x87_ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
205 #  define x87_unordr_f(r0, r1, r2)      x87cmp2(X86_CC_P, r0, r2, r1)
206 #  define x87_unordi_f(r0, r1, i0)      _x87_unordi_f(_jit, r0, r1, i0)
207 static void _x87_unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
208 #  define x87_ltr_d(r0, r1, r2)         x87cmp(X86_CC_A, r0, r2, r1)
209 #  define x87_lti_d(r0, r1, i0)         _x87_lti_d(_jit, r0, r1, i0)
210 static void _x87_lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
211 #  define x87_ler_d(r0, r1, r2)         x87cmp(X86_CC_AE, r0, r2, r1)
212 #  define x87_lei_d(r0, r1, i0)         _x87_lei_d(_jit, r0, r1, i0)
213 static void _x87_lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
214 #  define x87_eqr_d(r0, r1, r2)         _x87_eqr_d(_jit, r0, r2, r1)
215 static void _x87_eqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
216 #  define x87_eqi_d(r0, r1, i0)         _x87_eqi_d(_jit, r0, r1, i0)
217 static void _x87_eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
218 #  define x87_ger_d(r0, r1, r2)         x87cmp(X86_CC_AE, r0, r1, r2)
219 #  define x87_gei_d(r0, r1, i0)         _x87_gei_d(_jit, r0, r1, i0)
220 static void _x87_gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
221 #  define x87_gtr_d(r0, r1, r2)         x87cmp(X86_CC_A, r0, r1, r2)
222 #  define x87_gti_d(r0, r1, i0)         _x87_gti_d(_jit, r0, r1, i0)
223 static void _x87_gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
224 #  define x87_ner_d(r0, r1, r2)         _x87_ner_d(_jit, r0, r2, r1)
225 static void _x87_ner_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
226 #  define x87_nei_d(r0, r1, i0)         _x87_nei_d(_jit, r0, r1, i0)
227 static void _x87_nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
228 #  define x87_unltr_d(r0, r1, r2)       x87cmp(X86_CC_NAE, r0, r1, r2)
229 #  define x87_unlti_d(r0, r1, i0)       _x87_unlti_d(_jit, r0, r1, i0)
230 static void _x87_unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
231 #  define x87_unler_d(r0, r1, r2)       x87cmp(X86_CC_NA, r0, r1, r2)
232 #  define x87_unlei_d(r0, r1, i0)       _x87_unlei_d(_jit, r0, r1, i0)
233 static void _x87_unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
234 #  define x87_uneqr_d(r0, r1, r2)       x87cmp2(X86_CC_E, r0, r1, r2)
235 #  define x87_uneqi_d(r0, r1, i0)       _x87_uneqi_d(_jit, r0, r1, i0)
236 static void _x87_uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
237 #  define x87_unger_d(r0, r1, r2)       x87cmp(X86_CC_NA, r0, r2, r1)
238 #  define x87_ungei_d(r0, r1, i0)       _x87_ungei_d(_jit, r0, r1, i0)
239 static void _x87_ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
240 #  define x87_ungtr_d(r0, r1, r2)       x87cmp(X86_CC_NAE, r0, r2, r1)
241 #  define x87_ungti_d(r0, r1, i0)       _x87_ungti_d(_jit, r0, r1, i0)
242 static void _x87_ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
243 #  define x87_ltgtr_d(r0, r1, r2)       _x87_ltgtr_d(_jit, r0, r1, r2)
244 static void _x87_ltgtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
245 #  define x87_ltgti_d(r0, r1, i0)       _x87_ltgti_d(_jit, r0, r1, i0)
246 static void _x87_ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
247 #  define x87_ordr_d(r0, r1, r2)        x87cmp2(X86_CC_NP, r0, r2, r1)
248 #  define x87_ordi_d(r0, r1, i0)        _x87_ordi_d(_jit, r0, r1, i0)
249 static void _x87_ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
250 #  define x87_unordr_d(r0, r1, r2)      x87cmp2(X86_CC_P, r0, r2, r1)
251 #  define x87_unordi_d(r0, r1, i0)      _x87_unordi_d(_jit, r0, r1, i0)
252 static void _x87_unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
253 #define x87_movr_f(r0,r1)               _x87_movr_d(_jit,r0,r1)
254 #define x87_movr_d(r0,r1)               _x87_movr_d(_jit,r0,r1)
255 static void _x87_movr_d(jit_state_t*, jit_int32_t, jit_int32_t);
256 #define x87_movi_d(r0,i0)               _x87_movi_d(_jit,r0,i0)
257 static void _x87_movi_d(jit_state_t*, jit_int32_t, jit_float64_t*);
258 #  define x87_ldr_d(r0, r1)             _x87_ldr_d(_jit, r0, r1)
259 static void _x87_ldr_d(jit_state_t*, jit_int32_t, jit_int32_t);
260 #  define x87_ldi_d(r0, i0)             _x87_ldi_d(_jit, r0, i0)
261 static void _x87_ldi_d(jit_state_t*, jit_int32_t, jit_word_t);
262 #  define x87_ldxr_d(r0, r1, r2)        _x87_ldxr_d(_jit, r0, r1, r2)
263 static void _x87_ldxr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
264 #  define x87_ldxi_d(r0, r1, i0)        _x87_ldxi_d(_jit, r0, r1, i0)
265 static void _x87_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
266 #  define x87_str_d(r0, r1)             _x87_str_d(_jit, r0, r1)
267 static void _x87_str_d(jit_state_t*,jit_int32_t,jit_int32_t);
268 #  define x87_sti_d(i0, r0)             _x87_sti_d(_jit, i0, r0)
269 static void _x87_sti_d(jit_state_t*,jit_word_t,jit_int32_t);
270 #  define x87_stxr_d(r0, r1, r2)        _x87_stxr_d(_jit, r0, r1, r2)
271 static void _x87_stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
272 #  define x87_stxi_d(i0, r0, r1)        _x87_stxi_d(_jit, i0, r0, r1)
273 static void _x87_stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
274 #  define x87_bltr_f(i0, r0, r1)        x87jcc(X86_CC_A, i0, r1, r0)
275 #  define x87_blti_f(i0, r0, i1)        _x87_blti_f(_jit, i0, r0, i1)
276 static jit_word_t
277 _x87_blti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
278 #  define x87_bler_f(i0, r0, r1)        x87jcc(X86_CC_AE, i0, r1, r0)
279 #  define x87_blei_f(i0, r0, i1)        _x87_blei_f(_jit, i0, r0, i1)
280 static jit_word_t
281 _x87_blei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
282 #  define x87_beqr_f(i0, r0, r1)        _x87_beqr_d(_jit, i0, r0, r1)
283 #  define x87_beqi_f(i0, r0, i1)        _x87_beqi_f(_jit, i0, r0, i1)
284 static jit_word_t
285 _x87_beqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
286 #  define x87_bger_f(i0, r0, r1)        x87jcc(X86_CC_AE, i0, r0, r1)
287 #  define x87_bgei_f(i0, r0, i1)        _x87_bgei_f(_jit, i0, r0, i1)
288 static jit_word_t
289 _x87_bgei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
290 #  define x87_bgtr_f(i0, r0, r1)        x87jcc(X86_CC_A, i0, r0, r1)
291 #  define x87_bgti_f(i0, r0, i1)        _x87_bgti_f(_jit, i0, r0, i1)
292 static jit_word_t
293 _x87_bgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
294 #  define x87_bner_f(i0, r0, r1)        _x87_bner_d(_jit, i0, r0, r1)
295 #  define x87_bnei_f(i0, r0, i1)        _x87_bnei_f(_jit, i0, r0, i1)
296 static jit_word_t
297 _x87_bnei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
298 #  define x87_bunltr_f(i0, r0, r1)      x87jcc(X86_CC_NAE, i0, r0, r1)
299 #  define x87_bunlti_f(i0, r0, i1)      _x87_bunlti_f(_jit, i0, r0, i1)
300 static jit_word_t
301 _x87_bunlti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
302 #  define x87_bunler_f(i0, r0, r1)      x87jcc(X86_CC_NA, i0, r0, r1)
303 #  define x87_bunlei_f(i0, r0, i1)      _x87_bunlei_f(_jit, i0, r0, i1)
304 static jit_word_t
305 _x87_bunlei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
306 #  define x87_buneqr_f(i0, r0, r1)      x87jcc2(X86_CC_E, i0, r0, r1)
307 #  define x87_buneqi_f(i0, r0, i1)      _x87_buneqi_f(_jit, i0, r0, i1)
308 static jit_word_t
309 _x87_buneqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
310 #  define x87_bunger_f(i0, r0, r1)      x87jcc(X86_CC_NA, i0, r1, r0)
311 #  define x87_bungei_f(i0, r0, i1)      _x87_bungei_f(_jit, i0, r0, i1)
312 static jit_word_t
313 _x87_bungei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
314 #  define x87_bungtr_f(i0, r0, r1)      x87jcc(X86_CC_NAE, i0, r1, r0)
315 #  define x87_bungti_f(i0, r0, i1)      _x87_bungti_f(_jit, i0, r0, i1)
316 static jit_word_t
317 _x87_bungti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
318 #  define x87_bltgtr_f(i0, r0, r1)      x87jcc2(X86_CC_NE, i0, r0, r1)
319 #  define x87_bltgti_f(i0, r0, i1)      _x87_bltgti_f(_jit, i0, r0, i1)
320 static jit_word_t
321 _x87_bltgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
322 #  define x87_bordr_f(i0, r0, r1)       x87jcc2(X86_CC_NP, i0, r0, r1)
323 #  define x87_bordi_f(i0, r0, i1)       _x87_bordi_f(_jit, i0, r0, i1)
324 static jit_word_t
325 _x87_bordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
326 #  define x87_bunordr_f(i0, r0, r1)     x87jcc2(X86_CC_P, i0, r0, r1)
327 #  define x87_bunordi_f(i0, r0, i1)     _x87_bunordi_f(_jit, i0, r0, i1)
328 static jit_word_t
329 _x87_bunordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
330 #  define x87_bltr_d(i0, r0, r1)        x87jcc(X86_CC_A, i0, r1, r0)
331 #  define x87_blti_d(i0, r0, i1)        _x87_blti_d(_jit, i0, r0, i1)
332 static jit_word_t
333 _x87_blti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
334 #  define x87_bler_d(i0, r0, r1)        x87jcc(X86_CC_AE, i0, r1, r0)
335 #  define x87_blei_d(i0, r0, i1)        _x87_blei_d(_jit, i0, r0, i1)
336 static jit_word_t
337 _x87_blei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
338 #  define x87_beqr_d(i0, r0, r1)        _x87_beqr_d(_jit, i0, r0, r1)
339 static jit_word_t
340 _x87_beqr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
341 #  define x87_beqi_d(i0, r0, i1)        _x87_beqi_d(_jit, i0, r0, i1)
342 static jit_word_t
343 _x87_beqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
344 #  define x87_bger_d(i0, r0, r1)        x87jcc(X86_CC_AE, i0, r0, r1)
345 #  define x87_bgei_d(i0, r0, i1)        _x87_bgei_d(_jit, i0, r0, i1)
346 static jit_word_t
347 _x87_bgei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
348 #  define x87_bgtr_d(i0, r0, r1)        x87jcc(X86_CC_A, i0, r0, r1)
349 #  define x87_bgti_d(i0, r0, i1)        _x87_bgti_d(_jit, i0, r0, i1)
350 static jit_word_t
351 _x87_bgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
352 #  define x87_bner_d(i0, r0, r1)        _x87_bner_d(_jit, i0, r0, r1)
353 static jit_word_t
354 _x87_bner_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
355 #  define x87_bnei_d(i0, r0, i1)        _x87_bnei_d(_jit, i0, r0, i1)
356 static jit_word_t
357 _x87_bnei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
358 #  define x87_bunltr_d(i0, r0, r1)      x87jcc(X86_CC_NAE, i0, r0, r1)
359 #  define x87_bunlti_d(i0, r0, i1)      _x87_bunlti_d(_jit, i0, r0, i1)
360 static jit_word_t
361 _x87_bunlti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
362 #  define x87_bunler_d(i0, r0, r1)      x87jcc(X86_CC_NA, i0, r0, r1)
363 #  define x87_bunlei_d(i0, r0, i1)      _x87_bunlei_d(_jit, i0, r0, i1)
364 static jit_word_t
365 _x87_bunlei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
366 #  define x87_buneqr_d(i0, r0, r1)      x87jcc2(X86_CC_E, i0, r0, r1)
367 #  define x87_buneqi_d(i0, r0, i1)      _x87_buneqi_d(_jit, i0, r0, i1)
368 static jit_word_t
369 _x87_buneqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
370 #  define x87_bunger_d(i0, r0, r1)      x87jcc(X86_CC_NA, i0, r1, r0)
371 #  define x87_bungei_d(i0, r0, i1)      _x87_bungei_d(_jit, i0, r0, i1)
372 static jit_word_t
373 _x87_bungei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
374 #  define x87_bungtr_d(i0, r0, r1)      x87jcc(X86_CC_NAE, i0, r1, r0)
375 #  define x87_bungti_d(i0, r0, i1)      _x87_bungti_d(_jit, i0, r0, i1)
376 static jit_word_t
377 _x87_bungti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
378 #  define x87_bltgtr_d(i0, r0, r1)      x87jcc2(X86_CC_NE, i0, r0, r1)
379 #  define x87_bltgti_d(i0, r0, i1)      _x87_bltgti_d(_jit, i0, r0, i1)
380 static jit_word_t
381 _x87_bltgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
382 #  define x87_bordr_d(i0, r0, r1)       x87jcc2(X86_CC_NP, i0, r0, r1)
383 #  define x87_bordi_d(i0, r0, i1)       _x87_bordi_d(_jit, i0, r0, i1)
384 static jit_word_t
385 _x87_bordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
386 #  define x87_bunordr_d(i0, r0, r1)     x87jcc2(X86_CC_P, i0, r0, r1)
387 #  define x87_bunordi_d(i0, r0, i1)     _x87_bunordi_d(_jit, i0, r0, i1)
388 static jit_word_t
389 _x87_bunordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
390 #endif
391
392 #if CODE
393 #  define fpr_opi(name, type, size)                                     \
394 static void                                                             \
395 _x87_##name##i_##type(jit_state_t *_jit,                                \
396                       jit_int32_t r0, jit_int32_t r1,                   \
397                       jit_float##size##_t *i0)                          \
398 {                                                                       \
399     jit_int32_t         reg = jit_get_reg(jit_class_fpr);               \
400     assert(jit_x87_reg_p(reg));                                         \
401     x87_movi_##type(rn(reg), i0);                                       \
402     x87_##name##r_##type(r0, r1, rn(reg));                              \
403     jit_unget_reg(reg);                                                 \
404 }
405 #  define fpr_bopi(name, type, size)                                    \
406 static jit_word_t                                                       \
407 _x87_b##name##i_##type(jit_state_t *_jit,                               \
408                        jit_word_t i0, jit_int32_t r0,                   \
409                        jit_float##size##_t *i1)                         \
410 {                                                                       \
411     jit_word_t          w;                                              \
412     jit_int32_t         reg = jit_get_reg(jit_class_fpr|                \
413                                           jit_class_nospill);           \
414     assert(jit_x87_reg_p(reg));                                         \
415     x87_movi_##type(rn(reg), i1);                                       \
416     w = x87_b##name##r_##type(i0, r0, rn(reg));                         \
417     jit_unget_reg(reg);                                                 \
418     return (w);                                                         \
419 }
420 #  define fopi(name)                    fpr_opi(name, f, 32)
421 #  define fbopi(name)                   fpr_bopi(name, f, 32)
422 #  define dopi(name)                    fpr_opi(name, d, 64)
423 #  define dbopi(name)                   fpr_bopi(name, d, 64)
424
425 static void
426 _fstcwm(jit_state_t *_jit, jit_int32_t md,
427         jit_int32_t rb, jit_int32_t ri, jit_int32_t ms)
428 {
429     ic(0x9b);
430     rex(0, 1, rb, ri, _NOREG);
431     x87rx(017, md, rb, ri, ms);
432 }
433
434 static void
435 _x87rx(jit_state_t *_jit, jit_int32_t code, jit_int32_t md,
436        jit_int32_t rb, jit_int32_t ri, jit_int32_t ms)
437 {
438     rex(0, 1, rb, ri, _NOREG);
439     ic(0xd8 | (code >> 3));
440     rx((code & 7), md, rb, ri, ms);
441 }
442
443 static void
444 _x87ri(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0)
445 {
446     ic(0xd8 | (code >> 3));
447     mrm(0x03, (code & 7), r0);
448 }
449
450 static void
451 _x87rri(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0, jit_int32_t r1)
452 {
453     if (r1 == _ST0_REGNO)
454         x87ri(code | 040, r0);
455     else {
456         assert(r0 == _ST0_REGNO);
457         x87ri(code, r1);
458     }
459 }
460
461 fopi(add)
462 fopi(sub)
463 fopi(rsb)
464 fopi(mul)
465 fopi(div)
466
467 static void
468 _x87_addr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
469 {
470     if (r0 == r1) {
471         if (r2 == _ST0_REGNO)
472             faddr(r0, _ST0_REGNO);
473         else if (r0 == _ST0_REGNO)
474             faddr(_ST0_REGNO, r2);
475         else {
476             fxchr(r0);
477             faddr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
478             fxchr(r0);
479         }
480     }
481     else if (r0 == r2) {
482         if (r1 == _ST0_REGNO)
483             faddr(r0, _ST0_REGNO);
484         else if (r0 == _ST0_REGNO)
485             faddr(_ST0_REGNO, r1);
486         else {
487             fxchr(r0);
488             faddr(_ST0_REGNO, r1);
489             fxchr(r0);
490         }
491     }
492     else {
493         fldr(r1);
494         faddr(_ST0_REGNO, r2 + 1);
495         fstpr(r0 + 1);
496     }
497 }
498
499 dopi(add)
500
501 static void
502 _x87_subr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
503 {
504     if (r0 == r1) {
505         if (r2 == _ST0_REGNO)
506             fsubrr(r0, _ST0_REGNO);
507         else if (r0 == _ST0_REGNO)
508             fsubr(_ST0_REGNO, r2);
509         else {
510             fxchr(r0);
511             fsubr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
512             fxchr(r0);
513         }
514     }
515     else if (r0 == r2) {
516         if (r1 == _ST0_REGNO)
517             fsubr(r0, _ST0_REGNO);
518         else if (r0 == _ST0_REGNO)
519             fsubrr(_ST0_REGNO, r1);
520         else {
521             fxchr(r0);
522             fsubrr(_ST0_REGNO, r1);
523             fxchr(r0);
524         }
525     }
526     else {
527         fldr(r1);
528         fsubr(_ST0_REGNO, r2 + 1);
529         fstpr(r0 + 1);
530     }
531 }
532
533 dopi(sub)
534
535 dopi(rsb)
536
537 static void
538 _x87_mulr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
539 {
540     if (r0 == r1) {
541         if (r2 == _ST0_REGNO)
542             fmulr(r0, _ST0_REGNO);
543         else if (r0 == _ST0_REGNO)
544             fmulr(_ST0_REGNO, r2);
545         else {
546             fxchr(r0);
547             fmulr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
548             fxchr(r0);
549         }
550     }
551     else if (r0 == r2) {
552         if (r1 == _ST0_REGNO)
553             fmulr(r0, _ST0_REGNO);
554         else if (r0 == _ST0_REGNO)
555             fmulr(_ST0_REGNO, r1);
556         else {
557             fxchr(r0);
558             fmulr(_ST0_REGNO, r1);
559             fxchr(r0);
560         }
561     }
562     else {
563         fldr(r1);
564         fmulr(_ST0_REGNO, r2 + 1);
565         fstpr(r0 + 1);
566     }
567 }
568
569 dopi(mul)
570
571 static void
572 _x87_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
573 {
574     if (r0 == r1) {
575         if (r2 == _ST0_REGNO)
576             fdivrr(r0, _ST0_REGNO);
577         else if (r0 == _ST0_REGNO)
578             fdivr(_ST0_REGNO, r2);
579         else {
580             fxchr(r0);
581             fdivr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
582             fxchr(r0);
583         }
584     }
585     else if (r0 == r2) {
586         if (r1 == _ST0_REGNO)
587             fdivr(r0, _ST0_REGNO);
588         else if (r0 == _ST0_REGNO)
589             fsubrr(_ST0_REGNO, r1);
590         else {
591             fxchr(r0);
592             fdivrr(_ST0_REGNO, r1);
593             fxchr(r0);
594         }
595     }
596     else {
597         fldr(r1);
598         fdivr(_ST0_REGNO, r2 + 1);
599         fstpr(r0 + 1);
600     }
601 }
602
603 dopi(div)
604
605 static void
606 _x87_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
607 {
608     if (r0 == r1) {
609         if (r1 == _ST0_REGNO)
610             fabs_();
611         else {
612             fxchr(r0);
613             fabs_();
614             fxchr(r0);
615         }
616     }
617     else {
618         fldr(r1);
619         fabs_();
620         fstpr(r0 + 1);
621     }
622 }
623
624 static void
625 _x87_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
626 {
627     if (r0 == r1) {
628         if (r1 == _ST0_REGNO)
629             fchs_();
630         else {
631             fxchr(r0);
632             fchs_();
633             fxchr(r0);
634         }
635     }
636     else {
637         fldr(r1);
638         fchs_();
639         fstpr(r0 + 1);
640     }
641 }
642
643 static void
644 _x87_sqrtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
645 {
646     if (r0 == r1) {
647         if (r1 == _ST0_REGNO)
648             fsqrt_();
649         else {
650             fxchr(r0);
651             fsqrt_();
652             fxchr(r0);
653         }
654     }
655     else {
656         fldr(r1);
657         fsqrt_();
658         fstpr(r0 + 1);
659     }
660 }
661
662 static void
663 _x87_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
664 {
665     CHECK_CVT_OFFSET();
666 #if defined(sun)
667     /* for the sake of passing test cases in x87 mode, otherwise only sse
668      * is supported */
669     fstcwm(-4, _RBP_REGNO, _NOREG, _SCL1);
670     ldxi_s(r0, _RBP_REGNO, -4);
671     extr_uc(r0, r0);
672 #  define FPCW_CHOP     0xc00
673     ori(r0, r0, FPCW_CHOP);
674     stxi_s(-8, _RBP_REGNO, r0);
675     fldcwm(-8, _RBP_REGNO, _NOREG, _SCL1);
676     if (r1 == _ST0_REGNO)
677         fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
678     else {
679         fxchr(r1);
680         fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
681         fxchr(r1);
682     }
683     fldcwm(-4, _RBP_REGNO, _NOREG, _SCL1);
684     ldxi(r0, _RBP_REGNO, CVT_OFFSET);
685 #else
686     fldr(r1);
687     fisttplm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
688     ldxi_i(r0, _RBP_REGNO, CVT_OFFSET);
689 #endif
690 }
691
692 #  if __X64
693 static void
694 _x87_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
695 {
696     CHECK_CVT_OFFSET();
697     fldr(r1);
698     fisttpqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
699     ldxi(r0, _RBP_REGNO, CVT_OFFSET);
700 }
701 #  endif
702
703 static void
704 _x87_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
705 {
706     CHECK_CVT_OFFSET();
707     stxi(CVT_OFFSET, _RBP_REGNO, r1);
708 #  if __X32
709     fildlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
710 #  else
711     fildqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
712 #  endif
713     fstpr(r0 + 1);
714 }
715
716 static void
717 _x87cmp(jit_state_t *_jit, jit_int32_t code,
718         jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
719 {
720     jit_bool_t          rc;
721     jit_int32_t         reg;
722     if ((rc = reg8_p(r0)))
723         reg = r0;
724     else {
725         reg = _RAX_REGNO;
726         movr(r0, reg);
727     }
728     ixorr(reg, reg);
729     if (r1 == _ST0_REGNO)
730         fucomir(r2);
731     else {
732         fldr(r1);
733         fucomipr(r2 + 1);
734     }
735     cc(code, reg);
736     if (!rc)
737         xchgr(r0, reg);
738 }
739
740 static void
741 _x87cmp2(jit_state_t *_jit, jit_int32_t code,
742          jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
743 {
744     jit_bool_t                  rc;
745     jit_int32_t                 reg;
746     jit_int32_t                 f1, f2;
747     if (r2 == _ST0_REGNO)       f1 = r2, f2 = r1;
748     else                        f1 = r1, f2 = r2;
749     if ((rc = reg8_p(r0)))
750         reg = r0;
751     else {
752         reg = _RAX_REGNO;
753         movr(r0, reg);
754     }
755     ixorr(reg, reg);
756     if (f1 == _ST0_REGNO)
757         fucomir(f2);
758     else {
759         fldr(f1);
760         fucomipr(f2 + 1);
761     }
762     cc(code, reg);
763     if (!rc)
764         xchgr(r0, reg);
765 }
766
767 static jit_word_t
768 _x87jcc(jit_state_t *_jit, jit_int32_t code,
769         jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
770 {
771     if (r0 == _ST0_REGNO)
772         fucomir(r1);
773     else {
774         fldr(r0);
775         fucomipr(r1 + 1);
776     }
777     return (jcc(code, i0));
778 }
779
780 static jit_word_t
781 _x87jcc2(jit_state_t *_jit, jit_int32_t code,
782          jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
783 {
784     jit_int32_t                 f0, f1;
785     if (r1 == _ST0_REGNO)       f0 = r1, f1 = r0;
786     else                        f0 = r0, f1 = r1;
787     if (f0 == _ST0_REGNO)
788         fucomir(f1);
789     else {
790         fldr(f0);
791         fucomipr(f1 + 1);
792     }
793     return (jcc(code, i0));
794 }
795
796 fopi(lt)
797 fopi(le)
798 fopi(eq)
799 fopi(ge)
800 fopi(gt)
801 fopi(ne)
802 fopi(unlt)
803 fopi(unle)
804 fopi(uneq)
805 fopi(unge)
806 fopi(ungt)
807 fopi(ltgt)
808 fopi(ord)
809 fopi(unord)
810 fbopi(lt)
811 fbopi(le)
812 fbopi(eq)
813 fbopi(ge)
814 fbopi(gt)
815 fbopi(ne)
816 fbopi(unlt)
817 fbopi(unle)
818 fbopi(uneq)
819 fbopi(unge)
820 fbopi(ungt)
821 fbopi(ltgt)
822 fbopi(ord)
823 fbopi(unord)
824
825 static void
826 _x87_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0)
827 {
828     union {
829         jit_int32_t      i;
830         jit_float32_t    f;
831     } data;
832     jit_int32_t          reg;
833
834     data.f = *i0;
835     if (data.f == 0.0 && !(data.i & 0x80000000))
836         fldz();
837     else if (data.f == 1.0)
838         fld1();
839     else if (data.f == 3.3219280948873623478703195458468f)
840         fldl2t();
841     else if (data.f == 1.4426950408889634073599246886656f)
842         fldl2e();
843     else if (data.f == 3.1415926535897932384626421096161f)
844         fldpi();
845     else if (data.f == 0.3010299956639811952137387498515f)
846         fldlg2();
847     else if (data.f == 0.6931471805599453094172323683399f)
848         fldln2();
849     else {
850         if (_jitc->no_data) {
851             CHECK_CVT_OFFSET();
852             reg = jit_get_reg(jit_class_gpr);
853             movi(rn(reg), data.i);
854             stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
855             jit_unget_reg(reg);
856             x87_ldxi_f(r0, _RBP_REGNO, CVT_OFFSET);
857         }
858         else
859             x87_ldi_f(r0, (jit_word_t)i0);
860         return;
861     }
862     fstpr(r0 + 1);
863 }
864
865 static void
866 _x87_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
867 {
868     fldsm(0, r1, _NOREG, _SCL1);
869     fstpr(r0 + 1);
870 }
871
872 static void
873 _x87_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
874 {
875     jit_int32_t         reg;
876     if (x87_address_p(i0)) {
877         fldsm(i0, _NOREG, _NOREG, _SCL1);
878         fstpr(r0 + 1);
879     }
880     else {
881         reg = jit_get_reg(jit_class_gpr);
882         movi(rn(reg), i0);
883         x87_ldr_f(r0, rn(reg));
884         jit_unget_reg(reg);
885     }
886 }
887
888 static void
889 _x87_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
890 {
891 #if __X64_32
892     jit_int32_t         reg;
893     reg = jit_get_reg(jit_class_gpr);
894     addr(rn(reg), r1, r2);
895     x87_ldr_f(r0, rn(reg));
896     jit_unget_reg(reg);
897 #else
898     fldsm(0, r1, r2, _SCL1);
899     fstpr(r0 + 1);
900 #endif
901 }
902
903 static void
904 _x87_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
905 {
906     jit_int32_t         reg;
907     if (can_sign_extend_int_p(i0)) {
908         fldsm(i0, r1, _NOREG, _SCL1);
909         fstpr(r0 + 1);
910     }
911     else {
912         reg = jit_get_reg(jit_class_gpr);
913 #if __X64_32
914         addi(rn(reg), r1, i0);
915         x87_ldr_f(r0, rn(reg));
916 #else
917         movi(rn(reg), i0);
918         x87_ldxr_f(r0, r1, rn(reg));
919 #endif
920         jit_unget_reg(reg);
921     }
922 }
923
924 static void
925 _x87_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
926 {
927     if (r1 == _ST0_REGNO)
928         fstsm(0, r0, _NOREG, _SCL1);
929     else {
930         fxchr(r1);
931         fstsm(0, r0, _NOREG, _SCL1);
932         fxchr(r1);
933     }
934 }
935
936 static void
937 _x87_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
938 {
939     jit_int32_t         reg;
940     if (!x87_address_p(i0)) {
941         reg = jit_get_reg(jit_class_gpr);
942         movi(rn(reg), i0);
943         x87_str_f(rn(reg), r0);
944         jit_unget_reg(reg);
945     }
946     else if (r0 == _ST0_REGNO)
947         fstsm(i0, _NOREG, _NOREG, _SCL1);
948     else {
949         fxchr(r0);
950         fstsm(i0, _NOREG, _NOREG, _SCL1);
951         fxchr(r0);
952     }
953 }
954
955 static void
956 _x87_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
957 {
958 #if __X64_32
959     jit_int32_t         reg;
960     reg = jit_get_reg(jit_class_gpr);
961     addr(rn(reg), r0, r1);
962     x87_str_f(rn(reg), r2);
963     jit_unget_reg(reg);
964 #else
965     if (r2 == _ST0_REGNO)
966         fstsm(0, r0, r1, _SCL1);
967     else {
968         fxchr(r2);
969         fstsm(0, r0, r1, _SCL1);
970         fxchr(r2);
971     }
972 #endif
973 }
974
975 static void
976 _x87_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
977 {
978     jit_int32_t         reg;
979     if (!can_sign_extend_int_p(i0)) {
980         reg = jit_get_reg(jit_class_gpr);
981 #if __X64_32
982         addi(rn(reg), r0, i0);
983         x87_str_f(rn(reg), r1);
984 #else
985         movi(rn(reg), i0);
986         x87_stxr_f(rn(reg), r0, r1);
987 #endif
988         jit_unget_reg(reg);
989     }
990     else if (r1 == _ST0_REGNO)
991         fstsm(i0, r0, _NOREG, _SCL1);
992     else {
993         fxchr(r1);
994         fstsm(i0, r0, _NOREG, _SCL1);
995         fxchr(r1);
996     }
997 }
998
999 static void
1000 _x87_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1001 {
1002     if (r0 != r1) {
1003         if (r1 == _ST0)
1004             fstr(r0);
1005         else if (r0 == _ST0) {
1006             fxchr(r1);
1007             fstr(r1);
1008         }
1009         else {
1010             fldr(r1);
1011             fstpr(r0 + 1);
1012         }
1013     }
1014 }
1015
1016 static void
1017 _x87_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
1018 {
1019     union {
1020         jit_int32_t      ii[2];
1021         jit_word_t       w;
1022         jit_float64_t    d;
1023     } data;
1024     jit_int32_t          reg;
1025
1026     data.d = *i0;
1027     if (data.d == 0.0 && !(data.ii[1] & 0x80000000))
1028         fldz();
1029     else if (data.d == 1.0)
1030         fld1();
1031     else if (data.d == 3.3219280948873623478703195458468)
1032         fldl2t();
1033     else if (data.d == 1.4426950408889634073599246886656)
1034         fldl2e();
1035     else if (data.d == 3.1415926535897932384626421096161)
1036         fldpi();
1037     else if (data.d == 0.3010299956639811952137387498515)
1038         fldlg2();
1039     else if (data.d == 0.6931471805599453094172323683399)
1040         fldln2();
1041     else {
1042         if (_jitc->no_data) {
1043             CHECK_CVT_OFFSET();
1044             reg = jit_get_reg(jit_class_gpr);
1045 #if __X32 || __X64_32
1046             movi(rn(reg), data.ii[0]);
1047             stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
1048             movi(rn(reg), data.ii[1]);
1049             stxi_i(CVT_OFFSET + 4, _RBP_REGNO, rn(reg));
1050 #else
1051             movi(rn(reg), data.w);
1052             stxi_l(CVT_OFFSET, _RBP_REGNO, rn(reg));
1053 #endif
1054             jit_unget_reg(reg);
1055             x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET);
1056         }
1057         else
1058             x87_ldi_d(r0, (jit_word_t)i0);
1059         return;
1060     }
1061     fstpr(r0 + 1);
1062 }
1063
1064 dopi(lt)
1065 dopi(le)
1066
1067 static void
1068 _x87_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1069 {
1070     jit_bool_t                  rc;
1071     jit_word_t                  jp_code;
1072     jit_int32_t                 reg, f1, f2;
1073     if (r2 == _ST0_REGNO)       f1 = r2, f2 = r1;
1074     else                        f1 = r1, f2 = r2;
1075     if ((rc = reg8_p(r0)))
1076         reg = r0;
1077     else {
1078         reg = _RAX_REGNO;
1079         movr(r0, reg);
1080     }
1081     ixorr(reg, reg);
1082     if (f1 == _ST0_REGNO)
1083         fucomir(f2);
1084     else {
1085         fldr(f1);
1086         fucomipr(f2 + 1);
1087     }
1088     jp_code = jpes(0);
1089     cc(X86_CC_E, reg);
1090     patch_at(jp_code, _jit->pc.w);
1091     if (!rc)
1092         xchgr(r0, reg);
1093 }
1094
1095 dopi(eq)
1096 dopi(ge)
1097 dopi(gt)
1098
1099 static void
1100 _x87_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1101 {
1102     jit_bool_t                  rc;
1103     jit_word_t                  jp_code;
1104     jit_int32_t                 reg, f1, f2;
1105     if (r2 == _ST0_REGNO)       f1 = r2, f2 = r1;
1106     else                        f1 = r1, f2 = r2;
1107     if ((rc = reg8_p(r0)))
1108         reg = r0;
1109     else {
1110         reg = _RAX_REGNO;
1111         movr(r0, reg);
1112     }
1113     imovi(reg, 1);
1114     if (f1 == _ST0_REGNO)
1115         fucomir(f2);
1116     else {
1117         fldr(f1);
1118         fucomipr(f2 + 1);
1119     }
1120     jp_code = jpes(0);
1121     cc(X86_CC_NE, reg);
1122     patch_at(jp_code, _jit->pc.w);
1123     if (!rc)
1124         xchgr(r0, reg);
1125 }
1126
1127 dopi(ne)
1128 dopi(unlt)
1129 dopi(unle)
1130 dopi(uneq)
1131 dopi(unge)
1132 dopi(ungt)
1133
1134 static void
1135 _x87_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1136 {
1137     if (r1 == r2)
1138         movi(r0, 1);
1139     else
1140         x87cmp2(X86_CC_NE, r0, r1, r2);
1141 }
1142
1143 dopi(ltgt)
1144 dopi(ord)
1145 dopi(unord)
1146
1147 static void
1148 _x87_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1149 {
1150     fldlm(0, r1, _NOREG, _SCL1);
1151     fstpr(r0 + 1);
1152 }
1153
1154 static void
1155 _x87_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1156 {
1157     jit_int32_t         reg;
1158     if (x87_address_p(i0)) {
1159         fldlm(i0, _NOREG, _NOREG, _SCL1);
1160         fstpr(r0 + 1);
1161     }
1162     else {
1163         reg = jit_get_reg(jit_class_gpr);
1164         movi(rn(reg), i0);
1165         x87_ldr_d(r0, rn(reg));
1166         jit_unget_reg(reg);
1167     }
1168 }
1169
1170 static void
1171 _x87_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1172 {
1173 #if __X64_32
1174     jit_int32_t         reg;
1175     reg = jit_get_reg(jit_class_gpr);
1176     addr(rn(reg), r1, r2);
1177     x87_ldr_d(r0, rn(reg));
1178     jit_unget_reg(reg);
1179 #else
1180     fldlm(0, r1, r2, _SCL1);
1181     fstpr(r0 + 1);
1182 #endif
1183 }
1184
1185 static void
1186 _x87_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1187 {
1188     jit_int32_t         reg;
1189     if (can_sign_extend_int_p(i0)) {
1190         fldlm(i0, r1, _NOREG, _SCL1);
1191         fstpr(r0 + 1);
1192     }
1193     else {
1194         reg = jit_get_reg(jit_class_gpr);
1195 #if __X64_32
1196         addi(rn(reg), r1, i0);
1197         x87_ldr_d(r0, rn(reg));
1198 #else
1199         movi(rn(reg), i0);
1200         x87_ldxr_d(r0, r1, rn(reg));
1201 #endif
1202         jit_unget_reg(reg);
1203     }
1204 }
1205
1206 static void
1207 _x87_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1208 {
1209     if (r1 == _ST0_REGNO)
1210         fstlm(0, r0, _NOREG, _SCL1);
1211     else {
1212         fxchr(r1);
1213         fstlm(0, r0, _NOREG, _SCL1);
1214         fxchr(r1);
1215     }
1216 }
1217
1218 static void
1219 _x87_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1220 {
1221     jit_int32_t         reg;
1222     if (!x87_address_p(i0)) {
1223         reg = jit_get_reg(jit_class_gpr);
1224         movi(rn(reg), i0);
1225         x87_str_d(rn(reg), r0);
1226         jit_unget_reg(reg);
1227     }
1228     else if (r0 == _ST0_REGNO)
1229         fstlm(i0, _NOREG, _NOREG, _SCL1);
1230     else {
1231         fxchr(r0);
1232         fstlm(i0, _NOREG, _NOREG, _SCL1);
1233         fxchr(r0);
1234     }
1235 }
1236
1237 static void
1238 _x87_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1239 {
1240 #if __X64_32
1241     jit_int32_t         reg;
1242     reg = jit_get_reg(jit_class_gpr);
1243     addr(rn(reg), r0, r1);
1244     x87_str_d(rn(reg), r2);
1245     jit_unget_reg(reg);
1246 #else
1247     if (r2 == _ST0_REGNO)
1248         fstlm(0, r0, r1, _SCL1);
1249     else {
1250         fxchr(r2);
1251         fstlm(0, r0, r1, _SCL1);
1252         fxchr(r2);
1253     }
1254 #endif
1255 }
1256
1257 static void
1258 _x87_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1259 {
1260     jit_int32_t         reg;
1261     if (!can_sign_extend_int_p(i0)) {
1262         reg = jit_get_reg(jit_class_gpr);
1263 #if __X64_32
1264         addi(rn(reg), r0, i0);
1265         x87_str_d(rn(reg), r1);
1266 #else
1267         movi(rn(reg), i0);
1268         x87_stxr_d(rn(reg), r0, r1);
1269 #endif
1270         jit_unget_reg(reg);
1271     }
1272     else if (r1 == _ST0_REGNO)
1273         fstlm(i0, r0, _NOREG, _SCL1);
1274     else {
1275         fxchr(r1);
1276         fstlm(i0, r0, _NOREG, _SCL1);
1277         fxchr(r1);
1278     }
1279 }
1280
1281 dbopi(lt)
1282 dbopi(le)
1283
1284 static jit_word_t
1285 _x87_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1286 {
1287     jit_word_t                  w;
1288     jit_int32_t                 f0, f1;
1289     jit_word_t                  jp_code;
1290     if (r1 == _ST0_REGNO)       f0 = r1, f1 = r0;
1291     else                        f0 = r0, f1 = r1;
1292     if (f0 == _ST0_REGNO)
1293         fucomir(f1);
1294     else {
1295         fldr(f0);
1296         fucomipr(f1 + 1);
1297     }
1298     jp_code = jpes(0);
1299     w = jcc(X86_CC_E, i0);
1300     patch_at(jp_code, _jit->pc.w);
1301     return (w);
1302 }
1303 dbopi(eq)
1304 dbopi(ge)
1305 dbopi(gt)
1306
1307 static jit_word_t
1308 _x87_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1309 {
1310     jit_word_t                  w;
1311     jit_int32_t                 f0, f1;
1312     jit_word_t                  jp_code;
1313     jit_word_t                  jz_code;
1314     if (r1 == _ST0_REGNO)       f0 = r1, f1 = r0;
1315     else                        f0 = r0, f1 = r1;
1316     if (f0 == _ST0_REGNO)
1317         fucomir(f1);
1318     else {
1319         fldr(f0);
1320         fucomipr(f1 + 1);
1321     }
1322     jp_code = jpes(0);
1323     jz_code = jzs(0);
1324     patch_at(jp_code, _jit->pc.w);
1325     w = jmpi(i0);
1326     patch_at(jz_code, _jit->pc.w);
1327     return (w);
1328 }
1329 dbopi(ne)
1330 dbopi(unlt)
1331 dbopi(unle)
1332 dbopi(uneq)
1333 dbopi(unge)
1334 dbopi(ungt)
1335 dbopi(ltgt)
1336 dbopi(ord)
1337 dbopi(unord)
1338 #  undef fopi
1339 #  undef fbopi
1340 #  undef dopi
1341 #  undef dbopi
1342 #  undef fpr_bopi
1343 #  undef fpr_opi
1344 #endif