Commit | Line | Data |
---|---|---|
4a71579b PC |
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 | |
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 | |
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 | |
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 | |
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 | |
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) | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | } | |
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 | } | |
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 | |
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 | |
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 | } | |
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 | ||
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | } | |
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 | } | |
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 | |
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 | |
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 | } | |
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 | } | |
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 |