]> git.proxmox.com Git - mirror_qemu.git/blob - target-sparc/op.c
use the TCG code generator
[mirror_qemu.git] / target-sparc / op.c
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
23 /*XXX*/
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 (REGWPTR[16])
50 #include "op_template.h"
51 #define REGNAME i1
52 #define REG (REGWPTR[17])
53 #include "op_template.h"
54 #define REGNAME i2
55 #define REG (REGWPTR[18])
56 #include "op_template.h"
57 #define REGNAME i3
58 #define REG (REGWPTR[19])
59 #include "op_template.h"
60 #define REGNAME i4
61 #define REG (REGWPTR[20])
62 #include "op_template.h"
63 #define REGNAME i5
64 #define REG (REGWPTR[21])
65 #include "op_template.h"
66 #define REGNAME i6
67 #define REG (REGWPTR[22])
68 #include "op_template.h"
69 #define REGNAME i7
70 #define REG (REGWPTR[23])
71 #include "op_template.h"
72 #define REGNAME l0
73 #define REG (REGWPTR[8])
74 #include "op_template.h"
75 #define REGNAME l1
76 #define REG (REGWPTR[9])
77 #include "op_template.h"
78 #define REGNAME l2
79 #define REG (REGWPTR[10])
80 #include "op_template.h"
81 #define REGNAME l3
82 #define REG (REGWPTR[11])
83 #include "op_template.h"
84 #define REGNAME l4
85 #define REG (REGWPTR[12])
86 #include "op_template.h"
87 #define REGNAME l5
88 #define REG (REGWPTR[13])
89 #include "op_template.h"
90 #define REGNAME l6
91 #define REG (REGWPTR[14])
92 #include "op_template.h"
93 #define REGNAME l7
94 #define REG (REGWPTR[15])
95 #include "op_template.h"
96 #define REGNAME o0
97 #define REG (REGWPTR[0])
98 #include "op_template.h"
99 #define REGNAME o1
100 #define REG (REGWPTR[1])
101 #include "op_template.h"
102 #define REGNAME o2
103 #define REG (REGWPTR[2])
104 #include "op_template.h"
105 #define REGNAME o3
106 #define REG (REGWPTR[3])
107 #include "op_template.h"
108 #define REGNAME o4
109 #define REG (REGWPTR[4])
110 #include "op_template.h"
111 #define REGNAME o5
112 #define REG (REGWPTR[5])
113 #include "op_template.h"
114 #define REGNAME o6
115 #define REG (REGWPTR[6])
116 #include "op_template.h"
117 #define REGNAME o7
118 #define REG (REGWPTR[7])
119 #include "op_template.h"
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
218 #ifdef TARGET_SPARC64
219 #define REGNAME f32
220 #define REG (env->fpr[32])
221 #include "fop_template.h"
222 #define REGNAME f34
223 #define REG (env->fpr[34])
224 #include "fop_template.h"
225 #define REGNAME f36
226 #define REG (env->fpr[36])
227 #include "fop_template.h"
228 #define REGNAME f38
229 #define REG (env->fpr[38])
230 #include "fop_template.h"
231 #define REGNAME f40
232 #define REG (env->fpr[40])
233 #include "fop_template.h"
234 #define REGNAME f42
235 #define REG (env->fpr[42])
236 #include "fop_template.h"
237 #define REGNAME f44
238 #define REG (env->fpr[44])
239 #include "fop_template.h"
240 #define REGNAME f46
241 #define REG (env->fpr[46])
242 #include "fop_template.h"
243 #define REGNAME f48
244 #define REG (env->fpr[47])
245 #include "fop_template.h"
246 #define REGNAME f50
247 #define REG (env->fpr[50])
248 #include "fop_template.h"
249 #define REGNAME f52
250 #define REG (env->fpr[52])
251 #include "fop_template.h"
252 #define REGNAME f54
253 #define REG (env->fpr[54])
254 #include "fop_template.h"
255 #define REGNAME f56
256 #define REG (env->fpr[56])
257 #include "fop_template.h"
258 #define REGNAME f58
259 #define REG (env->fpr[58])
260 #include "fop_template.h"
261 #define REGNAME f60
262 #define REG (env->fpr[60])
263 #include "fop_template.h"
264 #define REGNAME f62
265 #define REG (env->fpr[62])
266 #include "fop_template.h"
267 #endif
268
269 #ifdef TARGET_SPARC64
270 #ifdef WORDS_BIGENDIAN
271 typedef union UREG64 {
272 struct { uint16_t v3, v2, v1, v0; } w;
273 struct { uint32_t v1, v0; } l;
274 uint64_t q;
275 } UREG64;
276 #else
277 typedef union UREG64 {
278 struct { uint16_t v0, v1, v2, v3; } w;
279 struct { uint32_t v0, v1; } l;
280 uint64_t q;
281 } UREG64;
282 #endif
283
284 #define PARAMQ1 \
285 ({\
286 UREG64 __p;\
287 __p.l.v1 = PARAM1;\
288 __p.l.v0 = PARAM2;\
289 __p.q;\
290 })
291
292 void OPPROTO op_movq_T0_im64(void)
293 {
294 T0 = PARAMQ1;
295 }
296
297 void OPPROTO op_movq_T1_im64(void)
298 {
299 T1 = PARAMQ1;
300 }
301
302 #define XFLAG_SET(x) ((env->xcc&x)?1:0)
303
304 #else
305 #define EIP (env->pc)
306 #endif
307
308 #define FLAG_SET(x) ((env->psr&x)?1:0)
309
310 void OPPROTO op_movl_T0_0(void)
311 {
312 T0 = 0;
313 }
314
315 void OPPROTO op_movl_T0_im(void)
316 {
317 T0 = (uint32_t)PARAM1;
318 }
319
320 void OPPROTO op_movl_T1_im(void)
321 {
322 T1 = (uint32_t)PARAM1;
323 }
324
325 void OPPROTO op_movl_T2_im(void)
326 {
327 T2 = (uint32_t)PARAM1;
328 }
329
330 void OPPROTO op_movl_T0_sim(void)
331 {
332 T0 = (int32_t)PARAM1;
333 }
334
335 void OPPROTO op_movl_T1_sim(void)
336 {
337 T1 = (int32_t)PARAM1;
338 }
339
340 void OPPROTO op_movl_T2_sim(void)
341 {
342 T2 = (int32_t)PARAM1;
343 }
344
345 void OPPROTO op_movl_T0_env(void)
346 {
347 T0 = *(uint32_t *)((char *)env + PARAM1);
348 }
349
350 void OPPROTO op_movl_env_T0(void)
351 {
352 *(uint32_t *)((char *)env + PARAM1) = T0;
353 }
354
355 void OPPROTO op_movtl_T0_env(void)
356 {
357 T0 = *(target_ulong *)((char *)env + PARAM1);
358 }
359
360 void OPPROTO op_movtl_env_T0(void)
361 {
362 *(target_ulong *)((char *)env + PARAM1) = T0;
363 }
364
365 void OPPROTO op_add_T1_T0(void)
366 {
367 T0 += T1;
368 }
369
370 void OPPROTO op_add_T1_T0_cc(void)
371 {
372 target_ulong src1;
373
374 src1 = T0;
375 T0 += T1;
376 env->psr = 0;
377 #ifdef TARGET_SPARC64
378 if (!(T0 & 0xffffffff))
379 env->psr |= PSR_ZERO;
380 if ((int32_t) T0 < 0)
381 env->psr |= PSR_NEG;
382 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
383 env->psr |= PSR_CARRY;
384 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
385 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
386 env->psr |= PSR_OVF;
387
388 env->xcc = 0;
389 if (!T0)
390 env->xcc |= PSR_ZERO;
391 if ((int64_t) T0 < 0)
392 env->xcc |= PSR_NEG;
393 if (T0 < src1)
394 env->xcc |= PSR_CARRY;
395 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
396 env->xcc |= PSR_OVF;
397 #else
398 if (!T0)
399 env->psr |= PSR_ZERO;
400 if ((int32_t) T0 < 0)
401 env->psr |= PSR_NEG;
402 if (T0 < src1)
403 env->psr |= PSR_CARRY;
404 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
405 env->psr |= PSR_OVF;
406 #endif
407 FORCE_RET();
408 }
409
410 void OPPROTO op_addx_T1_T0(void)
411 {
412 T0 += T1 + FLAG_SET(PSR_CARRY);
413 }
414
415 void OPPROTO op_addx_T1_T0_cc(void)
416 {
417 target_ulong src1;
418 src1 = T0;
419 if (FLAG_SET(PSR_CARRY))
420 {
421 T0 += T1 + 1;
422 env->psr = 0;
423 #ifdef TARGET_SPARC64
424 if ((T0 & 0xffffffff) <= (src1 & 0xffffffff))
425 env->psr |= PSR_CARRY;
426 env->xcc = 0;
427 if (T0 <= src1)
428 env->xcc |= PSR_CARRY;
429 #else
430 if (T0 <= src1)
431 env->psr |= PSR_CARRY;
432 #endif
433 }
434 else
435 {
436 T0 += T1;
437 env->psr = 0;
438 #ifdef TARGET_SPARC64
439 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
440 env->psr |= PSR_CARRY;
441 env->xcc = 0;
442 if (T0 < src1)
443 env->xcc |= PSR_CARRY;
444 #else
445 if (T0 < src1)
446 env->psr |= PSR_CARRY;
447 #endif
448 }
449 #ifdef TARGET_SPARC64
450 if (!(T0 & 0xffffffff))
451 env->psr |= PSR_ZERO;
452 if ((int32_t) T0 < 0)
453 env->psr |= PSR_NEG;
454 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
455 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
456 env->psr |= PSR_OVF;
457
458 if (!T0)
459 env->xcc |= PSR_ZERO;
460 if ((int64_t) T0 < 0)
461 env->xcc |= PSR_NEG;
462 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
463 env->xcc |= PSR_OVF;
464 #else
465 if (!T0)
466 env->psr |= PSR_ZERO;
467 if ((int32_t) T0 < 0)
468 env->psr |= PSR_NEG;
469 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
470 env->psr |= PSR_OVF;
471 #endif
472 FORCE_RET();
473 }
474
475 void OPPROTO op_tadd_T1_T0_cc(void)
476 {
477 target_ulong src1;
478
479 src1 = T0;
480 T0 += T1;
481 env->psr = 0;
482 #ifdef TARGET_SPARC64
483 if (!(T0 & 0xffffffff))
484 env->psr |= PSR_ZERO;
485 if ((int32_t) T0 < 0)
486 env->psr |= PSR_NEG;
487 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
488 env->psr |= PSR_CARRY;
489 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
490 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
491 env->psr |= PSR_OVF;
492 if ((src1 & 0x03) || (T1 & 0x03))
493 env->psr |= PSR_OVF;
494
495 env->xcc = 0;
496 if (!T0)
497 env->xcc |= PSR_ZERO;
498 if ((int64_t) T0 < 0)
499 env->xcc |= PSR_NEG;
500 if (T0 < src1)
501 env->xcc |= PSR_CARRY;
502 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
503 env->xcc |= PSR_OVF;
504 #else
505 if (!T0)
506 env->psr |= PSR_ZERO;
507 if ((int32_t) T0 < 0)
508 env->psr |= PSR_NEG;
509 if (T0 < src1)
510 env->psr |= PSR_CARRY;
511 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
512 env->psr |= PSR_OVF;
513 if ((src1 & 0x03) || (T1 & 0x03))
514 env->psr |= PSR_OVF;
515 #endif
516 FORCE_RET();
517 }
518
519 void OPPROTO op_tadd_T1_T0_ccTV(void)
520 {
521 target_ulong src1;
522
523 if ((T0 & 0x03) || (T1 & 0x03)) {
524 raise_exception(TT_TOVF);
525 FORCE_RET();
526 return;
527 }
528
529 src1 = T0;
530 T0 += T1;
531
532 #ifdef TARGET_SPARC64
533 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
534 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
535 raise_exception(TT_TOVF);
536 #else
537 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
538 raise_exception(TT_TOVF);
539 #endif
540
541 env->psr = 0;
542 #ifdef TARGET_SPARC64
543 if (!(T0 & 0xffffffff))
544 env->psr |= PSR_ZERO;
545 if ((int32_t) T0 < 0)
546 env->psr |= PSR_NEG;
547 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
548 env->psr |= PSR_CARRY;
549
550 env->xcc = 0;
551 if (!T0)
552 env->xcc |= PSR_ZERO;
553 if ((int64_t) T0 < 0)
554 env->xcc |= PSR_NEG;
555 if (T0 < src1)
556 env->xcc |= PSR_CARRY;
557 #else
558 if (!T0)
559 env->psr |= PSR_ZERO;
560 if ((int32_t) T0 < 0)
561 env->psr |= PSR_NEG;
562 if (T0 < src1)
563 env->psr |= PSR_CARRY;
564 #endif
565 FORCE_RET();
566 }
567
568 void OPPROTO op_sub_T1_T0(void)
569 {
570 T0 -= T1;
571 }
572
573 void OPPROTO op_sub_T1_T0_cc(void)
574 {
575 target_ulong src1;
576
577 src1 = T0;
578 T0 -= T1;
579 env->psr = 0;
580 #ifdef TARGET_SPARC64
581 if (!(T0 & 0xffffffff))
582 env->psr |= PSR_ZERO;
583 if ((int32_t) T0 < 0)
584 env->psr |= PSR_NEG;
585 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
586 env->psr |= PSR_CARRY;
587 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
588 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
589 env->psr |= PSR_OVF;
590
591 env->xcc = 0;
592 if (!T0)
593 env->xcc |= PSR_ZERO;
594 if ((int64_t) T0 < 0)
595 env->xcc |= PSR_NEG;
596 if (src1 < T1)
597 env->xcc |= PSR_CARRY;
598 if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
599 env->xcc |= PSR_OVF;
600 #else
601 if (!T0)
602 env->psr |= PSR_ZERO;
603 if ((int32_t) T0 < 0)
604 env->psr |= PSR_NEG;
605 if (src1 < T1)
606 env->psr |= PSR_CARRY;
607 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
608 env->psr |= PSR_OVF;
609 #endif
610 FORCE_RET();
611 }
612
613 void OPPROTO op_subx_T1_T0(void)
614 {
615 T0 -= T1 + FLAG_SET(PSR_CARRY);
616 }
617
618 void OPPROTO op_subx_T1_T0_cc(void)
619 {
620 target_ulong src1;
621 src1 = T0;
622 if (FLAG_SET(PSR_CARRY))
623 {
624 T0 -= T1 + 1;
625 env->psr = 0;
626 #ifdef TARGET_SPARC64
627 if ((src1 & 0xffffffff) <= (T1 & 0xffffffff))
628 env->psr |= PSR_CARRY;
629 env->xcc = 0;
630 if (src1 <= T1)
631 env->xcc |= PSR_CARRY;
632 #else
633 if (src1 <= T1)
634 env->psr |= PSR_CARRY;
635 #endif
636 }
637 else
638 {
639 T0 -= T1;
640 env->psr = 0;
641 #ifdef TARGET_SPARC64
642 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
643 env->psr |= PSR_CARRY;
644 env->xcc = 0;
645 if (src1 < T1)
646 env->xcc |= PSR_CARRY;
647 #else
648 if (src1 < T1)
649 env->psr |= PSR_CARRY;
650 #endif
651 }
652 #ifdef TARGET_SPARC64
653 if (!(T0 & 0xffffffff))
654 env->psr |= PSR_ZERO;
655 if ((int32_t) T0 < 0)
656 env->psr |= PSR_NEG;
657 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
658 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
659 env->psr |= PSR_OVF;
660
661 if (!T0)
662 env->xcc |= PSR_ZERO;
663 if ((int64_t) T0 < 0)
664 env->xcc |= PSR_NEG;
665 if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
666 env->xcc |= PSR_OVF;
667 #else
668 if (!T0)
669 env->psr |= PSR_ZERO;
670 if ((int32_t) T0 < 0)
671 env->psr |= PSR_NEG;
672 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
673 env->psr |= PSR_OVF;
674 #endif
675 FORCE_RET();
676 }
677
678 void OPPROTO op_tsub_T1_T0_cc(void)
679 {
680 target_ulong src1;
681
682 src1 = T0;
683 T0 -= T1;
684 env->psr = 0;
685 #ifdef TARGET_SPARC64
686 if (!(T0 & 0xffffffff))
687 env->psr |= PSR_ZERO;
688 if ((int32_t) T0 < 0)
689 env->psr |= PSR_NEG;
690 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
691 env->psr |= PSR_CARRY;
692 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
693 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
694 env->psr |= PSR_OVF;
695 if ((src1 & 0x03) || (T1 & 0x03))
696 env->psr |= PSR_OVF;
697
698 env->xcc = 0;
699 if (!T0)
700 env->xcc |= PSR_ZERO;
701 if ((int64_t) T0 < 0)
702 env->xcc |= PSR_NEG;
703 if (src1 < T1)
704 env->xcc |= PSR_CARRY;
705 if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
706 env->xcc |= PSR_OVF;
707 #else
708 if (!T0)
709 env->psr |= PSR_ZERO;
710 if ((int32_t) T0 < 0)
711 env->psr |= PSR_NEG;
712 if (src1 < T1)
713 env->psr |= PSR_CARRY;
714 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
715 env->psr |= PSR_OVF;
716 if ((src1 & 0x03) || (T1 & 0x03))
717 env->psr |= PSR_OVF;
718 #endif
719 FORCE_RET();
720 }
721
722 void OPPROTO op_tsub_T1_T0_ccTV(void)
723 {
724 target_ulong src1;
725
726 if ((T0 & 0x03) || (T1 & 0x03))
727 raise_exception(TT_TOVF);
728
729 src1 = T0;
730 T0 -= T1;
731
732 #ifdef TARGET_SPARC64
733 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
734 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
735 raise_exception(TT_TOVF);
736 #else
737 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
738 raise_exception(TT_TOVF);
739 #endif
740
741 env->psr = 0;
742 #ifdef TARGET_SPARC64
743 if (!(T0 & 0xffffffff))
744 env->psr |= PSR_ZERO;
745 if ((int32_t) T0 < 0)
746 env->psr |= PSR_NEG;
747 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
748 env->psr |= PSR_CARRY;
749
750 env->xcc = 0;
751 if (!T0)
752 env->xcc |= PSR_ZERO;
753 if ((int64_t) T0 < 0)
754 env->xcc |= PSR_NEG;
755 if (src1 < T1)
756 env->xcc |= PSR_CARRY;
757 #else
758 if (!T0)
759 env->psr |= PSR_ZERO;
760 if ((int32_t) T0 < 0)
761 env->psr |= PSR_NEG;
762 if (src1 < T1)
763 env->psr |= PSR_CARRY;
764 #endif
765 FORCE_RET();
766 }
767
768 void OPPROTO op_and_T1_T0(void)
769 {
770 T0 &= T1;
771 }
772
773 void OPPROTO op_or_T1_T0(void)
774 {
775 T0 |= T1;
776 }
777
778 void OPPROTO op_xor_T1_T0(void)
779 {
780 T0 ^= T1;
781 }
782
783 void OPPROTO op_andn_T1_T0(void)
784 {
785 T0 &= ~T1;
786 }
787
788 void OPPROTO op_orn_T1_T0(void)
789 {
790 T0 |= ~T1;
791 }
792
793 void OPPROTO op_xnor_T1_T0(void)
794 {
795 T0 ^= ~T1;
796 }
797
798 void OPPROTO op_umul_T1_T0(void)
799 {
800 uint64_t res;
801 res = (uint64_t) T0 * (uint64_t) T1;
802 #ifdef TARGET_SPARC64
803 T0 = res;
804 #else
805 T0 = res & 0xffffffff;
806 #endif
807 env->y = res >> 32;
808 }
809
810 void OPPROTO op_smul_T1_T0(void)
811 {
812 uint64_t res;
813 res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
814 #ifdef TARGET_SPARC64
815 T0 = res;
816 #else
817 T0 = res & 0xffffffff;
818 #endif
819 env->y = res >> 32;
820 }
821
822 void OPPROTO op_mulscc_T1_T0(void)
823 {
824 unsigned int b1, N, V, b2;
825 target_ulong src1;
826
827 N = FLAG_SET(PSR_NEG);
828 V = FLAG_SET(PSR_OVF);
829 b1 = N ^ V;
830 b2 = T0 & 1;
831 T0 = (b1 << 31) | (T0 >> 1);
832 if (!(env->y & 1))
833 T1 = 0;
834 /* do addition and update flags */
835 src1 = T0;
836 T0 += T1;
837 env->psr = 0;
838 if (!T0)
839 env->psr |= PSR_ZERO;
840 if ((int32_t) T0 < 0)
841 env->psr |= PSR_NEG;
842 if (T0 < src1)
843 env->psr |= PSR_CARRY;
844 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
845 env->psr |= PSR_OVF;
846 env->y = (b2 << 31) | (env->y >> 1);
847 FORCE_RET();
848 }
849
850 void OPPROTO op_udiv_T1_T0(void)
851 {
852 uint64_t x0;
853 uint32_t x1;
854
855 x0 = T0 | ((uint64_t) (env->y) << 32);
856 x1 = T1;
857
858 if (x1 == 0) {
859 raise_exception(TT_DIV_ZERO);
860 }
861
862 x0 = x0 / x1;
863 if (x0 > 0xffffffff) {
864 T0 = 0xffffffff;
865 T1 = 1;
866 } else {
867 T0 = x0;
868 T1 = 0;
869 }
870 FORCE_RET();
871 }
872
873 void OPPROTO op_sdiv_T1_T0(void)
874 {
875 int64_t x0;
876 int32_t x1;
877
878 x0 = T0 | ((int64_t) (env->y) << 32);
879 x1 = T1;
880
881 if (x1 == 0) {
882 raise_exception(TT_DIV_ZERO);
883 }
884
885 x0 = x0 / x1;
886 if ((int32_t) x0 != x0) {
887 T0 = x0 < 0? 0x80000000: 0x7fffffff;
888 T1 = 1;
889 } else {
890 T0 = x0;
891 T1 = 0;
892 }
893 FORCE_RET();
894 }
895
896 void OPPROTO op_div_cc(void)
897 {
898 env->psr = 0;
899 #ifdef TARGET_SPARC64
900 if (!T0)
901 env->psr |= PSR_ZERO;
902 if ((int32_t) T0 < 0)
903 env->psr |= PSR_NEG;
904 if (T1)
905 env->psr |= PSR_OVF;
906
907 env->xcc = 0;
908 if (!T0)
909 env->xcc |= PSR_ZERO;
910 if ((int64_t) T0 < 0)
911 env->xcc |= PSR_NEG;
912 #else
913 if (!T0)
914 env->psr |= PSR_ZERO;
915 if ((int32_t) T0 < 0)
916 env->psr |= PSR_NEG;
917 if (T1)
918 env->psr |= PSR_OVF;
919 #endif
920 FORCE_RET();
921 }
922
923 #ifdef TARGET_SPARC64
924 void OPPROTO op_mulx_T1_T0(void)
925 {
926 T0 *= T1;
927 FORCE_RET();
928 }
929
930 void OPPROTO op_udivx_T1_T0(void)
931 {
932 if (T1 == 0) {
933 raise_exception(TT_DIV_ZERO);
934 }
935 T0 /= T1;
936 FORCE_RET();
937 }
938
939 void OPPROTO op_sdivx_T1_T0(void)
940 {
941 if (T1 == 0) {
942 raise_exception(TT_DIV_ZERO);
943 }
944 if (T0 == INT64_MIN && T1 == -1)
945 T0 = INT64_MIN;
946 else
947 T0 /= (target_long) T1;
948 FORCE_RET();
949 }
950 #endif
951
952 void OPPROTO op_logic_T0_cc(void)
953 {
954 env->psr = 0;
955 #ifdef TARGET_SPARC64
956 if (!(T0 & 0xffffffff))
957 env->psr |= PSR_ZERO;
958 if ((int32_t) T0 < 0)
959 env->psr |= PSR_NEG;
960
961 env->xcc = 0;
962 if (!T0)
963 env->xcc |= PSR_ZERO;
964 if ((int64_t) T0 < 0)
965 env->xcc |= PSR_NEG;
966 #else
967 if (!T0)
968 env->psr |= PSR_ZERO;
969 if ((int32_t) T0 < 0)
970 env->psr |= PSR_NEG;
971 #endif
972 FORCE_RET();
973 }
974
975 void OPPROTO op_sll(void)
976 {
977 T0 <<= (T1 & 0x1f);
978 }
979
980 #ifdef TARGET_SPARC64
981 void OPPROTO op_sllx(void)
982 {
983 T0 <<= (T1 & 0x3f);
984 }
985
986 void OPPROTO op_srl(void)
987 {
988 T0 = (T0 & 0xffffffff) >> (T1 & 0x1f);
989 }
990
991 void OPPROTO op_srlx(void)
992 {
993 T0 >>= (T1 & 0x3f);
994 }
995
996 void OPPROTO op_sra(void)
997 {
998 T0 = ((int32_t) (T0 & 0xffffffff)) >> (T1 & 0x1f);
999 }
1000
1001 void OPPROTO op_srax(void)
1002 {
1003 T0 = ((int64_t) T0) >> (T1 & 0x3f);
1004 }
1005 #else
1006 void OPPROTO op_srl(void)
1007 {
1008 T0 >>= (T1 & 0x1f);
1009 }
1010
1011 void OPPROTO op_sra(void)
1012 {
1013 T0 = ((int32_t) T0) >> (T1 & 0x1f);
1014 }
1015 #endif
1016
1017 /* Load and store */
1018 #define MEMSUFFIX _raw
1019 #include "op_mem.h"
1020 #if !defined(CONFIG_USER_ONLY)
1021 #define MEMSUFFIX _user
1022 #include "op_mem.h"
1023
1024 #define MEMSUFFIX _kernel
1025 #include "op_mem.h"
1026
1027 #ifdef TARGET_SPARC64
1028 #define MEMSUFFIX _hypv
1029 #include "op_mem.h"
1030 #endif
1031 #endif
1032
1033 void OPPROTO op_ldfsr(void)
1034 {
1035 PUT_FSR32(env, *((uint32_t *) &FT0));
1036 helper_ldfsr();
1037 }
1038
1039 void OPPROTO op_stfsr(void)
1040 {
1041 *((uint32_t *) &FT0) = GET_FSR32(env);
1042 }
1043
1044 #ifndef TARGET_SPARC64
1045 void OPPROTO op_rdpsr(void)
1046 {
1047 do_rdpsr();
1048 }
1049
1050 void OPPROTO op_wrpsr(void)
1051 {
1052 do_wrpsr();
1053 FORCE_RET();
1054 }
1055
1056 void OPPROTO op_wrwim(void)
1057 {
1058 #if NWINDOWS == 32
1059 env->wim = T0;
1060 #else
1061 env->wim = T0 & ((1 << NWINDOWS) - 1);
1062 #endif
1063 }
1064
1065 void OPPROTO op_rett(void)
1066 {
1067 helper_rett();
1068 FORCE_RET();
1069 }
1070
1071 /* XXX: use another pointer for %iN registers to avoid slow wrapping
1072 handling ? */
1073 void OPPROTO op_save(void)
1074 {
1075 uint32_t cwp;
1076 cwp = (env->cwp - 1) & (NWINDOWS - 1);
1077 if (env->wim & (1 << cwp)) {
1078 raise_exception(TT_WIN_OVF);
1079 }
1080 set_cwp(cwp);
1081 FORCE_RET();
1082 }
1083
1084 void OPPROTO op_restore(void)
1085 {
1086 uint32_t cwp;
1087 cwp = (env->cwp + 1) & (NWINDOWS - 1);
1088 if (env->wim & (1 << cwp)) {
1089 raise_exception(TT_WIN_UNF);
1090 }
1091 set_cwp(cwp);
1092 FORCE_RET();
1093 }
1094 #else
1095 void OPPROTO op_rdccr(void)
1096 {
1097 T0 = GET_CCR(env);
1098 }
1099
1100 void OPPROTO op_wrccr(void)
1101 {
1102 PUT_CCR(env, T0);
1103 }
1104
1105 void OPPROTO op_rdtick(void)
1106 {
1107 T0 = do_tick_get_count(env->tick);
1108 }
1109
1110 void OPPROTO op_wrtick(void)
1111 {
1112 do_tick_set_count(env->tick, T0);
1113 }
1114
1115 void OPPROTO op_wrtick_cmpr(void)
1116 {
1117 do_tick_set_limit(env->tick, T0);
1118 }
1119
1120 void OPPROTO op_rdstick(void)
1121 {
1122 T0 = do_tick_get_count(env->stick);
1123 }
1124
1125 void OPPROTO op_wrstick(void)
1126 {
1127 do_tick_set_count(env->stick, T0);
1128 do_tick_set_count(env->hstick, T0);
1129 }
1130
1131 void OPPROTO op_wrstick_cmpr(void)
1132 {
1133 do_tick_set_limit(env->stick, T0);
1134 }
1135
1136 void OPPROTO op_wrhstick_cmpr(void)
1137 {
1138 do_tick_set_limit(env->hstick, T0);
1139 }
1140
1141 void OPPROTO op_rdtpc(void)
1142 {
1143 T0 = env->tpc[env->tl];
1144 }
1145
1146 void OPPROTO op_wrtpc(void)
1147 {
1148 env->tpc[env->tl] = T0;
1149 }
1150
1151 void OPPROTO op_rdtnpc(void)
1152 {
1153 T0 = env->tnpc[env->tl];
1154 }
1155
1156 void OPPROTO op_wrtnpc(void)
1157 {
1158 env->tnpc[env->tl] = T0;
1159 }
1160
1161 void OPPROTO op_rdtstate(void)
1162 {
1163 T0 = env->tstate[env->tl];
1164 }
1165
1166 void OPPROTO op_wrtstate(void)
1167 {
1168 env->tstate[env->tl] = T0;
1169 }
1170
1171 void OPPROTO op_rdtt(void)
1172 {
1173 T0 = env->tt[env->tl];
1174 }
1175
1176 void OPPROTO op_wrtt(void)
1177 {
1178 env->tt[env->tl] = T0;
1179 }
1180
1181 void OPPROTO op_rdpstate(void)
1182 {
1183 T0 = env->pstate;
1184 }
1185
1186 void OPPROTO op_wrpstate(void)
1187 {
1188 do_wrpstate();
1189 }
1190
1191 // CWP handling is reversed in V9, but we still use the V8 register
1192 // order.
1193 void OPPROTO op_rdcwp(void)
1194 {
1195 T0 = GET_CWP64(env);
1196 }
1197
1198 void OPPROTO op_wrcwp(void)
1199 {
1200 PUT_CWP64(env, T0);
1201 }
1202
1203 /* XXX: use another pointer for %iN registers to avoid slow wrapping
1204 handling ? */
1205 void OPPROTO op_save(void)
1206 {
1207 uint32_t cwp;
1208 cwp = (env->cwp - 1) & (NWINDOWS - 1);
1209 if (env->cansave == 0) {
1210 raise_exception(TT_SPILL | (env->otherwin != 0 ?
1211 (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1212 ((env->wstate & 0x7) << 2)));
1213 } else {
1214 if (env->cleanwin - env->canrestore == 0) {
1215 // XXX Clean windows without trap
1216 raise_exception(TT_CLRWIN);
1217 } else {
1218 env->cansave--;
1219 env->canrestore++;
1220 set_cwp(cwp);
1221 }
1222 }
1223 FORCE_RET();
1224 }
1225
1226 void OPPROTO op_restore(void)
1227 {
1228 uint32_t cwp;
1229 cwp = (env->cwp + 1) & (NWINDOWS - 1);
1230 if (env->canrestore == 0) {
1231 raise_exception(TT_FILL | (env->otherwin != 0 ?
1232 (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1233 ((env->wstate & 0x7) << 2)));
1234 } else {
1235 env->cansave++;
1236 env->canrestore--;
1237 set_cwp(cwp);
1238 }
1239 FORCE_RET();
1240 }
1241 #endif
1242
1243 void OPPROTO op_exception(void)
1244 {
1245 env->exception_index = PARAM1;
1246 cpu_loop_exit();
1247 FORCE_RET();
1248 }
1249
1250 void OPPROTO op_trap_T0(void)
1251 {
1252 env->exception_index = TT_TRAP + (T0 & 0x7f);
1253 cpu_loop_exit();
1254 FORCE_RET();
1255 }
1256
1257 void OPPROTO op_trapcc_T0(void)
1258 {
1259 if (T2) {
1260 env->exception_index = TT_TRAP + (T0 & 0x7f);
1261 cpu_loop_exit();
1262 }
1263 FORCE_RET();
1264 }
1265
1266 void OPPROTO op_fpexception_im(void)
1267 {
1268 env->exception_index = TT_FP_EXCP;
1269 env->fsr &= ~FSR_FTT_MASK;
1270 env->fsr |= PARAM1;
1271 cpu_loop_exit();
1272 FORCE_RET();
1273 }
1274
1275 void OPPROTO op_debug(void)
1276 {
1277 helper_debug();
1278 }
1279
1280 void OPPROTO op_eval_ba(void)
1281 {
1282 T2 = 1;
1283 }
1284
1285 void OPPROTO op_eval_be(void)
1286 {
1287 T2 = FLAG_SET(PSR_ZERO);
1288 }
1289
1290 void OPPROTO op_eval_ble(void)
1291 {
1292 target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1293
1294 T2 = Z | (N ^ V);
1295 }
1296
1297 void OPPROTO op_eval_bl(void)
1298 {
1299 target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1300
1301 T2 = N ^ V;
1302 }
1303
1304 void OPPROTO op_eval_bleu(void)
1305 {
1306 target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1307
1308 T2 = C | Z;
1309 }
1310
1311 void OPPROTO op_eval_bcs(void)
1312 {
1313 T2 = FLAG_SET(PSR_CARRY);
1314 }
1315
1316 void OPPROTO op_eval_bvs(void)
1317 {
1318 T2 = FLAG_SET(PSR_OVF);
1319 }
1320
1321 void OPPROTO op_eval_bn(void)
1322 {
1323 T2 = 0;
1324 }
1325
1326 void OPPROTO op_eval_bneg(void)
1327 {
1328 T2 = FLAG_SET(PSR_NEG);
1329 }
1330
1331 void OPPROTO op_eval_bne(void)
1332 {
1333 T2 = !FLAG_SET(PSR_ZERO);
1334 }
1335
1336 void OPPROTO op_eval_bg(void)
1337 {
1338 target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1339
1340 T2 = !(Z | (N ^ V));
1341 }
1342
1343 void OPPROTO op_eval_bge(void)
1344 {
1345 target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1346
1347 T2 = !(N ^ V);
1348 }
1349
1350 void OPPROTO op_eval_bgu(void)
1351 {
1352 target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1353
1354 T2 = !(C | Z);
1355 }
1356
1357 void OPPROTO op_eval_bcc(void)
1358 {
1359 T2 = !FLAG_SET(PSR_CARRY);
1360 }
1361
1362 void OPPROTO op_eval_bpos(void)
1363 {
1364 T2 = !FLAG_SET(PSR_NEG);
1365 }
1366
1367 void OPPROTO op_eval_bvc(void)
1368 {
1369 T2 = !FLAG_SET(PSR_OVF);
1370 }
1371
1372 #ifdef TARGET_SPARC64
1373 void OPPROTO op_eval_xbe(void)
1374 {
1375 T2 = XFLAG_SET(PSR_ZERO);
1376 }
1377
1378 void OPPROTO op_eval_xble(void)
1379 {
1380 target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1381
1382 T2 = Z | (N ^ V);
1383 }
1384
1385 void OPPROTO op_eval_xbl(void)
1386 {
1387 target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1388
1389 T2 = N ^ V;
1390 }
1391
1392 void OPPROTO op_eval_xbleu(void)
1393 {
1394 target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1395
1396 T2 = C | Z;
1397 }
1398
1399 void OPPROTO op_eval_xbcs(void)
1400 {
1401 T2 = XFLAG_SET(PSR_CARRY);
1402 }
1403
1404 void OPPROTO op_eval_xbvs(void)
1405 {
1406 T2 = XFLAG_SET(PSR_OVF);
1407 }
1408
1409 void OPPROTO op_eval_xbneg(void)
1410 {
1411 T2 = XFLAG_SET(PSR_NEG);
1412 }
1413
1414 void OPPROTO op_eval_xbne(void)
1415 {
1416 T2 = !XFLAG_SET(PSR_ZERO);
1417 }
1418
1419 void OPPROTO op_eval_xbg(void)
1420 {
1421 target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1422
1423 T2 = !(Z | (N ^ V));
1424 }
1425
1426 void OPPROTO op_eval_xbge(void)
1427 {
1428 target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1429
1430 T2 = !(N ^ V);
1431 }
1432
1433 void OPPROTO op_eval_xbgu(void)
1434 {
1435 target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1436
1437 T2 = !(C | Z);
1438 }
1439
1440 void OPPROTO op_eval_xbcc(void)
1441 {
1442 T2 = !XFLAG_SET(PSR_CARRY);
1443 }
1444
1445 void OPPROTO op_eval_xbpos(void)
1446 {
1447 T2 = !XFLAG_SET(PSR_NEG);
1448 }
1449
1450 void OPPROTO op_eval_xbvc(void)
1451 {
1452 T2 = !XFLAG_SET(PSR_OVF);
1453 }
1454 #endif
1455
1456 #define FCC
1457 #define FFLAG_SET(x) (env->fsr & x? 1: 0)
1458 #include "fbranch_template.h"
1459
1460 #ifdef TARGET_SPARC64
1461 #define FCC _fcc1
1462 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
1463 #include "fbranch_template.h"
1464 #define FCC _fcc2
1465 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
1466 #include "fbranch_template.h"
1467 #define FCC _fcc3
1468 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
1469 #include "fbranch_template.h"
1470 #endif
1471
1472 #ifdef TARGET_SPARC64
1473 void OPPROTO op_eval_brz(void)
1474 {
1475 T2 = (T0 == 0);
1476 }
1477
1478 void OPPROTO op_eval_brnz(void)
1479 {
1480 T2 = (T0 != 0);
1481 }
1482
1483 void OPPROTO op_eval_brlz(void)
1484 {
1485 T2 = ((int64_t)T0 < 0);
1486 }
1487
1488 void OPPROTO op_eval_brlez(void)
1489 {
1490 T2 = ((int64_t)T0 <= 0);
1491 }
1492
1493 void OPPROTO op_eval_brgz(void)
1494 {
1495 T2 = ((int64_t)T0 > 0);
1496 }
1497
1498 void OPPROTO op_eval_brgez(void)
1499 {
1500 T2 = ((int64_t)T0 >= 0);
1501 }
1502
1503 void OPPROTO op_jmp_im64(void)
1504 {
1505 env->pc = PARAMQ1;
1506 }
1507
1508 void OPPROTO op_movq_npc_im64(void)
1509 {
1510 env->npc = PARAMQ1;
1511 }
1512 #endif
1513
1514 void OPPROTO op_jmp_im(void)
1515 {
1516 env->pc = (uint32_t)PARAM1;
1517 }
1518
1519 void OPPROTO op_movl_npc_im(void)
1520 {
1521 env->npc = (uint32_t)PARAM1;
1522 }
1523
1524 void OPPROTO op_movl_npc_T0(void)
1525 {
1526 env->npc = T0;
1527 }
1528
1529 void OPPROTO op_mov_pc_npc(void)
1530 {
1531 env->pc = env->npc;
1532 }
1533
1534 void OPPROTO op_next_insn(void)
1535 {
1536 env->pc = env->npc;
1537 env->npc = env->npc + 4;
1538 }
1539
1540 void OPPROTO op_jmp_label(void)
1541 {
1542 GOTO_LABEL_PARAM(1);
1543 }
1544
1545 void OPPROTO op_jnz_T2_label(void)
1546 {
1547 if (T2)
1548 GOTO_LABEL_PARAM(1);
1549 FORCE_RET();
1550 }
1551
1552 void OPPROTO op_jz_T2_label(void)
1553 {
1554 if (!T2)
1555 GOTO_LABEL_PARAM(1);
1556 FORCE_RET();
1557 }
1558
1559 void OPPROTO op_flush_T0(void)
1560 {
1561 helper_flush(T0);
1562 }
1563
1564 void OPPROTO op_clear_ieee_excp_and_FTT(void)
1565 {
1566 env->fsr &= ~(FSR_FTT_MASK | FSR_CEXC_MASK);;
1567 }
1568
1569 #define F_OP(name, p) void OPPROTO op_f##name##p(void)
1570
1571 #if defined(CONFIG_USER_ONLY)
1572 #define F_BINOP(name) \
1573 F_OP(name, s) \
1574 { \
1575 set_float_exception_flags(0, &env->fp_status); \
1576 FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
1577 check_ieee_exceptions(); \
1578 } \
1579 F_OP(name, d) \
1580 { \
1581 set_float_exception_flags(0, &env->fp_status); \
1582 DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
1583 check_ieee_exceptions(); \
1584 } \
1585 F_OP(name, q) \
1586 { \
1587 set_float_exception_flags(0, &env->fp_status); \
1588 QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \
1589 check_ieee_exceptions(); \
1590 }
1591 #else
1592 #define F_BINOP(name) \
1593 F_OP(name, s) \
1594 { \
1595 set_float_exception_flags(0, &env->fp_status); \
1596 FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
1597 check_ieee_exceptions(); \
1598 } \
1599 F_OP(name, d) \
1600 { \
1601 set_float_exception_flags(0, &env->fp_status); \
1602 DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
1603 check_ieee_exceptions(); \
1604 }
1605 #endif
1606
1607 F_BINOP(add);
1608 F_BINOP(sub);
1609 F_BINOP(mul);
1610 F_BINOP(div);
1611 #undef F_BINOP
1612
1613 void OPPROTO op_fsmuld(void)
1614 {
1615 set_float_exception_flags(0, &env->fp_status);
1616 DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status),
1617 float32_to_float64(FT1, &env->fp_status),
1618 &env->fp_status);
1619 check_ieee_exceptions();
1620 }
1621
1622 #if defined(CONFIG_USER_ONLY)
1623 void OPPROTO op_fdmulq(void)
1624 {
1625 set_float_exception_flags(0, &env->fp_status);
1626 QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status),
1627 float64_to_float128(DT1, &env->fp_status),
1628 &env->fp_status);
1629 check_ieee_exceptions();
1630 }
1631 #endif
1632
1633 #if defined(CONFIG_USER_ONLY)
1634 #define F_HELPER(name) \
1635 F_OP(name, s) \
1636 { \
1637 do_f##name##s(); \
1638 } \
1639 F_OP(name, d) \
1640 { \
1641 do_f##name##d(); \
1642 } \
1643 F_OP(name, q) \
1644 { \
1645 do_f##name##q(); \
1646 }
1647 #else
1648 #define F_HELPER(name) \
1649 F_OP(name, s) \
1650 { \
1651 do_f##name##s(); \
1652 } \
1653 F_OP(name, d) \
1654 { \
1655 do_f##name##d(); \
1656 }
1657 #endif
1658
1659 F_HELPER(sqrt);
1660
1661 F_OP(neg, s)
1662 {
1663 FT0 = float32_chs(FT1);
1664 }
1665
1666 F_OP(abs, s)
1667 {
1668 do_fabss();
1669 }
1670
1671 F_HELPER(cmp);
1672 F_HELPER(cmpe);
1673
1674 #ifdef TARGET_SPARC64
1675 F_OP(neg, d)
1676 {
1677 DT0 = float64_chs(DT1);
1678 }
1679
1680 F_OP(abs, d)
1681 {
1682 do_fabsd();
1683 }
1684
1685 #if defined(CONFIG_USER_ONLY)
1686 F_OP(neg, q)
1687 {
1688 QT0 = float128_chs(QT1);
1689 }
1690
1691 F_OP(abs, q)
1692 {
1693 do_fabsd();
1694 }
1695 #endif
1696
1697 void OPPROTO op_fcmps_fcc1(void)
1698 {
1699 do_fcmps_fcc1();
1700 }
1701
1702 void OPPROTO op_fcmpd_fcc1(void)
1703 {
1704 do_fcmpd_fcc1();
1705 }
1706
1707 void OPPROTO op_fcmps_fcc2(void)
1708 {
1709 do_fcmps_fcc2();
1710 }
1711
1712 void OPPROTO op_fcmpd_fcc2(void)
1713 {
1714 do_fcmpd_fcc2();
1715 }
1716
1717 void OPPROTO op_fcmps_fcc3(void)
1718 {
1719 do_fcmps_fcc3();
1720 }
1721
1722 void OPPROTO op_fcmpd_fcc3(void)
1723 {
1724 do_fcmpd_fcc3();
1725 }
1726
1727 void OPPROTO op_fcmpes_fcc1(void)
1728 {
1729 do_fcmpes_fcc1();
1730 }
1731
1732 void OPPROTO op_fcmped_fcc1(void)
1733 {
1734 do_fcmped_fcc1();
1735 }
1736
1737 void OPPROTO op_fcmpes_fcc2(void)
1738 {
1739 do_fcmpes_fcc2();
1740 }
1741
1742 void OPPROTO op_fcmped_fcc2(void)
1743 {
1744 do_fcmped_fcc2();
1745 }
1746
1747 void OPPROTO op_fcmpes_fcc3(void)
1748 {
1749 do_fcmpes_fcc3();
1750 }
1751
1752 void OPPROTO op_fcmped_fcc3(void)
1753 {
1754 do_fcmped_fcc3();
1755 }
1756
1757 #if defined(CONFIG_USER_ONLY)
1758 void OPPROTO op_fcmpq_fcc1(void)
1759 {
1760 do_fcmpq_fcc1();
1761 }
1762
1763 void OPPROTO op_fcmpq_fcc2(void)
1764 {
1765 do_fcmpq_fcc2();
1766 }
1767
1768 void OPPROTO op_fcmpq_fcc3(void)
1769 {
1770 do_fcmpq_fcc3();
1771 }
1772
1773 void OPPROTO op_fcmpeq_fcc1(void)
1774 {
1775 do_fcmpeq_fcc1();
1776 }
1777
1778 void OPPROTO op_fcmpeq_fcc2(void)
1779 {
1780 do_fcmpeq_fcc2();
1781 }
1782
1783 void OPPROTO op_fcmpeq_fcc3(void)
1784 {
1785 do_fcmpeq_fcc3();
1786 }
1787 #endif
1788
1789 #endif
1790
1791 /* Integer to float conversion. */
1792 #ifdef USE_INT_TO_FLOAT_HELPERS
1793 F_HELPER(ito);
1794 #ifdef TARGET_SPARC64
1795 F_HELPER(xto);
1796 #endif
1797 #else
1798 F_OP(ito, s)
1799 {
1800 set_float_exception_flags(0, &env->fp_status);
1801 FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
1802 check_ieee_exceptions();
1803 }
1804
1805 F_OP(ito, d)
1806 {
1807 set_float_exception_flags(0, &env->fp_status);
1808 DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
1809 check_ieee_exceptions();
1810 }
1811
1812 #if defined(CONFIG_USER_ONLY)
1813 F_OP(ito, q)
1814 {
1815 set_float_exception_flags(0, &env->fp_status);
1816 QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
1817 check_ieee_exceptions();
1818 }
1819 #endif
1820
1821 #ifdef TARGET_SPARC64
1822 F_OP(xto, s)
1823 {
1824 set_float_exception_flags(0, &env->fp_status);
1825 FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
1826 check_ieee_exceptions();
1827 }
1828
1829 F_OP(xto, d)
1830 {
1831 set_float_exception_flags(0, &env->fp_status);
1832 DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
1833 check_ieee_exceptions();
1834 }
1835 #if defined(CONFIG_USER_ONLY)
1836 F_OP(xto, q)
1837 {
1838 set_float_exception_flags(0, &env->fp_status);
1839 QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
1840 check_ieee_exceptions();
1841 }
1842 #endif
1843 #endif
1844 #endif
1845 #undef F_HELPER
1846
1847 /* floating point conversion */
1848 void OPPROTO op_fdtos(void)
1849 {
1850 set_float_exception_flags(0, &env->fp_status);
1851 FT0 = float64_to_float32(DT1, &env->fp_status);
1852 check_ieee_exceptions();
1853 }
1854
1855 void OPPROTO op_fstod(void)
1856 {
1857 set_float_exception_flags(0, &env->fp_status);
1858 DT0 = float32_to_float64(FT1, &env->fp_status);
1859 check_ieee_exceptions();
1860 }
1861
1862 #if defined(CONFIG_USER_ONLY)
1863 void OPPROTO op_fqtos(void)
1864 {
1865 set_float_exception_flags(0, &env->fp_status);
1866 FT0 = float128_to_float32(QT1, &env->fp_status);
1867 check_ieee_exceptions();
1868 }
1869
1870 void OPPROTO op_fstoq(void)
1871 {
1872 set_float_exception_flags(0, &env->fp_status);
1873 QT0 = float32_to_float128(FT1, &env->fp_status);
1874 check_ieee_exceptions();
1875 }
1876
1877 void OPPROTO op_fqtod(void)
1878 {
1879 set_float_exception_flags(0, &env->fp_status);
1880 DT0 = float128_to_float64(QT1, &env->fp_status);
1881 check_ieee_exceptions();
1882 }
1883
1884 void OPPROTO op_fdtoq(void)
1885 {
1886 set_float_exception_flags(0, &env->fp_status);
1887 QT0 = float64_to_float128(DT1, &env->fp_status);
1888 check_ieee_exceptions();
1889 }
1890 #endif
1891
1892 /* Float to integer conversion. */
1893 void OPPROTO op_fstoi(void)
1894 {
1895 set_float_exception_flags(0, &env->fp_status);
1896 *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status);
1897 check_ieee_exceptions();
1898 }
1899
1900 void OPPROTO op_fdtoi(void)
1901 {
1902 set_float_exception_flags(0, &env->fp_status);
1903 *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
1904 check_ieee_exceptions();
1905 }
1906
1907 #if defined(CONFIG_USER_ONLY)
1908 void OPPROTO op_fqtoi(void)
1909 {
1910 set_float_exception_flags(0, &env->fp_status);
1911 *((int32_t *)&FT0) = float128_to_int32_round_to_zero(QT1, &env->fp_status);
1912 check_ieee_exceptions();
1913 }
1914 #endif
1915
1916 #ifdef TARGET_SPARC64
1917 void OPPROTO op_fstox(void)
1918 {
1919 set_float_exception_flags(0, &env->fp_status);
1920 *((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status);
1921 check_ieee_exceptions();
1922 }
1923
1924 void OPPROTO op_fdtox(void)
1925 {
1926 set_float_exception_flags(0, &env->fp_status);
1927 *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
1928 check_ieee_exceptions();
1929 }
1930
1931 #if defined(CONFIG_USER_ONLY)
1932 void OPPROTO op_fqtox(void)
1933 {
1934 set_float_exception_flags(0, &env->fp_status);
1935 *((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status);
1936 check_ieee_exceptions();
1937 }
1938 #endif
1939
1940 void OPPROTO op_fmovs_cc(void)
1941 {
1942 if (T2)
1943 FT0 = FT1;
1944 }
1945
1946 void OPPROTO op_fmovd_cc(void)
1947 {
1948 if (T2)
1949 DT0 = DT1;
1950 }
1951
1952 #if defined(CONFIG_USER_ONLY)
1953 void OPPROTO op_fmovq_cc(void)
1954 {
1955 if (T2)
1956 QT0 = QT1;
1957 }
1958 #endif
1959
1960 void OPPROTO op_mov_cc(void)
1961 {
1962 if (T2)
1963 T0 = T1;
1964 }
1965
1966 void OPPROTO op_flushw(void)
1967 {
1968 if (env->cansave != NWINDOWS - 2) {
1969 raise_exception(TT_SPILL | (env->otherwin != 0 ?
1970 (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1971 ((env->wstate & 0x7) << 2)));
1972 }
1973 }
1974
1975 void OPPROTO op_saved(void)
1976 {
1977 env->cansave++;
1978 if (env->otherwin == 0)
1979 env->canrestore--;
1980 else
1981 env->otherwin--;
1982 FORCE_RET();
1983 }
1984
1985 void OPPROTO op_restored(void)
1986 {
1987 env->canrestore++;
1988 if (env->cleanwin < NWINDOWS - 1)
1989 env->cleanwin++;
1990 if (env->otherwin == 0)
1991 env->cansave--;
1992 else
1993 env->otherwin--;
1994 FORCE_RET();
1995 }
1996
1997 void OPPROTO op_popc(void)
1998 {
1999 do_popc();
2000 }
2001
2002 void OPPROTO op_done(void)
2003 {
2004 do_done();
2005 }
2006
2007 void OPPROTO op_retry(void)
2008 {
2009 do_retry();
2010 }
2011
2012 void OPPROTO op_sir(void)
2013 {
2014 T0 = 0; // XXX
2015 }
2016
2017 void OPPROTO op_ld_asi_reg()
2018 {
2019 T0 += PARAM1;
2020 helper_ld_asi(env->asi, PARAM2, PARAM3);
2021 }
2022
2023 void OPPROTO op_st_asi_reg()
2024 {
2025 T0 += PARAM1;
2026 helper_st_asi(env->asi, PARAM2);
2027 }
2028
2029 void OPPROTO op_ldf_asi_reg()
2030 {
2031 T0 += PARAM1;
2032 helper_ldf_asi(env->asi, PARAM2, PARAM3);
2033 }
2034
2035 void OPPROTO op_stf_asi_reg()
2036 {
2037 T0 += PARAM1;
2038 helper_stf_asi(env->asi, PARAM2, PARAM3);
2039 }
2040
2041 void OPPROTO op_ldf_asi()
2042 {
2043 helper_ldf_asi(PARAM1, PARAM2, PARAM3);
2044 }
2045
2046 void OPPROTO op_stf_asi()
2047 {
2048 helper_stf_asi(PARAM1, PARAM2, PARAM3);
2049 }
2050
2051 void OPPROTO op_ldstub_asi_reg() /* XXX: should be atomically */
2052 {
2053 target_ulong tmp;
2054
2055 T0 += PARAM1;
2056 helper_ld_asi(env->asi, 1, 0);
2057 tmp = T1;
2058 T1 = 0xff;
2059 helper_st_asi(env->asi, 1);
2060 T1 = tmp;
2061 }
2062
2063 void OPPROTO op_swap_asi_reg() /* XXX: should be atomically */
2064 {
2065 target_ulong tmp1, tmp2;
2066
2067 T0 += PARAM1;
2068 tmp1 = T1;
2069 helper_ld_asi(env->asi, 4, 0);
2070 tmp2 = T1;
2071 T1 = tmp1;
2072 helper_st_asi(env->asi, 4);
2073 T1 = tmp2;
2074 }
2075
2076 void OPPROTO op_ldda_asi()
2077 {
2078 helper_ld_asi(PARAM1, 8, 0);
2079 T0 = T1 & 0xffffffffUL;
2080 T1 >>= 32;
2081 }
2082
2083 void OPPROTO op_ldda_asi_reg()
2084 {
2085 T0 += PARAM1;
2086 helper_ld_asi(env->asi, 8, 0);
2087 T0 = T1 & 0xffffffffUL;
2088 T1 >>= 32;
2089 }
2090
2091 void OPPROTO op_stda_asi()
2092 {
2093 T1 <<= 32;
2094 T1 += T2 & 0xffffffffUL;
2095 helper_st_asi(PARAM1, 8);
2096 }
2097
2098 void OPPROTO op_stda_asi_reg()
2099 {
2100 T0 += PARAM1;
2101 T1 <<= 32;
2102 T1 += T2 & 0xffffffffUL;
2103 helper_st_asi(env->asi, 8);
2104 }
2105
2106 void OPPROTO op_cas_asi() /* XXX: should be atomically */
2107 {
2108 target_ulong tmp;
2109
2110 tmp = T1 & 0xffffffffUL;
2111 helper_ld_asi(PARAM1, 4, 0);
2112 if (tmp == T1) {
2113 tmp = T1;
2114 T1 = T2 & 0xffffffffUL;
2115 helper_st_asi(PARAM1, 4);
2116 T1 = tmp;
2117 }
2118 T1 &= 0xffffffffUL;
2119 }
2120
2121 void OPPROTO op_cas_asi_reg() /* XXX: should be atomically */
2122 {
2123 target_ulong tmp;
2124
2125 T0 += PARAM1;
2126 tmp = T1 & 0xffffffffUL;
2127 helper_ld_asi(env->asi, 4, 0);
2128 if (tmp == T1) {
2129 tmp = T1;
2130 T1 = T2 & 0xffffffffUL;
2131 helper_st_asi(env->asi, 4);
2132 T1 = tmp;
2133 }
2134 T1 &= 0xffffffffUL;
2135 }
2136
2137 void OPPROTO op_casx_asi() /* XXX: should be atomically */
2138 {
2139 target_ulong tmp;
2140
2141 tmp = T1;
2142 helper_ld_asi(PARAM1, 8, 0);
2143 if (tmp == T1) {
2144 tmp = T1;
2145 T1 = T2;
2146 helper_st_asi(PARAM1, 8);
2147 T1 = tmp;
2148 }
2149 }
2150
2151 void OPPROTO op_casx_asi_reg() /* XXX: should be atomically */
2152 {
2153 target_ulong tmp;
2154
2155 T0 += PARAM1;
2156 tmp = T1;
2157 helper_ld_asi(env->asi, 8, 0);
2158 if (tmp == T1) {
2159 tmp = T1;
2160 T1 = T2;
2161 helper_st_asi(env->asi, 8);
2162 T1 = tmp;
2163 }
2164 }
2165 #endif
2166
2167 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
2168 void OPPROTO op_ld_asi()
2169 {
2170 helper_ld_asi(PARAM1, PARAM2, PARAM3);
2171 }
2172
2173 void OPPROTO op_st_asi()
2174 {
2175 helper_st_asi(PARAM1, PARAM2);
2176 }
2177
2178 void OPPROTO op_ldstub_asi() /* XXX: should be atomically */
2179 {
2180 target_ulong tmp;
2181
2182 helper_ld_asi(PARAM1, 1, 0);
2183 tmp = T1;
2184 T1 = 0xff;
2185 helper_st_asi(PARAM1, 1);
2186 T1 = tmp;
2187 }
2188
2189 void OPPROTO op_swap_asi() /* XXX: should be atomically */
2190 {
2191 target_ulong tmp1, tmp2;
2192
2193 tmp1 = T1;
2194 helper_ld_asi(PARAM1, 4, 0);
2195 tmp2 = T1;
2196 T1 = tmp1;
2197 helper_st_asi(PARAM1, 4);
2198 T1 = tmp2;
2199 }
2200 #endif
2201
2202 #ifdef TARGET_SPARC64
2203 // This function uses non-native bit order
2204 #define GET_FIELD(X, FROM, TO) \
2205 ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
2206
2207 // This function uses the order in the manuals, i.e. bit 0 is 2^0
2208 #define GET_FIELD_SP(X, FROM, TO) \
2209 GET_FIELD(X, 63 - (TO), 63 - (FROM))
2210
2211 void OPPROTO op_array8()
2212 {
2213 T0 = (GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
2214 (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
2215 (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
2216 (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
2217 (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
2218 (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12);
2219 }
2220
2221 void OPPROTO op_array16()
2222 {
2223 T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
2224 (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
2225 (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
2226 (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
2227 (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
2228 (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 1;
2229 }
2230
2231 void OPPROTO op_array32()
2232 {
2233 T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
2234 (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
2235 (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
2236 (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
2237 (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
2238 (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 2;
2239 }
2240
2241 void OPPROTO op_alignaddr()
2242 {
2243 uint64_t tmp;
2244
2245 tmp = T0 + T1;
2246 env->gsr &= ~7ULL;
2247 env->gsr |= tmp & 7ULL;
2248 T0 = tmp & ~7ULL;
2249 }
2250
2251 void OPPROTO op_faligndata()
2252 {
2253 uint64_t tmp;
2254
2255 tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8);
2256 tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
2257 *((uint64_t *)&DT0) = tmp;
2258 }
2259
2260 void OPPROTO op_movl_FT0_0(void)
2261 {
2262 *((uint32_t *)&FT0) = 0;
2263 }
2264
2265 void OPPROTO op_movl_DT0_0(void)
2266 {
2267 *((uint64_t *)&DT0) = 0;
2268 }
2269
2270 void OPPROTO op_movl_FT0_1(void)
2271 {
2272 *((uint32_t *)&FT0) = 0xffffffff;
2273 }
2274
2275 void OPPROTO op_movl_DT0_1(void)
2276 {
2277 *((uint64_t *)&DT0) = 0xffffffffffffffffULL;
2278 }
2279
2280 void OPPROTO op_fnot(void)
2281 {
2282 *(uint64_t *)&DT0 = ~*(uint64_t *)&DT1;
2283 }
2284
2285 void OPPROTO op_fnots(void)
2286 {
2287 *(uint32_t *)&FT0 = ~*(uint32_t *)&FT1;
2288 }
2289
2290 void OPPROTO op_fnor(void)
2291 {
2292 *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 | *(uint64_t *)&DT1);
2293 }
2294
2295 void OPPROTO op_fnors(void)
2296 {
2297 *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 | *(uint32_t *)&FT1);
2298 }
2299
2300 void OPPROTO op_for(void)
2301 {
2302 *(uint64_t *)&DT0 |= *(uint64_t *)&DT1;
2303 }
2304
2305 void OPPROTO op_fors(void)
2306 {
2307 *(uint32_t *)&FT0 |= *(uint32_t *)&FT1;
2308 }
2309
2310 void OPPROTO op_fxor(void)
2311 {
2312 *(uint64_t *)&DT0 ^= *(uint64_t *)&DT1;
2313 }
2314
2315 void OPPROTO op_fxors(void)
2316 {
2317 *(uint32_t *)&FT0 ^= *(uint32_t *)&FT1;
2318 }
2319
2320 void OPPROTO op_fand(void)
2321 {
2322 *(uint64_t *)&DT0 &= *(uint64_t *)&DT1;
2323 }
2324
2325 void OPPROTO op_fands(void)
2326 {
2327 *(uint32_t *)&FT0 &= *(uint32_t *)&FT1;
2328 }
2329
2330 void OPPROTO op_fornot(void)
2331 {
2332 *(uint64_t *)&DT0 = *(uint64_t *)&DT0 | ~*(uint64_t *)&DT1;
2333 }
2334
2335 void OPPROTO op_fornots(void)
2336 {
2337 *(uint32_t *)&FT0 = *(uint32_t *)&FT0 | ~*(uint32_t *)&FT1;
2338 }
2339
2340 void OPPROTO op_fandnot(void)
2341 {
2342 *(uint64_t *)&DT0 = *(uint64_t *)&DT0 & ~*(uint64_t *)&DT1;
2343 }
2344
2345 void OPPROTO op_fandnots(void)
2346 {
2347 *(uint32_t *)&FT0 = *(uint32_t *)&FT0 & ~*(uint32_t *)&FT1;
2348 }
2349
2350 void OPPROTO op_fnand(void)
2351 {
2352 *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 & *(uint64_t *)&DT1);
2353 }
2354
2355 void OPPROTO op_fnands(void)
2356 {
2357 *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 & *(uint32_t *)&FT1);
2358 }
2359
2360 void OPPROTO op_fxnor(void)
2361 {
2362 *(uint64_t *)&DT0 ^= ~*(uint64_t *)&DT1;
2363 }
2364
2365 void OPPROTO op_fxnors(void)
2366 {
2367 *(uint32_t *)&FT0 ^= ~*(uint32_t *)&FT1;
2368 }
2369
2370 #ifdef WORDS_BIGENDIAN
2371 #define VIS_B64(n) b[7 - (n)]
2372 #define VIS_W64(n) w[3 - (n)]
2373 #define VIS_SW64(n) sw[3 - (n)]
2374 #define VIS_L64(n) l[1 - (n)]
2375 #define VIS_B32(n) b[3 - (n)]
2376 #define VIS_W32(n) w[1 - (n)]
2377 #else
2378 #define VIS_B64(n) b[n]
2379 #define VIS_W64(n) w[n]
2380 #define VIS_SW64(n) sw[n]
2381 #define VIS_L64(n) l[n]
2382 #define VIS_B32(n) b[n]
2383 #define VIS_W32(n) w[n]
2384 #endif
2385
2386 typedef union {
2387 uint8_t b[8];
2388 uint16_t w[4];
2389 int16_t sw[4];
2390 uint32_t l[2];
2391 float64 d;
2392 } vis64;
2393
2394 typedef union {
2395 uint8_t b[4];
2396 uint16_t w[2];
2397 uint32_t l;
2398 float32 f;
2399 } vis32;
2400
2401 void OPPROTO op_fpmerge(void)
2402 {
2403 vis64 s, d;
2404
2405 s.d = DT0;
2406 d.d = DT1;
2407
2408 // Reverse calculation order to handle overlap
2409 d.VIS_B64(7) = s.VIS_B64(3);
2410 d.VIS_B64(6) = d.VIS_B64(3);
2411 d.VIS_B64(5) = s.VIS_B64(2);
2412 d.VIS_B64(4) = d.VIS_B64(2);
2413 d.VIS_B64(3) = s.VIS_B64(1);
2414 d.VIS_B64(2) = d.VIS_B64(1);
2415 d.VIS_B64(1) = s.VIS_B64(0);
2416 //d.VIS_B64(0) = d.VIS_B64(0);
2417
2418 DT0 = d.d;
2419 }
2420
2421 void OPPROTO op_fmul8x16(void)
2422 {
2423 vis64 s, d;
2424 uint32_t tmp;
2425
2426 s.d = DT0;
2427 d.d = DT1;
2428
2429 #define PMUL(r) \
2430 tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r); \
2431 if ((tmp & 0xff) > 0x7f) \
2432 tmp += 0x100; \
2433 d.VIS_W64(r) = tmp >> 8;
2434
2435 PMUL(0);
2436 PMUL(1);
2437 PMUL(2);
2438 PMUL(3);
2439 #undef PMUL
2440
2441 DT0 = d.d;
2442 }
2443
2444 void OPPROTO op_fmul8x16al(void)
2445 {
2446 vis64 s, d;
2447 uint32_t tmp;
2448
2449 s.d = DT0;
2450 d.d = DT1;
2451
2452 #define PMUL(r) \
2453 tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r); \
2454 if ((tmp & 0xff) > 0x7f) \
2455 tmp += 0x100; \
2456 d.VIS_W64(r) = tmp >> 8;
2457
2458 PMUL(0);
2459 PMUL(1);
2460 PMUL(2);
2461 PMUL(3);
2462 #undef PMUL
2463
2464 DT0 = d.d;
2465 }
2466
2467 void OPPROTO op_fmul8x16au(void)
2468 {
2469 vis64 s, d;
2470 uint32_t tmp;
2471
2472 s.d = DT0;
2473 d.d = DT1;
2474
2475 #define PMUL(r) \
2476 tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r); \
2477 if ((tmp & 0xff) > 0x7f) \
2478 tmp += 0x100; \
2479 d.VIS_W64(r) = tmp >> 8;
2480
2481 PMUL(0);
2482 PMUL(1);
2483 PMUL(2);
2484 PMUL(3);
2485 #undef PMUL
2486
2487 DT0 = d.d;
2488 }
2489
2490 void OPPROTO op_fmul8sux16(void)
2491 {
2492 vis64 s, d;
2493 uint32_t tmp;
2494
2495 s.d = DT0;
2496 d.d = DT1;
2497
2498 #define PMUL(r) \
2499 tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
2500 if ((tmp & 0xff) > 0x7f) \
2501 tmp += 0x100; \
2502 d.VIS_W64(r) = tmp >> 8;
2503
2504 PMUL(0);
2505 PMUL(1);
2506 PMUL(2);
2507 PMUL(3);
2508 #undef PMUL
2509
2510 DT0 = d.d;
2511 }
2512
2513 void OPPROTO op_fmul8ulx16(void)
2514 {
2515 vis64 s, d;
2516 uint32_t tmp;
2517
2518 s.d = DT0;
2519 d.d = DT1;
2520
2521 #define PMUL(r) \
2522 tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
2523 if ((tmp & 0xff) > 0x7f) \
2524 tmp += 0x100; \
2525 d.VIS_W64(r) = tmp >> 8;
2526
2527 PMUL(0);
2528 PMUL(1);
2529 PMUL(2);
2530 PMUL(3);
2531 #undef PMUL
2532
2533 DT0 = d.d;
2534 }
2535
2536 void OPPROTO op_fmuld8sux16(void)
2537 {
2538 vis64 s, d;
2539 uint32_t tmp;
2540
2541 s.d = DT0;
2542 d.d = DT1;
2543
2544 #define PMUL(r) \
2545 tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
2546 if ((tmp & 0xff) > 0x7f) \
2547 tmp += 0x100; \
2548 d.VIS_L64(r) = tmp;
2549
2550 // Reverse calculation order to handle overlap
2551 PMUL(1);
2552 PMUL(0);
2553 #undef PMUL
2554
2555 DT0 = d.d;
2556 }
2557
2558 void OPPROTO op_fmuld8ulx16(void)
2559 {
2560 vis64 s, d;
2561 uint32_t tmp;
2562
2563 s.d = DT0;
2564 d.d = DT1;
2565
2566 #define PMUL(r) \
2567 tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
2568 if ((tmp & 0xff) > 0x7f) \
2569 tmp += 0x100; \
2570 d.VIS_L64(r) = tmp;
2571
2572 // Reverse calculation order to handle overlap
2573 PMUL(1);
2574 PMUL(0);
2575 #undef PMUL
2576
2577 DT0 = d.d;
2578 }
2579
2580 void OPPROTO op_fexpand(void)
2581 {
2582 vis32 s;
2583 vis64 d;
2584
2585 s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff);
2586 d.d = DT1;
2587 d.VIS_L64(0) = s.VIS_W32(0) << 4;
2588 d.VIS_L64(1) = s.VIS_W32(1) << 4;
2589 d.VIS_L64(2) = s.VIS_W32(2) << 4;
2590 d.VIS_L64(3) = s.VIS_W32(3) << 4;
2591
2592 DT0 = d.d;
2593 }
2594
2595 #define VIS_OP(name, F) \
2596 void OPPROTO name##16(void) \
2597 { \
2598 vis64 s, d; \
2599 \
2600 s.d = DT0; \
2601 d.d = DT1; \
2602 \
2603 d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0)); \
2604 d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1)); \
2605 d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2)); \
2606 d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3)); \
2607 \
2608 DT0 = d.d; \
2609 } \
2610 \
2611 void OPPROTO name##16s(void) \
2612 { \
2613 vis32 s, d; \
2614 \
2615 s.f = FT0; \
2616 d.f = FT1; \
2617 \
2618 d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0)); \
2619 d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1)); \
2620 \
2621 FT0 = d.f; \
2622 } \
2623 \
2624 void OPPROTO name##32(void) \
2625 { \
2626 vis64 s, d; \
2627 \
2628 s.d = DT0; \
2629 d.d = DT1; \
2630 \
2631 d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0)); \
2632 d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1)); \
2633 \
2634 DT0 = d.d; \
2635 } \
2636 \
2637 void OPPROTO name##32s(void) \
2638 { \
2639 vis32 s, d; \
2640 \
2641 s.f = FT0; \
2642 d.f = FT1; \
2643 \
2644 d.l = F(d.l, s.l); \
2645 \
2646 FT0 = d.f; \
2647 }
2648
2649 #define FADD(a, b) ((a) + (b))
2650 #define FSUB(a, b) ((a) - (b))
2651 VIS_OP(op_fpadd, FADD)
2652 VIS_OP(op_fpsub, FSUB)
2653
2654 #define VIS_CMPOP(name, F) \
2655 void OPPROTO name##16(void) \
2656 { \
2657 vis64 s, d; \
2658 \
2659 s.d = DT0; \
2660 d.d = DT1; \
2661 \
2662 d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0; \
2663 d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0; \
2664 d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0; \
2665 d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0; \
2666 \
2667 DT0 = d.d; \
2668 } \
2669 \
2670 void OPPROTO name##32(void) \
2671 { \
2672 vis64 s, d; \
2673 \
2674 s.d = DT0; \
2675 d.d = DT1; \
2676 \
2677 d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0; \
2678 d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0; \
2679 \
2680 DT0 = d.d; \
2681 }
2682
2683 #define FCMPGT(a, b) ((a) > (b))
2684 #define FCMPEQ(a, b) ((a) == (b))
2685 #define FCMPLE(a, b) ((a) <= (b))
2686 #define FCMPNE(a, b) ((a) != (b))
2687
2688 VIS_CMPOP(op_fcmpgt, FCMPGT)
2689 VIS_CMPOP(op_fcmpeq, FCMPEQ)
2690 VIS_CMPOP(op_fcmple, FCMPLE)
2691 VIS_CMPOP(op_fcmpne, FCMPNE)
2692
2693 #endif
2694
2695 #define CHECK_ALIGN_OP(align) \
2696 void OPPROTO op_check_align_T0_ ## align (void) \
2697 { \
2698 if (T0 & align) \
2699 raise_exception(TT_UNALIGNED); \
2700 FORCE_RET(); \
2701 }
2702
2703 CHECK_ALIGN_OP(1)
2704 CHECK_ALIGN_OP(3)
2705 CHECK_ALIGN_OP(7)