PCI device saving for GT64xxx.
[qemu] / 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
526     src1 = T0;
527     T0 += T1;
528
529 #ifdef TARGET_SPARC64
530     if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
531          ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
532         raise_exception(TT_TOVF);
533 #else
534     if ((src1 & 0x03) || (T1 & 0x03))
535         raise_exception(TT_TOVF);
536 #endif
537
538     env->psr = 0;
539 #ifdef TARGET_SPARC64
540     if (!(T0 & 0xffffffff))
541         env->psr |= PSR_ZERO;
542     if ((int32_t) T0 < 0)
543         env->psr |= PSR_NEG;
544     if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
545         env->psr |= PSR_CARRY;
546
547     env->xcc = 0;
548     if (!T0)
549         env->xcc |= PSR_ZERO;
550     if ((int64_t) T0 < 0)
551         env->xcc |= PSR_NEG;
552     if (T0 < src1)
553         env->xcc |= PSR_CARRY;
554 #else
555     if (!T0)
556         env->psr |= PSR_ZERO;
557     if ((int32_t) T0 < 0)
558         env->psr |= PSR_NEG;
559     if (T0 < src1)
560         env->psr |= PSR_CARRY;
561 #endif
562     FORCE_RET();
563 }
564
565 void OPPROTO op_sub_T1_T0(void)
566 {
567     T0 -= T1;
568 }
569
570 void OPPROTO op_sub_T1_T0_cc(void)
571 {
572     target_ulong src1;
573
574     src1 = T0;
575     T0 -= T1;
576     env->psr = 0;
577 #ifdef TARGET_SPARC64
578     if (!(T0 & 0xffffffff))
579         env->psr |= PSR_ZERO;
580     if ((int32_t) T0 < 0)
581         env->psr |= PSR_NEG;
582     if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
583         env->psr |= PSR_CARRY;
584     if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
585          ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
586         env->psr |= PSR_OVF;
587
588     env->xcc = 0;
589     if (!T0)
590         env->xcc |= PSR_ZERO;
591     if ((int64_t) T0 < 0)
592         env->xcc |= PSR_NEG;
593     if (src1 < T1)
594         env->xcc |= PSR_CARRY;
595     if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
596         env->xcc |= PSR_OVF;
597 #else
598     if (!T0)
599         env->psr |= PSR_ZERO;
600     if ((int32_t) T0 < 0)
601         env->psr |= PSR_NEG;
602     if (src1 < T1)
603         env->psr |= PSR_CARRY;
604     if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
605         env->psr |= PSR_OVF;
606 #endif
607     FORCE_RET();
608 }
609
610 void OPPROTO op_subx_T1_T0(void)
611 {
612     T0 -= T1 + FLAG_SET(PSR_CARRY);
613 }
614
615 void OPPROTO op_subx_T1_T0_cc(void)
616 {
617     target_ulong src1;
618     src1 = T0;
619     if (FLAG_SET(PSR_CARRY))
620     {
621       T0 -= T1 + 1;
622       env->psr = 0;
623 #ifdef TARGET_SPARC64
624       if ((src1 & 0xffffffff) <= (T1 & 0xffffffff))
625         env->psr |= PSR_CARRY;
626       env->xcc = 0;
627       if (src1 <= T1)
628         env->xcc |= PSR_CARRY;
629 #else
630       if (src1 <= T1)
631         env->psr |= PSR_CARRY;
632 #endif
633     }
634     else
635     {
636       T0 -= T1;
637       env->psr = 0;
638 #ifdef TARGET_SPARC64
639       if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
640         env->psr |= PSR_CARRY;
641       env->xcc = 0;
642       if (src1 < T1)
643         env->xcc |= PSR_CARRY;
644 #else
645       if (src1 < T1)
646         env->psr |= PSR_CARRY;
647 #endif
648     }
649 #ifdef TARGET_SPARC64
650     if (!(T0 & 0xffffffff))
651         env->psr |= PSR_ZERO;
652     if ((int32_t) T0 < 0)
653         env->psr |= PSR_NEG;
654     if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
655          ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
656         env->psr |= PSR_OVF;
657
658     if (!T0)
659         env->xcc |= PSR_ZERO;
660     if ((int64_t) T0 < 0)
661         env->xcc |= PSR_NEG;
662     if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
663         env->xcc |= PSR_OVF;
664 #else
665     if (!T0)
666         env->psr |= PSR_ZERO;
667     if ((int32_t) T0 < 0)
668         env->psr |= PSR_NEG;
669     if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
670         env->psr |= PSR_OVF;
671 #endif
672     FORCE_RET();
673 }
674
675 void OPPROTO op_tsub_T1_T0_cc(void)
676 {
677     target_ulong src1;
678
679     src1 = T0;
680     T0 -= T1;
681     env->psr = 0;
682 #ifdef TARGET_SPARC64
683     if (!(T0 & 0xffffffff))
684         env->psr |= PSR_ZERO;
685     if ((int32_t) T0 < 0)
686         env->psr |= PSR_NEG;
687     if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
688         env->psr |= PSR_CARRY;
689     if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
690          ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
691         env->psr |= PSR_OVF;
692     if ((src1 & 0x03) || (T1 & 0x03))
693         env->psr |= PSR_OVF;
694
695     env->xcc = 0;
696     if (!T0)
697         env->xcc |= PSR_ZERO;
698     if ((int64_t) T0 < 0)
699         env->xcc |= PSR_NEG;
700     if (src1 < T1)
701         env->xcc |= PSR_CARRY;
702     if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
703         env->xcc |= PSR_OVF;
704 #else
705     if (!T0)
706         env->psr |= PSR_ZERO;
707     if ((int32_t) T0 < 0)
708         env->psr |= PSR_NEG;
709     if (src1 < T1)
710         env->psr |= PSR_CARRY;
711     if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
712         env->psr |= PSR_OVF;
713     if ((src1 & 0x03) || (T1 & 0x03))
714         env->psr |= PSR_OVF;
715 #endif
716     FORCE_RET();
717 }
718
719 void OPPROTO op_tsub_T1_T0_ccTV(void)
720 {
721     target_ulong src1;
722
723     if ((T0 & 0x03) || (T1 & 0x03))
724         raise_exception(TT_TOVF);
725
726     src1 = T0;
727     T0 -= T1;
728
729 #ifdef TARGET_SPARC64
730     if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
731          ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
732         raise_exception(TT_TOVF);
733 #else
734     if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
735         raise_exception(TT_TOVF);
736 #endif
737
738     env->psr = 0;
739 #ifdef TARGET_SPARC64
740     if (!(T0 & 0xffffffff))
741         env->psr |= PSR_ZERO;
742     if ((int32_t) T0 < 0)
743         env->psr |= PSR_NEG;
744     if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
745         env->psr |= PSR_CARRY;
746
747     env->xcc = 0;
748     if (!T0)
749         env->xcc |= PSR_ZERO;
750     if ((int64_t) T0 < 0)
751         env->xcc |= PSR_NEG;
752     if (src1 < T1)
753         env->xcc |= PSR_CARRY;
754 #else
755     if (!T0)
756         env->psr |= PSR_ZERO;
757     if ((int32_t) T0 < 0)
758         env->psr |= PSR_NEG;
759     if (src1 < T1)
760         env->psr |= PSR_CARRY;
761 #endif
762     FORCE_RET();
763 }
764
765 void OPPROTO op_and_T1_T0(void)
766 {
767     T0 &= T1;
768 }
769
770 void OPPROTO op_or_T1_T0(void)
771 {
772     T0 |= T1;
773 }
774
775 void OPPROTO op_xor_T1_T0(void)
776 {
777     T0 ^= T1;
778 }
779
780 void OPPROTO op_andn_T1_T0(void)
781 {
782     T0 &= ~T1;
783 }
784
785 void OPPROTO op_orn_T1_T0(void)
786 {
787     T0 |= ~T1;
788 }
789
790 void OPPROTO op_xnor_T1_T0(void)
791 {
792     T0 ^= ~T1;
793 }
794
795 void OPPROTO op_umul_T1_T0(void)
796 {
797     uint64_t res;
798     res = (uint64_t) T0 * (uint64_t) T1;
799 #ifdef TARGET_SPARC64
800     T0 = res;
801 #else
802     T0 = res & 0xffffffff;
803 #endif
804     env->y = res >> 32;
805 }
806
807 void OPPROTO op_smul_T1_T0(void)
808 {
809     uint64_t res;
810     res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
811 #ifdef TARGET_SPARC64
812     T0 = res;
813 #else
814     T0 = res & 0xffffffff;
815 #endif
816     env->y = res >> 32;
817 }
818
819 void OPPROTO op_mulscc_T1_T0(void)
820 {
821     unsigned int b1, N, V, b2;
822     target_ulong src1;
823
824     N = FLAG_SET(PSR_NEG);
825     V = FLAG_SET(PSR_OVF);
826     b1 = N ^ V;
827     b2 = T0 & 1;
828     T0 = (b1 << 31) | (T0 >> 1);
829     if (!(env->y & 1))
830         T1 = 0;
831     /* do addition and update flags */
832     src1 = T0;
833     T0 += T1;
834     env->psr = 0;
835     if (!T0)
836         env->psr |= PSR_ZERO;
837     if ((int32_t) T0 < 0)
838         env->psr |= PSR_NEG;
839     if (T0 < src1)
840         env->psr |= PSR_CARRY;
841     if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
842         env->psr |= PSR_OVF;
843     env->y = (b2 << 31) | (env->y >> 1);
844     FORCE_RET();
845 }
846
847 void OPPROTO op_udiv_T1_T0(void)
848 {
849     uint64_t x0;
850     uint32_t x1;
851
852     x0 = T0 | ((uint64_t) (env->y) << 32);
853     x1 = T1;
854
855     if (x1 == 0) {
856         raise_exception(TT_DIV_ZERO);
857     }
858
859     x0 = x0 / x1;
860     if (x0 > 0xffffffff) {
861         T0 = 0xffffffff;
862         T1 = 1;
863     } else {
864         T0 = x0;
865         T1 = 0;
866     }
867     FORCE_RET();
868 }
869
870 void OPPROTO op_sdiv_T1_T0(void)
871 {
872     int64_t x0;
873     int32_t x1;
874
875     x0 = T0 | ((int64_t) (env->y) << 32);
876     x1 = T1;
877
878     if (x1 == 0) {
879         raise_exception(TT_DIV_ZERO);
880     }
881
882     x0 = x0 / x1;
883     if ((int32_t) x0 != x0) {
884         T0 = x0 < 0? 0x80000000: 0x7fffffff;
885         T1 = 1;
886     } else {
887         T0 = x0;
888         T1 = 0;
889     }
890     FORCE_RET();
891 }
892
893 void OPPROTO op_div_cc(void)
894 {
895     env->psr = 0;
896 #ifdef TARGET_SPARC64
897     if (!T0)
898         env->psr |= PSR_ZERO;
899     if ((int32_t) T0 < 0)
900         env->psr |= PSR_NEG;
901     if (T1)
902         env->psr |= PSR_OVF;
903
904     env->xcc = 0;
905     if (!T0)
906         env->xcc |= PSR_ZERO;
907     if ((int64_t) T0 < 0)
908         env->xcc |= PSR_NEG;
909 #else
910     if (!T0)
911         env->psr |= PSR_ZERO;
912     if ((int32_t) T0 < 0)
913         env->psr |= PSR_NEG;
914     if (T1)
915         env->psr |= PSR_OVF;
916 #endif
917     FORCE_RET();
918 }
919
920 #ifdef TARGET_SPARC64
921 void OPPROTO op_mulx_T1_T0(void)
922 {
923     T0 *= T1;
924     FORCE_RET();
925 }
926
927 void OPPROTO op_udivx_T1_T0(void)
928 {
929     if (T1 == 0) {
930         raise_exception(TT_DIV_ZERO);
931     }
932     T0 /= T1;
933     FORCE_RET();
934 }
935
936 void OPPROTO op_sdivx_T1_T0(void)
937 {
938     if (T1 == 0) {
939         raise_exception(TT_DIV_ZERO);
940     }
941     if (T0 == INT64_MIN && T1 == -1)
942         T0 = INT64_MIN;
943     else
944         T0 /= (target_long) T1;
945     FORCE_RET();
946 }
947 #endif
948
949 void OPPROTO op_logic_T0_cc(void)
950 {
951     env->psr = 0;
952 #ifdef TARGET_SPARC64
953     if (!(T0 & 0xffffffff))
954         env->psr |= PSR_ZERO;
955     if ((int32_t) T0 < 0)
956         env->psr |= PSR_NEG;
957
958     env->xcc = 0;
959     if (!T0)
960         env->xcc |= PSR_ZERO;
961     if ((int64_t) T0 < 0)
962         env->xcc |= PSR_NEG;
963 #else
964     if (!T0)
965         env->psr |= PSR_ZERO;
966     if ((int32_t) T0 < 0)
967         env->psr |= PSR_NEG;
968 #endif
969     FORCE_RET();
970 }
971
972 void OPPROTO op_sll(void)
973 {
974     T0 <<= (T1 & 0x1f);
975 }
976
977 #ifdef TARGET_SPARC64
978 void OPPROTO op_sllx(void)
979 {
980     T0 <<= (T1 & 0x3f);
981 }
982
983 void OPPROTO op_srl(void)
984 {
985     T0 = (T0 & 0xffffffff) >> (T1 & 0x1f);
986 }
987
988 void OPPROTO op_srlx(void)
989 {
990     T0 >>= (T1 & 0x3f);
991 }
992
993 void OPPROTO op_sra(void)
994 {
995     T0 = ((int32_t) (T0 & 0xffffffff)) >> (T1 & 0x1f);
996 }
997
998 void OPPROTO op_srax(void)
999 {
1000     T0 = ((int64_t) T0) >> (T1 & 0x3f);
1001 }
1002 #else
1003 void OPPROTO op_srl(void)
1004 {
1005     T0 >>= (T1 & 0x1f);
1006 }
1007
1008 void OPPROTO op_sra(void)
1009 {
1010     T0 = ((int32_t) T0) >> (T1 & 0x1f);
1011 }
1012 #endif
1013
1014 /* Load and store */
1015 #define MEMSUFFIX _raw
1016 #include "op_mem.h"
1017 #if !defined(CONFIG_USER_ONLY)
1018 #define MEMSUFFIX _user
1019 #include "op_mem.h"
1020
1021 #define MEMSUFFIX _kernel
1022 #include "op_mem.h"
1023 #endif
1024
1025 void OPPROTO op_ldfsr(void)
1026 {
1027     PUT_FSR32(env, *((uint32_t *) &FT0));
1028     helper_ldfsr();
1029 }
1030
1031 void OPPROTO op_stfsr(void)
1032 {
1033     *((uint32_t *) &FT0) = GET_FSR32(env);
1034 }
1035
1036 #ifndef TARGET_SPARC64
1037 void OPPROTO op_rdpsr(void)
1038 {
1039     do_rdpsr();
1040 }
1041
1042 void OPPROTO op_wrpsr(void)
1043 {
1044     do_wrpsr();
1045     FORCE_RET();
1046 }
1047
1048 void OPPROTO op_wrwim(void)
1049 {
1050 #if NWINDOWS == 32
1051     env->wim = T0;
1052 #else
1053     env->wim = T0 & ((1 << NWINDOWS) - 1);
1054 #endif
1055 }
1056
1057 void OPPROTO op_rett(void)
1058 {
1059     helper_rett();
1060     FORCE_RET();
1061 }
1062
1063 /* XXX: use another pointer for %iN registers to avoid slow wrapping
1064    handling ? */
1065 void OPPROTO op_save(void)
1066 {
1067     uint32_t cwp;
1068     cwp = (env->cwp - 1) & (NWINDOWS - 1); 
1069     if (env->wim & (1 << cwp)) {
1070         raise_exception(TT_WIN_OVF);
1071     }
1072     set_cwp(cwp);
1073     FORCE_RET();
1074 }
1075
1076 void OPPROTO op_restore(void)
1077 {
1078     uint32_t cwp;
1079     cwp = (env->cwp + 1) & (NWINDOWS - 1); 
1080     if (env->wim & (1 << cwp)) {
1081         raise_exception(TT_WIN_UNF);
1082     }
1083     set_cwp(cwp);
1084     FORCE_RET();
1085 }
1086 #else
1087 void OPPROTO op_rdccr(void)
1088 {
1089     T0 = GET_CCR(env);
1090 }
1091
1092 void OPPROTO op_wrccr(void)
1093 {
1094     PUT_CCR(env, T0);
1095 }
1096
1097 void OPPROTO op_rdtick(void)
1098 {
1099     T0 = do_tick_get_count(env->tick);
1100 }
1101
1102 void OPPROTO op_wrtick(void)
1103 {
1104     do_tick_set_count(env->tick, T0);
1105 }
1106
1107 void OPPROTO op_wrtick_cmpr(void)
1108 {
1109     do_tick_set_limit(env->tick, T0);
1110 }
1111
1112 void OPPROTO op_rdstick(void)
1113 {
1114     T0 = do_tick_get_count(env->stick);
1115 }
1116
1117 void OPPROTO op_wrstick(void)
1118 {
1119     do_tick_set_count(env->stick, T0);
1120     do_tick_set_count(env->hstick, T0);
1121 }
1122
1123 void OPPROTO op_wrstick_cmpr(void)
1124 {
1125     do_tick_set_limit(env->stick, T0);
1126 }
1127
1128 void OPPROTO op_wrhstick_cmpr(void)
1129 {
1130     do_tick_set_limit(env->hstick, T0);
1131 }
1132
1133 void OPPROTO op_rdtpc(void)
1134 {
1135     T0 = env->tpc[env->tl];
1136 }
1137
1138 void OPPROTO op_wrtpc(void)
1139 {
1140     env->tpc[env->tl] = T0;
1141 }
1142
1143 void OPPROTO op_rdtnpc(void)
1144 {
1145     T0 = env->tnpc[env->tl];
1146 }
1147
1148 void OPPROTO op_wrtnpc(void)
1149 {
1150     env->tnpc[env->tl] = T0;
1151 }
1152
1153 void OPPROTO op_rdtstate(void)
1154 {
1155     T0 = env->tstate[env->tl];
1156 }
1157
1158 void OPPROTO op_wrtstate(void)
1159 {
1160     env->tstate[env->tl] = T0;
1161 }
1162
1163 void OPPROTO op_rdtt(void)
1164 {
1165     T0 = env->tt[env->tl];
1166 }
1167
1168 void OPPROTO op_wrtt(void)
1169 {
1170     env->tt[env->tl] = T0;
1171 }
1172
1173 void OPPROTO op_rdpstate(void)
1174 {
1175     T0 = env->pstate;
1176 }
1177
1178 void OPPROTO op_wrpstate(void)
1179 {
1180     do_wrpstate();
1181 }
1182
1183 // CWP handling is reversed in V9, but we still use the V8 register
1184 // order.
1185 void OPPROTO op_rdcwp(void)
1186 {
1187     T0 = NWINDOWS - 1 - env->cwp;
1188 }
1189
1190 void OPPROTO op_wrcwp(void)
1191 {
1192     env->cwp = NWINDOWS - 1 - T0;
1193 }
1194
1195 /* XXX: use another pointer for %iN registers to avoid slow wrapping
1196    handling ? */
1197 void OPPROTO op_save(void)
1198 {
1199     uint32_t cwp;
1200     cwp = (env->cwp - 1) & (NWINDOWS - 1); 
1201     if (env->cansave == 0) {
1202         raise_exception(TT_SPILL | (env->otherwin != 0 ? 
1203                                     (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1204                                     ((env->wstate & 0x7) << 2)));
1205     } else {
1206         if (env->cleanwin - env->canrestore == 0) {
1207             // XXX Clean windows without trap
1208             raise_exception(TT_CLRWIN);
1209         } else {
1210             env->cansave--;
1211             env->canrestore++;
1212             set_cwp(cwp);
1213         }
1214     }
1215     FORCE_RET();
1216 }
1217
1218 void OPPROTO op_restore(void)
1219 {
1220     uint32_t cwp;
1221     cwp = (env->cwp + 1) & (NWINDOWS - 1); 
1222     if (env->canrestore == 0) {
1223         raise_exception(TT_FILL | (env->otherwin != 0 ? 
1224                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1225                                    ((env->wstate & 0x7) << 2)));
1226     } else {
1227         env->cansave++;
1228         env->canrestore--;
1229         set_cwp(cwp);
1230     }
1231     FORCE_RET();
1232 }
1233 #endif
1234
1235 void OPPROTO op_exception(void)
1236 {
1237     env->exception_index = PARAM1;
1238     cpu_loop_exit();
1239 }
1240
1241 void OPPROTO op_trap_T0(void)
1242 {
1243     env->exception_index = TT_TRAP + (T0 & 0x7f);
1244     cpu_loop_exit();
1245 }
1246
1247 void OPPROTO op_trapcc_T0(void)
1248 {
1249     if (T2) {
1250         env->exception_index = TT_TRAP + (T0 & 0x7f);
1251         cpu_loop_exit();
1252     }
1253     FORCE_RET();
1254 }
1255
1256 void OPPROTO op_fpexception_im(void)
1257 {
1258     env->exception_index = TT_FP_EXCP;
1259     env->fsr &= ~FSR_FTT_MASK;
1260     env->fsr |= PARAM1;
1261     cpu_loop_exit();
1262     FORCE_RET();
1263 }
1264
1265 void OPPROTO op_debug(void)
1266 {
1267     helper_debug();
1268 }
1269
1270 void OPPROTO op_exit_tb(void)
1271 {
1272     EXIT_TB();
1273 }
1274
1275 void OPPROTO op_eval_ba(void)
1276 {
1277     T2 = 1;
1278 }
1279
1280 void OPPROTO op_eval_be(void)
1281 {
1282     T2 = FLAG_SET(PSR_ZERO);
1283 }
1284
1285 void OPPROTO op_eval_ble(void)
1286 {
1287     target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1288     
1289     T2 = Z | (N ^ V);
1290 }
1291
1292 void OPPROTO op_eval_bl(void)
1293 {
1294     target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1295
1296     T2 = N ^ V;
1297 }
1298
1299 void OPPROTO op_eval_bleu(void)
1300 {
1301     target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1302
1303     T2 = C | Z;
1304 }
1305
1306 void OPPROTO op_eval_bcs(void)
1307 {
1308     T2 = FLAG_SET(PSR_CARRY);
1309 }
1310
1311 void OPPROTO op_eval_bvs(void)
1312 {
1313     T2 = FLAG_SET(PSR_OVF);
1314 }
1315
1316 void OPPROTO op_eval_bn(void)
1317 {
1318     T2 = 0;
1319 }
1320
1321 void OPPROTO op_eval_bneg(void)
1322 {
1323     T2 = FLAG_SET(PSR_NEG);
1324 }
1325
1326 void OPPROTO op_eval_bne(void)
1327 {
1328     T2 = !FLAG_SET(PSR_ZERO);
1329 }
1330
1331 void OPPROTO op_eval_bg(void)
1332 {
1333     target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1334
1335     T2 = !(Z | (N ^ V));
1336 }
1337
1338 void OPPROTO op_eval_bge(void)
1339 {
1340     target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1341
1342     T2 = !(N ^ V);
1343 }
1344
1345 void OPPROTO op_eval_bgu(void)
1346 {
1347     target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1348
1349     T2 = !(C | Z);
1350 }
1351
1352 void OPPROTO op_eval_bcc(void)
1353 {
1354     T2 = !FLAG_SET(PSR_CARRY);
1355 }
1356
1357 void OPPROTO op_eval_bpos(void)
1358 {
1359     T2 = !FLAG_SET(PSR_NEG);
1360 }
1361
1362 void OPPROTO op_eval_bvc(void)
1363 {
1364     T2 = !FLAG_SET(PSR_OVF);
1365 }
1366
1367 #ifdef TARGET_SPARC64
1368 void OPPROTO op_eval_xbe(void)
1369 {
1370     T2 = XFLAG_SET(PSR_ZERO);
1371 }
1372
1373 void OPPROTO op_eval_xble(void)
1374 {
1375     target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1376     
1377     T2 = Z | (N ^ V);
1378 }
1379
1380 void OPPROTO op_eval_xbl(void)
1381 {
1382     target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1383
1384     T2 = N ^ V;
1385 }
1386
1387 void OPPROTO op_eval_xbleu(void)
1388 {
1389     target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1390
1391     T2 = C | Z;
1392 }
1393
1394 void OPPROTO op_eval_xbcs(void)
1395 {
1396     T2 = XFLAG_SET(PSR_CARRY);
1397 }
1398
1399 void OPPROTO op_eval_xbvs(void)
1400 {
1401     T2 = XFLAG_SET(PSR_OVF);
1402 }
1403
1404 void OPPROTO op_eval_xbneg(void)
1405 {
1406     T2 = XFLAG_SET(PSR_NEG);
1407 }
1408
1409 void OPPROTO op_eval_xbne(void)
1410 {
1411     T2 = !XFLAG_SET(PSR_ZERO);
1412 }
1413
1414 void OPPROTO op_eval_xbg(void)
1415 {
1416     target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1417
1418     T2 = !(Z | (N ^ V));
1419 }
1420
1421 void OPPROTO op_eval_xbge(void)
1422 {
1423     target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1424
1425     T2 = !(N ^ V);
1426 }
1427
1428 void OPPROTO op_eval_xbgu(void)
1429 {
1430     target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1431
1432     T2 = !(C | Z);
1433 }
1434
1435 void OPPROTO op_eval_xbcc(void)
1436 {
1437     T2 = !XFLAG_SET(PSR_CARRY);
1438 }
1439
1440 void OPPROTO op_eval_xbpos(void)
1441 {
1442     T2 = !XFLAG_SET(PSR_NEG);
1443 }
1444
1445 void OPPROTO op_eval_xbvc(void)
1446 {
1447     T2 = !XFLAG_SET(PSR_OVF);
1448 }
1449 #endif
1450
1451 #define FCC
1452 #define FFLAG_SET(x) (env->fsr & x? 1: 0)
1453 #include "fbranch_template.h"
1454
1455 #ifdef TARGET_SPARC64
1456 #define FCC _fcc1
1457 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
1458 #include "fbranch_template.h"
1459 #define FCC _fcc2
1460 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
1461 #include "fbranch_template.h"
1462 #define FCC _fcc3
1463 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
1464 #include "fbranch_template.h"
1465 #endif
1466
1467 #ifdef TARGET_SPARC64
1468 void OPPROTO op_eval_brz(void)
1469 {
1470     T2 = (T0 == 0);
1471 }
1472
1473 void OPPROTO op_eval_brnz(void)
1474 {
1475     T2 = (T0 != 0);
1476 }
1477
1478 void OPPROTO op_eval_brlz(void)
1479 {
1480     T2 = ((int64_t)T0 < 0);
1481 }
1482
1483 void OPPROTO op_eval_brlez(void)
1484 {
1485     T2 = ((int64_t)T0 <= 0);
1486 }
1487
1488 void OPPROTO op_eval_brgz(void)
1489 {
1490     T2 = ((int64_t)T0 > 0);
1491 }
1492
1493 void OPPROTO op_eval_brgez(void)
1494 {
1495     T2 = ((int64_t)T0 >= 0);
1496 }
1497
1498 void OPPROTO op_jmp_im64(void)
1499 {
1500     env->pc = PARAMQ1;
1501 }
1502
1503 void OPPROTO op_movq_npc_im64(void)
1504 {
1505     env->npc = PARAMQ1;
1506 }
1507 #endif
1508
1509 void OPPROTO op_jmp_im(void)
1510 {
1511     env->pc = (uint32_t)PARAM1;
1512 }
1513
1514 void OPPROTO op_movl_npc_im(void)
1515 {
1516     env->npc = (uint32_t)PARAM1;
1517 }
1518
1519 void OPPROTO op_movl_npc_T0(void)
1520 {
1521     if (T0 & 0x3)
1522         raise_exception(TT_UNALIGNED);
1523     else
1524         env->npc = T0;
1525 }
1526
1527 void OPPROTO op_mov_pc_npc(void)
1528 {
1529     env->pc = env->npc;
1530 }
1531
1532 void OPPROTO op_next_insn(void)
1533 {
1534     env->pc = env->npc;
1535     env->npc = env->npc + 4;
1536 }
1537
1538 void OPPROTO op_goto_tb0(void)
1539 {
1540     GOTO_TB(op_goto_tb0, PARAM1, 0);
1541 }
1542
1543 void OPPROTO op_goto_tb1(void)
1544 {
1545     GOTO_TB(op_goto_tb1, PARAM1, 1);
1546 }
1547
1548 void OPPROTO op_jmp_label(void)
1549 {
1550     GOTO_LABEL_PARAM(1);
1551 }
1552
1553 void OPPROTO op_jnz_T2_label(void)
1554 {
1555     if (T2)
1556         GOTO_LABEL_PARAM(1);
1557     FORCE_RET();
1558 }
1559
1560 void OPPROTO op_jz_T2_label(void)
1561 {
1562     if (!T2)
1563         GOTO_LABEL_PARAM(1);
1564     FORCE_RET();
1565 }
1566
1567 void OPPROTO op_flush_T0(void)
1568 {
1569     helper_flush(T0);
1570 }
1571
1572 void OPPROTO op_clear_ieee_excp_and_FTT(void)
1573 {
1574     env->fsr &= ~(FSR_FTT_MASK | FSR_CEXC_MASK);;
1575 }
1576
1577 #define F_OP(name, p) void OPPROTO op_f##name##p(void)
1578
1579 #define F_BINOP(name)                                           \
1580     F_OP(name, s)                                               \
1581     {                                                           \
1582         set_float_exception_flags(0, &env->fp_status);          \
1583         FT0 = float32_ ## name (FT0, FT1, &env->fp_status);     \
1584         check_ieee_exceptions();                                \
1585     }                                                           \
1586     F_OP(name, d)                                               \
1587     {                                                           \
1588         set_float_exception_flags(0, &env->fp_status);          \
1589         DT0 = float64_ ## name (DT0, DT1, &env->fp_status);     \
1590         check_ieee_exceptions();                                \
1591     }
1592
1593 F_BINOP(add);
1594 F_BINOP(sub);
1595 F_BINOP(mul);
1596 F_BINOP(div);
1597 #undef F_BINOP
1598
1599 void OPPROTO op_fsmuld(void)
1600 {
1601     set_float_exception_flags(0, &env->fp_status);
1602     DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status),
1603                       float32_to_float64(FT1, &env->fp_status),
1604                       &env->fp_status);
1605     check_ieee_exceptions();
1606 }
1607
1608 #define F_HELPER(name)    \
1609     F_OP(name, s)         \
1610     {                     \
1611         do_f##name##s();  \
1612     }                     \
1613     F_OP(name, d)         \
1614     {                     \
1615         do_f##name##d();  \
1616     }
1617
1618 F_HELPER(sqrt);
1619
1620 F_OP(neg, s)
1621 {
1622     FT0 = float32_chs(FT1);
1623 }
1624
1625 F_OP(abs, s)
1626 {
1627     do_fabss();
1628 }
1629
1630 F_HELPER(cmp);
1631 F_HELPER(cmpe);
1632
1633 #ifdef TARGET_SPARC64
1634 F_OP(neg, d)
1635 {
1636     DT0 = float64_chs(DT1);
1637 }
1638
1639 F_OP(abs, d)
1640 {
1641     do_fabsd();
1642 }
1643
1644 void OPPROTO op_fcmps_fcc1(void)
1645 {
1646     do_fcmps_fcc1();
1647 }
1648
1649 void OPPROTO op_fcmpd_fcc1(void)
1650 {
1651     do_fcmpd_fcc1();
1652 }
1653
1654 void OPPROTO op_fcmps_fcc2(void)
1655 {
1656     do_fcmps_fcc2();
1657 }
1658
1659 void OPPROTO op_fcmpd_fcc2(void)
1660 {
1661     do_fcmpd_fcc2();
1662 }
1663
1664 void OPPROTO op_fcmps_fcc3(void)
1665 {
1666     do_fcmps_fcc3();
1667 }
1668
1669 void OPPROTO op_fcmpd_fcc3(void)
1670 {
1671     do_fcmpd_fcc3();
1672 }
1673
1674 void OPPROTO op_fcmpes_fcc1(void)
1675 {
1676     do_fcmpes_fcc1();
1677 }
1678
1679 void OPPROTO op_fcmped_fcc1(void)
1680 {
1681     do_fcmped_fcc1();
1682 }
1683
1684 void OPPROTO op_fcmpes_fcc2(void)
1685 {
1686     do_fcmpes_fcc2();
1687 }
1688
1689 void OPPROTO op_fcmped_fcc2(void)
1690 {
1691     do_fcmped_fcc2();
1692 }
1693
1694 void OPPROTO op_fcmpes_fcc3(void)
1695 {
1696     do_fcmpes_fcc3();
1697 }
1698
1699 void OPPROTO op_fcmped_fcc3(void)
1700 {
1701     do_fcmped_fcc3();
1702 }
1703
1704 #endif
1705
1706 /* Integer to float conversion.  */
1707 #ifdef USE_INT_TO_FLOAT_HELPERS
1708 F_HELPER(ito);
1709 #else
1710 F_OP(ito, s)
1711 {
1712     set_float_exception_flags(0, &env->fp_status);
1713     FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
1714     check_ieee_exceptions();
1715 }
1716
1717 F_OP(ito, d)
1718 {
1719     set_float_exception_flags(0, &env->fp_status);
1720     DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
1721     check_ieee_exceptions();
1722 }
1723
1724 #ifdef TARGET_SPARC64
1725 F_OP(xto, s)
1726 {
1727     set_float_exception_flags(0, &env->fp_status);
1728     FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
1729     check_ieee_exceptions();
1730 }
1731
1732 F_OP(xto, d)
1733 {
1734     set_float_exception_flags(0, &env->fp_status);
1735     DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
1736     check_ieee_exceptions();
1737 }
1738 #endif
1739 #endif
1740 #undef F_HELPER
1741
1742 /* floating point conversion */
1743 void OPPROTO op_fdtos(void)
1744 {
1745     set_float_exception_flags(0, &env->fp_status);
1746     FT0 = float64_to_float32(DT1, &env->fp_status);
1747     check_ieee_exceptions();
1748 }
1749
1750 void OPPROTO op_fstod(void)
1751 {
1752     set_float_exception_flags(0, &env->fp_status);
1753     DT0 = float32_to_float64(FT1, &env->fp_status);
1754     check_ieee_exceptions();
1755 }
1756
1757 /* Float to integer conversion.  */
1758 void OPPROTO op_fstoi(void)
1759 {
1760     set_float_exception_flags(0, &env->fp_status);
1761     *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status);
1762     check_ieee_exceptions();
1763 }
1764
1765 void OPPROTO op_fdtoi(void)
1766 {
1767     set_float_exception_flags(0, &env->fp_status);
1768     *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
1769     check_ieee_exceptions();
1770 }
1771
1772 #ifdef TARGET_SPARC64
1773 void OPPROTO op_fstox(void)
1774 {
1775     set_float_exception_flags(0, &env->fp_status);
1776     *((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status);
1777     check_ieee_exceptions();
1778 }
1779
1780 void OPPROTO op_fdtox(void)
1781 {
1782     set_float_exception_flags(0, &env->fp_status);
1783     *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
1784     check_ieee_exceptions();
1785 }
1786
1787 void OPPROTO op_fmovs_cc(void)
1788 {
1789     if (T2)
1790         FT0 = FT1;
1791 }
1792
1793 void OPPROTO op_fmovd_cc(void)
1794 {
1795     if (T2)
1796         DT0 = DT1;
1797 }
1798
1799 void OPPROTO op_mov_cc(void)
1800 {
1801     if (T2)
1802         T0 = T1;
1803 }
1804
1805 void OPPROTO op_flushw(void)
1806 {
1807     if (env->cansave != NWINDOWS - 2) {
1808         raise_exception(TT_SPILL | (env->otherwin != 0 ? 
1809                                     (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1810                                     ((env->wstate & 0x7) << 2)));
1811     }
1812 }
1813
1814 void OPPROTO op_saved(void)
1815 {
1816     env->cansave++;
1817     if (env->otherwin == 0)
1818         env->canrestore--;
1819     else
1820         env->otherwin--;
1821     FORCE_RET();
1822 }
1823
1824 void OPPROTO op_restored(void)
1825 {
1826     env->canrestore++;
1827     if (env->cleanwin < NWINDOWS - 1)
1828         env->cleanwin++;
1829     if (env->otherwin == 0)
1830         env->cansave--;
1831     else
1832         env->otherwin--;
1833     FORCE_RET();
1834 }
1835
1836 void OPPROTO op_popc(void)
1837 {
1838     do_popc();
1839 }
1840
1841 void OPPROTO op_done(void)
1842 {
1843     do_done();
1844 }
1845
1846 void OPPROTO op_retry(void)
1847 {
1848     do_retry();
1849 }
1850
1851 void OPPROTO op_sir(void)
1852 {
1853     T0 = 0;  // XXX
1854 }
1855
1856 void OPPROTO op_ld_asi_reg()
1857 {
1858     T0 += PARAM1;
1859     helper_ld_asi(env->asi, PARAM2, PARAM3);
1860 }
1861
1862 void OPPROTO op_st_asi_reg()
1863 {
1864     T0 += PARAM1;
1865     helper_st_asi(env->asi, PARAM2, PARAM3);
1866 }
1867 #endif
1868
1869 void OPPROTO op_ld_asi()
1870 {
1871     helper_ld_asi(PARAM1, PARAM2, PARAM3);
1872 }
1873
1874 void OPPROTO op_st_asi()
1875 {
1876     helper_st_asi(PARAM1, PARAM2, PARAM3);
1877 }
1878
1879 #ifdef TARGET_SPARC64
1880 // This function uses non-native bit order
1881 #define GET_FIELD(X, FROM, TO)                                  \
1882     ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
1883
1884 // This function uses the order in the manuals, i.e. bit 0 is 2^0
1885 #define GET_FIELD_SP(X, FROM, TO)               \
1886     GET_FIELD(X, 63 - (TO), 63 - (FROM))
1887
1888 void OPPROTO op_array8()
1889 {
1890     T0 = (GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1891         (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1892         (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1893         (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1894         (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1895         (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12);
1896 }
1897
1898 void OPPROTO op_array16()
1899 {
1900     T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1901           (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1902           (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1903           (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1904           (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1905           (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 1;
1906 }
1907
1908 void OPPROTO op_array32()
1909 {
1910     T0 = ((GET_FIELD_SP(T0, 60, 63) << (17 + 2 * T1)) |
1911           (GET_FIELD_SP(T0, 39, 39 + T1 - 1) << (17 + T1)) |
1912           (GET_FIELD_SP(T0, 17 + T1 - 1, 17) << 17) |
1913           (GET_FIELD_SP(T0, 56, 59) << 13) | (GET_FIELD_SP(T0, 35, 38) << 9) |
1914           (GET_FIELD_SP(T0, 13, 16) << 5) | (((T0 >> 55) & 1) << 4) |
1915           (GET_FIELD_SP(T0, 33, 34) << 2) | GET_FIELD_SP(T0, 11, 12)) << 2;
1916 }
1917
1918 void OPPROTO op_alignaddr()
1919 {
1920     uint64_t tmp;
1921
1922     tmp = T0 + T1;
1923     env->gsr &= ~7ULL;
1924     env->gsr |= tmp & 7ULL;
1925     T0 = tmp & ~7ULL;
1926 }
1927
1928 void OPPROTO op_faligndata()
1929 {
1930     uint64_t tmp;
1931
1932     tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8);
1933     tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
1934     *((uint64_t *)&DT0) = tmp;
1935 }
1936
1937 void OPPROTO op_movl_FT0_0(void)
1938 {
1939     *((uint32_t *)&FT0) = 0;
1940 }
1941
1942 void OPPROTO op_movl_DT0_0(void)
1943 {
1944     *((uint64_t *)&DT0) = 0;
1945 }
1946
1947 void OPPROTO op_movl_FT0_1(void)
1948 {
1949     *((uint32_t *)&FT0) = 0xffffffff;
1950 }
1951
1952 void OPPROTO op_movl_DT0_1(void)
1953 {
1954     *((uint64_t *)&DT0) = 0xffffffffffffffffULL;
1955 }
1956
1957 void OPPROTO op_fnot(void)
1958 {
1959     *(uint64_t *)&DT0 = ~*(uint64_t *)&DT1;
1960 }
1961
1962 void OPPROTO op_fnots(void)
1963 {
1964     *(uint32_t *)&FT0 = ~*(uint32_t *)&FT1;
1965 }
1966
1967 void OPPROTO op_fnor(void)
1968 {
1969     *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 | *(uint64_t *)&DT1);
1970 }
1971
1972 void OPPROTO op_fnors(void)
1973 {
1974     *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 | *(uint32_t *)&FT1);
1975 }
1976
1977 void OPPROTO op_for(void)
1978 {
1979     *(uint64_t *)&DT0 |= *(uint64_t *)&DT1;
1980 }
1981
1982 void OPPROTO op_fors(void)
1983 {
1984     *(uint32_t *)&FT0 |= *(uint32_t *)&FT1;
1985 }
1986
1987 void OPPROTO op_fxor(void)
1988 {
1989     *(uint64_t *)&DT0 ^= *(uint64_t *)&DT1;
1990 }
1991
1992 void OPPROTO op_fxors(void)
1993 {
1994     *(uint32_t *)&FT0 ^= *(uint32_t *)&FT1;
1995 }
1996
1997 void OPPROTO op_fand(void)
1998 {
1999     *(uint64_t *)&DT0 &= *(uint64_t *)&DT1;
2000 }
2001
2002 void OPPROTO op_fands(void)
2003 {
2004     *(uint32_t *)&FT0 &= *(uint32_t *)&FT1;
2005 }
2006
2007 void OPPROTO op_fornot(void)
2008 {
2009     *(uint64_t *)&DT0 = *(uint64_t *)&DT0 | ~*(uint64_t *)&DT1;
2010 }
2011
2012 void OPPROTO op_fornots(void)
2013 {
2014     *(uint32_t *)&FT0 = *(uint32_t *)&FT0 | ~*(uint32_t *)&FT1;
2015 }
2016
2017 void OPPROTO op_fandnot(void)
2018 {
2019     *(uint64_t *)&DT0 = *(uint64_t *)&DT0 & ~*(uint64_t *)&DT1;
2020 }
2021
2022 void OPPROTO op_fandnots(void)
2023 {
2024     *(uint32_t *)&FT0 = *(uint32_t *)&FT0 & ~*(uint32_t *)&FT1;
2025 }
2026
2027 void OPPROTO op_fnand(void)
2028 {
2029     *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 & *(uint64_t *)&DT1);
2030 }
2031
2032 void OPPROTO op_fnands(void)
2033 {
2034     *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 & *(uint32_t *)&FT1);
2035 }
2036
2037 void OPPROTO op_fxnor(void)
2038 {
2039     *(uint64_t *)&DT0 ^= ~*(uint64_t *)&DT1;
2040 }
2041
2042 void OPPROTO op_fxnors(void)
2043 {
2044     *(uint32_t *)&FT0 ^= ~*(uint32_t *)&FT1;
2045 }
2046
2047 #ifdef WORDS_BIGENDIAN
2048 #define VIS_B64(n) b[7 - (n)]
2049 #define VIS_W64(n) w[3 - (n)]
2050 #define VIS_SW64(n) sw[3 - (n)]
2051 #define VIS_L64(n) l[1 - (n)]
2052 #define VIS_B32(n) b[3 - (n)]
2053 #define VIS_W32(n) w[1 - (n)]
2054 #else
2055 #define VIS_B64(n) b[n]
2056 #define VIS_W64(n) w[n]
2057 #define VIS_SW64(n) sw[n]
2058 #define VIS_L64(n) l[n]
2059 #define VIS_B32(n) b[n]
2060 #define VIS_W32(n) w[n]
2061 #endif
2062
2063 typedef union {
2064     uint8_t b[8];
2065     uint16_t w[4];
2066     int16_t sw[4];
2067     uint32_t l[2];
2068     float64 d;
2069 } vis64;
2070
2071 typedef union {
2072     uint8_t b[4];
2073     uint16_t w[2];
2074     uint32_t l;
2075     float32 f;
2076 } vis32;
2077
2078 void OPPROTO op_fpmerge(void)
2079 {
2080     vis64 s, d;
2081
2082     s.d = DT0;
2083     d.d = DT1;
2084
2085     // Reverse calculation order to handle overlap
2086     d.VIS_B64(7) = s.VIS_B64(3);
2087     d.VIS_B64(6) = d.VIS_B64(3);
2088     d.VIS_B64(5) = s.VIS_B64(2);
2089     d.VIS_B64(4) = d.VIS_B64(2);
2090     d.VIS_B64(3) = s.VIS_B64(1);
2091     d.VIS_B64(2) = d.VIS_B64(1);
2092     d.VIS_B64(1) = s.VIS_B64(0);
2093     //d.VIS_B64(0) = d.VIS_B64(0);
2094
2095     DT0 = d.d;
2096 }
2097
2098 void OPPROTO op_fmul8x16(void)
2099 {
2100     vis64 s, d;
2101     uint32_t tmp;
2102
2103     s.d = DT0;
2104     d.d = DT1;
2105
2106 #define PMUL(r)                                                 \
2107     tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r);       \
2108     if ((tmp & 0xff) > 0x7f)                                    \
2109         tmp += 0x100;                                           \
2110     d.VIS_W64(r) = tmp >> 8;
2111
2112     PMUL(0);
2113     PMUL(1);
2114     PMUL(2);
2115     PMUL(3);
2116 #undef PMUL
2117
2118     DT0 = d.d;
2119 }
2120
2121 void OPPROTO op_fmul8x16al(void)
2122 {
2123     vis64 s, d;
2124     uint32_t tmp;
2125
2126     s.d = DT0;
2127     d.d = DT1;
2128
2129 #define PMUL(r)                                                 \
2130     tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r);       \
2131     if ((tmp & 0xff) > 0x7f)                                    \
2132         tmp += 0x100;                                           \
2133     d.VIS_W64(r) = tmp >> 8;
2134
2135     PMUL(0);
2136     PMUL(1);
2137     PMUL(2);
2138     PMUL(3);
2139 #undef PMUL
2140
2141     DT0 = d.d;
2142 }
2143
2144 void OPPROTO op_fmul8x16au(void)
2145 {
2146     vis64 s, d;
2147     uint32_t tmp;
2148
2149     s.d = DT0;
2150     d.d = DT1;
2151
2152 #define PMUL(r)                                                 \
2153     tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r);       \
2154     if ((tmp & 0xff) > 0x7f)                                    \
2155         tmp += 0x100;                                           \
2156     d.VIS_W64(r) = tmp >> 8;
2157
2158     PMUL(0);
2159     PMUL(1);
2160     PMUL(2);
2161     PMUL(3);
2162 #undef PMUL
2163
2164     DT0 = d.d;
2165 }
2166
2167 void OPPROTO op_fmul8sux16(void)
2168 {
2169     vis64 s, d;
2170     uint32_t tmp;
2171
2172     s.d = DT0;
2173     d.d = DT1;
2174
2175 #define PMUL(r)                                                         \
2176     tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
2177     if ((tmp & 0xff) > 0x7f)                                            \
2178         tmp += 0x100;                                                   \
2179     d.VIS_W64(r) = tmp >> 8;
2180
2181     PMUL(0);
2182     PMUL(1);
2183     PMUL(2);
2184     PMUL(3);
2185 #undef PMUL
2186
2187     DT0 = d.d;
2188 }
2189
2190 void OPPROTO op_fmul8ulx16(void)
2191 {
2192     vis64 s, d;
2193     uint32_t tmp;
2194
2195     s.d = DT0;
2196     d.d = DT1;
2197
2198 #define PMUL(r)                                                         \
2199     tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
2200     if ((tmp & 0xff) > 0x7f)                                            \
2201         tmp += 0x100;                                                   \
2202     d.VIS_W64(r) = tmp >> 8;
2203
2204     PMUL(0);
2205     PMUL(1);
2206     PMUL(2);
2207     PMUL(3);
2208 #undef PMUL
2209
2210     DT0 = d.d;
2211 }
2212
2213 void OPPROTO op_fmuld8sux16(void)
2214 {
2215     vis64 s, d;
2216     uint32_t tmp;
2217
2218     s.d = DT0;
2219     d.d = DT1;
2220
2221 #define PMUL(r)                                                         \
2222     tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
2223     if ((tmp & 0xff) > 0x7f)                                            \
2224         tmp += 0x100;                                                   \
2225     d.VIS_L64(r) = tmp;
2226
2227     // Reverse calculation order to handle overlap
2228     PMUL(1);
2229     PMUL(0);
2230 #undef PMUL
2231
2232     DT0 = d.d;
2233 }
2234
2235 void OPPROTO op_fmuld8ulx16(void)
2236 {
2237     vis64 s, d;
2238     uint32_t tmp;
2239
2240     s.d = DT0;
2241     d.d = DT1;
2242
2243 #define PMUL(r)                                                         \
2244     tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
2245     if ((tmp & 0xff) > 0x7f)                                            \
2246         tmp += 0x100;                                                   \
2247     d.VIS_L64(r) = tmp;
2248
2249     // Reverse calculation order to handle overlap
2250     PMUL(1);
2251     PMUL(0);
2252 #undef PMUL
2253
2254     DT0 = d.d;
2255 }
2256
2257 void OPPROTO op_fexpand(void)
2258 {
2259     vis32 s;
2260     vis64 d;
2261
2262     s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff);
2263     d.d = DT1;
2264     d.VIS_L64(0) = s.VIS_W32(0) << 4;
2265     d.VIS_L64(1) = s.VIS_W32(1) << 4;
2266     d.VIS_L64(2) = s.VIS_W32(2) << 4;
2267     d.VIS_L64(3) = s.VIS_W32(3) << 4;
2268
2269     DT0 = d.d;
2270 }
2271
2272 #define VIS_OP(name, F)                                 \
2273     void OPPROTO name##16(void)                         \
2274     {                                                   \
2275         vis64 s, d;                                     \
2276                                                         \
2277         s.d = DT0;                                      \
2278         d.d = DT1;                                      \
2279                                                         \
2280         d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0));   \
2281         d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1));   \
2282         d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2));   \
2283         d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3));   \
2284                                                         \
2285         DT0 = d.d;                                      \
2286     }                                                   \
2287                                                         \
2288     void OPPROTO name##16s(void)                        \
2289     {                                                   \
2290         vis32 s, d;                                     \
2291                                                         \
2292         s.f = FT0;                                      \
2293         d.f = FT1;                                      \
2294                                                         \
2295         d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0));   \
2296         d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1));   \
2297                                                         \
2298         FT0 = d.f;                                      \
2299     }                                                   \
2300                                                         \
2301     void OPPROTO name##32(void)                         \
2302     {                                                   \
2303         vis64 s, d;                                     \
2304                                                         \
2305         s.d = DT0;                                      \
2306         d.d = DT1;                                      \
2307                                                         \
2308         d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0));   \
2309         d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1));   \
2310                                                         \
2311         DT0 = d.d;                                      \
2312     }                                                   \
2313                                                         \
2314     void OPPROTO name##32s(void)                        \
2315     {                                                   \
2316         vis32 s, d;                                     \
2317                                                         \
2318         s.f = FT0;                                      \
2319         d.f = FT1;                                      \
2320                                                         \
2321         d.l = F(d.l, s.l);                              \
2322                                                         \
2323         FT0 = d.f;                                      \
2324     }
2325
2326 #define FADD(a, b) ((a) + (b))
2327 #define FSUB(a, b) ((a) - (b))
2328 VIS_OP(op_fpadd, FADD)
2329 VIS_OP(op_fpsub, FSUB)
2330
2331 #define VIS_CMPOP(name, F)                                        \
2332     void OPPROTO name##16(void)                                   \
2333     {                                                             \
2334         vis64 s, d;                                               \
2335                                                                   \
2336         s.d = DT0;                                                \
2337         d.d = DT1;                                                \
2338                                                                   \
2339         d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0;       \
2340         d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0;      \
2341         d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0;      \
2342         d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0;      \
2343                                                                   \
2344         DT0 = d.d;                                                \
2345     }                                                             \
2346                                                                   \
2347     void OPPROTO name##32(void)                                   \
2348     {                                                             \
2349         vis64 s, d;                                               \
2350                                                                   \
2351         s.d = DT0;                                                \
2352         d.d = DT1;                                                \
2353                                                                   \
2354         d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0;       \
2355         d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0;      \
2356                                                                   \
2357         DT0 = d.d;                                                \
2358     }
2359
2360 #define FCMPGT(a, b) ((a) > (b))
2361 #define FCMPEQ(a, b) ((a) == (b))
2362 #define FCMPLE(a, b) ((a) <= (b))
2363 #define FCMPNE(a, b) ((a) != (b))
2364
2365 VIS_CMPOP(op_fcmpgt, FCMPGT)
2366 VIS_CMPOP(op_fcmpeq, FCMPEQ)
2367 VIS_CMPOP(op_fcmple, FCMPLE)
2368 VIS_CMPOP(op_fcmpne, FCMPNE)
2369
2370 #endif