Device hot-remove
[qemu-kvm/fedora.git] / target-sparc / op.c
blobee5d56f4f2f37356fe0b2e7b86e467b021a8224a
1 /*
2 SPARC micro operations
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
21 #include "exec.h"
22 #include "helper.h"
24 #define REGNAME f0
25 #define REG (env->fpr[0])
26 #include "fop_template.h"
27 #define REGNAME f1
28 #define REG (env->fpr[1])
29 #include "fop_template.h"
30 #define REGNAME f2
31 #define REG (env->fpr[2])
32 #include "fop_template.h"
33 #define REGNAME f3
34 #define REG (env->fpr[3])
35 #include "fop_template.h"
36 #define REGNAME f4
37 #define REG (env->fpr[4])
38 #include "fop_template.h"
39 #define REGNAME f5
40 #define REG (env->fpr[5])
41 #include "fop_template.h"
42 #define REGNAME f6
43 #define REG (env->fpr[6])
44 #include "fop_template.h"
45 #define REGNAME f7
46 #define REG (env->fpr[7])
47 #include "fop_template.h"
48 #define REGNAME f8
49 #define REG (env->fpr[8])
50 #include "fop_template.h"
51 #define REGNAME f9
52 #define REG (env->fpr[9])
53 #include "fop_template.h"
54 #define REGNAME f10
55 #define REG (env->fpr[10])
56 #include "fop_template.h"
57 #define REGNAME f11
58 #define REG (env->fpr[11])
59 #include "fop_template.h"
60 #define REGNAME f12
61 #define REG (env->fpr[12])
62 #include "fop_template.h"
63 #define REGNAME f13
64 #define REG (env->fpr[13])
65 #include "fop_template.h"
66 #define REGNAME f14
67 #define REG (env->fpr[14])
68 #include "fop_template.h"
69 #define REGNAME f15
70 #define REG (env->fpr[15])
71 #include "fop_template.h"
72 #define REGNAME f16
73 #define REG (env->fpr[16])
74 #include "fop_template.h"
75 #define REGNAME f17
76 #define REG (env->fpr[17])
77 #include "fop_template.h"
78 #define REGNAME f18
79 #define REG (env->fpr[18])
80 #include "fop_template.h"
81 #define REGNAME f19
82 #define REG (env->fpr[19])
83 #include "fop_template.h"
84 #define REGNAME f20
85 #define REG (env->fpr[20])
86 #include "fop_template.h"
87 #define REGNAME f21
88 #define REG (env->fpr[21])
89 #include "fop_template.h"
90 #define REGNAME f22
91 #define REG (env->fpr[22])
92 #include "fop_template.h"
93 #define REGNAME f23
94 #define REG (env->fpr[23])
95 #include "fop_template.h"
96 #define REGNAME f24
97 #define REG (env->fpr[24])
98 #include "fop_template.h"
99 #define REGNAME f25
100 #define REG (env->fpr[25])
101 #include "fop_template.h"
102 #define REGNAME f26
103 #define REG (env->fpr[26])
104 #include "fop_template.h"
105 #define REGNAME f27
106 #define REG (env->fpr[27])
107 #include "fop_template.h"
108 #define REGNAME f28
109 #define REG (env->fpr[28])
110 #include "fop_template.h"
111 #define REGNAME f29
112 #define REG (env->fpr[29])
113 #include "fop_template.h"
114 #define REGNAME f30
115 #define REG (env->fpr[30])
116 #include "fop_template.h"
117 #define REGNAME f31
118 #define REG (env->fpr[31])
119 #include "fop_template.h"
121 #ifdef TARGET_SPARC64
122 #define REGNAME f32
123 #define REG (env->fpr[32])
124 #include "fop_template.h"
125 #define REGNAME f34
126 #define REG (env->fpr[34])
127 #include "fop_template.h"
128 #define REGNAME f36
129 #define REG (env->fpr[36])
130 #include "fop_template.h"
131 #define REGNAME f38
132 #define REG (env->fpr[38])
133 #include "fop_template.h"
134 #define REGNAME f40
135 #define REG (env->fpr[40])
136 #include "fop_template.h"
137 #define REGNAME f42
138 #define REG (env->fpr[42])
139 #include "fop_template.h"
140 #define REGNAME f44
141 #define REG (env->fpr[44])
142 #include "fop_template.h"
143 #define REGNAME f46
144 #define REG (env->fpr[46])
145 #include "fop_template.h"
146 #define REGNAME f48
147 #define REG (env->fpr[47])
148 #include "fop_template.h"
149 #define REGNAME f50
150 #define REG (env->fpr[50])
151 #include "fop_template.h"
152 #define REGNAME f52
153 #define REG (env->fpr[52])
154 #include "fop_template.h"
155 #define REGNAME f54
156 #define REG (env->fpr[54])
157 #include "fop_template.h"
158 #define REGNAME f56
159 #define REG (env->fpr[56])
160 #include "fop_template.h"
161 #define REGNAME f58
162 #define REG (env->fpr[58])
163 #include "fop_template.h"
164 #define REGNAME f60
165 #define REG (env->fpr[60])
166 #include "fop_template.h"
167 #define REGNAME f62
168 #define REG (env->fpr[62])
169 #include "fop_template.h"
170 #endif
172 #ifdef TARGET_SPARC64
173 #define XFLAG_SET(x) ((env->xcc&x)?1:0)
174 #endif
176 #define FLAG_SET(x) ((env->psr&x)?1:0)
178 void OPPROTO op_add_T1_T0_cc(void)
180 target_ulong src1;
182 src1 = T0;
183 T0 += T1;
184 env->psr = 0;
185 #ifdef TARGET_SPARC64
186 if (!(T0 & 0xffffffff))
187 env->psr |= PSR_ZERO;
188 if ((int32_t) T0 < 0)
189 env->psr |= PSR_NEG;
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))
194 env->psr |= PSR_OVF;
196 env->xcc = 0;
197 if (!T0)
198 env->xcc |= PSR_ZERO;
199 if ((int64_t) T0 < 0)
200 env->xcc |= PSR_NEG;
201 if (T0 < src1)
202 env->xcc |= PSR_CARRY;
203 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
204 env->xcc |= PSR_OVF;
205 #else
206 if (!T0)
207 env->psr |= PSR_ZERO;
208 if ((int32_t) T0 < 0)
209 env->psr |= PSR_NEG;
210 if (T0 < src1)
211 env->psr |= PSR_CARRY;
212 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
213 env->psr |= PSR_OVF;
214 #endif
215 FORCE_RET();
218 void OPPROTO op_addx_T1_T0_cc(void)
220 target_ulong src1;
221 src1 = T0;
222 if (FLAG_SET(PSR_CARRY))
224 T0 += T1 + 1;
225 env->psr = 0;
226 #ifdef TARGET_SPARC64
227 if ((T0 & 0xffffffff) <= (src1 & 0xffffffff))
228 env->psr |= PSR_CARRY;
229 env->xcc = 0;
230 if (T0 <= src1)
231 env->xcc |= PSR_CARRY;
232 #else
233 if (T0 <= src1)
234 env->psr |= PSR_CARRY;
235 #endif
237 else
239 T0 += T1;
240 env->psr = 0;
241 #ifdef TARGET_SPARC64
242 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
243 env->psr |= PSR_CARRY;
244 env->xcc = 0;
245 if (T0 < src1)
246 env->xcc |= PSR_CARRY;
247 #else
248 if (T0 < src1)
249 env->psr |= PSR_CARRY;
250 #endif
252 #ifdef TARGET_SPARC64
253 if (!(T0 & 0xffffffff))
254 env->psr |= PSR_ZERO;
255 if ((int32_t) T0 < 0)
256 env->psr |= PSR_NEG;
257 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
258 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
259 env->psr |= PSR_OVF;
261 if (!T0)
262 env->xcc |= PSR_ZERO;
263 if ((int64_t) T0 < 0)
264 env->xcc |= PSR_NEG;
265 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
266 env->xcc |= PSR_OVF;
267 #else
268 if (!T0)
269 env->psr |= PSR_ZERO;
270 if ((int32_t) T0 < 0)
271 env->psr |= PSR_NEG;
272 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
273 env->psr |= PSR_OVF;
274 #endif
275 FORCE_RET();
278 void OPPROTO op_tadd_T1_T0_cc(void)
280 target_ulong src1;
282 src1 = T0;
283 T0 += T1;
284 env->psr = 0;
285 #ifdef TARGET_SPARC64
286 if (!(T0 & 0xffffffff))
287 env->psr |= PSR_ZERO;
288 if ((int32_t) T0 < 0)
289 env->psr |= PSR_NEG;
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))
294 env->psr |= PSR_OVF;
295 if ((src1 & 0x03) || (T1 & 0x03))
296 env->psr |= PSR_OVF;
298 env->xcc = 0;
299 if (!T0)
300 env->xcc |= PSR_ZERO;
301 if ((int64_t) T0 < 0)
302 env->xcc |= PSR_NEG;
303 if (T0 < src1)
304 env->xcc |= PSR_CARRY;
305 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
306 env->xcc |= PSR_OVF;
307 #else
308 if (!T0)
309 env->psr |= PSR_ZERO;
310 if ((int32_t) T0 < 0)
311 env->psr |= PSR_NEG;
312 if (T0 < src1)
313 env->psr |= PSR_CARRY;
314 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
315 env->psr |= PSR_OVF;
316 if ((src1 & 0x03) || (T1 & 0x03))
317 env->psr |= PSR_OVF;
318 #endif
319 FORCE_RET();
322 void OPPROTO op_tadd_T1_T0_ccTV(void)
324 target_ulong src1;
326 if ((T0 & 0x03) || (T1 & 0x03)) {
327 raise_exception(TT_TOVF);
328 FORCE_RET();
329 return;
332 src1 = T0;
333 T0 += T1;
335 #ifdef TARGET_SPARC64
336 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
337 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
338 raise_exception(TT_TOVF);
339 #else
340 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
341 raise_exception(TT_TOVF);
342 #endif
344 env->psr = 0;
345 #ifdef TARGET_SPARC64
346 if (!(T0 & 0xffffffff))
347 env->psr |= PSR_ZERO;
348 if ((int32_t) T0 < 0)
349 env->psr |= PSR_NEG;
350 if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
351 env->psr |= PSR_CARRY;
353 env->xcc = 0;
354 if (!T0)
355 env->xcc |= PSR_ZERO;
356 if ((int64_t) T0 < 0)
357 env->xcc |= PSR_NEG;
358 if (T0 < src1)
359 env->xcc |= PSR_CARRY;
360 #else
361 if (!T0)
362 env->psr |= PSR_ZERO;
363 if ((int32_t) T0 < 0)
364 env->psr |= PSR_NEG;
365 if (T0 < src1)
366 env->psr |= PSR_CARRY;
367 #endif
368 FORCE_RET();
371 void OPPROTO op_sub_T1_T0_cc(void)
373 target_ulong src1;
375 src1 = T0;
376 T0 -= T1;
377 env->psr = 0;
378 #ifdef TARGET_SPARC64
379 if (!(T0 & 0xffffffff))
380 env->psr |= PSR_ZERO;
381 if ((int32_t) T0 < 0)
382 env->psr |= PSR_NEG;
383 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
384 env->psr |= PSR_CARRY;
385 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
386 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
387 env->psr |= PSR_OVF;
389 env->xcc = 0;
390 if (!T0)
391 env->xcc |= PSR_ZERO;
392 if ((int64_t) T0 < 0)
393 env->xcc |= PSR_NEG;
394 if (src1 < T1)
395 env->xcc |= PSR_CARRY;
396 if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
397 env->xcc |= PSR_OVF;
398 #else
399 if (!T0)
400 env->psr |= PSR_ZERO;
401 if ((int32_t) T0 < 0)
402 env->psr |= PSR_NEG;
403 if (src1 < T1)
404 env->psr |= PSR_CARRY;
405 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
406 env->psr |= PSR_OVF;
407 #endif
408 FORCE_RET();
411 void OPPROTO op_subx_T1_T0_cc(void)
413 target_ulong src1;
414 src1 = T0;
415 if (FLAG_SET(PSR_CARRY))
417 T0 -= T1 + 1;
418 env->psr = 0;
419 #ifdef TARGET_SPARC64
420 if ((src1 & 0xffffffff) <= (T1 & 0xffffffff))
421 env->psr |= PSR_CARRY;
422 env->xcc = 0;
423 if (src1 <= T1)
424 env->xcc |= PSR_CARRY;
425 #else
426 if (src1 <= T1)
427 env->psr |= PSR_CARRY;
428 #endif
430 else
432 T0 -= T1;
433 env->psr = 0;
434 #ifdef TARGET_SPARC64
435 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
436 env->psr |= PSR_CARRY;
437 env->xcc = 0;
438 if (src1 < T1)
439 env->xcc |= PSR_CARRY;
440 #else
441 if (src1 < T1)
442 env->psr |= PSR_CARRY;
443 #endif
445 #ifdef TARGET_SPARC64
446 if (!(T0 & 0xffffffff))
447 env->psr |= PSR_ZERO;
448 if ((int32_t) T0 < 0)
449 env->psr |= PSR_NEG;
450 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
451 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
452 env->psr |= PSR_OVF;
454 if (!T0)
455 env->xcc |= PSR_ZERO;
456 if ((int64_t) T0 < 0)
457 env->xcc |= PSR_NEG;
458 if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
459 env->xcc |= PSR_OVF;
460 #else
461 if (!T0)
462 env->psr |= PSR_ZERO;
463 if ((int32_t) T0 < 0)
464 env->psr |= PSR_NEG;
465 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
466 env->psr |= PSR_OVF;
467 #endif
468 FORCE_RET();
471 void OPPROTO op_tsub_T1_T0_cc(void)
473 target_ulong src1;
475 src1 = T0;
476 T0 -= T1;
477 env->psr = 0;
478 #ifdef TARGET_SPARC64
479 if (!(T0 & 0xffffffff))
480 env->psr |= PSR_ZERO;
481 if ((int32_t) T0 < 0)
482 env->psr |= PSR_NEG;
483 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
484 env->psr |= PSR_CARRY;
485 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
486 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
487 env->psr |= PSR_OVF;
488 if ((src1 & 0x03) || (T1 & 0x03))
489 env->psr |= PSR_OVF;
491 env->xcc = 0;
492 if (!T0)
493 env->xcc |= PSR_ZERO;
494 if ((int64_t) T0 < 0)
495 env->xcc |= PSR_NEG;
496 if (src1 < T1)
497 env->xcc |= PSR_CARRY;
498 if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
499 env->xcc |= PSR_OVF;
500 #else
501 if (!T0)
502 env->psr |= PSR_ZERO;
503 if ((int32_t) T0 < 0)
504 env->psr |= PSR_NEG;
505 if (src1 < T1)
506 env->psr |= PSR_CARRY;
507 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
508 env->psr |= PSR_OVF;
509 if ((src1 & 0x03) || (T1 & 0x03))
510 env->psr |= PSR_OVF;
511 #endif
512 FORCE_RET();
515 void OPPROTO op_tsub_T1_T0_ccTV(void)
517 target_ulong src1;
519 if ((T0 & 0x03) || (T1 & 0x03))
520 raise_exception(TT_TOVF);
522 src1 = T0;
523 T0 -= T1;
525 #ifdef TARGET_SPARC64
526 if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
527 ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
528 raise_exception(TT_TOVF);
529 #else
530 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
531 raise_exception(TT_TOVF);
532 #endif
534 env->psr = 0;
535 #ifdef TARGET_SPARC64
536 if (!(T0 & 0xffffffff))
537 env->psr |= PSR_ZERO;
538 if ((int32_t) T0 < 0)
539 env->psr |= PSR_NEG;
540 if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
541 env->psr |= PSR_CARRY;
543 env->xcc = 0;
544 if (!T0)
545 env->xcc |= PSR_ZERO;
546 if ((int64_t) T0 < 0)
547 env->xcc |= PSR_NEG;
548 if (src1 < T1)
549 env->xcc |= PSR_CARRY;
550 #else
551 if (!T0)
552 env->psr |= PSR_ZERO;
553 if ((int32_t) T0 < 0)
554 env->psr |= PSR_NEG;
555 if (src1 < T1)
556 env->psr |= PSR_CARRY;
557 #endif
558 FORCE_RET();
561 void OPPROTO op_andn_T1_T0(void)
563 T0 &= ~T1;
566 void OPPROTO op_orn_T1_T0(void)
568 T0 |= ~T1;
571 void OPPROTO op_xnor_T1_T0(void)
573 T0 ^= ~T1;
576 void OPPROTO op_umul_T1_T0(void)
578 uint64_t res;
579 res = (uint64_t) T0 * (uint64_t) T1;
580 #ifdef TARGET_SPARC64
581 T0 = res;
582 #else
583 T0 = res & 0xffffffff;
584 #endif
585 env->y = res >> 32;
588 void OPPROTO op_smul_T1_T0(void)
590 uint64_t res;
591 res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
592 #ifdef TARGET_SPARC64
593 T0 = res;
594 #else
595 T0 = res & 0xffffffff;
596 #endif
597 env->y = res >> 32;
600 void OPPROTO op_mulscc_T1_T0(void)
602 unsigned int b1, N, V, b2;
603 target_ulong src1;
605 N = FLAG_SET(PSR_NEG);
606 V = FLAG_SET(PSR_OVF);
607 b1 = N ^ V;
608 b2 = T0 & 1;
609 T0 = (b1 << 31) | (T0 >> 1);
610 if (!(env->y & 1))
611 T1 = 0;
612 /* do addition and update flags */
613 src1 = T0;
614 T0 += T1;
615 env->psr = 0;
616 if (!T0)
617 env->psr |= PSR_ZERO;
618 if ((int32_t) T0 < 0)
619 env->psr |= PSR_NEG;
620 if (T0 < src1)
621 env->psr |= PSR_CARRY;
622 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
623 env->psr |= PSR_OVF;
624 env->y = (b2 << 31) | (env->y >> 1);
625 FORCE_RET();
628 void OPPROTO op_udiv_T1_T0(void)
630 uint64_t x0;
631 uint32_t x1;
633 x0 = T0 | ((uint64_t) (env->y) << 32);
634 x1 = T1;
636 if (x1 == 0) {
637 raise_exception(TT_DIV_ZERO);
640 x0 = x0 / x1;
641 if (x0 > 0xffffffff) {
642 T0 = 0xffffffff;
643 T1 = 1;
644 } else {
645 T0 = x0;
646 T1 = 0;
648 FORCE_RET();
651 void OPPROTO op_sdiv_T1_T0(void)
653 int64_t x0;
654 int32_t x1;
656 x0 = T0 | ((int64_t) (env->y) << 32);
657 x1 = T1;
659 if (x1 == 0) {
660 raise_exception(TT_DIV_ZERO);
663 x0 = x0 / x1;
664 if ((int32_t) x0 != x0) {
665 T0 = x0 < 0? 0x80000000: 0x7fffffff;
666 T1 = 1;
667 } else {
668 T0 = x0;
669 T1 = 0;
671 FORCE_RET();
674 void OPPROTO op_div_cc(void)
676 env->psr = 0;
677 #ifdef TARGET_SPARC64
678 if (!T0)
679 env->psr |= PSR_ZERO;
680 if ((int32_t) T0 < 0)
681 env->psr |= PSR_NEG;
682 if (T1)
683 env->psr |= PSR_OVF;
685 env->xcc = 0;
686 if (!T0)
687 env->xcc |= PSR_ZERO;
688 if ((int64_t) T0 < 0)
689 env->xcc |= PSR_NEG;
690 #else
691 if (!T0)
692 env->psr |= PSR_ZERO;
693 if ((int32_t) T0 < 0)
694 env->psr |= PSR_NEG;
695 if (T1)
696 env->psr |= PSR_OVF;
697 #endif
698 FORCE_RET();
701 #ifdef TARGET_SPARC64
702 void OPPROTO op_udivx_T1_T0(void)
704 if (T1 == 0) {
705 raise_exception(TT_DIV_ZERO);
707 T0 /= T1;
708 FORCE_RET();
711 void OPPROTO op_sdivx_T1_T0(void)
713 if (T1 == 0) {
714 raise_exception(TT_DIV_ZERO);
716 if (T0 == INT64_MIN && T1 == -1)
717 T0 = INT64_MIN;
718 else
719 T0 /= (target_long) T1;
720 FORCE_RET();
722 #endif
724 void OPPROTO op_logic_T0_cc(void)
726 env->psr = 0;
727 #ifdef TARGET_SPARC64
728 if (!(T0 & 0xffffffff))
729 env->psr |= PSR_ZERO;
730 if ((int32_t) T0 < 0)
731 env->psr |= PSR_NEG;
733 env->xcc = 0;
734 if (!T0)
735 env->xcc |= PSR_ZERO;
736 if ((int64_t) T0 < 0)
737 env->xcc |= PSR_NEG;
738 #else
739 if (!T0)
740 env->psr |= PSR_ZERO;
741 if ((int32_t) T0 < 0)
742 env->psr |= PSR_NEG;
743 #endif
744 FORCE_RET();
747 /* Load and store */
748 #define MEMSUFFIX _raw
749 #include "op_mem.h"
750 #if !defined(CONFIG_USER_ONLY)
751 #define MEMSUFFIX _user
752 #include "op_mem.h"
754 #define MEMSUFFIX _kernel
755 #include "op_mem.h"
757 #ifdef TARGET_SPARC64
758 #define MEMSUFFIX _hypv
759 #include "op_mem.h"
760 #endif
761 #endif
763 void OPPROTO op_ldfsr(void)
765 PUT_FSR32(env, *((uint32_t *) &FT0));
766 helper_ldfsr();
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
776 handling ? */
777 void OPPROTO op_save(void)
779 uint32_t cwp;
780 cwp = (env->cwp - 1) & (NWINDOWS - 1);
781 if (env->wim & (1 << cwp)) {
782 raise_exception(TT_WIN_OVF);
784 set_cwp(cwp);
785 FORCE_RET();
788 void OPPROTO op_restore(void)
790 uint32_t cwp;
791 cwp = (env->cwp + 1) & (NWINDOWS - 1);
792 if (env->wim & (1 << cwp)) {
793 raise_exception(TT_WIN_UNF);
795 set_cwp(cwp);
796 FORCE_RET();
798 #else
799 void OPPROTO op_rdccr(void)
801 T0 = GET_CCR(env);
804 void OPPROTO op_wrccr(void)
806 PUT_CCR(env, T0);
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
850 // order.
851 void OPPROTO op_rdcwp(void)
853 T0 = GET_CWP64(env);
856 void OPPROTO op_wrcwp(void)
858 PUT_CWP64(env, T0);
861 /* XXX: use another pointer for %iN registers to avoid slow wrapping
862 handling ? */
863 void OPPROTO op_save(void)
865 uint32_t cwp;
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)));
871 } else {
872 if (env->cleanwin - env->canrestore == 0) {
873 // XXX Clean windows without trap
874 raise_exception(TT_CLRWIN);
875 } else {
876 env->cansave--;
877 env->canrestore++;
878 set_cwp(cwp);
881 FORCE_RET();
884 void OPPROTO op_restore(void)
886 uint32_t cwp;
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)));
892 } else {
893 env->cansave++;
894 env->canrestore--;
895 set_cwp(cwp);
897 FORCE_RET();
899 #endif
901 void OPPROTO op_exception(void)
903 env->exception_index = PARAM1;
904 cpu_loop_exit();
905 FORCE_RET();
908 void OPPROTO op_fpexception_im(void)
910 env->exception_index = TT_FP_EXCP;
911 env->fsr &= ~FSR_FTT_MASK;
912 env->fsr |= PARAM1;
913 cpu_loop_exit();
914 FORCE_RET();
917 void OPPROTO op_eval_ba(void)
919 T2 = 1;
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);
931 T2 = Z | (N ^ V);
934 void OPPROTO op_eval_bl(void)
936 target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
938 T2 = N ^ V;
941 void OPPROTO op_eval_bleu(void)
943 target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
945 T2 = C | Z;
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)
960 T2 = 0;
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);
977 T2 = !(Z | (N ^ V));
980 void OPPROTO op_eval_bge(void)
982 target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
984 T2 = !(N ^ V);
987 void OPPROTO op_eval_bgu(void)
989 target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
991 T2 = !(C | Z);
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);
1019 T2 = Z | (N ^ V);
1022 void OPPROTO op_eval_xbl(void)
1024 target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1026 T2 = N ^ V;
1029 void OPPROTO op_eval_xbleu(void)
1031 target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1033 T2 = C | Z;
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);
1067 T2 = !(N ^ V);
1070 void OPPROTO op_eval_xbgu(void)
1072 target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1074 T2 = !(C | Z);
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);
1091 #endif
1093 #define FCC
1094 #define FFLAG_SET(x) (env->fsr & x? 1: 0)
1095 #include "fbranch_template.h"
1097 #ifdef TARGET_SPARC64
1098 #define FCC _fcc1
1099 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
1100 #include "fbranch_template.h"
1101 #define FCC _fcc2
1102 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
1103 #include "fbranch_template.h"
1104 #define FCC _fcc3
1105 #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
1106 #include "fbranch_template.h"
1107 #endif
1109 #ifdef TARGET_SPARC64
1110 void OPPROTO op_eval_brz(void)
1112 T2 = (T0 == 0);
1115 void OPPROTO op_eval_brnz(void)
1117 T2 = (T0 != 0);
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);
1139 #endif
1141 void OPPROTO op_jmp_label(void)
1143 GOTO_LABEL_PARAM(1);
1146 void OPPROTO op_jnz_T2_label(void)
1148 if (T2)
1149 GOTO_LABEL_PARAM(1);
1150 FORCE_RET();
1153 void OPPROTO op_jz_T2_label(void)
1155 if (!T2)
1156 GOTO_LABEL_PARAM(1);
1157 FORCE_RET();
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) \
1169 F_OP(name, s) \
1171 set_float_exception_flags(0, &env->fp_status); \
1172 FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
1173 check_ieee_exceptions(); \
1175 F_OP(name, d) \
1177 set_float_exception_flags(0, &env->fp_status); \
1178 DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
1179 check_ieee_exceptions(); \
1181 F_OP(name, q) \
1183 set_float_exception_flags(0, &env->fp_status); \
1184 QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \
1185 check_ieee_exceptions(); \
1187 #else
1188 #define F_BINOP(name) \
1189 F_OP(name, s) \
1191 set_float_exception_flags(0, &env->fp_status); \
1192 FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
1193 check_ieee_exceptions(); \
1195 F_OP(name, d) \
1197 set_float_exception_flags(0, &env->fp_status); \
1198 DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
1199 check_ieee_exceptions(); \
1201 #endif
1203 F_BINOP(add);
1204 F_BINOP(sub);
1205 F_BINOP(mul);
1206 F_BINOP(div);
1207 #undef F_BINOP
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),
1214 &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),
1224 &env->fp_status);
1225 check_ieee_exceptions();
1227 #endif
1229 #if defined(CONFIG_USER_ONLY)
1230 #define F_HELPER(name) \
1231 F_OP(name, s) \
1233 do_f##name##s(); \
1235 F_OP(name, d) \
1237 do_f##name##d(); \
1239 F_OP(name, q) \
1241 do_f##name##q(); \
1243 #else
1244 #define F_HELPER(name) \
1245 F_OP(name, s) \
1247 do_f##name##s(); \
1249 F_OP(name, d) \
1251 do_f##name##d(); \
1253 #endif
1255 F_HELPER(sqrt);
1257 F_OP(neg, s)
1259 FT0 = float32_chs(FT1);
1262 F_OP(abs, s)
1264 do_fabss();
1267 F_HELPER(cmp);
1268 F_HELPER(cmpe);
1270 #ifdef TARGET_SPARC64
1271 F_OP(neg, d)
1273 DT0 = float64_chs(DT1);
1276 F_OP(abs, d)
1278 do_fabsd();
1281 #if defined(CONFIG_USER_ONLY)
1282 F_OP(neg, q)
1284 QT0 = float128_chs(QT1);
1287 F_OP(abs, q)
1289 do_fabsd();
1291 #endif
1293 void OPPROTO op_fcmps_fcc1(void)
1295 do_fcmps_fcc1();
1298 void OPPROTO op_fcmpd_fcc1(void)
1300 do_fcmpd_fcc1();
1303 void OPPROTO op_fcmps_fcc2(void)
1305 do_fcmps_fcc2();
1308 void OPPROTO op_fcmpd_fcc2(void)
1310 do_fcmpd_fcc2();
1313 void OPPROTO op_fcmps_fcc3(void)
1315 do_fcmps_fcc3();
1318 void OPPROTO op_fcmpd_fcc3(void)
1320 do_fcmpd_fcc3();
1323 void OPPROTO op_fcmpes_fcc1(void)
1325 do_fcmpes_fcc1();
1328 void OPPROTO op_fcmped_fcc1(void)
1330 do_fcmped_fcc1();
1333 void OPPROTO op_fcmpes_fcc2(void)
1335 do_fcmpes_fcc2();
1338 void OPPROTO op_fcmped_fcc2(void)
1340 do_fcmped_fcc2();
1343 void OPPROTO op_fcmpes_fcc3(void)
1345 do_fcmpes_fcc3();
1348 void OPPROTO op_fcmped_fcc3(void)
1350 do_fcmped_fcc3();
1353 #if defined(CONFIG_USER_ONLY)
1354 void OPPROTO op_fcmpq_fcc1(void)
1356 do_fcmpq_fcc1();
1359 void OPPROTO op_fcmpq_fcc2(void)
1361 do_fcmpq_fcc2();
1364 void OPPROTO op_fcmpq_fcc3(void)
1366 do_fcmpq_fcc3();
1369 void OPPROTO op_fcmpeq_fcc1(void)
1371 do_fcmpeq_fcc1();
1374 void OPPROTO op_fcmpeq_fcc2(void)
1376 do_fcmpeq_fcc2();
1379 void OPPROTO op_fcmpeq_fcc3(void)
1381 do_fcmpeq_fcc3();
1383 #endif
1385 #endif
1387 /* Integer to float conversion. */
1388 #ifdef USE_INT_TO_FLOAT_HELPERS
1389 F_HELPER(ito);
1390 #ifdef TARGET_SPARC64
1391 F_HELPER(xto);
1392 #endif
1393 #else
1394 F_OP(ito, s)
1396 set_float_exception_flags(0, &env->fp_status);
1397 FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
1398 check_ieee_exceptions();
1401 F_OP(ito, d)
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)
1409 F_OP(ito, q)
1411 set_float_exception_flags(0, &env->fp_status);
1412 QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
1413 check_ieee_exceptions();
1415 #endif
1417 #ifdef TARGET_SPARC64
1418 F_OP(xto, s)
1420 set_float_exception_flags(0, &env->fp_status);
1421 FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
1422 check_ieee_exceptions();
1425 F_OP(xto, d)
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)
1432 F_OP(xto, q)
1434 set_float_exception_flags(0, &env->fp_status);
1435 QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
1436 check_ieee_exceptions();
1438 #endif
1439 #endif
1440 #endif
1441 #undef F_HELPER
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();
1486 #endif
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();
1510 #endif
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();
1534 #endif
1536 void OPPROTO op_fmovs_cc(void)
1538 if (T2)
1539 FT0 = FT1;
1542 void OPPROTO op_fmovd_cc(void)
1544 if (T2)
1545 DT0 = DT1;
1548 #if defined(CONFIG_USER_ONLY)
1549 void OPPROTO op_fmovq_cc(void)
1551 if (T2)
1552 QT0 = QT1;
1554 #endif
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)
1567 env->cansave++;
1568 if (env->otherwin == 0)
1569 env->canrestore--;
1570 else
1571 env->otherwin--;
1572 FORCE_RET();
1575 void OPPROTO op_restored(void)
1577 env->canrestore++;
1578 if (env->cleanwin < NWINDOWS - 1)
1579 env->cleanwin++;
1580 if (env->otherwin == 0)
1581 env->cansave--;
1582 else
1583 env->otherwin--;
1584 FORCE_RET();
1586 #endif
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()
1629 uint64_t tmp;
1631 tmp = T0 + T1;
1632 env->gsr &= ~7ULL;
1633 env->gsr |= tmp & 7ULL;
1634 T0 = tmp & ~7ULL;
1637 void OPPROTO op_faligndata()
1639 uint64_t tmp;
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)]
1763 #else
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]
1770 #endif
1772 typedef union {
1773 uint8_t b[8];
1774 uint16_t w[4];
1775 int16_t sw[4];
1776 uint32_t l[2];
1777 float64 d;
1778 } vis64;
1780 typedef union {
1781 uint8_t b[4];
1782 uint16_t w[2];
1783 uint32_t l;
1784 float32 f;
1785 } vis32;
1787 void OPPROTO op_fpmerge(void)
1789 vis64 s, d;
1791 s.d = DT0;
1792 d.d = DT1;
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);
1804 DT0 = d.d;
1807 void OPPROTO op_fmul8x16(void)
1809 vis64 s, d;
1810 uint32_t tmp;
1812 s.d = DT0;
1813 d.d = DT1;
1815 #define PMUL(r) \
1816 tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r); \
1817 if ((tmp & 0xff) > 0x7f) \
1818 tmp += 0x100; \
1819 d.VIS_W64(r) = tmp >> 8;
1821 PMUL(0);
1822 PMUL(1);
1823 PMUL(2);
1824 PMUL(3);
1825 #undef PMUL
1827 DT0 = d.d;
1830 void OPPROTO op_fmul8x16al(void)
1832 vis64 s, d;
1833 uint32_t tmp;
1835 s.d = DT0;
1836 d.d = DT1;
1838 #define PMUL(r) \
1839 tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r); \
1840 if ((tmp & 0xff) > 0x7f) \
1841 tmp += 0x100; \
1842 d.VIS_W64(r) = tmp >> 8;
1844 PMUL(0);
1845 PMUL(1);
1846 PMUL(2);
1847 PMUL(3);
1848 #undef PMUL
1850 DT0 = d.d;
1853 void OPPROTO op_fmul8x16au(void)
1855 vis64 s, d;
1856 uint32_t tmp;
1858 s.d = DT0;
1859 d.d = DT1;
1861 #define PMUL(r) \
1862 tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r); \
1863 if ((tmp & 0xff) > 0x7f) \
1864 tmp += 0x100; \
1865 d.VIS_W64(r) = tmp >> 8;
1867 PMUL(0);
1868 PMUL(1);
1869 PMUL(2);
1870 PMUL(3);
1871 #undef PMUL
1873 DT0 = d.d;
1876 void OPPROTO op_fmul8sux16(void)
1878 vis64 s, d;
1879 uint32_t tmp;
1881 s.d = DT0;
1882 d.d = DT1;
1884 #define PMUL(r) \
1885 tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
1886 if ((tmp & 0xff) > 0x7f) \
1887 tmp += 0x100; \
1888 d.VIS_W64(r) = tmp >> 8;
1890 PMUL(0);
1891 PMUL(1);
1892 PMUL(2);
1893 PMUL(3);
1894 #undef PMUL
1896 DT0 = d.d;
1899 void OPPROTO op_fmul8ulx16(void)
1901 vis64 s, d;
1902 uint32_t tmp;
1904 s.d = DT0;
1905 d.d = DT1;
1907 #define PMUL(r) \
1908 tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
1909 if ((tmp & 0xff) > 0x7f) \
1910 tmp += 0x100; \
1911 d.VIS_W64(r) = tmp >> 8;
1913 PMUL(0);
1914 PMUL(1);
1915 PMUL(2);
1916 PMUL(3);
1917 #undef PMUL
1919 DT0 = d.d;
1922 void OPPROTO op_fmuld8sux16(void)
1924 vis64 s, d;
1925 uint32_t tmp;
1927 s.d = DT0;
1928 d.d = DT1;
1930 #define PMUL(r) \
1931 tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
1932 if ((tmp & 0xff) > 0x7f) \
1933 tmp += 0x100; \
1934 d.VIS_L64(r) = tmp;
1936 // Reverse calculation order to handle overlap
1937 PMUL(1);
1938 PMUL(0);
1939 #undef PMUL
1941 DT0 = d.d;
1944 void OPPROTO op_fmuld8ulx16(void)
1946 vis64 s, d;
1947 uint32_t tmp;
1949 s.d = DT0;
1950 d.d = DT1;
1952 #define PMUL(r) \
1953 tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
1954 if ((tmp & 0xff) > 0x7f) \
1955 tmp += 0x100; \
1956 d.VIS_L64(r) = tmp;
1958 // Reverse calculation order to handle overlap
1959 PMUL(1);
1960 PMUL(0);
1961 #undef PMUL
1963 DT0 = d.d;
1966 void OPPROTO op_fexpand(void)
1968 vis32 s;
1969 vis64 d;
1971 s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff);
1972 d.d = DT1;
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;
1978 DT0 = d.d;
1981 #define VIS_OP(name, F) \
1982 void OPPROTO name##16(void) \
1984 vis64 s, d; \
1986 s.d = DT0; \
1987 d.d = DT1; \
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)); \
1994 DT0 = d.d; \
1997 void OPPROTO name##16s(void) \
1999 vis32 s, d; \
2001 s.f = FT0; \
2002 d.f = FT1; \
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)); \
2007 FT0 = d.f; \
2010 void OPPROTO name##32(void) \
2012 vis64 s, d; \
2014 s.d = DT0; \
2015 d.d = DT1; \
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)); \
2020 DT0 = d.d; \
2023 void OPPROTO name##32s(void) \
2025 vis32 s, d; \
2027 s.f = FT0; \
2028 d.f = FT1; \
2030 d.l = F(d.l, s.l); \
2032 FT0 = d.f; \
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) \
2043 vis64 s, d; \
2045 s.d = DT0; \
2046 d.d = DT1; \
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; \
2053 DT0 = d.d; \
2056 void OPPROTO name##32(void) \
2058 vis64 s, d; \
2060 s.d = DT0; \
2061 d.d = DT1; \
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; \
2066 DT0 = d.d; \
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)
2079 #endif
2081 #define CHECK_ALIGN_OP(align) \
2082 void OPPROTO op_check_align_T0_ ## align (void) \
2084 if (T0 & align) \
2085 raise_exception(TT_UNALIGNED); \
2086 FORCE_RET(); \
2089 CHECK_ALIGN_OP(1)
2090 CHECK_ALIGN_OP(3)
2091 CHECK_ALIGN_OP(7)