root / target-sparc / op.c @ c4dfa5b7
History | View | Annotate | Download (12 kB)
1 | 7a3f1944 | bellard | /*
|
---|---|---|---|
2 | 7a3f1944 | bellard | SPARC micro operations
|
3 | 7a3f1944 | bellard | |
4 | 7a3f1944 | bellard | Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
|
5 | 7a3f1944 | bellard | |
6 | 7a3f1944 | bellard | This library is free software; you can redistribute it and/or
|
7 | 7a3f1944 | bellard | modify it under the terms of the GNU Lesser General Public
|
8 | 7a3f1944 | bellard | License as published by the Free Software Foundation; either
|
9 | 7a3f1944 | bellard | version 2 of the License, or (at your option) any later version.
|
10 | 7a3f1944 | bellard | |
11 | 7a3f1944 | bellard | This library is distributed in the hope that it will be useful,
|
12 | 7a3f1944 | bellard | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 7a3f1944 | bellard | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 7a3f1944 | bellard | Lesser General Public License for more details.
|
15 | 7a3f1944 | bellard | |
16 | 7a3f1944 | bellard | You should have received a copy of the GNU Lesser General Public
|
17 | 7a3f1944 | bellard | License along with this library; if not, write to the Free Software
|
18 | 7a3f1944 | bellard | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19 | 7a3f1944 | bellard | */
|
20 | 7a3f1944 | bellard | |
21 | 7a3f1944 | bellard | #include "exec.h" |
22 | 7a3f1944 | bellard | |
23 | cf495bcf | bellard | /*XXX*/
|
24 | 7a3f1944 | bellard | #define REGNAME g0
|
25 | 7a3f1944 | bellard | #define REG (env->gregs[0]) |
26 | 7a3f1944 | bellard | #include "op_template.h" |
27 | 7a3f1944 | bellard | #define REGNAME g1
|
28 | 7a3f1944 | bellard | #define REG (env->gregs[1]) |
29 | 7a3f1944 | bellard | #include "op_template.h" |
30 | 7a3f1944 | bellard | #define REGNAME g2
|
31 | 7a3f1944 | bellard | #define REG (env->gregs[2]) |
32 | 7a3f1944 | bellard | #include "op_template.h" |
33 | 7a3f1944 | bellard | #define REGNAME g3
|
34 | 7a3f1944 | bellard | #define REG (env->gregs[3]) |
35 | 7a3f1944 | bellard | #include "op_template.h" |
36 | 7a3f1944 | bellard | #define REGNAME g4
|
37 | 7a3f1944 | bellard | #define REG (env->gregs[4]) |
38 | 7a3f1944 | bellard | #include "op_template.h" |
39 | 7a3f1944 | bellard | #define REGNAME g5
|
40 | 7a3f1944 | bellard | #define REG (env->gregs[5]) |
41 | 7a3f1944 | bellard | #include "op_template.h" |
42 | 7a3f1944 | bellard | #define REGNAME g6
|
43 | 7a3f1944 | bellard | #define REG (env->gregs[6]) |
44 | 7a3f1944 | bellard | #include "op_template.h" |
45 | 7a3f1944 | bellard | #define REGNAME g7
|
46 | 7a3f1944 | bellard | #define REG (env->gregs[7]) |
47 | 7a3f1944 | bellard | #include "op_template.h" |
48 | 7a3f1944 | bellard | #define REGNAME i0
|
49 | 7a3f1944 | bellard | #define REG (env->regwptr[16]) |
50 | 7a3f1944 | bellard | #include "op_template.h" |
51 | 7a3f1944 | bellard | #define REGNAME i1
|
52 | 7a3f1944 | bellard | #define REG (env->regwptr[17]) |
53 | 7a3f1944 | bellard | #include "op_template.h" |
54 | 7a3f1944 | bellard | #define REGNAME i2
|
55 | 7a3f1944 | bellard | #define REG (env->regwptr[18]) |
56 | 7a3f1944 | bellard | #include "op_template.h" |
57 | 7a3f1944 | bellard | #define REGNAME i3
|
58 | 7a3f1944 | bellard | #define REG (env->regwptr[19]) |
59 | 7a3f1944 | bellard | #include "op_template.h" |
60 | 7a3f1944 | bellard | #define REGNAME i4
|
61 | 7a3f1944 | bellard | #define REG (env->regwptr[20]) |
62 | 7a3f1944 | bellard | #include "op_template.h" |
63 | 7a3f1944 | bellard | #define REGNAME i5
|
64 | 7a3f1944 | bellard | #define REG (env->regwptr[21]) |
65 | 7a3f1944 | bellard | #include "op_template.h" |
66 | 7a3f1944 | bellard | #define REGNAME i6
|
67 | 7a3f1944 | bellard | #define REG (env->regwptr[22]) |
68 | 7a3f1944 | bellard | #include "op_template.h" |
69 | 7a3f1944 | bellard | #define REGNAME i7
|
70 | 7a3f1944 | bellard | #define REG (env->regwptr[23]) |
71 | 7a3f1944 | bellard | #include "op_template.h" |
72 | 7a3f1944 | bellard | #define REGNAME l0
|
73 | 7a3f1944 | bellard | #define REG (env->regwptr[8]) |
74 | 7a3f1944 | bellard | #include "op_template.h" |
75 | 7a3f1944 | bellard | #define REGNAME l1
|
76 | 7a3f1944 | bellard | #define REG (env->regwptr[9]) |
77 | 7a3f1944 | bellard | #include "op_template.h" |
78 | 7a3f1944 | bellard | #define REGNAME l2
|
79 | 7a3f1944 | bellard | #define REG (env->regwptr[10]) |
80 | 7a3f1944 | bellard | #include "op_template.h" |
81 | 7a3f1944 | bellard | #define REGNAME l3
|
82 | 7a3f1944 | bellard | #define REG (env->regwptr[11]) |
83 | 7a3f1944 | bellard | #include "op_template.h" |
84 | 7a3f1944 | bellard | #define REGNAME l4
|
85 | 7a3f1944 | bellard | #define REG (env->regwptr[12]) |
86 | 7a3f1944 | bellard | #include "op_template.h" |
87 | 7a3f1944 | bellard | #define REGNAME l5
|
88 | 7a3f1944 | bellard | #define REG (env->regwptr[13]) |
89 | 7a3f1944 | bellard | #include "op_template.h" |
90 | 7a3f1944 | bellard | #define REGNAME l6
|
91 | 7a3f1944 | bellard | #define REG (env->regwptr[14]) |
92 | 7a3f1944 | bellard | #include "op_template.h" |
93 | 7a3f1944 | bellard | #define REGNAME l7
|
94 | 7a3f1944 | bellard | #define REG (env->regwptr[15]) |
95 | 7a3f1944 | bellard | #include "op_template.h" |
96 | 7a3f1944 | bellard | #define REGNAME o0
|
97 | 7a3f1944 | bellard | #define REG (env->regwptr[0]) |
98 | 7a3f1944 | bellard | #include "op_template.h" |
99 | 7a3f1944 | bellard | #define REGNAME o1
|
100 | 7a3f1944 | bellard | #define REG (env->regwptr[1]) |
101 | 7a3f1944 | bellard | #include "op_template.h" |
102 | 7a3f1944 | bellard | #define REGNAME o2
|
103 | 7a3f1944 | bellard | #define REG (env->regwptr[2]) |
104 | 7a3f1944 | bellard | #include "op_template.h" |
105 | 7a3f1944 | bellard | #define REGNAME o3
|
106 | 7a3f1944 | bellard | #define REG (env->regwptr[3]) |
107 | 7a3f1944 | bellard | #include "op_template.h" |
108 | 7a3f1944 | bellard | #define REGNAME o4
|
109 | 7a3f1944 | bellard | #define REG (env->regwptr[4]) |
110 | 7a3f1944 | bellard | #include "op_template.h" |
111 | 7a3f1944 | bellard | #define REGNAME o5
|
112 | 7a3f1944 | bellard | #define REG (env->regwptr[5]) |
113 | 7a3f1944 | bellard | #include "op_template.h" |
114 | 7a3f1944 | bellard | #define REGNAME o6
|
115 | 7a3f1944 | bellard | #define REG (env->regwptr[6]) |
116 | 7a3f1944 | bellard | #include "op_template.h" |
117 | 7a3f1944 | bellard | #define REGNAME o7
|
118 | 7a3f1944 | bellard | #define REG (env->regwptr[7]) |
119 | 7a3f1944 | bellard | #include "op_template.h" |
120 | 7a3f1944 | bellard | #define EIP (env->pc)
|
121 | 7a3f1944 | bellard | |
122 | cf495bcf | bellard | #define FLAG_SET(x) (env->psr&x)?1:0 |
123 | cf495bcf | bellard | |
124 | 7a3f1944 | bellard | void OPPROTO op_movl_T0_0(void) |
125 | 7a3f1944 | bellard | { |
126 | cf495bcf | bellard | T0 = 0;
|
127 | 7a3f1944 | bellard | } |
128 | 7a3f1944 | bellard | |
129 | 7a3f1944 | bellard | void OPPROTO op_movl_T0_1(void) |
130 | 7a3f1944 | bellard | { |
131 | cf495bcf | bellard | T0 = 1;
|
132 | 7a3f1944 | bellard | } |
133 | 7a3f1944 | bellard | |
134 | 7a3f1944 | bellard | void OPPROTO op_movl_T0_im(void) |
135 | 7a3f1944 | bellard | { |
136 | cf495bcf | bellard | T0 = PARAM1; |
137 | 7a3f1944 | bellard | } |
138 | 7a3f1944 | bellard | |
139 | 7a3f1944 | bellard | void OPPROTO op_movl_T1_im(void) |
140 | 7a3f1944 | bellard | { |
141 | cf495bcf | bellard | T1 = PARAM1; |
142 | 7a3f1944 | bellard | } |
143 | 7a3f1944 | bellard | |
144 | 7a3f1944 | bellard | void OPPROTO op_movl_T2_im(void) |
145 | 7a3f1944 | bellard | { |
146 | cf495bcf | bellard | T2 = PARAM1; |
147 | 7a3f1944 | bellard | } |
148 | 7a3f1944 | bellard | |
149 | 7a3f1944 | bellard | void OPPROTO op_addl_T1_im(void) |
150 | 7a3f1944 | bellard | { |
151 | cf495bcf | bellard | T1 += PARAM1; |
152 | 7a3f1944 | bellard | } |
153 | 7a3f1944 | bellard | |
154 | 7a3f1944 | bellard | void OPPROTO op_addl_T1_T2(void) |
155 | 7a3f1944 | bellard | { |
156 | cf495bcf | bellard | T1 += T2; |
157 | 7a3f1944 | bellard | } |
158 | 7a3f1944 | bellard | |
159 | 7a3f1944 | bellard | void OPPROTO op_subl_T1_T2(void) |
160 | 7a3f1944 | bellard | { |
161 | cf495bcf | bellard | T1 -= T2; |
162 | 7a3f1944 | bellard | } |
163 | 7a3f1944 | bellard | |
164 | cf495bcf | bellard | void OPPROTO op_add_T1_T0(void) |
165 | 7a3f1944 | bellard | { |
166 | cf495bcf | bellard | T0 += T1; |
167 | 7a3f1944 | bellard | } |
168 | 7a3f1944 | bellard | |
169 | cf495bcf | bellard | void OPPROTO op_add_T1_T0_cc(void) |
170 | 7a3f1944 | bellard | { |
171 | cf495bcf | bellard | unsigned int src1; |
172 | cf495bcf | bellard | src1 = T0; |
173 | cf495bcf | bellard | T0 += T1; |
174 | cf495bcf | bellard | env->psr = 0;
|
175 | cf495bcf | bellard | if (!T0)
|
176 | cf495bcf | bellard | env->psr |= PSR_ZERO; |
177 | cf495bcf | bellard | if ((int) T0 < 0) |
178 | cf495bcf | bellard | env->psr |= PSR_NEG; |
179 | cf495bcf | bellard | if (T0 < src1)
|
180 | cf495bcf | bellard | env->psr |= PSR_CARRY; |
181 | cf495bcf | bellard | if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) |
182 | cf495bcf | bellard | env->psr |= PSR_OVF; |
183 | cf495bcf | bellard | FORCE_RET(); |
184 | 7a3f1944 | bellard | } |
185 | 7a3f1944 | bellard | |
186 | cf495bcf | bellard | void OPPROTO op_sub_T1_T0(void) |
187 | 7a3f1944 | bellard | { |
188 | cf495bcf | bellard | T0 -= T1; |
189 | 7a3f1944 | bellard | } |
190 | 7a3f1944 | bellard | |
191 | cf495bcf | bellard | void OPPROTO op_sub_T1_T0_cc(void) |
192 | 7a3f1944 | bellard | { |
193 | cf495bcf | bellard | unsigned int src1; |
194 | cf495bcf | bellard | |
195 | cf495bcf | bellard | src1 = T0; |
196 | cf495bcf | bellard | T0 -= T1; |
197 | cf495bcf | bellard | env->psr = 0;
|
198 | cf495bcf | bellard | if (!T0)
|
199 | cf495bcf | bellard | env->psr |= PSR_ZERO; |
200 | cf495bcf | bellard | if ((int) T0 < 0) |
201 | cf495bcf | bellard | env->psr |= PSR_NEG; |
202 | cf495bcf | bellard | if (src1 < T1)
|
203 | cf495bcf | bellard | env->psr |= PSR_CARRY; |
204 | cf495bcf | bellard | if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) |
205 | cf495bcf | bellard | env->psr |= PSR_OVF; |
206 | cf495bcf | bellard | FORCE_RET(); |
207 | 7a3f1944 | bellard | } |
208 | 7a3f1944 | bellard | |
209 | cf495bcf | bellard | void OPPROTO op_and_T1_T0(void) |
210 | 7a3f1944 | bellard | { |
211 | cf495bcf | bellard | T0 &= T1; |
212 | 7a3f1944 | bellard | } |
213 | 7a3f1944 | bellard | |
214 | cf495bcf | bellard | void OPPROTO op_or_T1_T0(void) |
215 | 7a3f1944 | bellard | { |
216 | cf495bcf | bellard | T0 |= T1; |
217 | 7a3f1944 | bellard | } |
218 | 7a3f1944 | bellard | |
219 | cf495bcf | bellard | void OPPROTO op_xor_T1_T0(void) |
220 | 7a3f1944 | bellard | { |
221 | cf495bcf | bellard | T0 ^= T1; |
222 | 7a3f1944 | bellard | } |
223 | 7a3f1944 | bellard | |
224 | cf495bcf | bellard | void OPPROTO op_andn_T1_T0(void) |
225 | 7a3f1944 | bellard | { |
226 | cf495bcf | bellard | T0 &= ~T1; |
227 | 7a3f1944 | bellard | } |
228 | 7a3f1944 | bellard | |
229 | cf495bcf | bellard | void OPPROTO op_orn_T1_T0(void) |
230 | 7a3f1944 | bellard | { |
231 | cf495bcf | bellard | T0 |= ~T1; |
232 | 7a3f1944 | bellard | } |
233 | 7a3f1944 | bellard | |
234 | cf495bcf | bellard | void OPPROTO op_xnor_T1_T0(void) |
235 | 7a3f1944 | bellard | { |
236 | cf495bcf | bellard | T0 ^= ~T1; |
237 | 7a3f1944 | bellard | } |
238 | 7a3f1944 | bellard | |
239 | cf495bcf | bellard | void OPPROTO op_addx_T1_T0(void) |
240 | 7a3f1944 | bellard | { |
241 | cf495bcf | bellard | T0 += T1 + ((env->psr & PSR_CARRY) ? 1 : 0); |
242 | 7a3f1944 | bellard | } |
243 | 7a3f1944 | bellard | |
244 | cf495bcf | bellard | void OPPROTO op_umul_T1_T0(void) |
245 | 7a3f1944 | bellard | { |
246 | cf495bcf | bellard | uint64_t res; |
247 | cf495bcf | bellard | res = (uint64_t) T0 *(uint64_t) T1; |
248 | cf495bcf | bellard | T0 = res & 0xffffffff;
|
249 | cf495bcf | bellard | env->y = res >> 32;
|
250 | 7a3f1944 | bellard | } |
251 | 7a3f1944 | bellard | |
252 | cf495bcf | bellard | void OPPROTO op_smul_T1_T0(void) |
253 | 7a3f1944 | bellard | { |
254 | cf495bcf | bellard | uint64_t res; |
255 | cf495bcf | bellard | res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1); |
256 | cf495bcf | bellard | T0 = res & 0xffffffff;
|
257 | cf495bcf | bellard | env->y = res >> 32;
|
258 | 7a3f1944 | bellard | } |
259 | 7a3f1944 | bellard | |
260 | cf495bcf | bellard | void OPPROTO op_mulscc_T1_T0(void) |
261 | 7a3f1944 | bellard | { |
262 | 4e8b5da2 | bellard | unsigned int b1, N, V, b2, src1; |
263 | 4e8b5da2 | bellard | N = FLAG_SET(PSR_NEG); |
264 | cf495bcf | bellard | V = FLAG_SET(PSR_OVF); |
265 | 4e8b5da2 | bellard | b1 = N ^ V; |
266 | cf495bcf | bellard | b2 = T0 & 1;
|
267 | cf495bcf | bellard | T0 = (b1 << 31) | (T0 >> 1); |
268 | cf495bcf | bellard | if (!(env->y & 1)) |
269 | cf495bcf | bellard | T1 = 0;
|
270 | cf495bcf | bellard | /* do addition and update flags */
|
271 | cf495bcf | bellard | src1 = T0; |
272 | cf495bcf | bellard | T0 += T1; |
273 | cf495bcf | bellard | env->psr = 0;
|
274 | cf495bcf | bellard | if (!T0)
|
275 | cf495bcf | bellard | env->psr |= PSR_ZERO; |
276 | cf495bcf | bellard | if ((int) T0 < 0) |
277 | cf495bcf | bellard | env->psr |= PSR_NEG; |
278 | cf495bcf | bellard | if (T0 < src1)
|
279 | cf495bcf | bellard | env->psr |= PSR_CARRY; |
280 | cf495bcf | bellard | if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) |
281 | cf495bcf | bellard | env->psr |= PSR_OVF; |
282 | cf495bcf | bellard | env->y = (b2 << 31) | (env->y >> 1); |
283 | cf495bcf | bellard | FORCE_RET(); |
284 | cf495bcf | bellard | } |
285 | cf495bcf | bellard | |
286 | cf495bcf | bellard | void OPPROTO op_udiv_T1_T0(void) |
287 | cf495bcf | bellard | { |
288 | cf495bcf | bellard | uint64_t x0; |
289 | cf495bcf | bellard | uint32_t x1; |
290 | cf495bcf | bellard | |
291 | cf495bcf | bellard | x0 = T0 | ((uint64_t) (env->y) << 32);
|
292 | cf495bcf | bellard | x1 = T1; |
293 | cf495bcf | bellard | x0 = x0 / x1; |
294 | cf495bcf | bellard | if (x0 > 0xffffffff) { |
295 | cf495bcf | bellard | T0 = 0xffffffff;
|
296 | cf495bcf | bellard | T1 = 1;
|
297 | cf495bcf | bellard | } else {
|
298 | cf495bcf | bellard | T0 = x0; |
299 | cf495bcf | bellard | T1 = 0;
|
300 | cf495bcf | bellard | } |
301 | cf495bcf | bellard | FORCE_RET(); |
302 | 7a3f1944 | bellard | } |
303 | 7a3f1944 | bellard | |
304 | cf495bcf | bellard | void OPPROTO op_sdiv_T1_T0(void) |
305 | 7a3f1944 | bellard | { |
306 | cf495bcf | bellard | int64_t x0; |
307 | cf495bcf | bellard | int32_t x1; |
308 | cf495bcf | bellard | |
309 | cf495bcf | bellard | x0 = T0 | ((uint64_t) (env->y) << 32);
|
310 | cf495bcf | bellard | x1 = T1; |
311 | cf495bcf | bellard | x0 = x0 / x1; |
312 | cf495bcf | bellard | if ((int32_t) x0 != x0) {
|
313 | cf495bcf | bellard | T0 = x0 >> 63;
|
314 | cf495bcf | bellard | T1 = 1;
|
315 | cf495bcf | bellard | } else {
|
316 | cf495bcf | bellard | T0 = x0; |
317 | cf495bcf | bellard | T1 = 0;
|
318 | cf495bcf | bellard | } |
319 | cf495bcf | bellard | FORCE_RET(); |
320 | 7a3f1944 | bellard | } |
321 | 7a3f1944 | bellard | |
322 | cf495bcf | bellard | void OPPROTO op_div_cc(void) |
323 | 7a3f1944 | bellard | { |
324 | cf495bcf | bellard | env->psr = 0;
|
325 | cf495bcf | bellard | if (!T0)
|
326 | cf495bcf | bellard | env->psr |= PSR_ZERO; |
327 | cf495bcf | bellard | if ((int) T0 < 0) |
328 | cf495bcf | bellard | env->psr |= PSR_NEG; |
329 | cf495bcf | bellard | if (T1)
|
330 | cf495bcf | bellard | env->psr |= PSR_OVF; |
331 | cf495bcf | bellard | FORCE_RET(); |
332 | 7a3f1944 | bellard | } |
333 | 7a3f1944 | bellard | |
334 | cf495bcf | bellard | void OPPROTO op_subx_T1_T0(void) |
335 | 7a3f1944 | bellard | { |
336 | cf495bcf | bellard | T0 -= T1 + ((env->psr & PSR_CARRY) ? 1 : 0); |
337 | 7a3f1944 | bellard | } |
338 | 7a3f1944 | bellard | |
339 | cf495bcf | bellard | void OPPROTO op_logic_T0_cc(void) |
340 | 7a3f1944 | bellard | { |
341 | cf495bcf | bellard | env->psr = 0;
|
342 | cf495bcf | bellard | if (!T0)
|
343 | cf495bcf | bellard | env->psr |= PSR_ZERO; |
344 | cf495bcf | bellard | if ((int) T0 < 0) |
345 | cf495bcf | bellard | env->psr |= PSR_NEG; |
346 | cf495bcf | bellard | FORCE_RET(); |
347 | 7a3f1944 | bellard | } |
348 | 7a3f1944 | bellard | |
349 | cf495bcf | bellard | void OPPROTO op_set_flags(void) |
350 | 7a3f1944 | bellard | { |
351 | cf495bcf | bellard | env->psr = 0;
|
352 | cf495bcf | bellard | if (!T0)
|
353 | cf495bcf | bellard | env->psr |= PSR_ZERO; |
354 | cf495bcf | bellard | if ((unsigned int) T0 < (unsigned int) T1) |
355 | cf495bcf | bellard | env->psr |= PSR_CARRY; |
356 | cf495bcf | bellard | if ((int) T0 < (int) T1) |
357 | cf495bcf | bellard | env->psr |= PSR_OVF; |
358 | cf495bcf | bellard | if ((int) T0 < 0) |
359 | cf495bcf | bellard | env->psr |= PSR_NEG; |
360 | cf495bcf | bellard | FORCE_RET(); |
361 | 7a3f1944 | bellard | } |
362 | 7a3f1944 | bellard | |
363 | cf495bcf | bellard | void OPPROTO op_sll(void) |
364 | 7a3f1944 | bellard | { |
365 | cf495bcf | bellard | T0 <<= T1; |
366 | 7a3f1944 | bellard | } |
367 | 7a3f1944 | bellard | |
368 | cf495bcf | bellard | void OPPROTO op_srl(void) |
369 | 7a3f1944 | bellard | { |
370 | cf495bcf | bellard | T0 >>= T1; |
371 | 7a3f1944 | bellard | } |
372 | 7a3f1944 | bellard | |
373 | cf495bcf | bellard | void OPPROTO op_sra(void) |
374 | 7a3f1944 | bellard | { |
375 | cf495bcf | bellard | T0 = ((int32_t) T0) >> T1; |
376 | 7a3f1944 | bellard | } |
377 | 7a3f1944 | bellard | |
378 | cf495bcf | bellard | void OPPROTO op_st(void) |
379 | 7a3f1944 | bellard | { |
380 | cf495bcf | bellard | stl((void *) T0, T1);
|
381 | 7a3f1944 | bellard | } |
382 | 7a3f1944 | bellard | |
383 | cf495bcf | bellard | void OPPROTO op_stb(void) |
384 | 7a3f1944 | bellard | { |
385 | cf495bcf | bellard | stb((void *) T0, T1);
|
386 | 7a3f1944 | bellard | } |
387 | 7a3f1944 | bellard | |
388 | cf495bcf | bellard | void OPPROTO op_sth(void) |
389 | 7a3f1944 | bellard | { |
390 | cf495bcf | bellard | stw((void *) T0, T1);
|
391 | 7a3f1944 | bellard | } |
392 | 7a3f1944 | bellard | |
393 | cf495bcf | bellard | void OPPROTO op_std(void) |
394 | 7a3f1944 | bellard | { |
395 | cf495bcf | bellard | stl((void *) T0, T1);
|
396 | cf495bcf | bellard | stl((void *) (T0 + 4), T2); |
397 | 7a3f1944 | bellard | } |
398 | 7a3f1944 | bellard | |
399 | cf495bcf | bellard | void OPPROTO op_ld(void) |
400 | 7a3f1944 | bellard | { |
401 | cf495bcf | bellard | T1 = ldl((void *) T0);
|
402 | 7a3f1944 | bellard | } |
403 | 7a3f1944 | bellard | |
404 | cf495bcf | bellard | void OPPROTO op_ldub(void) |
405 | 7a3f1944 | bellard | { |
406 | cf495bcf | bellard | T1 = ldub((void *) T0);
|
407 | 7a3f1944 | bellard | } |
408 | 7a3f1944 | bellard | |
409 | cf495bcf | bellard | void OPPROTO op_lduh(void) |
410 | 7a3f1944 | bellard | { |
411 | cf495bcf | bellard | T1 = lduw((void *) T0);
|
412 | 7a3f1944 | bellard | } |
413 | 7a3f1944 | bellard | |
414 | cf495bcf | bellard | void OPPROTO op_ldsb(void) |
415 | 7a3f1944 | bellard | { |
416 | cf495bcf | bellard | T1 = ldsb((void *) T0);
|
417 | 7a3f1944 | bellard | } |
418 | 7a3f1944 | bellard | |
419 | cf495bcf | bellard | void OPPROTO op_ldsh(void) |
420 | 7a3f1944 | bellard | { |
421 | cf495bcf | bellard | T1 = ldsw((void *) T0);
|
422 | 7a3f1944 | bellard | } |
423 | 7a3f1944 | bellard | |
424 | cf495bcf | bellard | void OPPROTO op_ldstub(void) |
425 | cf495bcf | bellard | { |
426 | cf495bcf | bellard | T1 = ldub((void *) T0);
|
427 | cf495bcf | bellard | stb((void *) T0, 0xff); /* XXX: Should be Atomically */ |
428 | cf495bcf | bellard | } |
429 | 7a3f1944 | bellard | |
430 | cf495bcf | bellard | void OPPROTO op_swap(void) |
431 | 7a3f1944 | bellard | { |
432 | cf495bcf | bellard | unsigned int tmp = ldl((void *) T0); |
433 | cf495bcf | bellard | stl((void *) T0, T1); /* XXX: Should be Atomically */ |
434 | cf495bcf | bellard | T1 = tmp; |
435 | 7a3f1944 | bellard | } |
436 | 7a3f1944 | bellard | |
437 | cf495bcf | bellard | void OPPROTO op_ldd(void) |
438 | 7a3f1944 | bellard | { |
439 | cf495bcf | bellard | T1 = ldl((void *) T0);
|
440 | cf495bcf | bellard | T0 = ldl((void *) (T0 + 4)); |
441 | 7a3f1944 | bellard | } |
442 | 7a3f1944 | bellard | |
443 | cf495bcf | bellard | void OPPROTO op_wry(void) |
444 | 7a3f1944 | bellard | { |
445 | cf495bcf | bellard | env->y = T0; |
446 | 7a3f1944 | bellard | } |
447 | 7a3f1944 | bellard | |
448 | cf495bcf | bellard | void OPPROTO op_rdy(void) |
449 | 7a3f1944 | bellard | { |
450 | cf495bcf | bellard | T0 = env->y; |
451 | 7a3f1944 | bellard | } |
452 | 7a3f1944 | bellard | |
453 | cf495bcf | bellard | void raise_exception(int tt) |
454 | cf495bcf | bellard | { |
455 | cf495bcf | bellard | env->exception_index = tt; |
456 | cf495bcf | bellard | cpu_loop_exit(); |
457 | cf495bcf | bellard | } |
458 | cf495bcf | bellard | |
459 | cf495bcf | bellard | void memcpy32(uint32_t *dst, const uint32_t *src) |
460 | 7a3f1944 | bellard | { |
461 | cf495bcf | bellard | dst[0] = src[0]; |
462 | cf495bcf | bellard | dst[1] = src[1]; |
463 | cf495bcf | bellard | dst[2] = src[2]; |
464 | cf495bcf | bellard | dst[3] = src[3]; |
465 | cf495bcf | bellard | dst[4] = src[4]; |
466 | cf495bcf | bellard | dst[5] = src[5]; |
467 | cf495bcf | bellard | dst[6] = src[6]; |
468 | cf495bcf | bellard | dst[7] = src[7]; |
469 | 7a3f1944 | bellard | } |
470 | 7a3f1944 | bellard | |
471 | cf495bcf | bellard | static inline void set_cwp(int new_cwp) |
472 | cf495bcf | bellard | { |
473 | cf495bcf | bellard | /* put the modified wrap registers at their proper location */
|
474 | cf495bcf | bellard | if (env->cwp == (NWINDOWS - 1)) |
475 | cf495bcf | bellard | memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
|
476 | cf495bcf | bellard | env->cwp = new_cwp; |
477 | cf495bcf | bellard | /* put the wrap registers at their temporary location */
|
478 | cf495bcf | bellard | if (new_cwp == (NWINDOWS - 1)) |
479 | cf495bcf | bellard | memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
|
480 | cf495bcf | bellard | env->regwptr = env->regbase + (new_cwp * 16);
|
481 | cf495bcf | bellard | } |
482 | 7a3f1944 | bellard | |
483 | cf495bcf | bellard | /* XXX: use another pointer for %iN registers to avoid slow wrapping
|
484 | cf495bcf | bellard | handling ? */
|
485 | cf495bcf | bellard | void OPPROTO op_save(void) |
486 | 7a3f1944 | bellard | { |
487 | cf495bcf | bellard | int cwp;
|
488 | cf495bcf | bellard | cwp = (env->cwp - 1) & (NWINDOWS - 1); |
489 | cf495bcf | bellard | if (env->wim & (1 << cwp)) { |
490 | cf495bcf | bellard | raise_exception(TT_WIN_OVF); |
491 | cf495bcf | bellard | } |
492 | cf495bcf | bellard | set_cwp(cwp); |
493 | cf495bcf | bellard | FORCE_RET(); |
494 | 7a3f1944 | bellard | } |
495 | 7a3f1944 | bellard | |
496 | cf495bcf | bellard | void OPPROTO op_restore(void) |
497 | 7a3f1944 | bellard | { |
498 | cf495bcf | bellard | int cwp;
|
499 | cf495bcf | bellard | cwp = (env->cwp + 1) & (NWINDOWS - 1); |
500 | cf495bcf | bellard | if (env->wim & (1 << cwp)) { |
501 | cf495bcf | bellard | raise_exception(TT_WIN_UNF); |
502 | cf495bcf | bellard | } |
503 | cf495bcf | bellard | set_cwp(cwp); |
504 | cf495bcf | bellard | FORCE_RET(); |
505 | 7a3f1944 | bellard | } |
506 | 7a3f1944 | bellard | |
507 | cf495bcf | bellard | void OPPROTO op_exception(void) |
508 | 7a3f1944 | bellard | { |
509 | cf495bcf | bellard | env->exception_index = PARAM1; |
510 | cf495bcf | bellard | cpu_loop_exit(); |
511 | 7a3f1944 | bellard | } |
512 | 7a3f1944 | bellard | |
513 | cf495bcf | bellard | void OPPROTO op_trap_T0(void) |
514 | 7a3f1944 | bellard | { |
515 | cf495bcf | bellard | env->exception_index = TT_TRAP + (T0 & 0x7f);
|
516 | cf495bcf | bellard | cpu_loop_exit(); |
517 | 7a3f1944 | bellard | } |
518 | 7a3f1944 | bellard | |
519 | cf495bcf | bellard | void OPPROTO op_trapcc_T0(void) |
520 | 7a3f1944 | bellard | { |
521 | cf495bcf | bellard | if (T2) {
|
522 | cf495bcf | bellard | env->exception_index = TT_TRAP + (T0 & 0x7f);
|
523 | cf495bcf | bellard | cpu_loop_exit(); |
524 | cf495bcf | bellard | } |
525 | cf495bcf | bellard | FORCE_RET(); |
526 | 7a3f1944 | bellard | } |
527 | 7a3f1944 | bellard | |
528 | cf495bcf | bellard | void OPPROTO op_exit_tb(void) |
529 | 7a3f1944 | bellard | { |
530 | cf495bcf | bellard | EXIT_TB(); |
531 | 7a3f1944 | bellard | } |
532 | 7a3f1944 | bellard | |
533 | cf495bcf | bellard | void OPPROTO op_eval_be(void) |
534 | 7a3f1944 | bellard | { |
535 | cf495bcf | bellard | T2 = (env->psr & PSR_ZERO); |
536 | 7a3f1944 | bellard | } |
537 | 7a3f1944 | bellard | |
538 | cf495bcf | bellard | void OPPROTO op_eval_ble(void) |
539 | 7a3f1944 | bellard | { |
540 | 612b477d | bellard | unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
541 | 612b477d | bellard | |
542 | cf495bcf | bellard | T2 = Z | (N ^ V); |
543 | 7a3f1944 | bellard | } |
544 | 7a3f1944 | bellard | |
545 | cf495bcf | bellard | void OPPROTO op_eval_bl(void) |
546 | 7a3f1944 | bellard | { |
547 | 612b477d | bellard | unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
548 | 612b477d | bellard | |
549 | cf495bcf | bellard | T2 = N ^ V; |
550 | 7a3f1944 | bellard | } |
551 | 7a3f1944 | bellard | |
552 | cf495bcf | bellard | void OPPROTO op_eval_bleu(void) |
553 | 7a3f1944 | bellard | { |
554 | 612b477d | bellard | unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); |
555 | 612b477d | bellard | |
556 | cf495bcf | bellard | T2 = C | Z; |
557 | 7a3f1944 | bellard | } |
558 | 7a3f1944 | bellard | |
559 | cf495bcf | bellard | void OPPROTO op_eval_bcs(void) |
560 | 7a3f1944 | bellard | { |
561 | cf495bcf | bellard | T2 = (env->psr & PSR_CARRY); |
562 | 7a3f1944 | bellard | } |
563 | 7a3f1944 | bellard | |
564 | cf495bcf | bellard | void OPPROTO op_eval_bvs(void) |
565 | 7a3f1944 | bellard | { |
566 | cf495bcf | bellard | T2 = (env->psr & PSR_OVF); |
567 | 7a3f1944 | bellard | } |
568 | 7a3f1944 | bellard | |
569 | cf495bcf | bellard | void OPPROTO op_eval_bneg(void) |
570 | 7a3f1944 | bellard | { |
571 | cf495bcf | bellard | T2 = (env->psr & PSR_NEG); |
572 | 7a3f1944 | bellard | } |
573 | 7a3f1944 | bellard | |
574 | cf495bcf | bellard | void OPPROTO op_eval_bne(void) |
575 | 7a3f1944 | bellard | { |
576 | cf495bcf | bellard | T2 = !(env->psr & PSR_ZERO); |
577 | 7a3f1944 | bellard | } |
578 | 7a3f1944 | bellard | |
579 | cf495bcf | bellard | void OPPROTO op_eval_bg(void) |
580 | 7a3f1944 | bellard | { |
581 | 612b477d | bellard | unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
582 | 612b477d | bellard | |
583 | cf495bcf | bellard | T2 = !(Z | (N ^ V)); |
584 | 7a3f1944 | bellard | } |
585 | 7a3f1944 | bellard | |
586 | cf495bcf | bellard | void OPPROTO op_eval_bge(void) |
587 | 7a3f1944 | bellard | { |
588 | 612b477d | bellard | unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
589 | 612b477d | bellard | |
590 | cf495bcf | bellard | T2 = !(N ^ V); |
591 | 7a3f1944 | bellard | } |
592 | 7a3f1944 | bellard | |
593 | cf495bcf | bellard | void OPPROTO op_eval_bgu(void) |
594 | 7a3f1944 | bellard | { |
595 | 612b477d | bellard | unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); |
596 | 612b477d | bellard | |
597 | cf495bcf | bellard | T2 = !(C | Z); |
598 | 7a3f1944 | bellard | } |
599 | 7a3f1944 | bellard | |
600 | cf495bcf | bellard | void OPPROTO op_eval_bcc(void) |
601 | 7a3f1944 | bellard | { |
602 | cf495bcf | bellard | T2 = !(env->psr & PSR_CARRY); |
603 | 7a3f1944 | bellard | } |
604 | 7a3f1944 | bellard | |
605 | cf495bcf | bellard | void OPPROTO op_eval_bpos(void) |
606 | cf495bcf | bellard | { |
607 | cf495bcf | bellard | T2 = !(env->psr & PSR_NEG); |
608 | cf495bcf | bellard | } |
609 | cf495bcf | bellard | |
610 | cf495bcf | bellard | void OPPROTO op_eval_bvc(void) |
611 | cf495bcf | bellard | { |
612 | cf495bcf | bellard | T2 = !(env->psr & PSR_OVF); |
613 | cf495bcf | bellard | } |
614 | cf495bcf | bellard | |
615 | cf495bcf | bellard | void OPPROTO op_movl_T2_0(void) |
616 | cf495bcf | bellard | { |
617 | cf495bcf | bellard | T2 = 0;
|
618 | cf495bcf | bellard | } |
619 | cf495bcf | bellard | |
620 | cf495bcf | bellard | void OPPROTO op_movl_T2_1(void) |
621 | cf495bcf | bellard | { |
622 | cf495bcf | bellard | T2 = 1;
|
623 | cf495bcf | bellard | } |
624 | cf495bcf | bellard | |
625 | cf495bcf | bellard | void OPPROTO op_jmp_im(void) |
626 | cf495bcf | bellard | { |
627 | cf495bcf | bellard | env->pc = PARAM1; |
628 | cf495bcf | bellard | } |
629 | cf495bcf | bellard | |
630 | cf495bcf | bellard | void OPPROTO op_movl_npc_im(void) |
631 | cf495bcf | bellard | { |
632 | cf495bcf | bellard | env->npc = PARAM1; |
633 | cf495bcf | bellard | } |
634 | 7a3f1944 | bellard | |
635 | cf495bcf | bellard | void OPPROTO op_movl_npc_T0(void) |
636 | 7a3f1944 | bellard | { |
637 | cf495bcf | bellard | env->npc = T0; |
638 | 7a3f1944 | bellard | } |
639 | 7a3f1944 | bellard | |
640 | cf495bcf | bellard | void OPPROTO op_next_insn(void) |
641 | 7a3f1944 | bellard | { |
642 | cf495bcf | bellard | env->pc = env->npc; |
643 | cf495bcf | bellard | env->npc = env->npc + 4;
|
644 | 7a3f1944 | bellard | } |
645 | 7a3f1944 | bellard | |
646 | 72cbca10 | bellard | void OPPROTO op_branch(void) |
647 | 72cbca10 | bellard | { |
648 | 72cbca10 | bellard | env->npc = PARAM3; /* XXX: optimize */
|
649 | 72cbca10 | bellard | JUMP_TB(op_branch, PARAM1, 0, PARAM2);
|
650 | 72cbca10 | bellard | } |
651 | 72cbca10 | bellard | |
652 | 72cbca10 | bellard | void OPPROTO op_branch2(void) |
653 | 7a3f1944 | bellard | { |
654 | cf495bcf | bellard | if (T2) {
|
655 | 72cbca10 | bellard | env->npc = PARAM2 + 4;
|
656 | 72cbca10 | bellard | JUMP_TB(op_branch2, PARAM1, 0, PARAM2);
|
657 | cf495bcf | bellard | } else {
|
658 | 72cbca10 | bellard | env->npc = PARAM3 + 4;
|
659 | 72cbca10 | bellard | JUMP_TB(op_branch2, PARAM1, 1, PARAM3);
|
660 | 72cbca10 | bellard | } |
661 | 72cbca10 | bellard | FORCE_RET(); |
662 | 72cbca10 | bellard | } |
663 | 72cbca10 | bellard | |
664 | 72cbca10 | bellard | void OPPROTO op_branch_a(void) |
665 | 72cbca10 | bellard | { |
666 | 72cbca10 | bellard | if (T2) {
|
667 | 72cbca10 | bellard | env->npc = PARAM2; /* XXX: optimize */
|
668 | 72cbca10 | bellard | JUMP_TB(op_generic_branch_a, PARAM1, 0, PARAM3);
|
669 | 72cbca10 | bellard | } else {
|
670 | 72cbca10 | bellard | env->npc = PARAM3 + 8; /* XXX: optimize */ |
671 | 72cbca10 | bellard | JUMP_TB(op_generic_branch_a, PARAM1, 1, PARAM3 + 4); |
672 | cf495bcf | bellard | } |
673 | cf495bcf | bellard | FORCE_RET(); |
674 | 7a3f1944 | bellard | } |
675 | 7a3f1944 | bellard | |
676 | 72cbca10 | bellard | void OPPROTO op_generic_branch(void) |
677 | 7a3f1944 | bellard | { |
678 | cf495bcf | bellard | if (T2) {
|
679 | cf495bcf | bellard | env->npc = PARAM1; |
680 | cf495bcf | bellard | } else {
|
681 | 72cbca10 | bellard | env->npc = PARAM2; |
682 | cf495bcf | bellard | } |
683 | cf495bcf | bellard | FORCE_RET(); |
684 | 7a3f1944 | bellard | } |
685 | 72cbca10 | bellard | |
686 | 658138bc | bellard | void OPPROTO op_flush_T0(void) |
687 | 658138bc | bellard | { |
688 | 658138bc | bellard | helper_flush(T0); |
689 | 658138bc | bellard | } |