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