Commit 74637406444c9276ecc26de970ff9018fbfc8735

Authored by aurel32
1 parent 8d71247e

target-ppc: convert arithmetic functions to TCG

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5590 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/helper.h
@@ -8,6 +8,12 @@ DEF_HELPER(uint32_t, helper_fcmpu, (void)) @@ -8,6 +8,12 @@ DEF_HELPER(uint32_t, helper_fcmpu, (void))
8 DEF_HELPER(uint32_t, helper_load_cr, (void)) 8 DEF_HELPER(uint32_t, helper_load_cr, (void))
9 DEF_HELPER(void, helper_store_cr, (target_ulong, uint32_t)) 9 DEF_HELPER(void, helper_store_cr, (target_ulong, uint32_t))
10 10
  11 +#if defined(TARGET_PPC64)
  12 +DEF_HELPER(uint64_t, helper_mulhd, (uint64_t, uint64_t))
  13 +DEF_HELPER(uint64_t, helper_mulhdu, (uint64_t, uint64_t))
  14 +DEF_HELPER(uint64_t, helper_mulldo, (uint64_t, uint64_t))
  15 +#endif
  16 +
11 DEF_HELPER(target_ulong, helper_cntlzw, (target_ulong t)) 17 DEF_HELPER(target_ulong, helper_cntlzw, (target_ulong t))
12 DEF_HELPER(target_ulong, helper_popcntb, (target_ulong val)) 18 DEF_HELPER(target_ulong, helper_popcntb, (target_ulong val))
13 DEF_HELPER(target_ulong, helper_sraw, (target_ulong, target_ulong)) 19 DEF_HELPER(target_ulong, helper_sraw, (target_ulong, target_ulong))
target-ppc/op.c
@@ -354,404 +354,6 @@ void OPPROTO op_check_addo_64 (void) @@ -354,404 +354,6 @@ void OPPROTO op_check_addo_64 (void)
354 } 354 }
355 #endif 355 #endif
356 356
357 -/* add carrying */  
358 -void OPPROTO op_check_addc (void)  
359 -{  
360 - if (likely((uint32_t)T0 >= (uint32_t)T2)) {  
361 - env->xer &= ~(1 << XER_CA);  
362 - } else {  
363 - env->xer |= (1 << XER_CA);  
364 - }  
365 - RETURN();  
366 -}  
367 -  
368 -#if defined(TARGET_PPC64)  
369 -void OPPROTO op_check_addc_64 (void)  
370 -{  
371 - if (likely((uint64_t)T0 >= (uint64_t)T2)) {  
372 - env->xer &= ~(1 << XER_CA);  
373 - } else {  
374 - env->xer |= (1 << XER_CA);  
375 - }  
376 - RETURN();  
377 -}  
378 -#endif  
379 -  
380 -/* add extended */  
381 -void OPPROTO op_adde (void)  
382 -{  
383 - do_adde();  
384 - RETURN();  
385 -}  
386 -  
387 -#if defined(TARGET_PPC64)  
388 -void OPPROTO op_adde_64 (void)  
389 -{  
390 - do_adde_64();  
391 - RETURN();  
392 -}  
393 -#endif  
394 -  
395 -/* add to minus one extended */  
396 -void OPPROTO op_add_me (void)  
397 -{  
398 - T0 += xer_ca + (-1);  
399 - if (likely((uint32_t)T1 != 0))  
400 - env->xer |= (1 << XER_CA);  
401 - RETURN();  
402 -}  
403 -  
404 -#if defined(TARGET_PPC64)  
405 -void OPPROTO op_add_me_64 (void)  
406 -{  
407 - T0 += xer_ca + (-1);  
408 - if (likely((uint64_t)T1 != 0))  
409 - env->xer |= (1 << XER_CA);  
410 - RETURN();  
411 -}  
412 -#endif  
413 -  
414 -void OPPROTO op_addmeo (void)  
415 -{  
416 - do_addmeo();  
417 - RETURN();  
418 -}  
419 -  
420 -void OPPROTO op_addmeo_64 (void)  
421 -{  
422 - do_addmeo();  
423 - RETURN();  
424 -}  
425 -  
426 -/* add to zero extended */  
427 -void OPPROTO op_add_ze (void)  
428 -{  
429 - T0 += xer_ca;  
430 - RETURN();  
431 -}  
432 -  
433 -/* divide word */  
434 -void OPPROTO op_divw (void)  
435 -{  
436 - if (unlikely(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||  
437 - (int32_t)T1 == 0)) {  
438 - T0 = (int32_t)(UINT32_MAX * ((uint32_t)T0 >> 31));  
439 - } else {  
440 - T0 = (int32_t)T0 / (int32_t)T1;  
441 - }  
442 - RETURN();  
443 -}  
444 -  
445 -#if defined(TARGET_PPC64)  
446 -void OPPROTO op_divd (void)  
447 -{  
448 - if (unlikely(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||  
449 - (int64_t)T1 == 0)) {  
450 - T0 = (int64_t)(UINT64_MAX * ((uint64_t)T0 >> 63));  
451 - } else {  
452 - T0 = (int64_t)T0 / (int64_t)T1;  
453 - }  
454 - RETURN();  
455 -}  
456 -#endif  
457 -  
458 -void OPPROTO op_divwo (void)  
459 -{  
460 - do_divwo();  
461 - RETURN();  
462 -}  
463 -  
464 -#if defined(TARGET_PPC64)  
465 -void OPPROTO op_divdo (void)  
466 -{  
467 - do_divdo();  
468 - RETURN();  
469 -}  
470 -#endif  
471 -  
472 -/* divide word unsigned */  
473 -void OPPROTO op_divwu (void)  
474 -{  
475 - if (unlikely(T1 == 0)) {  
476 - T0 = 0;  
477 - } else {  
478 - T0 = (uint32_t)T0 / (uint32_t)T1;  
479 - }  
480 - RETURN();  
481 -}  
482 -  
483 -#if defined(TARGET_PPC64)  
484 -void OPPROTO op_divdu (void)  
485 -{  
486 - if (unlikely(T1 == 0)) {  
487 - T0 = 0;  
488 - } else {  
489 - T0 /= T1;  
490 - }  
491 - RETURN();  
492 -}  
493 -#endif  
494 -  
495 -void OPPROTO op_divwuo (void)  
496 -{  
497 - do_divwuo();  
498 - RETURN();  
499 -}  
500 -  
501 -#if defined(TARGET_PPC64)  
502 -void OPPROTO op_divduo (void)  
503 -{  
504 - do_divduo();  
505 - RETURN();  
506 -}  
507 -#endif  
508 -  
509 -/* multiply high word */  
510 -void OPPROTO op_mulhw (void)  
511 -{  
512 - T0 = ((int64_t)((int32_t)T0) * (int64_t)((int32_t)T1)) >> 32;  
513 - RETURN();  
514 -}  
515 -  
516 -#if defined(TARGET_PPC64)  
517 -void OPPROTO op_mulhd (void)  
518 -{  
519 - uint64_t tl, th;  
520 -  
521 - muls64(&tl, &th, T0, T1);  
522 - T0 = th;  
523 - RETURN();  
524 -}  
525 -#endif  
526 -  
527 -/* multiply high word unsigned */  
528 -void OPPROTO op_mulhwu (void)  
529 -{  
530 - T0 = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1) >> 32;  
531 - RETURN();  
532 -}  
533 -  
534 -#if defined(TARGET_PPC64)  
535 -void OPPROTO op_mulhdu (void)  
536 -{  
537 - uint64_t tl, th;  
538 -  
539 - mulu64(&tl, &th, T0, T1);  
540 - T0 = th;  
541 - RETURN();  
542 -}  
543 -#endif  
544 -  
545 -/* multiply low immediate */  
546 -void OPPROTO op_mulli (void)  
547 -{  
548 - T0 = ((int32_t)T0 * (int32_t)PARAM1);  
549 - RETURN();  
550 -}  
551 -  
552 -/* multiply low word */  
553 -void OPPROTO op_mullw (void)  
554 -{  
555 -#if defined(TARGET_PPC64)  
556 - T0 = (int64_t)(int32_t)T0 * (int64_t)(int32_t)T1;  
557 -#else  
558 - T0 = (int32_t)(T0 * T1);  
559 -#endif  
560 - RETURN();  
561 -}  
562 -  
563 -#if defined(TARGET_PPC64)  
564 -void OPPROTO op_mulld (void)  
565 -{  
566 - T0 *= T1;  
567 - RETURN();  
568 -}  
569 -#endif  
570 -  
571 -void OPPROTO op_mullwo (void)  
572 -{  
573 - do_mullwo();  
574 - RETURN();  
575 -}  
576 -  
577 -#if defined(TARGET_PPC64)  
578 -void OPPROTO op_mulldo (void)  
579 -{  
580 - do_mulldo();  
581 - RETURN();  
582 -}  
583 -#endif  
584 -  
585 -/* negate */  
586 -void OPPROTO op_neg (void)  
587 -{  
588 - if (likely(T0 != INT32_MIN)) {  
589 - T0 = -(int32_t)T0;  
590 - }  
591 - RETURN();  
592 -}  
593 -  
594 -#if defined(TARGET_PPC64)  
595 -void OPPROTO op_neg_64 (void)  
596 -{  
597 - if (likely(T0 != INT64_MIN)) {  
598 - T0 = -(int64_t)T0;  
599 - }  
600 - RETURN();  
601 -}  
602 -#endif  
603 -  
604 -void OPPROTO op_nego (void)  
605 -{  
606 - do_nego();  
607 - RETURN();  
608 -}  
609 -  
610 -#if defined(TARGET_PPC64)  
611 -void OPPROTO op_nego_64 (void)  
612 -{  
613 - do_nego_64();  
614 - RETURN();  
615 -}  
616 -#endif  
617 -  
618 -/* subtract from carrying */  
619 -void OPPROTO op_check_subfc (void)  
620 -{  
621 - if (likely((uint32_t)T0 > (uint32_t)T1)) {  
622 - env->xer &= ~(1 << XER_CA);  
623 - } else {  
624 - env->xer |= (1 << XER_CA);  
625 - }  
626 - RETURN();  
627 -}  
628 -  
629 -#if defined(TARGET_PPC64)  
630 -void OPPROTO op_check_subfc_64 (void)  
631 -{  
632 - if (likely((uint64_t)T0 > (uint64_t)T1)) {  
633 - env->xer &= ~(1 << XER_CA);  
634 - } else {  
635 - env->xer |= (1 << XER_CA);  
636 - }  
637 - RETURN();  
638 -}  
639 -#endif  
640 -  
641 -/* subtract from extended */  
642 -void OPPROTO op_subfe (void)  
643 -{  
644 - do_subfe();  
645 - RETURN();  
646 -}  
647 -  
648 -#if defined(TARGET_PPC64)  
649 -void OPPROTO op_subfe_64 (void)  
650 -{  
651 - do_subfe_64();  
652 - RETURN();  
653 -}  
654 -#endif  
655 -  
656 -/* subtract from immediate carrying */  
657 -void OPPROTO op_subfic (void)  
658 -{  
659 - T0 = (int32_t)PARAM1 + ~T0 + 1;  
660 - if ((uint32_t)T0 <= (uint32_t)PARAM1) {  
661 - env->xer |= (1 << XER_CA);  
662 - } else {  
663 - env->xer &= ~(1 << XER_CA);  
664 - }  
665 - RETURN();  
666 -}  
667 -  
668 -#if defined(TARGET_PPC64)  
669 -void OPPROTO op_subfic_64 (void)  
670 -{  
671 - T0 = (int64_t)PARAM1 + ~T0 + 1;  
672 - if ((uint64_t)T0 <= (uint64_t)PARAM1) {  
673 - env->xer |= (1 << XER_CA);  
674 - } else {  
675 - env->xer &= ~(1 << XER_CA);  
676 - }  
677 - RETURN();  
678 -}  
679 -#endif  
680 -  
681 -/* subtract from minus one extended */  
682 -void OPPROTO op_subfme (void)  
683 -{  
684 - T0 = ~T0 + xer_ca - 1;  
685 - if (likely((uint32_t)T0 != UINT32_MAX))  
686 - env->xer |= (1 << XER_CA);  
687 - RETURN();  
688 -}  
689 -  
690 -#if defined(TARGET_PPC64)  
691 -void OPPROTO op_subfme_64 (void)  
692 -{  
693 - T0 = ~T0 + xer_ca - 1;  
694 - if (likely((uint64_t)T0 != UINT64_MAX))  
695 - env->xer |= (1 << XER_CA);  
696 - RETURN();  
697 -}  
698 -#endif  
699 -  
700 -void OPPROTO op_subfmeo (void)  
701 -{  
702 - do_subfmeo();  
703 - RETURN();  
704 -}  
705 -  
706 -#if defined(TARGET_PPC64)  
707 -void OPPROTO op_subfmeo_64 (void)  
708 -{  
709 - do_subfmeo_64();  
710 - RETURN();  
711 -}  
712 -#endif  
713 -  
714 -/* subtract from zero extended */  
715 -void OPPROTO op_subfze (void)  
716 -{  
717 - T1 = ~T0;  
718 - T0 = T1 + xer_ca;  
719 - if ((uint32_t)T0 < (uint32_t)T1) {  
720 - env->xer |= (1 << XER_CA);  
721 - } else {  
722 - env->xer &= ~(1 << XER_CA);  
723 - }  
724 - RETURN();  
725 -}  
726 -  
727 -#if defined(TARGET_PPC64)  
728 -void OPPROTO op_subfze_64 (void)  
729 -{  
730 - T1 = ~T0;  
731 - T0 = T1 + xer_ca;  
732 - if ((uint64_t)T0 < (uint64_t)T1) {  
733 - env->xer |= (1 << XER_CA);  
734 - } else {  
735 - env->xer &= ~(1 << XER_CA);  
736 - }  
737 - RETURN();  
738 -}  
739 -#endif  
740 -  
741 -void OPPROTO op_subfzeo (void)  
742 -{  
743 - do_subfzeo();  
744 - RETURN();  
745 -}  
746 -  
747 -#if defined(TARGET_PPC64)  
748 -void OPPROTO op_subfzeo_64 (void)  
749 -{  
750 - do_subfzeo_64();  
751 - RETURN();  
752 -}  
753 -#endif  
754 -  
755 /*** Integer shift ***/ 357 /*** Integer shift ***/
756 void OPPROTO op_srli_T1 (void) 358 void OPPROTO op_srli_T1 (void)
757 { 359 {
target-ppc/op_helper.c
@@ -113,258 +113,39 @@ void ppc_store_dump_spr (int sprn, target_ulong val) @@ -113,258 +113,39 @@ void ppc_store_dump_spr (int sprn, target_ulong val)
113 113
114 /*****************************************************************************/ 114 /*****************************************************************************/
115 /* Fixed point operations helpers */ 115 /* Fixed point operations helpers */
116 -void do_adde (void)  
117 -{  
118 - T2 = T0;  
119 - T0 += T1 + xer_ca;  
120 - if (likely(!((uint32_t)T0 < (uint32_t)T2 ||  
121 - (xer_ca == 1 && (uint32_t)T0 == (uint32_t)T2)))) {  
122 - env->xer &= ~(1 << XER_CA);  
123 - } else {  
124 - env->xer |= (1 << XER_CA);  
125 - }  
126 -}  
127 -  
128 #if defined(TARGET_PPC64) 116 #if defined(TARGET_PPC64)
129 -void do_adde_64 (void)  
130 -{  
131 - T2 = T0;  
132 - T0 += T1 + xer_ca;  
133 - if (likely(!((uint64_t)T0 < (uint64_t)T2 ||  
134 - (xer_ca == 1 && (uint64_t)T0 == (uint64_t)T2)))) {  
135 - env->xer &= ~(1 << XER_CA);  
136 - } else {  
137 - env->xer |= (1 << XER_CA);  
138 - }  
139 -}  
140 -#endif  
141 117
142 -void do_addmeo (void) 118 +/* multiply high word */
  119 +uint64_t helper_mulhd (uint64_t arg1, uint64_t arg2)
143 { 120 {
144 - int ov;  
145 - T1 = T0;  
146 - T0 += xer_ca + (-1);  
147 - ov = ((uint32_t)T1 & ((uint32_t)T1 ^ (uint32_t)T0)) >> 31;  
148 - if (ov) {  
149 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
150 - } else {  
151 - env->xer &= ~(1 << XER_OV);  
152 - }  
153 - if (likely((uint32_t)T1 != 0))  
154 - env->xer |= (1 << XER_CA);  
155 -} 121 + uint64_t tl, th;
156 122
157 -#if defined(TARGET_PPC64)  
158 -void do_addmeo_64 (void)  
159 -{  
160 - int ov;  
161 - T1 = T0;  
162 - T0 += xer_ca + (-1);  
163 - ov = ((uint64_t)T1 & ((uint64_t)T1 ^ (uint64_t)T0)) >> 63;  
164 - if (ov) {  
165 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
166 - } else {  
167 - env->xer &= ~(1 << XER_OV);  
168 - }  
169 - if (likely((uint64_t)T1 != 0))  
170 - env->xer |= (1 << XER_CA); 123 + muls64(&tl, &th, arg1, arg2);
  124 + return th;
171 } 125 }
172 -#endif  
173 126
174 -void do_divwo (void) 127 +/* multiply high word unsigned */
  128 +uint64_t helper_mulhdu (uint64_t arg1, uint64_t arg2)
175 { 129 {
176 - if (likely(!(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||  
177 - (int32_t)T1 == 0))) {  
178 - env->xer &= ~(1 << XER_OV);  
179 - T0 = (int32_t)T0 / (int32_t)T1;  
180 - } else {  
181 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
182 - T0 = UINT32_MAX * ((uint32_t)T0 >> 31);  
183 - }  
184 -} 130 + uint64_t tl, th;
185 131
186 -#if defined(TARGET_PPC64)  
187 -void do_divdo (void)  
188 -{  
189 - if (likely(!(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||  
190 - (int64_t)T1 == 0))) {  
191 - env->xer &= ~(1 << XER_OV);  
192 - T0 = (int64_t)T0 / (int64_t)T1;  
193 - } else {  
194 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
195 - T0 = UINT64_MAX * ((uint64_t)T0 >> 63);  
196 - }  
197 -}  
198 -#endif  
199 -  
200 -void do_divwuo (void)  
201 -{  
202 - if (likely((uint32_t)T1 != 0)) {  
203 - env->xer &= ~(1 << XER_OV);  
204 - T0 = (uint32_t)T0 / (uint32_t)T1;  
205 - } else {  
206 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
207 - T0 = 0;  
208 - } 132 + mulu64(&tl, &th, arg1, arg2);
  133 + return th;
209 } 134 }
210 135
211 -#if defined(TARGET_PPC64)  
212 -void do_divduo (void)  
213 -{  
214 - if (likely((uint64_t)T1 != 0)) {  
215 - env->xer &= ~(1 << XER_OV);  
216 - T0 = (uint64_t)T0 / (uint64_t)T1;  
217 - } else {  
218 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
219 - T0 = 0;  
220 - }  
221 -}  
222 -#endif  
223 -  
224 -void do_mullwo (void)  
225 -{  
226 - int64_t res = (int64_t)(int32_t)T0 * (int64_t)(int32_t)T1;  
227 -  
228 - if (likely((int32_t)res == res)) {  
229 - env->xer &= ~(1 << XER_OV);  
230 - } else {  
231 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
232 - }  
233 - T0 = (int32_t)res;  
234 -}  
235 -  
236 -#if defined(TARGET_PPC64)  
237 -void do_mulldo (void) 136 +uint64_t helper_mulldo (uint64_t arg1, uint64_t arg2)
238 { 137 {
239 int64_t th; 138 int64_t th;
240 uint64_t tl; 139 uint64_t tl;
241 140
242 - muls64(&tl, (uint64_t *)&th, T0, T1);  
243 - T0 = (int64_t)tl; 141 + muls64(&tl, (uint64_t *)&th, arg1, arg2);
244 /* If th != 0 && th != -1, then we had an overflow */ 142 /* If th != 0 && th != -1, then we had an overflow */
245 if (likely((uint64_t)(th + 1) <= 1)) { 143 if (likely((uint64_t)(th + 1) <= 1)) {
246 env->xer &= ~(1 << XER_OV); 144 env->xer &= ~(1 << XER_OV);
247 } else { 145 } else {
248 env->xer |= (1 << XER_OV) | (1 << XER_SO); 146 env->xer |= (1 << XER_OV) | (1 << XER_SO);
249 } 147 }
250 -}  
251 -#endif  
252 -  
253 -void do_nego (void)  
254 -{  
255 - if (likely((int32_t)T0 != INT32_MIN)) {  
256 - env->xer &= ~(1 << XER_OV);  
257 - T0 = -(int32_t)T0;  
258 - } else {  
259 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
260 - }  
261 -}  
262 -  
263 -#if defined(TARGET_PPC64)  
264 -void do_nego_64 (void)  
265 -{  
266 - if (likely((int64_t)T0 != INT64_MIN)) {  
267 - env->xer &= ~(1 << XER_OV);  
268 - T0 = -(int64_t)T0;  
269 - } else {  
270 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
271 - }  
272 -}  
273 -#endif  
274 -  
275 -void do_subfe (void)  
276 -{  
277 - T0 = T1 + ~T0 + xer_ca;  
278 - if (likely((uint32_t)T0 >= (uint32_t)T1 &&  
279 - (xer_ca == 0 || (uint32_t)T0 != (uint32_t)T1))) {  
280 - env->xer &= ~(1 << XER_CA);  
281 - } else {  
282 - env->xer |= (1 << XER_CA);  
283 - }  
284 -}  
285 -  
286 -#if defined(TARGET_PPC64)  
287 -void do_subfe_64 (void)  
288 -{  
289 - T0 = T1 + ~T0 + xer_ca;  
290 - if (likely((uint64_t)T0 >= (uint64_t)T1 &&  
291 - (xer_ca == 0 || (uint64_t)T0 != (uint64_t)T1))) {  
292 - env->xer &= ~(1 << XER_CA);  
293 - } else {  
294 - env->xer |= (1 << XER_CA);  
295 - }  
296 -}  
297 -#endif  
298 -  
299 -void do_subfmeo (void)  
300 -{  
301 - int ov;  
302 - T1 = T0;  
303 - T0 = ~T0 + xer_ca - 1;  
304 - ov = ((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0)) >> 31;  
305 - if (ov) {  
306 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
307 - } else {  
308 - env->xer &= ~(1 << XER_OV);  
309 - }  
310 - if (likely((uint32_t)T1 != UINT32_MAX))  
311 - env->xer |= (1 << XER_CA);  
312 -}  
313 -  
314 -#if defined(TARGET_PPC64)  
315 -void do_subfmeo_64 (void)  
316 -{  
317 - int ov;  
318 - T1 = T0;  
319 - T0 = ~T0 + xer_ca - 1;  
320 - ov = ((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0)) >> 63;  
321 - if (ov) {  
322 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
323 - } else {  
324 - env->xer &= ~(1 << XER_OV);  
325 - }  
326 - if (likely((uint64_t)T1 != UINT64_MAX))  
327 - env->xer |= (1 << XER_CA);  
328 -}  
329 -#endif  
330 -  
331 -void do_subfzeo (void)  
332 -{  
333 - int ov;  
334 - T1 = T0;  
335 - T0 = ~T0 + xer_ca;  
336 - ov = (((uint32_t)~T1 ^ UINT32_MAX) &  
337 - ((uint32_t)(~T1) ^ (uint32_t)T0)) >> 31;  
338 - if (ov) {  
339 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
340 - } else {  
341 - env->xer &= ~(1 << XER_OV);  
342 - }  
343 - if (likely((uint32_t)T0 >= (uint32_t)~T1)) {  
344 - env->xer &= ~(1 << XER_CA);  
345 - } else {  
346 - env->xer |= (1 << XER_CA);  
347 - }  
348 -}  
349 -  
350 -#if defined(TARGET_PPC64)  
351 -void do_subfzeo_64 (void)  
352 -{  
353 - int ov;  
354 - T1 = T0;  
355 - T0 = ~T0 + xer_ca;  
356 - ov = (((uint64_t)~T1 ^ UINT64_MAX) &  
357 - ((uint64_t)(~T1) ^ (uint64_t)T0)) >> 63;  
358 - if (ov) {  
359 - env->xer |= (1 << XER_OV) | (1 << XER_SO);  
360 - } else {  
361 - env->xer &= ~(1 << XER_OV);  
362 - }  
363 - if (likely((uint64_t)T0 >= (uint64_t)~T1)) {  
364 - env->xer &= ~(1 << XER_CA);  
365 - } else {  
366 - env->xer |= (1 << XER_CA);  
367 - } 148 + return (int64_t)tl;
368 } 149 }
369 #endif 150 #endif
370 151
target-ppc/op_helper.h
@@ -61,38 +61,6 @@ void do_store_fpscr (uint32_t mask); @@ -61,38 +61,6 @@ void do_store_fpscr (uint32_t mask);
61 target_ulong ppc_load_dump_spr (int sprn); 61 target_ulong ppc_load_dump_spr (int sprn);
62 void ppc_store_dump_spr (int sprn, target_ulong val); 62 void ppc_store_dump_spr (int sprn, target_ulong val);
63 63
64 -/* Integer arithmetic helpers */  
65 -void do_adde (void);  
66 -void do_addmeo (void);  
67 -void do_divwo (void);  
68 -void do_divwuo (void);  
69 -void do_mullwo (void);  
70 -void do_nego (void);  
71 -void do_subfe (void);  
72 -void do_subfmeo (void);  
73 -void do_subfzeo (void);  
74 -void do_cntlzw (void);  
75 -#if defined(TARGET_PPC64)  
76 -void do_cntlzd (void);  
77 -#endif  
78 -void do_sraw (void);  
79 -#if defined(TARGET_PPC64)  
80 -void do_adde_64 (void);  
81 -void do_addmeo_64 (void);  
82 -void do_divdo (void);  
83 -void do_divduo (void);  
84 -void do_mulldo (void);  
85 -void do_nego_64 (void);  
86 -void do_subfe_64 (void);  
87 -void do_subfmeo_64 (void);  
88 -void do_subfzeo_64 (void);  
89 -void do_srad (void);  
90 -#endif  
91 -void do_popcntb (void);  
92 -#if defined(TARGET_PPC64)  
93 -void do_popcntb_64 (void);  
94 -#endif  
95 -  
96 /* Floating-point arithmetic helpers */ 64 /* Floating-point arithmetic helpers */
97 void do_compute_fprf (int set_class); 65 void do_compute_fprf (int set_class);
98 #ifdef CONFIG_SOFTFLOAT 66 #ifdef CONFIG_SOFTFLOAT
target-ppc/translate.c
@@ -852,431 +852,603 @@ GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL) @@ -852,431 +852,603 @@ GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
852 } 852 }
853 853
854 /*** Integer arithmetic ***/ 854 /*** Integer arithmetic ***/
855 -#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type) \  
856 -GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \  
857 -{ \  
858 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); \  
859 - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); \  
860 - gen_op_##name(); \  
861 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); \  
862 - if (unlikely(Rc(ctx->opcode) != 0)) \  
863 - gen_set_Rc0(ctx, cpu_T[0]); \  
864 -}  
865 855
866 -#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type) \  
867 -GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \  
868 -{ \  
869 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); \  
870 - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); \  
871 - gen_op_##name(); \  
872 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); \  
873 - if (unlikely(Rc(ctx->opcode) != 0)) \  
874 - gen_set_Rc0(ctx, cpu_T[0]); \  
875 -} 856 +static always_inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0, TCGv arg1, TCGv arg2, int sub)
  857 +{
  858 + int l1;
  859 + TCGv t0;
876 860
877 -#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \  
878 -GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \  
879 -{ \  
880 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); \  
881 - gen_op_##name(); \  
882 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); \  
883 - if (unlikely(Rc(ctx->opcode) != 0)) \  
884 - gen_set_Rc0(ctx, cpu_T[0]); \ 861 + l1 = gen_new_label();
  862 + /* Start with XER OV disabled, the most likely case */
  863 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
  864 + t0 = tcg_temp_local_new(TCG_TYPE_TL);
  865 + tcg_gen_xor_tl(t0, arg0, arg1);
  866 +#if defined(TARGET_PPC64)
  867 + if (!ctx->sf_mode)
  868 + tcg_gen_ext32s_tl(t0, t0);
  869 +#endif
  870 + if (sub)
  871 + tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
  872 + else
  873 + tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
  874 + tcg_gen_xor_tl(t0, arg1, arg2);
  875 +#if defined(TARGET_PPC64)
  876 + if (!ctx->sf_mode)
  877 + tcg_gen_ext32s_tl(t0, t0);
  878 +#endif
  879 + if (sub)
  880 + tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
  881 + else
  882 + tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
  883 + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
  884 + gen_set_label(l1);
  885 + tcg_temp_free(t0);
885 } 886 }
886 -#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type) \  
887 -GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \  
888 -{ \  
889 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); \  
890 - gen_op_##name(); \  
891 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); \  
892 - if (unlikely(Rc(ctx->opcode) != 0)) \  
893 - gen_set_Rc0(ctx, cpu_T[0]); \ 887 +
  888 +static always_inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1, TCGv arg2, int sub)
  889 +{
  890 + int l1 = gen_new_label();
  891 +
  892 +#if defined(TARGET_PPC64)
  893 + if (!(ctx->sf_mode)) {
  894 + TCGv t0, t1;
  895 + t0 = tcg_temp_new(TCG_TYPE_TL);
  896 + t1 = tcg_temp_new(TCG_TYPE_TL);
  897 +
  898 + tcg_gen_ext32u_tl(t0, arg1);
  899 + tcg_gen_ext32u_tl(t1, arg2);
  900 + if (sub) {
  901 + tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
  902 + } else {
  903 + tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
  904 + }
  905 + } else
  906 +#endif
  907 + if (sub) {
  908 + tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
  909 + } else {
  910 + tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
  911 + }
  912 + tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
  913 + gen_set_label(l1);
894 } 914 }
895 915
896 -/* Two operands arithmetic functions */  
897 -#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type) \  
898 -__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type) \  
899 -__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type) 916 +/* Common add function */
  917 +static always_inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
  918 + int add_ca, int compute_ca, int compute_ov)
  919 +{
  920 + TCGv t0, t1;
900 921
901 -/* Two operands arithmetic functions with no overflow allowed */  
902 -#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type) \  
903 -__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type) 922 + if ((!compute_ca && !compute_ov) ||
  923 + (GET_TCGV(ret) != GET_TCGV(arg1) && GET_TCGV(ret) != GET_TCGV(arg2))) {
  924 + t0 = ret;
  925 + } else {
  926 + t0 = tcg_temp_local_new(TCG_TYPE_TL);
  927 + }
904 928
905 -/* One operand arithmetic functions */  
906 -#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \  
907 -__GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \  
908 -__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type) 929 + if (add_ca) {
  930 + t1 = tcg_temp_local_new(TCG_TYPE_TL);
  931 + tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
  932 + tcg_gen_shri_tl(t1, t1, XER_CA);
  933 + }
909 934
910 -#if defined(TARGET_PPC64)  
911 -#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type) \  
912 -GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \  
913 -{ \  
914 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); \  
915 - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); \  
916 - if (ctx->sf_mode) \  
917 - gen_op_##name##_64(); \  
918 - else \  
919 - gen_op_##name(); \  
920 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); \  
921 - if (unlikely(Rc(ctx->opcode) != 0)) \  
922 - gen_set_Rc0(ctx, cpu_T[0]); \  
923 -} 935 + if (compute_ca && compute_ov) {
  936 + /* Start with XER CA and OV disabled, the most likely case */
  937 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
  938 + } else if (compute_ca) {
  939 + /* Start with XER CA disabled, the most likely case */
  940 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
  941 + } else if (compute_ov) {
  942 + /* Start with XER OV disabled, the most likely case */
  943 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
  944 + }
924 945
925 -#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type) \  
926 -GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \  
927 -{ \  
928 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); \  
929 - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); \  
930 - if (ctx->sf_mode) \  
931 - gen_op_##name##_64(); \  
932 - else \  
933 - gen_op_##name(); \  
934 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); \  
935 - if (unlikely(Rc(ctx->opcode) != 0)) \  
936 - gen_set_Rc0(ctx, cpu_T[0]); \  
937 -} 946 + tcg_gen_add_tl(t0, arg1, arg2);
938 947
939 -#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \  
940 -GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \  
941 -{ \  
942 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); \  
943 - if (ctx->sf_mode) \  
944 - gen_op_##name##_64(); \  
945 - else \  
946 - gen_op_##name(); \  
947 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); \  
948 - if (unlikely(Rc(ctx->opcode) != 0)) \  
949 - gen_set_Rc0(ctx, cpu_T[0]); \ 948 + if (compute_ca) {
  949 + gen_op_arith_compute_ca(ctx, t0, arg1, 0);
  950 + }
  951 + if (add_ca) {
  952 + tcg_gen_add_tl(t0, t0, t1);
  953 + gen_op_arith_compute_ca(ctx, t0, t1, 0);
  954 + tcg_temp_free(t1);
  955 + }
  956 + if (compute_ov) {
  957 + gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
  958 + }
  959 +
  960 + if (unlikely(Rc(ctx->opcode) != 0))
  961 + gen_set_Rc0(ctx, t0);
  962 +
  963 + if (GET_TCGV(t0) != GET_TCGV(ret)) {
  964 + tcg_gen_mov_tl(ret, t0);
  965 + tcg_temp_free(t0);
  966 + }
950 } 967 }
951 -#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type) \  
952 -GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \ 968 +/* Add functions with two operands */
  969 +#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov) \
  970 +GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER) \
953 { \ 971 { \
954 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); \  
955 - if (ctx->sf_mode) \  
956 - gen_op_##name##_64(); \  
957 - else \  
958 - gen_op_##name(); \  
959 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); \  
960 - if (unlikely(Rc(ctx->opcode) != 0)) \  
961 - gen_set_Rc0(ctx, cpu_T[0]); \ 972 + gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
  973 + cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
  974 + add_ca, compute_ca, compute_ov); \
  975 +}
  976 +/* Add functions with one operand and one immediate */
  977 +#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, \
  978 + add_ca, compute_ca, compute_ov) \
  979 +GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER) \
  980 +{ \
  981 + TCGv t0 = tcg_const_local_tl(const_val); \
  982 + gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
  983 + cpu_gpr[rA(ctx->opcode)], t0, \
  984 + add_ca, compute_ca, compute_ov); \
  985 + tcg_temp_free(t0); \
962 } 986 }
963 987
964 -/* Two operands arithmetic functions */  
965 -#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type) \  
966 -__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type) \  
967 -__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type) 988 +/* add add. addo addo. */
  989 +GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
  990 +GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
  991 +/* addc addc. addco addco. */
  992 +GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
  993 +GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
  994 +/* adde adde. addeo addeo. */
  995 +GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
  996 +GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
  997 +/* addme addme. addmeo addmeo. */
  998 +GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
  999 +GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
  1000 +/* addze addze. addzeo addzeo.*/
  1001 +GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
  1002 +GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
  1003 +/* addi */
  1004 +GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
  1005 +{
  1006 + target_long simm = SIMM(ctx->opcode);
968 1007
969 -/* Two operands arithmetic functions with no overflow allowed */  
970 -#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type) \  
971 -__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type) 1008 + if (rA(ctx->opcode) == 0) {
  1009 + /* li case */
  1010 + tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
  1011 + } else {
  1012 + tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm);
  1013 + }
  1014 +}
  1015 +/* addic addic.*/
  1016 +static always_inline void gen_op_addic (DisasContext *ctx, TCGv ret, TCGv arg1,
  1017 + int compute_Rc0)
  1018 +{
  1019 + target_long simm = SIMM(ctx->opcode);
972 1020
973 -/* One operand arithmetic functions */  
974 -#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \  
975 -__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \  
976 -__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)  
977 -#else  
978 -#define GEN_INT_ARITH2_64 GEN_INT_ARITH2  
979 -#define GEN_INT_ARITHN_64 GEN_INT_ARITHN  
980 -#define GEN_INT_ARITH1_64 GEN_INT_ARITH1  
981 -#endif 1021 + /* Start with XER CA and OV disabled, the most likely case */
  1022 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
982 1023
983 -/* add add. addo addo. */  
984 -static always_inline void gen_op_add (void)  
985 -{  
986 - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1024 + if (likely(simm != 0)) {
  1025 + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
  1026 + tcg_gen_addi_tl(t0, arg1, simm);
  1027 + gen_op_arith_compute_ca(ctx, t0, arg1, 0);
  1028 + tcg_gen_mov_tl(ret, t0);
  1029 + tcg_temp_free(t0);
  1030 + } else {
  1031 + tcg_gen_mov_tl(ret, arg1);
  1032 + }
  1033 + if (compute_Rc0) {
  1034 + gen_set_Rc0(ctx, ret);
  1035 + }
987 } 1036 }
988 -static always_inline void gen_op_addo (void) 1037 +GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
989 { 1038 {
990 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
991 - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);  
992 - gen_op_check_addo(); 1039 + gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
993 } 1040 }
994 -#if defined(TARGET_PPC64)  
995 -#define gen_op_add_64 gen_op_add  
996 -static always_inline void gen_op_addo_64 (void) 1041 +GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
997 { 1042 {
998 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
999 - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);  
1000 - gen_op_check_addo_64(); 1043 + gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
1001 } 1044 }
1002 -#endif  
1003 -GEN_INT_ARITH2_64 (add, 0x1F, 0x0A, 0x08, PPC_INTEGER);  
1004 -/* addc addc. addco addco. */  
1005 -static always_inline void gen_op_addc (void) 1045 +/* addis */
  1046 +GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1006 { 1047 {
1007 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1008 - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);  
1009 - gen_op_check_addc(); 1048 + target_long simm = SIMM(ctx->opcode);
  1049 +
  1050 + if (rA(ctx->opcode) == 0) {
  1051 + /* lis case */
  1052 + tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
  1053 + } else {
  1054 + tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm << 16);
  1055 + }
1010 } 1056 }
1011 -static always_inline void gen_op_addco (void) 1057 +
  1058 +static always_inline void gen_op_arith_divw (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
  1059 + int sign, int compute_ov)
1012 { 1060 {
1013 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1014 - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);  
1015 - gen_op_check_addc();  
1016 - gen_op_check_addo();  
1017 -} 1061 + int l1, l2, l3;
  1062 + TCGv t0, t1, t2;
  1063 +
1018 #if defined(TARGET_PPC64) 1064 #if defined(TARGET_PPC64)
1019 -static always_inline void gen_op_addc_64 (void)  
1020 -{  
1021 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1022 - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);  
1023 - gen_op_check_addc_64();  
1024 -}  
1025 -static always_inline void gen_op_addco_64 (void)  
1026 -{  
1027 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1028 - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);  
1029 - gen_op_check_addc_64();  
1030 - gen_op_check_addo_64();  
1031 -} 1065 + t0 = tcg_temp_local_new(TCG_TYPE_I32);
  1066 + t1 = t0;
  1067 + t2 = tcg_temp_local_new(TCG_TYPE_I32);
  1068 + tcg_gen_trunc_i64_i32(t1, arg1);
  1069 + tcg_gen_trunc_i64_i32(t2, arg2);
  1070 +#else
  1071 + t0 = ret;
  1072 + t1 = arg1;
  1073 + t2 = arg2;
1032 #endif 1074 #endif
1033 -GEN_INT_ARITH2_64 (addc, 0x1F, 0x0A, 0x00, PPC_INTEGER);  
1034 -/* adde adde. addeo addeo. */  
1035 -static always_inline void gen_op_addeo (void)  
1036 -{  
1037 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1038 - gen_op_adde();  
1039 - gen_op_check_addo();  
1040 -} 1075 + l1 = gen_new_label();
  1076 + l2 = gen_new_label();
  1077 + tcg_gen_brcondi_i32(TCG_COND_EQ, t2, 0, l1);
  1078 + if (sign) {
  1079 + l3 = gen_new_label();
  1080 + tcg_gen_brcondi_i32(TCG_COND_NE, t2, -1, l3);
  1081 + tcg_gen_brcondi_i32(TCG_COND_EQ, t1, INT32_MIN, l1);
  1082 + gen_set_label(l3);
  1083 + }
  1084 + if (sign) {
  1085 + tcg_gen_div_i32(t0, t1, t2);
  1086 + } else {
  1087 + tcg_gen_divu_i32(t0, t1, t2);
  1088 + }
  1089 + if (compute_ov) {
  1090 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
  1091 + }
  1092 + tcg_gen_br(l2);
  1093 + gen_set_label(l1);
  1094 + if (sign) {
  1095 + tcg_gen_sari_i32(t0, t1, 31);
  1096 + } else {
  1097 + tcg_gen_movi_i32(t0, 0);
  1098 + }
  1099 + if (compute_ov) {
  1100 + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
  1101 + }
  1102 + gen_set_label(l2);
1041 #if defined(TARGET_PPC64) 1103 #if defined(TARGET_PPC64)
1042 -static always_inline void gen_op_addeo_64 (void)  
1043 -{  
1044 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1045 - gen_op_adde_64();  
1046 - gen_op_check_addo_64();  
1047 -} 1104 + tcg_gen_extu_i32_i64(ret, t0);
  1105 + tcg_temp_free(t0);
1048 #endif 1106 #endif
1049 -GEN_INT_ARITH2_64 (adde, 0x1F, 0x0A, 0x04, PPC_INTEGER);  
1050 -/* addme addme. addmeo addmeo. */  
1051 -static always_inline void gen_op_addme (void)  
1052 -{  
1053 - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);  
1054 - gen_op_add_me(); 1107 + if (unlikely(Rc(ctx->opcode) != 0))
  1108 + gen_set_Rc0(ctx, ret);
1055 } 1109 }
  1110 +/* Div functions */
  1111 +#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov) \
  1112 +GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER) \
  1113 +{ \
  1114 + gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)], \
  1115 + cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
  1116 + sign, compute_ov); \
  1117 +}
  1118 +/* divwu divwu. divwuo divwuo. */
  1119 +GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
  1120 +GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
  1121 +/* divw divw. divwo divwo. */
  1122 +GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
  1123 +GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
1056 #if defined(TARGET_PPC64) 1124 #if defined(TARGET_PPC64)
1057 -static always_inline void gen_op_addme_64 (void) 1125 +static always_inline void gen_op_divd (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
  1126 + int sign, int compute_ov)
1058 { 1127 {
1059 - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);  
1060 - gen_op_add_me_64(); 1128 + int l1, l2, l3;
  1129 +
  1130 + l1 = gen_new_label();
  1131 + l2 = gen_new_label();
  1132 +
  1133 + tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
  1134 + if (sign) {
  1135 + l3 = gen_new_label();
  1136 + tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
  1137 + tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
  1138 + gen_set_label(l3);
  1139 + }
  1140 + if (sign) {
  1141 + tcg_gen_div_i64(ret, arg1, arg2);
  1142 + } else {
  1143 + tcg_gen_divu_i64(ret, arg1, arg2);
  1144 + }
  1145 + if (compute_ov) {
  1146 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
  1147 + }
  1148 + tcg_gen_br(l2);
  1149 + gen_set_label(l1);
  1150 + if (sign) {
  1151 + tcg_gen_sari_i64(ret, arg1, 63);
  1152 + } else {
  1153 + tcg_gen_movi_i64(ret, 0);
  1154 + }
  1155 + if (compute_ov) {
  1156 + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
  1157 + }
  1158 + gen_set_label(l2);
  1159 + if (unlikely(Rc(ctx->opcode) != 0))
  1160 + gen_set_Rc0(ctx, ret);
1061 } 1161 }
  1162 +#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov) \
  1163 +GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B) \
  1164 +{ \
  1165 + gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)], \
  1166 + cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
  1167 + sign, compute_ov); \
  1168 +}
  1169 +/* divwu divwu. divwuo divwuo. */
  1170 +GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
  1171 +GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
  1172 +/* divw divw. divwo divwo. */
  1173 +GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
  1174 +GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1062 #endif 1175 #endif
1063 -GEN_INT_ARITH1_64 (addme, 0x1F, 0x0A, 0x07, PPC_INTEGER);  
1064 -/* addze addze. addzeo addzeo. */  
1065 -static always_inline void gen_op_addze (void) 1176 +
  1177 +/* mulhw mulhw. */
  1178 +GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER)
1066 { 1179 {
1067 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1068 - gen_op_add_ze();  
1069 - gen_op_check_addc(); 1180 + TCGv t0, t1;
  1181 +
  1182 + t0 = tcg_temp_new(TCG_TYPE_I64);
  1183 + t1 = tcg_temp_new(TCG_TYPE_I64);
  1184 +#if defined(TARGET_PPC64)
  1185 + tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
  1186 + tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
  1187 + tcg_gen_mul_i64(t0, t0, t1);
  1188 + tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
  1189 +#else
  1190 + tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
  1191 + tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
  1192 + tcg_gen_mul_i64(t0, t0, t1);
  1193 + tcg_gen_shri_i64(t0, t0, 32);
  1194 + tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
  1195 +#endif
  1196 + tcg_temp_free(t0);
  1197 + tcg_temp_free(t1);
  1198 + if (unlikely(Rc(ctx->opcode) != 0))
  1199 + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1070 } 1200 }
1071 -static always_inline void gen_op_addzeo (void) 1201 +/* mulhwu mulhwu. */
  1202 +GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER)
1072 { 1203 {
1073 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1074 - gen_op_add_ze();  
1075 - gen_op_check_addc();  
1076 - gen_op_check_addo();  
1077 -} 1204 + TCGv t0, t1;
  1205 +
  1206 + t0 = tcg_temp_new(TCG_TYPE_I64);
  1207 + t1 = tcg_temp_new(TCG_TYPE_I64);
1078 #if defined(TARGET_PPC64) 1208 #if defined(TARGET_PPC64)
1079 -static always_inline void gen_op_addze_64 (void)  
1080 -{  
1081 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1082 - gen_op_add_ze();  
1083 - gen_op_check_addc_64(); 1209 + tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
  1210 + tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
  1211 + tcg_gen_mul_i64(t0, t0, t1);
  1212 + tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
  1213 +#else
  1214 + tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
  1215 + tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
  1216 + tcg_gen_mul_i64(t0, t0, t1);
  1217 + tcg_gen_shri_i64(t0, t0, 32);
  1218 + tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
  1219 +#endif
  1220 + tcg_temp_free(t0);
  1221 + tcg_temp_free(t1);
  1222 + if (unlikely(Rc(ctx->opcode) != 0))
  1223 + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1084 } 1224 }
1085 -static always_inline void gen_op_addzeo_64 (void) 1225 +/* mullw mullw. */
  1226 +GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER)
1086 { 1227 {
1087 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1088 - gen_op_add_ze();  
1089 - gen_op_check_addc_64();  
1090 - gen_op_check_addo_64();  
1091 -} 1228 +#if defined(TARGET_PPC64)
  1229 + TCGv t0, t1;
  1230 + t0 = tcg_temp_new(TCG_TYPE_TL);
  1231 + t1 = tcg_temp_new(TCG_TYPE_TL);
  1232 + tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
  1233 + tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
  1234 + tcg_gen_mul_tl(t0, t0, t1);
  1235 + tcg_temp_free(t0);
  1236 + tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], t0);
  1237 + tcg_temp_free(t1);
  1238 +#else
  1239 + tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
  1240 + cpu_gpr[rB(ctx->opcode)]);
1092 #endif 1241 #endif
1093 -GEN_INT_ARITH1_64 (addze, 0x1F, 0x0A, 0x06, PPC_INTEGER);  
1094 -/* divw divw. divwo divwo. */  
1095 -GEN_INT_ARITH2 (divw, 0x1F, 0x0B, 0x0F, PPC_INTEGER);  
1096 -/* divwu divwu. divwuo divwuo. */  
1097 -GEN_INT_ARITH2 (divwu, 0x1F, 0x0B, 0x0E, PPC_INTEGER);  
1098 -/* mulhw mulhw. */  
1099 -GEN_INT_ARITHN (mulhw, 0x1F, 0x0B, 0x02, PPC_INTEGER);  
1100 -/* mulhwu mulhwu. */  
1101 -GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);  
1102 -/* mullw mullw. mullwo mullwo. */  
1103 -GEN_INT_ARITH2 (mullw, 0x1F, 0x0B, 0x07, PPC_INTEGER);  
1104 -/* neg neg. nego nego. */  
1105 -GEN_INT_ARITH1_64 (neg, 0x1F, 0x08, 0x03, PPC_INTEGER);  
1106 -/* subf subf. subfo subfo. */  
1107 -static always_inline void gen_op_subf (void)  
1108 -{  
1109 - tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]); 1242 + if (unlikely(Rc(ctx->opcode) != 0))
  1243 + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1110 } 1244 }
1111 -static always_inline void gen_op_subfo (void) 1245 +/* mullwo mullwo. */
  1246 +GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER)
1112 { 1247 {
1113 - tcg_gen_not_tl(cpu_T[2], cpu_T[0]);  
1114 - tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);  
1115 - gen_op_check_addo();  
1116 -} 1248 + int l1;
  1249 + TCGv t0, t1;
  1250 +
  1251 + t0 = tcg_temp_local_new(TCG_TYPE_I64);
  1252 + t1 = tcg_temp_local_new(TCG_TYPE_I64);
  1253 + l1 = gen_new_label();
  1254 + /* Start with XER OV disabled, the most likely case */
  1255 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1117 #if defined(TARGET_PPC64) 1256 #if defined(TARGET_PPC64)
1118 -#define gen_op_subf_64 gen_op_subf  
1119 -static always_inline void gen_op_subfo_64 (void)  
1120 -{  
1121 - tcg_gen_not_i64(cpu_T[2], cpu_T[0]);  
1122 - tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);  
1123 - gen_op_check_addo_64();  
1124 -} 1257 + tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx->opcode)]);
  1258 + tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx->opcode)]);
  1259 +#else
  1260 + tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
  1261 + tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1125 #endif 1262 #endif
1126 -GEN_INT_ARITH2_64 (subf, 0x1F, 0x08, 0x01, PPC_INTEGER);  
1127 -/* subfc subfc. subfco subfco. */  
1128 -static always_inline void gen_op_subfc (void)  
1129 -{  
1130 - tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);  
1131 - gen_op_check_subfc(); 1263 + tcg_gen_mul_i64(t0, t0, t1);
  1264 +#if defined(TARGET_PPC64)
  1265 + tcg_gen_ext32s_i64(cpu_gpr[rD(ctx->opcode)], t0);
  1266 + tcg_gen_brcond_i64(TCG_COND_EQ, t0, cpu_gpr[rD(ctx->opcode)], l1);
  1267 +#else
  1268 + tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
  1269 + tcg_gen_ext32s_i64(t1, t0);
  1270 + tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
  1271 +#endif
  1272 + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
  1273 + gen_set_label(l1);
  1274 + if (unlikely(Rc(ctx->opcode) != 0))
  1275 + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1132 } 1276 }
1133 -static always_inline void gen_op_subfco (void) 1277 +/* mulli */
  1278 +GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1134 { 1279 {
1135 - tcg_gen_not_tl(cpu_T[2], cpu_T[0]);  
1136 - tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);  
1137 - gen_op_check_subfc();  
1138 - gen_op_check_addo(); 1280 + tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
  1281 + SIMM(ctx->opcode));
1139 } 1282 }
1140 #if defined(TARGET_PPC64) 1283 #if defined(TARGET_PPC64)
1141 -static always_inline void gen_op_subfc_64 (void)  
1142 -{  
1143 - tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);  
1144 - gen_op_check_subfc_64(); 1284 +#define GEN_INT_ARITH_MUL_HELPER(name, opc3) \
  1285 +GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B) \
  1286 +{ \
  1287 + tcg_gen_helper_1_2(helper_##name, cpu_gpr[rD(ctx->opcode)], \
  1288 + cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \
  1289 + if (unlikely(Rc(ctx->opcode) != 0)) \
  1290 + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); \
1145 } 1291 }
1146 -static always_inline void gen_op_subfco_64 (void) 1292 +/* mulhd mulhd. */
  1293 +GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00);
  1294 +/* mulhdu mulhdu. */
  1295 +GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02);
  1296 +/* mulld mulld. */
  1297 +GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B)
1147 { 1298 {
1148 - tcg_gen_not_i64(cpu_T[2], cpu_T[0]);  
1149 - tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);  
1150 - gen_op_check_subfc_64();  
1151 - gen_op_check_addo_64(); 1299 + tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
  1300 + cpu_gpr[rB(ctx->opcode)]);
  1301 + if (unlikely(Rc(ctx->opcode) != 0))
  1302 + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1152 } 1303 }
  1304 +/* mulldo mulldo. */
  1305 +GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17);
1153 #endif 1306 #endif
1154 -GEN_INT_ARITH2_64 (subfc, 0x1F, 0x08, 0x00, PPC_INTEGER);  
1155 -/* subfe subfe. subfeo subfeo. */  
1156 -static always_inline void gen_op_subfeo (void) 1307 +
  1308 +/* neg neg. nego nego. */
  1309 +static always_inline void gen_op_neg (DisasContext *ctx, TCGv ret, TCGv arg1, int ov_check)
1157 { 1310 {
1158 - tcg_gen_not_tl(cpu_T[2], cpu_T[0]);  
1159 - gen_op_subfe();  
1160 - gen_op_check_addo();  
1161 -} 1311 + int l1, l2;
  1312 +
  1313 + l1 = gen_new_label();
  1314 + l2 = gen_new_label();
1162 #if defined(TARGET_PPC64) 1315 #if defined(TARGET_PPC64)
1163 -#define gen_op_subfe_64 gen_op_subfe  
1164 -static always_inline void gen_op_subfeo_64 (void) 1316 + if (ctx->sf_mode) {
  1317 + tcg_gen_brcondi_tl(TCG_COND_EQ, arg1, INT64_MIN, l1);
  1318 + } else {
  1319 + TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
  1320 + tcg_gen_ext32s_tl(t0, arg1);
  1321 + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
  1322 + }
  1323 +#else
  1324 + tcg_gen_brcondi_tl(TCG_COND_EQ, arg1, INT32_MIN, l1);
  1325 +#endif
  1326 + tcg_gen_neg_tl(ret, arg1);
  1327 + if (ov_check) {
  1328 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
  1329 + }
  1330 + tcg_gen_br(l2);
  1331 + gen_set_label(l1);
  1332 + tcg_gen_mov_tl(ret, arg1);
  1333 + if (ov_check) {
  1334 + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
  1335 + }
  1336 + gen_set_label(l2);
  1337 + if (unlikely(Rc(ctx->opcode) != 0))
  1338 + gen_set_Rc0(ctx, ret);
  1339 +}
  1340 +GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER)
1165 { 1341 {
1166 - tcg_gen_not_i64(cpu_T[2], cpu_T[0]);  
1167 - gen_op_subfe_64();  
1168 - gen_op_check_addo_64(); 1342 + gen_op_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
1169 } 1343 }
1170 -#endif  
1171 -GEN_INT_ARITH2_64 (subfe, 0x1F, 0x08, 0x04, PPC_INTEGER);  
1172 -/* subfme subfme. subfmeo subfmeo. */  
1173 -GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);  
1174 -/* subfze subfze. subfzeo subfzeo. */  
1175 -GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);  
1176 -/* addi */  
1177 -GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) 1344 +GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER)
1178 { 1345 {
1179 - target_long simm = SIMM(ctx->opcode);  
1180 -  
1181 - if (rA(ctx->opcode) == 0) {  
1182 - /* li case */  
1183 - tcg_gen_movi_tl(cpu_T[0], simm);  
1184 - } else {  
1185 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);  
1186 - if (likely(simm != 0))  
1187 - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);  
1188 - }  
1189 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); 1346 + gen_op_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
1190 } 1347 }
1191 -/* addic */  
1192 -GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) 1348 +
  1349 +/* Common subf function */
  1350 +static always_inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
  1351 + int add_ca, int compute_ca, int compute_ov)
1193 { 1352 {
1194 - target_long simm = SIMM(ctx->opcode); 1353 + TCGv t0, t1;
1195 1354
1196 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);  
1197 - if (likely(simm != 0)) {  
1198 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1199 - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);  
1200 -#if defined(TARGET_PPC64)  
1201 - if (ctx->sf_mode)  
1202 - gen_op_check_addc_64();  
1203 - else  
1204 -#endif  
1205 - gen_op_check_addc(); 1355 + if ((!compute_ca && !compute_ov) ||
  1356 + (GET_TCGV(ret) != GET_TCGV(arg1) && GET_TCGV(ret) != GET_TCGV(arg2))) {
  1357 + t0 = ret;
1206 } else { 1358 } else {
1207 - tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA)); 1359 + t0 = tcg_temp_local_new(TCG_TYPE_TL);
1208 } 1360 }
1209 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);  
1210 -}  
1211 -/* addic. */  
1212 -GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)  
1213 -{  
1214 - target_long simm = SIMM(ctx->opcode);  
1215 1361
1216 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);  
1217 - if (likely(simm != 0)) {  
1218 - tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);  
1219 - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);  
1220 -#if defined(TARGET_PPC64)  
1221 - if (ctx->sf_mode)  
1222 - gen_op_check_addc_64();  
1223 - else  
1224 -#endif  
1225 - gen_op_check_addc();  
1226 - } else {  
1227 - tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA)); 1362 + if (add_ca) {
  1363 + t1 = tcg_temp_local_new(TCG_TYPE_TL);
  1364 + tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
  1365 + tcg_gen_shri_tl(t1, t1, XER_CA);
1228 } 1366 }
1229 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);  
1230 - gen_set_Rc0(ctx, cpu_T[0]);  
1231 -}  
1232 -/* addis */  
1233 -GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)  
1234 -{  
1235 - target_long simm = SIMM(ctx->opcode);  
1236 1367
1237 - if (rA(ctx->opcode) == 0) {  
1238 - /* lis case */  
1239 - tcg_gen_movi_tl(cpu_T[0], simm << 16); 1368 + if (compute_ca && compute_ov) {
  1369 + /* Start with XER CA and OV disabled, the most likely case */
  1370 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
  1371 + } else if (compute_ca) {
  1372 + /* Start with XER CA disabled, the most likely case */
  1373 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
  1374 + } else if (compute_ov) {
  1375 + /* Start with XER OV disabled, the most likely case */
  1376 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
  1377 + }
  1378 +
  1379 + if (add_ca) {
  1380 + tcg_gen_not_tl(t0, arg1);
  1381 + tcg_gen_add_tl(t0, t0, arg2);
  1382 + gen_op_arith_compute_ca(ctx, t0, arg2, 0);
  1383 + tcg_gen_add_tl(t0, t0, t1);
  1384 + gen_op_arith_compute_ca(ctx, t0, t1, 0);
  1385 + tcg_temp_free(t1);
1240 } else { 1386 } else {
1241 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);  
1242 - if (likely(simm != 0))  
1243 - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm << 16); 1387 + tcg_gen_sub_tl(t0, arg2, arg1);
  1388 + if (compute_ca) {
  1389 + gen_op_arith_compute_ca(ctx, t0, arg2, 1);
  1390 + }
  1391 + }
  1392 + if (compute_ov) {
  1393 + gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
  1394 + }
  1395 +
  1396 + if (unlikely(Rc(ctx->opcode) != 0))
  1397 + gen_set_Rc0(ctx, t0);
  1398 +
  1399 + if (GET_TCGV(t0) != GET_TCGV(ret)) {
  1400 + tcg_gen_mov_tl(ret, t0);
  1401 + tcg_temp_free(t0);
1244 } 1402 }
1245 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);  
1246 } 1403 }
1247 -/* mulli */  
1248 -GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)  
1249 -{  
1250 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);  
1251 - gen_op_mulli(SIMM(ctx->opcode));  
1252 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); 1404 +/* Sub functions with Two operands functions */
  1405 +#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \
  1406 +GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER) \
  1407 +{ \
  1408 + gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
  1409 + cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
  1410 + add_ca, compute_ca, compute_ov); \
  1411 +}
  1412 +/* Sub functions with one operand and one immediate */
  1413 +#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \
  1414 + add_ca, compute_ca, compute_ov) \
  1415 +GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER) \
  1416 +{ \
  1417 + TCGv t0 = tcg_const_local_tl(const_val); \
  1418 + gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
  1419 + cpu_gpr[rA(ctx->opcode)], t0, \
  1420 + add_ca, compute_ca, compute_ov); \
  1421 + tcg_temp_free(t0); \
1253 } 1422 }
  1423 +/* subf subf. subfo subfo. */
  1424 +GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
  1425 +GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
  1426 +/* subfc subfc. subfco subfco. */
  1427 +GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
  1428 +GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
  1429 +/* subfe subfe. subfeo subfo. */
  1430 +GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
  1431 +GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
  1432 +/* subfme subfme. subfmeo subfmeo. */
  1433 +GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
  1434 +GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
  1435 +/* subfze subfze. subfzeo subfzeo.*/
  1436 +GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
  1437 +GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1254 /* subfic */ 1438 /* subfic */
1255 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) 1439 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1256 { 1440 {
1257 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);  
1258 -#if defined(TARGET_PPC64)  
1259 - if (ctx->sf_mode)  
1260 - gen_op_subfic_64(SIMM(ctx->opcode));  
1261 - else  
1262 -#endif  
1263 - gen_op_subfic(SIMM(ctx->opcode));  
1264 - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); 1441 + /* Start with XER CA and OV disabled, the most likely case */
  1442 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
  1443 + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
  1444 + TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
  1445 + tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
  1446 + gen_op_arith_compute_ca(ctx, t0, t1, 1);
  1447 + tcg_temp_free(t1);
  1448 + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
  1449 + tcg_temp_free(t0);
1265 } 1450 }
1266 1451
1267 -#if defined(TARGET_PPC64)  
1268 -/* mulhd mulhd. */  
1269 -GEN_INT_ARITHN (mulhd, 0x1F, 0x09, 0x02, PPC_64B);  
1270 -/* mulhdu mulhdu. */  
1271 -GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);  
1272 -/* mulld mulld. mulldo mulldo. */  
1273 -GEN_INT_ARITH2 (mulld, 0x1F, 0x09, 0x07, PPC_64B);  
1274 -/* divd divd. divdo divdo. */  
1275 -GEN_INT_ARITH2 (divd, 0x1F, 0x09, 0x0F, PPC_64B);  
1276 -/* divdu divdu. divduo divduo. */  
1277 -GEN_INT_ARITH2 (divdu, 0x1F, 0x09, 0x0E, PPC_64B);  
1278 -#endif  
1279 -  
1280 /*** Integer logical ***/ 1452 /*** Integer logical ***/
1281 #define GEN_LOGICAL2(name, tcg_op, opc, type) \ 1453 #define GEN_LOGICAL2(name, tcg_op, opc, type) \
1282 GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type) \ 1454 GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type) \
@@ -5090,7 +5262,7 @@ static always_inline void gen_405_mulladd_insn (DisasContext *ctx, @@ -5090,7 +5262,7 @@ static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
5090 } 5262 }
5091 if (opc2 & 0x02) { 5263 if (opc2 & 0x02) {
5092 /* nmultiply-and-accumulate (0x0E) */ 5264 /* nmultiply-and-accumulate (0x0E) */
5093 - gen_op_neg(); 5265 + tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
5094 } 5266 }
5095 if (opc2 & 0x04) { 5267 if (opc2 & 0x04) {
5096 /* (n)multiply-and-accumulate (0x0C - 0x0E) */ 5268 /* (n)multiply-and-accumulate (0x0C - 0x0E) */