]>
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 FB |
477 | /* Load and store */ |
478 | #define MEMSUFFIX _raw | |
479 | #include "op_mem.h" | |
480 | #if !defined(CONFIG_USER_ONLY) | |
481 | #define MEMSUFFIX _user | |
482 | #include "op_mem.h" | |
483 | ||
484 | #define MEMSUFFIX _kernel | |
485 | #include "op_mem.h" | |
486 | #endif | |
e8af50a3 FB |
487 | |
488 | void OPPROTO op_ldfsr(void) | |
489 | { | |
490 | env->fsr = *((uint32_t *) &FT0); | |
8d5f07fa | 491 | helper_ldfsr(); |
e8af50a3 FB |
492 | } |
493 | ||
494 | void OPPROTO op_stfsr(void) | |
495 | { | |
496 | *((uint32_t *) &FT0) = env->fsr; | |
e8af50a3 FB |
497 | } |
498 | ||
cf495bcf | 499 | void OPPROTO op_wry(void) |
7a3f1944 | 500 | { |
cf495bcf | 501 | env->y = T0; |
7a3f1944 FB |
502 | } |
503 | ||
cf495bcf | 504 | void OPPROTO op_rdy(void) |
7a3f1944 | 505 | { |
cf495bcf | 506 | T0 = env->y; |
7a3f1944 FB |
507 | } |
508 | ||
e8af50a3 | 509 | void OPPROTO op_rdwim(void) |
cf495bcf | 510 | { |
e8af50a3 FB |
511 | T0 = env->wim; |
512 | } | |
513 | ||
514 | void OPPROTO op_wrwim(void) | |
515 | { | |
516 | env->wim = T0; | |
517 | FORCE_RET(); | |
518 | } | |
519 | ||
520 | void OPPROTO op_rdpsr(void) | |
521 | { | |
522 | T0 = GET_PSR(env); | |
e8af50a3 FB |
523 | } |
524 | ||
525 | void OPPROTO op_wrpsr(void) | |
526 | { | |
8d5f07fa | 527 | int cwp; |
e8af50a3 FB |
528 | env->psr = T0 & ~PSR_ICC; |
529 | env->psrs = (T0 & PSR_S)? 1 : 0; | |
530 | env->psrps = (T0 & PSR_PS)? 1 : 0; | |
531 | env->psret = (T0 & PSR_ET)? 1 : 0; | |
8d5f07fa FB |
532 | cwp = (T0 & PSR_CWP) & (NWINDOWS - 1); |
533 | set_cwp(cwp); | |
e8af50a3 FB |
534 | FORCE_RET(); |
535 | } | |
536 | ||
537 | void OPPROTO op_rdtbr(void) | |
538 | { | |
539 | T0 = env->tbr; | |
540 | } | |
cf495bcf | 541 | |
e8af50a3 | 542 | void OPPROTO op_wrtbr(void) |
7a3f1944 | 543 | { |
e8af50a3 FB |
544 | env->tbr = T0; |
545 | FORCE_RET(); | |
7a3f1944 FB |
546 | } |
547 | ||
e8af50a3 | 548 | void OPPROTO op_rett(void) |
cf495bcf | 549 | { |
e8af50a3 FB |
550 | helper_rett(); |
551 | FORCE_RET(); | |
cf495bcf | 552 | } |
7a3f1944 | 553 | |
e8af50a3 FB |
554 | void raise_exception(int tt) |
555 | { | |
556 | env->exception_index = tt; | |
557 | cpu_loop_exit(); | |
558 | } | |
559 | ||
cf495bcf FB |
560 | /* XXX: use another pointer for %iN registers to avoid slow wrapping |
561 | handling ? */ | |
562 | void OPPROTO op_save(void) | |
7a3f1944 | 563 | { |
cf495bcf FB |
564 | int cwp; |
565 | cwp = (env->cwp - 1) & (NWINDOWS - 1); | |
566 | if (env->wim & (1 << cwp)) { | |
567 | raise_exception(TT_WIN_OVF); | |
568 | } | |
569 | set_cwp(cwp); | |
570 | FORCE_RET(); | |
7a3f1944 FB |
571 | } |
572 | ||
cf495bcf | 573 | void OPPROTO op_restore(void) |
7a3f1944 | 574 | { |
cf495bcf FB |
575 | int cwp; |
576 | cwp = (env->cwp + 1) & (NWINDOWS - 1); | |
577 | if (env->wim & (1 << cwp)) { | |
578 | raise_exception(TT_WIN_UNF); | |
579 | } | |
580 | set_cwp(cwp); | |
581 | FORCE_RET(); | |
7a3f1944 FB |
582 | } |
583 | ||
cf495bcf | 584 | void OPPROTO op_exception(void) |
7a3f1944 | 585 | { |
cf495bcf FB |
586 | env->exception_index = PARAM1; |
587 | cpu_loop_exit(); | |
7a3f1944 FB |
588 | } |
589 | ||
cf495bcf | 590 | void OPPROTO op_trap_T0(void) |
7a3f1944 | 591 | { |
cf495bcf FB |
592 | env->exception_index = TT_TRAP + (T0 & 0x7f); |
593 | cpu_loop_exit(); | |
7a3f1944 FB |
594 | } |
595 | ||
cf495bcf | 596 | void OPPROTO op_trapcc_T0(void) |
7a3f1944 | 597 | { |
cf495bcf FB |
598 | if (T2) { |
599 | env->exception_index = TT_TRAP + (T0 & 0x7f); | |
600 | cpu_loop_exit(); | |
601 | } | |
602 | FORCE_RET(); | |
7a3f1944 FB |
603 | } |
604 | ||
e8af50a3 FB |
605 | void OPPROTO op_debug(void) |
606 | { | |
607 | env->exception_index = EXCP_DEBUG; | |
608 | cpu_loop_exit(); | |
609 | } | |
610 | ||
cf495bcf | 611 | void OPPROTO op_exit_tb(void) |
7a3f1944 | 612 | { |
cf495bcf | 613 | EXIT_TB(); |
7a3f1944 FB |
614 | } |
615 | ||
cf495bcf | 616 | void OPPROTO op_eval_be(void) |
7a3f1944 | 617 | { |
cf495bcf | 618 | T2 = (env->psr & PSR_ZERO); |
7a3f1944 FB |
619 | } |
620 | ||
cf495bcf | 621 | void OPPROTO op_eval_ble(void) |
7a3f1944 | 622 | { |
612b477d FB |
623 | unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
624 | ||
cf495bcf | 625 | T2 = Z | (N ^ V); |
7a3f1944 FB |
626 | } |
627 | ||
cf495bcf | 628 | void OPPROTO op_eval_bl(void) |
7a3f1944 | 629 | { |
612b477d FB |
630 | unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
631 | ||
cf495bcf | 632 | T2 = N ^ V; |
7a3f1944 FB |
633 | } |
634 | ||
cf495bcf | 635 | void OPPROTO op_eval_bleu(void) |
7a3f1944 | 636 | { |
612b477d FB |
637 | unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); |
638 | ||
cf495bcf | 639 | T2 = C | Z; |
7a3f1944 FB |
640 | } |
641 | ||
cf495bcf | 642 | void OPPROTO op_eval_bcs(void) |
7a3f1944 | 643 | { |
cf495bcf | 644 | T2 = (env->psr & PSR_CARRY); |
7a3f1944 FB |
645 | } |
646 | ||
cf495bcf | 647 | void OPPROTO op_eval_bvs(void) |
7a3f1944 | 648 | { |
cf495bcf | 649 | T2 = (env->psr & PSR_OVF); |
7a3f1944 FB |
650 | } |
651 | ||
cf495bcf | 652 | void OPPROTO op_eval_bneg(void) |
7a3f1944 | 653 | { |
cf495bcf | 654 | T2 = (env->psr & PSR_NEG); |
7a3f1944 FB |
655 | } |
656 | ||
cf495bcf | 657 | void OPPROTO op_eval_bne(void) |
7a3f1944 | 658 | { |
cf495bcf | 659 | T2 = !(env->psr & PSR_ZERO); |
7a3f1944 FB |
660 | } |
661 | ||
cf495bcf | 662 | void OPPROTO op_eval_bg(void) |
7a3f1944 | 663 | { |
612b477d FB |
664 | unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
665 | ||
cf495bcf | 666 | T2 = !(Z | (N ^ V)); |
7a3f1944 FB |
667 | } |
668 | ||
cf495bcf | 669 | void OPPROTO op_eval_bge(void) |
7a3f1944 | 670 | { |
612b477d FB |
671 | unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); |
672 | ||
cf495bcf | 673 | T2 = !(N ^ V); |
7a3f1944 FB |
674 | } |
675 | ||
cf495bcf | 676 | void OPPROTO op_eval_bgu(void) |
7a3f1944 | 677 | { |
612b477d FB |
678 | unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); |
679 | ||
cf495bcf | 680 | T2 = !(C | Z); |
7a3f1944 FB |
681 | } |
682 | ||
cf495bcf | 683 | void OPPROTO op_eval_bcc(void) |
7a3f1944 | 684 | { |
cf495bcf | 685 | T2 = !(env->psr & PSR_CARRY); |
7a3f1944 FB |
686 | } |
687 | ||
cf495bcf FB |
688 | void OPPROTO op_eval_bpos(void) |
689 | { | |
690 | T2 = !(env->psr & PSR_NEG); | |
691 | } | |
692 | ||
693 | void OPPROTO op_eval_bvc(void) | |
694 | { | |
695 | T2 = !(env->psr & PSR_OVF); | |
696 | } | |
697 | ||
e8af50a3 FB |
698 | /* FCC1:FCC0: 0 =, 1 <, 2 >, 3 u */ |
699 | ||
700 | void OPPROTO op_eval_fbne(void) | |
701 | { | |
702 | // !0 | |
703 | T2 = (env->fsr & (FSR_FCC1 | FSR_FCC0)); /* L or G or U */ | |
704 | } | |
705 | ||
706 | void OPPROTO op_eval_fblg(void) | |
707 | { | |
708 | // 1 or 2 | |
709 | T2 = FFLAG_SET(FSR_FCC0) ^ FFLAG_SET(FSR_FCC1); | |
710 | } | |
711 | ||
712 | void OPPROTO op_eval_fbul(void) | |
713 | { | |
714 | // 1 or 3 | |
715 | T2 = FFLAG_SET(FSR_FCC0); | |
716 | } | |
717 | ||
718 | void OPPROTO op_eval_fbl(void) | |
719 | { | |
720 | // 1 | |
721 | T2 = FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); | |
722 | } | |
723 | ||
724 | void OPPROTO op_eval_fbug(void) | |
725 | { | |
726 | // 2 or 3 | |
727 | T2 = FFLAG_SET(FSR_FCC1); | |
728 | } | |
729 | ||
730 | void OPPROTO op_eval_fbg(void) | |
731 | { | |
732 | // 2 | |
733 | T2 = !FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); | |
734 | } | |
735 | ||
736 | void OPPROTO op_eval_fbu(void) | |
737 | { | |
738 | // 3 | |
739 | T2 = FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); | |
740 | } | |
741 | ||
742 | void OPPROTO op_eval_fbe(void) | |
743 | { | |
744 | // 0 | |
745 | T2 = !FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); | |
746 | } | |
747 | ||
748 | void OPPROTO op_eval_fbue(void) | |
749 | { | |
750 | // 0 or 3 | |
751 | T2 = !(FFLAG_SET(FSR_FCC1) ^ FFLAG_SET(FSR_FCC0)); | |
752 | } | |
753 | ||
754 | void OPPROTO op_eval_fbge(void) | |
755 | { | |
756 | // 0 or 2 | |
757 | T2 = !FFLAG_SET(FSR_FCC0); | |
758 | } | |
759 | ||
760 | void OPPROTO op_eval_fbuge(void) | |
761 | { | |
762 | // !1 | |
763 | T2 = !(FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1)); | |
764 | } | |
765 | ||
766 | void OPPROTO op_eval_fble(void) | |
767 | { | |
768 | // 0 or 1 | |
769 | T2 = !FFLAG_SET(FSR_FCC1); | |
770 | } | |
771 | ||
772 | void OPPROTO op_eval_fbule(void) | |
773 | { | |
774 | // !2 | |
775 | T2 = !(!FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); | |
776 | } | |
777 | ||
778 | void OPPROTO op_eval_fbo(void) | |
779 | { | |
780 | // !3 | |
781 | T2 = !(FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); | |
782 | } | |
783 | ||
cf495bcf FB |
784 | void OPPROTO op_movl_T2_0(void) |
785 | { | |
786 | T2 = 0; | |
787 | } | |
788 | ||
789 | void OPPROTO op_movl_T2_1(void) | |
790 | { | |
791 | T2 = 1; | |
792 | } | |
793 | ||
794 | void OPPROTO op_jmp_im(void) | |
795 | { | |
796 | env->pc = PARAM1; | |
797 | } | |
798 | ||
799 | void OPPROTO op_movl_npc_im(void) | |
800 | { | |
801 | env->npc = PARAM1; | |
802 | } | |
7a3f1944 | 803 | |
cf495bcf | 804 | void OPPROTO op_movl_npc_T0(void) |
7a3f1944 | 805 | { |
cf495bcf | 806 | env->npc = T0; |
7a3f1944 FB |
807 | } |
808 | ||
cf495bcf | 809 | void OPPROTO op_next_insn(void) |
7a3f1944 | 810 | { |
cf495bcf FB |
811 | env->pc = env->npc; |
812 | env->npc = env->npc + 4; | |
7a3f1944 FB |
813 | } |
814 | ||
72cbca10 FB |
815 | void OPPROTO op_branch(void) |
816 | { | |
817 | env->npc = PARAM3; /* XXX: optimize */ | |
818 | JUMP_TB(op_branch, PARAM1, 0, PARAM2); | |
819 | } | |
820 | ||
821 | void OPPROTO op_branch2(void) | |
7a3f1944 | 822 | { |
cf495bcf | 823 | if (T2) { |
72cbca10 FB |
824 | env->npc = PARAM2 + 4; |
825 | JUMP_TB(op_branch2, PARAM1, 0, PARAM2); | |
cf495bcf | 826 | } else { |
72cbca10 FB |
827 | env->npc = PARAM3 + 4; |
828 | JUMP_TB(op_branch2, PARAM1, 1, PARAM3); | |
829 | } | |
830 | FORCE_RET(); | |
831 | } | |
832 | ||
833 | void OPPROTO op_branch_a(void) | |
834 | { | |
835 | if (T2) { | |
836 | env->npc = PARAM2; /* XXX: optimize */ | |
837 | JUMP_TB(op_generic_branch_a, PARAM1, 0, PARAM3); | |
838 | } else { | |
839 | env->npc = PARAM3 + 8; /* XXX: optimize */ | |
840 | JUMP_TB(op_generic_branch_a, PARAM1, 1, PARAM3 + 4); | |
cf495bcf FB |
841 | } |
842 | FORCE_RET(); | |
7a3f1944 FB |
843 | } |
844 | ||
72cbca10 | 845 | void OPPROTO op_generic_branch(void) |
7a3f1944 | 846 | { |
cf495bcf | 847 | if (T2) { |
cf495bcf FB |
848 | env->npc = PARAM1; |
849 | } else { | |
72cbca10 | 850 | env->npc = PARAM2; |
cf495bcf FB |
851 | } |
852 | FORCE_RET(); | |
7a3f1944 | 853 | } |
72cbca10 | 854 | |
658138bc FB |
855 | void OPPROTO op_flush_T0(void) |
856 | { | |
857 | helper_flush(T0); | |
858 | } | |
e8af50a3 FB |
859 | |
860 | void OPPROTO op_fnegs(void) | |
861 | { | |
862 | FT0 = -FT1; | |
863 | } | |
864 | ||
865 | void OPPROTO op_fabss(void) | |
866 | { | |
867 | do_fabss(); | |
868 | } | |
869 | ||
870 | void OPPROTO op_fsqrts(void) | |
871 | { | |
872 | do_fsqrts(); | |
873 | } | |
874 | ||
875 | void OPPROTO op_fsqrtd(void) | |
876 | { | |
877 | do_fsqrtd(); | |
878 | } | |
879 | ||
880 | void OPPROTO op_fmuls(void) | |
881 | { | |
882 | FT0 *= FT1; | |
883 | } | |
884 | ||
885 | void OPPROTO op_fmuld(void) | |
886 | { | |
887 | DT0 *= DT1; | |
888 | } | |
889 | ||
890 | void OPPROTO op_fsmuld(void) | |
891 | { | |
892 | DT0 = FT0 * FT1; | |
893 | } | |
894 | ||
895 | void OPPROTO op_fadds(void) | |
896 | { | |
897 | FT0 += FT1; | |
898 | } | |
899 | ||
900 | void OPPROTO op_faddd(void) | |
901 | { | |
902 | DT0 += DT1; | |
903 | } | |
904 | ||
905 | void OPPROTO op_fsubs(void) | |
906 | { | |
907 | FT0 -= FT1; | |
908 | } | |
909 | ||
910 | void OPPROTO op_fsubd(void) | |
911 | { | |
912 | DT0 -= DT1; | |
913 | } | |
914 | ||
915 | void OPPROTO op_fdivs(void) | |
916 | { | |
917 | FT0 /= FT1; | |
918 | } | |
919 | ||
920 | void OPPROTO op_fdivd(void) | |
921 | { | |
922 | DT0 /= DT1; | |
923 | } | |
924 | ||
925 | void OPPROTO op_fcmps(void) | |
926 | { | |
927 | do_fcmps(); | |
928 | } | |
929 | ||
930 | void OPPROTO op_fcmpd(void) | |
931 | { | |
932 | do_fcmpd(); | |
933 | } | |
934 | ||
a0c4cb4a | 935 | #ifdef USE_INT_TO_FLOAT_HELPERS |
e8af50a3 FB |
936 | void OPPROTO op_fitos(void) |
937 | { | |
a0c4cb4a | 938 | do_fitos(); |
e8af50a3 FB |
939 | } |
940 | ||
a0c4cb4a | 941 | void OPPROTO op_fitod(void) |
e8af50a3 | 942 | { |
a0c4cb4a FB |
943 | do_fitod(); |
944 | } | |
945 | #else | |
946 | void OPPROTO op_fitos(void) | |
947 | { | |
948 | FT0 = (float) *((int32_t *)&FT1); | |
e8af50a3 FB |
949 | } |
950 | ||
951 | void OPPROTO op_fitod(void) | |
952 | { | |
953 | DT0 = (double) *((int32_t *)&FT1); | |
954 | } | |
a0c4cb4a FB |
955 | #endif |
956 | ||
957 | void OPPROTO op_fdtos(void) | |
958 | { | |
959 | FT0 = (float) DT1; | |
960 | } | |
e8af50a3 FB |
961 | |
962 | void OPPROTO op_fstod(void) | |
963 | { | |
964 | DT0 = (double) FT1; | |
965 | } | |
966 | ||
967 | void OPPROTO op_fstoi(void) | |
968 | { | |
969 | *((int32_t *)&FT0) = (int32_t) FT1; | |
970 | } | |
971 | ||
972 | void OPPROTO op_fdtoi(void) | |
973 | { | |
974 | *((int32_t *)&FT0) = (int32_t) DT1; | |
975 | } | |
976 | ||
977 | void OPPROTO op_ld_asi() | |
978 | { | |
979 | helper_ld_asi(PARAM1, PARAM2, PARAM3); | |
980 | } | |
981 | ||
982 | void OPPROTO op_st_asi() | |
983 | { | |
984 | helper_st_asi(PARAM1, PARAM2, PARAM3); | |
985 | } | |
986 |