Commit fb0eaffc6d9982b5eee439b8461851bd18bf35ce

Authored by bellard
1 parent 07ad1b93

PowerPC fixes (Jocelyn Mayer)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@483 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/cpu.h
@@ -152,7 +152,7 @@ typedef struct CPUPPCState { @@ -152,7 +152,7 @@ typedef struct CPUPPCState {
152 /* general purpose registers */ 152 /* general purpose registers */
153 uint32_t gpr[32]; 153 uint32_t gpr[32];
154 /* floating point registers */ 154 /* floating point registers */
155 - uint64_t fpr[32]; 155 + double fpr[32];
156 /* segment registers */ 156 /* segment registers */
157 ppc_sr_t sr[16]; 157 ppc_sr_t sr[16];
158 /* special purpose registers */ 158 /* special purpose registers */
@@ -172,7 +172,10 @@ typedef struct CPUPPCState { @@ -172,7 +172,10 @@ typedef struct CPUPPCState {
172 uint32_t exception; 172 uint32_t exception;
173 173
174 /* qemu dedicated */ 174 /* qemu dedicated */
175 - uint64_t ft0; /* temporary float register */ 175 + /* temporary float registers */
  176 + double ft0;
  177 + double ft1;
  178 + double ft2;
176 int interrupt_request; 179 int interrupt_request;
177 jmp_buf jmp_env; 180 jmp_buf jmp_env;
178 int exception_index; 181 int exception_index;
@@ -374,35 +377,4 @@ enum { @@ -374,35 +377,4 @@ enum {
374 EXCP_BRANCH = 0x104, /* branch instruction */ 377 EXCP_BRANCH = 0x104, /* branch instruction */
375 }; 378 };
376 379
377 -/*  
378 - * We need to put in some extra aux table entries to tell glibc what  
379 - * the cache block size is, so it can use the dcbz instruction safely.  
380 - */  
381 -#define AT_DCACHEBSIZE 19  
382 -#define AT_ICACHEBSIZE 20  
383 -#define AT_UCACHEBSIZE 21  
384 -/* A special ignored type value for PPC, for glibc compatibility. */  
385 -#define AT_IGNOREPPC 22  
386 -/*  
387 - * The requirements here are:  
388 - * - keep the final alignment of sp (sp & 0xf)  
389 - * - make sure the 32-bit value at the first 16 byte aligned position of  
390 - * AUXV is greater than 16 for glibc compatibility.  
391 - * AT_IGNOREPPC is used for that.  
392 - * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,  
393 - * even if DLINFO_ARCH_ITEMS goes to zero or is undefined.  
394 - */  
395 -#define DLINFO_ARCH_ITEMS 3  
396 -#define ARCH_DLINFO \  
397 -do { \  
398 - /* \  
399 - * Now handle glibc compatibility. \  
400 - */ \  
401 - NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \  
402 - NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \  
403 - \  
404 - NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20); \  
405 - NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20); \  
406 - NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \  
407 - } while (0)  
408 #endif /* !defined (__CPU_PPC_H__) */ 380 #endif /* !defined (__CPU_PPC_H__) */
target-ppc/exec.h
@@ -29,6 +29,12 @@ register uint32_t T2 asm(AREG3); @@ -29,6 +29,12 @@ register uint32_t T2 asm(AREG3);
29 29
30 #define PARAM(n) ((uint32_t)PARAM##n) 30 #define PARAM(n) ((uint32_t)PARAM##n)
31 #define SPARAM(n) ((int32_t)PARAM##n) 31 #define SPARAM(n) ((int32_t)PARAM##n)
  32 +#define FT0 (env->ft0)
  33 +#define FT1 (env->ft1)
  34 +#define FT2 (env->ft2)
  35 +#define FTS0 ((float)env->ft0)
  36 +#define FTS1 ((float)env->ft1)
  37 +#define FTS2 ((float)env->ft2)
32 38
33 #define RETURN() __asm__ __volatile__(""); 39 #define RETURN() __asm__ __volatile__("");
34 40
@@ -145,8 +151,8 @@ uint32_t do_load_xer (void); @@ -145,8 +151,8 @@ uint32_t do_load_xer (void);
145 void do_store_xer (uint32_t value); 151 void do_store_xer (uint32_t value);
146 uint32_t do_load_msr (void); 152 uint32_t do_load_msr (void);
147 void do_store_msr (uint32_t msr_value); 153 void do_store_msr (uint32_t msr_value);
148 -uint32_t do_load_fpscr (void);  
149 -void do_store_fpscr (uint8_t mask, uint32_t fp); 154 +void do_load_fpscr (void);
  155 +void do_store_fpscr (uint32_t mask);
150 156
151 int32_t do_sraw(int32_t Ta, uint32_t Tb); 157 int32_t do_sraw(int32_t Ta, uint32_t Tb);
152 void do_lmw (int reg, uint32_t src); 158 void do_lmw (int reg, uint32_t src);
@@ -154,4 +160,7 @@ void do_stmw (int reg, uint32_t dest); @@ -154,4 +160,7 @@ void do_stmw (int reg, uint32_t dest);
154 void do_lsw (uint32_t reg, int count, uint32_t src); 160 void do_lsw (uint32_t reg, int count, uint32_t src);
155 void do_stsw (uint32_t reg, int count, uint32_t dest); 161 void do_stsw (uint32_t reg, int count, uint32_t dest);
156 162
  163 +void do_dcbz (void);
  164 +void do_icbi (void);
  165 +
157 #endif /* !defined (__PPC_H__) */ 166 #endif /* !defined (__PPC_H__) */
target-ppc/helper.c
@@ -121,67 +121,67 @@ void do_store_msr (uint32_t msr_value) @@ -121,67 +121,67 @@ void do_store_msr (uint32_t msr_value)
121 } 121 }
122 122
123 /* The 32 MSB of the target fpr are undefined. They'll be zero... */ 123 /* The 32 MSB of the target fpr are undefined. They'll be zero... */
124 -uint32_t do_load_fpscr (void) 124 +/* Floating point operations helpers */
  125 +void do_load_fpscr (void)
125 { 126 {
126 - return (fpscr_fx << FPSCR_FX) |  
127 - (fpscr_fex << FPSCR_FEX) |  
128 - (fpscr_vx << FPSCR_VX) |  
129 - (fpscr_ox << FPSCR_OX) |  
130 - (fpscr_ux << FPSCR_UX) |  
131 - (fpscr_zx << FPSCR_ZX) |  
132 - (fpscr_xx << FPSCR_XX) |  
133 - (fpscr_vsxnan << FPSCR_VXSNAN) |  
134 - (fpscr_vxisi << FPSCR_VXISI) |  
135 - (fpscr_vxidi << FPSCR_VXIDI) |  
136 - (fpscr_vxzdz << FPSCR_VXZDZ) |  
137 - (fpscr_vximz << FPSCR_VXIMZ) |  
138 - (fpscr_fr << FPSCR_FR) |  
139 - (fpscr_fi << FPSCR_FI) |  
140 - (fpscr_fprf << FPSCR_FPRF) |  
141 - (fpscr_vxsoft << FPSCR_VXSOFT) |  
142 - (fpscr_vxsqrt << FPSCR_VXSQRT) |  
143 - (fpscr_oe << FPSCR_OE) |  
144 - (fpscr_ue << FPSCR_UE) |  
145 - (fpscr_ze << FPSCR_ZE) |  
146 - (fpscr_xe << FPSCR_XE) |  
147 - (fpscr_ni << FPSCR_NI) |  
148 - (fpscr_rn << FPSCR_RN); 127 + /* The 32 MSB of the target fpr are undefined.
  128 + * They'll be zero...
  129 + */
  130 + union {
  131 + double d;
  132 + struct {
  133 + uint32_t u[2];
  134 + } s;
  135 + } u;
  136 + int i;
  137 +
  138 + u.s.u[0] = 0;
  139 + u.s.u[1] = 0;
  140 + for (i = 0; i < 8; i++)
  141 + u.s.u[1] |= env->fpscr[i] << (4 * i);
  142 + FT0 = u.d;
149 } 143 }
150 144
151 -/* We keep only 32 bits of input... */  
152 -/* For now, this is COMPLETELY BUGGY ! */  
153 -void do_store_fpscr (uint8_t mask, uint32_t fp) 145 +void do_store_fpscr (uint32_t mask)
154 { 146 {
  147 + /*
  148 + * We use only the 32 LSB of the incoming fpr
  149 + */
  150 + union {
  151 + double d;
  152 + struct {
  153 + uint32_t u[2];
  154 + } s;
  155 + } u;
155 int i; 156 int i;
156 157
157 - for (i = 0; i < 7; i++) {  
158 - if ((mask & (1 << i)) == 0)  
159 - fp &= ~(0xf << (4 * i)); 158 + u.d = FT0;
  159 + if (mask & 0x80)
  160 + env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[1] >> 28) & ~0x9);
  161 + for (i = 1; i < 7; i++) {
  162 + if (mask & (1 << (7 - i)))
  163 + env->fpscr[i] = (u.s.u[1] >> (4 * (7 - i))) & 0xF;
  164 + }
  165 + /* TODO: update FEX & VX */
  166 + /* Set rounding mode */
  167 + switch (env->fpscr[0] & 0x3) {
  168 + case 0:
  169 + /* Best approximation (round to nearest) */
  170 + fesetround(FE_TONEAREST);
  171 + break;
  172 + case 1:
  173 + /* Smaller magnitude (round toward zero) */
  174 + fesetround(FE_TOWARDZERO);
  175 + break;
  176 + case 2:
  177 + /* Round toward +infinite */
  178 + fesetround(FE_UPWARD);
  179 + break;
  180 + case 3:
  181 + /* Round toward -infinite */
  182 + fesetround(FE_DOWNWARD);
  183 + break;
160 } 184 }
161 - if ((mask & 80) != 0)  
162 - fpscr_fx = (fp >> FPSCR_FX) & 0x01;  
163 - fpscr_fex = (fp >> FPSCR_FEX) & 0x01;  
164 - fpscr_vx = (fp >> FPSCR_VX) & 0x01;  
165 - fpscr_ox = (fp >> FPSCR_OX) & 0x01;  
166 - fpscr_ux = (fp >> FPSCR_UX) & 0x01;  
167 - fpscr_zx = (fp >> FPSCR_ZX) & 0x01;  
168 - fpscr_xx = (fp >> FPSCR_XX) & 0x01;  
169 - fpscr_vsxnan = (fp >> FPSCR_VXSNAN) & 0x01;  
170 - fpscr_vxisi = (fp >> FPSCR_VXISI) & 0x01;  
171 - fpscr_vxidi = (fp >> FPSCR_VXIDI) & 0x01;  
172 - fpscr_vxzdz = (fp >> FPSCR_VXZDZ) & 0x01;  
173 - fpscr_vximz = (fp >> FPSCR_VXIMZ) & 0x01;  
174 - fpscr_fr = (fp >> FPSCR_FR) & 0x01;  
175 - fpscr_fi = (fp >> FPSCR_FI) & 0x01;  
176 - fpscr_fprf = (fp >> FPSCR_FPRF) & 0x1F;  
177 - fpscr_vxsoft = (fp >> FPSCR_VXSOFT) & 0x01;  
178 - fpscr_vxsqrt = (fp >> FPSCR_VXSQRT) & 0x01;  
179 - fpscr_oe = (fp >> FPSCR_OE) & 0x01;  
180 - fpscr_ue = (fp >> FPSCR_UE) & 0x01;  
181 - fpscr_ze = (fp >> FPSCR_ZE) & 0x01;  
182 - fpscr_xe = (fp >> FPSCR_XE) & 0x01;  
183 - fpscr_ni = (fp >> FPSCR_NI) & 0x01;  
184 - fpscr_rn = (fp >> FPSCR_RN) & 0x03;  
185 } 185 }
186 186
187 int32_t do_sraw(int32_t value, uint32_t shift) 187 int32_t do_sraw(int32_t value, uint32_t shift)
@@ -220,20 +220,14 @@ void do_lsw (uint32_t reg, int count, uint32_t src) @@ -220,20 +220,14 @@ void do_lsw (uint32_t reg, int count, uint32_t src)
220 int sh; 220 int sh;
221 221
222 for (; count > 3; count -= 4, src += 4) { 222 for (; count > 3; count -= 4, src += 4) {
223 - if (reg == 32)  
224 - reg = 0;  
225 ugpr(reg++) = ld32(src); 223 ugpr(reg++) = ld32(src);
  224 + if (T2 == 32)
  225 + T2 = 0;
226 } 226 }
227 if (count > 0) { 227 if (count > 0) {
228 - for (sh = 24, tmp = 0; count > 0; count--, src++, sh -= 8) {  
229 - if (reg == 32)  
230 - reg = 0;  
231 - tmp |= ld8(src) << sh;  
232 - if (sh == 0) {  
233 - sh = 32;  
234 - ugpr(reg++) = tmp;  
235 tmp = 0; 228 tmp = 0;
236 - } 229 + for (sh = 24; count > 0; count--, src++, sh -= 8) {
  230 + tmp |= ld8(src) << sh;
237 } 231 }
238 ugpr(reg) = tmp; 232 ugpr(reg) = tmp;
239 } 233 }
@@ -244,19 +238,30 @@ void do_stsw (uint32_t reg, int count, uint32_t dest) @@ -244,19 +238,30 @@ void do_stsw (uint32_t reg, int count, uint32_t dest)
244 int sh; 238 int sh;
245 239
246 for (; count > 3; count -= 4, dest += 4) { 240 for (; count > 3; count -= 4, dest += 4) {
  241 + st32(dest, ugpr(reg++));
247 if (reg == 32) 242 if (reg == 32)
248 reg = 0; 243 reg = 0;
249 - st32(dest, ugpr(reg++));  
250 } 244 }
251 if (count > 0) { 245 if (count > 0) {
252 for (sh = 24; count > 0; count--, dest++, sh -= 8) { 246 for (sh = 24; count > 0; count--, dest++, sh -= 8) {
253 - if (reg == 32)  
254 - reg = 0;  
255 st8(dest, (ugpr(reg) >> sh) & 0xFF); 247 st8(dest, (ugpr(reg) >> sh) & 0xFF);
256 - if (sh == 0) {  
257 - sh = 32;  
258 - reg++;  
259 } 248 }
260 } 249 }
  250 +}
  251 +
  252 +void do_dcbz (void)
  253 +{
  254 + int i;
  255 +
  256 + /* Assume cache line size is 32 */
  257 + for (i = 0; i < 8; i++) {
  258 + st32(T0, 0);
  259 + T0 += 4;
261 } 260 }
262 } 261 }
  262 +
  263 +/* Instruction cache invalidation helper */
  264 +void do_icbi (void)
  265 +{
  266 + tb_invalidate_page(T0);
  267 +}
target-ppc/op.c
@@ -27,6 +27,12 @@ @@ -27,6 +27,12 @@
27 #define Ts2 (int32_t)T2 27 #define Ts2 (int32_t)T2
28 28
29 #define FT0 (env->ft0) 29 #define FT0 (env->ft0)
  30 +#define FT1 (env->ft1)
  31 +#define FT2 (env->ft2)
  32 +
  33 +#define FTS0 ((float)env->ft0)
  34 +#define FTS1 ((float)env->ft1)
  35 +#define FTS2 ((float)env->ft2)
30 36
31 #define PPC_OP(name) void op_##name(void) 37 #define PPC_OP(name) void op_##name(void)
32 38
@@ -173,6 +179,13 @@ PPC_OP(set_Rc0_1) @@ -173,6 +179,13 @@ PPC_OP(set_Rc0_1)
173 RETURN(); 179 RETURN();
174 } 180 }
175 181
  182 +/* Set Rc1 (for floating point arithmetic) */
  183 +PPC_OP(set_Rc1)
  184 +{
  185 + env->crf[1] = regs->fpscr[7];
  186 + RETURN();
  187 +}
  188 +
176 PPC_OP(set_T0) 189 PPC_OP(set_T0)
177 { 190 {
178 T0 = PARAM(1); 191 T0 = PARAM(1);
@@ -278,6 +291,25 @@ PPC_OP(load_lr) @@ -278,6 +291,25 @@ PPC_OP(load_lr)
278 RETURN(); 291 RETURN();
279 } 292 }
280 293
  294 +/* FPSCR */
  295 +PPC_OP(load_fpscr)
  296 +{
  297 + do_load_fpscr();
  298 + RETURN();
  299 +}
  300 +
  301 +PPC_OP(store_fpscr)
  302 +{
  303 + do_store_fpscr(PARAM(1));
  304 + RETURN();
  305 +}
  306 +
  307 +PPC_OP(reset_scrfx)
  308 +{
  309 + regs->fpscr[7] &= ~0x8;
  310 + RETURN();
  311 +}
  312 +
281 /* Set reservation */ 313 /* Set reservation */
282 PPC_OP(set_reservation) 314 PPC_OP(set_reservation)
283 { 315 {
@@ -988,7 +1020,7 @@ PPC_OP(xori) @@ -988,7 +1020,7 @@ PPC_OP(xori)
988 /* rotate left word immediate then mask insert */ 1020 /* rotate left word immediate then mask insert */
989 PPC_OP(rlwimi) 1021 PPC_OP(rlwimi)
990 { 1022 {
991 - T0 = rotl(T0, PARAM(1) & PARAM(2)) | (T0 & PARAM(3)); 1023 + T0 = (rotl(T0, PARAM(1)) & PARAM(2)) | (T1 & PARAM(3));
992 RETURN(); 1024 RETURN();
993 } 1025 }
994 1026
@@ -1216,123 +1248,171 @@ PPC_OP(store_spr) @@ -1216,123 +1248,171 @@ PPC_OP(store_spr)
1216 regs->spr[PARAM(1)] = T0; 1248 regs->spr[PARAM(1)] = T0;
1217 } 1249 }
1218 1250
1219 -/* FPSCR */  
1220 -PPC_OP(load_fpscr)  
1221 -{  
1222 - T0 = do_load_fpscr();  
1223 -}  
1224 -  
1225 -PPC_OP(store_fpscr)  
1226 -{  
1227 - do_store_fpscr(PARAM(1), T0);  
1228 -}  
1229 -  
1230 /*** Floating-point store ***/ 1251 /*** Floating-point store ***/
1231 1252
1232 -static inline uint32_t dtos(uint64_t f)  
1233 -{  
1234 - unsigned int e, m, s;  
1235 - e = (((f >> 52) & 0x7ff) - 1022) + 126;  
1236 - s = (f >> 63);  
1237 - m = (f >> 29);  
1238 - return (s << 31) | (e << 23) | m;  
1239 -}  
1240 -  
1241 -static inline uint64_t stod(uint32_t f)  
1242 -{  
1243 - unsigned int e, m, s;  
1244 - e = ((f >> 23) & 0xff) - 126 + 1022;  
1245 - s = f >> 31;  
1246 - m = f & ((1 << 23) - 1);  
1247 - return ((uint64_t)s << 63) | ((uint64_t)e << 52) | ((uint64_t)m << 29);  
1248 -}  
1249 -  
1250 PPC_OP(stfd_z_FT0) 1253 PPC_OP(stfd_z_FT0)
1251 { 1254 {
1252 - st64(SPARAM(1), FT0); 1255 + stfq((void *)SPARAM(1), FT0);
1253 } 1256 }
1254 1257
1255 PPC_OP(stfd_FT0) 1258 PPC_OP(stfd_FT0)
1256 { 1259 {
1257 T0 += SPARAM(1); 1260 T0 += SPARAM(1);
1258 - st64(T0, FT0); 1261 + stfq((void *)T0, FT0);
1259 } 1262 }
1260 1263
1261 PPC_OP(stfdx_z_FT0) 1264 PPC_OP(stfdx_z_FT0)
1262 { 1265 {
1263 - st64(T0, FT0); 1266 + stfq((void *)T0, FT0);
1264 } 1267 }
1265 1268
1266 PPC_OP(stfdx_FT0) 1269 PPC_OP(stfdx_FT0)
1267 { 1270 {
1268 T0 += T1; 1271 T0 += T1;
1269 - st64(T0, FT0); 1272 + stfq((void *)T0, FT0);
1270 } 1273 }
1271 1274
1272 -  
1273 PPC_OP(stfs_z_FT0) 1275 PPC_OP(stfs_z_FT0)
1274 { 1276 {
1275 - st32(SPARAM(1), dtos(FT0)); 1277 + float tmp = FT0;
  1278 + stfl((void *)SPARAM(1), tmp);
1276 } 1279 }
1277 1280
1278 PPC_OP(stfs_FT0) 1281 PPC_OP(stfs_FT0)
1279 { 1282 {
  1283 + float tmp = FT0;
1280 T0 += SPARAM(1); 1284 T0 += SPARAM(1);
1281 - st32(T0, dtos(FT0)); 1285 + stfl((void *)T0, tmp);
1282 } 1286 }
1283 1287
1284 PPC_OP(stfsx_z_FT0) 1288 PPC_OP(stfsx_z_FT0)
1285 { 1289 {
1286 - st32(T0, dtos(FT0)); 1290 + float tmp = FT0;
  1291 + stfl((void *)T0, tmp);
1287 } 1292 }
1288 1293
1289 PPC_OP(stfsx_FT0) 1294 PPC_OP(stfsx_FT0)
1290 { 1295 {
  1296 + float tmp = FT0;
1291 T0 += T1; 1297 T0 += T1;
1292 - st32(T0, dtos(FT0)); 1298 + stfl((void *)T0, tmp);
1293 } 1299 }
1294 1300
1295 /*** Floating-point load ***/ 1301 /*** Floating-point load ***/
1296 PPC_OP(lfd_z_FT0) 1302 PPC_OP(lfd_z_FT0)
1297 { 1303 {
1298 - FT0 = ld64(SPARAM(1)); 1304 + FT0 = ldfq((void *)SPARAM(1));
1299 } 1305 }
1300 1306
1301 PPC_OP(lfd_FT0) 1307 PPC_OP(lfd_FT0)
1302 { 1308 {
1303 T0 += SPARAM(1); 1309 T0 += SPARAM(1);
1304 - FT0 = ld64(T0); 1310 + FT0 = ldfq((void *)T0);
1305 } 1311 }
1306 1312
1307 PPC_OP(lfdx_z_FT0) 1313 PPC_OP(lfdx_z_FT0)
1308 { 1314 {
1309 - FT0 = ld64(T0); 1315 + FT0 = ldfq((void *)T0);
1310 } 1316 }
1311 1317
1312 PPC_OP(lfdx_FT0) 1318 PPC_OP(lfdx_FT0)
1313 { 1319 {
1314 T0 += T1; 1320 T0 += T1;
1315 - FT0 = ld64(T0); 1321 + FT0 = ldfq((void *)T0);
1316 } 1322 }
1317 1323
1318 PPC_OP(lfs_z_FT0) 1324 PPC_OP(lfs_z_FT0)
1319 { 1325 {
1320 - FT0 = stod(ld32(SPARAM(1))); 1326 + float tmp = ldfl((void *)SPARAM(1));
  1327 + FT0 = tmp;
1321 } 1328 }
1322 1329
1323 PPC_OP(lfs_FT0) 1330 PPC_OP(lfs_FT0)
1324 { 1331 {
  1332 + float tmp;
1325 T0 += SPARAM(1); 1333 T0 += SPARAM(1);
1326 - FT0 = stod(ld32(T0)); 1334 + tmp = ldfl((void *)T0);
  1335 + FT0 = tmp;
1327 } 1336 }
1328 1337
1329 PPC_OP(lfsx_z_FT0) 1338 PPC_OP(lfsx_z_FT0)
1330 { 1339 {
1331 - FT0 = stod(ld32(T0)); 1340 + float tmp;
  1341 + tmp = ldfl((void *)T0);
  1342 + FT0 = tmp;
1332 } 1343 }
1333 1344
1334 PPC_OP(lfsx_FT0) 1345 PPC_OP(lfsx_FT0)
1335 { 1346 {
  1347 + float tmp;
  1348 + T0 += T1;
  1349 + tmp = ldfl((void *)T0);
  1350 + FT0 = tmp;
  1351 +}
  1352 +
  1353 +PPC_OP(lwarx_z)
  1354 +{
  1355 + T1 = ld32(T0);
  1356 + regs->reserve = T0;
  1357 + RETURN();
  1358 +}
  1359 +
  1360 +PPC_OP(lwarx)
  1361 +{
  1362 + T0 += T1;
  1363 + T1 = ld32(T0);
  1364 + regs->reserve = T0;
  1365 + RETURN();
  1366 +}
  1367 +
  1368 +PPC_OP(stwcx_z)
  1369 +{
  1370 + if (regs->reserve != T0) {
  1371 + env->crf[0] = xer_ov;
  1372 + } else {
  1373 + st32(T0, T1);
  1374 + env->crf[0] = xer_ov | 0x02;
  1375 + }
  1376 + regs->reserve = 0;
  1377 + RETURN();
  1378 +}
  1379 +
  1380 +PPC_OP(stwcx)
  1381 +{
1336 T0 += T1; 1382 T0 += T1;
1337 - FT0 = stod(ld32(T0)); 1383 + if (regs->reserve != (T0 & ~0x03)) {
  1384 + env->crf[0] = xer_ov;
  1385 + } else {
  1386 + st32(T0, T2);
  1387 + env->crf[0] = xer_ov | 0x02;
  1388 + }
  1389 + regs->reserve = 0;
  1390 + RETURN();
  1391 +}
  1392 +
  1393 +PPC_OP(dcbz_z)
  1394 +{
  1395 + do_dcbz();
  1396 + RETURN();
  1397 +}
  1398 +
  1399 +PPC_OP(dcbz)
  1400 +{
  1401 + T0 += T1;
  1402 + do_dcbz();
  1403 + RETURN();
  1404 +}
  1405 +
  1406 +/* Instruction cache block invalidate */
  1407 +PPC_OP(icbi_z)
  1408 +{
  1409 + do_icbi();
  1410 + RETURN();
  1411 +}
  1412 +
  1413 +PPC_OP(icbi)
  1414 +{
  1415 + T0 += T1;
  1416 + do_icbi();
  1417 + RETURN();
1338 } 1418 }
target-ppc/op_template.h
@@ -70,18 +70,90 @@ void OPPROTO glue(op_store_T1_crf_crf, REG)(void) @@ -70,18 +70,90 @@ void OPPROTO glue(op_store_T1_crf_crf, REG)(void)
70 regs->crf[REG] = T1; 70 regs->crf[REG] = T1;
71 } 71 }
72 72
  73 +/* Floating point condition and status register moves */
  74 +void OPPROTO glue(op_load_fpscr_T0_fpscr, REG)(void)
  75 +{
  76 + T0 = regs->fpscr[REG];
  77 + RETURN();
  78 +}
  79 +
  80 +#if REG == 0
  81 +void OPPROTO glue(op_store_T0_fpscr_fpscr, REG)(void)
  82 +{
  83 + regs->fpscr[REG] = (regs->fpscr[REG] & 0x9) | (T0 & ~0x9);
  84 + RETURN();
  85 +}
  86 +
  87 +void OPPROTO glue(op_store_T0_fpscri_fpscr, REG)(void)
  88 +{
  89 + regs->fpscr[REG] = (regs->fpscr[REG] & ~0x9) | (PARAM(1) & 0x9);
  90 + RETURN();
  91 +}
  92 +
  93 +void OPPROTO glue(op_clear_fpscr_fpscr, REG)(void)
  94 +{
  95 + regs->fpscr[REG] = (regs->fpscr[REG] & 0x9);
  96 + RETURN();
  97 +}
  98 +#else
  99 +void OPPROTO glue(op_store_T0_fpscr_fpscr, REG)(void)
  100 +{
  101 + regs->fpscr[REG] = T0;
  102 + RETURN();
  103 +}
  104 +
  105 +void OPPROTO glue(op_store_T0_fpscri_fpscr, REG)(void)
  106 +{
  107 + regs->fpscr[REG] = PARAM(1);
  108 + RETURN();
  109 +}
  110 +
  111 +void OPPROTO glue(op_clear_fpscr_fpscr, REG)(void)
  112 +{
  113 + regs->fpscr[REG] = 0x0;
  114 + RETURN();
  115 +}
  116 +#endif
  117 +
73 #endif /* REG <= 7 */ 118 #endif /* REG <= 7 */
74 119
75 /* float moves */ 120 /* float moves */
76 121
77 -void OPPROTO glue(op_load_FT0_fpr, REG)(void) 122 +/* floating point registers moves */
  123 +void OPPROTO glue(op_load_fpr_FT0_fpr, REG)(void)
78 { 124 {
79 FT0 = env->fpr[REG]; 125 FT0 = env->fpr[REG];
  126 + RETURN();
80 } 127 }
81 128
82 -void OPPROTO glue(op_store_FT0_fpr, REG)(void) 129 +void OPPROTO glue(op_store_FT0_fpr_fpr, REG)(void)
83 { 130 {
84 env->fpr[REG] = FT0; 131 env->fpr[REG] = FT0;
  132 + RETURN();
  133 +}
  134 +
  135 +void OPPROTO glue(op_load_fpr_FT1_fpr, REG)(void)
  136 +{
  137 + FT1 = env->fpr[REG];
  138 + RETURN();
  139 +}
  140 +
  141 +void OPPROTO glue(op_store_FT1_fpr_fpr, REG)(void)
  142 +{
  143 + env->fpr[REG] = FT1;
  144 + RETURN();
  145 +}
  146 +
  147 +void OPPROTO glue(op_load_fpr_FT2_fpr, REG)(void)
  148 +{
  149 + FT2 = env->fpr[REG];
  150 + RETURN();
  151 +}
  152 +
  153 +void OPPROTO glue(op_store_FT2_fpr_fpr, REG)(void)
  154 +{
  155 + env->fpr[REG] = FT2;
  156 + RETURN();
85 } 157 }
86 158
87 #undef REG 159 #undef REG
target-ppc/translate.c
@@ -38,6 +38,9 @@ static uint32_t *gen_opparam_ptr; @@ -38,6 +38,9 @@ static uint32_t *gen_opparam_ptr;
38 #include "gen-op.h" 38 #include "gen-op.h"
39 39
40 typedef void (GenOpFunc)(void); 40 typedef void (GenOpFunc)(void);
  41 +typedef void (GenOpFunc1)(long);
  42 +typedef void (GenOpFunc2)(long, long);
  43 +typedef void (GenOpFunc3)(long, long, long);
41 44
42 #define GEN8(func, NAME) \ 45 #define GEN8(func, NAME) \
43 static GenOpFunc *NAME ## _table [8] = {\ 46 static GenOpFunc *NAME ## _table [8] = {\
@@ -70,6 +73,25 @@ GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf) @@ -70,6 +73,25 @@ GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf)
70 GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf) 73 GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf)
71 GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf) 74 GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf)
72 75
  76 +/* Floating point condition and status register moves */
  77 +GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
  78 +GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
  79 +GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
  80 +static GenOpFunc1 *gen_op_store_T0_fpscri_fpscr_table[8] = {
  81 + &gen_op_store_T0_fpscri_fpscr0,
  82 + &gen_op_store_T0_fpscri_fpscr1,
  83 + &gen_op_store_T0_fpscri_fpscr2,
  84 + &gen_op_store_T0_fpscri_fpscr3,
  85 + &gen_op_store_T0_fpscri_fpscr4,
  86 + &gen_op_store_T0_fpscri_fpscr5,
  87 + &gen_op_store_T0_fpscri_fpscr6,
  88 + &gen_op_store_T0_fpscri_fpscr7,
  89 +};
  90 +static inline void gen_op_store_T0_fpscri(int n, uint8_t param)
  91 +{
  92 + (*gen_op_store_T0_fpscri_fpscr_table[n])(param);
  93 +}
  94 +
73 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr) 95 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr)
74 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr) 96 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr)
75 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr) 97 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr)
@@ -78,8 +100,13 @@ GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr) @@ -78,8 +100,13 @@ GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr)
78 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr) 100 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr)
79 GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr) 101 GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr)
80 102
81 -GEN32(gen_op_load_FT0_fpr, gen_op_load_FT0_fpr)  
82 -GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr) 103 +/* floating point registers moves */
  104 +GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
  105 +GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
  106 +GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
  107 +GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
  108 +GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
  109 +GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
83 110
84 static uint8_t spr_access[1024 / 2]; 111 static uint8_t spr_access[1024 / 2];
85 112
@@ -198,10 +225,14 @@ EXTRACT_HELPER(SH, 11, 5); @@ -198,10 +225,14 @@ EXTRACT_HELPER(SH, 11, 5);
198 EXTRACT_HELPER(MB, 6, 5); 225 EXTRACT_HELPER(MB, 6, 5);
199 /* Mask end */ 226 /* Mask end */
200 EXTRACT_HELPER(ME, 1, 5); 227 EXTRACT_HELPER(ME, 1, 5);
  228 +/* Trap operand */
  229 +EXTRACT_HELPER(TO, 21, 5);
201 230
202 EXTRACT_HELPER(CRM, 12, 8); 231 EXTRACT_HELPER(CRM, 12, 8);
203 EXTRACT_HELPER(FM, 17, 8); 232 EXTRACT_HELPER(FM, 17, 8);
204 EXTRACT_HELPER(SR, 16, 4); 233 EXTRACT_HELPER(SR, 16, 4);
  234 +EXTRACT_HELPER(FPIMM, 20, 4);
  235 +
205 /*** Jump target decoding ***/ 236 /*** Jump target decoding ***/
206 /* Displacement */ 237 /* Displacement */
207 EXTRACT_SHELPER(d, 0, 16); 238 EXTRACT_SHELPER(d, 0, 16);
@@ -597,6 +628,7 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -597,6 +628,7 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
597 mb = MB(ctx->opcode); 628 mb = MB(ctx->opcode);
598 me = ME(ctx->opcode); 629 me = ME(ctx->opcode);
599 gen_op_load_gpr_T0(rS(ctx->opcode)); 630 gen_op_load_gpr_T0(rS(ctx->opcode));
  631 + gen_op_load_gpr_T1(rA(ctx->opcode));
600 gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me)); 632 gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me));
601 if (Rc(ctx->opcode) != 0) 633 if (Rc(ctx->opcode) != 0)
602 gen_op_set_Rc0(); 634 gen_op_set_Rc0();
@@ -847,47 +879,67 @@ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) @@ -847,47 +879,67 @@ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
847 /* mcrfs */ 879 /* mcrfs */
848 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) 880 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
849 { 881 {
850 - SET_RETVAL(EXCP_INVAL); 882 + gen_op_load_fpscr_T0(crfS(ctx->opcode));
  883 + gen_op_store_T0_crf(crfD(ctx->opcode));
  884 + gen_op_clear_fpscr(crfS(ctx->opcode));
  885 + SET_RETVAL(0);
851 } 886 }
852 887
853 /* mffs */ 888 /* mffs */
854 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT) 889 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
855 { 890 {
856 gen_op_load_fpscr(); 891 gen_op_load_fpscr();
857 - gen_op_store_T0_gpr(rD(ctx->opcode));  
858 - if (Rc(ctx->opcode)) {  
859 - /* Update CR1 */  
860 - } 892 + gen_op_store_FT0_fpr(rD(ctx->opcode));
  893 + if (Rc(ctx->opcode))
  894 + gen_op_set_Rc1();
861 SET_RETVAL(0); 895 SET_RETVAL(0);
862 } 896 }
863 897
864 /* mtfsb0 */ 898 /* mtfsb0 */
865 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT) 899 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
866 { 900 {
867 - SET_RETVAL(EXCP_INVAL); 901 + uint8_t crb;
  902 +
  903 + crb = crbD(ctx->opcode) >> 2;
  904 + gen_op_load_fpscr_T0(crb);
  905 + gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03)));
  906 + gen_op_store_T0_fpscr(crb);
  907 + if (Rc(ctx->opcode))
  908 + gen_op_set_Rc1();
  909 + SET_RETVAL(0);
868 } 910 }
869 911
870 /* mtfsb1 */ 912 /* mtfsb1 */
871 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) 913 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
872 { 914 {
873 - SET_RETVAL(EXCP_INVAL); 915 + uint8_t crb;
  916 +
  917 + crb = crbD(ctx->opcode) >> 2;
  918 + gen_op_load_fpscr_T0(crb);
  919 + gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
  920 + gen_op_store_T0_fpscr(crb);
  921 + if (Rc(ctx->opcode))
  922 + gen_op_set_Rc1();
  923 + SET_RETVAL(0);
874 } 924 }
875 925
876 /* mtfsf */ 926 /* mtfsf */
877 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) 927 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
878 { 928 {
879 - gen_op_load_gpr_T0(rB(ctx->opcode)); 929 + gen_op_load_fpr_FT0(rB(ctx->opcode));
880 gen_op_store_fpscr(FM(ctx->opcode)); 930 gen_op_store_fpscr(FM(ctx->opcode));
881 - if (Rc(ctx->opcode)) {  
882 - /* Update CR1 */  
883 - } 931 + if (Rc(ctx->opcode))
  932 + gen_op_set_Rc1();
884 SET_RETVAL(0); 933 SET_RETVAL(0);
885 } 934 }
886 935
887 /* mtfsfi */ 936 /* mtfsfi */
888 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) 937 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
889 { 938 {
890 - SET_RETVAL(EXCP_INVAL); 939 + gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
  940 + if (Rc(ctx->opcode))
  941 + gen_op_set_Rc1();
  942 + SET_RETVAL(0);
891 } 943 }
892 944
893 /*** Integer load ***/ 945 /*** Integer load ***/
@@ -1179,13 +1231,11 @@ GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_MEM) @@ -1179,13 +1231,11 @@ GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_MEM)
1179 reserve = 1; 1231 reserve = 1;
1180 if (rA(ctx->opcode) == 0) { 1232 if (rA(ctx->opcode) == 0) {
1181 gen_op_load_gpr_T0(rB(ctx->opcode)); 1233 gen_op_load_gpr_T0(rB(ctx->opcode));
1182 - gen_op_lwzx_z();  
1183 - gen_op_set_reservation(); 1234 + gen_op_lwarx_z();
1184 } else { 1235 } else {
1185 gen_op_load_gpr_T0(rA(ctx->opcode)); 1236 gen_op_load_gpr_T0(rA(ctx->opcode));
1186 gen_op_load_gpr_T1(rB(ctx->opcode)); 1237 gen_op_load_gpr_T1(rB(ctx->opcode));
1187 - gen_op_lwzx();  
1188 - gen_op_set_reservation(); 1238 + gen_op_lwarx();
1189 } 1239 }
1190 gen_op_store_T1_gpr(rD(ctx->opcode)); 1240 gen_op_store_T1_gpr(rD(ctx->opcode));
1191 SET_RETVAL(0); 1241 SET_RETVAL(0);
@@ -1207,8 +1257,6 @@ GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_MEM) @@ -1207,8 +1257,6 @@ GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_MEM)
1207 gen_op_load_gpr_T2(rS(ctx->opcode)); 1257 gen_op_load_gpr_T2(rS(ctx->opcode));
1208 gen_op_stwx(); 1258 gen_op_stwx();
1209 } 1259 }
1210 - gen_op_set_Rc0_1();  
1211 - gen_op_reset_reservation();  
1212 } 1260 }
1213 SET_RETVAL(0); 1261 SET_RETVAL(0);
1214 } 1262 }
@@ -1294,7 +1342,7 @@ GEN_LDF(s, 0x10); @@ -1294,7 +1342,7 @@ GEN_LDF(s, 0x10);
1294 GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ 1342 GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1295 { \ 1343 { \
1296 uint32_t simm = SIMM(ctx->opcode); \ 1344 uint32_t simm = SIMM(ctx->opcode); \
1297 - gen_op_load_FT0_fpr(rS(ctx->opcode));\ 1345 + gen_op_load_fpr_FT0(rS(ctx->opcode));\
1298 if (rA(ctx->opcode) == 0) { \ 1346 if (rA(ctx->opcode) == 0) { \
1299 gen_op_stf##width##_z_FT0(simm); \ 1347 gen_op_stf##width##_z_FT0(simm); \
1300 } else { \ 1348 } else { \
@@ -1310,7 +1358,7 @@ GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -1310,7 +1358,7 @@ GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1310 if (rA(ctx->opcode) == 0) \ 1358 if (rA(ctx->opcode) == 0) \
1311 SET_RETVAL(EXCP_INVAL); \ 1359 SET_RETVAL(EXCP_INVAL); \
1312 gen_op_load_gpr_T0(rA(ctx->opcode)); \ 1360 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1313 - gen_op_load_FT0_fpr(rS(ctx->opcode));\ 1361 + gen_op_load_fpr_FT0(rS(ctx->opcode));\
1314 gen_op_stf##width##_FT0(SIMM(ctx->opcode)); \ 1362 gen_op_stf##width##_FT0(SIMM(ctx->opcode)); \
1315 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 1363 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1316 SET_RETVAL(0); \ 1364 SET_RETVAL(0); \
@@ -1323,7 +1371,7 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ @@ -1323,7 +1371,7 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1323 SET_RETVAL(EXCP_INVAL); \ 1371 SET_RETVAL(EXCP_INVAL); \
1324 gen_op_load_gpr_T0(rA(ctx->opcode)); \ 1372 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1325 gen_op_load_gpr_T1(rB(ctx->opcode)); \ 1373 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1326 - gen_op_load_FT0_fpr(rS(ctx->opcode));\ 1374 + gen_op_load_fpr_FT0(rS(ctx->opcode));\
1327 gen_op_stf##width##x_FT0(); \ 1375 gen_op_stf##width##x_FT0(); \
1328 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 1376 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1329 SET_RETVAL(0); \ 1377 SET_RETVAL(0); \
@@ -1332,7 +1380,7 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ @@ -1332,7 +1380,7 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1332 #define GEN_STFX(width, opc) \ 1380 #define GEN_STFX(width, opc) \
1333 GEN_HANDLER(stf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ 1381 GEN_HANDLER(stf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1334 { \ 1382 { \
1335 - gen_op_load_FT0_fpr(rS(ctx->opcode));\ 1383 + gen_op_load_fpr_FT0(rS(ctx->opcode));\
1336 if (rA(ctx->opcode) == 0) { \ 1384 if (rA(ctx->opcode) == 0) { \
1337 gen_op_load_gpr_T0(rB(ctx->opcode)); \ 1385 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1338 gen_op_stf##width##x_z_FT0(); \ 1386 gen_op_stf##width##x_z_FT0(); \
@@ -1811,12 +1859,28 @@ GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x02, 0x03E00001, PPC_MEM) @@ -1811,12 +1859,28 @@ GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x02, 0x03E00001, PPC_MEM)
1811 /* dcbz */ 1859 /* dcbz */
1812 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x08, 0x03E00001, PPC_MEM) 1860 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x08, 0x03E00001, PPC_MEM)
1813 { 1861 {
  1862 + if (rA(ctx->opcode) == 0) {
  1863 + gen_op_load_gpr_T0(rB(ctx->opcode));
  1864 + gen_op_dcbz_z();
  1865 + } else {
  1866 + gen_op_load_gpr_T0(rA(ctx->opcode));
  1867 + gen_op_load_gpr_T1(rB(ctx->opcode));
  1868 + gen_op_dcbz();
  1869 + }
1814 SET_RETVAL(0); 1870 SET_RETVAL(0);
1815 } 1871 }
1816 1872
1817 /* icbi */ 1873 /* icbi */
1818 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_MEM) 1874 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_MEM)
1819 { 1875 {
  1876 + if (rA(ctx->opcode) == 0) {
  1877 + gen_op_load_gpr_T0(rB(ctx->opcode));
  1878 + gen_op_icbi_z();
  1879 + } else {
  1880 + gen_op_load_gpr_T0(rA(ctx->opcode));
  1881 + gen_op_load_gpr_T1(rB(ctx->opcode));
  1882 + gen_op_icbi();
  1883 + }
1820 SET_RETVAL(0); 1884 SET_RETVAL(0);
1821 } 1885 }
1822 1886
@@ -2252,7 +2316,7 @@ void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags) @@ -2252,7 +2316,7 @@ void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
2252 for (i = 0; i < 16; i++) { 2316 for (i = 0; i < 16; i++) {
2253 if ((i & 3) == 0) 2317 if ((i & 3) == 0)
2254 fprintf(logfile, "FPR%02d:", i); 2318 fprintf(logfile, "FPR%02d:", i);
2255 - fprintf(logfile, " %016llx", env->fpr[i]); 2319 + fprintf(logfile, " %016llx", *((uint64_t *)(&env->fpr[i])));
2256 if ((i & 3) == 3) 2320 if ((i & 3) == 3)
2257 fprintf(logfile, "\n"); 2321 fprintf(logfile, "\n");
2258 } 2322 }
@@ -2361,7 +2425,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -2361,7 +2425,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2361 #endif 2425 #endif
2362 } 2426 }
2363 #if defined (DO_STEP_FLUSH) 2427 #if defined (DO_STEP_FLUSH)
2364 - tb_flush(); 2428 + tb_flush(env);
2365 #endif 2429 #endif
2366 /* We need to update the time base */ 2430 /* We need to update the time base */
2367 if (!search_pc) 2431 if (!search_pc)