4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
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.
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.
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
25 #define REG (env->fpr[0])
26 #include "fop_template.h"
28 #define REG (env->fpr[1])
29 #include "fop_template.h"
31 #define REG (env->fpr[2])
32 #include "fop_template.h"
34 #define REG (env->fpr[3])
35 #include "fop_template.h"
37 #define REG (env->fpr[4])
38 #include "fop_template.h"
40 #define REG (env->fpr[5])
41 #include "fop_template.h"
43 #define REG (env->fpr[6])
44 #include "fop_template.h"
46 #define REG (env->fpr[7])
47 #include "fop_template.h"
49 #define REG (env->fpr[8])
50 #include "fop_template.h"
52 #define REG (env->fpr[9])
53 #include "fop_template.h"
55 #define REG (env->fpr[10])
56 #include "fop_template.h"
58 #define REG (env->fpr[11])
59 #include "fop_template.h"
61 #define REG (env->fpr[12])
62 #include "fop_template.h"
64 #define REG (env->fpr[13])
65 #include "fop_template.h"
67 #define REG (env->fpr[14])
68 #include "fop_template.h"
70 #define REG (env->fpr[15])
71 #include "fop_template.h"
73 #define REG (env->fpr[16])
74 #include "fop_template.h"
76 #define REG (env->fpr[17])
77 #include "fop_template.h"
79 #define REG (env->fpr[18])
80 #include "fop_template.h"
82 #define REG (env->fpr[19])
83 #include "fop_template.h"
85 #define REG (env->fpr[20])
86 #include "fop_template.h"
88 #define REG (env->fpr[21])
89 #include "fop_template.h"
91 #define REG (env->fpr[22])
92 #include "fop_template.h"
94 #define REG (env->fpr[23])
95 #include "fop_template.h"
97 #define REG (env->fpr[24])
98 #include "fop_template.h"
100 #define REG (env->fpr[25])
101 #include "fop_template.h"
103 #define REG (env->fpr[26])
104 #include "fop_template.h"
106 #define REG (env->fpr[27])
107 #include "fop_template.h"
109 #define REG (env->fpr[28])
110 #include "fop_template.h"
112 #define REG (env->fpr[29])
113 #include "fop_template.h"
115 #define REG (env->fpr[30])
116 #include "fop_template.h"
118 #define REG (env->fpr[31])
119 #include "fop_template.h"
121 #ifdef TARGET_SPARC64
123 #define REG (env->fpr[32])
124 #include "fop_template.h"
126 #define REG (env->fpr[34])
127 #include "fop_template.h"
129 #define REG (env->fpr[36])
130 #include "fop_template.h"
132 #define REG (env->fpr[38])
133 #include "fop_template.h"
135 #define REG (env->fpr[40])
136 #include "fop_template.h"
138 #define REG (env->fpr[42])
139 #include "fop_template.h"
141 #define REG (env->fpr[44])
142 #include "fop_template.h"
144 #define REG (env->fpr[46])
145 #include "fop_template.h"
147 #define REG (env->fpr[47])
148 #include "fop_template.h"
150 #define REG (env->fpr[50])
151 #include "fop_template.h"
153 #define REG (env->fpr[52])
154 #include "fop_template.h"
156 #define REG (env->fpr[54])
157 #include "fop_template.h"
159 #define REG (env->fpr[56])
160 #include "fop_template.h"
162 #define REG (env->fpr[58])
163 #include "fop_template.h"
165 #define REG (env->fpr[60])
166 #include "fop_template.h"
168 #define REG (env->fpr[62])
169 #include "fop_template.h"
172 #ifdef TARGET_SPARC64
173 #define XFLAG_SET(x) ((env->xcc&x)?1:0)
176 #define FLAG_SET(x) ((env->psr&x)?1:0)
178 void OPPROTO
op_add_T1_T0_cc(void)
185 #ifdef TARGET_SPARC64
186 if (!(T0
& 0xffffffff))
187 env
->psr
|= PSR_ZERO
;
188 if ((int32_t) T0
< 0)
190 if ((T0
& 0xffffffff) < (src1
& 0xffffffff))
191 env
->psr
|= PSR_CARRY
;
192 if ((((src1
& 0xffffffff) ^ (T1
& 0xffffffff) ^ -1) &
193 ((src1
& 0xffffffff) ^ (T0
& 0xffffffff))) & (1 << 31))
198 env
->xcc
|= PSR_ZERO
;
199 if ((int64_t) T0
< 0)
202 env
->xcc
|= PSR_CARRY
;
203 if (((src1
^ T1
^ -1) & (src1
^ T0
)) & (1ULL << 63))
207 env
->psr
|= PSR_ZERO
;
208 if ((int32_t) T0
< 0)
211 env
->psr
|= PSR_CARRY
;
212 if (((src1
^ T1
^ -1) & (src1
^ T0
)) & (1 << 31))
218 void OPPROTO
op_addx_T1_T0_cc(void)
222 if (FLAG_SET(PSR_CARRY
))
226 #ifdef TARGET_SPARC64
227 if ((T0
& 0xffffffff) <= (src1
& 0xffffffff))
228 env
->psr
|= PSR_CARRY
;
231 env
->xcc
|= PSR_CARRY
;
234 env
->psr
|= PSR_CARRY
;
241 #ifdef TARGET_SPARC64
242 if ((T0
& 0xffffffff) < (src1
& 0xffffffff))
243 env
->psr
|= PSR_CARRY
;
246 env
->xcc
|= PSR_CARRY
;
249 env
->psr
|= PSR_CARRY
;
252 #ifdef TARGET_SPARC64
253 if (!(T0
& 0xffffffff))
254 env
->psr
|= PSR_ZERO
;
255 if ((int32_t) T0
< 0)
257 if ((((src1
& 0xffffffff) ^ (T1
& 0xffffffff) ^ -1) &
258 ((src1
& 0xffffffff) ^ (T0
& 0xffffffff))) & (1 << 31))
262 env
->xcc
|= PSR_ZERO
;
263 if ((int64_t) T0
< 0)
265 if (((src1
^ T1
^ -1) & (src1
^ T0
)) & (1ULL << 63))
269 env
->psr
|= PSR_ZERO
;
270 if ((int32_t) T0
< 0)
272 if (((src1
^ T1
^ -1) & (src1
^ T0
)) & (1 << 31))
278 void OPPROTO
op_tadd_T1_T0_cc(void)
285 #ifdef TARGET_SPARC64
286 if (!(T0
& 0xffffffff))
287 env
->psr
|= PSR_ZERO
;
288 if ((int32_t) T0
< 0)
290 if ((T0
& 0xffffffff) < (src1
& 0xffffffff))
291 env
->psr
|= PSR_CARRY
;
292 if ((((src1
& 0xffffffff) ^ (T1
& 0xffffffff) ^ -1) &
293 ((src1
& 0xffffffff) ^ (T0
& 0xffffffff))) & (1 << 31))
295 if ((src1
& 0x03) || (T1
& 0x03))
300 env
->xcc
|= PSR_ZERO
;
301 if ((int64_t) T0
< 0)
304 env
->xcc
|= PSR_CARRY
;
305 if (((src1
^ T1
^ -1) & (src1
^ T0
)) & (1ULL << 63))
309 env
->psr
|= PSR_ZERO
;
310 if ((int32_t) T0
< 0)
313 env
->psr
|= PSR_CARRY
;
314 if (((src1
^ T1
^ -1) & (src1
^ T0
)) & (1 << 31))
316 if ((src1
& 0x03) || (T1
& 0x03))
322 void OPPROTO
op_tadd_T1_T0_ccTV(void)
326 if ((T0
& 0x03) || (T1
& 0x03)) {
327 raise_exception(TT_TOVF
);
335 #ifdef TARGET_SPARC64
336 if ((((src1
& 0xffffffff) ^ (T1
& 0xffffffff) ^ -1) &
337 ((src1
& 0xffffffff) ^ (T0
& 0xffffffff))) & (1 << 31))
338 raise_exception(TT_TOVF
);
340 if (((src1
^ T1
^ -1) & (src1
^ T0
)) & (1 << 31))
341 raise_exception(TT_TOVF
);
345 #ifdef TARGET_SPARC64
346 if (!(T0
& 0xffffffff))
347 env
->psr
|= PSR_ZERO
;
348 if ((int32_t) T0
< 0)
350 if ((T0
& 0xffffffff) < (src1
& 0xffffffff))
351 env
->psr
|= PSR_CARRY
;
355 env
->xcc
|= PSR_ZERO
;
356 if ((int64_t) T0
< 0)
359 env
->xcc
|= PSR_CARRY
;
362 env
->psr
|= PSR_ZERO
;
363 if ((int32_t) T0
< 0)
366 env
->psr
|= PSR_CARRY
;
371 void OPPROTO
op_sub_T1_T0_cc(void)
378 #ifdef TARGET_SPARC64
379 if (!(T0
& 0xffffffff))
380 env
->psr
|= PSR_ZERO
;
381 if ((int32_t) T0
< 0)
383 if ((src1
& 0xffffffff) < (T1
& 0xffffffff))
384 env
->psr
|= PSR_CARRY
;
385 if ((((src1
& 0xffffffff) ^ (T1
& 0xffffffff)) &
386 ((src1
& 0xffffffff) ^ (T0
& 0xffffffff))) & (1 << 31))
391 env
->xcc
|= PSR_ZERO
;
392 if ((int64_t) T0
< 0)
395 env
->xcc
|= PSR_CARRY
;
396 if (((src1
^ T1
) & (src1
^ T0
)) & (1ULL << 63))
400 env
->psr
|= PSR_ZERO
;
401 if ((int32_t) T0
< 0)
404 env
->psr
|= PSR_CARRY
;
405 if (((src1
^ T1
) & (src1
^ T0
)) & (1 << 31))
411 void OPPROTO
op_subx_T1_T0_cc(void)
415 if (FLAG_SET(PSR_CARRY
))
419 #ifdef TARGET_SPARC64
420 if ((src1
& 0xffffffff) <= (T1
& 0xffffffff))
421 env
->psr
|= PSR_CARRY
;
424 env
->xcc
|= PSR_CARRY
;
427 env
->psr
|= PSR_CARRY
;
434 #ifdef TARGET_SPARC64
435 if ((src1
& 0xffffffff) < (T1
& 0xffffffff))
436 env
->psr
|= PSR_CARRY
;
439 env
->xcc
|= PSR_CARRY
;
442 env
->psr
|= PSR_CARRY
;
445 #ifdef TARGET_SPARC64
446 if (!(T0
& 0xffffffff))
447 env
->psr
|= PSR_ZERO
;
448 if ((int32_t) T0
< 0)
450 if ((((src1
& 0xffffffff) ^ (T1
& 0xffffffff)) &
451 ((src1
& 0xffffffff) ^ (T0
& 0xffffffff))) & (1 << 31))
455 env
->xcc
|= PSR_ZERO
;
456 if ((int64_t) T0
< 0)
458 if (((src1
^ T1
) & (src1
^ T0
)) & (1ULL << 63))
462 env
->psr
|= PSR_ZERO
;
463 if ((int32_t) T0
< 0)
465 if (((src1
^ T1
) & (src1
^ T0
)) & (1 << 31))
471 void OPPROTO
op_tsub_T1_T0_cc(void)
478 #ifdef TARGET_SPARC64
479 if (!(T0
& 0xffffffff))
480 env
->psr
|= PSR_ZERO
;
481 if ((int32_t) T0
< 0)
483 if ((src1
& 0xffffffff) < (T1
& 0xffffffff))
484 env
->psr
|= PSR_CARRY
;
485 if ((((src1
& 0xffffffff) ^ (T1
& 0xffffffff)) &
486 ((src1
& 0xffffffff) ^ (T0
& 0xffffffff))) & (1 << 31))
488 if ((src1
& 0x03) || (T1
& 0x03))
493 env
->xcc
|= PSR_ZERO
;
494 if ((int64_t) T0
< 0)
497 env
->xcc
|= PSR_CARRY
;
498 if (((src1
^ T1
) & (src1
^ T0
)) & (1ULL << 63))
502 env
->psr
|= PSR_ZERO
;
503 if ((int32_t) T0
< 0)
506 env
->psr
|= PSR_CARRY
;
507 if (((src1
^ T1
) & (src1
^ T0
)) & (1 << 31))
509 if ((src1
& 0x03) || (T1
& 0x03))
515 void OPPROTO
op_tsub_T1_T0_ccTV(void)
519 if ((T0
& 0x03) || (T1
& 0x03))
520 raise_exception(TT_TOVF
);
525 #ifdef TARGET_SPARC64
526 if ((((src1
& 0xffffffff) ^ (T1
& 0xffffffff)) &
527 ((src1
& 0xffffffff) ^ (T0
& 0xffffffff))) & (1 << 31))
528 raise_exception(TT_TOVF
);
530 if (((src1
^ T1
) & (src1
^ T0
)) & (1 << 31))
531 raise_exception(TT_TOVF
);
535 #ifdef TARGET_SPARC64
536 if (!(T0
& 0xffffffff))
537 env
->psr
|= PSR_ZERO
;
538 if ((int32_t) T0
< 0)
540 if ((src1
& 0xffffffff) < (T1
& 0xffffffff))
541 env
->psr
|= PSR_CARRY
;
545 env
->xcc
|= PSR_ZERO
;
546 if ((int64_t) T0
< 0)
549 env
->xcc
|= PSR_CARRY
;
552 env
->psr
|= PSR_ZERO
;
553 if ((int32_t) T0
< 0)
556 env
->psr
|= PSR_CARRY
;
561 void OPPROTO
op_andn_T1_T0(void)
566 void OPPROTO
op_orn_T1_T0(void)
571 void OPPROTO
op_xnor_T1_T0(void)
576 void OPPROTO
op_umul_T1_T0(void)
579 res
= (uint64_t) T0
* (uint64_t) T1
;
580 #ifdef TARGET_SPARC64
583 T0
= res
& 0xffffffff;
588 void OPPROTO
op_smul_T1_T0(void)
591 res
= (int64_t) ((int32_t) T0
) * (int64_t) ((int32_t) T1
);
592 #ifdef TARGET_SPARC64
595 T0
= res
& 0xffffffff;
600 void OPPROTO
op_mulscc_T1_T0(void)
602 unsigned int b1
, N
, V
, b2
;
605 N
= FLAG_SET(PSR_NEG
);
606 V
= FLAG_SET(PSR_OVF
);
609 T0
= (b1
<< 31) | (T0
>> 1);
612 /* do addition and update flags */
617 env
->psr
|= PSR_ZERO
;
618 if ((int32_t) T0
< 0)
621 env
->psr
|= PSR_CARRY
;
622 if (((src1
^ T1
^ -1) & (src1
^ T0
)) & (1 << 31))
624 env
->y
= (b2
<< 31) | (env
->y
>> 1);
628 void OPPROTO
op_udiv_T1_T0(void)
633 x0
= T0
| ((uint64_t) (env
->y
) << 32);
637 raise_exception(TT_DIV_ZERO
);
641 if (x0
> 0xffffffff) {
651 void OPPROTO
op_sdiv_T1_T0(void)
656 x0
= T0
| ((int64_t) (env
->y
) << 32);
660 raise_exception(TT_DIV_ZERO
);
664 if ((int32_t) x0
!= x0
) {
665 T0
= x0
< 0? 0x80000000: 0x7fffffff;
674 void OPPROTO
op_div_cc(void)
677 #ifdef TARGET_SPARC64
679 env
->psr
|= PSR_ZERO
;
680 if ((int32_t) T0
< 0)
687 env
->xcc
|= PSR_ZERO
;
688 if ((int64_t) T0
< 0)
692 env
->psr
|= PSR_ZERO
;
693 if ((int32_t) T0
< 0)
701 #ifdef TARGET_SPARC64
702 void OPPROTO
op_udivx_T1_T0(void)
705 raise_exception(TT_DIV_ZERO
);
711 void OPPROTO
op_sdivx_T1_T0(void)
714 raise_exception(TT_DIV_ZERO
);
716 if (T0
== INT64_MIN
&& T1
== -1)
719 T0
/= (target_long
) T1
;
724 void OPPROTO
op_logic_T0_cc(void)
727 #ifdef TARGET_SPARC64
728 if (!(T0
& 0xffffffff))
729 env
->psr
|= PSR_ZERO
;
730 if ((int32_t) T0
< 0)
735 env
->xcc
|= PSR_ZERO
;
736 if ((int64_t) T0
< 0)
740 env
->psr
|= PSR_ZERO
;
741 if ((int32_t) T0
< 0)
748 #define MEMSUFFIX _raw
750 #if !defined(CONFIG_USER_ONLY)
751 #define MEMSUFFIX _user
754 #define MEMSUFFIX _kernel
757 #ifdef TARGET_SPARC64
758 #define MEMSUFFIX _hypv
763 void OPPROTO
op_ldfsr(void)
765 PUT_FSR32(env
, *((uint32_t *) &FT0
));
769 void OPPROTO
op_stfsr(void)
771 *((uint32_t *) &FT0
) = GET_FSR32(env
);
774 #ifndef TARGET_SPARC64
775 /* XXX: use another pointer for %iN registers to avoid slow wrapping
777 void OPPROTO
op_save(void)
780 cwp
= (env
->cwp
- 1) & (NWINDOWS
- 1);
781 if (env
->wim
& (1 << cwp
)) {
782 raise_exception(TT_WIN_OVF
);
788 void OPPROTO
op_restore(void)
791 cwp
= (env
->cwp
+ 1) & (NWINDOWS
- 1);
792 if (env
->wim
& (1 << cwp
)) {
793 raise_exception(TT_WIN_UNF
);
799 void OPPROTO
op_rdccr(void)
804 void OPPROTO
op_wrccr(void)
809 void OPPROTO
op_rdtpc(void)
811 T0
= env
->tpc
[env
->tl
];
814 void OPPROTO
op_wrtpc(void)
816 env
->tpc
[env
->tl
] = T0
;
819 void OPPROTO
op_rdtnpc(void)
821 T0
= env
->tnpc
[env
->tl
];
824 void OPPROTO
op_wrtnpc(void)
826 env
->tnpc
[env
->tl
] = T0
;
829 void OPPROTO
op_rdtstate(void)
831 T0
= env
->tstate
[env
->tl
];
834 void OPPROTO
op_wrtstate(void)
836 env
->tstate
[env
->tl
] = T0
;
839 void OPPROTO
op_rdtt(void)
841 T0
= env
->tt
[env
->tl
];
844 void OPPROTO
op_wrtt(void)
846 env
->tt
[env
->tl
] = T0
;
849 // CWP handling is reversed in V9, but we still use the V8 register
851 void OPPROTO
op_rdcwp(void)
856 void OPPROTO
op_wrcwp(void)
861 /* XXX: use another pointer for %iN registers to avoid slow wrapping
863 void OPPROTO
op_save(void)
866 cwp
= (env
->cwp
- 1) & (NWINDOWS
- 1);
867 if (env
->cansave
== 0) {
868 raise_exception(TT_SPILL
| (env
->otherwin
!= 0 ?
869 (TT_WOTHER
| ((env
->wstate
& 0x38) >> 1)):
870 ((env
->wstate
& 0x7) << 2)));
872 if (env
->cleanwin
- env
->canrestore
== 0) {
873 // XXX Clean windows without trap
874 raise_exception(TT_CLRWIN
);
884 void OPPROTO
op_restore(void)
887 cwp
= (env
->cwp
+ 1) & (NWINDOWS
- 1);
888 if (env
->canrestore
== 0) {
889 raise_exception(TT_FILL
| (env
->otherwin
!= 0 ?
890 (TT_WOTHER
| ((env
->wstate
& 0x38) >> 1)):
891 ((env
->wstate
& 0x7) << 2)));
901 void OPPROTO
op_exception(void)
903 env
->exception_index
= PARAM1
;
908 void OPPROTO
op_fpexception_im(void)
910 env
->exception_index
= TT_FP_EXCP
;
911 env
->fsr
&= ~FSR_FTT_MASK
;
917 void OPPROTO
op_eval_ba(void)
922 void OPPROTO
op_eval_be(void)
924 T2
= FLAG_SET(PSR_ZERO
);
927 void OPPROTO
op_eval_ble(void)
929 target_ulong Z
= FLAG_SET(PSR_ZERO
), N
= FLAG_SET(PSR_NEG
), V
= FLAG_SET(PSR_OVF
);
934 void OPPROTO
op_eval_bl(void)
936 target_ulong N
= FLAG_SET(PSR_NEG
), V
= FLAG_SET(PSR_OVF
);
941 void OPPROTO
op_eval_bleu(void)
943 target_ulong Z
= FLAG_SET(PSR_ZERO
), C
= FLAG_SET(PSR_CARRY
);
948 void OPPROTO
op_eval_bcs(void)
950 T2
= FLAG_SET(PSR_CARRY
);
953 void OPPROTO
op_eval_bvs(void)
955 T2
= FLAG_SET(PSR_OVF
);
958 void OPPROTO
op_eval_bn(void)
963 void OPPROTO
op_eval_bneg(void)
965 T2
= FLAG_SET(PSR_NEG
);
968 void OPPROTO
op_eval_bne(void)
970 T2
= !FLAG_SET(PSR_ZERO
);
973 void OPPROTO
op_eval_bg(void)
975 target_ulong Z
= FLAG_SET(PSR_ZERO
), N
= FLAG_SET(PSR_NEG
), V
= FLAG_SET(PSR_OVF
);
980 void OPPROTO
op_eval_bge(void)
982 target_ulong N
= FLAG_SET(PSR_NEG
), V
= FLAG_SET(PSR_OVF
);
987 void OPPROTO
op_eval_bgu(void)
989 target_ulong Z
= FLAG_SET(PSR_ZERO
), C
= FLAG_SET(PSR_CARRY
);
994 void OPPROTO
op_eval_bcc(void)
996 T2
= !FLAG_SET(PSR_CARRY
);
999 void OPPROTO
op_eval_bpos(void)
1001 T2
= !FLAG_SET(PSR_NEG
);
1004 void OPPROTO
op_eval_bvc(void)
1006 T2
= !FLAG_SET(PSR_OVF
);
1009 #ifdef TARGET_SPARC64
1010 void OPPROTO
op_eval_xbe(void)
1012 T2
= XFLAG_SET(PSR_ZERO
);
1015 void OPPROTO
op_eval_xble(void)
1017 target_ulong Z
= XFLAG_SET(PSR_ZERO
), N
= XFLAG_SET(PSR_NEG
), V
= XFLAG_SET(PSR_OVF
);
1022 void OPPROTO
op_eval_xbl(void)
1024 target_ulong N
= XFLAG_SET(PSR_NEG
), V
= XFLAG_SET(PSR_OVF
);
1029 void OPPROTO
op_eval_xbleu(void)
1031 target_ulong Z
= XFLAG_SET(PSR_ZERO
), C
= XFLAG_SET(PSR_CARRY
);
1036 void OPPROTO
op_eval_xbcs(void)
1038 T2
= XFLAG_SET(PSR_CARRY
);
1041 void OPPROTO
op_eval_xbvs(void)
1043 T2
= XFLAG_SET(PSR_OVF
);
1046 void OPPROTO
op_eval_xbneg(void)
1048 T2
= XFLAG_SET(PSR_NEG
);
1051 void OPPROTO
op_eval_xbne(void)
1053 T2
= !XFLAG_SET(PSR_ZERO
);
1056 void OPPROTO
op_eval_xbg(void)
1058 target_ulong Z
= XFLAG_SET(PSR_ZERO
), N
= XFLAG_SET(PSR_NEG
), V
= XFLAG_SET(PSR_OVF
);
1060 T2
= !(Z
| (N
^ V
));
1063 void OPPROTO
op_eval_xbge(void)
1065 target_ulong N
= XFLAG_SET(PSR_NEG
), V
= XFLAG_SET(PSR_OVF
);
1070 void OPPROTO
op_eval_xbgu(void)
1072 target_ulong Z
= XFLAG_SET(PSR_ZERO
), C
= XFLAG_SET(PSR_CARRY
);
1077 void OPPROTO
op_eval_xbcc(void)
1079 T2
= !XFLAG_SET(PSR_CARRY
);
1082 void OPPROTO
op_eval_xbpos(void)
1084 T2
= !XFLAG_SET(PSR_NEG
);
1087 void OPPROTO
op_eval_xbvc(void)
1089 T2
= !XFLAG_SET(PSR_OVF
);
1094 #define FFLAG_SET(x) (env->fsr & x? 1: 0)
1095 #include "fbranch_template.h"
1097 #ifdef TARGET_SPARC64
1099 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
1100 #include "fbranch_template.h"
1102 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
1103 #include "fbranch_template.h"
1105 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
1106 #include "fbranch_template.h"
1109 #ifdef TARGET_SPARC64
1110 void OPPROTO
op_eval_brz(void)
1115 void OPPROTO
op_eval_brnz(void)
1120 void OPPROTO
op_eval_brlz(void)
1122 T2
= ((int64_t)T0
< 0);
1125 void OPPROTO
op_eval_brlez(void)
1127 T2
= ((int64_t)T0
<= 0);
1130 void OPPROTO
op_eval_brgz(void)
1132 T2
= ((int64_t)T0
> 0);
1135 void OPPROTO
op_eval_brgez(void)
1137 T2
= ((int64_t)T0
>= 0);
1141 void OPPROTO
op_jmp_label(void)
1143 GOTO_LABEL_PARAM(1);
1146 void OPPROTO
op_jnz_T2_label(void)
1149 GOTO_LABEL_PARAM(1);
1153 void OPPROTO
op_jz_T2_label(void)
1156 GOTO_LABEL_PARAM(1);
1160 void OPPROTO
op_clear_ieee_excp_and_FTT(void)
1162 env
->fsr
&= ~(FSR_FTT_MASK
| FSR_CEXC_MASK
);;
1165 #define F_OP(name, p) void OPPROTO op_f##name##p(void)
1167 #if defined(CONFIG_USER_ONLY)
1168 #define F_BINOP(name) \
1171 set_float_exception_flags(0, &env->fp_status); \
1172 FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
1173 check_ieee_exceptions(); \
1177 set_float_exception_flags(0, &env->fp_status); \
1178 DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
1179 check_ieee_exceptions(); \
1183 set_float_exception_flags(0, &env->fp_status); \
1184 QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \
1185 check_ieee_exceptions(); \
1188 #define F_BINOP(name) \
1191 set_float_exception_flags(0, &env->fp_status); \
1192 FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
1193 check_ieee_exceptions(); \
1197 set_float_exception_flags(0, &env->fp_status); \
1198 DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
1199 check_ieee_exceptions(); \
1209 void OPPROTO
op_fsmuld(void)
1211 set_float_exception_flags(0, &env
->fp_status
);
1212 DT0
= float64_mul(float32_to_float64(FT0
, &env
->fp_status
),
1213 float32_to_float64(FT1
, &env
->fp_status
),
1215 check_ieee_exceptions();
1218 #if defined(CONFIG_USER_ONLY)
1219 void OPPROTO
op_fdmulq(void)
1221 set_float_exception_flags(0, &env
->fp_status
);
1222 QT0
= float128_mul(float64_to_float128(DT0
, &env
->fp_status
),
1223 float64_to_float128(DT1
, &env
->fp_status
),
1225 check_ieee_exceptions();
1229 #if defined(CONFIG_USER_ONLY)
1230 #define F_HELPER(name) \
1244 #define F_HELPER(name) \
1259 FT0
= float32_chs(FT1
);
1270 #ifdef TARGET_SPARC64
1273 DT0
= float64_chs(DT1
);
1281 #if defined(CONFIG_USER_ONLY)
1284 QT0
= float128_chs(QT1
);
1293 void OPPROTO
op_fcmps_fcc1(void)
1298 void OPPROTO
op_fcmpd_fcc1(void)
1303 void OPPROTO
op_fcmps_fcc2(void)
1308 void OPPROTO
op_fcmpd_fcc2(void)
1313 void OPPROTO
op_fcmps_fcc3(void)
1318 void OPPROTO
op_fcmpd_fcc3(void)
1323 void OPPROTO
op_fcmpes_fcc1(void)
1328 void OPPROTO
op_fcmped_fcc1(void)
1333 void OPPROTO
op_fcmpes_fcc2(void)
1338 void OPPROTO
op_fcmped_fcc2(void)
1343 void OPPROTO
op_fcmpes_fcc3(void)
1348 void OPPROTO
op_fcmped_fcc3(void)
1353 #if defined(CONFIG_USER_ONLY)
1354 void OPPROTO
op_fcmpq_fcc1(void)
1359 void OPPROTO
op_fcmpq_fcc2(void)
1364 void OPPROTO
op_fcmpq_fcc3(void)
1369 void OPPROTO
op_fcmpeq_fcc1(void)
1374 void OPPROTO
op_fcmpeq_fcc2(void)
1379 void OPPROTO
op_fcmpeq_fcc3(void)
1387 /* Integer to float conversion. */
1388 #ifdef USE_INT_TO_FLOAT_HELPERS
1390 #ifdef TARGET_SPARC64
1396 set_float_exception_flags(0, &env
->fp_status
);
1397 FT0
= int32_to_float32(*((int32_t *)&FT1
), &env
->fp_status
);
1398 check_ieee_exceptions();
1403 set_float_exception_flags(0, &env
->fp_status
);
1404 DT0
= int32_to_float64(*((int32_t *)&FT1
), &env
->fp_status
);
1405 check_ieee_exceptions();
1408 #if defined(CONFIG_USER_ONLY)
1411 set_float_exception_flags(0, &env
->fp_status
);
1412 QT0
= int32_to_float128(*((int32_t *)&FT1
), &env
->fp_status
);
1413 check_ieee_exceptions();
1417 #ifdef TARGET_SPARC64
1420 set_float_exception_flags(0, &env
->fp_status
);
1421 FT0
= int64_to_float32(*((int64_t *)&DT1
), &env
->fp_status
);
1422 check_ieee_exceptions();
1427 set_float_exception_flags(0, &env
->fp_status
);
1428 DT0
= int64_to_float64(*((int64_t *)&DT1
), &env
->fp_status
);
1429 check_ieee_exceptions();
1431 #if defined(CONFIG_USER_ONLY)
1434 set_float_exception_flags(0, &env
->fp_status
);
1435 QT0
= int64_to_float128(*((int64_t *)&DT1
), &env
->fp_status
);
1436 check_ieee_exceptions();
1443 /* floating point conversion */
1444 void OPPROTO
op_fdtos(void)
1446 set_float_exception_flags(0, &env
->fp_status
);
1447 FT0
= float64_to_float32(DT1
, &env
->fp_status
);
1448 check_ieee_exceptions();
1451 void OPPROTO
op_fstod(void)
1453 set_float_exception_flags(0, &env
->fp_status
);
1454 DT0
= float32_to_float64(FT1
, &env
->fp_status
);
1455 check_ieee_exceptions();
1458 #if defined(CONFIG_USER_ONLY)
1459 void OPPROTO
op_fqtos(void)
1461 set_float_exception_flags(0, &env
->fp_status
);
1462 FT0
= float128_to_float32(QT1
, &env
->fp_status
);
1463 check_ieee_exceptions();
1466 void OPPROTO
op_fstoq(void)
1468 set_float_exception_flags(0, &env
->fp_status
);
1469 QT0
= float32_to_float128(FT1
, &env
->fp_status
);
1470 check_ieee_exceptions();
1473 void OPPROTO
op_fqtod(void)
1475 set_float_exception_flags(0, &env
->fp_status
);
1476 DT0
= float128_to_float64(QT1
, &env
->fp_status
);
1477 check_ieee_exceptions();
1480 void OPPROTO
op_fdtoq(void)
1482 set_float_exception_flags(0, &env
->fp_status
);
1483 QT0
= float64_to_float128(DT1
, &env
->fp_status
);
1484 check_ieee_exceptions();
1488 /* Float to integer conversion. */
1489 void OPPROTO
op_fstoi(void)
1491 set_float_exception_flags(0, &env
->fp_status
);
1492 *((int32_t *)&FT0
) = float32_to_int32_round_to_zero(FT1
, &env
->fp_status
);
1493 check_ieee_exceptions();
1496 void OPPROTO
op_fdtoi(void)
1498 set_float_exception_flags(0, &env
->fp_status
);
1499 *((int32_t *)&FT0
) = float64_to_int32_round_to_zero(DT1
, &env
->fp_status
);
1500 check_ieee_exceptions();
1503 #if defined(CONFIG_USER_ONLY)
1504 void OPPROTO
op_fqtoi(void)
1506 set_float_exception_flags(0, &env
->fp_status
);
1507 *((int32_t *)&FT0
) = float128_to_int32_round_to_zero(QT1
, &env
->fp_status
);
1508 check_ieee_exceptions();
1512 #ifdef TARGET_SPARC64
1513 void OPPROTO
op_fstox(void)
1515 set_float_exception_flags(0, &env
->fp_status
);
1516 *((int64_t *)&DT0
) = float32_to_int64_round_to_zero(FT1
, &env
->fp_status
);
1517 check_ieee_exceptions();
1520 void OPPROTO
op_fdtox(void)
1522 set_float_exception_flags(0, &env
->fp_status
);
1523 *((int64_t *)&DT0
) = float64_to_int64_round_to_zero(DT1
, &env
->fp_status
);
1524 check_ieee_exceptions();
1527 #if defined(CONFIG_USER_ONLY)
1528 void OPPROTO
op_fqtox(void)
1530 set_float_exception_flags(0, &env
->fp_status
);
1531 *((int64_t *)&DT0
) = float128_to_int64_round_to_zero(QT1
, &env
->fp_status
);
1532 check_ieee_exceptions();
1536 void OPPROTO
op_fmovs_cc(void)
1542 void OPPROTO
op_fmovd_cc(void)
1548 #if defined(CONFIG_USER_ONLY)
1549 void OPPROTO
op_fmovq_cc(void)
1556 void OPPROTO
op_flushw(void)
1558 if (env
->cansave
!= NWINDOWS
- 2) {
1559 raise_exception(TT_SPILL
| (env
->otherwin
!= 0 ?
1560 (TT_WOTHER
| ((env
->wstate
& 0x38) >> 1)):
1561 ((env
->wstate
& 0x7) << 2)));
1565 void OPPROTO
op_saved(void)
1568 if (env
->otherwin
== 0)
1575 void OPPROTO
op_restored(void)
1578 if (env
->cleanwin
< NWINDOWS
- 1)
1580 if (env
->otherwin
== 0)
1588 #ifdef TARGET_SPARC64
1589 // This function uses non-native bit order
1590 #define GET_FIELD(X, FROM, TO) \
1591 ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
1593 // This function uses the order in the manuals, i.e. bit 0 is 2^0
1594 #define GET_FIELD_SP(X, FROM, TO) \
1595 GET_FIELD(X, 63 - (TO), 63 - (FROM))
1597 void OPPROTO
op_array8()
1599 T0
= (GET_FIELD_SP(T0
, 60, 63) << (17 + 2 * T1
)) |
1600 (GET_FIELD_SP(T0
, 39, 39 + T1
- 1) << (17 + T1
)) |
1601 (GET_FIELD_SP(T0
, 17 + T1
- 1, 17) << 17) |
1602 (GET_FIELD_SP(T0
, 56, 59) << 13) | (GET_FIELD_SP(T0
, 35, 38) << 9) |
1603 (GET_FIELD_SP(T0
, 13, 16) << 5) | (((T0
>> 55) & 1) << 4) |
1604 (GET_FIELD_SP(T0
, 33, 34) << 2) | GET_FIELD_SP(T0
, 11, 12);
1607 void OPPROTO
op_array16()
1609 T0
= ((GET_FIELD_SP(T0
, 60, 63) << (17 + 2 * T1
)) |
1610 (GET_FIELD_SP(T0
, 39, 39 + T1
- 1) << (17 + T1
)) |
1611 (GET_FIELD_SP(T0
, 17 + T1
- 1, 17) << 17) |
1612 (GET_FIELD_SP(T0
, 56, 59) << 13) | (GET_FIELD_SP(T0
, 35, 38) << 9) |
1613 (GET_FIELD_SP(T0
, 13, 16) << 5) | (((T0
>> 55) & 1) << 4) |
1614 (GET_FIELD_SP(T0
, 33, 34) << 2) | GET_FIELD_SP(T0
, 11, 12)) << 1;
1617 void OPPROTO
op_array32()
1619 T0
= ((GET_FIELD_SP(T0
, 60, 63) << (17 + 2 * T1
)) |
1620 (GET_FIELD_SP(T0
, 39, 39 + T1
- 1) << (17 + T1
)) |
1621 (GET_FIELD_SP(T0
, 17 + T1
- 1, 17) << 17) |
1622 (GET_FIELD_SP(T0
, 56, 59) << 13) | (GET_FIELD_SP(T0
, 35, 38) << 9) |
1623 (GET_FIELD_SP(T0
, 13, 16) << 5) | (((T0
>> 55) & 1) << 4) |
1624 (GET_FIELD_SP(T0
, 33, 34) << 2) | GET_FIELD_SP(T0
, 11, 12)) << 2;
1627 void OPPROTO
op_alignaddr()
1633 env
->gsr
|= tmp
& 7ULL;
1637 void OPPROTO
op_faligndata()
1641 tmp
= (*((uint64_t *)&DT0
)) << ((env
->gsr
& 7) * 8);
1642 tmp
|= (*((uint64_t *)&DT1
)) >> (64 - (env
->gsr
& 7) * 8);
1643 *((uint64_t *)&DT0
) = tmp
;
1646 void OPPROTO
op_movl_FT0_0(void)
1648 *((uint32_t *)&FT0
) = 0;
1651 void OPPROTO
op_movl_DT0_0(void)
1653 *((uint64_t *)&DT0
) = 0;
1656 void OPPROTO
op_movl_FT0_1(void)
1658 *((uint32_t *)&FT0
) = 0xffffffff;
1661 void OPPROTO
op_movl_DT0_1(void)
1663 *((uint64_t *)&DT0
) = 0xffffffffffffffffULL
;
1666 void OPPROTO
op_fnot(void)
1668 *(uint64_t *)&DT0
= ~*(uint64_t *)&DT1
;
1671 void OPPROTO
op_fnots(void)
1673 *(uint32_t *)&FT0
= ~*(uint32_t *)&FT1
;
1676 void OPPROTO
op_fnor(void)
1678 *(uint64_t *)&DT0
= ~(*(uint64_t *)&DT0
| *(uint64_t *)&DT1
);
1681 void OPPROTO
op_fnors(void)
1683 *(uint32_t *)&FT0
= ~(*(uint32_t *)&FT0
| *(uint32_t *)&FT1
);
1686 void OPPROTO
op_for(void)
1688 *(uint64_t *)&DT0
|= *(uint64_t *)&DT1
;
1691 void OPPROTO
op_fors(void)
1693 *(uint32_t *)&FT0
|= *(uint32_t *)&FT1
;
1696 void OPPROTO
op_fxor(void)
1698 *(uint64_t *)&DT0
^= *(uint64_t *)&DT1
;
1701 void OPPROTO
op_fxors(void)
1703 *(uint32_t *)&FT0
^= *(uint32_t *)&FT1
;
1706 void OPPROTO
op_fand(void)
1708 *(uint64_t *)&DT0
&= *(uint64_t *)&DT1
;
1711 void OPPROTO
op_fands(void)
1713 *(uint32_t *)&FT0
&= *(uint32_t *)&FT1
;
1716 void OPPROTO
op_fornot(void)
1718 *(uint64_t *)&DT0
= *(uint64_t *)&DT0
| ~*(uint64_t *)&DT1
;
1721 void OPPROTO
op_fornots(void)
1723 *(uint32_t *)&FT0
= *(uint32_t *)&FT0
| ~*(uint32_t *)&FT1
;
1726 void OPPROTO
op_fandnot(void)
1728 *(uint64_t *)&DT0
= *(uint64_t *)&DT0
& ~*(uint64_t *)&DT1
;
1731 void OPPROTO
op_fandnots(void)
1733 *(uint32_t *)&FT0
= *(uint32_t *)&FT0
& ~*(uint32_t *)&FT1
;
1736 void OPPROTO
op_fnand(void)
1738 *(uint64_t *)&DT0
= ~(*(uint64_t *)&DT0
& *(uint64_t *)&DT1
);
1741 void OPPROTO
op_fnands(void)
1743 *(uint32_t *)&FT0
= ~(*(uint32_t *)&FT0
& *(uint32_t *)&FT1
);
1746 void OPPROTO
op_fxnor(void)
1748 *(uint64_t *)&DT0
^= ~*(uint64_t *)&DT1
;
1751 void OPPROTO
op_fxnors(void)
1753 *(uint32_t *)&FT0
^= ~*(uint32_t *)&FT1
;
1756 #ifdef WORDS_BIGENDIAN
1757 #define VIS_B64(n) b[7 - (n)]
1758 #define VIS_W64(n) w[3 - (n)]
1759 #define VIS_SW64(n) sw[3 - (n)]
1760 #define VIS_L64(n) l[1 - (n)]
1761 #define VIS_B32(n) b[3 - (n)]
1762 #define VIS_W32(n) w[1 - (n)]
1764 #define VIS_B64(n) b[n]
1765 #define VIS_W64(n) w[n]
1766 #define VIS_SW64(n) sw[n]
1767 #define VIS_L64(n) l[n]
1768 #define VIS_B32(n) b[n]
1769 #define VIS_W32(n) w[n]
1787 void OPPROTO
op_fpmerge(void)
1794 // Reverse calculation order to handle overlap
1795 d
.VIS_B64(7) = s
.VIS_B64(3);
1796 d
.VIS_B64(6) = d
.VIS_B64(3);
1797 d
.VIS_B64(5) = s
.VIS_B64(2);
1798 d
.VIS_B64(4) = d
.VIS_B64(2);
1799 d
.VIS_B64(3) = s
.VIS_B64(1);
1800 d
.VIS_B64(2) = d
.VIS_B64(1);
1801 d
.VIS_B64(1) = s
.VIS_B64(0);
1802 //d.VIS_B64(0) = d.VIS_B64(0);
1807 void OPPROTO
op_fmul8x16(void)
1816 tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r); \
1817 if ((tmp & 0xff) > 0x7f) \
1819 d.VIS_W64(r) = tmp >> 8;
1830 void OPPROTO
op_fmul8x16al(void)
1839 tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r); \
1840 if ((tmp & 0xff) > 0x7f) \
1842 d.VIS_W64(r) = tmp >> 8;
1853 void OPPROTO
op_fmul8x16au(void)
1862 tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r); \
1863 if ((tmp & 0xff) > 0x7f) \
1865 d.VIS_W64(r) = tmp >> 8;
1876 void OPPROTO
op_fmul8sux16(void)
1885 tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
1886 if ((tmp & 0xff) > 0x7f) \
1888 d.VIS_W64(r) = tmp >> 8;
1899 void OPPROTO
op_fmul8ulx16(void)
1908 tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
1909 if ((tmp & 0xff) > 0x7f) \
1911 d.VIS_W64(r) = tmp >> 8;
1922 void OPPROTO
op_fmuld8sux16(void)
1931 tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
1932 if ((tmp & 0xff) > 0x7f) \
1936 // Reverse calculation order to handle overlap
1944 void OPPROTO
op_fmuld8ulx16(void)
1953 tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
1954 if ((tmp & 0xff) > 0x7f) \
1958 // Reverse calculation order to handle overlap
1966 void OPPROTO
op_fexpand(void)
1971 s
.l
= (uint32_t)(*(uint64_t *)&DT0
& 0xffffffff);
1973 d
.VIS_L64(0) = s
.VIS_W32(0) << 4;
1974 d
.VIS_L64(1) = s
.VIS_W32(1) << 4;
1975 d
.VIS_L64(2) = s
.VIS_W32(2) << 4;
1976 d
.VIS_L64(3) = s
.VIS_W32(3) << 4;
1981 #define VIS_OP(name, F) \
1982 void OPPROTO name##16(void) \
1989 d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0)); \
1990 d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1)); \
1991 d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2)); \
1992 d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3)); \
1997 void OPPROTO name##16s(void) \
2004 d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0)); \
2005 d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1)); \
2010 void OPPROTO name##32(void) \
2017 d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0)); \
2018 d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1)); \
2023 void OPPROTO name##32s(void) \
2030 d.l = F(d.l, s.l); \
2035 #define FADD(a, b) ((a) + (b))
2036 #define FSUB(a, b) ((a) - (b))
2037 VIS_OP(op_fpadd
, FADD
)
2038 VIS_OP(op_fpsub
, FSUB
)
2040 #define VIS_CMPOP(name, F) \
2041 void OPPROTO name##16(void) \
2048 d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0; \
2049 d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0; \
2050 d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0; \
2051 d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0; \
2056 void OPPROTO name##32(void) \
2063 d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0; \
2064 d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0; \
2069 #define FCMPGT(a, b) ((a) > (b))
2070 #define FCMPEQ(a, b) ((a) == (b))
2071 #define FCMPLE(a, b) ((a) <= (b))
2072 #define FCMPNE(a, b) ((a) != (b))
2074 VIS_CMPOP(op_fcmpgt
, FCMPGT
)
2075 VIS_CMPOP(op_fcmpeq
, FCMPEQ
)
2076 VIS_CMPOP(op_fcmple
, FCMPLE
)
2077 VIS_CMPOP(op_fcmpne
, FCMPNE
)
2081 #define CHECK_ALIGN_OP(align) \
2082 void OPPROTO op_check_align_T0_ ## align (void) \
2085 raise_exception(TT_UNALIGNED); \