Merge pull request #377 from pcercuei/libretro
[pcsx_rearmed.git] / deps / lightning / lib / jit_x86-x87.c
1 /*
2  * Copyright (C) 2012-2019  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          word;                                           \
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     word = x87_b##name##r_##type(i0, r0, rn(reg));                      \
417     jit_unget_reg(reg);                                                 \
418     return (word);                                                      \
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 #if defined(sun)
666     /* for the sake of passing test cases in x87 mode, otherwise only sse
667      * is supported */
668     fstcwm(-4, _RBP_REGNO, _NOREG, _SCL1);
669     ldxi_s(r0, _RBP_REGNO, -4);
670     extr_uc(r0, r0);
671 #  define FPCW_CHOP     0xc00
672     ori(r0, r0, FPCW_CHOP);
673     stxi_s(-8, _RBP_REGNO, r0);
674     fldcwm(-8, _RBP_REGNO, _NOREG, _SCL1);
675     if (r1 == _ST0_REGNO)
676         fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
677     else {
678         fxchr(r1);
679         fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
680         fxchr(r1);
681     }
682     fldcwm(-4, _RBP_REGNO, _NOREG, _SCL1);
683     ldxi(r0, _RBP_REGNO, CVT_OFFSET);
684 #else
685     fldr(r1);
686     fisttplm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
687     ldxi_i(r0, _RBP_REGNO, CVT_OFFSET);
688 #endif
689 }
690
691 #  if __X64
692 static void
693 _x87_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
694 {
695     fldr(r1);
696     fisttpqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
697     ldxi(r0, _RBP_REGNO, CVT_OFFSET);
698 }
699 #  endif
700
701 static void
702 _x87_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
703 {
704     stxi(CVT_OFFSET, _RBP_REGNO, r1);
705 #  if __X32
706     fildlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
707 #  else
708     fildqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
709 #  endif
710     fstpr(r0 + 1);
711 }
712
713 static void
714 _x87cmp(jit_state_t *_jit, jit_int32_t code,
715         jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
716 {
717     jit_bool_t          rc;
718     jit_int32_t         reg;
719     if ((rc = reg8_p(r0)))
720         reg = r0;
721     else {
722         reg = _RAX_REGNO;
723         movr(r0, reg);
724     }
725     ixorr(reg, reg);
726     if (r1 == _ST0_REGNO)
727         fucomir(r2);
728     else {
729         fldr(r1);
730         fucomipr(r2 + 1);
731     }
732     cc(code, reg);
733     if (!rc)
734         xchgr(r0, reg);
735 }
736
737 static void
738 _x87cmp2(jit_state_t *_jit, jit_int32_t code,
739          jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
740 {
741     jit_bool_t                  rc;
742     jit_int32_t                 reg;
743     jit_int32_t                 f1, f2;
744     if (r2 == _ST0_REGNO)       f1 = r2, f2 = r1;
745     else                        f1 = r1, f2 = r2;
746     if ((rc = reg8_p(r0)))
747         reg = r0;
748     else {
749         reg = _RAX_REGNO;
750         movr(r0, reg);
751     }
752     ixorr(reg, reg);
753     if (f1 == _ST0_REGNO)
754         fucomir(f2);
755     else {
756         fldr(f1);
757         fucomipr(f2 + 1);
758     }
759     cc(code, reg);
760     if (!rc)
761         xchgr(r0, reg);
762 }
763
764 static jit_word_t
765 _x87jcc(jit_state_t *_jit, jit_int32_t code,
766         jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
767 {
768     if (r0 == _ST0_REGNO)
769         fucomir(r1);
770     else {
771         fldr(r0);
772         fucomipr(r1 + 1);
773     }
774     jcc(code, i0);
775     return (_jit->pc.w);
776 }
777
778 static jit_word_t
779 _x87jcc2(jit_state_t *_jit, jit_int32_t code,
780          jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
781 {
782     jit_int32_t                 f0, f1;
783     if (r1 == _ST0_REGNO)       f0 = r1, f1 = r0;
784     else                        f0 = r0, f1 = r1;
785     if (f0 == _ST0_REGNO)
786         fucomir(f1);
787     else {
788         fldr(f0);
789         fucomipr(f1 + 1);
790     }
791     jcc(code, i0);
792     return (_jit->pc.w);
793 }
794
795 fopi(lt)
796 fopi(le)
797 fopi(eq)
798 fopi(ge)
799 fopi(gt)
800 fopi(ne)
801 fopi(unlt)
802 fopi(unle)
803 fopi(uneq)
804 fopi(unge)
805 fopi(ungt)
806 fopi(ltgt)
807 fopi(ord)
808 fopi(unord)
809 fbopi(lt)
810 fbopi(le)
811 fbopi(eq)
812 fbopi(ge)
813 fbopi(gt)
814 fbopi(ne)
815 fbopi(unlt)
816 fbopi(unle)
817 fbopi(uneq)
818 fbopi(unge)
819 fbopi(ungt)
820 fbopi(ltgt)
821 fbopi(ord)
822 fbopi(unord)
823
824 static void
825 _x87_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0)
826 {
827     union {
828         jit_int32_t      i;
829         jit_float32_t    f;
830     } data;
831     jit_int32_t          reg;
832
833     data.f = *i0;
834     if (data.f == 0.0 && !(data.i & 0x80000000))
835         fldz();
836     else if (data.f == 1.0)
837         fld1();
838     else if (data.f == 3.3219280948873623478703195458468f)
839         fldl2t();
840     else if (data.f == 1.4426950408889634073599246886656f)
841         fldl2e();
842     else if (data.f == 3.1415926535897932384626421096161f)
843         fldpi();
844     else if (data.f == 0.3010299956639811952137387498515f)
845         fldlg2();
846     else if (data.f == 0.6931471805599453094172323683399f)
847         fldln2();
848     else {
849         if (_jitc->no_data) {
850             reg = jit_get_reg(jit_class_gpr);
851             movi(rn(reg), data.i);
852             stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
853             jit_unget_reg(reg);
854             x87_ldxi_f(r0, _RBP_REGNO, CVT_OFFSET);
855         }
856         else
857             x87_ldi_f(r0, (jit_word_t)i0);
858         return;
859     }
860     fstpr(r0 + 1);
861 }
862
863 static void
864 _x87_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
865 {
866     fldsm(0, r1, _NOREG, _SCL1);
867     fstpr(r0 + 1);
868 }
869
870 static void
871 _x87_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
872 {
873     jit_int32_t         reg;
874     if (x87_address_p(i0)) {
875         fldsm(i0, _NOREG, _NOREG, _SCL1);
876         fstpr(r0 + 1);
877     }
878     else {
879         reg = jit_get_reg(jit_class_gpr);
880         movi(rn(reg), i0);
881         x87_ldr_f(r0, rn(reg));
882         jit_unget_reg(reg);
883     }
884 }
885
886 static void
887 _x87_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
888 {
889 #if __X64_32
890     jit_int32_t         reg;
891     reg = jit_get_reg(jit_class_gpr);
892     addr(rn(reg), r1, r2);
893     x87_ldr_f(r0, rn(reg));
894     jit_unget_reg(reg);
895 #else
896     fldsm(0, r1, r2, _SCL1);
897     fstpr(r0 + 1);
898 #endif
899 }
900
901 static void
902 _x87_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
903 {
904     jit_int32_t         reg;
905     if (can_sign_extend_int_p(i0)) {
906         fldsm(i0, r1, _NOREG, _SCL1);
907         fstpr(r0 + 1);
908     }
909     else {
910         reg = jit_get_reg(jit_class_gpr);
911 #if __X64_32
912         addi(rn(reg), r1, i0);
913         x87_ldr_f(r0, rn(reg));
914 #else
915         movi(rn(reg), i0);
916         x87_ldxr_f(r0, r1, rn(reg));
917 #endif
918         jit_unget_reg(reg);
919     }
920 }
921
922 static void
923 _x87_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
924 {
925     if (r1 == _ST0_REGNO)
926         fstsm(0, r0, _NOREG, _SCL1);
927     else {
928         fxchr(r1);
929         fstsm(0, r0, _NOREG, _SCL1);
930         fxchr(r1);
931     }
932 }
933
934 static void
935 _x87_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
936 {
937     jit_int32_t         reg;
938     if (!x87_address_p(i0)) {
939         reg = jit_get_reg(jit_class_gpr);
940         movi(rn(reg), i0);
941         x87_str_f(rn(reg), r0);
942         jit_unget_reg(reg);
943     }
944     else if (r0 == _ST0_REGNO)
945         fstsm(i0, _NOREG, _NOREG, _SCL1);
946     else {
947         fxchr(r0);
948         fstsm(i0, _NOREG, _NOREG, _SCL1);
949         fxchr(r0);
950     }
951 }
952
953 static void
954 _x87_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
955 {
956 #if __X64_32
957     jit_int32_t         reg;
958     reg = jit_get_reg(jit_class_gpr);
959     addr(rn(reg), r0, r1);
960     x87_str_f(rn(reg), r2);
961     jit_unget_reg(reg);
962 #else
963     if (r2 == _ST0_REGNO)
964         fstsm(0, r0, r1, _SCL1);
965     else {
966         fxchr(r2);
967         fstsm(0, r0, r1, _SCL1);
968         fxchr(r2);
969     }
970 #endif
971 }
972
973 static void
974 _x87_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
975 {
976     jit_int32_t         reg;
977     if (!can_sign_extend_int_p(i0)) {
978         reg = jit_get_reg(jit_class_gpr);
979 #if __X64_32
980         addi(rn(reg), r0, i0);
981         x87_str_f(rn(reg), r1);
982 #else
983         movi(rn(reg), i0);
984         x87_stxr_f(rn(reg), r0, r1);
985 #endif
986         jit_unget_reg(reg);
987     }
988     else if (r1 == _ST0_REGNO)
989         fstsm(i0, r0, _NOREG, _SCL1);
990     else {
991         fxchr(r1);
992         fstsm(i0, r0, _NOREG, _SCL1);
993         fxchr(r1);
994     }
995 }
996
997 static void
998 _x87_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
999 {
1000     if (r0 != r1) {
1001         if (r1 == _ST0)
1002             fstr(r0);
1003         else if (r0 == _ST0) {
1004             fxchr(r1);
1005             fstr(r1);
1006         }
1007         else {
1008             fldr(r1);
1009             fstpr(r0 + 1);
1010         }
1011     }
1012 }
1013
1014 static void
1015 _x87_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
1016 {
1017     union {
1018         jit_int32_t      ii[2];
1019         jit_word_t       w;
1020         jit_float64_t    d;
1021     } data;
1022     jit_int32_t          reg;
1023
1024     data.d = *i0;
1025     if (data.d == 0.0 && !(data.ii[1] & 0x80000000))
1026         fldz();
1027     else if (data.d == 1.0)
1028         fld1();
1029     else if (data.d == 3.3219280948873623478703195458468)
1030         fldl2t();
1031     else if (data.d == 1.4426950408889634073599246886656)
1032         fldl2e();
1033     else if (data.d == 3.1415926535897932384626421096161)
1034         fldpi();
1035     else if (data.d == 0.3010299956639811952137387498515)
1036         fldlg2();
1037     else if (data.d == 0.6931471805599453094172323683399)
1038         fldln2();
1039     else {
1040         if (_jitc->no_data) {
1041             reg = jit_get_reg(jit_class_gpr);
1042 #if __X32 || __X64_32
1043             movi(rn(reg), data.ii[0]);
1044             stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
1045             movi(rn(reg), data.ii[1]);
1046             stxi_i(CVT_OFFSET + 4, _RBP_REGNO, rn(reg));
1047 #else
1048             movi(rn(reg), data.w);
1049             stxi_l(CVT_OFFSET, _RBP_REGNO, rn(reg));
1050 #endif
1051             jit_unget_reg(reg);
1052             x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET);
1053         }
1054         else
1055             x87_ldi_d(r0, (jit_word_t)i0);
1056         return;
1057     }
1058     fstpr(r0 + 1);
1059 }
1060
1061 dopi(lt)
1062 dopi(le)
1063
1064 static void
1065 _x87_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1066 {
1067     jit_bool_t                  rc;
1068     jit_word_t                  jp_code;
1069     jit_int32_t                 reg, f1, f2;
1070     if (r2 == _ST0_REGNO)       f1 = r2, f2 = r1;
1071     else                        f1 = r1, f2 = r2;
1072     if ((rc = reg8_p(r0)))
1073         reg = r0;
1074     else {
1075         reg = _RAX_REGNO;
1076         movr(r0, reg);
1077     }
1078     ixorr(reg, reg);
1079     if (f1 == _ST0_REGNO)
1080         fucomir(f2);
1081     else {
1082         fldr(f1);
1083         fucomipr(f2 + 1);
1084     }
1085     jpes(0);
1086     jp_code = _jit->pc.w;
1087     cc(X86_CC_E, reg);
1088     patch_rel_char(jp_code, _jit->pc.w);
1089     if (!rc)
1090         xchgr(r0, reg);
1091 }
1092
1093 dopi(eq)
1094 dopi(ge)
1095 dopi(gt)
1096
1097 static void
1098 _x87_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1099 {
1100     jit_bool_t                  rc;
1101     jit_word_t                  jp_code;
1102     jit_int32_t                 reg, f1, f2;
1103     if (r2 == _ST0_REGNO)       f1 = r2, f2 = r1;
1104     else                        f1 = r1, f2 = r2;
1105     if ((rc = reg8_p(r0)))
1106         reg = r0;
1107     else {
1108         reg = _RAX_REGNO;
1109         movr(r0, reg);
1110     }
1111     imovi(reg, 1);
1112     if (f1 == _ST0_REGNO)
1113         fucomir(f2);
1114     else {
1115         fldr(f1);
1116         fucomipr(f2 + 1);
1117     }
1118     jpes(0);
1119     jp_code = _jit->pc.w;
1120     cc(X86_CC_NE, reg);
1121     patch_rel_char(jp_code, _jit->pc.w);
1122     if (!rc)
1123         xchgr(r0, reg);
1124 }
1125
1126 dopi(ne)
1127 dopi(unlt)
1128 dopi(unle)
1129 dopi(uneq)
1130 dopi(unge)
1131 dopi(ungt)
1132
1133 static void
1134 _x87_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1135 {
1136     if (r1 == r2)
1137         movi(r0, 1);
1138     else
1139         x87cmp2(X86_CC_NE, r0, r1, r2);
1140 }
1141
1142 dopi(ltgt)
1143 dopi(ord)
1144 dopi(unord)
1145
1146 static void
1147 _x87_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1148 {
1149     fldlm(0, r1, _NOREG, _SCL1);
1150     fstpr(r0 + 1);
1151 }
1152
1153 static void
1154 _x87_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
1155 {
1156     jit_int32_t         reg;
1157     if (x87_address_p(i0)) {
1158         fldlm(i0, _NOREG, _NOREG, _SCL1);
1159         fstpr(r0 + 1);
1160     }
1161     else {
1162         reg = jit_get_reg(jit_class_gpr);
1163         movi(rn(reg), i0);
1164         x87_ldr_d(r0, rn(reg));
1165         jit_unget_reg(reg);
1166     }
1167 }
1168
1169 static void
1170 _x87_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1171 {
1172 #if __X64_32
1173     jit_int32_t         reg;
1174     reg = jit_get_reg(jit_class_gpr);
1175     addr(rn(reg), r1, r2);
1176     x87_ldr_d(r0, rn(reg));
1177     jit_unget_reg(reg);
1178 #else
1179     fldlm(0, r1, r2, _SCL1);
1180     fstpr(r0 + 1);
1181 #endif
1182 }
1183
1184 static void
1185 _x87_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
1186 {
1187     jit_int32_t         reg;
1188     if (can_sign_extend_int_p(i0)) {
1189         fldlm(i0, r1, _NOREG, _SCL1);
1190         fstpr(r0 + 1);
1191     }
1192     else {
1193         reg = jit_get_reg(jit_class_gpr);
1194 #if __X64_32
1195         addi(rn(reg), r1, i0);
1196         x87_ldr_d(r0, rn(reg));
1197 #else
1198         movi(rn(reg), i0);
1199         x87_ldxr_d(r0, r1, rn(reg));
1200 #endif
1201         jit_unget_reg(reg);
1202     }
1203 }
1204
1205 static void
1206 _x87_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
1207 {
1208     if (r1 == _ST0_REGNO)
1209         fstlm(0, r0, _NOREG, _SCL1);
1210     else {
1211         fxchr(r1);
1212         fstlm(0, r0, _NOREG, _SCL1);
1213         fxchr(r1);
1214     }
1215 }
1216
1217 static void
1218 _x87_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
1219 {
1220     jit_int32_t         reg;
1221     if (!x87_address_p(i0)) {
1222         reg = jit_get_reg(jit_class_gpr);
1223         movi(rn(reg), i0);
1224         x87_str_d(rn(reg), r0);
1225         jit_unget_reg(reg);
1226     }
1227     else if (r0 == _ST0_REGNO)
1228         fstlm(i0, _NOREG, _NOREG, _SCL1);
1229     else {
1230         fxchr(r0);
1231         fstlm(i0, _NOREG, _NOREG, _SCL1);
1232         fxchr(r0);
1233     }
1234 }
1235
1236 static void
1237 _x87_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
1238 {
1239 #if __X64_32
1240     jit_int32_t         reg;
1241     reg = jit_get_reg(jit_class_gpr);
1242     addr(rn(reg), r0, r1);
1243     x87_str_d(rn(reg), r2);
1244     jit_unget_reg(reg);
1245 #else
1246     if (r2 == _ST0_REGNO)
1247         fstlm(0, r0, r1, _SCL1);
1248     else {
1249         fxchr(r2);
1250         fstlm(0, r0, r1, _SCL1);
1251         fxchr(r2);
1252     }
1253 #endif
1254 }
1255
1256 static void
1257 _x87_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1258 {
1259     jit_int32_t         reg;
1260     if (!can_sign_extend_int_p(i0)) {
1261         reg = jit_get_reg(jit_class_gpr);
1262 #if __X64_32
1263         addi(rn(reg), r0, i0);
1264         x87_str_d(rn(reg), r1);
1265 #else
1266         movi(rn(reg), i0);
1267         x87_stxr_d(rn(reg), r0, r1);
1268 #endif
1269         jit_unget_reg(reg);
1270     }
1271     else if (r1 == _ST0_REGNO)
1272         fstlm(i0, r0, _NOREG, _SCL1);
1273     else {
1274         fxchr(r1);
1275         fstlm(i0, r0, _NOREG, _SCL1);
1276         fxchr(r1);
1277     }
1278 }
1279
1280 dbopi(lt)
1281 dbopi(le)
1282
1283 static jit_word_t
1284 _x87_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1285 {
1286     jit_int32_t                 f0, f1;
1287     jit_word_t                  jp_code;
1288     if (r1 == _ST0_REGNO)       f0 = r1, f1 = r0;
1289     else                        f0 = r0, f1 = r1;
1290     if (f0 == _ST0_REGNO)
1291         fucomir(f1);
1292     else {
1293         fldr(f0);
1294         fucomipr(f1 + 1);
1295     }
1296     jpes(0);
1297     jp_code = _jit->pc.w;
1298     jcc(X86_CC_E, i0);
1299     patch_rel_char(jp_code, _jit->pc.w);
1300     return (_jit->pc.w);
1301 }
1302 dbopi(eq)
1303 dbopi(ge)
1304 dbopi(gt)
1305
1306 static jit_word_t
1307 _x87_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
1308 {
1309     jit_int32_t                 f0, f1;
1310     jit_word_t                  jp_code;
1311     jit_word_t                  jz_code;
1312     if (r1 == _ST0_REGNO)       f0 = r1, f1 = r0;
1313     else                        f0 = r0, f1 = r1;
1314     if (f0 == _ST0_REGNO)
1315         fucomir(f1);
1316     else {
1317         fldr(f0);
1318         fucomipr(f1 + 1);
1319     }
1320     jpes(0);
1321     jp_code = _jit->pc.w;
1322     jzs(0);
1323     jz_code = _jit->pc.w;
1324     patch_rel_char(jp_code, _jit->pc.w);
1325     jmpi(i0);
1326     patch_rel_char(jz_code, _jit->pc.w);
1327     return (_jit->pc.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