Commit 3d7b417e13152587df587fe58789740c3ef7abb9

Authored by aurel32
1 parent d75a0b97

target-ppc: Convert XER accesses to TCG

Define XER bits as a single register and access them individually to
avoid defining 5 32-bit registers (TCG doesn't permit to map 8-bit
registers).

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

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5500 c046a42c-6fe2-441c-8c8c-71466251a162
gdbstub.c
@@ -445,7 +445,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) @@ -445,7 +445,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
445 } 445 }
446 case 67: GET_REGL(env->lr); 446 case 67: GET_REGL(env->lr);
447 case 68: GET_REGL(env->ctr); 447 case 68: GET_REGL(env->ctr);
448 - case 69: GET_REG32(ppc_load_xer(env)); 448 + case 69: GET_REGL(env->xer);
449 case 70: GET_REG32(0); /* fpscr */ 449 case 70: GET_REG32(0); /* fpscr */
450 } 450 }
451 } 451 }
@@ -485,8 +485,8 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) @@ -485,8 +485,8 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
485 env->ctr = ldtul_p(mem_buf); 485 env->ctr = ldtul_p(mem_buf);
486 return sizeof(target_ulong); 486 return sizeof(target_ulong);
487 case 69: 487 case 69:
488 - ppc_store_xer(env, ldl_p(mem_buf));  
489 - return 4; 488 + env->xer = ldtul_p(mem_buf);
  489 + return sizeof(target_ulong);
490 case 70: 490 case 70:
491 /* fpscr */ 491 /* fpscr */
492 return 4; 492 return 4;
monitor.c
@@ -1582,7 +1582,7 @@ static target_long monitor_get_xer (const struct MonitorDef *md, int val) @@ -1582,7 +1582,7 @@ static target_long monitor_get_xer (const struct MonitorDef *md, int val)
1582 CPUState *env = mon_get_cpu(); 1582 CPUState *env = mon_get_cpu();
1583 if (!env) 1583 if (!env)
1584 return 0; 1584 return 0;
1585 - return ppc_load_xer(env); 1585 + return env->xer;
1586 } 1586 }
1587 1587
1588 static target_long monitor_get_decr (const struct MonitorDef *md, int val) 1588 static target_long monitor_get_decr (const struct MonitorDef *md, int val)
target-ppc/cpu.h
@@ -553,8 +553,7 @@ struct CPUPPCState { @@ -553,8 +553,7 @@ struct CPUPPCState {
553 /* condition register */ 553 /* condition register */
554 uint32_t crf[8]; 554 uint32_t crf[8];
555 /* XER */ 555 /* XER */
556 - /* XXX: We use only 5 fields, but we want to keep the structure aligned */  
557 - uint8_t xer[8]; 556 + target_ulong xer;
558 /* Reservation address */ 557 /* Reservation address */
559 target_ulong reserve; 558 target_ulong reserve;
560 559
@@ -831,16 +830,16 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) @@ -831,16 +830,16 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
831 830
832 /*****************************************************************************/ 831 /*****************************************************************************/
833 /* Registers definitions */ 832 /* Registers definitions */
834 -#define XER_SO 31  
835 -#define XER_OV 30  
836 -#define XER_CA 29  
837 -#define XER_CMP 8  
838 -#define XER_BC 0  
839 -#define xer_so env->xer[4]  
840 -#define xer_ov env->xer[6]  
841 -#define xer_ca env->xer[2]  
842 -#define xer_cmp env->xer[1]  
843 -#define xer_bc env->xer[0] 833 +#define XER_SO 31
  834 +#define XER_OV 30
  835 +#define XER_CA 29
  836 +#define XER_CMP 8
  837 +#define XER_BC 0
  838 +#define xer_so ((env->xer >> XER_SO) & 1)
  839 +#define xer_ov ((env->xer >> XER_OV) & 1)
  840 +#define xer_ca ((env->xer >> XER_CA) & 1)
  841 +#define xer_cmp ((env->xer >> XER_CMP) & 0xFF)
  842 +#define xer_bc ((env->xer >> XER_BC) & 0x7F)
844 843
845 /* SPR definitions */ 844 /* SPR definitions */
846 #define SPR_MQ (0x000) 845 #define SPR_MQ (0x000)
target-ppc/helper.c
@@ -2124,16 +2124,6 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value) @@ -2124,16 +2124,6 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
2124 } 2124 }
2125 #endif /* !defined (CONFIG_USER_ONLY) */ 2125 #endif /* !defined (CONFIG_USER_ONLY) */
2126 2126
2127 -target_ulong ppc_load_xer (CPUPPCState *env)  
2128 -{  
2129 - return hreg_load_xer(env);  
2130 -}  
2131 -  
2132 -void ppc_store_xer (CPUPPCState *env, target_ulong value)  
2133 -{  
2134 - hreg_store_xer(env, value);  
2135 -}  
2136 -  
2137 /* GDBstub can read and write MSR... */ 2127 /* GDBstub can read and write MSR... */
2138 void ppc_store_msr (CPUPPCState *env, target_ulong value) 2128 void ppc_store_msr (CPUPPCState *env, target_ulong value)
2139 { 2129 {
target-ppc/helper_regs.h
@@ -21,24 +21,6 @@ @@ -21,24 +21,6 @@
21 #if !defined(__HELPER_REGS_H__) 21 #if !defined(__HELPER_REGS_H__)
22 #define __HELPER_REGS_H__ 22 #define __HELPER_REGS_H__
23 23
24 -static always_inline target_ulong hreg_load_xer (CPUPPCState *env)  
25 -{  
26 - return (xer_so << XER_SO) |  
27 - (xer_ov << XER_OV) |  
28 - (xer_ca << XER_CA) |  
29 - (xer_bc << XER_BC) |  
30 - (xer_cmp << XER_CMP);  
31 -}  
32 -  
33 -static always_inline void hreg_store_xer (CPUPPCState *env, target_ulong value)  
34 -{  
35 - xer_so = (value >> XER_SO) & 0x01;  
36 - xer_ov = (value >> XER_OV) & 0x01;  
37 - xer_ca = (value >> XER_CA) & 0x01;  
38 - xer_cmp = (value >> XER_CMP) & 0xFF;  
39 - xer_bc = (value >> XER_BC) & 0x7F;  
40 -}  
41 -  
42 /* Swap temporary saved registers with GPRs */ 24 /* Swap temporary saved registers with GPRs */
43 static always_inline void hreg_swap_gpr_tgpr (CPUPPCState *env) 25 static always_inline void hreg_swap_gpr_tgpr (CPUPPCState *env)
44 { 26 {
target-ppc/op.c
@@ -58,49 +58,6 @@ void OPPROTO op_store_cr (void) @@ -58,49 +58,6 @@ void OPPROTO op_store_cr (void)
58 RETURN(); 58 RETURN();
59 } 59 }
60 60
61 -void OPPROTO op_load_xer_cr (void)  
62 -{  
63 - T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);  
64 - RETURN();  
65 -}  
66 -  
67 -void OPPROTO op_clear_xer_ov (void)  
68 -{  
69 - xer_so = 0;  
70 - xer_ov = 0;  
71 - RETURN();  
72 -}  
73 -  
74 -void OPPROTO op_clear_xer_ca (void)  
75 -{  
76 - xer_ca = 0;  
77 - RETURN();  
78 -}  
79 -  
80 -void OPPROTO op_load_xer_bc (void)  
81 -{  
82 - T1 = xer_bc;  
83 - RETURN();  
84 -}  
85 -  
86 -void OPPROTO op_store_xer_bc (void)  
87 -{  
88 - xer_bc = T0;  
89 - RETURN();  
90 -}  
91 -  
92 -void OPPROTO op_load_xer (void)  
93 -{  
94 - T0 = hreg_load_xer(env);  
95 - RETURN();  
96 -}  
97 -  
98 -void OPPROTO op_store_xer (void)  
99 -{  
100 - hreg_store_xer(env, T0);  
101 - RETURN();  
102 -}  
103 -  
104 #if defined(TARGET_PPC64) 61 #if defined(TARGET_PPC64)
105 void OPPROTO op_store_pri (void) 62 void OPPROTO op_store_pri (void)
106 { 63 {
@@ -574,18 +531,26 @@ void OPPROTO op_dec_ctr (void) @@ -574,18 +531,26 @@ void OPPROTO op_dec_ctr (void)
574 /* add */ 531 /* add */
575 void OPPROTO op_check_addo (void) 532 void OPPROTO op_check_addo (void)
576 { 533 {
577 - xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) & 534 + int ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
578 ((uint32_t)T2 ^ (uint32_t)T0)) >> 31; 535 ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
579 - xer_so |= xer_ov; 536 + if (ov) {
  537 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
  538 + } else {
  539 + env->xer &= ~(1 << XER_OV);
  540 + }
580 RETURN(); 541 RETURN();
581 } 542 }
582 543
583 #if defined(TARGET_PPC64) 544 #if defined(TARGET_PPC64)
584 void OPPROTO op_check_addo_64 (void) 545 void OPPROTO op_check_addo_64 (void)
585 { 546 {
586 - xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) & 547 + int ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
587 ((uint64_t)T2 ^ (uint64_t)T0)) >> 63; 548 ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
588 - xer_so |= xer_ov; 549 + if (ov) {
  550 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
  551 + } else {
  552 + env->xer &= ~(1 << XER_OV);
  553 + }
589 RETURN(); 554 RETURN();
590 } 555 }
591 #endif 556 #endif
@@ -594,9 +559,9 @@ void OPPROTO op_check_addo_64 (void) @@ -594,9 +559,9 @@ void OPPROTO op_check_addo_64 (void)
594 void OPPROTO op_check_addc (void) 559 void OPPROTO op_check_addc (void)
595 { 560 {
596 if (likely((uint32_t)T0 >= (uint32_t)T2)) { 561 if (likely((uint32_t)T0 >= (uint32_t)T2)) {
597 - xer_ca = 0; 562 + env->xer &= ~(1 << XER_CA);
598 } else { 563 } else {
599 - xer_ca = 1; 564 + env->xer |= (1 << XER_CA);
600 } 565 }
601 RETURN(); 566 RETURN();
602 } 567 }
@@ -605,9 +570,9 @@ void OPPROTO op_check_addc (void) @@ -605,9 +570,9 @@ void OPPROTO op_check_addc (void)
605 void OPPROTO op_check_addc_64 (void) 570 void OPPROTO op_check_addc_64 (void)
606 { 571 {
607 if (likely((uint64_t)T0 >= (uint64_t)T2)) { 572 if (likely((uint64_t)T0 >= (uint64_t)T2)) {
608 - xer_ca = 0; 573 + env->xer &= ~(1 << XER_CA);
609 } else { 574 } else {
610 - xer_ca = 1; 575 + env->xer |= (1 << XER_CA);
611 } 576 }
612 RETURN(); 577 RETURN();
613 } 578 }
@@ -633,7 +598,7 @@ void OPPROTO op_add_me (void) @@ -633,7 +598,7 @@ void OPPROTO op_add_me (void)
633 { 598 {
634 T0 += xer_ca + (-1); 599 T0 += xer_ca + (-1);
635 if (likely((uint32_t)T1 != 0)) 600 if (likely((uint32_t)T1 != 0))
636 - xer_ca = 1; 601 + env->xer |= (1 << XER_CA);
637 RETURN(); 602 RETURN();
638 } 603 }
639 604
@@ -642,7 +607,7 @@ void OPPROTO op_add_me_64 (void) @@ -642,7 +607,7 @@ void OPPROTO op_add_me_64 (void)
642 { 607 {
643 T0 += xer_ca + (-1); 608 T0 += xer_ca + (-1);
644 if (likely((uint64_t)T1 != 0)) 609 if (likely((uint64_t)T1 != 0))
645 - xer_ca = 1; 610 + env->xer |= (1 << XER_CA);
646 RETURN(); 611 RETURN();
647 } 612 }
648 #endif 613 #endif
@@ -855,9 +820,9 @@ void OPPROTO op_nego_64 (void) @@ -855,9 +820,9 @@ void OPPROTO op_nego_64 (void)
855 void OPPROTO op_check_subfc (void) 820 void OPPROTO op_check_subfc (void)
856 { 821 {
857 if (likely((uint32_t)T0 > (uint32_t)T1)) { 822 if (likely((uint32_t)T0 > (uint32_t)T1)) {
858 - xer_ca = 0; 823 + env->xer &= ~(1 << XER_CA);
859 } else { 824 } else {
860 - xer_ca = 1; 825 + env->xer |= (1 << XER_CA);
861 } 826 }
862 RETURN(); 827 RETURN();
863 } 828 }
@@ -866,9 +831,9 @@ void OPPROTO op_check_subfc (void) @@ -866,9 +831,9 @@ void OPPROTO op_check_subfc (void)
866 void OPPROTO op_check_subfc_64 (void) 831 void OPPROTO op_check_subfc_64 (void)
867 { 832 {
868 if (likely((uint64_t)T0 > (uint64_t)T1)) { 833 if (likely((uint64_t)T0 > (uint64_t)T1)) {
869 - xer_ca = 0; 834 + env->xer &= ~(1 << XER_CA);
870 } else { 835 } else {
871 - xer_ca = 1; 836 + env->xer |= (1 << XER_CA);
872 } 837 }
873 RETURN(); 838 RETURN();
874 } 839 }
@@ -894,9 +859,9 @@ void OPPROTO op_subfic (void) @@ -894,9 +859,9 @@ void OPPROTO op_subfic (void)
894 { 859 {
895 T0 = (int32_t)PARAM1 + ~T0 + 1; 860 T0 = (int32_t)PARAM1 + ~T0 + 1;
896 if ((uint32_t)T0 <= (uint32_t)PARAM1) { 861 if ((uint32_t)T0 <= (uint32_t)PARAM1) {
897 - xer_ca = 1; 862 + env->xer |= (1 << XER_CA);
898 } else { 863 } else {
899 - xer_ca = 0; 864 + env->xer &= ~(1 << XER_CA);
900 } 865 }
901 RETURN(); 866 RETURN();
902 } 867 }
@@ -906,9 +871,9 @@ void OPPROTO op_subfic_64 (void) @@ -906,9 +871,9 @@ void OPPROTO op_subfic_64 (void)
906 { 871 {
907 T0 = (int64_t)PARAM1 + ~T0 + 1; 872 T0 = (int64_t)PARAM1 + ~T0 + 1;
908 if ((uint64_t)T0 <= (uint64_t)PARAM1) { 873 if ((uint64_t)T0 <= (uint64_t)PARAM1) {
909 - xer_ca = 1; 874 + env->xer |= (1 << XER_CA);
910 } else { 875 } else {
911 - xer_ca = 0; 876 + env->xer &= ~(1 << XER_CA);
912 } 877 }
913 RETURN(); 878 RETURN();
914 } 879 }
@@ -919,7 +884,7 @@ void OPPROTO op_subfme (void) @@ -919,7 +884,7 @@ void OPPROTO op_subfme (void)
919 { 884 {
920 T0 = ~T0 + xer_ca - 1; 885 T0 = ~T0 + xer_ca - 1;
921 if (likely((uint32_t)T0 != UINT32_MAX)) 886 if (likely((uint32_t)T0 != UINT32_MAX))
922 - xer_ca = 1; 887 + env->xer |= (1 << XER_CA);
923 RETURN(); 888 RETURN();
924 } 889 }
925 890
@@ -928,7 +893,7 @@ void OPPROTO op_subfme_64 (void) @@ -928,7 +893,7 @@ void OPPROTO op_subfme_64 (void)
928 { 893 {
929 T0 = ~T0 + xer_ca - 1; 894 T0 = ~T0 + xer_ca - 1;
930 if (likely((uint64_t)T0 != UINT64_MAX)) 895 if (likely((uint64_t)T0 != UINT64_MAX))
931 - xer_ca = 1; 896 + env->xer |= (1 << XER_CA);
932 RETURN(); 897 RETURN();
933 } 898 }
934 #endif 899 #endif
@@ -953,9 +918,9 @@ void OPPROTO op_subfze (void) @@ -953,9 +918,9 @@ void OPPROTO op_subfze (void)
953 T1 = ~T0; 918 T1 = ~T0;
954 T0 = T1 + xer_ca; 919 T0 = T1 + xer_ca;
955 if ((uint32_t)T0 < (uint32_t)T1) { 920 if ((uint32_t)T0 < (uint32_t)T1) {
956 - xer_ca = 1; 921 + env->xer |= (1 << XER_CA);
957 } else { 922 } else {
958 - xer_ca = 0; 923 + env->xer &= ~(1 << XER_CA);
959 } 924 }
960 RETURN(); 925 RETURN();
961 } 926 }
@@ -966,9 +931,9 @@ void OPPROTO op_subfze_64 (void) @@ -966,9 +931,9 @@ void OPPROTO op_subfze_64 (void)
966 T1 = ~T0; 931 T1 = ~T0;
967 T0 = T1 + xer_ca; 932 T0 = T1 + xer_ca;
968 if ((uint64_t)T0 < (uint64_t)T1) { 933 if ((uint64_t)T0 < (uint64_t)T1) {
969 - xer_ca = 1; 934 + env->xer |= (1 << XER_CA);
970 } else { 935 } else {
971 - xer_ca = 0; 936 + env->xer &= ~(1 << XER_CA);
972 } 937 }
973 RETURN(); 938 RETURN();
974 } 939 }
@@ -1317,9 +1282,9 @@ void OPPROTO op_srawi (void) @@ -1317,9 +1282,9 @@ void OPPROTO op_srawi (void)
1317 1282
1318 T0 = (int32_t)T0 >> PARAM1; 1283 T0 = (int32_t)T0 >> PARAM1;
1319 if ((int32_t)T1 < 0 && (T1 & mask) != 0) { 1284 if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
1320 - xer_ca = 1; 1285 + env->xer |= (1 << XER_CA);
1321 } else { 1286 } else {
1322 - xer_ca = 0; 1287 + env->xer &= ~(1 << XER_CA);
1323 } 1288 }
1324 RETURN(); 1289 RETURN();
1325 } 1290 }
@@ -1331,9 +1296,9 @@ void OPPROTO op_sradi (void) @@ -1331,9 +1296,9 @@ void OPPROTO op_sradi (void)
1331 1296
1332 T0 = (int64_t)T0 >> PARAM1; 1297 T0 = (int64_t)T0 >> PARAM1;
1333 if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) { 1298 if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
1334 - xer_ca = 1; 1299 + env->xer |= (1 << XER_CA);
1335 } else { 1300 } else {
1336 - xer_ca = 0; 1301 + env->xer &= ~(1 << XER_CA);
1337 } 1302 }
1338 RETURN(); 1303 RETURN();
1339 } 1304 }
@@ -1975,7 +1940,7 @@ void OPPROTO op_POWER_nabso (void) @@ -1975,7 +1940,7 @@ void OPPROTO op_POWER_nabso (void)
1975 /* nabs never overflows */ 1940 /* nabs never overflows */
1976 if (T0 > 0) 1941 if (T0 > 0)
1977 T0 = -T0; 1942 T0 = -T0;
1978 - xer_ov = 0; 1943 + env->xer &= ~(1 << XER_OV);
1979 RETURN(); 1944 RETURN();
1980 } 1945 }
1981 1946
@@ -2189,10 +2154,9 @@ void OPPROTO op_405_check_sat (void) @@ -2189,10 +2154,9 @@ void OPPROTO op_405_check_sat (void)
2189 void OPPROTO op_405_check_ovu (void) 2154 void OPPROTO op_405_check_ovu (void)
2190 { 2155 {
2191 if (likely(T0 >= T2)) { 2156 if (likely(T0 >= T2)) {
2192 - xer_ov = 0; 2157 + env->xer &= ~(1 << XER_OV);
2193 } else { 2158 } else {
2194 - xer_ov = 1;  
2195 - xer_so = 1; 2159 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
2196 } 2160 }
2197 RETURN(); 2161 RETURN();
2198 } 2162 }
target-ppc/op_helper.c
@@ -119,9 +119,9 @@ void do_adde (void) @@ -119,9 +119,9 @@ void do_adde (void)
119 T0 += T1 + xer_ca; 119 T0 += T1 + xer_ca;
120 if (likely(!((uint32_t)T0 < (uint32_t)T2 || 120 if (likely(!((uint32_t)T0 < (uint32_t)T2 ||
121 (xer_ca == 1 && (uint32_t)T0 == (uint32_t)T2)))) { 121 (xer_ca == 1 && (uint32_t)T0 == (uint32_t)T2)))) {
122 - xer_ca = 0; 122 + env->xer &= ~(1 << XER_CA);
123 } else { 123 } else {
124 - xer_ca = 1; 124 + env->xer |= (1 << XER_CA);
125 } 125 }
126 } 126 }
127 127
@@ -132,32 +132,42 @@ void do_adde_64 (void) @@ -132,32 +132,42 @@ void do_adde_64 (void)
132 T0 += T1 + xer_ca; 132 T0 += T1 + xer_ca;
133 if (likely(!((uint64_t)T0 < (uint64_t)T2 || 133 if (likely(!((uint64_t)T0 < (uint64_t)T2 ||
134 (xer_ca == 1 && (uint64_t)T0 == (uint64_t)T2)))) { 134 (xer_ca == 1 && (uint64_t)T0 == (uint64_t)T2)))) {
135 - xer_ca = 0; 135 + env->xer &= ~(1 << XER_CA);
136 } else { 136 } else {
137 - xer_ca = 1; 137 + env->xer |= (1 << XER_CA);
138 } 138 }
139 } 139 }
140 #endif 140 #endif
141 141
142 void do_addmeo (void) 142 void do_addmeo (void)
143 { 143 {
  144 + int ov;
144 T1 = T0; 145 T1 = T0;
145 T0 += xer_ca + (-1); 146 T0 += xer_ca + (-1);
146 - xer_ov = ((uint32_t)T1 & ((uint32_t)T1 ^ (uint32_t)T0)) >> 31;  
147 - xer_so |= xer_ov; 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 + }
148 if (likely((uint32_t)T1 != 0)) 153 if (likely((uint32_t)T1 != 0))
149 - xer_ca = 1; 154 + env->xer |= (1 << XER_CA);
150 } 155 }
151 156
152 #if defined(TARGET_PPC64) 157 #if defined(TARGET_PPC64)
153 void do_addmeo_64 (void) 158 void do_addmeo_64 (void)
154 { 159 {
  160 + int ov;
155 T1 = T0; 161 T1 = T0;
156 T0 += xer_ca + (-1); 162 T0 += xer_ca + (-1);
157 - xer_ov = ((uint64_t)T1 & ((uint64_t)T1 ^ (uint64_t)T0)) >> 63;  
158 - xer_so |= xer_ov; 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 + }
159 if (likely((uint64_t)T1 != 0)) 169 if (likely((uint64_t)T1 != 0))
160 - xer_ca = 1; 170 + env->xer |= (1 << XER_CA);
161 } 171 }
162 #endif 172 #endif
163 173
@@ -165,13 +175,12 @@ void do_divwo (void) @@ -165,13 +175,12 @@ void do_divwo (void)
165 { 175 {
166 if (likely(!(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) || 176 if (likely(!(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
167 (int32_t)T1 == 0))) { 177 (int32_t)T1 == 0))) {
168 - xer_ov = 0; 178 + env->xer &= ~(1 << XER_OV);
169 T0 = (int32_t)T0 / (int32_t)T1; 179 T0 = (int32_t)T0 / (int32_t)T1;
170 } else { 180 } else {
171 - xer_ov = 1; 181 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
172 T0 = UINT32_MAX * ((uint32_t)T0 >> 31); 182 T0 = UINT32_MAX * ((uint32_t)T0 >> 31);
173 } 183 }
174 - xer_so |= xer_ov;  
175 } 184 }
176 185
177 #if defined(TARGET_PPC64) 186 #if defined(TARGET_PPC64)
@@ -179,24 +188,22 @@ void do_divdo (void) @@ -179,24 +188,22 @@ void do_divdo (void)
179 { 188 {
180 if (likely(!(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) || 189 if (likely(!(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
181 (int64_t)T1 == 0))) { 190 (int64_t)T1 == 0))) {
182 - xer_ov = 0; 191 + env->xer &= ~(1 << XER_OV);
183 T0 = (int64_t)T0 / (int64_t)T1; 192 T0 = (int64_t)T0 / (int64_t)T1;
184 } else { 193 } else {
185 - xer_ov = 1; 194 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
186 T0 = UINT64_MAX * ((uint64_t)T0 >> 63); 195 T0 = UINT64_MAX * ((uint64_t)T0 >> 63);
187 } 196 }
188 - xer_so |= xer_ov;  
189 } 197 }
190 #endif 198 #endif
191 199
192 void do_divwuo (void) 200 void do_divwuo (void)
193 { 201 {
194 if (likely((uint32_t)T1 != 0)) { 202 if (likely((uint32_t)T1 != 0)) {
195 - xer_ov = 0; 203 + env->xer &= ~(1 << XER_OV);
196 T0 = (uint32_t)T0 / (uint32_t)T1; 204 T0 = (uint32_t)T0 / (uint32_t)T1;
197 } else { 205 } else {
198 - xer_ov = 1;  
199 - xer_so = 1; 206 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
200 T0 = 0; 207 T0 = 0;
201 } 208 }
202 } 209 }
@@ -205,11 +212,10 @@ void do_divwuo (void) @@ -205,11 +212,10 @@ void do_divwuo (void)
205 void do_divduo (void) 212 void do_divduo (void)
206 { 213 {
207 if (likely((uint64_t)T1 != 0)) { 214 if (likely((uint64_t)T1 != 0)) {
208 - xer_ov = 0; 215 + env->xer &= ~(1 << XER_OV);
209 T0 = (uint64_t)T0 / (uint64_t)T1; 216 T0 = (uint64_t)T0 / (uint64_t)T1;
210 } else { 217 } else {
211 - xer_ov = 1;  
212 - xer_so = 1; 218 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
213 T0 = 0; 219 T0 = 0;
214 } 220 }
215 } 221 }
@@ -220,10 +226,9 @@ void do_mullwo (void) @@ -220,10 +226,9 @@ void do_mullwo (void)
220 int64_t res = (int64_t)(int32_t)T0 * (int64_t)(int32_t)T1; 226 int64_t res = (int64_t)(int32_t)T0 * (int64_t)(int32_t)T1;
221 227
222 if (likely((int32_t)res == res)) { 228 if (likely((int32_t)res == res)) {
223 - xer_ov = 0; 229 + env->xer &= ~(1 << XER_OV);
224 } else { 230 } else {
225 - xer_ov = 1;  
226 - xer_so = 1; 231 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
227 } 232 }
228 T0 = (int32_t)res; 233 T0 = (int32_t)res;
229 } 234 }
@@ -238,22 +243,20 @@ void do_mulldo (void) @@ -238,22 +243,20 @@ void do_mulldo (void)
238 T0 = (int64_t)tl; 243 T0 = (int64_t)tl;
239 /* If th != 0 && th != -1, then we had an overflow */ 244 /* If th != 0 && th != -1, then we had an overflow */
240 if (likely((uint64_t)(th + 1) <= 1)) { 245 if (likely((uint64_t)(th + 1) <= 1)) {
241 - xer_ov = 0; 246 + env->xer &= ~(1 << XER_OV);
242 } else { 247 } else {
243 - xer_ov = 1; 248 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
244 } 249 }
245 - xer_so |= xer_ov;  
246 } 250 }
247 #endif 251 #endif
248 252
249 void do_nego (void) 253 void do_nego (void)
250 { 254 {
251 if (likely((int32_t)T0 != INT32_MIN)) { 255 if (likely((int32_t)T0 != INT32_MIN)) {
252 - xer_ov = 0; 256 + env->xer &= ~(1 << XER_OV);
253 T0 = -(int32_t)T0; 257 T0 = -(int32_t)T0;
254 } else { 258 } else {
255 - xer_ov = 1;  
256 - xer_so = 1; 259 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
257 } 260 }
258 } 261 }
259 262
@@ -261,11 +264,10 @@ void do_nego (void) @@ -261,11 +264,10 @@ void do_nego (void)
261 void do_nego_64 (void) 264 void do_nego_64 (void)
262 { 265 {
263 if (likely((int64_t)T0 != INT64_MIN)) { 266 if (likely((int64_t)T0 != INT64_MIN)) {
264 - xer_ov = 0; 267 + env->xer &= ~(1 << XER_OV);
265 T0 = -(int64_t)T0; 268 T0 = -(int64_t)T0;
266 } else { 269 } else {
267 - xer_ov = 1;  
268 - xer_so = 1; 270 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
269 } 271 }
270 } 272 }
271 #endif 273 #endif
@@ -275,9 +277,9 @@ void do_subfe (void) @@ -275,9 +277,9 @@ void do_subfe (void)
275 T0 = T1 + ~T0 + xer_ca; 277 T0 = T1 + ~T0 + xer_ca;
276 if (likely((uint32_t)T0 >= (uint32_t)T1 && 278 if (likely((uint32_t)T0 >= (uint32_t)T1 &&
277 (xer_ca == 0 || (uint32_t)T0 != (uint32_t)T1))) { 279 (xer_ca == 0 || (uint32_t)T0 != (uint32_t)T1))) {
278 - xer_ca = 0; 280 + env->xer &= ~(1 << XER_CA);
279 } else { 281 } else {
280 - xer_ca = 1; 282 + env->xer |= (1 << XER_CA);
281 } 283 }
282 } 284 }
283 285
@@ -287,61 +289,81 @@ void do_subfe_64 (void) @@ -287,61 +289,81 @@ void do_subfe_64 (void)
287 T0 = T1 + ~T0 + xer_ca; 289 T0 = T1 + ~T0 + xer_ca;
288 if (likely((uint64_t)T0 >= (uint64_t)T1 && 290 if (likely((uint64_t)T0 >= (uint64_t)T1 &&
289 (xer_ca == 0 || (uint64_t)T0 != (uint64_t)T1))) { 291 (xer_ca == 0 || (uint64_t)T0 != (uint64_t)T1))) {
290 - xer_ca = 0; 292 + env->xer &= ~(1 << XER_CA);
291 } else { 293 } else {
292 - xer_ca = 1; 294 + env->xer |= (1 << XER_CA);
293 } 295 }
294 } 296 }
295 #endif 297 #endif
296 298
297 void do_subfmeo (void) 299 void do_subfmeo (void)
298 { 300 {
  301 + int ov;
299 T1 = T0; 302 T1 = T0;
300 T0 = ~T0 + xer_ca - 1; 303 T0 = ~T0 + xer_ca - 1;
301 - xer_ov = ((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0)) >> 31;  
302 - xer_so |= xer_ov; 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 + }
303 if (likely((uint32_t)T1 != UINT32_MAX)) 310 if (likely((uint32_t)T1 != UINT32_MAX))
304 - xer_ca = 1; 311 + env->xer |= (1 << XER_CA);
305 } 312 }
306 313
307 #if defined(TARGET_PPC64) 314 #if defined(TARGET_PPC64)
308 void do_subfmeo_64 (void) 315 void do_subfmeo_64 (void)
309 { 316 {
  317 + int ov;
310 T1 = T0; 318 T1 = T0;
311 T0 = ~T0 + xer_ca - 1; 319 T0 = ~T0 + xer_ca - 1;
312 - xer_ov = ((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0)) >> 63;  
313 - xer_so |= xer_ov; 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 + }
314 if (likely((uint64_t)T1 != UINT64_MAX)) 326 if (likely((uint64_t)T1 != UINT64_MAX))
315 - xer_ca = 1; 327 + env->xer |= (1 << XER_CA);
316 } 328 }
317 #endif 329 #endif
318 330
319 void do_subfzeo (void) 331 void do_subfzeo (void)
320 { 332 {
  333 + int ov;
321 T1 = T0; 334 T1 = T0;
322 T0 = ~T0 + xer_ca; 335 T0 = ~T0 + xer_ca;
323 - xer_ov = (((uint32_t)~T1 ^ UINT32_MAX) &  
324 - ((uint32_t)(~T1) ^ (uint32_t)T0)) >> 31;  
325 - xer_so |= xer_ov; 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 + }
326 if (likely((uint32_t)T0 >= (uint32_t)~T1)) { 343 if (likely((uint32_t)T0 >= (uint32_t)~T1)) {
327 - xer_ca = 0; 344 + env->xer &= ~(1 << XER_CA);
328 } else { 345 } else {
329 - xer_ca = 1; 346 + env->xer |= (1 << XER_CA);
330 } 347 }
331 } 348 }
332 349
333 #if defined(TARGET_PPC64) 350 #if defined(TARGET_PPC64)
334 void do_subfzeo_64 (void) 351 void do_subfzeo_64 (void)
335 { 352 {
  353 + int ov;
336 T1 = T0; 354 T1 = T0;
337 T0 = ~T0 + xer_ca; 355 T0 = ~T0 + xer_ca;
338 - xer_ov = (((uint64_t)~T1 ^ UINT64_MAX) &  
339 - ((uint64_t)(~T1) ^ (uint64_t)T0)) >> 63;  
340 - xer_so |= xer_ov; 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 + }
341 if (likely((uint64_t)T0 >= (uint64_t)~T1)) { 363 if (likely((uint64_t)T0 >= (uint64_t)~T1)) {
342 - xer_ca = 0; 364 + env->xer &= ~(1 << XER_CA);
343 } else { 365 } else {
344 - xer_ca = 1; 366 + env->xer |= (1 << XER_CA);
345 } 367 }
346 } 368 }
347 #endif 369 #endif
@@ -367,20 +389,20 @@ void do_sraw (void) @@ -367,20 +389,20 @@ void do_sraw (void)
367 if (likely((uint32_t)T1 != 0)) { 389 if (likely((uint32_t)T1 != 0)) {
368 ret = (int32_t)T0 >> (T1 & 0x1fUL); 390 ret = (int32_t)T0 >> (T1 & 0x1fUL);
369 if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) { 391 if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) {
370 - xer_ca = 0; 392 + env->xer &= ~(1 << XER_CA);
371 } else { 393 } else {
372 - xer_ca = 1; 394 + env->xer |= (1 << XER_CA);
373 } 395 }
374 } else { 396 } else {
375 ret = T0; 397 ret = T0;
376 - xer_ca = 0; 398 + env->xer &= ~(1 << XER_CA);
377 } 399 }
378 } else { 400 } else {
379 ret = UINT32_MAX * ((uint32_t)T0 >> 31); 401 ret = UINT32_MAX * ((uint32_t)T0 >> 31);
380 if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) { 402 if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) {
381 - xer_ca = 0; 403 + env->xer &= ~(1 << XER_CA);
382 } else { 404 } else {
383 - xer_ca = 1; 405 + env->xer |= (1 << XER_CA);
384 } 406 }
385 } 407 }
386 T0 = ret; 408 T0 = ret;
@@ -395,20 +417,20 @@ void do_srad (void) @@ -395,20 +417,20 @@ void do_srad (void)
395 if (likely((uint64_t)T1 != 0)) { 417 if (likely((uint64_t)T1 != 0)) {
396 ret = (int64_t)T0 >> (T1 & 0x3FUL); 418 ret = (int64_t)T0 >> (T1 & 0x3FUL);
397 if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) { 419 if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) {
398 - xer_ca = 0; 420 + env->xer &= ~(1 << XER_CA);
399 } else { 421 } else {
400 - xer_ca = 1; 422 + env->xer |= (1 << XER_CA);
401 } 423 }
402 } else { 424 } else {
403 ret = T0; 425 ret = T0;
404 - xer_ca = 0; 426 + env->xer &= ~(1 << XER_CA);
405 } 427 }
406 } else { 428 } else {
407 ret = UINT64_MAX * ((uint64_t)T0 >> 63); 429 ret = UINT64_MAX * ((uint64_t)T0 >> 63);
408 if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) { 430 if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) {
409 - xer_ca = 0; 431 + env->xer &= ~(1 << XER_CA);
410 } else { 432 } else {
411 - xer_ca = 1; 433 + env->xer |= (1 << XER_CA);
412 } 434 }
413 } 435 }
414 T0 = ret; 436 T0 = ret;
@@ -1478,14 +1500,13 @@ void do_POWER_abso (void) @@ -1478,14 +1500,13 @@ void do_POWER_abso (void)
1478 { 1500 {
1479 if ((int32_t)T0 == INT32_MIN) { 1501 if ((int32_t)T0 == INT32_MIN) {
1480 T0 = INT32_MAX; 1502 T0 = INT32_MAX;
1481 - xer_ov = 1; 1503 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
1482 } else if ((int32_t)T0 < 0) { 1504 } else if ((int32_t)T0 < 0) {
1483 T0 = -T0; 1505 T0 = -T0;
1484 - xer_ov = 0; 1506 + env->xer &= ~(1 << XER_OV);
1485 } else { 1507 } else {
1486 - xer_ov = 0; 1508 + env->xer &= ~(1 << XER_OV);
1487 } 1509 }
1488 - xer_so |= xer_ov;  
1489 } 1510 }
1490 1511
1491 void do_POWER_clcs (void) 1512 void do_POWER_clcs (void)
@@ -1538,19 +1559,18 @@ void do_POWER_divo (void) @@ -1538,19 +1559,18 @@ void do_POWER_divo (void)
1538 (int32_t)T1 == 0) { 1559 (int32_t)T1 == 0) {
1539 T0 = UINT32_MAX * ((uint32_t)T0 >> 31); 1560 T0 = UINT32_MAX * ((uint32_t)T0 >> 31);
1540 env->spr[SPR_MQ] = 0; 1561 env->spr[SPR_MQ] = 0;
1541 - xer_ov = 1; 1562 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
1542 } else { 1563 } else {
1543 tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ]; 1564 tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ];
1544 env->spr[SPR_MQ] = tmp % T1; 1565 env->spr[SPR_MQ] = tmp % T1;
1545 tmp /= (int32_t)T1; 1566 tmp /= (int32_t)T1;
1546 if (tmp > (int64_t)INT32_MAX || tmp < (int64_t)INT32_MIN) { 1567 if (tmp > (int64_t)INT32_MAX || tmp < (int64_t)INT32_MIN) {
1547 - xer_ov = 1; 1568 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
1548 } else { 1569 } else {
1549 - xer_ov = 0; 1570 + env->xer &= ~(1 << XER_OV);
1550 } 1571 }
1551 T0 = tmp; 1572 T0 = tmp;
1552 } 1573 }
1553 - xer_so |= xer_ov;  
1554 } 1574 }
1555 1575
1556 void do_POWER_divs (void) 1576 void do_POWER_divs (void)
@@ -1571,13 +1591,12 @@ void do_POWER_divso (void) @@ -1571,13 +1591,12 @@ void do_POWER_divso (void)
1571 (int32_t)T1 == 0) { 1591 (int32_t)T1 == 0) {
1572 T0 = UINT32_MAX * ((uint32_t)T0 >> 31); 1592 T0 = UINT32_MAX * ((uint32_t)T0 >> 31);
1573 env->spr[SPR_MQ] = 0; 1593 env->spr[SPR_MQ] = 0;
1574 - xer_ov = 1; 1594 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
1575 } else { 1595 } else {
1576 T0 = (int32_t)T0 / (int32_t)T1; 1596 T0 = (int32_t)T0 / (int32_t)T1;
1577 env->spr[SPR_MQ] = (int32_t)T0 % (int32_t)T1; 1597 env->spr[SPR_MQ] = (int32_t)T0 % (int32_t)T1;
1578 - xer_ov = 0; 1598 + env->xer &= ~(1 << XER_OV);
1579 } 1599 }
1580 - xer_so |= xer_ov;  
1581 } 1600 }
1582 1601
1583 void do_POWER_dozo (void) 1602 void do_POWER_dozo (void)
@@ -1587,14 +1606,13 @@ void do_POWER_dozo (void) @@ -1587,14 +1606,13 @@ void do_POWER_dozo (void)
1587 T0 = T1 - T0; 1606 T0 = T1 - T0;
1588 if (((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) & 1607 if (((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1589 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)) { 1608 ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)) {
1590 - xer_ov = 1;  
1591 - xer_so = 1; 1609 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
1592 } else { 1610 } else {
1593 - xer_ov = 0; 1611 + env->xer &= ~(1 << XER_OV);
1594 } 1612 }
1595 } else { 1613 } else {
1596 T0 = 0; 1614 T0 = 0;
1597 - xer_ov = 0; 1615 + env->xer &= ~(1 << XER_OV);
1598 } 1616 }
1599 } 1617 }
1600 1618
@@ -1621,10 +1639,9 @@ void do_POWER_mulo (void) @@ -1621,10 +1639,9 @@ void do_POWER_mulo (void)
1621 env->spr[SPR_MQ] = tmp >> 32; 1639 env->spr[SPR_MQ] = tmp >> 32;
1622 T0 = tmp; 1640 T0 = tmp;
1623 if (tmp >> 32 != ((uint64_t)T0 >> 16) * ((uint64_t)T1 >> 16)) { 1641 if (tmp >> 32 != ((uint64_t)T0 >> 16) * ((uint64_t)T1 >> 16)) {
1624 - xer_ov = 1;  
1625 - xer_so = 1; 1642 + env->xer |= (1 << XER_OV) | (1 << XER_SO);
1626 } else { 1643 } else {
1627 - xer_ov = 0; 1644 + env->xer &= ~(1 << XER_OV);
1628 } 1645 }
1629 } 1646 }
1630 1647
target-ppc/translate.c
@@ -62,6 +62,7 @@ static TCGv cpu_crf[8]; @@ -62,6 +62,7 @@ static TCGv cpu_crf[8];
62 static TCGv cpu_nip; 62 static TCGv cpu_nip;
63 static TCGv cpu_ctr; 63 static TCGv cpu_ctr;
64 static TCGv cpu_lr; 64 static TCGv cpu_lr;
  65 +static TCGv cpu_xer;
65 66
66 /* dyngen register indexes */ 67 /* dyngen register indexes */
67 static TCGv cpu_T[3]; 68 static TCGv cpu_T[3];
@@ -175,6 +176,9 @@ void ppc_translate_init(void) @@ -175,6 +176,9 @@ void ppc_translate_init(void)
175 cpu_lr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, 176 cpu_lr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
176 offsetof(CPUState, lr), "lr"); 177 offsetof(CPUState, lr), "lr");
177 178
  179 + cpu_xer = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
  180 + offsetof(CPUState, xer), "xer");
  181 +
178 /* register helpers */ 182 /* register helpers */
179 #undef DEF_HELPER 183 #undef DEF_HELPER
180 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name); 184 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
@@ -1057,7 +1061,7 @@ GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -1057,7 +1061,7 @@ GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1057 #endif 1061 #endif
1058 gen_op_check_addc(); 1062 gen_op_check_addc();
1059 } else { 1063 } else {
1060 - gen_op_clear_xer_ca(); 1064 + tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
1061 } 1065 }
1062 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); 1066 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1063 } 1067 }
@@ -1077,7 +1081,7 @@ GEN_HANDLER2(addic_, &quot;addic.&quot;, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -1077,7 +1081,7 @@ GEN_HANDLER2(addic_, &quot;addic.&quot;, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1077 #endif 1081 #endif
1078 gen_op_check_addc(); 1082 gen_op_check_addc();
1079 } else { 1083 } else {
1080 - gen_op_clear_xer_ca(); 1084 + tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
1081 } 1085 }
1082 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); 1086 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1083 gen_set_Rc0(ctx); 1087 gen_set_Rc0(ctx);
@@ -2852,7 +2856,7 @@ GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING) @@ -2852,7 +2856,7 @@ GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
2852 if (ra == 0) { 2856 if (ra == 0) {
2853 ra = rb; 2857 ra = rb;
2854 } 2858 }
2855 - gen_op_load_xer_bc(); 2859 + tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
2856 op_ldstsx(lswx, rD(ctx->opcode), ra, rb); 2860 op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2857 } 2861 }
2858 2862
@@ -2876,7 +2880,7 @@ GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING) @@ -2876,7 +2880,7 @@ GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
2876 /* NIP cannot be restored if the memory exception comes from an helper */ 2880 /* NIP cannot be restored if the memory exception comes from an helper */
2877 gen_update_nip(ctx, ctx->nip - 4); 2881 gen_update_nip(ctx, ctx->nip - 4);
2878 gen_addr_reg_index(cpu_T[0], ctx); 2882 gen_addr_reg_index(cpu_T[0], ctx);
2879 - gen_op_load_xer_bc(); 2883 + tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
2880 op_ldsts(stsw, rS(ctx->opcode)); 2884 op_ldsts(stsw, rS(ctx->opcode));
2881 } 2885 }
2882 2886
@@ -3509,10 +3513,9 @@ GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B) @@ -3509,10 +3513,9 @@ GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3509 /* mcrxr */ 3513 /* mcrxr */
3510 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC) 3514 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3511 { 3515 {
3512 - gen_op_load_xer_cr();  
3513 - tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);  
3514 - gen_op_clear_xer_ov();  
3515 - gen_op_clear_xer_ca(); 3516 + tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
  3517 + tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
  3518 + tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
3516 } 3519 }
3517 3520
3518 /* mfcr */ 3521 /* mfcr */
@@ -4310,10 +4313,12 @@ GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR) @@ -4310,10 +4313,12 @@ GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
4310 } 4313 }
4311 /* NIP cannot be restored if the memory exception comes from an helper */ 4314 /* NIP cannot be restored if the memory exception comes from an helper */
4312 gen_update_nip(ctx, ctx->nip - 4); 4315 gen_update_nip(ctx, ctx->nip - 4);
4313 - gen_op_load_xer_bc();  
4314 - gen_op_load_xer_cmp(); 4316 + tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
  4317 + tcg_gen_shri_tl(cpu_T[2], cpu_xer, XER_CMP);
  4318 + tcg_gen_andi_tl(cpu_T[2], cpu_T[2], 0xFF);
4315 op_POWER_lscbx(rD(ctx->opcode), ra, rb); 4319 op_POWER_lscbx(rD(ctx->opcode), ra, rb);
4316 - gen_op_store_xer_bc(); 4320 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
  4321 + tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
4317 if (unlikely(Rc(ctx->opcode) != 0)) 4322 if (unlikely(Rc(ctx->opcode) != 0))
4318 gen_set_Rc0(ctx); 4323 gen_set_Rc0(ctx);
4319 } 4324 }
@@ -5500,7 +5505,8 @@ GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC) @@ -5500,7 +5505,8 @@ GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5500 tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); 5505 tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
5501 gen_op_440_dlmzb(); 5506 gen_op_440_dlmzb();
5502 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); 5507 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
5503 - gen_op_store_xer_bc(); 5508 + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
  5509 + tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
5504 if (Rc(ctx->opcode)) { 5510 if (Rc(ctx->opcode)) {
5505 gen_op_440_dlmzb_update_Rc(); 5511 gen_op_440_dlmzb_update_Rc();
5506 tcg_gen_andi_i32(cpu_crf[0], cpu_T[0], 0xf); 5512 tcg_gen_andi_i32(cpu_crf[0], cpu_T[0], 0xf);
@@ -6391,7 +6397,7 @@ void cpu_dump_state (CPUState *env, FILE *f, @@ -6391,7 +6397,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
6391 int i; 6397 int i;
6392 6398
6393 cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX " XER %08x\n", 6399 cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX " XER %08x\n",
6394 - env->nip, env->lr, env->ctr, hreg_load_xer(env)); 6400 + env->nip, env->lr, env->ctr, env->xer);
6395 cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX " HF " ADDRX " idx %d\n", 6401 cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX " HF " ADDRX " idx %d\n",
6396 env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx); 6402 env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
6397 #if !defined(NO_TIMER_DUMP) 6403 #if !defined(NO_TIMER_DUMP)
target-ppc/translate_init.c
@@ -99,12 +99,12 @@ static void spr_write_clear (void *opaque, int sprn) @@ -99,12 +99,12 @@ static void spr_write_clear (void *opaque, int sprn)
99 /* XER */ 99 /* XER */
100 static void spr_read_xer (void *opaque, int sprn) 100 static void spr_read_xer (void *opaque, int sprn)
101 { 101 {
102 - gen_op_load_xer(); 102 + tcg_gen_mov_tl(cpu_T[0], cpu_xer);
103 } 103 }
104 104
105 static void spr_write_xer (void *opaque, int sprn) 105 static void spr_write_xer (void *opaque, int sprn)
106 { 106 {
107 - gen_op_store_xer(); 107 + tcg_gen_mov_tl(cpu_xer, cpu_T[0]);
108 } 108 }
109 109
110 /* LR */ 110 /* LR */