Revision fb0eaffc

b/target-ppc/cpu.h
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 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 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__) */
b/target-ppc/exec.h
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 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 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__) */
b/target-ppc/helper.c
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 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 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
}
b/target-ppc/op.c
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 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 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 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 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
}
b/target-ppc/op_template.h
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
b/target-ppc/translate.c
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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)

Also available in: Unified diff