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 152 /* general purpose registers */
153 153 uint32_t gpr[32];
154 154 /* floating point registers */
155   - uint64_t fpr[32];
  155 + double fpr[32];
156 156 /* segment registers */
157 157 ppc_sr_t sr[16];
158 158 /* special purpose registers */
... ... @@ -172,7 +172,10 @@ typedef struct CPUPPCState {
172 172 uint32_t exception;
173 173  
174 174 /* qemu dedicated */
175   - uint64_t ft0; /* temporary float register */
  175 + /* temporary float registers */
  176 + double ft0;
  177 + double ft1;
  178 + double ft2;
176 179 int interrupt_request;
177 180 jmp_buf jmp_env;
178 181 int exception_index;
... ... @@ -374,35 +377,4 @@ enum {
374 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 380 #endif /* !defined (__CPU_PPC_H__) */
... ...
target-ppc/exec.h
... ... @@ -29,6 +29,12 @@ register uint32_t T2 asm(AREG3);
29 29  
30 30 #define PARAM(n) ((uint32_t)PARAM##n)
31 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 39 #define RETURN() __asm__ __volatile__("");
34 40  
... ... @@ -145,8 +151,8 @@ uint32_t do_load_xer (void);
145 151 void do_store_xer (uint32_t value);
146 152 uint32_t do_load_msr (void);
147 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 157 int32_t do_sraw(int32_t Ta, uint32_t Tb);
152 158 void do_lmw (int reg, uint32_t src);
... ... @@ -154,4 +160,7 @@ void do_stmw (int reg, uint32_t dest);
154 160 void do_lsw (uint32_t reg, int count, uint32_t src);
155 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 166 #endif /* !defined (__PPC_H__) */
... ...
target-ppc/helper.c
... ... @@ -121,67 +121,67 @@ void do_store_msr (uint32_t msr_value)
121 121 }
122 122  
123 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 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 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 220 int sh;
221 221  
222 222 for (; count > 3; count -= 4, src += 4) {
223   - if (reg == 32)
224   - reg = 0;
225 223 ugpr(reg++) = ld32(src);
  224 + if (T2 == 32)
  225 + T2 = 0;
226 226 }
227 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 228 tmp = 0;
236   - }
  229 + for (sh = 24; count > 0; count--, src++, sh -= 8) {
  230 + tmp |= ld8(src) << sh;
237 231 }
238 232 ugpr(reg) = tmp;
239 233 }
... ... @@ -244,19 +238,30 @@ void do_stsw (uint32_t reg, int count, uint32_t dest)
244 238 int sh;
245 239  
246 240 for (; count > 3; count -= 4, dest += 4) {
  241 + st32(dest, ugpr(reg++));
247 242 if (reg == 32)
248 243 reg = 0;
249   - st32(dest, ugpr(reg++));
250 244 }
251 245 if (count > 0) {
252 246 for (sh = 24; count > 0; count--, dest++, sh -= 8) {
253   - if (reg == 32)
254   - reg = 0;
255 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 27 #define Ts2 (int32_t)T2
28 28  
29 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 37 #define PPC_OP(name) void op_##name(void)
32 38  
... ... @@ -173,6 +179,13 @@ PPC_OP(set_Rc0_1)
173 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 189 PPC_OP(set_T0)
177 190 {
178 191 T0 = PARAM(1);
... ... @@ -278,6 +291,25 @@ PPC_OP(load_lr)
278 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 313 /* Set reservation */
282 314 PPC_OP(set_reservation)
283 315 {
... ... @@ -988,7 +1020,7 @@ PPC_OP(xori)
988 1020 /* rotate left word immediate then mask insert */
989 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 1024 RETURN();
993 1025 }
994 1026  
... ... @@ -1216,123 +1248,171 @@ PPC_OP(store_spr)
1216 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 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 1253 PPC_OP(stfd_z_FT0)
1251 1254 {
1252   - st64(SPARAM(1), FT0);
  1255 + stfq((void *)SPARAM(1), FT0);
1253 1256 }
1254 1257  
1255 1258 PPC_OP(stfd_FT0)
1256 1259 {
1257 1260 T0 += SPARAM(1);
1258   - st64(T0, FT0);
  1261 + stfq((void *)T0, FT0);
1259 1262 }
1260 1263  
1261 1264 PPC_OP(stfdx_z_FT0)
1262 1265 {
1263   - st64(T0, FT0);
  1266 + stfq((void *)T0, FT0);
1264 1267 }
1265 1268  
1266 1269 PPC_OP(stfdx_FT0)
1267 1270 {
1268 1271 T0 += T1;
1269   - st64(T0, FT0);
  1272 + stfq((void *)T0, FT0);
1270 1273 }
1271 1274  
1272   -
1273 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 1281 PPC_OP(stfs_FT0)
1279 1282 {
  1283 + float tmp = FT0;
1280 1284 T0 += SPARAM(1);
1281   - st32(T0, dtos(FT0));
  1285 + stfl((void *)T0, tmp);
1282 1286 }
1283 1287  
1284 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 1294 PPC_OP(stfsx_FT0)
1290 1295 {
  1296 + float tmp = FT0;
1291 1297 T0 += T1;
1292   - st32(T0, dtos(FT0));
  1298 + stfl((void *)T0, tmp);
1293 1299 }
1294 1300  
1295 1301 /*** Floating-point load ***/
1296 1302 PPC_OP(lfd_z_FT0)
1297 1303 {
1298   - FT0 = ld64(SPARAM(1));
  1304 + FT0 = ldfq((void *)SPARAM(1));
1299 1305 }
1300 1306  
1301 1307 PPC_OP(lfd_FT0)
1302 1308 {
1303 1309 T0 += SPARAM(1);
1304   - FT0 = ld64(T0);
  1310 + FT0 = ldfq((void *)T0);
1305 1311 }
1306 1312  
1307 1313 PPC_OP(lfdx_z_FT0)
1308 1314 {
1309   - FT0 = ld64(T0);
  1315 + FT0 = ldfq((void *)T0);
1310 1316 }
1311 1317  
1312 1318 PPC_OP(lfdx_FT0)
1313 1319 {
1314 1320 T0 += T1;
1315   - FT0 = ld64(T0);
  1321 + FT0 = ldfq((void *)T0);
1316 1322 }
1317 1323  
1318 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 1330 PPC_OP(lfs_FT0)
1324 1331 {
  1332 + float tmp;
1325 1333 T0 += SPARAM(1);
1326   - FT0 = stod(ld32(T0));
  1334 + tmp = ldfl((void *)T0);
  1335 + FT0 = tmp;
1327 1336 }
1328 1337  
1329 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 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 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 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 118 #endif /* REG <= 7 */
74 119  
75 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 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 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 159 #undef REG
... ...
target-ppc/translate.c
... ... @@ -38,6 +38,9 @@ static uint32_t *gen_opparam_ptr;
38 38 #include "gen-op.h"
39 39  
40 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 45 #define GEN8(func, NAME) \
43 46 static GenOpFunc *NAME ## _table [8] = {\
... ... @@ -70,6 +73,25 @@ GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf)
70 73 GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf)
71 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 95 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr)
74 96 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr)
75 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 100 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr)
79 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 111 static uint8_t spr_access[1024 / 2];
85 112  
... ... @@ -198,10 +225,14 @@ EXTRACT_HELPER(SH, 11, 5);
198 225 EXTRACT_HELPER(MB, 6, 5);
199 226 /* Mask end */
200 227 EXTRACT_HELPER(ME, 1, 5);
  228 +/* Trap operand */
  229 +EXTRACT_HELPER(TO, 21, 5);
201 230  
202 231 EXTRACT_HELPER(CRM, 12, 8);
203 232 EXTRACT_HELPER(FM, 17, 8);
204 233 EXTRACT_HELPER(SR, 16, 4);
  234 +EXTRACT_HELPER(FPIMM, 20, 4);
  235 +
205 236 /*** Jump target decoding ***/
206 237 /* Displacement */
207 238 EXTRACT_SHELPER(d, 0, 16);
... ... @@ -597,6 +628,7 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
597 628 mb = MB(ctx->opcode);
598 629 me = ME(ctx->opcode);
599 630 gen_op_load_gpr_T0(rS(ctx->opcode));
  631 + gen_op_load_gpr_T1(rA(ctx->opcode));
600 632 gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me));
601 633 if (Rc(ctx->opcode) != 0)
602 634 gen_op_set_Rc0();
... ... @@ -847,47 +879,67 @@ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
847 879 /* mcrfs */
848 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 888 /* mffs */
854 889 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
855 890 {
856 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 895 SET_RETVAL(0);
862 896 }
863 897  
864 898 /* mtfsb0 */
865 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 912 /* mtfsb1 */
871 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 926 /* mtfsf */
877 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 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 933 SET_RETVAL(0);
885 934 }
886 935  
887 936 /* mtfsfi */
888 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 945 /*** Integer load ***/
... ... @@ -1179,13 +1231,11 @@ GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_MEM)
1179 1231 reserve = 1;
1180 1232 if (rA(ctx->opcode) == 0) {
1181 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 1235 } else {
1185 1236 gen_op_load_gpr_T0(rA(ctx->opcode));
1186 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 1240 gen_op_store_T1_gpr(rD(ctx->opcode));
1191 1241 SET_RETVAL(0);
... ... @@ -1207,8 +1257,6 @@ GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_MEM)
1207 1257 gen_op_load_gpr_T2(rS(ctx->opcode));
1208 1258 gen_op_stwx();
1209 1259 }
1210   - gen_op_set_Rc0_1();
1211   - gen_op_reset_reservation();
1212 1260 }
1213 1261 SET_RETVAL(0);
1214 1262 }
... ... @@ -1294,7 +1342,7 @@ GEN_LDF(s, 0x10);
1294 1342 GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1295 1343 { \
1296 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 1346 if (rA(ctx->opcode) == 0) { \
1299 1347 gen_op_stf##width##_z_FT0(simm); \
1300 1348 } else { \
... ... @@ -1310,7 +1358,7 @@ GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1310 1358 if (rA(ctx->opcode) == 0) \
1311 1359 SET_RETVAL(EXCP_INVAL); \
1312 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 1362 gen_op_stf##width##_FT0(SIMM(ctx->opcode)); \
1315 1363 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1316 1364 SET_RETVAL(0); \
... ... @@ -1323,7 +1371,7 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1323 1371 SET_RETVAL(EXCP_INVAL); \
1324 1372 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1325 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 1375 gen_op_stf##width##x_FT0(); \
1328 1376 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1329 1377 SET_RETVAL(0); \
... ... @@ -1332,7 +1380,7 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1332 1380 #define GEN_STFX(width, opc) \
1333 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 1384 if (rA(ctx->opcode) == 0) { \
1337 1385 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1338 1386 gen_op_stf##width##x_z_FT0(); \
... ... @@ -1811,12 +1859,28 @@ GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x02, 0x03E00001, PPC_MEM)
1811 1859 /* dcbz */
1812 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 1870 SET_RETVAL(0);
1815 1871 }
1816 1872  
1817 1873 /* icbi */
1818 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 1884 SET_RETVAL(0);
1821 1885 }
1822 1886  
... ... @@ -2252,7 +2316,7 @@ void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
2252 2316 for (i = 0; i < 16; i++) {
2253 2317 if ((i & 3) == 0)
2254 2318 fprintf(logfile, "FPR%02d:", i);
2255   - fprintf(logfile, " %016llx", env->fpr[i]);
  2319 + fprintf(logfile, " %016llx", *((uint64_t *)(&env->fpr[i])));
2256 2320 if ((i & 3) == 3)
2257 2321 fprintf(logfile, "\n");
2258 2322 }
... ... @@ -2361,7 +2425,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2361 2425 #endif
2362 2426 }
2363 2427 #if defined (DO_STEP_FLUSH)
2364   - tb_flush();
  2428 + tb_flush(env);
2365 2429 #endif
2366 2430 /* We need to update the time base */
2367 2431 if (!search_pc)
... ...