Commit fb0eaffc6d9982b5eee439b8461851bd18bf35ce
1 parent
07ad1b93
PowerPC fixes (Jocelyn Mayer)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@483 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
382 additions
and
180 deletions
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) | ... | ... |