1 /*
2  * Copyright (C) 2013-2019  Free Software Foundation, Inc.
3  *
4  * This file is part of GNU lightning.
5  *
6  * GNU lightning is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * GNU lightning is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14  * License for more details.
15  *
16  * Authors:
17  *	Paulo Cesar Pereira de Andrade
18  */
19 
20 #if PROTO
21 #  define A64_SCVTF			0x1e220000
22 #  define A64_FMOVWV			0x1e260000
23 #  define A64_FMOVVW			0x1e270000
24 #  define A64_FMOVXV			0x9e260000
25 #  define A64_FMOVVX			0x9e270000
26 #  define A64_FCVTZS			0x1e380000
27 #  define A64_FCMPE			0x1e202010
28 #  define A64_FMOV			0x1e204000
29 #  define A64_FABS			0x1e20c000
30 #  define A64_FNEG			0x1e214000
31 #  define A64_FSQRT			0x1e21c000
32 #  define A64_FCVTS			0x1e224000
33 #  define A64_FCVTD			0x1e22c000
34 #  define A64_FMUL			0x1e200800
35 #  define A64_FDIV			0x1e201800
36 #  define A64_FADD			0x1e202800
37 #  define A64_FSUB			0x1e203800
38 #  define FCMPES(Rn,Rm)			os_vv(A64_FCMPE,0,Rn,Rm)
39 #  define FCMPED(Rn,Rm)			os_vv(A64_FCMPE,1,Rn,Rm)
40 #  define FMOVS(Rd,Rn)			osvv_(A64_FMOV,0,Rd,Rn)
41 #  define FMOVD(Rd,Rn)			osvv_(A64_FMOV,1,Rd,Rn)
42 #  define FMOVWS(Rd,Rn)			osvv_(A64_FMOVWV,0,Rd,Rn)
43 #  define FMOVSW(Rd,Rn)			osvv_(A64_FMOVVW,0,Rd,Rn)
44 #  define FMOVXD(Rd,Rn)			osvv_(A64_FMOVXV,1,Rd,Rn)
45 #  define FMOVDX(Rd,Rn)			osvv_(A64_FMOVVX,1,Rd,Rn)
46 #  define FCVT_SD(Rd,Rn)		osvv_(A64_FCVTS,1,Rd,Rn)
47 #  define FCVT_DS(Rd,Rn)		osvv_(A64_FCVTD,0,Rd,Rn)
48 #  define SCVTFS(Rd,Rn)			osvv_(A64_SCVTF|XS,0,Rd,Rn)
49 #  define SCVTFD(Rd,Rn)			osvv_(A64_SCVTF|XS,1,Rd,Rn)
50 #  define FCVTSZ_WS(Rd,Rn)		osvv_(A64_FCVTZS,0,Rd,Rn)
51 #  define FCVTSZ_WD(Rd,Rn)		osvv_(A64_FCVTZS,1,Rd,Rn)
52 #  define FCVTSZ_XS(Rd,Rn)		osvv_(A64_FCVTZS|XS,0,Rd,Rn)
53 #  define FCVTSZ_XD(Rd,Rn)		osvv_(A64_FCVTZS|XS,1,Rd,Rn)
54 #  define FABSS(Rd,Rn)			osvv_(A64_FABS,0,Rd,Rn)
55 #  define FABSD(Rd,Rn)			osvv_(A64_FABS,1,Rd,Rn)
56 #  define FNEGS(Rd,Rn)			osvv_(A64_FNEG,0,Rd,Rn)
57 #  define FNEGD(Rd,Rn)			osvv_(A64_FNEG,1,Rd,Rn)
58 #  define FSQRTS(Rd,Rn)			osvv_(A64_FSQRT,0,Rd,Rn)
59 #  define FSQRTD(Rd,Rn)			osvv_(A64_FSQRT,1,Rd,Rn)
60 #  define FADDS(Rd,Rn,Rm)		osvvv(A64_FADD,0,Rd,Rn,Rm)
61 #  define FADDD(Rd,Rn,Rm)		osvvv(A64_FADD,1,Rd,Rn,Rm)
62 #  define FSUBS(Rd,Rn,Rm)		osvvv(A64_FSUB,0,Rd,Rn,Rm)
63 #  define FSUBD(Rd,Rn,Rm)		osvvv(A64_FSUB,1,Rd,Rn,Rm)
64 #  define FMULS(Rd,Rn,Rm)		osvvv(A64_FMUL,0,Rd,Rn,Rm)
65 #  define FMULD(Rd,Rn,Rm)		osvvv(A64_FMUL,1,Rd,Rn,Rm)
66 #  define FDIVS(Rd,Rn,Rm)		osvvv(A64_FDIV,0,Rd,Rn,Rm)
67 #  define FDIVD(Rd,Rn,Rm)		osvvv(A64_FDIV,1,Rd,Rn,Rm)
68 #  define osvvv(Op,Sz,Rd,Rn,Rm)		_osvvv(_jit,Op,Sz,Rd,Rn,Rm)
69 static void _osvvv(jit_state_t*,jit_int32_t,jit_int32_t,
70 		   jit_int32_t,jit_int32_t,jit_int32_t);
71 #  define osvv_(Op,Sz,Rd,Rn)		_osvv_(_jit,Op,Sz,Rd,Rn)
72 static void _osvv_(jit_state_t*,jit_int32_t,
73 		   jit_int32_t,jit_int32_t,jit_int32_t);
74 #  define os_vv(Op,Sz,Rn,Rm)		_os_vv(_jit,Op,Sz,Rn,Rm)
75 static void _os_vv(jit_state_t*,jit_int32_t,
76 		   jit_int32_t,jit_int32_t,jit_int32_t);
77 #  define truncr_f_i(r0,r1)		_truncr_f_i(_jit,r0,r1)
78 static void _truncr_f_i(jit_state_t*,jit_int32_t,jit_int32_t);
79 #  define truncr_f_l(r0,r1)		FCVTSZ_XS(r0,r1)
80 #  define truncr_d_i(r0,r1)		_truncr_d_i(_jit,r0,r1)
81 static void _truncr_d_i(jit_state_t*,jit_int32_t,jit_int32_t);
82 #  define truncr_d_l(r0,r1)		FCVTSZ_XD(r0,r1)
83 #  define addr_f(r0,r1,r2)		FADDS(r0,r1,r2)
84 #  define addi_f(r0,r1,i0)		_addi_f(_jit,r0,r1,i0)
85 static void _addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
86 #  define subr_f(r0,r1,r2)		FSUBS(r0,r1,r2)
87 #  define subi_f(r0,r1,i0)		_subi_f(_jit,r0,r1,i0)
88 static void _subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
89 #  define rsbr_f(r0, r1, r2)		subr_f(r0, r2, r1)
90 #  define rsbi_f(r0, r1, i0)		_rsbi_f(_jit, r0, r1, i0)
91 static void _rsbi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
92 #  define mulr_f(r0,r1,r2)		FMULS(r0,r1,r2)
93 #  define muli_f(r0,r1,i0)		_muli_f(_jit,r0,r1,i0)
94 static void _muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
95 #  define divr_f(r0,r1,r2)		FDIVS(r0,r1,r2)
96 #  define divi_f(r0,r1,i0)		_divi_f(_jit,r0,r1,i0)
97 static void _divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
98 #  define absr_f(r0,r1)			FABSS(r0,r1)
99 #  define negr_f(r0,r1)			FNEGS(r0,r1)
100 #  define sqrtr_f(r0,r1)		FSQRTS(r0,r1)
101 #  define extr_f(r0,r1)			SCVTFS(r0,r1)
102 #  define ldr_f(r0,r1)			_ldr_f(_jit,r0,r1)
103 static void _ldr_f(jit_state_t*,jit_int32_t,jit_int32_t);
104 #  define ldi_f(r0,i0)			_ldi_f(_jit,r0,i0)
105 static void _ldi_f(jit_state_t*,jit_int32_t,jit_word_t);
106 #  define ldxr_f(r0,r1,r2)		_ldxr_f(_jit,r0,r1,r2)
107 static void _ldxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
108 #  define ldxi_f(r0,r1,i0)		_ldxi_f(_jit,r0,r1,i0)
109 static void _ldxi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
110 #  define str_f(r0,r1)			_str_f(_jit,r0,r1)
111 static void _str_f(jit_state_t*,jit_int32_t,jit_int32_t);
112 #  define sti_f(i0,r0)			_sti_f(_jit,i0,r0)
113 static void _sti_f(jit_state_t*,jit_word_t,jit_int32_t);
114 #  define stxr_f(r0,r1,r2)		_stxr_f(_jit,r0,r1,r2)
115 static void _stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
116 #  define stxi_f(i0,r0,r1)		_stxi_f(_jit,i0,r0,r1)
117 static void _stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
118 #  define movr_f(r0,r1)			_movr_f(_jit,r0,r1)
119 static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t);
120 #  define movi_f(r0,i0)			_movi_f(_jit,r0,i0)
121 static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t);
122 #  define extr_d_f(r0,r1)		FCVT_SD(r0,r1)
123 #  define fccr(cc,r0,r1,r2)		_fccr(_jit,cc,r0,r1,r2)
124 static void _fccr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
125 #  define fcci(cc,r0,r1,i0)		_fcci(_jit,cc,r0,r1,i0)
126 static void _fcci(jit_state_t*,
127 		  jit_int32_t,jit_int32_t,jit_int32_t,jit_float32_t);
128 #  define ltr_f(r0,r1,r2)		fccr(CC_MI,r0,r1,r2)
129 #  define lti_f(r0,r1,i0)		fcci(CC_MI,r0,r1,i0)
130 #  define ler_f(r0,r1,r2)		fccr(CC_LS,r0,r1,r2)
131 #  define lei_f(r0,r1,i0)		fcci(CC_LS,r0,r1,i0)
132 #  define eqr_f(r0,r1,r2)		fccr(CC_EQ,r0,r1,r2)
133 #  define eqi_f(r0,r1,i0)		fcci(CC_EQ,r0,r1,i0)
134 #  define ger_f(r0,r1,r2)		fccr(CC_GE,r0,r1,r2)
135 #  define gei_f(r0,r1,i0)		fcci(CC_GE,r0,r1,i0)
136 #  define gtr_f(r0,r1,r2)		fccr(CC_GT,r0,r1,r2)
137 #  define gti_f(r0,r1,i0)		fcci(CC_GT,r0,r1,i0)
138 #  define ner_f(r0,r1,r2)		fccr(CC_NE,r0,r1,r2)
139 #  define nei_f(r0,r1,i0)		fcci(CC_NE,r0,r1,i0)
140 #  define unltr_f(r0,r1,r2)		fccr(CC_LT,r0,r1,r2)
141 #  define unlti_f(r0,r1,i0)		fcci(CC_LT,r0,r1,i0)
142 #  define unler_f(r0,r1,r2)		fccr(CC_LE,r0,r1,r2)
143 #  define unlei_f(r0,r1,i0)		fcci(CC_LE,r0,r1,i0)
144 #  define uneqr_f(r0,r1,r2)		_uneqr_f(_jit,r0,r1,r2)
145 static void _uneqr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
146 #  define uneqi_f(r0,r1,i0)		_uneqi_f(_jit,r0,r1,i0)
147 static void _uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
148 #  define unger_f(r0,r1,r2)		fccr(CC_PL,r0,r1,r2)
149 #  define ungei_f(r0,r1,i0)		fcci(CC_PL,r0,r1,i0)
150 #  define ungtr_f(r0,r1,r2)		fccr(CC_HI,r0,r1,r2)
151 #  define ungti_f(r0,r1,i0)		fcci(CC_HI,r0,r1,i0)
152 #  define ltgtr_f(r0,r1,r2)		_ltgtr_f(_jit,r0,r1,r2)
153 static void _ltgtr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
154 #  define ltgti_f(r0,r1,i0)		_ltgti_f(_jit,r0,r1,i0)
155 static void _ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t);
156 #  define ordr_f(r0,r1,r2)		fccr(CC_VC,r0,r1,r2)
157 #  define ordi_f(r0,r1,i0)		fcci(CC_VC,r0,r1,i0)
158 #  define unordr_f(r0,r1,r2)		fccr(CC_VS,r0,r1,r2)
159 #  define unordi_f(r0,r1,i0)		fcci(CC_VS,r0,r1,i0)
160 #define fbccr(cc,i0,r0,r1)		_fbccr(_jit,cc,i0,r0,r1)
161 static jit_word_t
162 _fbccr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
163 #define fbcci(cc,i0,r0,i1)		_fbcci(_jit,cc,i0,r0,i1)
164 static jit_word_t
165 _fbcci(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float32_t);
166 #  define bltr_f(i0,r0,r1)		fbccr(BCC_MI,i0,r0,r1)
167 #  define blti_f(i0,r0,i1)		fbcci(BCC_MI,i0,r0,i1)
168 #  define bler_f(i0,r0,r1)		fbccr(BCC_LS,i0,r0,r1)
169 #  define blei_f(i0,r0,i1)		fbcci(BCC_LS,i0,r0,i1)
170 #  define beqr_f(i0,r0,r1)		fbccr(BCC_EQ,i0,r0,r1)
171 #  define beqi_f(i0,r0,i1)		fbcci(BCC_EQ,i0,r0,i1)
172 #  define bger_f(i0,r0,r1)		fbccr(BCC_GE,i0,r0,r1)
173 #  define bgei_f(i0,r0,i1)		fbcci(BCC_GE,i0,r0,i1)
174 #  define bgtr_f(i0,r0,r1)		fbccr(BCC_GT,i0,r0,r1)
175 #  define bgti_f(i0,r0,i1)		fbcci(BCC_GT,i0,r0,i1)
176 #  define bner_f(i0,r0,r1)		fbccr(BCC_NE,i0,r0,r1)
177 #  define bnei_f(i0,r0,i1)		fbcci(BCC_NE,i0,r0,i1)
178 #  define bunltr_f(i0,r0,r1)		fbccr(BCC_LT,i0,r0,r1)
179 #  define bunlti_f(i0,r0,i1)		fbcci(BCC_LT,i0,r0,i1)
180 #  define bunler_f(i0,r0,r1)		fbccr(BCC_LE,i0,r0,r1)
181 #  define bunlei_f(i0,r0,i1)		fbcci(BCC_LE,i0,r0,i1)
182 #  define buneqr_f(i0,r0,r1)		_buneqr_f(_jit,i0,r0,r1)
183 static jit_word_t _buneqr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
184 #  define buneqi_f(i0,r0,i1)		_buneqi_f(_jit,i0,r0,i1)
185 static jit_word_t _buneqi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
186 #  define bunger_f(i0,r0,r1)		fbccr(BCC_PL,i0,r0,r1)
187 #  define bungei_f(i0,r0,i1)		fbcci(BCC_PL,i0,r0,i1)
188 #  define bungtr_f(i0,r0,r1)		fbccr(BCC_HI,i0,r0,r1)
189 #  define bungti_f(i0,r0,i1)		fbcci(BCC_HI,i0,r0,i1)
190 #  define bltgtr_f(i0,r0,r1)		_bltgtr_f(_jit,i0,r0,r1)
191 static jit_word_t _bltgtr_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
192 #  define bltgti_f(i0,r0,i1)		_bltgti_f(_jit,i0,r0,i1)
193 static jit_word_t _bltgti_f(jit_state_t*,jit_word_t,jit_int32_t,jit_float32_t);
194 #  define bordr_f(i0,r0,r1)		fbccr(BCC_VC,i0,r0,r1)
195 #  define bordi_f(i0,r0,i1)		fbcci(BCC_VC,i0,r0,i1)
196 #  define bunordr_f(i0,r0,r1)		fbccr(BCC_VS,i0,r0,r1)
197 #  define bunordi_f(i0,r0,i1)		fbcci(BCC_VS,i0,r0,i1)
198 #  define addr_d(r0,r1,r2)		FADDD(r0,r1,r2)
199 #  define addi_d(r0,r1,i0)		_addi_d(_jit,r0,r1,i0)
200 static void _addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
201 #  define subr_d(r0,r1,r2)		FSUBD(r0,r1,r2)
202 #  define subi_d(r0,r1,i0)		_subi_d(_jit,r0,r1,i0)
203 static void _subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
204 #  define rsbr_d(r0, r1, r2)		subr_d(r0, r2, r1)
205 #  define rsbi_d(r0, r1, i0)		_rsbi_d(_jit, r0, r1, i0)
206 static void _rsbi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
207 #  define mulr_d(r0,r1,r2)		FMULD(r0,r1,r2)
208 #  define muli_d(r0,r1,i0)		_muli_d(_jit,r0,r1,i0)
209 static void _muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
210 #  define divr_d(r0,r1,r2)		FDIVD(r0,r1,r2)
211 #  define divi_d(r0,r1,i0)		_divi_d(_jit,r0,r1,i0)
212 static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
213 #  define absr_d(r0,r1)			FABSD(r0,r1)
214 #  define negr_d(r0,r1)			FNEGD(r0,r1)
215 #  define sqrtr_d(r0,r1)		FSQRTD(r0,r1)
216 #  define extr_d(r0,r1)			SCVTFD(r0,r1)
217 #  define ldr_d(r0,r1)			_ldr_d(_jit,r0,r1)
218 static void _ldr_d(jit_state_t*,jit_int32_t,jit_int32_t);
219 #  define ldi_d(r0,i0)			_ldi_d(_jit,r0,i0)
220 static void _ldi_d(jit_state_t*,jit_int32_t,jit_word_t);
221 #  define ldxr_d(r0,r1,r2)		_ldxr_d(_jit,r0,r1,r2)
222 static void _ldxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
223 #  define ldxi_d(r0,r1,i0)		_ldxi_d(_jit,r0,r1,i0)
224 static void _ldxi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
225 #  define str_d(r0,r1)			_str_d(_jit,r0,r1)
226 static void _str_d(jit_state_t*,jit_int32_t,jit_int32_t);
227 #  define sti_d(i0,r0)			_sti_d(_jit,i0,r0)
228 static void _sti_d(jit_state_t*,jit_word_t,jit_int32_t);
229 #  define stxr_d(r0,r1,r2)		_stxr_d(_jit,r0,r1,r2)
230 static void _stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
231 #  define stxi_d(i0,r0,r1)		_stxi_d(_jit,i0,r0,r1)
232 static void _stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
233 #  define movr_d(r0,r1)			_movr_d(_jit,r0,r1)
234 static void _movr_d(jit_state_t*,jit_int32_t,jit_int32_t);
235 #  define movi_d(r0,i0)			_movi_d(_jit,r0,i0)
236 static void _movi_d(jit_state_t*,jit_int32_t,jit_float64_t);
237 #  define extr_f_d(r0,r1)		FCVT_DS(r0,r1)
238 #  define dccr(cc,r0,r1,r2)		_dccr(_jit,cc,r0,r1,r2)
239 static void _dccr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t,jit_int32_t);
240 #  define dcci(cc,r0,r1,i0)		_dcci(_jit,cc,r0,r1,i0)
241 static void _dcci(jit_state_t*,
242 		  jit_int32_t,jit_int32_t,jit_int32_t,jit_float64_t);
243 #  define ltr_d(r0,r1,r2)		dccr(CC_MI,r0,r1,r2)
244 #  define lti_d(r0,r1,i0)		dcci(CC_MI,r0,r1,i0)
245 #  define ler_d(r0,r1,r2)		dccr(CC_LS,r0,r1,r2)
246 #  define lei_d(r0,r1,i0)		dcci(CC_LS,r0,r1,i0)
247 #  define eqr_d(r0,r1,r2)		dccr(CC_EQ,r0,r1,r2)
248 #  define eqi_d(r0,r1,i0)		dcci(CC_EQ,r0,r1,i0)
249 #  define ger_d(r0,r1,r2)		dccr(CC_GE,r0,r1,r2)
250 #  define gei_d(r0,r1,i0)		dcci(CC_GE,r0,r1,i0)
251 #  define gtr_d(r0,r1,r2)		dccr(CC_GT,r0,r1,r2)
252 #  define gti_d(r0,r1,i0)		dcci(CC_GT,r0,r1,i0)
253 #  define ner_d(r0,r1,r2)		dccr(CC_NE,r0,r1,r2)
254 #  define nei_d(r0,r1,i0)		dcci(CC_NE,r0,r1,i0)
255 #  define unltr_d(r0,r1,r2)		dccr(CC_LT,r0,r1,r2)
256 #  define unlti_d(r0,r1,i0)		dcci(CC_LT,r0,r1,i0)
257 #  define unler_d(r0,r1,r2)		dccr(CC_LE,r0,r1,r2)
258 #  define unlei_d(r0,r1,i0)		dcci(CC_LE,r0,r1,i0)
259 #  define uneqr_d(r0,r1,r2)		_uneqr_d(_jit,r0,r1,r2)
260 static void _uneqr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
261 #  define uneqi_d(r0,r1,i0)		_uneqi_d(_jit,r0,r1,i0)
262 static void _uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
263 #  define unger_d(r0,r1,r2)		dccr(CC_PL,r0,r1,r2)
264 #  define ungei_d(r0,r1,i0)		dcci(CC_PL,r0,r1,i0)
265 #  define ungtr_d(r0,r1,r2)		dccr(CC_HI,r0,r1,r2)
266 #  define ungti_d(r0,r1,i0)		dcci(CC_HI,r0,r1,i0)
267 #  define ltgtr_d(r0,r1,r2)		_ltgtr_d(_jit,r0,r1,r2)
268 static void _ltgtr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
269 #  define ltgti_d(r0,r1,i0)		_ltgti_d(_jit,r0,r1,i0)
270 static void _ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t);
271 #  define ordr_d(r0,r1,r2)		dccr(CC_VC,r0,r1,r2)
272 #  define ordi_d(r0,r1,i0)		dcci(CC_VC,r0,r1,i0)
273 #  define unordr_d(r0,r1,r2)		dccr(CC_VS,r0,r1,r2)
274 #  define unordi_d(r0,r1,i0)		dcci(CC_VS,r0,r1,i0)
275 #define dbccr(cc,i0,r0,r1)		_dbccr(_jit,cc,i0,r0,r1)
276 static jit_word_t
277 _dbccr(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_int32_t);
278 #define dbcci(cc,i0,r0,i1)		_dbcci(_jit,cc,i0,r0,i1)
279 static jit_word_t
280 _dbcci(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_float64_t);
281 #  define bltr_d(i0,r0,r1)		dbccr(BCC_MI,i0,r0,r1)
282 #  define blti_d(i0,r0,i1)		dbcci(BCC_MI,i0,r0,i1)
283 #  define bler_d(i0,r0,r1)		dbccr(BCC_LS,i0,r0,r1)
284 #  define blei_d(i0,r0,i1)		dbcci(BCC_LS,i0,r0,i1)
285 #  define beqr_d(i0,r0,r1)		dbccr(BCC_EQ,i0,r0,r1)
286 #  define beqi_d(i0,r0,i1)		dbcci(BCC_EQ,i0,r0,i1)
287 #  define bger_d(i0,r0,r1)		dbccr(BCC_GE,i0,r0,r1)
288 #  define bgei_d(i0,r0,i1)		dbcci(BCC_GE,i0,r0,i1)
289 #  define bgtr_d(i0,r0,r1)		dbccr(BCC_GT,i0,r0,r1)
290 #  define bgti_d(i0,r0,i1)		dbcci(BCC_GT,i0,r0,i1)
291 #  define bner_d(i0,r0,r1)		dbccr(BCC_NE,i0,r0,r1)
292 #  define bnei_d(i0,r0,i1)		dbcci(BCC_NE,i0,r0,i1)
293 #  define bunltr_d(i0,r0,r1)		dbccr(BCC_LT,i0,r0,r1)
294 #  define bunlti_d(i0,r0,i1)		dbcci(BCC_LT,i0,r0,i1)
295 #  define bunler_d(i0,r0,r1)		dbccr(BCC_LE,i0,r0,r1)
296 #  define bunlei_d(i0,r0,i1)		dbcci(BCC_LE,i0,r0,i1)
297 #  define buneqr_d(i0,r0,r1)		_buneqr_d(_jit,i0,r0,r1)
298 static jit_word_t _buneqr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
299 #  define buneqi_d(i0,r0,i1)		_buneqi_d(_jit,i0,r0,i1)
300 static jit_word_t _buneqi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
301 #  define bunger_d(i0,r0,r1)		dbccr(BCC_PL,i0,r0,r1)
302 #  define bungei_d(i0,r0,i1)		dbcci(BCC_PL,i0,r0,i1)
303 #  define bungtr_d(i0,r0,r1)		dbccr(BCC_HI,i0,r0,r1)
304 #  define bungti_d(i0,r0,i1)		dbcci(BCC_HI,i0,r0,i1)
305 #  define bltgtr_d(i0,r0,r1)		_bltgtr_d(_jit,i0,r0,r1)
306 static jit_word_t _bltgtr_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
307 #  define bltgti_d(i0,r0,i1)		_bltgti_d(_jit,i0,r0,i1)
308 static jit_word_t _bltgti_d(jit_state_t*,jit_word_t,jit_int32_t,jit_float64_t);
309 #  define bordr_d(i0,r0,r1)		dbccr(BCC_VC,i0,r0,r1)
310 #  define bordi_d(i0,r0,i1)		dbcci(BCC_VC,i0,r0,i1)
311 #  define bunordr_d(i0,r0,r1)		dbccr(BCC_VS,i0,r0,r1)
312 #  define bunordi_d(i0,r0,i1)		dbcci(BCC_VS,i0,r0,i1)
313 #  define vaarg_d(r0, r1)		_vaarg_d(_jit, r0, r1)
314 static void _vaarg_d(jit_state_t*, jit_int32_t, jit_int32_t);
315 #endif
316 
317 #if CODE
318 static void
_osvvv(jit_state_t * _jit,jit_int32_t Op,jit_int32_t Sz,jit_int32_t Rd,jit_int32_t Rn,jit_int32_t Rm)319 _osvvv(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Sz,
320        jit_int32_t Rd, jit_int32_t Rn, jit_int32_t Rm)
321 {
322     instr_t	i;
323     assert(!(Rd &       ~0x1f));
324     assert(!(Rn &       ~0x1f));
325     assert(!(Rm &       ~0x1f));
326     assert(!(Sz &        ~0x3));
327     assert(!(Op & ~0xffe0fc00));
328     i.w = Op;
329     i.size.b = Sz;
330     i.Rd.b = Rd;
331     i.Rn.b = Rn;
332     i.Rm.b = Rm;
333     ii(i.w);
334 }
335 
336 static void
_osvv_(jit_state_t * _jit,jit_int32_t Op,jit_int32_t Sz,jit_int32_t Rd,jit_int32_t Rn)337 _osvv_(jit_state_t *_jit, jit_int32_t Op,
338        jit_int32_t Sz, jit_int32_t Rd, jit_int32_t Rn)
339 {
340     instr_t	i;
341     assert(!(Rd &       ~0x1f));
342     assert(!(Rn &       ~0x1f));
343     assert(!(Sz &        ~0x3));
344     assert(!(Op & ~0xfffffc00));
345     i.w = Op;
346     i.size.b = Sz;
347     i.Rd.b = Rd;
348     i.Rn.b = Rn;
349     ii(i.w);
350 }
351 
352 static void
_os_vv(jit_state_t * _jit,jit_int32_t Op,jit_int32_t Sz,jit_int32_t Rn,jit_int32_t Rm)353 _os_vv(jit_state_t *_jit, jit_int32_t Op,
354        jit_int32_t Sz, jit_int32_t Rn, jit_int32_t Rm)
355 {
356     instr_t	i;
357     assert(!(Rn &       ~0x1f));
358     assert(!(Rm &       ~0x1f));
359     assert(!(Sz &        ~0x3));
360     assert(!(Op & ~0xff20fc1f));
361     i.w = Op;
362     i.size.b = Sz;
363     i.Rn.b = Rn;
364     i.Rm.b = Rm;
365     ii(i.w);
366 }
367 
368 #define fopi(name)							\
369 static void								\
370 _##name##i_f(jit_state_t *_jit,						\
371 	     jit_int32_t r0, jit_int32_t r1, jit_float32_t i0)		\
372 {									\
373     jit_int32_t		reg = jit_get_reg(jit_class_fpr);		\
374     movi_f(rn(reg), i0);						\
375     name##r_f(r0, r1, rn(reg));						\
376     jit_unget_reg(reg);							\
377 }
378 #define dopi(name)							\
379 static void								\
380 _##name##i_d(jit_state_t *_jit,						\
381 	     jit_int32_t r0, jit_int32_t r1, jit_float64_t i0)		\
382 {									\
383     jit_int32_t		reg = jit_get_reg(jit_class_fpr);		\
384     movi_d(rn(reg), i0);						\
385     name##r_d(r0, r1, rn(reg));						\
386     jit_unget_reg(reg);							\
387 }
388 #define fbopi(name)							\
389 static jit_word_t							\
390 _b##name##i_f(jit_state_t *_jit,					\
391 	      jit_word_t i0, jit_int32_t r0, jit_float32_t i1)		\
392 {									\
393     jit_word_t		word;						\
394     jit_int32_t		reg = jit_get_reg(jit_class_fpr|		\
395 					  jit_class_nospill);		\
396     movi_f(rn(reg), i1);						\
397     word = b##name##r_f(i0, r0, rn(reg));				\
398     jit_unget_reg(reg);							\
399     return (word);							\
400 }
401 #define dbopi(name)							\
402 static jit_word_t							\
403 _b##name##i_d(jit_state_t *_jit,					\
404 	      jit_word_t i0, jit_int32_t r0, jit_float64_t i1)		\
405 {									\
406     jit_word_t		word;						\
407     jit_int32_t		reg = jit_get_reg(jit_class_fpr|		\
408 					  jit_class_nospill);		\
409     movi_d(rn(reg), i1);						\
410     word = b##name##r_d(i0, r0, rn(reg));				\
411     jit_unget_reg(reg);							\
412     return (word);							\
413 }
414 
415 static void
_truncr_f_i(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1)416 _truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
417 {
418     FCVTSZ_WS(r0, r1);
419     extr_i(r0, r0);
420 }
421 
422 static void
_truncr_d_i(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1)423 _truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
424 {
425     FCVTSZ_WD(r0, r1);
426     extr_i(r0, r0);
427 }
428 
429 fopi(add)
fopi(sub)430 fopi(sub)
431 fopi(rsb)
432 fopi(mul)
433 fopi(div)
434 
435 static void
436 _ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
437 {
438     jit_int32_t		reg;
439     reg = jit_get_reg(jit_class_gpr);
440     ldr_i(rn(reg), r1);
441     FMOVSW(r0, rn(reg));
442     jit_unget_reg(reg);
443 }
444 
445 static void
_ldi_f(jit_state_t * _jit,jit_int32_t r0,jit_word_t i0)446 _ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
447 {
448     jit_int32_t		reg;
449     reg = jit_get_reg(jit_class_gpr);
450     ldi_i(rn(reg), i0);
451     FMOVSW(r0, rn(reg));
452     jit_unget_reg(reg);
453 }
454 
455 static void
_ldxr_f(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)456 _ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
457 {
458     jit_int32_t		reg;
459     reg = jit_get_reg(jit_class_gpr);
460     ldxr_i(rn(reg), r1, r2);
461     FMOVSW(r0, rn(reg));
462     jit_unget_reg(reg);
463 }
464 
465 static void
_ldxi_f(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_word_t i0)466 _ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
467 {
468     jit_int32_t		reg;
469     reg = jit_get_reg(jit_class_gpr);
470     ldxi_i(rn(reg), r1, i0);
471     FMOVSW(r0, rn(reg));
472     jit_unget_reg(reg);
473 }
474 
475 static void
_str_f(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1)476 _str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
477 {
478     jit_int32_t		reg;
479     reg = jit_get_reg(jit_class_gpr);
480     FMOVWS(rn(reg), r1);
481     str_i(r0, rn(reg));
482     jit_unget_reg(reg);
483 }
484 
485 static void
_sti_f(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0)486 _sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
487 {
488     jit_int32_t		reg;
489     reg = jit_get_reg(jit_class_gpr);
490     FMOVWS(rn(reg), r0);
491     sti_i(i0, rn(reg));
492     jit_unget_reg(reg);
493 }
494 
495 static void
_stxr_f(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)496 _stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
497 {
498     jit_int32_t		reg;
499     reg = jit_get_reg(jit_class_gpr);
500     FMOVWS(rn(reg), r2);
501     stxr_i(r0, r1, rn(reg));
502     jit_unget_reg(reg);
503 }
504 
505 static void
_stxi_f(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)506 _stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
507 {
508     jit_int32_t		reg;
509     reg = jit_get_reg(jit_class_gpr);
510     FMOVWS(rn(reg), r1);
511     stxi_i(i0, r0, rn(reg));
512     jit_unget_reg(reg);
513 }
514 
515 static void
_movr_f(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1)516 _movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
517 {
518     if (r0 != r1)
519 	FMOVS(r0, r1);
520 }
521 
522 static void
_movi_f(jit_state_t * _jit,jit_int32_t r0,jit_float32_t i0)523 _movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0)
524 {
525     union {
526 	jit_int32_t	i;
527 	jit_float32_t	f;
528     } u;
529     jit_int32_t		reg;
530     u.f = i0;
531     if (u.i == 0)
532 	FMOVSW(r0, WZR_REGNO);
533     else {
534 	reg = jit_get_reg(jit_class_gpr);
535 	/* prevent generating unused top 32 bits */
536 	movi(rn(reg), ((jit_word_t)u.i) & 0xffffffff);
537 	FMOVSW(r0, rn(reg));
538 	jit_unget_reg(reg);
539     }
540 }
541 
542 static void
_fccr(jit_state_t * _jit,jit_int32_t cc,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)543 _fccr(jit_state_t *_jit, jit_int32_t cc,
544       jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
545 {
546     FCMPES(r1, r2);
547     CSET(r0, cc);
548 }
549 
550 static void
_fcci(jit_state_t * _jit,jit_int32_t cc,jit_int32_t r0,jit_int32_t r1,jit_float32_t i0)551 _fcci(jit_state_t *_jit, jit_int32_t cc,
552       jit_int32_t r0, jit_int32_t r1, jit_float32_t i0)
553 {
554     jit_int32_t		reg;
555     reg = jit_get_reg(jit_class_fpr);
556     movi_f(rn(reg), i0);
557     fccr(cc, r0, r1, rn(reg));
558     jit_unget_reg(reg);
559 }
560 
561 static void
_uneqr_f(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)562 _uneqr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
563 {
564     jit_word_t		w;
565     FCMPES(r1, r2);
566     CSET(r0, CC_VS);
567     w = _jit->pc.w;
568     B_C(BCC_VS, 1);		/* unordered satisfies condition */
569     CSET(r0, CC_EQ);		/* equal satisfies condition */
570     patch_at(w, _jit->pc.w);
571 }
fopi(uneq)572 fopi(uneq)
573 
574 static void
575 _ltgtr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
576 {
577     jit_word_t		w;
578     FCMPES(r1, r2);
579     CSET(r0, CC_VC);		/* set to 1 if ordered */
580     w = _jit->pc.w;
581     B_C(BCC_VS, 1);		/* unordered does not satisfy condition */
582     CSET(r0, CC_NE);		/* set to 1 if not equal */
583     patch_at(w, _jit->pc.w);
584 }
fopi(ltgt)585 fopi(ltgt)
586 
587 static jit_word_t
588 _fbccr(jit_state_t *_jit, jit_int32_t cc,
589        jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
590 {
591     jit_word_t		w, d;
592     FCMPES(r0, r1);
593     w = _jit->pc.w;
594     d = (i0 - w) >> 2;
595     B_C(cc, d);
596     return (w);
597 }
598 
599 static jit_word_t
_fbcci(jit_state_t * _jit,jit_int32_t cc,jit_word_t i0,jit_int32_t r0,jit_float32_t i1)600 _fbcci(jit_state_t *_jit, jit_int32_t cc,
601        jit_word_t i0, jit_int32_t r0, jit_float32_t i1)
602 {
603     jit_word_t		w;
604     jit_int32_t		reg;
605     reg = jit_get_reg(jit_class_fpr|jit_class_nospill);
606     movi_f(rn(reg), i1);
607     w = fbccr(cc, i0, r0, rn(reg));
608     jit_unget_reg(reg);
609     return (w);
610 }
611 
612 static jit_word_t
_buneqr_f(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)613 _buneqr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
614 {
615     jit_word_t		u, v, w;
616     FCMPES(r0, r1);
617     u = _jit->pc.w;
618     B_C(BCC_VS, 1);		/* unordered satisfies condition */
619     v = _jit->pc.w;
620     B_C(BCC_NE, 1);		/* not equal (or unordered) does not satisfy */
621     patch_at(u, _jit->pc.w);
622     w = _jit->pc.w;
623     B((i0 - w) >> 2);
624     patch_at(v, _jit->pc.w);
625     return (w);
626 }
fbopi(uneq)627 fbopi(uneq)
628 
629 static jit_word_t
630 _bltgtr_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
631 {
632     jit_word_t		u, v, w;
633     FCMPES(r0, r1);
634     u = _jit->pc.w;
635     B_C(BCC_VS, 2);		/* jump over if unordered */
636     v = _jit->pc.w;
637     B_C(BCC_EQ, 1);		/* jump over if equal */
638     w = _jit->pc.w;
639     B((i0 - w) >> 2);
640     patch_at(u, _jit->pc.w);
641     patch_at(v, _jit->pc.w);
642     return (w);
643 }
644 fbopi(ltgt)
645 
dopi(add)646 dopi(add)
647 dopi(sub)
648 dopi(rsb)
649 dopi(mul)
650 dopi(div)
651 
652 static void
653 _ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
654 {
655     jit_int32_t		reg;
656     reg = jit_get_reg(jit_class_gpr);
657     ldr_l(rn(reg), r1);
658     FMOVDX(r0, rn(reg));
659     jit_unget_reg(reg);
660 }
661 
662 static void
_ldi_d(jit_state_t * _jit,jit_int32_t r0,jit_word_t i0)663 _ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
664 {
665     jit_int32_t		reg;
666     reg = jit_get_reg(jit_class_gpr);
667     ldi_l(rn(reg), i0);
668     FMOVDX(r0, rn(reg));
669     jit_unget_reg(reg);
670 }
671 
672 static void
_ldxr_d(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)673 _ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
674 {
675     jit_int32_t		reg;
676     reg = jit_get_reg(jit_class_gpr);
677     ldxr_l(rn(reg), r1, r2);
678     FMOVDX(r0, rn(reg));
679     jit_unget_reg(reg);
680 }
681 
682 static void
_ldxi_d(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_word_t i0)683 _ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
684 {
685     jit_int32_t		reg;
686     reg = jit_get_reg(jit_class_gpr);
687     ldxi_l(rn(reg), r1, i0);
688     FMOVDX(r0, rn(reg));
689     jit_unget_reg(reg);
690 }
691 
692 static void
_str_d(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1)693 _str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
694 {
695     jit_int32_t		reg;
696     reg = jit_get_reg(jit_class_gpr);
697     FMOVXD(rn(reg), r1);
698     str_l(r0, rn(reg));
699     jit_unget_reg(reg);
700 }
701 
702 static void
_sti_d(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0)703 _sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
704 {
705     jit_int32_t		reg;
706     reg = jit_get_reg(jit_class_gpr);
707     FMOVXD(rn(reg), r0);
708     sti_l(i0, rn(reg));
709     jit_unget_reg(reg);
710 }
711 
712 static void
_stxr_d(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)713 _stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
714 {
715     jit_int32_t		reg;
716     reg = jit_get_reg(jit_class_gpr);
717     FMOVXD(rn(reg), r2);
718     stxr_l(r0, r1, rn(reg));
719     jit_unget_reg(reg);
720 }
721 
722 static void
_stxi_d(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)723 _stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
724 {
725     jit_int32_t		reg;
726     reg = jit_get_reg(jit_class_gpr);
727     FMOVXD(rn(reg), r1);
728     stxi_l(i0, r0, rn(reg));
729     jit_unget_reg(reg);
730 }
731 
732 static void
_movr_d(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1)733 _movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
734 {
735     if (r0 != r1)
736 	FMOVD(r0, r1);
737 }
738 
739 static void
_movi_d(jit_state_t * _jit,jit_int32_t r0,jit_float64_t i0)740 _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0)
741 {
742     union {
743 	jit_int64_t	l;
744 	jit_float64_t	d;
745     } u;
746     jit_int32_t		reg;
747     u.d = i0;
748     if (u.l == 0)
749 	FMOVDX(r0, XZR_REGNO);
750     else {
751 	reg = jit_get_reg(jit_class_gpr);
752 	movi(rn(reg), u.l);
753 	FMOVDX(r0, rn(reg));
754 	jit_unget_reg(reg);
755     }
756 }
757 
758 static void
_dccr(jit_state_t * _jit,jit_int32_t cc,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)759 _dccr(jit_state_t *_jit, jit_int32_t cc,
760       jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
761 {
762     FCMPED(r1, r2);
763     CSET(r0, cc);
764 }
765 
766 static void
_dcci(jit_state_t * _jit,jit_int32_t cc,jit_int32_t r0,jit_int32_t r1,jit_float64_t i0)767 _dcci(jit_state_t *_jit, jit_int32_t cc,
768       jit_int32_t r0, jit_int32_t r1, jit_float64_t i0)
769 {
770     jit_int32_t		reg;
771     reg = jit_get_reg(jit_class_fpr);
772     movi_d(rn(reg), i0);
773     dccr(cc, r0, r1, rn(reg));
774     jit_unget_reg(reg);
775 }
776 
777 static void
_uneqr_d(jit_state_t * _jit,jit_int32_t r0,jit_int32_t r1,jit_int32_t r2)778 _uneqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
779 {
780     jit_word_t		w;
781     FCMPED(r1, r2);
782     CSET(r0, CC_VS);
783     w = _jit->pc.w;
784     B_C(BCC_VS, 1);		/* unordered satisfies condition */
785     CSET(r0, CC_EQ);		/* equal satisfies condition */
786     patch_at(w, _jit->pc.w);
787 }
dopi(uneq)788 dopi(uneq)
789 
790 static void
791 _ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
792 {
793     jit_word_t		w;
794     FCMPED(r1, r2);
795     CSET(r0, CC_VC);		/* set to 1 if ordered */
796     w = _jit->pc.w;
797     B_C(BCC_VS, 1);		/* unordered does not satisfy condition */
798     CSET(r0, CC_NE);		/* set to 1 if not equal */
799     patch_at(w, _jit->pc.w);
800 }
dopi(ltgt)801 dopi(ltgt)
802 
803 static jit_word_t
804 _dbccr(jit_state_t *_jit, jit_int32_t cc,
805        jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
806 {
807     jit_word_t		w, d;
808     FCMPED(r0, r1);
809     w = _jit->pc.w;
810     d = (i0 - w) >> 2;
811     B_C(cc, d);
812     return (w);
813 }
814 
815 static jit_word_t
_dbcci(jit_state_t * _jit,jit_int32_t cc,jit_word_t i0,jit_int32_t r0,jit_float64_t i1)816 _dbcci(jit_state_t *_jit, jit_int32_t cc,
817        jit_word_t i0, jit_int32_t r0, jit_float64_t i1)
818 {
819     jit_word_t		w;
820     jit_int32_t		reg;
821     reg = jit_get_reg(jit_class_fpr|jit_class_nospill);
822     movi_d(rn(reg), i1);
823     w = dbccr(cc, i0, r0, rn(reg));
824     jit_unget_reg(reg);
825     return (w);
826 }
827 
828 static jit_word_t
_buneqr_d(jit_state_t * _jit,jit_word_t i0,jit_int32_t r0,jit_int32_t r1)829 _buneqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
830 {
831     jit_word_t		u, v, w;
832     FCMPED(r0, r1);
833     u = _jit->pc.w;
834     B_C(BCC_VS, 1);		/* unordered satisfies condition */
835     v = _jit->pc.w;
836     B_C(BCC_NE, 1);		/* not equal (or unordered) does not satisfy */
837     patch_at(u, _jit->pc.w);
838     w = _jit->pc.w;
839     B((i0 - w) >> 2);
840     patch_at(v, _jit->pc.w);
841     return (w);
842 }
dbopi(uneq)843 dbopi(uneq)
844 
845 static jit_word_t
846 _bltgtr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
847 {
848     jit_word_t		u, v, w;
849     FCMPED(r0, r1);
850     u = _jit->pc.w;
851     B_C(BCC_VS, 2);		/* jump over if unordered */
852     v = _jit->pc.w;
853     B_C(BCC_EQ, 1);		/* jump over if equal */
854     w = _jit->pc.w;
855     B((i0 - w) >> 2);
856     patch_at(u, _jit->pc.w);
857     patch_at(v, _jit->pc.w);
858     return (w);
859 }
dbopi(ltgt)860 dbopi(ltgt)
861 
862 static void
863 _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
864 {
865     jit_word_t		ge_code;
866     jit_word_t		lt_code;
867     jit_int32_t		rg0, rg1;
868 
869     assert(_jitc->function->self.call & jit_call_varargs);
870 
871     rg0 = jit_get_reg(jit_class_gpr);
872     rg1 = jit_get_reg(jit_class_gpr);
873 
874     /* Load the fp offset in save area in the first temporary. */
875     ldxi_i(rn(rg0), r1, offsetof(jit_va_list_t, fpoff));
876 
877     /* Jump over if there are no remaining arguments in the save area. */
878     ge_code = bgei(_jit->pc.w, rn(rg0), 0);
879 
880     /* Load the gp save pointer in the second temporary. */
881     ldxi(rn(rg1), r1, offsetof(jit_va_list_t, fptop));
882 
883     /* Load the vararg argument in the first argument. */
884     ldxr_d(r0, rn(rg1), rn(rg0));
885 
886     /* Update the fp offset. */
887     addi(rn(rg0), rn(rg0), 16);
888     stxi_i(offsetof(jit_va_list_t, fpoff), r1, rn(rg0));
889 
890     /* Will only need one temporary register below. */
891     jit_unget_reg(rg1);
892 
893     /* Jump over overflow code. */
894     lt_code = jmpi_p(_jit->pc.w);
895 
896     /* Where to land if argument is in overflow area. */
897     patch_at(ge_code, _jit->pc.w);
898 
899     /* Load stack pointer. */
900     ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack));
901 
902     /* Load argument. */
903     ldr_d(r0, rn(rg0));
904 
905     /* Update stack pointer. */
906     addi(rn(rg0), rn(rg0), 8);
907     stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0));
908 
909     /* Where to land if argument is in gp save area. */
910     patch_at(lt_code, _jit->pc.w);
911 
912     jit_unget_reg(rg0);
913 }
914 #endif
915