]>
Commit | Line | Data |
---|---|---|
7a3f1944 FB |
1 | /* |
2 | SPARC micro operations | |
3 | ||
4 | Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at> | |
5 | ||
6 | This library is free software; you can redistribute it and/or | |
7 | modify it under the terms of the GNU Lesser General Public | |
8 | License as published by the Free Software Foundation; either | |
9 | version 2 of the License, or (at your option) any later version. | |
10 | ||
11 | This library is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | Lesser General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public | |
17 | License along with this library; if not, write to the Free Software | |
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | */ | |
20 | ||
21 | #include "exec.h" | |
22 | ||
cf495bcf | 23 | /*XXX*/ |
7a3f1944 FB |
24 | #define REGNAME g0 |
25 | #define REG (env->gregs[0]) | |
26 | #include "op_template.h" | |
27 | #define REGNAME g1 | |
28 | #define REG (env->gregs[1]) | |
29 | #include "op_template.h" | |
30 | #define REGNAME g2 | |
31 | #define REG (env->gregs[2]) | |
32 | #include "op_template.h" | |
33 | #define REGNAME g3 | |
34 | #define REG (env->gregs[3]) | |
35 | #include "op_template.h" | |
36 | #define REGNAME g4 | |
37 | #define REG (env->gregs[4]) | |
38 | #include "op_template.h" | |
39 | #define REGNAME g5 | |
40 | #define REG (env->gregs[5]) | |
41 | #include "op_template.h" | |
42 | #define REGNAME g6 | |
43 | #define REG (env->gregs[6]) | |
44 | #include "op_template.h" | |
45 | #define REGNAME g7 | |
46 | #define REG (env->gregs[7]) | |
47 | #include "op_template.h" | |
48 | #define REGNAME i0 | |
49 | #define REG (env->regwptr[16]) | |
50 | #include "op_template.h" | |
51 | #define REGNAME i1 | |
52 | #define REG (env->regwptr[17]) | |
53 | #include "op_template.h" | |
54 | #define REGNAME i2 | |
55 | #define REG (env->regwptr[18]) | |
56 | #include "op_template.h" | |
57 | #define REGNAME i3 | |
58 | #define REG (env->regwptr[19]) | |
59 | #include "op_template.h" | |
60 | #define REGNAME i4 | |
61 | #define REG (env->regwptr[20]) | |
62 | #include "op_template.h" | |
63 | #define REGNAME i5 | |
64 | #define REG (env->regwptr[21]) | |
65 | #include "op_template.h" | |
66 | #define REGNAME i6 | |
67 | #define REG (env->regwptr[22]) | |
68 | #include "op_template.h" | |
69 | #define REGNAME i7 | |
70 | #define REG (env->regwptr[23]) | |
71 | #include "op_template.h" | |
72 | #define REGNAME l0 | |
73 | #define REG (env->regwptr[8]) | |
74 | #include "op_template.h" | |
75 | #define REGNAME l1 | |
76 | #define REG (env->regwptr[9]) | |
77 | #include "op_template.h" | |
78 | #define REGNAME l2 | |
79 | #define REG (env->regwptr[10]) | |
80 | #include "op_template.h" | |
81 | #define REGNAME l3 | |
82 | #define REG (env->regwptr[11]) | |
83 | #include "op_template.h" | |
84 | #define REGNAME l4 | |
85 | #define REG (env->regwptr[12]) | |
86 | #include "op_template.h" | |
87 | #define REGNAME l5 | |
88 | #define REG (env->regwptr[13]) | |
89 | #include "op_template.h" | |
90 | #define REGNAME l6 | |
91 | #define REG (env->regwptr[14]) | |
92 | #include "op_template.h" | |
93 | #define REGNAME l7 | |
94 | #define REG (env->regwptr[15]) | |
95 | #include "op_template.h" | |
96 | #define REGNAME o0 | |
97 | #define REG (env->regwptr[0]) | |
98 | #include "op_template.h" | |
99 | #define REGNAME o1 | |
100 | #define REG (env->regwptr[1]) | |
101 | #include "op_template.h" | |
102 | #define REGNAME o2 | |
103 | #define REG (env->regwptr[2]) | |
104 | #include "op_template.h" | |
105 | #define REGNAME o3 | |
106 | #define REG (env->regwptr[3]) | |
107 | #include "op_template.h" | |
108 | #define REGNAME o4 | |
109 | #define REG (env->regwptr[4]) | |
110 | #include "op_template.h" | |
111 | #define REGNAME o5 | |
112 | #define REG (env->regwptr[5]) | |
113 | #include "op_template.h" | |
114 | #define REGNAME o6 | |
115 | #define REG (env->regwptr[6]) | |
116 | #include "op_template.h" | |
117 | #define REGNAME o7 | |
118 | #define REG (env->regwptr[7]) | |
119 | #include "op_template.h" | |
e8af50a3 FB |
120 | |
121 | #define REGNAME f0 | |
122 | #define REG (env->fpr[0]) | |
123 | #include "fop_template.h" | |
124 | #define REGNAME f1 | |
125 | #define REG (env->fpr[1]) | |
126 | #include "fop_template.h" | |
127 | #define REGNAME f2 | |
128 | #define REG (env->fpr[2]) | |
129 | #include "fop_template.h" | |
130 | #define REGNAME f3 | |
131 | #define REG (env->fpr[3]) | |
132 | #include "fop_template.h" | |
133 | #define REGNAME f4 | |
134 | #define REG (env->fpr[4]) | |
135 | #include "fop_template.h" | |
136 | #define REGNAME f5 | |
137 | #define REG (env->fpr[5]) | |
138 | #include "fop_template.h" | |
139 | #define REGNAME f6 | |
140 | #define REG (env->fpr[6]) | |
141 | #include "fop_template.h" | |
142 | #define REGNAME f7 | |
143 | #define REG (env->fpr[7]) | |
144 | #include "fop_template.h" | |
145 | #define REGNAME f8 | |
146 | #define REG (env->fpr[8]) | |
147 | #include "fop_template.h" | |
148 | #define REGNAME f9 | |
149 | #define REG (env->fpr[9]) | |
150 | #include "fop_template.h" | |
151 | #define REGNAME f10 | |
152 | #define REG (env->fpr[10]) | |
153 | #include "fop_template.h" | |
154 | #define REGNAME f11 | |
155 | #define REG (env->fpr[11]) | |
156 | #include "fop_template.h" | |
157 | #define REGNAME f12 | |
158 | #define REG (env->fpr[12]) | |
159 | #include "fop_template.h" | |
160 | #define REGNAME f13 | |
161 | #define REG (env->fpr[13]) | |
162 | #include "fop_template.h" | |
163 | #define REGNAME f14 | |
164 | #define REG (env->fpr[14]) | |
165 | #include "fop_template.h" | |
166 | #define REGNAME f15 | |
167 | #define REG (env->fpr[15]) | |
168 | #include "fop_template.h" | |
169 | #define REGNAME f16 | |
170 | #define REG (env->fpr[16]) | |
171 | #include "fop_template.h" | |
172 | #define REGNAME f17 | |
173 | #define REG (env->fpr[17]) | |
174 | #include "fop_template.h" | |
175 | #define REGNAME f18 | |
176 | #define REG (env->fpr[18]) | |
177 | #include "fop_template.h" | |
178 | #define REGNAME f19 | |
179 | #define REG (env->fpr[19]) | |
180 | #include "fop_template.h" | |
181 | #define REGNAME f20 | |
182 | #define REG (env->fpr[20]) | |
183 | #include "fop_template.h" | |
184 | #define REGNAME f21 | |
185 | #define REG (env->fpr[21]) | |
186 | #include "fop_template.h" | |
187 | #define REGNAME f22 | |
188 | #define REG (env->fpr[22]) | |
189 | #include "fop_template.h" | |
190 | #define REGNAME f23 | |
191 | #define REG (env->fpr[23]) | |
192 | #include "fop_template.h" | |
193 | #define REGNAME f24 | |
194 | #define REG (env->fpr[24]) | |
195 | #include "fop_template.h" | |
196 | #define REGNAME f25 | |
197 | #define REG (env->fpr[25]) | |
198 | #include "fop_template.h" | |
199 | #define REGNAME f26 | |
200 | #define REG (env->fpr[26]) | |
201 | #include "fop_template.h" | |
202 | #define REGNAME f27 | |
203 | #define REG (env->fpr[27]) | |
204 | #include "fop_template.h" | |
205 | #define REGNAME f28 | |
206 | #define REG (env->fpr[28]) | |
207 | #include "fop_template.h" | |
208 | #define REGNAME f29 | |
209 | #define REG (env->fpr[29]) | |
210 | #include "fop_template.h" | |
211 | #define REGNAME f30 | |
212 | #define REG (env->fpr[30]) | |
213 | #include "fop_template.h" | |
214 | #define REGNAME f31 | |
215 | #define REG (env->fpr[31]) | |
216 | #include "fop_template.h" | |
217 | ||
7a3f1944 FB |
218 | #define EIP (env->pc) |
219 | ||
cf495bcf | 220 | #define FLAG_SET(x) (env->psr&x)?1:0 |
e8af50a3 | 221 | #define FFLAG_SET(x) ((env->fsr&x)?1:0) |
cf495bcf | 222 | |
7a3f1944 FB |
223 | void OPPROTO op_movl_T0_0(void) |
224 | { | |
cf495bcf | 225 | T0 = 0; |
7a3f1944 FB |
226 | } |
227 | ||
228 | void OPPROTO op_movl_T0_1(void) | |
229 | { | |
cf495bcf | 230 | T0 = 1; |
7a3f1944 FB |
231 | } |
232 | ||
233 | void OPPROTO op_movl_T0_im(void) | |
234 | { | |
cf495bcf | 235 | T0 = PARAM1; |
7a3f1944 FB |
236 | } |
237 | ||
238 | void OPPROTO op_movl_T1_im(void) | |
239 | { | |
cf495bcf | 240 | T1 = PARAM1; |
7a3f1944 FB |
241 | } |
242 | ||
243 | void OPPROTO op_movl_T2_im(void) | |
244 | { | |
cf495bcf | 245 | T2 = PARAM1; |
7a3f1944 FB |
246 | } |
247 | ||
248 | void OPPROTO op_addl_T1_im(void) | |
249 | { | |
cf495bcf | 250 | T1 += PARAM1; |
7a3f1944 FB |
251 | } |
252 | ||
253 | void OPPROTO op_addl_T1_T2(void) | |
254 | { | |
cf495bcf | 255 | T1 += T2; |
7a3f1944 FB |
256 | } |
257 | ||
258 | void OPPROTO op_subl_T1_T2(void) | |
259 | { | |
cf495bcf | 260 | T1 -= T2; |
7a3f1944 FB |
261 | } |
262 | ||
cf495bcf | 263 | void OPPROTO op_add_T1_T0(void) |
7a3f1944 | 264 | { |
cf495bcf | 265 | T0 += T1; |
7a3f1944 FB |
266 | } |
267 | ||
cf495bcf | 268 | void OPPROTO op_add_T1_T0_cc(void) |
7a3f1944 | 269 | { |
cf495bcf FB |
270 | unsigned int src1; |
271 | src1 = T0; | |
272 | T0 += T1; | |
273 | env->psr = 0; | |
274 | if (!T0) | |
275 | env->psr |= PSR_ZERO; | |
276 | if ((int) T0 < 0) | |
277 | env->psr |= PSR_NEG; | |
278 | if (T0 < src1) | |
279 | env->psr |= PSR_CARRY; | |
280 | if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) | |
281 | env->psr |= PSR_OVF; | |
282 | FORCE_RET(); | |
7a3f1944 FB |
283 | } |
284 | ||
cf495bcf | 285 | void OPPROTO op_sub_T1_T0(void) |
7a3f1944 | 286 | { |
cf495bcf | 287 | T0 -= T1; |
7a3f1944 FB |
288 | } |
289 | ||
cf495bcf | 290 | void OPPROTO op_sub_T1_T0_cc(void) |
7a3f1944 | 291 | { |
cf495bcf FB |
292 | unsigned int src1; |
293 | ||
294 | src1 = T0; | |
295 | T0 -= T1; | |
296 | env->psr = 0; | |
297 | if (!T0) | |
298 | env->psr |= PSR_ZERO; | |
299 | if ((int) T0 < 0) | |
300 | env->psr |= PSR_NEG; | |
301 | if (src1 < T1) | |
302 | env->psr |= PSR_CARRY; | |
303 | if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) | |
304 | env->psr |= PSR_OVF; | |
305 | FORCE_RET(); | |
7a3f1944 FB |
306 | } |
307 | ||
cf495bcf | 308 | void OPPROTO op_and_T1_T0(void) |
7a3f1944 | 309 | { |
cf495bcf | 310 | T0 &= T1; |
7a3f1944 FB |
311 | } |
312 | ||
cf495bcf | 313 | void OPPROTO op_or_T1_T0(void) |
7a3f1944 | 314 | { |
cf495bcf | 315 | T0 |= T1; |
7a3f1944 FB |
316 | } |
317 | ||
cf495bcf | 318 | void OPPROTO op_xor_T1_T0(void) |
7a3f1944 | 319 | { |
cf495bcf | 320 | T0 ^= T1; |
7a3f1944 FB |
321 | } |
322 | ||
cf495bcf | 323 | void OPPROTO op_andn_T1_T0(void) |
7a3f1944 | 324 | { |
cf495bcf | 325 | T0 &= ~T1; |
7a3f1944 FB |
326 | } |
327 | ||
cf495bcf | 328 | void OPPROTO op_orn_T1_T0(void) |
7a3f1944 | 329 | { |
cf495bcf | 330 | T0 |= ~T1; |
7a3f1944 FB |
331 | } |
332 | ||
cf495bcf | 333 | void OPPROTO op_xnor_T1_T0(void) |
7a3f1944 | 334 | { |
cf495bcf | 335 | T0 ^= ~T1; |
7a3f1944 FB |
336 | } |
337 | ||
cf495bcf | 338 | void OPPROTO op_addx_T1_T0(void) |
7a3f1944 | 339 | { |
cf495bcf | 340 | T0 += T1 + ((env->psr & PSR_CARRY) ? 1 : 0); |
7a3f1944 FB |
341 | } |
342 | ||
cf495bcf | 343 | void OPPROTO op_umul_T1_T0(void) |
7a3f1944 | 344 | { |
cf495bcf FB |
345 | uint64_t res; |
346 | res = (uint64_t) T0 *(uint64_t) T1; | |
347 | T0 = res & 0xffffffff; | |
348 | env->y = res >> 32; | |
7a3f1944 FB |
349 | } |
350 | ||
cf495bcf | 351 | void OPPROTO op_smul_T1_T0(void) |
7a3f1944 | 352 | { |
cf495bcf FB |
353 | uint64_t res; |
354 | res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1); | |
355 | T0 = res & 0xffffffff; | |
356 | env->y = res >> 32; | |
7a3f1944 FB |
357 | } |
358 | ||
cf495bcf | 359 | void OPPROTO op_mulscc_T1_T0(void) |
7a3f1944 | 360 | { |
4e8b5da2 FB |
361 | unsigned int b1, N, V, b2, src1; |
362 | N = FLAG_SET(PSR_NEG); | |
cf495bcf | 363 | V = FLAG_SET(PSR_OVF); |
4e8b5da2 | 364 | b1 = N ^ V; |
cf495bcf FB |
365 | b2 = T0 & 1; |
366 | T0 = (b1 << 31) | (T0 >> 1); | |
367 | if (!(env->y & 1)) | |
368 | T1 = 0; | |
369 | /* do addition and update flags */ | |
370 | src1 = T0; | |
371 | T0 += T1; | |
372 | env->psr = 0; | |
373 | if (!T0) | |
374 | env->psr |= PSR_ZERO; | |
375 | if ((int) T0 < 0) | |
376 | env->psr |= PSR_NEG; | |
377 | if (T0 < src1) | |
378 | env->psr |= PSR_CARRY; | |
379 | if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) | |
380 | env->psr |= PSR_OVF; | |
381 | env->y = (b2 << 31) | (env->y >> 1); | |
382 | FORCE_RET(); | |
383 | } | |
384 | ||
385 | void OPPROTO op_udiv_T1_T0(void) | |
386 | { | |
387 | uint64_t x0; | |
388 | uint32_t x1; | |
389 | ||
390 | x0 = T0 | ((uint64_t) (env->y) << 32); | |
391 | x1 = T1; | |
392 | x0 = x0 / x1; | |
393 | if (x0 > 0xffffffff) { | |
394 | T0 = 0xffffffff; | |
395 | T1 = 1; | |
396 | } else { | |
397 | T0 = x0; | |
398 | T1 = 0; | |
399 | } | |
400 | FORCE_RET(); | |
7a3f1944 FB |
401 | } |
402 | ||
cf495bcf | 403 | void OPPROTO op_sdiv_T1_T0(void) |
7a3f1944 | 404 | { |
cf495bcf FB |
405 | int64_t x0; |
406 | int32_t x1; | |
407 | ||
408 | x0 = T0 | ((uint64_t) (env->y) << 32); | |
409 | x1 = T1; | |
410 | x0 = x0 / x1; | |
411 | if ((int32_t) x0 != x0) { | |
412 | T0 = x0 >> 63; | |
413 | T1 = 1; | |
414 | } else { | |
415 | T0 = x0; | |
416 | T1 = 0; | |
417 | } | |
418 | FORCE_RET(); | |
7a3f1944 FB |
419 | } |
420 | ||
cf495bcf | 421 | void OPPROTO op_div_cc(void) |
7a3f1944 | 422 | { |
cf495bcf FB |
423 | env->psr = 0; |
424 | if (!T0) | |
425 | env->psr |= PSR_ZERO; | |
426 | if ((int) T0 < 0) | |
427 | env->psr |= PSR_NEG; | |
428 | if (T1) | |
429 | env->psr |= PSR_OVF; | |
430 | FORCE_RET(); | |
7a3f1944 FB |
431 | } |
432 | ||
cf495bcf | 433 | void OPPROTO op_subx_T1_T0(void) |
7a3f1944 | 434 | { |
cf495bcf | 435 | T0 -= T1 + ((env->psr & PSR_CARRY) ? 1 : 0); |
7a3f1944 FB |
436 | } |
437 | ||
cf495bcf | 438 | void OPPROTO op_logic_T0_cc(void) |
7a3f1944 | 439 | { |
cf495bcf FB |
440 | env->psr = 0; |
441 | if (!T0) | |
442 | env->psr |= PSR_ZERO; | |
443 | if ((int) T0 < 0) | |
444 | env->psr |= PSR_NEG; | |
445 | FORCE_RET(); | |
7a3f1944 FB |
446 | } |
447 | ||
cf495bcf | 448 | void OPPROTO op_set_flags(void) |
7a3f1944 | 449 | { |
cf495bcf FB |
450 | env->psr = 0; |
451 | if (!T0) | |
452 | env->psr |= PSR_ZERO; | |
453 | if ((unsigned int) T0 < (unsigned int) T1) | |
454 | env->psr |= PSR_CARRY; | |
455 | if ((int) T0 < (int) T1) | |
456 | env->psr |= PSR_OVF; | |
457 | if ((int) T0 < 0) | |
458 | env->psr |= PSR_NEG; | |
459 | FORCE_RET(); | |
7a3f1944 FB |
460 | } |
461 | ||
cf495bcf | 462 | void OPPROTO op_sll(void) |
7a3f1944 | 463 | { |
cf495bcf | 464 | T0 <<= T1; |
7a3f1944 FB |
465 | } |
466 | ||
cf495bcf | 467 | void OPPROTO op_srl(void) |
7a3f1944 | 468 | { |
cf495bcf | 469 | T0 >>= T1; |
7a3f1944 FB |
470 | } |
471 | ||
cf495bcf | 472 | void OPPROTO op_sra(void) |
7a3f1944 | 473 | { |
cf495bcf | 474 | T0 = ((int32_t) T0) >> T1; |
7a3f1944 FB |
475 | } |
476 | ||
e8af50a3 | 477 | #if 0 |
cf495bcf | 478 | void OPPROTO op_st(void) |
7a3f1944 | 479 | { |
cf495bcf | 480 | stl((void *) T0, T1); |
7a3f1944 FB |
481 | } |
482 | ||
cf495bcf | 483 | void OPPROTO op_stb(void) |
7a3f1944 | 484 | { |
cf495bcf | 485 | stb((void *) T0, T1); |
7a3f1944 FB |
486 | } |
487 | ||
cf495bcf | 488 | void OPPROTO op_sth(void) |
7a3f1944 | 489 | { |
cf495bcf | 490 | stw((void *) T0, T1); |
7a3f1944 FB |
491 | } |
492 | ||
cf495bcf | 493 | void OPPROTO op_std(void) |
7a3f1944 | 494 | { |
cf495bcf FB |
495 | stl((void *) T0, T1); |
496 | stl((void *) (T0 + 4), T2); | |
7a3f1944 FB |
497 | } |
498 | ||
cf495bcf | 499 | void OPPROTO op_ld(void) |
7a3f1944 | 500 | { |
cf495bcf | 501 | T1 = ldl((void *) T0); |
7a3f1944 FB |
502 | } |
503 | ||
cf495bcf | 504 | void OPPROTO op_ldub(void) |
7a3f1944 | 505 | { |
cf495bcf | 506 | T1 = ldub((void *) T0); |
7a3f1944 FB |
507 | } |
508 | ||
cf495bcf | 509 | void OPPROTO op_lduh(void) |
7a3f1944 | 510 | { |
cf495bcf | 511 | T1 = lduw((void *) T0); |
7a3f1944 FB |
512 | } |
513 | ||
cf495bcf | 514 | void OPPROTO op_ldsb(void) |
7a3f1944 | 515 | { |
cf495bcf | 516 | T1 = ldsb((void *) T0); |
7a3f1944 FB |
517 | } |
518 | ||
cf495bcf | 519 | void OPPROTO op_ldsh(void) |
7a3f1944 | 520 | { |
cf495bcf | 521 | T1 = ldsw((void *) T0); |
7a3f1944 FB |
522 | } |
523 | ||
cf495bcf FB |
524 | void OPPROTO op_ldstub(void) |
525 | { | |
526 | T1 = ldub((void *) T0); | |
527 | stb((void *) T0, 0xff); /* XXX: Should be Atomically */ | |
528 | } | |
7a3f1944 | 529 | |
cf495bcf | 530 | void OPPROTO op_swap(void) |
7a3f1944 | 531 | { |
cf495bcf FB |
532 | unsigned int tmp = ldl((void *) T0); |
533 | stl((void *) T0, T1); /* XXX: Should be Atomically */ | |
534 | T1 = tmp; | |
7a3f1944 FB |
535 | } |
536 | ||
cf495bcf | 537 | void OPPROTO op_ldd(void) |
7a3f1944 | 538 | { |
cf495bcf FB |
539 | T1 = ldl((void *) T0); |
540 | T0 = ldl((void *) (T0 + 4)); | |
7a3f1944 FB |
541 | } |
542 | ||
e8af50a3 FB |
543 | void OPPROTO op_stf(void) |
544 | { | |
545 | stfl((void *) T0, FT0); | |
546 | } | |
547 | ||
548 | void OPPROTO op_stdf(void) | |
549 | { | |
550 | stfq((void *) T0, DT0); | |
551 | } | |
552 | ||
553 | void OPPROTO op_ldf(void) | |
554 | { | |
555 | FT0 = ldfl((void *) T0); | |
556 | } | |
557 | ||
558 | void OPPROTO op_lddf(void) | |
559 | { | |
560 | DT0 = ldfq((void *) T0); | |
561 | } | |
562 | #else | |
563 | /* Load and store */ | |
564 | #define MEMSUFFIX _raw | |
565 | #include "op_mem.h" | |
566 | #if !defined(CONFIG_USER_ONLY) | |
567 | #define MEMSUFFIX _user | |
568 | #include "op_mem.h" | |
569 | ||
570 | #define MEMSUFFIX _kernel | |
571 | #include "op_mem.h" | |
572 | #endif | |
573 | #endif | |
574 | ||
575 | void OPPROTO op_ldfsr(void) | |
576 | { | |
577 | env->fsr = *((uint32_t *) &FT0); | |
578 | FORCE_RET(); | |
579 | } | |
580 | ||
581 | void OPPROTO op_stfsr(void) | |
582 | { | |
583 | *((uint32_t *) &FT0) = env->fsr; | |
584 | helper_stfsr(); | |
585 | FORCE_RET(); | |
586 | } | |
587 | ||
cf495bcf | 588 | void OPPROTO op_wry(void) |
7a3f1944 | 589 | { |
cf495bcf | 590 | env->y = T0; |
7a3f1944 FB |
591 | } |
592 | ||
cf495bcf | 593 | void OPPROTO op_rdy(void) |
7a3f1944 | 594 | { |
cf495bcf | 595 | T0 = env->y; |
7a3f1944 FB |
596 | } |
597 | ||
e8af50a3 | 598 | void OPPROTO op_rdwim(void) |
cf495bcf | 599 | { |
e8af50a3 FB |
600 | T0 = env->wim; |
601 | } | |
602 | ||
603 | void OPPROTO op_wrwim(void) | |
604 | { | |
605 | env->wim = T0; | |
606 | FORCE_RET(); | |
607 | } | |
608 | ||
609 | void OPPROTO op_rdpsr(void) | |
610 | { | |
611 | T0 = GET_PSR(env); | |
612 | FORCE_RET(); | |
613 | } | |
614 | ||
615 | void OPPROTO op_wrpsr(void) | |
616 | { | |
617 | env->psr = T0 & ~PSR_ICC; | |
618 | env->psrs = (T0 & PSR_S)? 1 : 0; | |
619 | env->psrps = (T0 & PSR_PS)? 1 : 0; | |
620 | env->psret = (T0 & PSR_ET)? 1 : 0; | |
621 | env->cwp = (T0 & PSR_CWP); | |
622 | FORCE_RET(); | |
623 | } | |
624 | ||
625 | void OPPROTO op_rdtbr(void) | |
626 | { | |
627 | T0 = env->tbr; | |
628 | } | |
cf495bcf | 629 | |
e8af50a3 | 630 | void OPPROTO op_wrtbr(void) |
7a3f1944 | 631 | { |
e8af50a3 FB |
632 | env->tbr = T0; |
633 | FORCE_RET(); | |
7a3f1944 FB |
634 | } |
635 | ||
e8af50a3 | 636 | void OPPROTO op_rett(void) |
cf495bcf | 637 | { |
e8af50a3 FB |
638 | helper_rett(); |
639 | FORCE_RET(); | |
cf495bcf | 640 | } |
7a3f1944 | 641 | |
e8af50a3 FB |
642 | void raise_exception(int tt) |
643 | { | |
644 | env->exception_index = tt; | |
645 | cpu_loop_exit(); | |
646 | } | |
647 | ||
cf495bcf FB |
648 | /* XXX: use another pointer for %iN registers to avoid slow wrapping |
649 | handling ? */ | |
650 | void OPPROTO op_save(void) | |
7a3f1944 | 651 | { |
cf495bcf FB |
652 | int cwp; |
653 | cwp = (env->cwp - 1) & (NWINDOWS - 1); | |
654 | if (env->wim & (1 << cwp)) { | |
655 | raise_exception(TT_WIN_OVF); | |
656 | } | |
657 | set_cwp(cwp); | |
658 | FORCE_RET(); | |
7a3f1944 FB |
659 | } |
660 | ||
cf495bcf | 661 | void OPPROTO op_restore(void) |
7a3f1944 | 662 | { |
cf495bcf FB |
663 | int cwp; |
664 | cwp = (env->cwp + 1) & (NWINDOWS - 1); | |
665 | if (env->wim & (1 << cwp)) { | |
666 | raise_exception(TT_WIN_UNF); | |
667 | } | |
668 | set_cwp(cwp); | |
669 | FORCE_RET(); | |
7a3f1944 FB |
670 | } |
671 | ||
cf495bcf | 672 | void OPPROTO op_exception(void) |
7a3f1944 | 673 | { |
cf495bcf FB |
674 | env->exception_index = PARAM1; |
675 | cpu_loop_exit(); | |
7a3f1944 FB |
676 | } |
677 | ||
cf495bcf | 678 | void OPPROTO op_trap_T0(void) |
7a3f1944 | 679 | { |
cf495bcf FB |
680 | env->exception_index = TT_TRAP + (T0 & 0x7f); |
681 | cpu_loop_exit(); | |
7a3f1944 FB |
682 | } |
683 | ||
cf495bcf | 684 | void OPPROTO op_trapcc_T0(void) |
7a3f1944 | 685 | { |
cf495bcf FB |
686 | if (T2) { |
687 | env->exception_index = TT_TRAP + (T0 & 0x7f); | |
688 | cpu_loop_exit(); | |
689 | } | |
690 | FORCE_RET(); | |
7a3f1944 FB |
691 | } |
692 | ||
e8af50a3 FB |
693 | void OPPROTO op_debug(void) |
694 | { | |
695 | env->exception_index = EXCP_DEBUG; | |
696 | cpu_loop_exit(); | |
697 | } | |
698 | ||
cf495bcf | 699 | void OPPROTO op_exit_tb(void) |
7a3f1944 | 700 | { |
cf495bcf | 701 | EXIT_TB(); |
7a3f1944 FB |
702 | } |
703 | ||
cf495bcf | 704 | void OPPROTO op_eval_be(void) |
7a3f1944 | 705 | { |
cf495bcf | 706 | T2 = (env->psr & PSR_ZERO); |
7a3f1944 FB |
707 | } |
708 | ||
cf495bcf | 709 | void OPPROTO op_eval_ble(void) |
7a3f1944 | 710 | { |
612b477d FB |
711 | unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
712 | ||
cf495bcf | 713 | T2 = Z | (N ^ V); |
7a3f1944 FB |
714 | } |
715 | ||
cf495bcf | 716 | void OPPROTO op_eval_bl(void) |
7a3f1944 | 717 | { |
612b477d FB |
718 | unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
719 | ||
cf495bcf | 720 | T2 = N ^ V; |
7a3f1944 FB |
721 | } |
722 | ||
cf495bcf | 723 | void OPPROTO op_eval_bleu(void) |
7a3f1944 | 724 | { |
612b477d FB |
725 | unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); |
726 | ||
cf495bcf | 727 | T2 = C | Z; |
7a3f1944 FB |
728 | } |
729 | ||
cf495bcf | 730 | void OPPROTO op_eval_bcs(void) |
7a3f1944 | 731 | { |
cf495bcf | 732 | T2 = (env->psr & PSR_CARRY); |
7a3f1944 FB |
733 | } |
734 | ||
cf495bcf | 735 | void OPPROTO op_eval_bvs(void) |
7a3f1944 | 736 | { |
cf495bcf | 737 | T2 = (env->psr & PSR_OVF); |
7a3f1944 FB |
738 | } |
739 | ||
cf495bcf | 740 | void OPPROTO op_eval_bneg(void) |
7a3f1944 | 741 | { |
cf495bcf | 742 | T2 = (env->psr & PSR_NEG); |
7a3f1944 FB |
743 | } |
744 | ||
cf495bcf | 745 | void OPPROTO op_eval_bne(void) |
7a3f1944 | 746 | { |
cf495bcf | 747 | T2 = !(env->psr & PSR_ZERO); |
7a3f1944 FB |
748 | } |
749 | ||
cf495bcf | 750 | void OPPROTO op_eval_bg(void) |
7a3f1944 | 751 | { |
612b477d FB |
752 | unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
753 | ||
cf495bcf | 754 | T2 = !(Z | (N ^ V)); |
7a3f1944 FB |
755 | } |
756 | ||
cf495bcf | 757 | void OPPROTO op_eval_bge(void) |
7a3f1944 | 758 | { |
612b477d FB |
759 | unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
760 | ||
cf495bcf | 761 | T2 = !(N ^ V); |
7a3f1944 FB |
762 | } |
763 | ||
cf495bcf | 764 | void OPPROTO op_eval_bgu(void) |
7a3f1944 | 765 | { |
612b477d FB |
766 | unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); |
767 | ||
cf495bcf | 768 | T2 = !(C | Z); |
7a3f1944 FB |
769 | } |
770 | ||
cf495bcf | 771 | void OPPROTO op_eval_bcc(void) |
7a3f1944 | 772 | { |
cf495bcf | 773 | T2 = !(env->psr & PSR_CARRY); |
7a3f1944 FB |
774 | } |
775 | ||
cf495bcf FB |
776 | void OPPROTO op_eval_bpos(void) |
777 | { | |
778 | T2 = !(env->psr & PSR_NEG); | |
779 | } | |
780 | ||
781 | void OPPROTO op_eval_bvc(void) | |
782 | { | |
783 | T2 = !(env->psr & PSR_OVF); | |
784 | } | |
785 | ||
e8af50a3 FB |
786 | /* FCC1:FCC0: 0 =, 1 <, 2 >, 3 u */ |
787 | ||
788 | void OPPROTO op_eval_fbne(void) | |
789 | { | |
790 | // !0 | |
791 | T2 = (env->fsr & (FSR_FCC1 | FSR_FCC0)); /* L or G or U */ | |
792 | } | |
793 | ||
794 | void OPPROTO op_eval_fblg(void) | |
795 | { | |
796 | // 1 or 2 | |
797 | T2 = FFLAG_SET(FSR_FCC0) ^ FFLAG_SET(FSR_FCC1); | |
798 | } | |
799 | ||
800 | void OPPROTO op_eval_fbul(void) | |
801 | { | |
802 | // 1 or 3 | |
803 | T2 = FFLAG_SET(FSR_FCC0); | |
804 | } | |
805 | ||
806 | void OPPROTO op_eval_fbl(void) | |
807 | { | |
808 | // 1 | |
809 | T2 = FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); | |
810 | } | |
811 | ||
812 | void OPPROTO op_eval_fbug(void) | |
813 | { | |
814 | // 2 or 3 | |
815 | T2 = FFLAG_SET(FSR_FCC1); | |
816 | } | |
817 | ||
818 | void OPPROTO op_eval_fbg(void) | |
819 | { | |
820 | // 2 | |
821 | T2 = !FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); | |
822 | } | |
823 | ||
824 | void OPPROTO op_eval_fbu(void) | |
825 | { | |
826 | // 3 | |
827 | T2 = FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); | |
828 | } | |
829 | ||
830 | void OPPROTO op_eval_fbe(void) | |
831 | { | |
832 | // 0 | |
833 | T2 = !FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); | |
834 | } | |
835 | ||
836 | void OPPROTO op_eval_fbue(void) | |
837 | { | |
838 | // 0 or 3 | |
839 | T2 = !(FFLAG_SET(FSR_FCC1) ^ FFLAG_SET(FSR_FCC0)); | |
840 | } | |
841 | ||
842 | void OPPROTO op_eval_fbge(void) | |
843 | { | |
844 | // 0 or 2 | |
845 | T2 = !FFLAG_SET(FSR_FCC0); | |
846 | } | |
847 | ||
848 | void OPPROTO op_eval_fbuge(void) | |
849 | { | |
850 | // !1 | |
851 | T2 = !(FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1)); | |
852 | } | |
853 | ||
854 | void OPPROTO op_eval_fble(void) | |
855 | { | |
856 | // 0 or 1 | |
857 | T2 = !FFLAG_SET(FSR_FCC1); | |
858 | } | |
859 | ||
860 | void OPPROTO op_eval_fbule(void) | |
861 | { | |
862 | // !2 | |
863 | T2 = !(!FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); | |
864 | } | |
865 | ||
866 | void OPPROTO op_eval_fbo(void) | |
867 | { | |
868 | // !3 | |
869 | T2 = !(FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); | |
870 | } | |
871 | ||
cf495bcf FB |
872 | void OPPROTO op_movl_T2_0(void) |
873 | { | |
874 | T2 = 0; | |
875 | } | |
876 | ||
877 | void OPPROTO op_movl_T2_1(void) | |
878 | { | |
879 | T2 = 1; | |
880 | } | |
881 | ||
882 | void OPPROTO op_jmp_im(void) | |
883 | { | |
884 | env->pc = PARAM1; | |
885 | } | |
886 | ||
887 | void OPPROTO op_movl_npc_im(void) | |
888 | { | |
889 | env->npc = PARAM1; | |
890 | } | |
7a3f1944 | 891 | |
cf495bcf | 892 | void OPPROTO op_movl_npc_T0(void) |
7a3f1944 | 893 | { |
cf495bcf | 894 | env->npc = T0; |
7a3f1944 FB |
895 | } |
896 | ||
cf495bcf | 897 | void OPPROTO op_next_insn(void) |
7a3f1944 | 898 | { |
cf495bcf FB |
899 | env->pc = env->npc; |
900 | env->npc = env->npc + 4; | |
7a3f1944 FB |
901 | } |
902 | ||
72cbca10 FB |
903 | void OPPROTO op_branch(void) |
904 | { | |
905 | env->npc = PARAM3; /* XXX: optimize */ | |
906 | JUMP_TB(op_branch, PARAM1, 0, PARAM2); | |
907 | } | |
908 | ||
909 | void OPPROTO op_branch2(void) | |
7a3f1944 | 910 | { |
cf495bcf | 911 | if (T2) { |
72cbca10 FB |
912 | env->npc = PARAM2 + 4; |
913 | JUMP_TB(op_branch2, PARAM1, 0, PARAM2); | |
cf495bcf | 914 | } else { |
72cbca10 FB |
915 | env->npc = PARAM3 + 4; |
916 | JUMP_TB(op_branch2, PARAM1, 1, PARAM3); | |
917 | } | |
918 | FORCE_RET(); | |
919 | } | |
920 | ||
921 | void OPPROTO op_branch_a(void) | |
922 | { | |
923 | if (T2) { | |
924 | env->npc = PARAM2; /* XXX: optimize */ | |
925 | JUMP_TB(op_generic_branch_a, PARAM1, 0, PARAM3); | |
926 | } else { | |
927 | env->npc = PARAM3 + 8; /* XXX: optimize */ | |
928 | JUMP_TB(op_generic_branch_a, PARAM1, 1, PARAM3 + 4); | |
cf495bcf FB |
929 | } |
930 | FORCE_RET(); | |
7a3f1944 FB |
931 | } |
932 | ||
72cbca10 | 933 | void OPPROTO op_generic_branch(void) |
7a3f1944 | 934 | { |
cf495bcf | 935 | if (T2) { |
cf495bcf FB |
936 | env->npc = PARAM1; |
937 | } else { | |
72cbca10 | 938 | env->npc = PARAM2; |
cf495bcf FB |
939 | } |
940 | FORCE_RET(); | |
7a3f1944 | 941 | } |
72cbca10 | 942 | |
658138bc FB |
943 | void OPPROTO op_flush_T0(void) |
944 | { | |
945 | helper_flush(T0); | |
946 | } | |
e8af50a3 FB |
947 | |
948 | void OPPROTO op_fnegs(void) | |
949 | { | |
950 | FT0 = -FT1; | |
951 | } | |
952 | ||
953 | void OPPROTO op_fabss(void) | |
954 | { | |
955 | do_fabss(); | |
956 | } | |
957 | ||
958 | void OPPROTO op_fsqrts(void) | |
959 | { | |
960 | do_fsqrts(); | |
961 | } | |
962 | ||
963 | void OPPROTO op_fsqrtd(void) | |
964 | { | |
965 | do_fsqrtd(); | |
966 | } | |
967 | ||
968 | void OPPROTO op_fmuls(void) | |
969 | { | |
970 | FT0 *= FT1; | |
971 | } | |
972 | ||
973 | void OPPROTO op_fmuld(void) | |
974 | { | |
975 | DT0 *= DT1; | |
976 | } | |
977 | ||
978 | void OPPROTO op_fsmuld(void) | |
979 | { | |
980 | DT0 = FT0 * FT1; | |
981 | } | |
982 | ||
983 | void OPPROTO op_fadds(void) | |
984 | { | |
985 | FT0 += FT1; | |
986 | } | |
987 | ||
988 | void OPPROTO op_faddd(void) | |
989 | { | |
990 | DT0 += DT1; | |
991 | } | |
992 | ||
993 | void OPPROTO op_fsubs(void) | |
994 | { | |
995 | FT0 -= FT1; | |
996 | } | |
997 | ||
998 | void OPPROTO op_fsubd(void) | |
999 | { | |
1000 | DT0 -= DT1; | |
1001 | } | |
1002 | ||
1003 | void OPPROTO op_fdivs(void) | |
1004 | { | |
1005 | FT0 /= FT1; | |
1006 | } | |
1007 | ||
1008 | void OPPROTO op_fdivd(void) | |
1009 | { | |
1010 | DT0 /= DT1; | |
1011 | } | |
1012 | ||
1013 | void OPPROTO op_fcmps(void) | |
1014 | { | |
1015 | do_fcmps(); | |
1016 | } | |
1017 | ||
1018 | void OPPROTO op_fcmpd(void) | |
1019 | { | |
1020 | do_fcmpd(); | |
1021 | } | |
1022 | ||
1023 | void OPPROTO op_fitos(void) | |
1024 | { | |
1025 | FT0 = (float) *((int32_t *)&FT1); | |
1026 | } | |
1027 | ||
1028 | void OPPROTO op_fdtos(void) | |
1029 | { | |
1030 | FT0 = (float) DT1; | |
1031 | } | |
1032 | ||
1033 | void OPPROTO op_fitod(void) | |
1034 | { | |
1035 | DT0 = (double) *((int32_t *)&FT1); | |
1036 | } | |
1037 | ||
1038 | void OPPROTO op_fstod(void) | |
1039 | { | |
1040 | DT0 = (double) FT1; | |
1041 | } | |
1042 | ||
1043 | void OPPROTO op_fstoi(void) | |
1044 | { | |
1045 | *((int32_t *)&FT0) = (int32_t) FT1; | |
1046 | } | |
1047 | ||
1048 | void OPPROTO op_fdtoi(void) | |
1049 | { | |
1050 | *((int32_t *)&FT0) = (int32_t) DT1; | |
1051 | } | |
1052 | ||
1053 | void OPPROTO op_ld_asi() | |
1054 | { | |
1055 | helper_ld_asi(PARAM1, PARAM2, PARAM3); | |
1056 | } | |
1057 | ||
1058 | void OPPROTO op_st_asi() | |
1059 | { | |
1060 | helper_st_asi(PARAM1, PARAM2, PARAM3); | |
1061 | } | |
1062 |