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