Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ e1571908

History | View | Annotate | Download (239.8 kB)

1
/*
2
 *  PowerPC emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2003-2007 Jocelyn Mayer
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include <stdarg.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <inttypes.h>
25

    
26
#include "cpu.h"
27
#include "exec-all.h"
28
#include "disas.h"
29
#include "helper.h"
30
#include "tcg-op.h"
31
#include "qemu-common.h"
32

    
33
#define CPU_SINGLE_STEP 0x1
34
#define CPU_BRANCH_STEP 0x2
35
#define GDBSTUB_SINGLE_STEP 0x4
36

    
37
/* Include definitions for instructions classes and implementations flags */
38
//#define DO_SINGLE_STEP
39
//#define PPC_DEBUG_DISAS
40
//#define DO_PPC_STATISTICS
41
//#define OPTIMIZE_FPRF_UPDATE
42

    
43
/*****************************************************************************/
44
/* Code translation helpers                                                  */
45

    
46
/* global register indexes */
47
static TCGv cpu_env;
48
static char cpu_reg_names[10*3 + 22*4 /* GPR */
49
#if !defined(TARGET_PPC64)
50
    + 10*4 + 22*5 /* SPE GPRh */
51
#endif
52
    + 10*4 + 22*5 /* FPR */
53
    + 2*(10*6 + 22*7) /* AVRh, AVRl */
54
    + 8*5 /* CRF */];
55
static TCGv cpu_gpr[32];
56
#if !defined(TARGET_PPC64)
57
static TCGv cpu_gprh[32];
58
#endif
59
static TCGv cpu_fpr[32];
60
static TCGv cpu_avrh[32], cpu_avrl[32];
61
static TCGv cpu_crf[8];
62
static TCGv cpu_nip;
63
static TCGv cpu_ctr;
64
static TCGv cpu_lr;
65
static TCGv cpu_xer;
66
static TCGv cpu_fpscr;
67

    
68
/* dyngen register indexes */
69
static TCGv cpu_T[3];
70
#if defined(TARGET_PPC64)
71
#define cpu_T64 cpu_T
72
#else
73
static TCGv cpu_T64[3];
74
#endif
75
static TCGv cpu_FT[3];
76
static TCGv cpu_AVRh[3], cpu_AVRl[3];
77

    
78
#include "gen-icount.h"
79

    
80
void ppc_translate_init(void)
81
{
82
    int i;
83
    char* p;
84
    static int done_init = 0;
85

    
86
    if (done_init)
87
        return;
88

    
89
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
90
#if TARGET_LONG_BITS > HOST_LONG_BITS
91
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
92
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
93
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
94
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
95
    cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
96
                                  TCG_AREG0, offsetof(CPUState, t2), "T2");
97
#else
98
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
99
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
100
    cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
101
#endif
102
#if !defined(TARGET_PPC64)
103
    cpu_T64[0] = tcg_global_mem_new(TCG_TYPE_I64,
104
                                    TCG_AREG0, offsetof(CPUState, t0_64),
105
                                    "T0_64");
106
    cpu_T64[1] = tcg_global_mem_new(TCG_TYPE_I64,
107
                                    TCG_AREG0, offsetof(CPUState, t1_64),
108
                                    "T1_64");
109
    cpu_T64[2] = tcg_global_mem_new(TCG_TYPE_I64,
110
                                    TCG_AREG0, offsetof(CPUState, t2_64),
111
                                    "T2_64");
112
#endif
113

    
114
    cpu_FT[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
115
                                   offsetof(CPUState, ft0), "FT0");
116
    cpu_FT[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
117
                                   offsetof(CPUState, ft1), "FT1");
118
    cpu_FT[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
119
                                   offsetof(CPUState, ft2), "FT2");
120

    
121
    cpu_AVRh[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
122
                                     offsetof(CPUState, avr0.u64[0]), "AVR0H");
123
    cpu_AVRl[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
124
                                     offsetof(CPUState, avr0.u64[1]), "AVR0L");
125
    cpu_AVRh[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
126
                                     offsetof(CPUState, avr1.u64[0]), "AVR1H");
127
    cpu_AVRl[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
128
                                     offsetof(CPUState, avr1.u64[1]), "AVR1L");
129
    cpu_AVRh[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
130
                                     offsetof(CPUState, avr2.u64[0]), "AVR2H");
131
    cpu_AVRl[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
132
                                     offsetof(CPUState, avr2.u64[1]), "AVR2L");
133

    
134
    p = cpu_reg_names;
135

    
136
    for (i = 0; i < 8; i++) {
137
        sprintf(p, "crf%d", i);
138
        cpu_crf[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
139
                                        offsetof(CPUState, crf[i]), p);
140
        p += 5;
141
    }
142

    
143
    for (i = 0; i < 32; i++) {
144
        sprintf(p, "r%d", i);
145
        cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
146
                                        offsetof(CPUState, gpr[i]), p);
147
        p += (i < 10) ? 3 : 4;
148
#if !defined(TARGET_PPC64)
149
        sprintf(p, "r%dH", i);
150
        cpu_gprh[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
151
                                         offsetof(CPUState, gprh[i]), p);
152
        p += (i < 10) ? 4 : 5;
153
#endif
154

    
155
        sprintf(p, "fp%d", i);
156
        cpu_fpr[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
157
                                        offsetof(CPUState, fpr[i]), p);
158
        p += (i < 10) ? 4 : 5;
159

    
160
        sprintf(p, "avr%dH", i);
161
        cpu_avrh[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
162
                                         offsetof(CPUState, avr[i].u64[0]), p);
163
        p += (i < 10) ? 6 : 7;
164

    
165
        sprintf(p, "avr%dL", i);
166
        cpu_avrl[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
167
                                         offsetof(CPUState, avr[i].u64[1]), p);
168
        p += (i < 10) ? 6 : 7;
169
    }
170

    
171
    cpu_nip = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
172
                                 offsetof(CPUState, nip), "nip");
173

    
174
    cpu_ctr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
175
                                 offsetof(CPUState, ctr), "ctr");
176

    
177
    cpu_lr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
178
                                offsetof(CPUState, lr), "lr");
179

    
180
    cpu_xer = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
181
                                 offsetof(CPUState, xer), "xer");
182

    
183
    cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
184
                                   offsetof(CPUState, fpscr), "fpscr");
185

    
186
    /* register helpers */
187
#undef DEF_HELPER
188
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
189
#include "helper.h"
190

    
191
    done_init = 1;
192
}
193

    
194
#if defined(OPTIMIZE_FPRF_UPDATE)
195
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
196
static uint16_t **gen_fprf_ptr;
197
#endif
198

    
199
/* internal defines */
200
typedef struct DisasContext {
201
    struct TranslationBlock *tb;
202
    target_ulong nip;
203
    uint32_t opcode;
204
    uint32_t exception;
205
    /* Routine used to access memory */
206
    int mem_idx;
207
    /* Translation flags */
208
#if !defined(CONFIG_USER_ONLY)
209
    int supervisor;
210
#endif
211
#if defined(TARGET_PPC64)
212
    int sf_mode;
213
#endif
214
    int fpu_enabled;
215
    int altivec_enabled;
216
    int spe_enabled;
217
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
218
    int singlestep_enabled;
219
    int dcache_line_size;
220
} DisasContext;
221

    
222
struct opc_handler_t {
223
    /* invalid bits */
224
    uint32_t inval;
225
    /* instruction type */
226
    uint64_t type;
227
    /* handler */
228
    void (*handler)(DisasContext *ctx);
229
#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
230
    const char *oname;
231
#endif
232
#if defined(DO_PPC_STATISTICS)
233
    uint64_t count;
234
#endif
235
};
236

    
237
static always_inline void gen_reset_fpstatus (void)
238
{
239
#ifdef CONFIG_SOFTFLOAT
240
    gen_op_reset_fpstatus();
241
#endif
242
}
243

    
244
static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
245
{
246
    if (set_fprf != 0) {
247
        /* This case might be optimized later */
248
#if defined(OPTIMIZE_FPRF_UPDATE)
249
        *gen_fprf_ptr++ = gen_opc_ptr;
250
#endif
251
        gen_op_compute_fprf(1);
252
        if (unlikely(set_rc))
253
            tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
254
        gen_op_float_check_status();
255
    } else if (unlikely(set_rc)) {
256
        /* We always need to compute fpcc */
257
        gen_op_compute_fprf(0);
258
        tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
259
        if (set_fprf)
260
            gen_op_float_check_status();
261
    }
262
}
263

    
264
static always_inline void gen_optimize_fprf (void)
265
{
266
#if defined(OPTIMIZE_FPRF_UPDATE)
267
    uint16_t **ptr;
268

    
269
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
270
        *ptr = INDEX_op_nop1;
271
    gen_fprf_ptr = gen_fprf_buf;
272
#endif
273
}
274

    
275
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
276
{
277
#if defined(TARGET_PPC64)
278
    if (ctx->sf_mode)
279
        tcg_gen_movi_tl(cpu_nip, nip);
280
    else
281
#endif
282
        tcg_gen_movi_tl(cpu_nip, (uint32_t)nip);
283
}
284

    
285
#define GEN_EXCP(ctx, excp, error)                                            \
286
do {                                                                          \
287
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
288
        gen_update_nip(ctx, (ctx)->nip);                                      \
289
    }                                                                         \
290
    gen_op_raise_exception_err((excp), (error));                              \
291
    ctx->exception = (excp);                                                  \
292
} while (0)
293

    
294
#define GEN_EXCP_INVAL(ctx)                                                   \
295
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
296
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
297

    
298
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
299
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
300
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
301

    
302
#define GEN_EXCP_PRIVREG(ctx)                                                 \
303
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
304
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
305

    
306
#define GEN_EXCP_NO_FP(ctx)                                                   \
307
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
308

    
309
#define GEN_EXCP_NO_AP(ctx)                                                   \
310
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
311

    
312
#define GEN_EXCP_NO_VR(ctx)                                                   \
313
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
314

    
315
/* Stop translation */
316
static always_inline void GEN_STOP (DisasContext *ctx)
317
{
318
    gen_update_nip(ctx, ctx->nip);
319
    ctx->exception = POWERPC_EXCP_STOP;
320
}
321

    
322
/* No need to update nip here, as execution flow will change */
323
static always_inline void GEN_SYNC (DisasContext *ctx)
324
{
325
    ctx->exception = POWERPC_EXCP_SYNC;
326
}
327

    
328
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
329
static void gen_##name (DisasContext *ctx);                                   \
330
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
331
static void gen_##name (DisasContext *ctx)
332

    
333
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
334
static void gen_##name (DisasContext *ctx);                                   \
335
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
336
static void gen_##name (DisasContext *ctx)
337

    
338
typedef struct opcode_t {
339
    unsigned char opc1, opc2, opc3;
340
#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
341
    unsigned char pad[5];
342
#else
343
    unsigned char pad[1];
344
#endif
345
    opc_handler_t handler;
346
    const char *oname;
347
} opcode_t;
348

    
349
/*****************************************************************************/
350
/***                           Instruction decoding                        ***/
351
#define EXTRACT_HELPER(name, shift, nb)                                       \
352
static always_inline uint32_t name (uint32_t opcode)                          \
353
{                                                                             \
354
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
355
}
356

    
357
#define EXTRACT_SHELPER(name, shift, nb)                                      \
358
static always_inline int32_t name (uint32_t opcode)                           \
359
{                                                                             \
360
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
361
}
362

    
363
/* Opcode part 1 */
364
EXTRACT_HELPER(opc1, 26, 6);
365
/* Opcode part 2 */
366
EXTRACT_HELPER(opc2, 1, 5);
367
/* Opcode part 3 */
368
EXTRACT_HELPER(opc3, 6, 5);
369
/* Update Cr0 flags */
370
EXTRACT_HELPER(Rc, 0, 1);
371
/* Destination */
372
EXTRACT_HELPER(rD, 21, 5);
373
/* Source */
374
EXTRACT_HELPER(rS, 21, 5);
375
/* First operand */
376
EXTRACT_HELPER(rA, 16, 5);
377
/* Second operand */
378
EXTRACT_HELPER(rB, 11, 5);
379
/* Third operand */
380
EXTRACT_HELPER(rC, 6, 5);
381
/***                               Get CRn                                 ***/
382
EXTRACT_HELPER(crfD, 23, 3);
383
EXTRACT_HELPER(crfS, 18, 3);
384
EXTRACT_HELPER(crbD, 21, 5);
385
EXTRACT_HELPER(crbA, 16, 5);
386
EXTRACT_HELPER(crbB, 11, 5);
387
/* SPR / TBL */
388
EXTRACT_HELPER(_SPR, 11, 10);
389
static always_inline uint32_t SPR (uint32_t opcode)
390
{
391
    uint32_t sprn = _SPR(opcode);
392

    
393
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
394
}
395
/***                              Get constants                            ***/
396
EXTRACT_HELPER(IMM, 12, 8);
397
/* 16 bits signed immediate value */
398
EXTRACT_SHELPER(SIMM, 0, 16);
399
/* 16 bits unsigned immediate value */
400
EXTRACT_HELPER(UIMM, 0, 16);
401
/* Bit count */
402
EXTRACT_HELPER(NB, 11, 5);
403
/* Shift count */
404
EXTRACT_HELPER(SH, 11, 5);
405
/* Mask start */
406
EXTRACT_HELPER(MB, 6, 5);
407
/* Mask end */
408
EXTRACT_HELPER(ME, 1, 5);
409
/* Trap operand */
410
EXTRACT_HELPER(TO, 21, 5);
411

    
412
EXTRACT_HELPER(CRM, 12, 8);
413
EXTRACT_HELPER(FM, 17, 8);
414
EXTRACT_HELPER(SR, 16, 4);
415
EXTRACT_HELPER(FPIMM, 12, 4);
416

    
417
/***                            Jump target decoding                       ***/
418
/* Displacement */
419
EXTRACT_SHELPER(d, 0, 16);
420
/* Immediate address */
421
static always_inline target_ulong LI (uint32_t opcode)
422
{
423
    return (opcode >> 0) & 0x03FFFFFC;
424
}
425

    
426
static always_inline uint32_t BD (uint32_t opcode)
427
{
428
    return (opcode >> 0) & 0xFFFC;
429
}
430

    
431
EXTRACT_HELPER(BO, 21, 5);
432
EXTRACT_HELPER(BI, 16, 5);
433
/* Absolute/relative address */
434
EXTRACT_HELPER(AA, 1, 1);
435
/* Link */
436
EXTRACT_HELPER(LK, 0, 1);
437

    
438
/* Create a mask between <start> and <end> bits */
439
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
440
{
441
    target_ulong ret;
442

    
443
#if defined(TARGET_PPC64)
444
    if (likely(start == 0)) {
445
        ret = UINT64_MAX << (63 - end);
446
    } else if (likely(end == 63)) {
447
        ret = UINT64_MAX >> start;
448
    }
449
#else
450
    if (likely(start == 0)) {
451
        ret = UINT32_MAX << (31  - end);
452
    } else if (likely(end == 31)) {
453
        ret = UINT32_MAX >> start;
454
    }
455
#endif
456
    else {
457
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
458
            (((target_ulong)(-1ULL) >> (end)) >> 1);
459
        if (unlikely(start > end))
460
            return ~ret;
461
    }
462

    
463
    return ret;
464
}
465

    
466
/*****************************************************************************/
467
/* PowerPC Instructions types definitions                                    */
468
enum {
469
    PPC_NONE           = 0x0000000000000000ULL,
470
    /* PowerPC base instructions set                                         */
471
    PPC_INSNS_BASE     = 0x0000000000000001ULL,
472
    /*   integer operations instructions                                     */
473
#define PPC_INTEGER PPC_INSNS_BASE
474
    /*   flow control instructions                                           */
475
#define PPC_FLOW    PPC_INSNS_BASE
476
    /*   virtual memory instructions                                         */
477
#define PPC_MEM     PPC_INSNS_BASE
478
    /*   ld/st with reservation instructions                                 */
479
#define PPC_RES     PPC_INSNS_BASE
480
    /*   spr/msr access instructions                                         */
481
#define PPC_MISC    PPC_INSNS_BASE
482
    /* Deprecated instruction sets                                           */
483
    /*   Original POWER instruction set                                      */
484
    PPC_POWER          = 0x0000000000000002ULL,
485
    /*   POWER2 instruction set extension                                    */
486
    PPC_POWER2         = 0x0000000000000004ULL,
487
    /*   Power RTC support                                                   */
488
    PPC_POWER_RTC      = 0x0000000000000008ULL,
489
    /*   Power-to-PowerPC bridge (601)                                       */
490
    PPC_POWER_BR       = 0x0000000000000010ULL,
491
    /* 64 bits PowerPC instruction set                                       */
492
    PPC_64B            = 0x0000000000000020ULL,
493
    /*   New 64 bits extensions (PowerPC 2.0x)                               */
494
    PPC_64BX           = 0x0000000000000040ULL,
495
    /*   64 bits hypervisor extensions                                       */
496
    PPC_64H            = 0x0000000000000080ULL,
497
    /*   New wait instruction (PowerPC 2.0x)                                 */
498
    PPC_WAIT           = 0x0000000000000100ULL,
499
    /*   Time base mftb instruction                                          */
500
    PPC_MFTB           = 0x0000000000000200ULL,
501

    
502
    /* Fixed-point unit extensions                                           */
503
    /*   PowerPC 602 specific                                                */
504
    PPC_602_SPEC       = 0x0000000000000400ULL,
505
    /*   isel instruction                                                    */
506
    PPC_ISEL           = 0x0000000000000800ULL,
507
    /*   popcntb instruction                                                 */
508
    PPC_POPCNTB        = 0x0000000000001000ULL,
509
    /*   string load / store                                                 */
510
    PPC_STRING         = 0x0000000000002000ULL,
511

    
512
    /* Floating-point unit extensions                                        */
513
    /*   Optional floating point instructions                                */
514
    PPC_FLOAT          = 0x0000000000010000ULL,
515
    /* New floating-point extensions (PowerPC 2.0x)                          */
516
    PPC_FLOAT_EXT      = 0x0000000000020000ULL,
517
    PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
518
    PPC_FLOAT_FRES     = 0x0000000000080000ULL,
519
    PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
520
    PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
521
    PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
522
    PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
523

    
524
    /* Vector/SIMD extensions                                                */
525
    /*   Altivec support                                                     */
526
    PPC_ALTIVEC        = 0x0000000001000000ULL,
527
    /*   PowerPC 2.03 SPE extension                                          */
528
    PPC_SPE            = 0x0000000002000000ULL,
529
    /*   PowerPC 2.03 SPE floating-point extension                           */
530
    PPC_SPEFPU         = 0x0000000004000000ULL,
531

    
532
    /* Optional memory control instructions                                  */
533
    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
534
    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
535
    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
536
    /*   sync instruction                                                    */
537
    PPC_MEM_SYNC       = 0x0000000080000000ULL,
538
    /*   eieio instruction                                                   */
539
    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
540

    
541
    /* Cache control instructions                                            */
542
    PPC_CACHE          = 0x0000000200000000ULL,
543
    /*   icbi instruction                                                    */
544
    PPC_CACHE_ICBI     = 0x0000000400000000ULL,
545
    /*   dcbz instruction with fixed cache line size                         */
546
    PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
547
    /*   dcbz instruction with tunable cache line size                       */
548
    PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
549
    /*   dcba instruction                                                    */
550
    PPC_CACHE_DCBA     = 0x0000002000000000ULL,
551
    /*   Freescale cache locking instructions                                */
552
    PPC_CACHE_LOCK     = 0x0000004000000000ULL,
553

    
554
    /* MMU related extensions                                                */
555
    /*   external control instructions                                       */
556
    PPC_EXTERN         = 0x0000010000000000ULL,
557
    /*   segment register access instructions                                */
558
    PPC_SEGMENT        = 0x0000020000000000ULL,
559
    /*   PowerPC 6xx TLB management instructions                             */
560
    PPC_6xx_TLB        = 0x0000040000000000ULL,
561
    /* PowerPC 74xx TLB management instructions                              */
562
    PPC_74xx_TLB       = 0x0000080000000000ULL,
563
    /*   PowerPC 40x TLB management instructions                             */
564
    PPC_40x_TLB        = 0x0000100000000000ULL,
565
    /*   segment register access instructions for PowerPC 64 "bridge"        */
566
    PPC_SEGMENT_64B    = 0x0000200000000000ULL,
567
    /*   SLB management                                                      */
568
    PPC_SLBI           = 0x0000400000000000ULL,
569

    
570
    /* Embedded PowerPC dedicated instructions                               */
571
    PPC_WRTEE          = 0x0001000000000000ULL,
572
    /* PowerPC 40x exception model                                           */
573
    PPC_40x_EXCP       = 0x0002000000000000ULL,
574
    /* PowerPC 405 Mac instructions                                          */
575
    PPC_405_MAC        = 0x0004000000000000ULL,
576
    /* PowerPC 440 specific instructions                                     */
577
    PPC_440_SPEC       = 0x0008000000000000ULL,
578
    /* BookE (embedded) PowerPC specification                                */
579
    PPC_BOOKE          = 0x0010000000000000ULL,
580
    /* mfapidi instruction                                                   */
581
    PPC_MFAPIDI        = 0x0020000000000000ULL,
582
    /* tlbiva instruction                                                    */
583
    PPC_TLBIVA         = 0x0040000000000000ULL,
584
    /* tlbivax instruction                                                   */
585
    PPC_TLBIVAX        = 0x0080000000000000ULL,
586
    /* PowerPC 4xx dedicated instructions                                    */
587
    PPC_4xx_COMMON     = 0x0100000000000000ULL,
588
    /* PowerPC 40x ibct instructions                                         */
589
    PPC_40x_ICBT       = 0x0200000000000000ULL,
590
    /* rfmci is not implemented in all BookE PowerPC                         */
591
    PPC_RFMCI          = 0x0400000000000000ULL,
592
    /* rfdi instruction                                                      */
593
    PPC_RFDI           = 0x0800000000000000ULL,
594
    /* DCR accesses                                                          */
595
    PPC_DCR            = 0x1000000000000000ULL,
596
    /* DCR extended accesse                                                  */
597
    PPC_DCRX           = 0x2000000000000000ULL,
598
    /* user-mode DCR access, implemented in PowerPC 460                      */
599
    PPC_DCRUX          = 0x4000000000000000ULL,
600
};
601

    
602
/*****************************************************************************/
603
/* PowerPC instructions table                                                */
604
#if HOST_LONG_BITS == 64
605
#define OPC_ALIGN 8
606
#else
607
#define OPC_ALIGN 4
608
#endif
609
#if defined(__APPLE__)
610
#define OPCODES_SECTION                                                       \
611
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
612
#else
613
#define OPCODES_SECTION                                                       \
614
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
615
#endif
616

    
617
#if defined(DO_PPC_STATISTICS)
618
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
619
OPCODES_SECTION opcode_t opc_##name = {                                       \
620
    .opc1 = op1,                                                              \
621
    .opc2 = op2,                                                              \
622
    .opc3 = op3,                                                              \
623
    .pad  = { 0, },                                                           \
624
    .handler = {                                                              \
625
        .inval   = invl,                                                      \
626
        .type = _typ,                                                         \
627
        .handler = &gen_##name,                                               \
628
        .oname = stringify(name),                                             \
629
    },                                                                        \
630
    .oname = stringify(name),                                                 \
631
}
632
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
633
OPCODES_SECTION opcode_t opc_##name = {                                       \
634
    .opc1 = op1,                                                              \
635
    .opc2 = op2,                                                              \
636
    .opc3 = op3,                                                              \
637
    .pad  = { 0, },                                                           \
638
    .handler = {                                                              \
639
        .inval   = invl,                                                      \
640
        .type = _typ,                                                         \
641
        .handler = &gen_##name,                                               \
642
        .oname = onam,                                                        \
643
    },                                                                        \
644
    .oname = onam,                                                            \
645
}
646
#else
647
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
648
OPCODES_SECTION opcode_t opc_##name = {                                       \
649
    .opc1 = op1,                                                              \
650
    .opc2 = op2,                                                              \
651
    .opc3 = op3,                                                              \
652
    .pad  = { 0, },                                                           \
653
    .handler = {                                                              \
654
        .inval   = invl,                                                      \
655
        .type = _typ,                                                         \
656
        .handler = &gen_##name,                                               \
657
    },                                                                        \
658
    .oname = stringify(name),                                                 \
659
}
660
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
661
OPCODES_SECTION opcode_t opc_##name = {                                       \
662
    .opc1 = op1,                                                              \
663
    .opc2 = op2,                                                              \
664
    .opc3 = op3,                                                              \
665
    .pad  = { 0, },                                                           \
666
    .handler = {                                                              \
667
        .inval   = invl,                                                      \
668
        .type = _typ,                                                         \
669
        .handler = &gen_##name,                                               \
670
    },                                                                        \
671
    .oname = onam,                                                            \
672
}
673
#endif
674

    
675
#define GEN_OPCODE_MARK(name)                                                 \
676
OPCODES_SECTION opcode_t opc_##name = {                                       \
677
    .opc1 = 0xFF,                                                             \
678
    .opc2 = 0xFF,                                                             \
679
    .opc3 = 0xFF,                                                             \
680
    .pad  = { 0, },                                                           \
681
    .handler = {                                                              \
682
        .inval   = 0x00000000,                                                \
683
        .type = 0x00,                                                         \
684
        .handler = NULL,                                                      \
685
    },                                                                        \
686
    .oname = stringify(name),                                                 \
687
}
688

    
689
/* Start opcode list */
690
GEN_OPCODE_MARK(start);
691

    
692
/* Invalid instruction */
693
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
694
{
695
    GEN_EXCP_INVAL(ctx);
696
}
697

    
698
static opc_handler_t invalid_handler = {
699
    .inval   = 0xFFFFFFFF,
700
    .type    = PPC_NONE,
701
    .handler = gen_invalid,
702
};
703

    
704
/***                           Integer comparison                          ***/
705

    
706
static always_inline void gen_op_cmp(TCGv t0, TCGv t1, int s, int crf)
707
{
708
    int l1, l2, l3;
709

    
710
    tcg_gen_shri_i32(cpu_crf[crf], cpu_xer, XER_SO);
711
    tcg_gen_andi_i32(cpu_crf[crf], cpu_crf[crf], 1);
712

    
713
    l1 = gen_new_label();
714
    l2 = gen_new_label();
715
    l3 = gen_new_label();
716
    if (s) {
717
        tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
718
        tcg_gen_brcond_tl(TCG_COND_GT, t0, t1, l2);
719
    } else {
720
        tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
721
        tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l2);
722
    }
723
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_EQ);
724
    tcg_gen_br(l3);
725
    gen_set_label(l1);
726
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_LT);
727
    tcg_gen_br(l3);
728
    gen_set_label(l2);
729
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_GT);
730
    gen_set_label(l3);
731
}
732

    
733
static always_inline void gen_op_cmpi(TCGv t0, target_ulong t1, int s, int crf)
734
{
735
    TCGv temp = tcg_const_local_tl(t1);
736
    gen_op_cmp(t0, temp, s, crf);
737
    tcg_temp_free(temp);
738
}
739

    
740
#if defined(TARGET_PPC64)
741
static always_inline void gen_op_cmp32(TCGv t0, TCGv t1, int s, int crf)
742
{
743
    TCGv t0_32, t1_32;
744
    t0_32 = tcg_temp_local_new(TCG_TYPE_TL);
745
    t1_32 = tcg_temp_local_new(TCG_TYPE_TL);
746
    if (s) {
747
        tcg_gen_ext32s_tl(t0_32, t0);
748
        tcg_gen_ext32s_tl(t1_32, t1);
749
    } else {
750
        tcg_gen_ext32u_tl(t0_32, t0);
751
        tcg_gen_ext32u_tl(t1_32, t1);
752
    }
753
    gen_op_cmp(t0_32, t1_32, s, crf);
754
    tcg_temp_free(t1_32);
755
    tcg_temp_free(t0_32);
756
}
757

    
758
static always_inline void gen_op_cmpi32(TCGv t0, target_ulong t1, int s, int crf)
759
{
760
    TCGv temp = tcg_const_local_tl(t1);
761
    gen_op_cmp32(t0, temp, s, crf);
762
    tcg_temp_free(temp);
763
}
764
#endif
765

    
766
static always_inline void gen_set_Rc0 (DisasContext *ctx, TCGv reg)
767
{
768
#if defined(TARGET_PPC64)
769
    if (!(ctx->sf_mode))
770
        gen_op_cmpi32(reg, 0, 1, 0);
771
    else
772
#endif
773
        gen_op_cmpi(reg, 0, 1, 0);
774
}
775

    
776
/* cmp */
777
GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER)
778
{
779
#if defined(TARGET_PPC64)
780
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
781
        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
782
                     1, crfD(ctx->opcode));
783
    else
784
#endif
785
        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
786
                   1, crfD(ctx->opcode));
787
}
788

    
789
/* cmpi */
790
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
791
{
792
#if defined(TARGET_PPC64)
793
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
794
        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
795
                      1, crfD(ctx->opcode));
796
    else
797
#endif
798
        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
799
                    1, crfD(ctx->opcode));
800
}
801

    
802
/* cmpl */
803
GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER)
804
{
805
#if defined(TARGET_PPC64)
806
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
807
        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
808
                     0, crfD(ctx->opcode));
809
    else
810
#endif
811
        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
812
                   0, crfD(ctx->opcode));
813
}
814

    
815
/* cmpli */
816
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
817
{
818
#if defined(TARGET_PPC64)
819
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
820
        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
821
                      0, crfD(ctx->opcode));
822
    else
823
#endif
824
        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
825
                    0, crfD(ctx->opcode));
826
}
827

    
828
/* isel (PowerPC 2.03 specification) */
829
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
830
{
831
    int l1, l2;
832
    uint32_t bi = rC(ctx->opcode);
833
    uint32_t mask;
834
    TCGv temp;
835

    
836
    l1 = gen_new_label();
837
    l2 = gen_new_label();
838

    
839
    mask = 1 << (3 - (bi & 0x03));
840
    temp = tcg_temp_new(TCG_TYPE_I32);
841
    tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
842
    tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
843
    if (rA(ctx->opcode) == 0)
844
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
845
    else
846
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
847
    tcg_gen_br(l2);
848
    gen_set_label(l1);
849
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
850
    gen_set_label(l2);
851
}
852

    
853
/***                           Integer arithmetic                          ***/
854
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
855
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
856
{                                                                             \
857
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
858
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
859
    gen_op_##name();                                                          \
860
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
861
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
862
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
863
}
864

    
865
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
866
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
867
{                                                                             \
868
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
869
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
870
    gen_op_##name();                                                          \
871
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
872
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
873
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
874
}
875

    
876
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
877
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
878
{                                                                             \
879
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
880
    gen_op_##name();                                                          \
881
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
882
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
883
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
884
}
885
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
886
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
887
{                                                                             \
888
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
889
    gen_op_##name();                                                          \
890
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
891
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
892
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
893
}
894

    
895
/* Two operands arithmetic functions */
896
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
897
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
898
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
899

    
900
/* Two operands arithmetic functions with no overflow allowed */
901
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
902
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
903

    
904
/* One operand arithmetic functions */
905
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
906
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
907
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
908

    
909
#if defined(TARGET_PPC64)
910
#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
911
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
912
{                                                                             \
913
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
914
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
915
    if (ctx->sf_mode)                                                         \
916
        gen_op_##name##_64();                                                 \
917
    else                                                                      \
918
        gen_op_##name();                                                      \
919
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
920
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
921
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
922
}
923

    
924
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
925
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
926
{                                                                             \
927
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
928
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
929
    if (ctx->sf_mode)                                                         \
930
        gen_op_##name##_64();                                                 \
931
    else                                                                      \
932
        gen_op_##name();                                                      \
933
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
934
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
935
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
936
}
937

    
938
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
939
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
940
{                                                                             \
941
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
942
    if (ctx->sf_mode)                                                         \
943
        gen_op_##name##_64();                                                 \
944
    else                                                                      \
945
        gen_op_##name();                                                      \
946
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
947
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
948
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
949
}
950
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
951
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
952
{                                                                             \
953
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
954
    if (ctx->sf_mode)                                                         \
955
        gen_op_##name##_64();                                                 \
956
    else                                                                      \
957
        gen_op_##name();                                                      \
958
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
959
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
960
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
961
}
962

    
963
/* Two operands arithmetic functions */
964
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
965
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
966
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
967

    
968
/* Two operands arithmetic functions with no overflow allowed */
969
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
970
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
971

    
972
/* One operand arithmetic functions */
973
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
974
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
975
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
976
#else
977
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
978
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
979
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
980
#endif
981

    
982
/* add    add.    addo    addo.    */
983
static always_inline void gen_op_add (void)
984
{
985
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
986
}
987
static always_inline void gen_op_addo (void)
988
{
989
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
990
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
991
    gen_op_check_addo();
992
}
993
#if defined(TARGET_PPC64)
994
#define gen_op_add_64 gen_op_add
995
static always_inline void gen_op_addo_64 (void)
996
{
997
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
998
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
999
    gen_op_check_addo_64();
1000
}
1001
#endif
1002
GEN_INT_ARITH2_64 (add,    0x1F, 0x0A, 0x08, PPC_INTEGER);
1003
/* addc   addc.   addco   addco.   */
1004
static always_inline void gen_op_addc (void)
1005
{
1006
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1007
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1008
    gen_op_check_addc();
1009
}
1010
static always_inline void gen_op_addco (void)
1011
{
1012
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1013
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1014
    gen_op_check_addc();
1015
    gen_op_check_addo();
1016
}
1017
#if defined(TARGET_PPC64)
1018
static always_inline void gen_op_addc_64 (void)
1019
{
1020
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1021
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1022
    gen_op_check_addc_64();
1023
}
1024
static always_inline void gen_op_addco_64 (void)
1025
{
1026
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1027
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1028
    gen_op_check_addc_64();
1029
    gen_op_check_addo_64();
1030
}
1031
#endif
1032
GEN_INT_ARITH2_64 (addc,   0x1F, 0x0A, 0x00, PPC_INTEGER);
1033
/* adde   adde.   addeo   addeo.   */
1034
static always_inline void gen_op_addeo (void)
1035
{
1036
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1037
    gen_op_adde();
1038
    gen_op_check_addo();
1039
}
1040
#if defined(TARGET_PPC64)
1041
static always_inline void gen_op_addeo_64 (void)
1042
{
1043
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1044
    gen_op_adde_64();
1045
    gen_op_check_addo_64();
1046
}
1047
#endif
1048
GEN_INT_ARITH2_64 (adde,   0x1F, 0x0A, 0x04, PPC_INTEGER);
1049
/* addme  addme.  addmeo  addmeo.  */
1050
static always_inline void gen_op_addme (void)
1051
{
1052
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1053
    gen_op_add_me();
1054
}
1055
#if defined(TARGET_PPC64)
1056
static always_inline void gen_op_addme_64 (void)
1057
{
1058
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1059
    gen_op_add_me_64();
1060
}
1061
#endif
1062
GEN_INT_ARITH1_64 (addme,  0x1F, 0x0A, 0x07, PPC_INTEGER);
1063
/* addze  addze.  addzeo  addzeo.  */
1064
static always_inline void gen_op_addze (void)
1065
{
1066
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1067
    gen_op_add_ze();
1068
    gen_op_check_addc();
1069
}
1070
static always_inline void gen_op_addzeo (void)
1071
{
1072
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1073
    gen_op_add_ze();
1074
    gen_op_check_addc();
1075
    gen_op_check_addo();
1076
}
1077
#if defined(TARGET_PPC64)
1078
static always_inline void gen_op_addze_64 (void)
1079
{
1080
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1081
    gen_op_add_ze();
1082
    gen_op_check_addc_64();
1083
}
1084
static always_inline void gen_op_addzeo_64 (void)
1085
{
1086
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1087
    gen_op_add_ze();
1088
    gen_op_check_addc_64();
1089
    gen_op_check_addo_64();
1090
}
1091
#endif
1092
GEN_INT_ARITH1_64 (addze,  0x1F, 0x0A, 0x06, PPC_INTEGER);
1093
/* divw   divw.   divwo   divwo.   */
1094
GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F, PPC_INTEGER);
1095
/* divwu  divwu.  divwuo  divwuo.  */
1096
GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E, PPC_INTEGER);
1097
/* mulhw  mulhw.                   */
1098
GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02, PPC_INTEGER);
1099
/* mulhwu mulhwu.                  */
1100
GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);
1101
/* mullw  mullw.  mullwo  mullwo.  */
1102
GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07, PPC_INTEGER);
1103
/* neg    neg.    nego    nego.    */
1104
GEN_INT_ARITH1_64 (neg,    0x1F, 0x08, 0x03, PPC_INTEGER);
1105
/* subf   subf.   subfo   subfo.   */
1106
static always_inline void gen_op_subf (void)
1107
{
1108
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1109
}
1110
static always_inline void gen_op_subfo (void)
1111
{
1112
    tcg_gen_not_tl(cpu_T[2], cpu_T[0]);
1113
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1114
    gen_op_check_addo();
1115
}
1116
#if defined(TARGET_PPC64)
1117
#define gen_op_subf_64 gen_op_subf
1118
static always_inline void gen_op_subfo_64 (void)
1119
{
1120
    tcg_gen_not_i64(cpu_T[2], cpu_T[0]);
1121
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1122
    gen_op_check_addo_64();
1123
}
1124
#endif
1125
GEN_INT_ARITH2_64 (subf,   0x1F, 0x08, 0x01, PPC_INTEGER);
1126
/* subfc  subfc.  subfco  subfco.  */
1127
static always_inline void gen_op_subfc (void)
1128
{
1129
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1130
    gen_op_check_subfc();
1131
}
1132
static always_inline void gen_op_subfco (void)
1133
{
1134
    tcg_gen_not_tl(cpu_T[2], cpu_T[0]);
1135
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1136
    gen_op_check_subfc();
1137
    gen_op_check_addo();
1138
}
1139
#if defined(TARGET_PPC64)
1140
static always_inline void gen_op_subfc_64 (void)
1141
{
1142
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1143
    gen_op_check_subfc_64();
1144
}
1145
static always_inline void gen_op_subfco_64 (void)
1146
{
1147
    tcg_gen_not_i64(cpu_T[2], cpu_T[0]);
1148
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1149
    gen_op_check_subfc_64();
1150
    gen_op_check_addo_64();
1151
}
1152
#endif
1153
GEN_INT_ARITH2_64 (subfc,  0x1F, 0x08, 0x00, PPC_INTEGER);
1154
/* subfe  subfe.  subfeo  subfeo.  */
1155
static always_inline void gen_op_subfeo (void)
1156
{
1157
    tcg_gen_not_tl(cpu_T[2], cpu_T[0]);
1158
    gen_op_subfe();
1159
    gen_op_check_addo();
1160
}
1161
#if defined(TARGET_PPC64)
1162
#define gen_op_subfe_64 gen_op_subfe
1163
static always_inline void gen_op_subfeo_64 (void)
1164
{
1165
    tcg_gen_not_i64(cpu_T[2], cpu_T[0]);
1166
    gen_op_subfe_64();
1167
    gen_op_check_addo_64();
1168
}
1169
#endif
1170
GEN_INT_ARITH2_64 (subfe,  0x1F, 0x08, 0x04, PPC_INTEGER);
1171
/* subfme subfme. subfmeo subfmeo. */
1172
GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);
1173
/* subfze subfze. subfzeo subfzeo. */
1174
GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);
1175
/* addi */
1176
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1177
{
1178
    target_long simm = SIMM(ctx->opcode);
1179

    
1180
    if (rA(ctx->opcode) == 0) {
1181
        /* li case */
1182
        tcg_gen_movi_tl(cpu_T[0], simm);
1183
    } else {
1184
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1185
        if (likely(simm != 0))
1186
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);
1187
    }
1188
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1189
}
1190
/* addic */
1191
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1192
{
1193
    target_long simm = SIMM(ctx->opcode);
1194

    
1195
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1196
    if (likely(simm != 0)) {
1197
        tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1198
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);
1199
#if defined(TARGET_PPC64)
1200
        if (ctx->sf_mode)
1201
            gen_op_check_addc_64();
1202
        else
1203
#endif
1204
            gen_op_check_addc();
1205
    } else {
1206
        tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
1207
    }
1208
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1209
}
1210
/* addic. */
1211
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1212
{
1213
    target_long simm = SIMM(ctx->opcode);
1214

    
1215
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1216
    if (likely(simm != 0)) {
1217
        tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1218
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);
1219
#if defined(TARGET_PPC64)
1220
        if (ctx->sf_mode)
1221
            gen_op_check_addc_64();
1222
        else
1223
#endif
1224
            gen_op_check_addc();
1225
    } else {
1226
        tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
1227
    }
1228
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1229
    gen_set_Rc0(ctx, cpu_T[0]);
1230
}
1231
/* addis */
1232
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1233
{
1234
    target_long simm = SIMM(ctx->opcode);
1235

    
1236
    if (rA(ctx->opcode) == 0) {
1237
        /* lis case */
1238
        tcg_gen_movi_tl(cpu_T[0], simm << 16);
1239
    } else {
1240
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1241
        if (likely(simm != 0))
1242
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm << 16);
1243
    }
1244
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1245
}
1246
/* mulli */
1247
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1248
{
1249
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1250
    gen_op_mulli(SIMM(ctx->opcode));
1251
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1252
}
1253
/* subfic */
1254
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1255
{
1256
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1257
#if defined(TARGET_PPC64)
1258
    if (ctx->sf_mode)
1259
        gen_op_subfic_64(SIMM(ctx->opcode));
1260
    else
1261
#endif
1262
        gen_op_subfic(SIMM(ctx->opcode));
1263
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1264
}
1265

    
1266
#if defined(TARGET_PPC64)
1267
/* mulhd  mulhd.                   */
1268
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
1269
/* mulhdu mulhdu.                  */
1270
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
1271
/* mulld  mulld.  mulldo  mulldo.  */
1272
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
1273
/* divd   divd.   divdo   divdo.   */
1274
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
1275
/* divdu  divdu.  divduo  divduo.  */
1276
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
1277
#endif
1278

    
1279
/***                            Integer logical                            ***/
1280
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1281
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1282
{                                                                             \
1283
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
1284
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
1285
    gen_op_##name();                                                          \
1286
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
1287
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1288
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
1289
}
1290
#define GEN_LOGICAL2(name, opc, type)                                         \
1291
__GEN_LOGICAL2(name, 0x1C, opc, type)
1292

    
1293
#define GEN_LOGICAL1(name, opc, type)                                         \
1294
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1295
{                                                                             \
1296
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
1297
    gen_op_##name();                                                          \
1298
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
1299
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1300
        gen_set_Rc0(ctx, cpu_T[0]);                                           \
1301
}
1302

    
1303
/* and & and. */
1304
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1305
/* andc & andc. */
1306
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1307
/* andi. */
1308
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1309
{
1310
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1311
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], UIMM(ctx->opcode));
1312
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1313
    gen_set_Rc0(ctx, cpu_T[0]);
1314
}
1315
/* andis. */
1316
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1317
{
1318
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1319
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], UIMM(ctx->opcode) << 16);
1320
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1321
    gen_set_Rc0(ctx, cpu_T[0]);
1322
}
1323

    
1324
/* cntlzw */
1325
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1326
/* eqv & eqv. */
1327
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1328
/* extsb & extsb. */
1329
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1330
/* extsh & extsh. */
1331
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1332
/* nand & nand. */
1333
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1334
/* nor & nor. */
1335
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1336

    
1337
/* or & or. */
1338
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1339
{
1340
    int rs, ra, rb;
1341

    
1342
    rs = rS(ctx->opcode);
1343
    ra = rA(ctx->opcode);
1344
    rb = rB(ctx->opcode);
1345
    /* Optimisation for mr. ri case */
1346
    if (rs != ra || rs != rb) {
1347
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
1348
        if (rs != rb) {
1349
            tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]);
1350
            gen_op_or();
1351
        }
1352
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
1353
        if (unlikely(Rc(ctx->opcode) != 0))
1354
            gen_set_Rc0(ctx, cpu_T[0]);
1355
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1356
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
1357
        gen_set_Rc0(ctx, cpu_T[0]);
1358
#if defined(TARGET_PPC64)
1359
    } else {
1360
        switch (rs) {
1361
        case 1:
1362
            /* Set process priority to low */
1363
            gen_op_store_pri(2);
1364
            break;
1365
        case 6:
1366
            /* Set process priority to medium-low */
1367
            gen_op_store_pri(3);
1368
            break;
1369
        case 2:
1370
            /* Set process priority to normal */
1371
            gen_op_store_pri(4);
1372
            break;
1373
#if !defined(CONFIG_USER_ONLY)
1374
        case 31:
1375
            if (ctx->supervisor > 0) {
1376
                /* Set process priority to very low */
1377
                gen_op_store_pri(1);
1378
            }
1379
            break;
1380
        case 5:
1381
            if (ctx->supervisor > 0) {
1382
                /* Set process priority to medium-hight */
1383
                gen_op_store_pri(5);
1384
            }
1385
            break;
1386
        case 3:
1387
            if (ctx->supervisor > 0) {
1388
                /* Set process priority to high */
1389
                gen_op_store_pri(6);
1390
            }
1391
            break;
1392
        case 7:
1393
            if (ctx->supervisor > 1) {
1394
                /* Set process priority to very high */
1395
                gen_op_store_pri(7);
1396
            }
1397
            break;
1398
#endif
1399
        default:
1400
            /* nop */
1401
            break;
1402
        }
1403
#endif
1404
    }
1405
}
1406

    
1407
/* orc & orc. */
1408
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1409
/* xor & xor. */
1410
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1411
{
1412
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1413
    /* Optimisation for "set to zero" case */
1414
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1415
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1416
        gen_op_xor();
1417
    } else {
1418
        tcg_gen_movi_tl(cpu_T[0], 0);
1419
    }
1420
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1421
    if (unlikely(Rc(ctx->opcode) != 0))
1422
        gen_set_Rc0(ctx, cpu_T[0]);
1423
}
1424
/* ori */
1425
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1426
{
1427
    target_ulong uimm = UIMM(ctx->opcode);
1428

    
1429
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1430
        /* NOP */
1431
        /* XXX: should handle special NOPs for POWER series */
1432
        return;
1433
    }
1434
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1435
    if (likely(uimm != 0))
1436
        gen_op_ori(uimm);
1437
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1438
}
1439
/* oris */
1440
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1441
{
1442
    target_ulong uimm = UIMM(ctx->opcode);
1443

    
1444
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1445
        /* NOP */
1446
        return;
1447
    }
1448
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1449
    if (likely(uimm != 0))
1450
        gen_op_ori(uimm << 16);
1451
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1452
}
1453
/* xori */
1454
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1455
{
1456
    target_ulong uimm = UIMM(ctx->opcode);
1457

    
1458
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1459
        /* NOP */
1460
        return;
1461
    }
1462
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1463
    if (likely(uimm != 0))
1464
        gen_op_xori(uimm);
1465
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1466
}
1467

    
1468
/* xoris */
1469
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1470
{
1471
    target_ulong uimm = UIMM(ctx->opcode);
1472

    
1473
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1474
        /* NOP */
1475
        return;
1476
    }
1477
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1478
    if (likely(uimm != 0))
1479
        gen_op_xori(uimm << 16);
1480
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1481
}
1482

    
1483
/* popcntb : PowerPC 2.03 specification */
1484
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
1485
{
1486
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1487
#if defined(TARGET_PPC64)
1488
    if (ctx->sf_mode)
1489
        gen_op_popcntb_64();
1490
    else
1491
#endif
1492
        gen_op_popcntb();
1493
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1494
}
1495

    
1496
#if defined(TARGET_PPC64)
1497
/* extsw & extsw. */
1498
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1499
/* cntlzd */
1500
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1501
#endif
1502

    
1503
/***                             Integer rotate                            ***/
1504
/* rlwimi & rlwimi. */
1505
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1506
{
1507
    target_ulong mask;
1508
    uint32_t mb, me, sh;
1509

    
1510
    mb = MB(ctx->opcode);
1511
    me = ME(ctx->opcode);
1512
    sh = SH(ctx->opcode);
1513
    if (likely(sh == 0)) {
1514
        if (likely(mb == 0 && me == 31)) {
1515
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1516
            goto do_store;
1517
        } else if (likely(mb == 31 && me == 0)) {
1518
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1519
            goto do_store;
1520
        }
1521
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1522
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1523
        goto do_mask;
1524
    }
1525
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1526
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1527
    gen_op_rotli32_T0(SH(ctx->opcode));
1528
 do_mask:
1529
#if defined(TARGET_PPC64)
1530
    mb += 32;
1531
    me += 32;
1532
#endif
1533
    mask = MASK(mb, me);
1534
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], mask);
1535
    tcg_gen_andi_tl(cpu_T[1], cpu_T[1], ~mask);
1536
    gen_op_or();
1537
 do_store:
1538
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1539
    if (unlikely(Rc(ctx->opcode) != 0))
1540
        gen_set_Rc0(ctx, cpu_T[0]);
1541
}
1542
/* rlwinm & rlwinm. */
1543
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1544
{
1545
    uint32_t mb, me, sh;
1546

    
1547
    sh = SH(ctx->opcode);
1548
    mb = MB(ctx->opcode);
1549
    me = ME(ctx->opcode);
1550
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1551
    if (likely(sh == 0)) {
1552
        goto do_mask;
1553
    }
1554
    if (likely(mb == 0)) {
1555
        if (likely(me == 31)) {
1556
            gen_op_rotli32_T0(sh);
1557
            goto do_store;
1558
        } else if (likely(me == (31 - sh))) {
1559
            gen_op_sli_T0(sh);
1560
            goto do_store;
1561
        }
1562
    } else if (likely(me == 31)) {
1563
        if (likely(sh == (32 - mb))) {
1564
            gen_op_srli_T0(mb);
1565
            goto do_store;
1566
        }
1567
    }
1568
    gen_op_rotli32_T0(sh);
1569
 do_mask:
1570
#if defined(TARGET_PPC64)
1571
    mb += 32;
1572
    me += 32;
1573
#endif
1574
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], MASK(mb, me));
1575
 do_store:
1576
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1577
    if (unlikely(Rc(ctx->opcode) != 0))
1578
        gen_set_Rc0(ctx, cpu_T[0]);
1579
}
1580
/* rlwnm & rlwnm. */
1581
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1582
{
1583
    uint32_t mb, me;
1584

    
1585
    mb = MB(ctx->opcode);
1586
    me = ME(ctx->opcode);
1587
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1588
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1589
    gen_op_rotl32_T0_T1();
1590
    if (unlikely(mb != 0 || me != 31)) {
1591
#if defined(TARGET_PPC64)
1592
        mb += 32;
1593
        me += 32;
1594
#endif
1595
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], MASK(mb, me));
1596
    }
1597
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1598
    if (unlikely(Rc(ctx->opcode) != 0))
1599
        gen_set_Rc0(ctx, cpu_T[0]);
1600
}
1601

    
1602
#if defined(TARGET_PPC64)
1603
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1604
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1605
{                                                                             \
1606
    gen_##name(ctx, 0);                                                       \
1607
}                                                                             \
1608
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1609
             PPC_64B)                                                         \
1610
{                                                                             \
1611
    gen_##name(ctx, 1);                                                       \
1612
}
1613
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1614
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1615
{                                                                             \
1616
    gen_##name(ctx, 0, 0);                                                    \
1617
}                                                                             \
1618
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
1619
             PPC_64B)                                                         \
1620
{                                                                             \
1621
    gen_##name(ctx, 0, 1);                                                    \
1622
}                                                                             \
1623
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1624
             PPC_64B)                                                         \
1625
{                                                                             \
1626
    gen_##name(ctx, 1, 0);                                                    \
1627
}                                                                             \
1628
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
1629
             PPC_64B)                                                         \
1630
{                                                                             \
1631
    gen_##name(ctx, 1, 1);                                                    \
1632
}
1633

    
1634
static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
1635
                                      uint32_t me, uint32_t sh)
1636
{
1637
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1638
    if (likely(sh == 0)) {
1639
        goto do_mask;
1640
    }
1641
    if (likely(mb == 0)) {
1642
        if (likely(me == 63)) {
1643
            gen_op_rotli64_T0(sh);
1644
            goto do_store;
1645
        } else if (likely(me == (63 - sh))) {
1646
            gen_op_sli_T0(sh);
1647
            goto do_store;
1648
        }
1649
    } else if (likely(me == 63)) {
1650
        if (likely(sh == (64 - mb))) {
1651
            gen_op_srli_T0_64(mb);
1652
            goto do_store;
1653
        }
1654
    }
1655
    gen_op_rotli64_T0(sh);
1656
 do_mask:
1657
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], MASK(mb, me));
1658
 do_store:
1659
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1660
    if (unlikely(Rc(ctx->opcode) != 0))
1661
        gen_set_Rc0(ctx, cpu_T[0]);
1662
}
1663
/* rldicl - rldicl. */
1664
static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1665
{
1666
    uint32_t sh, mb;
1667

    
1668
    sh = SH(ctx->opcode) | (shn << 5);
1669
    mb = MB(ctx->opcode) | (mbn << 5);
1670
    gen_rldinm(ctx, mb, 63, sh);
1671
}
1672
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1673
/* rldicr - rldicr. */
1674
static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1675
{
1676
    uint32_t sh, me;
1677

    
1678
    sh = SH(ctx->opcode) | (shn << 5);
1679
    me = MB(ctx->opcode) | (men << 5);
1680
    gen_rldinm(ctx, 0, me, sh);
1681
}
1682
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1683
/* rldic - rldic. */
1684
static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1685
{
1686
    uint32_t sh, mb;
1687

    
1688
    sh = SH(ctx->opcode) | (shn << 5);
1689
    mb = MB(ctx->opcode) | (mbn << 5);
1690
    gen_rldinm(ctx, mb, 63 - sh, sh);
1691
}
1692
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1693

    
1694
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1695
                                     uint32_t me)
1696
{
1697
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1698
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1699
    gen_op_rotl64_T0_T1();
1700
    if (unlikely(mb != 0 || me != 63)) {
1701
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], MASK(mb, me));
1702
    }
1703
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1704
    if (unlikely(Rc(ctx->opcode) != 0))
1705
        gen_set_Rc0(ctx, cpu_T[0]);
1706
}
1707

    
1708
/* rldcl - rldcl. */
1709
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1710
{
1711
    uint32_t mb;
1712

    
1713
    mb = MB(ctx->opcode) | (mbn << 5);
1714
    gen_rldnm(ctx, mb, 63);
1715
}
1716
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1717
/* rldcr - rldcr. */
1718
static always_inline void gen_rldcr (DisasContext *ctx, int men)
1719
{
1720
    uint32_t me;
1721

    
1722
    me = MB(ctx->opcode) | (men << 5);
1723
    gen_rldnm(ctx, 0, me);
1724
}
1725
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1726
/* rldimi - rldimi. */
1727
static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1728
{
1729
    uint64_t mask;
1730
    uint32_t sh, mb, me;
1731

    
1732
    sh = SH(ctx->opcode) | (shn << 5);
1733
    mb = MB(ctx->opcode) | (mbn << 5);
1734
    me = 63 - sh;
1735
    if (likely(sh == 0)) {
1736
        if (likely(mb == 0)) {
1737
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1738
            goto do_store;
1739
        }
1740
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1741
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1742
        goto do_mask;
1743
    }
1744
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1745
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1746
    gen_op_rotli64_T0(sh);
1747
 do_mask:
1748
    mask = MASK(mb, me);
1749
    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], mask);
1750
    tcg_gen_andi_tl(cpu_T[1], cpu_T[1], ~mask);
1751
    gen_op_or();
1752
 do_store:
1753
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1754
    if (unlikely(Rc(ctx->opcode) != 0))
1755
        gen_set_Rc0(ctx, cpu_T[0]);
1756
}
1757
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1758
#endif
1759

    
1760
/***                             Integer shift                             ***/
1761
/* slw & slw. */
1762
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1763
/* sraw & sraw. */
1764
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1765
/* srawi & srawi. */
1766
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1767
{
1768
    int mb, me;
1769
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1770
    if (SH(ctx->opcode) != 0) {
1771
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1772
        mb = 32 - SH(ctx->opcode);
1773
        me = 31;
1774
#if defined(TARGET_PPC64)
1775
        mb += 32;
1776
        me += 32;
1777
#endif
1778
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1779
    }
1780
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1781
    if (unlikely(Rc(ctx->opcode) != 0))
1782
        gen_set_Rc0(ctx, cpu_T[0]);
1783
}
1784
/* srw & srw. */
1785
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1786

    
1787
#if defined(TARGET_PPC64)
1788
/* sld & sld. */
1789
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1790
/* srad & srad. */
1791
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1792
/* sradi & sradi. */
1793
static always_inline void gen_sradi (DisasContext *ctx, int n)
1794
{
1795
    uint64_t mask;
1796
    int sh, mb, me;
1797

    
1798
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1799
    sh = SH(ctx->opcode) + (n << 5);
1800
    if (sh != 0) {
1801
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1802
        mb = 64 - SH(ctx->opcode);
1803
        me = 63;
1804
        mask = MASK(mb, me);
1805
        gen_op_sradi(sh, mask >> 32, mask);
1806
    }
1807
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1808
    if (unlikely(Rc(ctx->opcode) != 0))
1809
        gen_set_Rc0(ctx, cpu_T[0]);
1810
}
1811
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1812
{
1813
    gen_sradi(ctx, 0);
1814
}
1815
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1816
{
1817
    gen_sradi(ctx, 1);
1818
}
1819
/* srd & srd. */
1820
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1821
#endif
1822

    
1823
/***                       Floating-Point arithmetic                       ***/
1824
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1825
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1826
{                                                                             \
1827
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1828
        GEN_EXCP_NO_FP(ctx);                                                  \
1829
        return;                                                               \
1830
    }                                                                         \
1831
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
1832
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rC(ctx->opcode)]);                     \
1833
    tcg_gen_mov_i64(cpu_FT[2], cpu_fpr[rB(ctx->opcode)]);                     \
1834
    gen_reset_fpstatus();                                                     \
1835
    gen_op_f##op();                                                           \
1836
    if (isfloat) {                                                            \
1837
        gen_op_frsp();                                                        \
1838
    }                                                                         \
1839
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1840
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1841
}
1842

    
1843
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1844
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1845
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1846

    
1847
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1848
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1849
{                                                                             \
1850
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1851
        GEN_EXCP_NO_FP(ctx);                                                  \
1852
        return;                                                               \
1853
    }                                                                         \
1854
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
1855
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);                     \
1856
    gen_reset_fpstatus();                                                     \
1857
    gen_op_f##op();                                                           \
1858
    if (isfloat) {                                                            \
1859
        gen_op_frsp();                                                        \
1860
    }                                                                         \
1861
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1862
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1863
}
1864
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
1865
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1866
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1867

    
1868
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1869
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1870
{                                                                             \
1871
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1872
        GEN_EXCP_NO_FP(ctx);                                                  \
1873
        return;                                                               \
1874
    }                                                                         \
1875
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
1876
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rC(ctx->opcode)]);                     \
1877
    gen_reset_fpstatus();                                                     \
1878
    gen_op_f##op();                                                           \
1879
    if (isfloat) {                                                            \
1880
        gen_op_frsp();                                                        \
1881
    }                                                                         \
1882
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1883
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1884
}
1885
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
1886
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1887
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1888

    
1889
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
1890
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1891
{                                                                             \
1892
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1893
        GEN_EXCP_NO_FP(ctx);                                                  \
1894
        return;                                                               \
1895
    }                                                                         \
1896
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);                     \
1897
    gen_reset_fpstatus();                                                     \
1898
    gen_op_f##name();                                                         \
1899
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1900
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1901
}
1902

    
1903
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1904
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1905
{                                                                             \
1906
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1907
        GEN_EXCP_NO_FP(ctx);                                                  \
1908
        return;                                                               \
1909
    }                                                                         \
1910
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);                     \
1911
    gen_reset_fpstatus();                                                     \
1912
    gen_op_f##name();                                                         \
1913
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1914
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1915
}
1916

    
1917
/* fadd - fadds */
1918
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1919
/* fdiv - fdivs */
1920
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1921
/* fmul - fmuls */
1922
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
1923

    
1924
/* fre */
1925
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1926

    
1927
/* fres */
1928
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1929

    
1930
/* frsqrte */
1931
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
1932

    
1933
/* frsqrtes */
1934
static always_inline void gen_op_frsqrtes (void)
1935
{
1936
    gen_op_frsqrte();
1937
    gen_op_frsp();
1938
}
1939
GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1940

    
1941
/* fsel */
1942
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1943
/* fsub - fsubs */
1944
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1945
/* Optional: */
1946
/* fsqrt */
1947
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1948
{
1949
    if (unlikely(!ctx->fpu_enabled)) {
1950
        GEN_EXCP_NO_FP(ctx);
1951
        return;
1952
    }
1953
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
1954
    gen_reset_fpstatus();
1955
    gen_op_fsqrt();
1956
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
1957
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1958
}
1959

    
1960
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1961
{
1962
    if (unlikely(!ctx->fpu_enabled)) {
1963
        GEN_EXCP_NO_FP(ctx);
1964
        return;
1965
    }
1966
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
1967
    gen_reset_fpstatus();
1968
    gen_op_fsqrt();
1969
    gen_op_frsp();
1970
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
1971
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1972
}
1973

    
1974
/***                     Floating-Point multiply-and-add                   ***/
1975
/* fmadd - fmadds */
1976
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1977
/* fmsub - fmsubs */
1978
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1979
/* fnmadd - fnmadds */
1980
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1981
/* fnmsub - fnmsubs */
1982
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1983

    
1984
/***                     Floating-Point round & convert                    ***/
1985
/* fctiw */
1986
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1987
/* fctiwz */
1988
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1989
/* frsp */
1990
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
1991
#if defined(TARGET_PPC64)
1992
/* fcfid */
1993
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
1994
/* fctid */
1995
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
1996
/* fctidz */
1997
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
1998
#endif
1999

    
2000
/* frin */
2001
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
2002
/* friz */
2003
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
2004
/* frip */
2005
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
2006
/* frim */
2007
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
2008

    
2009
/***                         Floating-Point compare                        ***/
2010
/* fcmpo */
2011
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
2012
{
2013
    if (unlikely(!ctx->fpu_enabled)) {
2014
        GEN_EXCP_NO_FP(ctx);
2015
        return;
2016
    }
2017
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
2018
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
2019
    gen_reset_fpstatus();
2020
    tcg_gen_helper_1_0(helper_fcmpo, cpu_crf[crfD(ctx->opcode)]);
2021
    gen_op_float_check_status();
2022
}
2023

    
2024
/* fcmpu */
2025
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
2026
{
2027
    if (unlikely(!ctx->fpu_enabled)) {
2028
        GEN_EXCP_NO_FP(ctx);
2029
        return;
2030
    }
2031
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
2032
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
2033
    gen_reset_fpstatus();
2034
    tcg_gen_helper_1_0(helper_fcmpu, cpu_crf[crfD(ctx->opcode)]);
2035
    gen_op_float_check_status();
2036
}
2037

    
2038
/***                         Floating-point move                           ***/
2039
/* fabs */
2040
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
2041
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
2042

    
2043
/* fmr  - fmr. */
2044
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
2045
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
2046
{
2047
    if (unlikely(!ctx->fpu_enabled)) {
2048
        GEN_EXCP_NO_FP(ctx);
2049
        return;
2050
    }
2051
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2052
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2053
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2054
}
2055

    
2056
/* fnabs */
2057
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
2058
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
2059
/* fneg */
2060
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
2061
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
2062

    
2063
/***                  Floating-Point status & ctrl register                ***/
2064
/* mcrfs */
2065
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
2066
{
2067
    int bfa;
2068

    
2069
    if (unlikely(!ctx->fpu_enabled)) {
2070
        GEN_EXCP_NO_FP(ctx);
2071
        return;
2072
    }
2073
    gen_optimize_fprf();
2074
    bfa = 4 * (7 - crfS(ctx->opcode));
2075
    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
2076
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
2077
    gen_op_fpscr_resetbit(~(0xF << bfa));
2078
}
2079

    
2080
/* mffs */
2081
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
2082
{
2083
    if (unlikely(!ctx->fpu_enabled)) {
2084
        GEN_EXCP_NO_FP(ctx);
2085
        return;
2086
    }
2087
    gen_optimize_fprf();
2088
    gen_reset_fpstatus();
2089
    gen_op_load_fpscr_FT0();
2090
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2091
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2092
}
2093

    
2094
/* mtfsb0 */
2095
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
2096
{
2097
    uint8_t crb;
2098

    
2099
    if (unlikely(!ctx->fpu_enabled)) {
2100
        GEN_EXCP_NO_FP(ctx);
2101
        return;
2102
    }
2103
    crb = 32 - (crbD(ctx->opcode) >> 2);
2104
    gen_optimize_fprf();
2105
    gen_reset_fpstatus();
2106
    if (likely(crb != 30 && crb != 29))
2107
        gen_op_fpscr_resetbit(~(1 << crb));
2108
    if (unlikely(Rc(ctx->opcode) != 0)) {
2109
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2110
    }
2111
}
2112

    
2113
/* mtfsb1 */
2114
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2115
{
2116
    uint8_t crb;
2117

    
2118
    if (unlikely(!ctx->fpu_enabled)) {
2119
        GEN_EXCP_NO_FP(ctx);
2120
        return;
2121
    }
2122
    crb = 32 - (crbD(ctx->opcode) >> 2);
2123
    gen_optimize_fprf();
2124
    gen_reset_fpstatus();
2125
    /* XXX: we pretend we can only do IEEE floating-point computations */
2126
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
2127
        gen_op_fpscr_setbit(crb);
2128
    if (unlikely(Rc(ctx->opcode) != 0)) {
2129
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2130
    }
2131
    /* We can raise a differed exception */
2132
    gen_op_float_check_status();
2133
}
2134

    
2135
/* mtfsf */
2136
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2137
{
2138
    if (unlikely(!ctx->fpu_enabled)) {
2139
        GEN_EXCP_NO_FP(ctx);
2140
        return;
2141
    }
2142
    gen_optimize_fprf();
2143
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2144
    gen_reset_fpstatus();
2145
    gen_op_store_fpscr(FM(ctx->opcode));
2146
    if (unlikely(Rc(ctx->opcode) != 0)) {
2147
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2148
    }
2149
    /* We can raise a differed exception */
2150
    gen_op_float_check_status();
2151
}
2152

    
2153
/* mtfsfi */
2154
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2155
{
2156
    int bf, sh;
2157

    
2158
    if (unlikely(!ctx->fpu_enabled)) {
2159
        GEN_EXCP_NO_FP(ctx);
2160
        return;
2161
    }
2162
    bf = crbD(ctx->opcode) >> 2;
2163
    sh = 7 - bf;
2164
    gen_optimize_fprf();
2165
    tcg_gen_movi_i64(cpu_FT[0], FPIMM(ctx->opcode) << (4 * sh));
2166
    gen_reset_fpstatus();
2167
    gen_op_store_fpscr(1 << sh);
2168
    if (unlikely(Rc(ctx->opcode) != 0)) {
2169
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2170
    }
2171
    /* We can raise a differed exception */
2172
    gen_op_float_check_status();
2173
}
2174

    
2175
/***                           Addressing modes                            ***/
2176
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2177
static always_inline void gen_addr_imm_index (TCGv EA,
2178
                                              DisasContext *ctx,
2179
                                              target_long maskl)
2180
{
2181
    target_long simm = SIMM(ctx->opcode);
2182

    
2183
    simm &= ~maskl;
2184
    if (rA(ctx->opcode) == 0)
2185
        tcg_gen_movi_tl(EA, simm);
2186
    else if (likely(simm != 0))
2187
        tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2188
    else
2189
        tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2190
}
2191

    
2192
static always_inline void gen_addr_reg_index (TCGv EA,
2193
                                              DisasContext *ctx)
2194
{
2195
    if (rA(ctx->opcode) == 0)
2196
        tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2197
    else
2198
        tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2199
}
2200

    
2201
static always_inline void gen_addr_register (TCGv EA,
2202
                                             DisasContext *ctx)
2203
{
2204
    if (rA(ctx->opcode) == 0)
2205
        tcg_gen_movi_tl(EA, 0);
2206
    else
2207
        tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2208
}
2209

    
2210
#if defined(TARGET_PPC64)
2211
#define _GEN_MEM_FUNCS(name, mode)                                            \
2212
    &gen_op_##name##_##mode,                                                  \
2213
    &gen_op_##name##_le_##mode,                                               \
2214
    &gen_op_##name##_64_##mode,                                               \
2215
    &gen_op_##name##_le_64_##mode
2216
#else
2217
#define _GEN_MEM_FUNCS(name, mode)                                            \
2218
    &gen_op_##name##_##mode,                                                  \
2219
    &gen_op_##name##_le_##mode
2220
#endif
2221
#if defined(CONFIG_USER_ONLY)
2222
#if defined(TARGET_PPC64)
2223
#define NB_MEM_FUNCS 4
2224
#else
2225
#define NB_MEM_FUNCS 2
2226
#endif
2227
#define GEN_MEM_FUNCS(name)                                                   \
2228
    _GEN_MEM_FUNCS(name, raw)
2229
#else
2230
#if defined(TARGET_PPC64)
2231
#define NB_MEM_FUNCS 12
2232
#else
2233
#define NB_MEM_FUNCS 6
2234
#endif
2235
#define GEN_MEM_FUNCS(name)                                                   \
2236
    _GEN_MEM_FUNCS(name, user),                                               \
2237
    _GEN_MEM_FUNCS(name, kernel),                                             \
2238
    _GEN_MEM_FUNCS(name, hypv)
2239
#endif
2240

    
2241
/***                             Integer load                              ***/
2242
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
2243
#define OP_LD_TABLE(width)                                                    \
2244
static GenOpFunc *gen_op_l##width[NB_MEM_FUNCS] = {                           \
2245
    GEN_MEM_FUNCS(l##width),                                                  \
2246
};
2247
#define OP_ST_TABLE(width)                                                    \
2248
static GenOpFunc *gen_op_st##width[NB_MEM_FUNCS] = {                          \
2249
    GEN_MEM_FUNCS(st##width),                                                 \
2250
};
2251

    
2252

    
2253
#if defined(TARGET_PPC64)
2254
#define GEN_QEMU_LD_PPC64(width)                                                 \
2255
static always_inline void gen_qemu_ld##width##_ppc64(TCGv t0, TCGv t1, int flags)\
2256
{                                                                                \
2257
    if (likely(flags & 2))                                                       \
2258
        tcg_gen_qemu_ld##width(t0, t1, flags >> 2);                              \
2259
    else {                                                                       \
2260
        TCGv addr = tcg_temp_new(TCG_TYPE_TL);                                   \
2261
        tcg_gen_ext32u_tl(addr, t1);                                             \
2262
        tcg_gen_qemu_ld##width(t0, addr, flags >> 2);                            \
2263
        tcg_temp_free(addr);                                                     \
2264
    }                                                                            \
2265
}
2266
GEN_QEMU_LD_PPC64(8u)
2267
GEN_QEMU_LD_PPC64(8s)
2268
GEN_QEMU_LD_PPC64(16u)
2269
GEN_QEMU_LD_PPC64(16s)
2270
GEN_QEMU_LD_PPC64(32u)
2271
GEN_QEMU_LD_PPC64(32s)
2272
GEN_QEMU_LD_PPC64(64)
2273

    
2274
#define GEN_QEMU_ST_PPC64(width)                                                 \
2275
static always_inline void gen_qemu_st##width##_ppc64(TCGv t0, TCGv t1, int flags)\
2276
{                                                                                \
2277
    if (likely(flags & 2))                                                       \
2278
        tcg_gen_qemu_st##width(t0, t1, flags >> 2);                              \
2279
    else {                                                                       \
2280
        TCGv addr = tcg_temp_new(TCG_TYPE_TL);                                   \
2281
        tcg_gen_ext32u_tl(addr, t1);                                             \
2282
        tcg_gen_qemu_st##width(t0, addr, flags >> 2);                            \
2283
        tcg_temp_free(addr);                                                     \
2284
    }                                                                            \
2285
}
2286
GEN_QEMU_ST_PPC64(8)
2287
GEN_QEMU_ST_PPC64(16)
2288
GEN_QEMU_ST_PPC64(32)
2289
GEN_QEMU_ST_PPC64(64)
2290

    
2291
static always_inline void gen_qemu_ld8u(TCGv t0, TCGv t1, int flags)
2292
{
2293
    gen_qemu_ld8u_ppc64(t0, t1, flags);
2294
}
2295

    
2296
static always_inline void gen_qemu_ld8s(TCGv t0, TCGv t1, int flags)
2297
{
2298
    gen_qemu_ld8s_ppc64(t0, t1, flags);
2299
}
2300

    
2301
static always_inline void gen_qemu_ld16u(TCGv t0, TCGv t1, int flags)
2302
{
2303
    if (unlikely(flags & 1)) {
2304
        TCGv t0_32;
2305
        gen_qemu_ld16u_ppc64(t0, t1, flags);
2306
        t0_32 = tcg_temp_new(TCG_TYPE_I32);
2307
        tcg_gen_trunc_tl_i32(t0_32, t0);
2308
        tcg_gen_bswap16_i32(t0_32, t0_32);
2309
        tcg_gen_extu_i32_tl(t0, t0_32);
2310
        tcg_temp_free(t0_32);
2311
    } else
2312
        gen_qemu_ld16u_ppc64(t0, t1, flags);
2313
}
2314

    
2315
static always_inline void gen_qemu_ld16s(TCGv t0, TCGv t1, int flags)
2316
{
2317
    if (unlikely(flags & 1)) {
2318
        TCGv t0_32;
2319
        gen_qemu_ld16u_ppc64(t0, t1, flags);
2320
        t0_32 = tcg_temp_new(TCG_TYPE_I32);
2321
        tcg_gen_trunc_tl_i32(t0_32, t0);
2322
        tcg_gen_bswap16_i32(t0_32, t0_32);
2323
        tcg_gen_extu_i32_tl(t0, t0_32);
2324
        tcg_gen_ext16s_tl(t0, t0);
2325
        tcg_temp_free(t0_32);
2326
    } else
2327
        gen_qemu_ld16s_ppc64(t0, t1, flags);
2328
}
2329

    
2330
static always_inline void gen_qemu_ld32u(TCGv t0, TCGv t1, int flags)
2331
{
2332
    if (unlikely(flags & 1)) {
2333
        TCGv t0_32;
2334
        gen_qemu_ld32u_ppc64(t0, t1, flags);
2335
        t0_32 = tcg_temp_new(TCG_TYPE_I32);
2336
        tcg_gen_trunc_tl_i32(t0_32, t0);
2337
        tcg_gen_bswap_i32(t0_32, t0_32);
2338
        tcg_gen_extu_i32_tl(t0, t0_32);
2339
        tcg_temp_free(t0_32);
2340
    } else
2341
        gen_qemu_ld32u_ppc64(t0, t1, flags);
2342
}
2343

    
2344
static always_inline void gen_qemu_ld32s(TCGv t0, TCGv t1, int flags)
2345
{
2346
    if (unlikely(flags & 1)) {
2347
        TCGv t0_32;
2348
        gen_qemu_ld32u_ppc64(t0, t1, flags);
2349
        t0_32 = tcg_temp_new(TCG_TYPE_I32);
2350
        tcg_gen_trunc_tl_i32(t0_32, t0);
2351
        tcg_gen_bswap_i32(t0_32, t0_32);
2352
        tcg_gen_ext_i32_tl(t0, t0_32);
2353
        tcg_temp_free(t0_32);
2354
    } else
2355
        gen_qemu_ld32s_ppc64(t0, t1, flags);
2356
}
2357

    
2358
static always_inline void gen_qemu_ld64(TCGv t0, TCGv t1, int flags)
2359
{
2360
    gen_qemu_ld64_ppc64(t0, t1, flags);
2361
    if (unlikely(flags & 1))
2362
        tcg_gen_bswap_i64(t0, t0);
2363
}
2364

    
2365
static always_inline void gen_qemu_st8(TCGv t0, TCGv t1, int flags)
2366
{
2367
    gen_qemu_st8_ppc64(t0, t1, flags);
2368
}
2369

    
2370
static always_inline void gen_qemu_st16(TCGv t0, TCGv t1, int flags)
2371
{
2372
    if (unlikely(flags & 1)) {
2373
        TCGv temp1, temp2;
2374
        temp1 = tcg_temp_new(TCG_TYPE_I32);
2375
        tcg_gen_trunc_tl_i32(temp1, t0);
2376
        tcg_gen_ext16u_i32(temp1, temp1);
2377
        tcg_gen_bswap16_i32(temp1, temp1);
2378
        temp2 = tcg_temp_new(TCG_TYPE_I64);
2379
        tcg_gen_extu_i32_tl(temp2, temp1);
2380
        tcg_temp_free(temp1);
2381
        gen_qemu_st16_ppc64(temp2, t1, flags);
2382
        tcg_temp_free(temp2);
2383
    } else
2384
        gen_qemu_st16_ppc64(t0, t1, flags);
2385
}
2386

    
2387
static always_inline void gen_qemu_st32(TCGv t0, TCGv t1, int flags)
2388
{
2389
    if (unlikely(flags & 1)) {
2390
        TCGv temp1, temp2;
2391
        temp1 = tcg_temp_new(TCG_TYPE_I32);
2392
        tcg_gen_trunc_tl_i32(temp1, t0);
2393
        tcg_gen_bswap_i32(temp1, temp1);
2394
        temp2 = tcg_temp_new(TCG_TYPE_I64);
2395
        tcg_gen_extu_i32_tl(temp2, temp1);
2396
        tcg_temp_free(temp1);
2397
        gen_qemu_st32_ppc64(temp2, t1, flags);
2398
        tcg_temp_free(temp2);
2399
    } else
2400
        gen_qemu_st32_ppc64(t0, t1, flags);
2401
}
2402

    
2403
static always_inline void gen_qemu_st64(TCGv t0, TCGv t1, int flags)
2404
{
2405
    if (unlikely(flags & 1)) {
2406
        TCGv temp = tcg_temp_new(TCG_TYPE_I64);
2407
        tcg_gen_bswap_i64(temp, t0);
2408
        gen_qemu_st64_ppc64(temp, t1, flags);
2409
        tcg_temp_free(temp);
2410
    } else
2411
        gen_qemu_st64_ppc64(t0, t1, flags);
2412
}
2413

    
2414

    
2415
#else /* defined(TARGET_PPC64) */
2416
#define GEN_QEMU_LD_PPC32(width)                                                 \
2417
static always_inline void gen_qemu_ld##width##_ppc32(TCGv t0, TCGv t1, int flags)\
2418
{                                                                                \
2419
    tcg_gen_qemu_ld##width(t0, t1, flags >> 1);                                  \
2420
}
2421
GEN_QEMU_LD_PPC32(8u)
2422
GEN_QEMU_LD_PPC32(8s)
2423
GEN_QEMU_LD_PPC32(16u)
2424
GEN_QEMU_LD_PPC32(16s)
2425
GEN_QEMU_LD_PPC32(32u)
2426
GEN_QEMU_LD_PPC32(32s)
2427
GEN_QEMU_LD_PPC32(64)
2428

    
2429
#define GEN_QEMU_ST_PPC32(width)                                                 \
2430
static always_inline void gen_qemu_st##width##_ppc32(TCGv t0, TCGv t1, int flags)\
2431
{                                                                                \
2432
    tcg_gen_qemu_st##width(t0, t1, flags >> 1);                                  \
2433
}
2434
GEN_QEMU_ST_PPC32(8)
2435
GEN_QEMU_ST_PPC32(16)
2436
GEN_QEMU_ST_PPC32(32)
2437
GEN_QEMU_ST_PPC32(64)
2438

    
2439
static always_inline void gen_qemu_ld8u(TCGv t0, TCGv t1, int flags)
2440
{
2441
    gen_qemu_ld8u_ppc32(t0, t1, flags >> 1);
2442
}
2443

    
2444
static always_inline void gen_qemu_ld8s(TCGv t0, TCGv t1, int flags)
2445
{
2446
    gen_qemu_ld8s_ppc32(t0, t1, flags >> 1);
2447
}
2448

    
2449
static always_inline void gen_qemu_ld16u(TCGv t0, TCGv t1, int flags)
2450
{
2451
    gen_qemu_ld16u_ppc32(t0, t1, flags >> 1);
2452
    if (unlikely(flags & 1))
2453
        tcg_gen_bswap16_i32(t0, t0);
2454
}
2455

    
2456
static always_inline void gen_qemu_ld16s(TCGv t0, TCGv t1, int flags)
2457
{
2458
    if (unlikely(flags & 1)) {
2459
        gen_qemu_ld16u_ppc32(t0, t1, flags);
2460
        tcg_gen_bswap16_i32(t0, t0);
2461
        tcg_gen_ext16s_i32(t0, t0);
2462
    } else
2463
        gen_qemu_ld16s_ppc32(t0, t1, flags);
2464
}
2465

    
2466
static always_inline void gen_qemu_ld32u(TCGv t0, TCGv t1, int flags)
2467
{
2468
    gen_qemu_ld32u_ppc32(t0, t1, flags);
2469
    if (unlikely(flags & 1))
2470
        tcg_gen_bswap_i32(t0, t0);
2471
}
2472

    
2473
static always_inline void gen_qemu_ld64(TCGv t0, TCGv t1, int flags)
2474
{
2475
    gen_qemu_ld64_ppc32(t0, t1, flags);
2476
    if (unlikely(flags & 1))
2477
        tcg_gen_bswap_i64(t0, t0);
2478
}
2479

    
2480
static always_inline void gen_qemu_st8(TCGv t0, TCGv t1, int flags)
2481
{
2482
    gen_qemu_st8_ppc32(t0, t1, flags >> 1);
2483
}
2484

    
2485
static always_inline void gen_qemu_st16(TCGv t0, TCGv t1, int flags)
2486
{
2487
    if (unlikely(flags & 1)) {
2488
        TCGv temp = tcg_temp_new(TCG_TYPE_I32);
2489
        tcg_gen_ext16u_i32(temp, t0);
2490
        tcg_gen_bswap16_i32(temp, temp);
2491
        gen_qemu_st16_ppc32(temp, t1, flags >> 1);
2492
        tcg_temp_free(temp);
2493
    } else
2494
        gen_qemu_st16_ppc32(t0, t1, flags >> 1);
2495
}
2496

    
2497
static always_inline void gen_qemu_st32(TCGv t0, TCGv t1, int flags)
2498
{
2499
    if (unlikely(flags & 1)) {
2500
        TCGv temp = tcg_temp_new(TCG_TYPE_I32);
2501
        tcg_gen_bswap_i32(temp, t0);
2502
        gen_qemu_st32_ppc32(temp, t1, flags >> 1);
2503
        tcg_temp_free(temp);
2504
    } else
2505
        gen_qemu_st32_ppc32(t0, t1, flags >> 1);
2506
}
2507

    
2508
static always_inline void gen_qemu_st64(TCGv t0, TCGv t1, int flags)
2509
{
2510
    if (unlikely(flags & 1)) {
2511
        TCGv temp = tcg_temp_new(TCG_TYPE_I64);
2512
        tcg_gen_bswap_i64(temp, t0);
2513
        gen_qemu_st64_ppc32(temp, t1, flags >> 1);
2514
        tcg_temp_free(temp);
2515
    } else
2516
        gen_qemu_st64_ppc32(t0, t1, flags >> 1);
2517
}
2518

    
2519
#endif
2520

    
2521
#define GEN_LD(width, opc, type)                                              \
2522
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2523
{                                                                             \
2524
    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
2525
    gen_addr_imm_index(EA, ctx, 0);                                           \
2526
    gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
2527
    tcg_temp_free(EA);                                                        \
2528
}
2529

    
2530
#define GEN_LDU(width, opc, type)                                             \
2531
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2532
{                                                                             \
2533
    TCGv EA;                                                                  \
2534
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2535
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2536
        GEN_EXCP_INVAL(ctx);                                                  \
2537
        return;                                                               \
2538
    }                                                                         \
2539
    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
2540
    if (type == PPC_64B)                                                      \
2541
        gen_addr_imm_index(EA, ctx, 0x03);                                    \
2542
    else                                                                      \
2543
        gen_addr_imm_index(EA, ctx, 0);                                       \
2544
    gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
2545
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2546
    tcg_temp_free(EA);                                                        \
2547
}
2548

    
2549
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2550
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2551
{                                                                             \
2552
    TCGv EA;                                                                  \
2553
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2554
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2555
        GEN_EXCP_INVAL(ctx);                                                  \
2556
        return;                                                               \
2557
    }                                                                         \
2558
    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
2559
    gen_addr_reg_index(EA, ctx);                                              \
2560
    gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
2561
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2562
    tcg_temp_free(EA);                                                        \
2563
}
2564

    
2565
#define GEN_LDX(width, opc2, opc3, type)                                      \
2566
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2567
{                                                                             \
2568
    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
2569
    gen_addr_reg_index(EA, ctx);                                              \
2570
    gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
2571
    tcg_temp_free(EA);                                                        \
2572
}
2573

    
2574
#define GEN_LDS(width, op, type)                                              \
2575
GEN_LD(width, op | 0x20, type);                                               \
2576
GEN_LDU(width, op | 0x21, type);                                              \
2577
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2578
GEN_LDX(width, 0x17, op | 0x00, type)
2579

    
2580
/* lbz lbzu lbzux lbzx */
2581
GEN_LDS(8u, 0x02, PPC_INTEGER);
2582
/* lha lhau lhaux lhax */
2583
GEN_LDS(16s, 0x0A, PPC_INTEGER);
2584
/* lhz lhzu lhzux lhzx */
2585
GEN_LDS(16u, 0x08, PPC_INTEGER);
2586
/* lwz lwzu lwzux lwzx */
2587
GEN_LDS(32u, 0x00, PPC_INTEGER);
2588
#if defined(TARGET_PPC64)
2589
/* lwaux */
2590
GEN_LDUX(32s, 0x15, 0x0B, PPC_64B);
2591
/* lwax */
2592
GEN_LDX(32s, 0x15, 0x0A, PPC_64B);
2593
/* ldux */
2594
GEN_LDUX(64, 0x15, 0x01, PPC_64B);
2595
/* ldx */
2596
GEN_LDX(64, 0x15, 0x00, PPC_64B);
2597
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2598
{
2599
    TCGv EA;
2600
    if (Rc(ctx->opcode)) {
2601
        if (unlikely(rA(ctx->opcode) == 0 ||
2602
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2603
            GEN_EXCP_INVAL(ctx);
2604
            return;
2605
        }
2606
    }
2607
    EA = tcg_temp_new(TCG_TYPE_TL);
2608
    gen_addr_imm_index(EA, ctx, 0x03);
2609
    if (ctx->opcode & 0x02) {
2610
        /* lwa (lwau is undefined) */
2611
        gen_qemu_ld32s(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);
2612
    } else {
2613
        /* ld - ldu */
2614
        gen_qemu_ld64(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);
2615
    }
2616
    if (Rc(ctx->opcode))
2617
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2618
    tcg_temp_free(EA);
2619
}
2620
/* lq */
2621
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2622
{
2623
#if defined(CONFIG_USER_ONLY)
2624
    GEN_EXCP_PRIVOPC(ctx);
2625
#else
2626
    int ra, rd;
2627
    TCGv EA;
2628

    
2629
    /* Restore CPU state */
2630
    if (unlikely(ctx->supervisor == 0)) {
2631
        GEN_EXCP_PRIVOPC(ctx);
2632
        return;
2633
    }
2634
    ra = rA(ctx->opcode);
2635
    rd = rD(ctx->opcode);
2636
    if (unlikely((rd & 1) || rd == ra)) {
2637
        GEN_EXCP_INVAL(ctx);
2638
        return;
2639
    }
2640
    if (unlikely(ctx->mem_idx & 1)) {
2641
        /* Little-endian mode is not handled */
2642
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2643
        return;
2644
    }
2645
    EA = tcg_temp_new(TCG_TYPE_TL);
2646
    gen_addr_imm_index(EA, ctx, 0x0F);
2647
    gen_qemu_ld64(cpu_gpr[rd], EA, ctx->mem_idx);
2648
    tcg_gen_addi_tl(EA, EA, 8);
2649
    gen_qemu_ld64(cpu_gpr[rd+1], EA, ctx->mem_idx);
2650
    tcg_temp_free(EA);
2651
#endif
2652
}
2653
#endif
2654

    
2655
/***                              Integer store                            ***/
2656
#define GEN_ST(width, opc, type)                                              \
2657
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2658
{                                                                             \
2659
    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
2660
    gen_addr_imm_index(EA, ctx, 0);                                           \
2661
    gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);       \
2662
    tcg_temp_free(EA);                                                        \
2663
}
2664

    
2665
#define GEN_STU(width, opc, type)                                             \
2666
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2667
{                                                                             \
2668
    TCGv EA;                                                                  \
2669
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2670
        GEN_EXCP_INVAL(ctx);                                                  \
2671
        return;                                                               \
2672
    }                                                                         \
2673
    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
2674
    if (type == PPC_64B)                                                      \
2675
        gen_addr_imm_index(EA, ctx, 0x03);                                    \
2676
    else                                                                      \
2677
        gen_addr_imm_index(EA, ctx, 0);                                       \
2678
    gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);           \
2679
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2680
    tcg_temp_free(EA);                                                        \
2681
}
2682

    
2683
#define GEN_STUX(width, opc2, opc3, type)                                     \
2684
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2685
{                                                                             \
2686
    TCGv EA;                                                                  \
2687
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2688
        GEN_EXCP_INVAL(ctx);                                                  \
2689
        return;                                                               \
2690
    }                                                                         \
2691
    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
2692
    gen_addr_reg_index(EA, ctx);                                              \
2693
    gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);           \
2694
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2695
    tcg_temp_free(EA);                                                        \
2696
}
2697

    
2698
#define GEN_STX(width, opc2, opc3, type)                                      \
2699
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2700
{                                                                             \
2701
    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
2702
    gen_addr_reg_index(EA, ctx);                                              \
2703
    gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);           \
2704
    tcg_temp_free(EA);                                                        \
2705
}
2706

    
2707
#define GEN_STS(width, op, type)                                              \
2708
GEN_ST(width, op | 0x20, type);                                               \
2709
GEN_STU(width, op | 0x21, type);                                              \
2710
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2711
GEN_STX(width, 0x17, op | 0x00, type)
2712

    
2713
/* stb stbu stbux stbx */
2714
GEN_STS(8, 0x06, PPC_INTEGER);
2715
/* sth sthu sthux sthx */
2716
GEN_STS(16, 0x0C, PPC_INTEGER);
2717
/* stw stwu stwux stwx */
2718
GEN_STS(32, 0x04, PPC_INTEGER);
2719
#if defined(TARGET_PPC64)
2720
GEN_STUX(64, 0x15, 0x05, PPC_64B);
2721
GEN_STX(64, 0x15, 0x04, PPC_64B);
2722
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2723
{
2724
    int rs;
2725
    TCGv EA;
2726

    
2727
    rs = rS(ctx->opcode);
2728
    if ((ctx->opcode & 0x3) == 0x2) {
2729
#if defined(CONFIG_USER_ONLY)
2730
        GEN_EXCP_PRIVOPC(ctx);
2731
#else
2732
        /* stq */
2733
        if (unlikely(ctx->supervisor == 0)) {
2734
            GEN_EXCP_PRIVOPC(ctx);
2735
            return;
2736
        }
2737
        if (unlikely(rs & 1)) {
2738
            GEN_EXCP_INVAL(ctx);
2739
            return;
2740
        }
2741
        if (unlikely(ctx->mem_idx & 1)) {
2742
            /* Little-endian mode is not handled */
2743
            GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2744
            return;
2745
        }
2746
        EA = tcg_temp_new(TCG_TYPE_TL);
2747
        gen_addr_imm_index(EA, ctx, 0x03);
2748
        gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
2749
        tcg_gen_addi_tl(EA, EA, 8);
2750
        gen_qemu_st64(cpu_gpr[rs+1], EA, ctx->mem_idx);
2751
        tcg_temp_free(EA);
2752
#endif
2753
    } else {
2754
        /* std / stdu */
2755
        if (Rc(ctx->opcode)) {
2756
            if (unlikely(rA(ctx->opcode) == 0)) {
2757
                GEN_EXCP_INVAL(ctx);
2758
                return;
2759
            }
2760
        }
2761
        EA = tcg_temp_new(TCG_TYPE_TL);
2762
        gen_addr_imm_index(EA, ctx, 0x03);
2763
        gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
2764
        if (Rc(ctx->opcode))
2765
            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2766
        tcg_temp_free(EA);
2767
    }
2768
}
2769
#endif
2770
/***                Integer load and store with byte reverse               ***/
2771
/* lhbrx */
2772
void always_inline gen_qemu_ld16ur(TCGv t0, TCGv t1, int flags)
2773
{
2774
    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
2775
    gen_qemu_ld16u(temp, t1, flags);
2776
    tcg_gen_bswap16_i32(temp, temp);
2777
    tcg_gen_extu_i32_tl(t0, temp);
2778
    tcg_temp_free(temp);
2779
}
2780
GEN_LDX(16ur, 0x16, 0x18, PPC_INTEGER);
2781

    
2782
/* lwbrx */
2783
void always_inline gen_qemu_ld32ur(TCGv t0, TCGv t1, int flags)
2784
{
2785
    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
2786
    gen_qemu_ld32u(temp, t1, flags);
2787
    tcg_gen_bswap_i32(temp, temp);
2788
    tcg_gen_extu_i32_tl(t0, temp);
2789
    tcg_temp_free(temp);
2790
}
2791
GEN_LDX(32ur, 0x16, 0x10, PPC_INTEGER);
2792

    
2793
/* sthbrx */
2794
void always_inline gen_qemu_st16r(TCGv t0, TCGv t1, int flags)
2795
{
2796
    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
2797
    tcg_gen_trunc_tl_i32(temp, t0);
2798
    tcg_gen_ext16u_i32(temp, temp);
2799
    tcg_gen_bswap16_i32(temp, temp);
2800
    gen_qemu_st16(temp, t1, flags);
2801
    tcg_temp_free(temp);
2802
}
2803
GEN_STX(16r, 0x16, 0x1C, PPC_INTEGER);
2804

    
2805
/* stwbrx */
2806
void always_inline gen_qemu_st32r(TCGv t0, TCGv t1, int flags)
2807
{
2808
    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
2809
    tcg_gen_trunc_tl_i32(temp, t0);
2810
    tcg_gen_bswap_i32(temp, temp);
2811
    gen_qemu_st32(temp, t1, flags);
2812
    tcg_temp_free(temp);
2813
}
2814
GEN_STX(32r, 0x16, 0x14, PPC_INTEGER);
2815

    
2816
/***                    Integer load and store multiple                    ***/
2817
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2818
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
2819
    GEN_MEM_FUNCS(lmw),
2820
};
2821
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
2822
    GEN_MEM_FUNCS(stmw),
2823
};
2824

    
2825
/* lmw */
2826
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2827
{
2828
    /* NIP cannot be restored if the memory exception comes from an helper */
2829
    gen_update_nip(ctx, ctx->nip - 4);
2830
    gen_addr_imm_index(cpu_T[0], ctx, 0);
2831
    op_ldstm(lmw, rD(ctx->opcode));
2832
}
2833

    
2834
/* stmw */
2835
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2836
{
2837
    /* NIP cannot be restored if the memory exception comes from an helper */
2838
    gen_update_nip(ctx, ctx->nip - 4);
2839
    gen_addr_imm_index(cpu_T[0], ctx, 0);
2840
    op_ldstm(stmw, rS(ctx->opcode));
2841
}
2842

    
2843
/***                    Integer load and store strings                     ***/
2844
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2845
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2846
/* string load & stores are by definition endian-safe */
2847
#define gen_op_lswi_le_raw       gen_op_lswi_raw
2848
#define gen_op_lswi_le_user      gen_op_lswi_user
2849
#define gen_op_lswi_le_kernel    gen_op_lswi_kernel
2850
#define gen_op_lswi_le_hypv      gen_op_lswi_hypv
2851
#define gen_op_lswi_le_64_raw    gen_op_lswi_raw
2852
#define gen_op_lswi_le_64_user   gen_op_lswi_user
2853
#define gen_op_lswi_le_64_kernel gen_op_lswi_kernel
2854
#define gen_op_lswi_le_64_hypv   gen_op_lswi_hypv
2855
static GenOpFunc1 *gen_op_lswi[NB_MEM_FUNCS] = {
2856
    GEN_MEM_FUNCS(lswi),
2857
};
2858
#define gen_op_lswx_le_raw       gen_op_lswx_raw
2859
#define gen_op_lswx_le_user      gen_op_lswx_user
2860
#define gen_op_lswx_le_kernel    gen_op_lswx_kernel
2861
#define gen_op_lswx_le_hypv      gen_op_lswx_hypv
2862
#define gen_op_lswx_le_64_raw    gen_op_lswx_raw
2863
#define gen_op_lswx_le_64_user   gen_op_lswx_user
2864
#define gen_op_lswx_le_64_kernel gen_op_lswx_kernel
2865
#define gen_op_lswx_le_64_hypv   gen_op_lswx_hypv
2866
static GenOpFunc3 *gen_op_lswx[NB_MEM_FUNCS] = {
2867
    GEN_MEM_FUNCS(lswx),
2868
};
2869
#define gen_op_stsw_le_raw       gen_op_stsw_raw
2870
#define gen_op_stsw_le_user      gen_op_stsw_user
2871
#define gen_op_stsw_le_kernel    gen_op_stsw_kernel
2872
#define gen_op_stsw_le_hypv      gen_op_stsw_hypv
2873
#define gen_op_stsw_le_64_raw    gen_op_stsw_raw
2874
#define gen_op_stsw_le_64_user   gen_op_stsw_user
2875
#define gen_op_stsw_le_64_kernel gen_op_stsw_kernel
2876
#define gen_op_stsw_le_64_hypv   gen_op_stsw_hypv
2877
static GenOpFunc1 *gen_op_stsw[NB_MEM_FUNCS] = {
2878
    GEN_MEM_FUNCS(stsw),
2879
};
2880

    
2881
/* lswi */
2882
/* PowerPC32 specification says we must generate an exception if
2883
 * rA is in the range of registers to be loaded.
2884
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2885
 * For now, I'll follow the spec...
2886
 */
2887
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
2888
{
2889
    int nb = NB(ctx->opcode);
2890
    int start = rD(ctx->opcode);
2891
    int ra = rA(ctx->opcode);
2892
    int nr;
2893

    
2894
    if (nb == 0)
2895
        nb = 32;
2896
    nr = nb / 4;
2897
    if (unlikely(((start + nr) > 32  &&
2898
                  start <= ra && (start + nr - 32) > ra) ||
2899
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2900
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
2901
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
2902
        return;
2903
    }
2904
    /* NIP cannot be restored if the memory exception comes from an helper */
2905
    gen_update_nip(ctx, ctx->nip - 4);
2906
    gen_addr_register(cpu_T[0], ctx);
2907
    tcg_gen_movi_tl(cpu_T[1], nb);
2908
    op_ldsts(lswi, start);
2909
}
2910

    
2911
/* lswx */
2912
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
2913
{
2914
    int ra = rA(ctx->opcode);
2915
    int rb = rB(ctx->opcode);
2916

    
2917
    /* NIP cannot be restored if the memory exception comes from an helper */
2918
    gen_update_nip(ctx, ctx->nip - 4);
2919
    gen_addr_reg_index(cpu_T[0], ctx);
2920
    if (ra == 0) {
2921
        ra = rb;
2922
    }
2923
    tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
2924
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2925
}
2926

    
2927
/* stswi */
2928
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
2929
{
2930
    int nb = NB(ctx->opcode);
2931

    
2932
    /* NIP cannot be restored if the memory exception comes from an helper */
2933
    gen_update_nip(ctx, ctx->nip - 4);
2934
    gen_addr_register(cpu_T[0], ctx);
2935
    if (nb == 0)
2936
        nb = 32;
2937
    tcg_gen_movi_tl(cpu_T[1], nb);
2938
    op_ldsts(stsw, rS(ctx->opcode));
2939
}
2940

    
2941
/* stswx */
2942
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
2943
{
2944
    /* NIP cannot be restored if the memory exception comes from an helper */
2945
    gen_update_nip(ctx, ctx->nip - 4);
2946
    gen_addr_reg_index(cpu_T[0], ctx);
2947
    tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
2948
    op_ldsts(stsw, rS(ctx->opcode));
2949
}
2950

    
2951
/***                        Memory synchronisation                         ***/
2952
/* eieio */
2953
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2954
{
2955
}
2956

    
2957
/* isync */
2958
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2959
{
2960
    GEN_STOP(ctx);
2961
}
2962

    
2963
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2964
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2965
static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
2966
    GEN_MEM_FUNCS(lwarx),
2967
};
2968
static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
2969
    GEN_MEM_FUNCS(stwcx),
2970
};
2971

    
2972
/* lwarx */
2973
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2974
{
2975
    /* NIP cannot be restored if the memory exception comes from an helper */
2976
    gen_update_nip(ctx, ctx->nip - 4);
2977
    gen_addr_reg_index(cpu_T[0], ctx);
2978
    op_lwarx();
2979
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
2980
}
2981

    
2982
/* stwcx. */
2983
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2984
{
2985
    /* NIP cannot be restored if the memory exception comes from an helper */
2986
    gen_update_nip(ctx, ctx->nip - 4);
2987
    gen_addr_reg_index(cpu_T[0], ctx);
2988
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
2989
    op_stwcx();
2990
}
2991

    
2992
#if defined(TARGET_PPC64)
2993
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2994
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2995
static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
2996
    GEN_MEM_FUNCS(ldarx),
2997
};
2998
static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
2999
    GEN_MEM_FUNCS(stdcx),
3000
};
3001

    
3002
/* ldarx */
3003
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
3004
{
3005
    /* NIP cannot be restored if the memory exception comes from an helper */
3006
    gen_update_nip(ctx, ctx->nip - 4);
3007
    gen_addr_reg_index(cpu_T[0], ctx);
3008
    op_ldarx();
3009
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
3010
}
3011

    
3012
/* stdcx. */
3013
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
3014
{
3015
    /* NIP cannot be restored if the memory exception comes from an helper */
3016
    gen_update_nip(ctx, ctx->nip - 4);
3017
    gen_addr_reg_index(cpu_T[0], ctx);
3018
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
3019
    op_stdcx();
3020
}
3021
#endif /* defined(TARGET_PPC64) */
3022

    
3023
/* sync */
3024
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
3025
{
3026
}
3027

    
3028
/* wait */
3029
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
3030
{
3031
    /* Stop translation, as the CPU is supposed to sleep from now */
3032
    gen_op_wait();
3033
    GEN_EXCP(ctx, EXCP_HLT, 1);
3034
}
3035

    
3036
/***                         Floating-point load                           ***/
3037
#define GEN_LDF(width, opc, type)                                             \
3038
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
3039
{                                                                             \
3040
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3041
        GEN_EXCP_NO_FP(ctx);                                                  \
3042
        return;                                                               \
3043
    }                                                                         \
3044
    gen_addr_imm_index(cpu_T[0], ctx, 0);                                     \
3045
    op_ldst(l##width);                                                        \
3046
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
3047
}
3048

    
3049
#define GEN_LDUF(width, opc, type)                                            \
3050
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
3051
{                                                                             \
3052
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3053
        GEN_EXCP_NO_FP(ctx);                                                  \
3054
        return;                                                               \
3055
    }                                                                         \
3056
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3057
        GEN_EXCP_INVAL(ctx);                                                  \
3058
        return;                                                               \
3059
    }                                                                         \
3060
    gen_addr_imm_index(cpu_T[0], ctx, 0);                                     \
3061
    op_ldst(l##width);                                                        \
3062
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
3063
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
3064
}
3065

    
3066
#define GEN_LDUXF(width, opc, type)                                           \
3067
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
3068
{                                                                             \
3069
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3070
        GEN_EXCP_NO_FP(ctx);                                                  \
3071
        return;                                                               \
3072
    }                                                                         \
3073
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3074
        GEN_EXCP_INVAL(ctx);                                                  \
3075
        return;                                                               \
3076
    }                                                                         \
3077
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
3078
    op_ldst(l##width);                                                        \
3079
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
3080
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
3081
}
3082

    
3083
#define GEN_LDXF(width, opc2, opc3, type)                                     \
3084
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
3085
{                                                                             \
3086
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3087
        GEN_EXCP_NO_FP(ctx);                                                  \
3088
        return;                                                               \
3089
    }                                                                         \
3090
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
3091
    op_ldst(l##width);                                                        \
3092
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
3093
}
3094

    
3095
#define GEN_LDFS(width, op, type)                                             \
3096
OP_LD_TABLE(width);                                                           \
3097
GEN_LDF(width, op | 0x20, type);                                              \
3098
GEN_LDUF(width, op | 0x21, type);                                             \
3099
GEN_LDUXF(width, op | 0x01, type);                                            \
3100
GEN_LDXF(width, 0x17, op | 0x00, type)
3101

    
3102
/* lfd lfdu lfdux lfdx */
3103
GEN_LDFS(fd, 0x12, PPC_FLOAT);
3104
/* lfs lfsu lfsux lfsx */
3105
GEN_LDFS(fs, 0x10, PPC_FLOAT);
3106

    
3107
/***                         Floating-point store                          ***/
3108
#define GEN_STF(width, opc, type)                                             \
3109
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
3110
{                                                                             \
3111
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3112
        GEN_EXCP_NO_FP(ctx);                                                  \
3113
        return;                                                               \
3114
    }                                                                         \
3115
    gen_addr_imm_index(cpu_T[0], ctx, 0);                                     \
3116
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
3117
    op_ldst(st##width);                                                       \
3118
}
3119

    
3120
#define GEN_STUF(width, opc, type)                                            \
3121
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
3122
{                                                                             \
3123
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3124
        GEN_EXCP_NO_FP(ctx);                                                  \
3125
        return;                                                               \
3126
    }                                                                         \
3127
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3128
        GEN_EXCP_INVAL(ctx);                                                  \
3129
        return;                                                               \
3130
    }                                                                         \
3131
    gen_addr_imm_index(cpu_T[0], ctx, 0);                                     \
3132
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
3133
    op_ldst(st##width);                                                       \
3134
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
3135
}
3136

    
3137
#define GEN_STUXF(width, opc, type)                                           \
3138
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
3139
{                                                                             \
3140
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3141
        GEN_EXCP_NO_FP(ctx);                                                  \
3142
        return;                                                               \
3143
    }                                                                         \
3144
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3145
        GEN_EXCP_INVAL(ctx);                                                  \
3146
        return;                                                               \
3147
    }                                                                         \
3148
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
3149
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
3150
    op_ldst(st##width);                                                       \
3151
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
3152
}
3153

    
3154
#define GEN_STXF(width, opc2, opc3, type)                                     \
3155
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
3156
{                                                                             \
3157
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3158
        GEN_EXCP_NO_FP(ctx);                                                  \
3159
        return;                                                               \
3160
    }                                                                         \
3161
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
3162
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
3163
    op_ldst(st##width);                                                       \
3164
}
3165

    
3166
#define GEN_STFS(width, op, type)                                             \
3167
OP_ST_TABLE(width);                                                           \
3168
GEN_STF(width, op | 0x20, type);                                              \
3169
GEN_STUF(width, op | 0x21, type);                                             \
3170
GEN_STUXF(width, op | 0x01, type);                                            \
3171
GEN_STXF(width, 0x17, op | 0x00, type)
3172

    
3173
/* stfd stfdu stfdux stfdx */
3174
GEN_STFS(fd, 0x16, PPC_FLOAT);
3175
/* stfs stfsu stfsux stfsx */
3176
GEN_STFS(fs, 0x14, PPC_FLOAT);
3177

    
3178
/* Optional: */
3179
/* stfiwx */
3180
OP_ST_TABLE(fiw);
3181
GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
3182

    
3183
/***                                Branch                                 ***/
3184
static always_inline void gen_goto_tb (DisasContext *ctx, int n,
3185
                                       target_ulong dest)
3186
{
3187
    TranslationBlock *tb;
3188
    tb = ctx->tb;
3189
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3190
        likely(!ctx->singlestep_enabled)) {
3191
        tcg_gen_goto_tb(n);
3192
        tcg_gen_movi_tl(cpu_T[1], dest);
3193
#if defined(TARGET_PPC64)
3194
        if (ctx->sf_mode)
3195
            tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3);
3196
        else
3197
#endif
3198
            tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3);
3199
        tcg_gen_exit_tb((long)tb + n);
3200
    } else {
3201
        tcg_gen_movi_tl(cpu_T[1], dest);
3202
#if defined(TARGET_PPC64)
3203
        if (ctx->sf_mode)
3204
            tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3);
3205
        else
3206
#endif
3207
            tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3);
3208
        if (unlikely(ctx->singlestep_enabled)) {
3209
            if ((ctx->singlestep_enabled &
3210
                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
3211
                ctx->exception == POWERPC_EXCP_BRANCH) {
3212
                target_ulong tmp = ctx->nip;
3213
                ctx->nip = dest;
3214
                GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
3215
                ctx->nip = tmp;
3216
            }
3217
            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3218
                gen_update_nip(ctx, dest);
3219
                gen_op_debug();
3220
            }
3221
        }
3222
        tcg_gen_exit_tb(0);
3223
    }
3224
}
3225

    
3226
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
3227
{
3228
#if defined(TARGET_PPC64)
3229
    if (ctx->sf_mode != 0 && (nip >> 32))
3230
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
3231
    else
3232
#endif
3233
        gen_op_setlr(ctx->nip);
3234
}
3235

    
3236
/* b ba bl bla */
3237
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3238
{
3239
    target_ulong li, target;
3240

    
3241
    ctx->exception = POWERPC_EXCP_BRANCH;
3242
    /* sign extend LI */
3243
#if defined(TARGET_PPC64)
3244
    if (ctx->sf_mode)
3245
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
3246
    else
3247
#endif
3248
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
3249
    if (likely(AA(ctx->opcode) == 0))
3250
        target = ctx->nip + li - 4;
3251
    else
3252
        target = li;
3253
#if defined(TARGET_PPC64)
3254
    if (!ctx->sf_mode)
3255
        target = (uint32_t)target;
3256
#endif
3257
    if (LK(ctx->opcode))
3258
        gen_setlr(ctx, ctx->nip);
3259
    gen_goto_tb(ctx, 0, target);
3260
}
3261

    
3262
#define BCOND_IM  0
3263
#define BCOND_LR  1
3264
#define BCOND_CTR 2
3265

    
3266
static always_inline void gen_bcond (DisasContext *ctx, int type)
3267
{
3268
    target_ulong target = 0;
3269
    target_ulong li;
3270
    uint32_t bo = BO(ctx->opcode);
3271
    uint32_t bi = BI(ctx->opcode);
3272
    uint32_t mask;
3273

    
3274
    ctx->exception = POWERPC_EXCP_BRANCH;
3275
    if ((bo & 0x4) == 0)
3276
        gen_op_dec_ctr();
3277
    switch(type) {
3278
    case BCOND_IM:
3279
        li = (target_long)((int16_t)(BD(ctx->opcode)));
3280
        if (likely(AA(ctx->opcode) == 0)) {
3281
            target = ctx->nip + li - 4;
3282
        } else {
3283
            target = li;
3284
        }
3285
#if defined(TARGET_PPC64)
3286
        if (!ctx->sf_mode)
3287
            target = (uint32_t)target;
3288
#endif
3289
        break;
3290
    case BCOND_CTR:
3291
        gen_op_movl_T1_ctr();
3292
        break;
3293
    default:
3294
    case BCOND_LR:
3295
        gen_op_movl_T1_lr();
3296
        break;
3297
    }
3298
    if (LK(ctx->opcode))
3299
        gen_setlr(ctx, ctx->nip);
3300
    if (bo & 0x10) {
3301
        /* No CR condition */
3302
        switch (bo & 0x6) {
3303
        case 0:
3304
#if defined(TARGET_PPC64)
3305
            if (ctx->sf_mode)
3306
                gen_op_test_ctr_64();
3307
            else
3308
#endif
3309
                gen_op_test_ctr();
3310
            break;
3311
        case 2:
3312
#if defined(TARGET_PPC64)
3313
            if (ctx->sf_mode)
3314
                gen_op_test_ctrz_64();
3315
            else
3316
#endif
3317
                gen_op_test_ctrz();
3318
            break;
3319
        default:
3320
        case 4:
3321
        case 6:
3322
            if (type == BCOND_IM) {
3323
                gen_goto_tb(ctx, 0, target);
3324
                return;
3325
            } else {
3326
#if defined(TARGET_PPC64)
3327
                if (ctx->sf_mode)
3328
                    tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3);
3329
                else
3330
#endif
3331
                    tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3);
3332
                goto no_test;
3333
            }
3334
            break;
3335
        }
3336
    } else {
3337
        mask = 1 << (3 - (bi & 0x03));
3338
        tcg_gen_mov_i32(cpu_T[0], cpu_crf[bi >> 2]);
3339
        if (bo & 0x8) {
3340
            switch (bo & 0x6) {
3341
            case 0:
3342
#if defined(TARGET_PPC64)
3343
                if (ctx->sf_mode)
3344
                    gen_op_test_ctr_true_64(mask);
3345
                else
3346
#endif
3347
                    gen_op_test_ctr_true(mask);
3348
                break;
3349
            case 2:
3350
#if defined(TARGET_PPC64)
3351
                if (ctx->sf_mode)
3352
                    gen_op_test_ctrz_true_64(mask);
3353
                else
3354
#endif
3355
                    gen_op_test_ctrz_true(mask);
3356
                break;
3357
            default:
3358
            case 4:
3359
            case 6:
3360
                gen_op_test_true(mask);
3361
                break;
3362
            }
3363
        } else {
3364
            switch (bo & 0x6) {
3365
            case 0:
3366
#if defined(TARGET_PPC64)
3367
                if (ctx->sf_mode)
3368
                    gen_op_test_ctr_false_64(mask);
3369
                else
3370
#endif
3371
                    gen_op_test_ctr_false(mask);
3372
                break;
3373
            case 2:
3374
#if defined(TARGET_PPC64)
3375
                if (ctx->sf_mode)
3376
                    gen_op_test_ctrz_false_64(mask);
3377
                else
3378
#endif
3379
                    gen_op_test_ctrz_false(mask);
3380
                break;
3381
            default:
3382
            case 4:
3383
            case 6:
3384
                gen_op_test_false(mask);
3385
                break;
3386
            }
3387
        }
3388
    }
3389
    if (type == BCOND_IM) {
3390
        int l1 = gen_new_label();
3391
        gen_op_jz_T0(l1);
3392
        gen_goto_tb(ctx, 0, target);
3393
        gen_set_label(l1);
3394
        gen_goto_tb(ctx, 1, ctx->nip);
3395
    } else {
3396
#if defined(TARGET_PPC64)
3397
        if (ctx->sf_mode)
3398
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
3399
        else
3400
#endif
3401
            gen_op_btest_T1(ctx->nip);
3402
    no_test:
3403
        tcg_gen_exit_tb(0);
3404
    }
3405
}
3406

    
3407
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3408
{
3409
    gen_bcond(ctx, BCOND_IM);
3410
}
3411

    
3412
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3413
{
3414
    gen_bcond(ctx, BCOND_CTR);
3415
}
3416

    
3417
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3418
{
3419
    gen_bcond(ctx, BCOND_LR);
3420
}
3421

    
3422
/***                      Condition register logical                       ***/
3423
#define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3424
GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                   \
3425
{                                                                             \
3426
    uint8_t bitmask;                                                          \
3427
    int sh;                                                                   \
3428
    TCGv temp1, temp2;                                                        \
3429
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3430
    temp1 = tcg_temp_new(TCG_TYPE_I32);                                       \
3431
    if (sh > 0)                                                               \
3432
        tcg_gen_shri_i32(temp1, cpu_crf[crbA(ctx->opcode) >> 2], sh);         \
3433
    else if (sh < 0)                                                          \
3434
        tcg_gen_shli_i32(temp1, cpu_crf[crbA(ctx->opcode) >> 2], -sh);        \
3435
    else                                                                      \
3436
        tcg_gen_mov_i32(temp1, cpu_crf[crbB(ctx->opcode) >> 2]);              \
3437
    temp2 = tcg_temp_new(TCG_TYPE_I32);                                       \
3438
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3439
    if (sh > 0)                                                               \
3440
        tcg_gen_shri_i32(temp2, cpu_crf[crbB(ctx->opcode) >> 2], sh);         \
3441
    else if (sh < 0)                                                          \
3442
        tcg_gen_shli_i32(temp2, cpu_crf[crbB(ctx->opcode) >> 2], -sh);        \
3443
    else                                                                      \
3444
        tcg_gen_mov_i32(temp2, cpu_crf[crbB(ctx->opcode) >> 2]);              \
3445
    tcg_op(temp1, temp1, temp2);                                              \
3446
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3447
    tcg_gen_andi_i32(temp1, temp1, bitmask);                                  \
3448
    tcg_gen_andi_i32(temp2, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);       \
3449
    tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], temp1, temp2);            \
3450
    tcg_temp_free(temp1);                                                     \
3451
    tcg_temp_free(temp2);                                                     \
3452
}
3453

    
3454
/* crand */
3455
GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
3456
/* crandc */
3457
GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
3458
/* creqv */
3459
GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
3460
/* crnand */
3461
GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
3462
/* crnor */
3463
GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
3464
/* cror */
3465
GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
3466
/* crorc */
3467
GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
3468
/* crxor */
3469
GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
3470
/* mcrf */
3471
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3472
{
3473
    tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
3474
}
3475

    
3476
/***                           System linkage                              ***/
3477
/* rfi (supervisor only) */
3478
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3479
{
3480
#if defined(CONFIG_USER_ONLY)
3481
    GEN_EXCP_PRIVOPC(ctx);
3482
#else
3483
    /* Restore CPU state */
3484
    if (unlikely(!ctx->supervisor)) {
3485
        GEN_EXCP_PRIVOPC(ctx);
3486
        return;
3487
    }
3488
    gen_op_rfi();
3489
    GEN_SYNC(ctx);
3490
#endif
3491
}
3492

    
3493
#if defined(TARGET_PPC64)
3494
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3495
{
3496
#if defined(CONFIG_USER_ONLY)
3497
    GEN_EXCP_PRIVOPC(ctx);
3498
#else
3499
    /* Restore CPU state */
3500
    if (unlikely(!ctx->supervisor)) {
3501
        GEN_EXCP_PRIVOPC(ctx);
3502
        return;
3503
    }
3504
    gen_op_rfid();
3505
    GEN_SYNC(ctx);
3506
#endif
3507
}
3508

    
3509
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3510
{
3511
#if defined(CONFIG_USER_ONLY)
3512
    GEN_EXCP_PRIVOPC(ctx);
3513
#else
3514
    /* Restore CPU state */
3515
    if (unlikely(ctx->supervisor <= 1)) {
3516
        GEN_EXCP_PRIVOPC(ctx);
3517
        return;
3518
    }
3519
    gen_op_hrfid();
3520
    GEN_SYNC(ctx);
3521
#endif
3522
}
3523
#endif
3524

    
3525
/* sc */
3526
#if defined(CONFIG_USER_ONLY)
3527
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3528
#else
3529
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3530
#endif
3531
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3532
{
3533
    uint32_t lev;
3534

    
3535
    lev = (ctx->opcode >> 5) & 0x7F;
3536
    GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
3537
}
3538

    
3539
/***                                Trap                                   ***/
3540
/* tw */
3541
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3542
{
3543
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3544
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3545
    /* Update the nip since this might generate a trap exception */
3546
    gen_update_nip(ctx, ctx->nip);
3547
    gen_op_tw(TO(ctx->opcode));
3548
}
3549

    
3550
/* twi */
3551
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3552
{
3553
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3554
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3555
    /* Update the nip since this might generate a trap exception */
3556
    gen_update_nip(ctx, ctx->nip);
3557
    gen_op_tw(TO(ctx->opcode));
3558
}
3559

    
3560
#if defined(TARGET_PPC64)
3561
/* td */
3562
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3563
{
3564
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3565
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3566
    /* Update the nip since this might generate a trap exception */
3567
    gen_update_nip(ctx, ctx->nip);
3568
    gen_op_td(TO(ctx->opcode));
3569
}
3570

    
3571
/* tdi */
3572
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3573
{
3574
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3575
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3576
    /* Update the nip since this might generate a trap exception */
3577
    gen_update_nip(ctx, ctx->nip);
3578
    gen_op_td(TO(ctx->opcode));
3579
}
3580
#endif
3581

    
3582
/***                          Processor control                            ***/
3583
/* mcrxr */
3584
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3585
{
3586
    tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
3587
    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
3588
    tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
3589
}
3590

    
3591
/* mfcr */
3592
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3593
{
3594
    uint32_t crm, crn;
3595

    
3596
    if (likely(ctx->opcode & 0x00100000)) {
3597
        crm = CRM(ctx->opcode);
3598
        if (likely((crm ^ (crm - 1)) == 0)) {
3599
            crn = ffs(crm);
3600
            tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
3601
        }
3602
    } else {
3603
        tcg_gen_helper_1_0(helper_load_cr, cpu_gpr[rD(ctx->opcode)]);
3604
    }
3605
}
3606

    
3607
/* mfmsr */
3608
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3609
{
3610
#if defined(CONFIG_USER_ONLY)
3611
    GEN_EXCP_PRIVREG(ctx);
3612
#else
3613
    if (unlikely(!ctx->supervisor)) {
3614
        GEN_EXCP_PRIVREG(ctx);
3615
        return;
3616
    }
3617
    gen_op_load_msr();
3618
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3619
#endif
3620
}
3621

    
3622
#if 1
3623
#define SPR_NOACCESS ((void *)(-1UL))
3624
#else
3625
static void spr_noaccess (void *opaque, int sprn)
3626
{
3627
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3628
    printf("ERROR: try to access SPR %d !\n", sprn);
3629
}
3630
#define SPR_NOACCESS (&spr_noaccess)
3631
#endif
3632

    
3633
/* mfspr */
3634
static always_inline void gen_op_mfspr (DisasContext *ctx)
3635
{
3636
    void (*read_cb)(void *opaque, int sprn);
3637
    uint32_t sprn = SPR(ctx->opcode);
3638

    
3639
#if !defined(CONFIG_USER_ONLY)
3640
    if (ctx->supervisor == 2)
3641
        read_cb = ctx->spr_cb[sprn].hea_read;
3642
    else if (ctx->supervisor)
3643
        read_cb = ctx->spr_cb[sprn].oea_read;
3644
    else
3645
#endif
3646
        read_cb = ctx->spr_cb[sprn].uea_read;
3647
    if (likely(read_cb != NULL)) {
3648
        if (likely(read_cb != SPR_NOACCESS)) {
3649
            (*read_cb)(ctx, sprn);
3650
            tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3651
        } else {
3652
            /* Privilege exception */
3653
            /* This is a hack to avoid warnings when running Linux:
3654
             * this OS breaks the PowerPC virtualisation model,
3655
             * allowing userland application to read the PVR
3656
             */
3657
            if (sprn != SPR_PVR) {
3658
                if (loglevel != 0) {
3659
                    fprintf(logfile, "Trying to read privileged spr %d %03x at "
3660
                            ADDRX "\n", sprn, sprn, ctx->nip);
3661
                }
3662
                printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
3663
                       sprn, sprn, ctx->nip);
3664
            }
3665
            GEN_EXCP_PRIVREG(ctx);
3666
        }
3667
    } else {
3668
        /* Not defined */
3669
        if (loglevel != 0) {
3670
            fprintf(logfile, "Trying to read invalid spr %d %03x at "
3671
                    ADDRX "\n", sprn, sprn, ctx->nip);
3672
        }
3673
        printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
3674
               sprn, sprn, ctx->nip);
3675
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3676
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3677
    }
3678
}
3679

    
3680
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3681
{
3682
    gen_op_mfspr(ctx);
3683
}
3684

    
3685
/* mftb */
3686
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3687
{
3688
    gen_op_mfspr(ctx);
3689
}
3690

    
3691
/* mtcrf */
3692
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3693
{
3694
    uint32_t crm, crn;
3695

    
3696
    crm = CRM(ctx->opcode);
3697
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3698
        crn = ffs(crm);
3699
        tcg_gen_shri_i32(cpu_crf[7 - crn], cpu_gpr[rS(ctx->opcode)], crn * 4);
3700
        tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
3701
    } else {
3702
        TCGv temp = tcg_const_tl(crm);
3703
        tcg_gen_helper_0_2(helper_store_cr, cpu_gpr[rS(ctx->opcode)], temp);
3704
        tcg_temp_free(temp);
3705
    }
3706
}
3707

    
3708
/* mtmsr */
3709
#if defined(TARGET_PPC64)
3710
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3711
{
3712
#if defined(CONFIG_USER_ONLY)
3713
    GEN_EXCP_PRIVREG(ctx);
3714
#else
3715
    if (unlikely(!ctx->supervisor)) {
3716
        GEN_EXCP_PRIVREG(ctx);
3717
        return;
3718
    }
3719
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3720
    if (ctx->opcode & 0x00010000) {
3721
        /* Special form that does not need any synchronisation */
3722
        gen_op_update_riee();
3723
    } else {
3724
        /* XXX: we need to update nip before the store
3725
         *      if we enter power saving mode, we will exit the loop
3726
         *      directly from ppc_store_msr
3727
         */
3728
        gen_update_nip(ctx, ctx->nip);
3729
        gen_op_store_msr();
3730
        /* Must stop the translation as machine state (may have) changed */
3731
        /* Note that mtmsr is not always defined as context-synchronizing */
3732
        ctx->exception = POWERPC_EXCP_STOP;
3733
    }
3734
#endif
3735
}
3736
#endif
3737

    
3738
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3739
{
3740
#if defined(CONFIG_USER_ONLY)
3741
    GEN_EXCP_PRIVREG(ctx);
3742
#else
3743
    if (unlikely(!ctx->supervisor)) {
3744
        GEN_EXCP_PRIVREG(ctx);
3745
        return;
3746
    }
3747
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3748
    if (ctx->opcode & 0x00010000) {
3749
        /* Special form that does not need any synchronisation */
3750
        gen_op_update_riee();
3751
    } else {
3752
        /* XXX: we need to update nip before the store
3753
         *      if we enter power saving mode, we will exit the loop
3754
         *      directly from ppc_store_msr
3755
         */
3756
        gen_update_nip(ctx, ctx->nip);
3757
#if defined(TARGET_PPC64)
3758
        if (!ctx->sf_mode)
3759
            gen_op_store_msr_32();
3760
        else
3761
#endif
3762
            gen_op_store_msr();
3763
        /* Must stop the translation as machine state (may have) changed */
3764
        /* Note that mtmsrd is not always defined as context-synchronizing */
3765
        ctx->exception = POWERPC_EXCP_STOP;
3766
    }
3767
#endif
3768
}
3769

    
3770
/* mtspr */
3771
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3772
{
3773
    void (*write_cb)(void *opaque, int sprn);
3774
    uint32_t sprn = SPR(ctx->opcode);
3775

    
3776
#if !defined(CONFIG_USER_ONLY)
3777
    if (ctx->supervisor == 2)
3778
        write_cb = ctx->spr_cb[sprn].hea_write;
3779
    else if (ctx->supervisor)
3780
        write_cb = ctx->spr_cb[sprn].oea_write;
3781
    else
3782
#endif
3783
        write_cb = ctx->spr_cb[sprn].uea_write;
3784
    if (likely(write_cb != NULL)) {
3785
        if (likely(write_cb != SPR_NOACCESS)) {
3786
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3787
            (*write_cb)(ctx, sprn);
3788
        } else {
3789
            /* Privilege exception */
3790
            if (loglevel != 0) {
3791
                fprintf(logfile, "Trying to write privileged spr %d %03x at "
3792
                        ADDRX "\n", sprn, sprn, ctx->nip);
3793
            }
3794
            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
3795
                   sprn, sprn, ctx->nip);
3796
            GEN_EXCP_PRIVREG(ctx);
3797
        }
3798
    } else {
3799
        /* Not defined */
3800
        if (loglevel != 0) {
3801
            fprintf(logfile, "Trying to write invalid spr %d %03x at "
3802
                    ADDRX "\n", sprn, sprn, ctx->nip);
3803
        }
3804
        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
3805
               sprn, sprn, ctx->nip);
3806
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3807
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3808
    }
3809
}
3810

    
3811
/***                         Cache management                              ***/
3812
/* dcbf */
3813
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3814
{
3815
    /* XXX: specification says this is treated as a load by the MMU */
3816
    TCGv temp = tcg_temp_new(TCG_TYPE_TL);
3817
    gen_addr_reg_index(temp, ctx);
3818
    gen_qemu_ld8u(temp, temp, ctx->mem_idx);
3819
    tcg_temp_free(temp);
3820
}
3821

    
3822
/* dcbi (Supervisor only) */
3823
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3824
{
3825
#if defined(CONFIG_USER_ONLY)
3826
    GEN_EXCP_PRIVOPC(ctx);
3827
#else
3828
    TCGv EA, val;
3829
    if (unlikely(!ctx->supervisor)) {
3830
        GEN_EXCP_PRIVOPC(ctx);
3831
        return;
3832
    }
3833
    EA = tcg_temp_new(TCG_TYPE_TL);
3834
    gen_addr_reg_index(EA, ctx);
3835
    val = tcg_temp_new(TCG_TYPE_TL);
3836
    /* XXX: specification says this should be treated as a store by the MMU */
3837
    gen_qemu_ld8u(val, EA, ctx->mem_idx);
3838
    gen_qemu_st8(val, EA, ctx->mem_idx);
3839
    tcg_temp_free(val);
3840
    tcg_temp_free(EA);
3841
#endif
3842
}
3843

    
3844
/* dcdst */
3845
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3846
{
3847
    /* XXX: specification say this is treated as a load by the MMU */
3848
    TCGv temp = tcg_temp_new(TCG_TYPE_TL);
3849
    gen_addr_reg_index(temp, ctx);
3850
    gen_qemu_ld8u(temp, temp, ctx->mem_idx);
3851
    tcg_temp_free(temp);
3852
}
3853

    
3854
/* dcbt */
3855
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3856
{
3857
    /* interpreted as no-op */
3858
    /* XXX: specification say this is treated as a load by the MMU
3859
     *      but does not generate any exception
3860
     */
3861
}
3862

    
3863
/* dcbtst */
3864
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3865
{
3866
    /* interpreted as no-op */
3867
    /* XXX: specification say this is treated as a load by the MMU
3868
     *      but does not generate any exception
3869
     */
3870
}
3871

    
3872
/* dcbz */
3873
#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
3874
static GenOpFunc *gen_op_dcbz[4][NB_MEM_FUNCS] = {
3875
    /* 32 bytes cache line size */
3876
    {
3877
#define gen_op_dcbz_l32_le_raw        gen_op_dcbz_l32_raw
3878
#define gen_op_dcbz_l32_le_user       gen_op_dcbz_l32_user
3879
#define gen_op_dcbz_l32_le_kernel     gen_op_dcbz_l32_kernel
3880
#define gen_op_dcbz_l32_le_hypv       gen_op_dcbz_l32_hypv
3881
#define gen_op_dcbz_l32_le_64_raw     gen_op_dcbz_l32_64_raw
3882
#define gen_op_dcbz_l32_le_64_user    gen_op_dcbz_l32_64_user
3883
#define gen_op_dcbz_l32_le_64_kernel  gen_op_dcbz_l32_64_kernel
3884
#define gen_op_dcbz_l32_le_64_hypv    gen_op_dcbz_l32_64_hypv
3885
        GEN_MEM_FUNCS(dcbz_l32),
3886
    },
3887
    /* 64 bytes cache line size */
3888
    {
3889
#define gen_op_dcbz_l64_le_raw        gen_op_dcbz_l64_raw
3890
#define gen_op_dcbz_l64_le_user       gen_op_dcbz_l64_user
3891
#define gen_op_dcbz_l64_le_kernel     gen_op_dcbz_l64_kernel
3892
#define gen_op_dcbz_l64_le_hypv       gen_op_dcbz_l64_hypv
3893
#define gen_op_dcbz_l64_le_64_raw     gen_op_dcbz_l64_64_raw
3894
#define gen_op_dcbz_l64_le_64_user    gen_op_dcbz_l64_64_user
3895
#define gen_op_dcbz_l64_le_64_kernel  gen_op_dcbz_l64_64_kernel
3896
#define gen_op_dcbz_l64_le_64_hypv    gen_op_dcbz_l64_64_hypv
3897
        GEN_MEM_FUNCS(dcbz_l64),
3898
    },
3899
    /* 128 bytes cache line size */
3900
    {
3901
#define gen_op_dcbz_l128_le_raw       gen_op_dcbz_l128_raw
3902
#define gen_op_dcbz_l128_le_user      gen_op_dcbz_l128_user
3903
#define gen_op_dcbz_l128_le_kernel    gen_op_dcbz_l128_kernel
3904
#define gen_op_dcbz_l128_le_hypv      gen_op_dcbz_l128_hypv
3905
#define gen_op_dcbz_l128_le_64_raw    gen_op_dcbz_l128_64_raw
3906
#define gen_op_dcbz_l128_le_64_user   gen_op_dcbz_l128_64_user
3907
#define gen_op_dcbz_l128_le_64_kernel gen_op_dcbz_l128_64_kernel
3908
#define gen_op_dcbz_l128_le_64_hypv   gen_op_dcbz_l128_64_hypv
3909
        GEN_MEM_FUNCS(dcbz_l128),
3910
    },
3911
    /* tunable cache line size */
3912
    {
3913
#define gen_op_dcbz_le_raw            gen_op_dcbz_raw
3914
#define gen_op_dcbz_le_user           gen_op_dcbz_user
3915
#define gen_op_dcbz_le_kernel         gen_op_dcbz_kernel
3916
#define gen_op_dcbz_le_hypv           gen_op_dcbz_hypv
3917
#define gen_op_dcbz_le_64_raw         gen_op_dcbz_64_raw
3918
#define gen_op_dcbz_le_64_user        gen_op_dcbz_64_user
3919
#define gen_op_dcbz_le_64_kernel      gen_op_dcbz_64_kernel
3920
#define gen_op_dcbz_le_64_hypv        gen_op_dcbz_64_hypv
3921
        GEN_MEM_FUNCS(dcbz),
3922
    },
3923
};
3924

    
3925
static always_inline void handler_dcbz (DisasContext *ctx,
3926
                                        int dcache_line_size)
3927
{
3928
    int n;
3929

    
3930
    switch (dcache_line_size) {
3931
    case 32:
3932
        n = 0;
3933
        break;
3934
    case 64:
3935
        n = 1;
3936
        break;
3937
    case 128:
3938
        n = 2;
3939
        break;
3940
    default:
3941
        n = 3;
3942
        break;
3943
    }
3944
    op_dcbz(n);
3945
}
3946

    
3947
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
3948
{
3949
    gen_addr_reg_index(cpu_T[0], ctx);
3950
    handler_dcbz(ctx, ctx->dcache_line_size);
3951
    gen_op_check_reservation();
3952
}
3953

    
3954
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
3955
{
3956
    gen_addr_reg_index(cpu_T[0], ctx);
3957
    if (ctx->opcode & 0x00200000)
3958
        handler_dcbz(ctx, ctx->dcache_line_size);
3959
    else
3960
        handler_dcbz(ctx, -1);
3961
    gen_op_check_reservation();
3962
}
3963

    
3964
/* icbi */
3965
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3966
#define gen_op_icbi_le_raw       gen_op_icbi_raw
3967
#define gen_op_icbi_le_user      gen_op_icbi_user
3968
#define gen_op_icbi_le_kernel    gen_op_icbi_kernel
3969
#define gen_op_icbi_le_hypv      gen_op_icbi_hypv
3970
#define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
3971
#define gen_op_icbi_le_64_user   gen_op_icbi_64_user
3972
#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
3973
#define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
3974
static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
3975
    GEN_MEM_FUNCS(icbi),
3976
};
3977

    
3978
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
3979
{
3980
    /* NIP cannot be restored if the memory exception comes from an helper */
3981
    gen_update_nip(ctx, ctx->nip - 4);
3982
    gen_addr_reg_index(cpu_T[0], ctx);
3983
    op_icbi();
3984
}
3985

    
3986
/* Optional: */
3987
/* dcba */
3988
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3989
{
3990
    /* interpreted as no-op */
3991
    /* XXX: specification say this is treated as a store by the MMU
3992
     *      but does not generate any exception
3993
     */
3994
}
3995

    
3996
/***                    Segment register manipulation                      ***/
3997
/* Supervisor only: */
3998
/* mfsr */
3999
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
4000
{
4001
#if defined(CONFIG_USER_ONLY)
4002
    GEN_EXCP_PRIVREG(ctx);
4003
#else
4004
    if (unlikely(!ctx->supervisor)) {
4005
        GEN_EXCP_PRIVREG(ctx);
4006
        return;
4007
    }
4008
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4009
    gen_op_load_sr();
4010
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4011
#endif
4012
}
4013

    
4014
/* mfsrin */
4015
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
4016
{
4017
#if defined(CONFIG_USER_ONLY)
4018
    GEN_EXCP_PRIVREG(ctx);
4019
#else
4020
    if (unlikely(!ctx->supervisor)) {
4021
        GEN_EXCP_PRIVREG(ctx);
4022
        return;
4023
    }
4024
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4025
    gen_op_srli_T1(28);
4026
    gen_op_load_sr();
4027
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4028
#endif
4029
}
4030

    
4031
/* mtsr */
4032
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
4033
{
4034
#if defined(CONFIG_USER_ONLY)
4035
    GEN_EXCP_PRIVREG(ctx);
4036
#else
4037
    if (unlikely(!ctx->supervisor)) {
4038
        GEN_EXCP_PRIVREG(ctx);
4039
        return;
4040
    }
4041
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4042
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4043
    gen_op_store_sr();
4044
#endif
4045
}
4046

    
4047
/* mtsrin */
4048
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
4049
{
4050
#if defined(CONFIG_USER_ONLY)
4051
    GEN_EXCP_PRIVREG(ctx);
4052
#else
4053
    if (unlikely(!ctx->supervisor)) {
4054
        GEN_EXCP_PRIVREG(ctx);
4055
        return;
4056
    }
4057
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4058
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4059
    gen_op_srli_T1(28);
4060
    gen_op_store_sr();
4061
#endif
4062
}
4063

    
4064
#if defined(TARGET_PPC64)
4065
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4066
/* mfsr */
4067
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
4068
{
4069
#if defined(CONFIG_USER_ONLY)
4070
    GEN_EXCP_PRIVREG(ctx);
4071
#else
4072
    if (unlikely(!ctx->supervisor)) {
4073
        GEN_EXCP_PRIVREG(ctx);
4074
        return;
4075
    }
4076
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4077
    gen_op_load_slb();
4078
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4079
#endif
4080
}
4081

    
4082
/* mfsrin */
4083
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
4084
             PPC_SEGMENT_64B)
4085
{
4086
#if defined(CONFIG_USER_ONLY)
4087
    GEN_EXCP_PRIVREG(ctx);
4088
#else
4089
    if (unlikely(!ctx->supervisor)) {
4090
        GEN_EXCP_PRIVREG(ctx);
4091
        return;
4092
    }
4093
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4094
    gen_op_srli_T1(28);
4095
    gen_op_load_slb();
4096
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4097
#endif
4098
}
4099

    
4100
/* mtsr */
4101
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
4102
{
4103
#if defined(CONFIG_USER_ONLY)
4104
    GEN_EXCP_PRIVREG(ctx);
4105
#else
4106
    if (unlikely(!ctx->supervisor)) {
4107
        GEN_EXCP_PRIVREG(ctx);
4108
        return;
4109
    }
4110
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4111
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4112
    gen_op_store_slb();
4113
#endif
4114
}
4115

    
4116
/* mtsrin */
4117
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
4118
             PPC_SEGMENT_64B)
4119
{
4120
#if defined(CONFIG_USER_ONLY)
4121
    GEN_EXCP_PRIVREG(ctx);
4122
#else
4123
    if (unlikely(!ctx->supervisor)) {
4124
        GEN_EXCP_PRIVREG(ctx);
4125
        return;
4126
    }
4127
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4128
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4129
    gen_op_srli_T1(28);
4130
    gen_op_store_slb();
4131
#endif
4132
}
4133
#endif /* defined(TARGET_PPC64) */
4134

    
4135
/***                      Lookaside buffer management                      ***/
4136
/* Optional & supervisor only: */
4137
/* tlbia */
4138
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
4139
{
4140
#if defined(CONFIG_USER_ONLY)
4141
    GEN_EXCP_PRIVOPC(ctx);
4142
#else
4143
    if (unlikely(!ctx->supervisor)) {
4144
        GEN_EXCP_PRIVOPC(ctx);
4145
        return;
4146
    }
4147
    gen_op_tlbia();
4148
#endif
4149
}
4150

    
4151
/* tlbie */
4152
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
4153
{
4154
#if defined(CONFIG_USER_ONLY)
4155
    GEN_EXCP_PRIVOPC(ctx);
4156
#else
4157
    if (unlikely(!ctx->supervisor)) {
4158
        GEN_EXCP_PRIVOPC(ctx);
4159
        return;
4160
    }
4161
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4162
#if defined(TARGET_PPC64)
4163
    if (ctx->sf_mode)
4164
        gen_op_tlbie_64();
4165
    else
4166
#endif
4167
        gen_op_tlbie();
4168
#endif
4169
}
4170

    
4171
/* tlbsync */
4172
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
4173
{
4174
#if defined(CONFIG_USER_ONLY)
4175
    GEN_EXCP_PRIVOPC(ctx);
4176
#else
4177
    if (unlikely(!ctx->supervisor)) {
4178
        GEN_EXCP_PRIVOPC(ctx);
4179
        return;
4180
    }
4181
    /* This has no effect: it should ensure that all previous
4182
     * tlbie have completed
4183
     */
4184
    GEN_STOP(ctx);
4185
#endif
4186
}
4187

    
4188
#if defined(TARGET_PPC64)
4189
/* slbia */
4190
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
4191
{
4192
#if defined(CONFIG_USER_ONLY)
4193
    GEN_EXCP_PRIVOPC(ctx);
4194
#else
4195
    if (unlikely(!ctx->supervisor)) {
4196
        GEN_EXCP_PRIVOPC(ctx);
4197
        return;
4198
    }
4199
    gen_op_slbia();
4200
#endif
4201
}
4202

    
4203
/* slbie */
4204
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
4205
{
4206
#if defined(CONFIG_USER_ONLY)
4207
    GEN_EXCP_PRIVOPC(ctx);
4208
#else
4209
    if (unlikely(!ctx->supervisor)) {
4210
        GEN_EXCP_PRIVOPC(ctx);
4211
        return;
4212
    }
4213
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4214
    gen_op_slbie();
4215
#endif
4216
}
4217
#endif
4218

    
4219
/***                              External control                         ***/
4220
/* Optional: */
4221
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
4222
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
4223
static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
4224
    GEN_MEM_FUNCS(eciwx),
4225
};
4226
static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
4227
    GEN_MEM_FUNCS(ecowx),
4228
};
4229

    
4230
/* eciwx */
4231
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
4232
{
4233
    /* Should check EAR[E] & alignment ! */
4234
    gen_addr_reg_index(cpu_T[0], ctx);
4235
    op_eciwx();
4236
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4237
}
4238

    
4239
/* ecowx */
4240
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
4241
{
4242
    /* Should check EAR[E] & alignment ! */
4243
    gen_addr_reg_index(cpu_T[0], ctx);
4244
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4245
    op_ecowx();
4246
}
4247

    
4248
/* PowerPC 601 specific instructions */
4249
/* abs - abs. */
4250
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
4251
{
4252
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4253
    gen_op_POWER_abs();
4254
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4255
    if (unlikely(Rc(ctx->opcode) != 0))
4256
        gen_set_Rc0(ctx, cpu_T[0]);
4257
}
4258

    
4259
/* abso - abso. */
4260
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
4261
{
4262
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4263
    gen_op_POWER_abso();
4264
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4265
    if (unlikely(Rc(ctx->opcode) != 0))
4266
        gen_set_Rc0(ctx, cpu_T[0]);
4267
}
4268

    
4269
/* clcs */
4270
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
4271
{
4272
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4273
    gen_op_POWER_clcs();
4274
    /* Rc=1 sets CR0 to an undefined state */
4275
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4276
}
4277

    
4278
/* div - div. */
4279
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
4280
{
4281
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4282
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4283
    gen_op_POWER_div();
4284
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4285
    if (unlikely(Rc(ctx->opcode) != 0))
4286
        gen_set_Rc0(ctx, cpu_T[0]);
4287
}
4288

    
4289
/* divo - divo. */
4290
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
4291
{
4292
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4293
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4294
    gen_op_POWER_divo();
4295
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4296
    if (unlikely(Rc(ctx->opcode) != 0))
4297
        gen_set_Rc0(ctx, cpu_T[0]);
4298
}
4299

    
4300
/* divs - divs. */
4301
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
4302
{
4303
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4304
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4305
    gen_op_POWER_divs();
4306
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4307
    if (unlikely(Rc(ctx->opcode) != 0))
4308
        gen_set_Rc0(ctx, cpu_T[0]);
4309
}
4310

    
4311
/* divso - divso. */
4312
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
4313
{
4314
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4315
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4316
    gen_op_POWER_divso();
4317
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4318
    if (unlikely(Rc(ctx->opcode) != 0))
4319
        gen_set_Rc0(ctx, cpu_T[0]);
4320
}
4321

    
4322
/* doz - doz. */
4323
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
4324
{
4325
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4326
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4327
    gen_op_POWER_doz();
4328
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4329
    if (unlikely(Rc(ctx->opcode) != 0))
4330
        gen_set_Rc0(ctx, cpu_T[0]);
4331
}
4332

    
4333
/* dozo - dozo. */
4334
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
4335
{
4336
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4337
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4338
    gen_op_POWER_dozo();
4339
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4340
    if (unlikely(Rc(ctx->opcode) != 0))
4341
        gen_set_Rc0(ctx, cpu_T[0]);
4342
}
4343

    
4344
/* dozi */
4345
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4346
{
4347
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4348
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
4349
    gen_op_POWER_doz();
4350
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4351
}
4352

    
4353
/* As lscbx load from memory byte after byte, it's always endian safe.
4354
 * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones
4355
 */
4356
#define op_POWER_lscbx(start, ra, rb)                                         \
4357
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
4358
#define gen_op_POWER_lscbx_64_raw       gen_op_POWER_lscbx_raw
4359
#define gen_op_POWER_lscbx_64_user      gen_op_POWER_lscbx_user
4360
#define gen_op_POWER_lscbx_64_kernel    gen_op_POWER_lscbx_kernel
4361
#define gen_op_POWER_lscbx_64_hypv      gen_op_POWER_lscbx_hypv
4362
#define gen_op_POWER_lscbx_le_raw       gen_op_POWER_lscbx_raw
4363
#define gen_op_POWER_lscbx_le_user      gen_op_POWER_lscbx_user
4364
#define gen_op_POWER_lscbx_le_kernel    gen_op_POWER_lscbx_kernel
4365
#define gen_op_POWER_lscbx_le_hypv      gen_op_POWER_lscbx_hypv
4366
#define gen_op_POWER_lscbx_le_64_raw    gen_op_POWER_lscbx_raw
4367
#define gen_op_POWER_lscbx_le_64_user   gen_op_POWER_lscbx_user
4368
#define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel
4369
#define gen_op_POWER_lscbx_le_64_hypv   gen_op_POWER_lscbx_hypv
4370
static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = {
4371
    GEN_MEM_FUNCS(POWER_lscbx),
4372
};
4373

    
4374
/* lscbx - lscbx. */
4375
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
4376
{
4377
    int ra = rA(ctx->opcode);
4378
    int rb = rB(ctx->opcode);
4379

    
4380
    gen_addr_reg_index(cpu_T[0], ctx);
4381
    if (ra == 0) {
4382
        ra = rb;
4383
    }
4384
    /* NIP cannot be restored if the memory exception comes from an helper */
4385
    gen_update_nip(ctx, ctx->nip - 4);
4386
    tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
4387
    tcg_gen_shri_tl(cpu_T[2], cpu_xer, XER_CMP);
4388
    tcg_gen_andi_tl(cpu_T[2], cpu_T[2], 0xFF);
4389
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
4390
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
4391
    tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
4392
    if (unlikely(Rc(ctx->opcode) != 0))
4393
        gen_set_Rc0(ctx, cpu_T[0]);
4394
}
4395

    
4396
/* maskg - maskg. */
4397
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
4398
{
4399
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4400
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4401
    gen_op_POWER_maskg();
4402
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4403
    if (unlikely(Rc(ctx->opcode) != 0))
4404
        gen_set_Rc0(ctx, cpu_T[0]);
4405
}
4406

    
4407
/* maskir - maskir. */
4408
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4409
{
4410
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4411
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4412
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4413
    gen_op_POWER_maskir();
4414
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4415
    if (unlikely(Rc(ctx->opcode) != 0))
4416
        gen_set_Rc0(ctx, cpu_T[0]);
4417
}
4418

    
4419
/* mul - mul. */
4420
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4421
{
4422
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4423
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4424
    gen_op_POWER_mul();
4425
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4426
    if (unlikely(Rc(ctx->opcode) != 0))
4427
        gen_set_Rc0(ctx, cpu_T[0]);
4428
}
4429

    
4430
/* mulo - mulo. */
4431
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4432
{
4433
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4434
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4435
    gen_op_POWER_mulo();
4436
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4437
    if (unlikely(Rc(ctx->opcode) != 0))
4438
        gen_set_Rc0(ctx, cpu_T[0]);
4439
}
4440

    
4441
/* nabs - nabs. */
4442
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4443
{
4444
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4445
    gen_op_POWER_nabs();
4446
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4447
    if (unlikely(Rc(ctx->opcode) != 0))
4448
        gen_set_Rc0(ctx, cpu_T[0]);
4449
}
4450

    
4451
/* nabso - nabso. */
4452
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4453
{
4454
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4455
    gen_op_POWER_nabso();
4456
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4457
    if (unlikely(Rc(ctx->opcode) != 0))
4458
        gen_set_Rc0(ctx, cpu_T[0]);
4459
}
4460

    
4461
/* rlmi - rlmi. */
4462
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4463
{
4464
    uint32_t mb, me;
4465

    
4466
    mb = MB(ctx->opcode);
4467
    me = ME(ctx->opcode);
4468
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4469
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4470
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4471
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4472
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4473
    if (unlikely(Rc(ctx->opcode) != 0))
4474
        gen_set_Rc0(ctx, cpu_T[0]);
4475
}
4476

    
4477
/* rrib - rrib. */
4478
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4479
{
4480
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4481
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4482
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4483
    gen_op_POWER_rrib();
4484
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4485
    if (unlikely(Rc(ctx->opcode) != 0))
4486
        gen_set_Rc0(ctx, cpu_T[0]);
4487
}
4488

    
4489
/* sle - sle. */
4490
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4491
{
4492
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4493
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4494
    gen_op_POWER_sle();
4495
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4496
    if (unlikely(Rc(ctx->opcode) != 0))
4497
        gen_set_Rc0(ctx, cpu_T[0]);
4498
}
4499

    
4500
/* sleq - sleq. */
4501
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4502
{
4503
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4504
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4505
    gen_op_POWER_sleq();
4506
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4507
    if (unlikely(Rc(ctx->opcode) != 0))
4508
        gen_set_Rc0(ctx, cpu_T[0]);
4509
}
4510

    
4511
/* sliq - sliq. */
4512
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4513
{
4514
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4515
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4516
    gen_op_POWER_sle();
4517
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4518
    if (unlikely(Rc(ctx->opcode) != 0))
4519
        gen_set_Rc0(ctx, cpu_T[0]);
4520
}
4521

    
4522
/* slliq - slliq. */
4523
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4524
{
4525
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4526
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4527
    gen_op_POWER_sleq();
4528
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4529
    if (unlikely(Rc(ctx->opcode) != 0))
4530
        gen_set_Rc0(ctx, cpu_T[0]);
4531
}
4532

    
4533
/* sllq - sllq. */
4534
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4535
{
4536
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4537
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4538
    gen_op_POWER_sllq();
4539
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4540
    if (unlikely(Rc(ctx->opcode) != 0))
4541
        gen_set_Rc0(ctx, cpu_T[0]);
4542
}
4543

    
4544
/* slq - slq. */
4545
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4546
{
4547
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4548
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4549
    gen_op_POWER_slq();
4550
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4551
    if (unlikely(Rc(ctx->opcode) != 0))
4552
        gen_set_Rc0(ctx, cpu_T[0]);
4553
}
4554

    
4555
/* sraiq - sraiq. */
4556
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4557
{
4558
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4559
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4560
    gen_op_POWER_sraq();
4561
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4562
    if (unlikely(Rc(ctx->opcode) != 0))
4563
        gen_set_Rc0(ctx, cpu_T[0]);
4564
}
4565

    
4566
/* sraq - sraq. */
4567
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4568
{
4569
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4570
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4571
    gen_op_POWER_sraq();
4572
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4573
    if (unlikely(Rc(ctx->opcode) != 0))
4574
        gen_set_Rc0(ctx, cpu_T[0]);
4575
}
4576

    
4577
/* sre - sre. */
4578
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4579
{
4580
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4581
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4582
    gen_op_POWER_sre();
4583
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4584
    if (unlikely(Rc(ctx->opcode) != 0))
4585
        gen_set_Rc0(ctx, cpu_T[0]);
4586
}
4587

    
4588
/* srea - srea. */
4589
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4590
{
4591
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4592
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4593
    gen_op_POWER_srea();
4594
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4595
    if (unlikely(Rc(ctx->opcode) != 0))
4596
        gen_set_Rc0(ctx, cpu_T[0]);
4597
}
4598

    
4599
/* sreq */
4600
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4601
{
4602
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4603
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4604
    gen_op_POWER_sreq();
4605
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4606
    if (unlikely(Rc(ctx->opcode) != 0))
4607
        gen_set_Rc0(ctx, cpu_T[0]);
4608
}
4609

    
4610
/* sriq */
4611
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4612
{
4613
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4614
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4615
    gen_op_POWER_srq();
4616
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4617
    if (unlikely(Rc(ctx->opcode) != 0))
4618
        gen_set_Rc0(ctx, cpu_T[0]);
4619
}
4620

    
4621
/* srliq */
4622
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4623
{
4624
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4625
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4626
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4627
    gen_op_POWER_srlq();
4628
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4629
    if (unlikely(Rc(ctx->opcode) != 0))
4630
        gen_set_Rc0(ctx, cpu_T[0]);
4631
}
4632

    
4633
/* srlq */
4634
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4635
{
4636
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4637
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4638
    gen_op_POWER_srlq();
4639
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4640
    if (unlikely(Rc(ctx->opcode) != 0))
4641
        gen_set_Rc0(ctx, cpu_T[0]);
4642
}
4643

    
4644
/* srq */
4645
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4646
{
4647
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4648
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4649
    gen_op_POWER_srq();
4650
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4651
    if (unlikely(Rc(ctx->opcode) != 0))
4652
        gen_set_Rc0(ctx, cpu_T[0]);
4653
}
4654

    
4655
/* PowerPC 602 specific instructions */
4656
/* dsa  */
4657
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4658
{
4659
    /* XXX: TODO */
4660
    GEN_EXCP_INVAL(ctx);
4661
}
4662

    
4663
/* esa */
4664
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4665
{
4666
    /* XXX: TODO */
4667
    GEN_EXCP_INVAL(ctx);
4668
}
4669

    
4670
/* mfrom */
4671
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4672
{
4673
#if defined(CONFIG_USER_ONLY)
4674
    GEN_EXCP_PRIVOPC(ctx);
4675
#else
4676
    if (unlikely(!ctx->supervisor)) {
4677
        GEN_EXCP_PRIVOPC(ctx);
4678
        return;
4679
    }
4680
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4681
    gen_op_602_mfrom();
4682
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4683
#endif
4684
}
4685

    
4686
/* 602 - 603 - G2 TLB management */
4687
/* tlbld */
4688
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4689
{
4690
#if defined(CONFIG_USER_ONLY)
4691
    GEN_EXCP_PRIVOPC(ctx);
4692
#else
4693
    if (unlikely(!ctx->supervisor)) {
4694
        GEN_EXCP_PRIVOPC(ctx);
4695
        return;
4696
    }
4697
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4698
    gen_op_6xx_tlbld();
4699
#endif
4700
}
4701

    
4702
/* tlbli */
4703
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4704
{
4705
#if defined(CONFIG_USER_ONLY)
4706
    GEN_EXCP_PRIVOPC(ctx);
4707
#else
4708
    if (unlikely(!ctx->supervisor)) {
4709
        GEN_EXCP_PRIVOPC(ctx);
4710
        return;
4711
    }
4712
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4713
    gen_op_6xx_tlbli();
4714
#endif
4715
}
4716

    
4717
/* 74xx TLB management */
4718
/* tlbld */
4719
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4720
{
4721
#if defined(CONFIG_USER_ONLY)
4722
    GEN_EXCP_PRIVOPC(ctx);
4723
#else
4724
    if (unlikely(!ctx->supervisor)) {
4725
        GEN_EXCP_PRIVOPC(ctx);
4726
        return;
4727
    }
4728
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4729
    gen_op_74xx_tlbld();
4730
#endif
4731
}
4732

    
4733
/* tlbli */
4734
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4735
{
4736
#if defined(CONFIG_USER_ONLY)
4737
    GEN_EXCP_PRIVOPC(ctx);
4738
#else
4739
    if (unlikely(!ctx->supervisor)) {
4740
        GEN_EXCP_PRIVOPC(ctx);
4741
        return;
4742
    }
4743
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4744
    gen_op_74xx_tlbli();
4745
#endif
4746
}
4747

    
4748
/* POWER instructions not in PowerPC 601 */
4749
/* clf */
4750
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4751
{
4752
    /* Cache line flush: implemented as no-op */
4753
}
4754

    
4755
/* cli */
4756
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4757
{
4758
    /* Cache line invalidate: privileged and treated as no-op */
4759
#if defined(CONFIG_USER_ONLY)
4760
    GEN_EXCP_PRIVOPC(ctx);
4761
#else
4762
    if (unlikely(!ctx->supervisor)) {
4763
        GEN_EXCP_PRIVOPC(ctx);
4764
        return;
4765
    }
4766
#endif
4767
}
4768

    
4769
/* dclst */
4770
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4771
{
4772
    /* Data cache line store: treated as no-op */
4773
}
4774

    
4775
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4776
{
4777
#if defined(CONFIG_USER_ONLY)
4778
    GEN_EXCP_PRIVOPC(ctx);
4779
#else
4780
    if (unlikely(!ctx->supervisor)) {
4781
        GEN_EXCP_PRIVOPC(ctx);
4782
        return;
4783
    }
4784
    int ra = rA(ctx->opcode);
4785
    int rd = rD(ctx->opcode);
4786

    
4787
    gen_addr_reg_index(cpu_T[0], ctx);
4788
    gen_op_POWER_mfsri();
4789
    tcg_gen_mov_tl(cpu_gpr[rd], cpu_T[0]);
4790
    if (ra != 0 && ra != rd)
4791
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[1]);
4792
#endif
4793
}
4794

    
4795
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4796
{
4797
#if defined(CONFIG_USER_ONLY)
4798
    GEN_EXCP_PRIVOPC(ctx);
4799
#else
4800
    if (unlikely(!ctx->supervisor)) {
4801
        GEN_EXCP_PRIVOPC(ctx);
4802
        return;
4803
    }
4804
    gen_addr_reg_index(cpu_T[0], ctx);
4805
    gen_op_POWER_rac();
4806
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4807
#endif
4808
}
4809

    
4810
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4811
{
4812
#if defined(CONFIG_USER_ONLY)
4813
    GEN_EXCP_PRIVOPC(ctx);
4814
#else
4815
    if (unlikely(!ctx->supervisor)) {
4816
        GEN_EXCP_PRIVOPC(ctx);
4817
        return;
4818
    }
4819
    gen_op_POWER_rfsvc();
4820
    GEN_SYNC(ctx);
4821
#endif
4822
}
4823

    
4824
/* svc is not implemented for now */
4825

    
4826
/* POWER2 specific instructions */
4827
/* Quad manipulation (load/store two floats at a time) */
4828
/* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
4829
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4830
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4831
#define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
4832
#define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
4833
#define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
4834
#define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
4835
#define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
4836
#define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
4837
#define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
4838
#define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
4839
#define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
4840
#define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
4841
#define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
4842
#define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
4843
#define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
4844
#define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
4845
#define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
4846
#define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
4847
static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
4848
    GEN_MEM_FUNCS(POWER2_lfq),
4849
};
4850
static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
4851
    GEN_MEM_FUNCS(POWER2_stfq),
4852
};
4853

    
4854
/* lfq */
4855
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4856
{
4857
    /* NIP cannot be restored if the memory exception comes from an helper */
4858
    gen_update_nip(ctx, ctx->nip - 4);
4859
    gen_addr_imm_index(cpu_T[0], ctx, 0);
4860
    op_POWER2_lfq();
4861
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4862
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4863
}
4864

    
4865
/* lfqu */
4866
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4867
{
4868
    int ra = rA(ctx->opcode);
4869

    
4870
    /* NIP cannot be restored if the memory exception comes from an helper */
4871
    gen_update_nip(ctx, ctx->nip - 4);
4872
    gen_addr_imm_index(cpu_T[0], ctx, 0);
4873
    op_POWER2_lfq();
4874
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4875
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4876
    if (ra != 0)
4877
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4878
}
4879

    
4880
/* lfqux */
4881
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4882
{
4883
    int ra = rA(ctx->opcode);
4884

    
4885
    /* NIP cannot be restored if the memory exception comes from an helper */
4886
    gen_update_nip(ctx, ctx->nip - 4);
4887
    gen_addr_reg_index(cpu_T[0], ctx);
4888
    op_POWER2_lfq();
4889
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4890
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4891
    if (ra != 0)
4892
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4893
}
4894

    
4895
/* lfqx */
4896
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4897
{
4898
    /* NIP cannot be restored if the memory exception comes from an helper */
4899
    gen_update_nip(ctx, ctx->nip - 4);
4900
    gen_addr_reg_index(cpu_T[0], ctx);
4901
    op_POWER2_lfq();
4902
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4903
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4904
}
4905

    
4906
/* stfq */
4907
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4908
{
4909
    /* NIP cannot be restored if the memory exception comes from an helper */
4910
    gen_update_nip(ctx, ctx->nip - 4);
4911
    gen_addr_imm_index(cpu_T[0], ctx, 0);
4912
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4913
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4914
    op_POWER2_stfq();
4915
}
4916

    
4917
/* stfqu */
4918
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4919
{
4920
    int ra = rA(ctx->opcode);
4921

    
4922
    /* NIP cannot be restored if the memory exception comes from an helper */
4923
    gen_update_nip(ctx, ctx->nip - 4);
4924
    gen_addr_imm_index(cpu_T[0], ctx, 0);
4925
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4926
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4927
    op_POWER2_stfq();
4928
    if (ra != 0)
4929
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4930
}
4931

    
4932
/* stfqux */
4933
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4934
{
4935
    int ra = rA(ctx->opcode);
4936

    
4937
    /* NIP cannot be restored if the memory exception comes from an helper */
4938
    gen_update_nip(ctx, ctx->nip - 4);
4939
    gen_addr_reg_index(cpu_T[0], ctx);
4940
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4941
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4942
    op_POWER2_stfq();
4943
    if (ra != 0)
4944
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4945
}
4946

    
4947
/* stfqx */
4948
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4949
{
4950
    /* NIP cannot be restored if the memory exception comes from an helper */
4951
    gen_update_nip(ctx, ctx->nip - 4);
4952
    gen_addr_reg_index(cpu_T[0], ctx);
4953
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4954
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4955
    op_POWER2_stfq();
4956
}
4957

    
4958
/* BookE specific instructions */
4959
/* XXX: not implemented on 440 ? */
4960
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
4961
{
4962
    /* XXX: TODO */
4963
    GEN_EXCP_INVAL(ctx);
4964
}
4965

    
4966
/* XXX: not implemented on 440 ? */
4967
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
4968
{
4969
#if defined(CONFIG_USER_ONLY)
4970
    GEN_EXCP_PRIVOPC(ctx);
4971
#else
4972
    if (unlikely(!ctx->supervisor)) {
4973
        GEN_EXCP_PRIVOPC(ctx);
4974
        return;
4975
    }
4976
    gen_addr_reg_index(cpu_T[0], ctx);
4977
    /* Use the same micro-ops as for tlbie */
4978
#if defined(TARGET_PPC64)
4979
    if (ctx->sf_mode)
4980
        gen_op_tlbie_64();
4981
    else
4982
#endif
4983
        gen_op_tlbie();
4984
#endif
4985
}
4986

    
4987
/* All 405 MAC instructions are translated here */
4988
static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
4989
                                                int opc2, int opc3,
4990
                                                int ra, int rb, int rt, int Rc)
4991
{
4992
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[ra]);
4993
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]);
4994
    switch (opc3 & 0x0D) {
4995
    case 0x05:
4996
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4997
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4998
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4999
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5000
        /* mulchw - mulchw. */
5001
        gen_op_405_mulchw();
5002
        break;
5003
    case 0x04:
5004
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5005
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5006
        /* mulchwu - mulchwu. */
5007
        gen_op_405_mulchwu();
5008
        break;
5009
    case 0x01:
5010
        /* machhw    - machhw.    - machhwo   - machhwo.   */
5011
        /* machhws   - machhws.   - machhwso  - machhwso.  */
5012
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5013
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5014
        /* mulhhw - mulhhw. */
5015
        gen_op_405_mulhhw();
5016
        break;
5017
    case 0x00:
5018
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5019
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5020
        /* mulhhwu - mulhhwu. */
5021
        gen_op_405_mulhhwu();
5022
        break;
5023
    case 0x0D:
5024
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5025
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5026
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5027
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5028
        /* mullhw - mullhw. */
5029
        gen_op_405_mullhw();
5030
        break;
5031
    case 0x0C:
5032
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5033
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5034
        /* mullhwu - mullhwu. */
5035
        gen_op_405_mullhwu();
5036
        break;
5037
    }
5038
    if (opc2 & 0x02) {
5039
        /* nmultiply-and-accumulate (0x0E) */
5040
        gen_op_neg();
5041
    }
5042
    if (opc2 & 0x04) {
5043
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
5044
        tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rt]);
5045
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
5046
        gen_op_405_add_T0_T2();
5047
    }
5048
    if (opc3 & 0x10) {
5049
        /* Check overflow */
5050
        if (opc3 & 0x01)
5051
            gen_op_check_addo();
5052
        else
5053
            gen_op_405_check_ovu();
5054
    }
5055
    if (opc3 & 0x02) {
5056
        /* Saturate */
5057
        if (opc3 & 0x01)
5058
            gen_op_405_check_sat();
5059
        else
5060
            gen_op_405_check_satu();
5061
    }
5062
    tcg_gen_mov_tl(cpu_gpr[rt], cpu_T[0]);
5063
    if (unlikely(Rc) != 0) {
5064
        /* Update Rc0 */
5065
        gen_set_Rc0(ctx, cpu_T[0]);
5066
    }
5067
}
5068

    
5069
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
5070
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
5071
{                                                                             \
5072
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
5073
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
5074
}
5075

    
5076
/* macchw    - macchw.    */
5077
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
5078
/* macchwo   - macchwo.   */
5079
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
5080
/* macchws   - macchws.   */
5081
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
5082
/* macchwso  - macchwso.  */
5083
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
5084
/* macchwsu  - macchwsu.  */
5085
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
5086
/* macchwsuo - macchwsuo. */
5087
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
5088
/* macchwu   - macchwu.   */
5089
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
5090
/* macchwuo  - macchwuo.  */
5091
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
5092
/* machhw    - machhw.    */
5093
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
5094
/* machhwo   - machhwo.   */
5095
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
5096
/* machhws   - machhws.   */
5097
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
5098
/* machhwso  - machhwso.  */
5099
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
5100
/* machhwsu  - machhwsu.  */
5101
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
5102
/* machhwsuo - machhwsuo. */
5103
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
5104
/* machhwu   - machhwu.   */
5105
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
5106
/* machhwuo  - machhwuo.  */
5107
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
5108
/* maclhw    - maclhw.    */
5109
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
5110
/* maclhwo   - maclhwo.   */
5111
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
5112
/* maclhws   - maclhws.   */
5113
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
5114
/* maclhwso  - maclhwso.  */
5115
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
5116
/* maclhwu   - maclhwu.   */
5117
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
5118
/* maclhwuo  - maclhwuo.  */
5119
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
5120
/* maclhwsu  - maclhwsu.  */
5121
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
5122
/* maclhwsuo - maclhwsuo. */
5123
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
5124
/* nmacchw   - nmacchw.   */
5125
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
5126
/* nmacchwo  - nmacchwo.  */
5127
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
5128
/* nmacchws  - nmacchws.  */
5129
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
5130
/* nmacchwso - nmacchwso. */
5131
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
5132
/* nmachhw   - nmachhw.   */
5133
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
5134
/* nmachhwo  - nmachhwo.  */
5135
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
5136
/* nmachhws  - nmachhws.  */
5137
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
5138
/* nmachhwso - nmachhwso. */
5139
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
5140
/* nmaclhw   - nmaclhw.   */
5141
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
5142
/* nmaclhwo  - nmaclhwo.  */
5143
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
5144
/* nmaclhws  - nmaclhws.  */
5145
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
5146
/* nmaclhwso - nmaclhwso. */
5147
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
5148

    
5149
/* mulchw  - mulchw.  */
5150
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
5151
/* mulchwu - mulchwu. */
5152
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
5153
/* mulhhw  - mulhhw.  */
5154
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
5155
/* mulhhwu - mulhhwu. */
5156
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
5157
/* mullhw  - mullhw.  */
5158
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
5159
/* mullhwu - mullhwu. */
5160
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
5161

    
5162
/* mfdcr */
5163
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
5164
{
5165
#if defined(CONFIG_USER_ONLY)
5166
    GEN_EXCP_PRIVREG(ctx);
5167
#else
5168
    uint32_t dcrn = SPR(ctx->opcode);
5169

    
5170
    if (unlikely(!ctx->supervisor)) {
5171
        GEN_EXCP_PRIVREG(ctx);
5172
        return;
5173
    }
5174
    tcg_gen_movi_tl(cpu_T[0], dcrn);
5175
    gen_op_load_dcr();
5176
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5177
#endif
5178
}
5179

    
5180
/* mtdcr */
5181
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
5182
{
5183
#if defined(CONFIG_USER_ONLY)
5184
    GEN_EXCP_PRIVREG(ctx);
5185
#else
5186
    uint32_t dcrn = SPR(ctx->opcode);
5187

    
5188
    if (unlikely(!ctx->supervisor)) {
5189
        GEN_EXCP_PRIVREG(ctx);
5190
        return;
5191
    }
5192
    tcg_gen_movi_tl(cpu_T[0], dcrn);
5193
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5194
    gen_op_store_dcr();
5195
#endif
5196
}
5197

    
5198
/* mfdcrx */
5199
/* XXX: not implemented on 440 ? */
5200
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
5201
{
5202
#if defined(CONFIG_USER_ONLY)
5203
    GEN_EXCP_PRIVREG(ctx);
5204
#else
5205
    if (unlikely(!ctx->supervisor)) {
5206
        GEN_EXCP_PRIVREG(ctx);
5207
        return;
5208
    }
5209
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5210
    gen_op_load_dcr();
5211
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5212
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5213
#endif
5214
}
5215

    
5216
/* mtdcrx */
5217
/* XXX: not implemented on 440 ? */
5218
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
5219
{
5220
#if defined(CONFIG_USER_ONLY)
5221
    GEN_EXCP_PRIVREG(ctx);
5222
#else
5223
    if (unlikely(!ctx->supervisor)) {
5224
        GEN_EXCP_PRIVREG(ctx);
5225
        return;
5226
    }
5227
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5228
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5229
    gen_op_store_dcr();
5230
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5231
#endif
5232
}
5233

    
5234
/* mfdcrux (PPC 460) : user-mode access to DCR */
5235
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
5236
{
5237
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5238
    gen_op_load_dcr();
5239
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5240
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5241
}
5242

    
5243
/* mtdcrux (PPC 460) : user-mode access to DCR */
5244
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
5245
{
5246
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5247
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5248
    gen_op_store_dcr();
5249
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5250
}
5251

    
5252
/* dccci */
5253
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
5254
{
5255
#if defined(CONFIG_USER_ONLY)
5256
    GEN_EXCP_PRIVOPC(ctx);
5257
#else
5258
    if (unlikely(!ctx->supervisor)) {
5259
        GEN_EXCP_PRIVOPC(ctx);
5260
        return;
5261
    }
5262
    /* interpreted as no-op */
5263
#endif
5264
}
5265

    
5266
/* dcread */
5267
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
5268
{
5269
#if defined(CONFIG_USER_ONLY)
5270
    GEN_EXCP_PRIVOPC(ctx);
5271
#else
5272
    TCGv EA, val;
5273
    if (unlikely(!ctx->supervisor)) {
5274
        GEN_EXCP_PRIVOPC(ctx);
5275
        return;
5276
    }
5277
    EA = tcg_temp_new(TCG_TYPE_TL);
5278
    gen_addr_reg_index(EA, ctx);
5279
    val = tcg_temp_new(TCG_TYPE_TL);
5280
    gen_qemu_ld32u(val, EA, ctx->mem_idx);
5281
    tcg_temp_free(val);
5282
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
5283
    tcg_temp_free(EA);
5284
#endif
5285
}
5286

    
5287
/* icbt */
5288
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
5289
{
5290
    /* interpreted as no-op */
5291
    /* XXX: specification say this is treated as a load by the MMU
5292
     *      but does not generate any exception
5293
     */
5294
}
5295

    
5296
/* iccci */
5297
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
5298
{
5299
#if defined(CONFIG_USER_ONLY)
5300
    GEN_EXCP_PRIVOPC(ctx);
5301
#else
5302
    if (unlikely(!ctx->supervisor)) {
5303
        GEN_EXCP_PRIVOPC(ctx);
5304
        return;
5305
    }
5306
    /* interpreted as no-op */
5307
#endif
5308
}
5309

    
5310
/* icread */
5311
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
5312
{
5313
#if defined(CONFIG_USER_ONLY)
5314
    GEN_EXCP_PRIVOPC(ctx);
5315
#else
5316
    if (unlikely(!ctx->supervisor)) {
5317
        GEN_EXCP_PRIVOPC(ctx);
5318
        return;
5319
    }
5320
    /* interpreted as no-op */
5321
#endif
5322
}
5323

    
5324
/* rfci (supervisor only) */
5325
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
5326
{
5327
#if defined(CONFIG_USER_ONLY)
5328
    GEN_EXCP_PRIVOPC(ctx);
5329
#else
5330
    if (unlikely(!ctx->supervisor)) {
5331
        GEN_EXCP_PRIVOPC(ctx);
5332
        return;
5333
    }
5334
    /* Restore CPU state */
5335
    gen_op_40x_rfci();
5336
    GEN_SYNC(ctx);
5337
#endif
5338
}
5339

    
5340
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
5341
{
5342
#if defined(CONFIG_USER_ONLY)
5343
    GEN_EXCP_PRIVOPC(ctx);
5344
#else
5345
    if (unlikely(!ctx->supervisor)) {
5346
        GEN_EXCP_PRIVOPC(ctx);
5347
        return;
5348
    }
5349
    /* Restore CPU state */
5350
    gen_op_rfci();
5351
    GEN_SYNC(ctx);
5352
#endif
5353
}
5354

    
5355
/* BookE specific */
5356
/* XXX: not implemented on 440 ? */
5357
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
5358
{
5359
#if defined(CONFIG_USER_ONLY)
5360
    GEN_EXCP_PRIVOPC(ctx);
5361
#else
5362
    if (unlikely(!ctx->supervisor)) {
5363
        GEN_EXCP_PRIVOPC(ctx);
5364
        return;
5365
    }
5366
    /* Restore CPU state */
5367
    gen_op_rfdi();
5368
    GEN_SYNC(ctx);
5369
#endif
5370
}
5371

    
5372
/* XXX: not implemented on 440 ? */
5373
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
5374
{
5375
#if defined(CONFIG_USER_ONLY)
5376
    GEN_EXCP_PRIVOPC(ctx);
5377
#else
5378
    if (unlikely(!ctx->supervisor)) {
5379
        GEN_EXCP_PRIVOPC(ctx);
5380
        return;
5381
    }
5382
    /* Restore CPU state */
5383
    gen_op_rfmci();
5384
    GEN_SYNC(ctx);
5385
#endif
5386
}
5387

    
5388
/* TLB management - PowerPC 405 implementation */
5389
/* tlbre */
5390
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
5391
{
5392
#if defined(CONFIG_USER_ONLY)
5393
    GEN_EXCP_PRIVOPC(ctx);
5394
#else
5395
    if (unlikely(!ctx->supervisor)) {
5396
        GEN_EXCP_PRIVOPC(ctx);
5397
        return;
5398
    }
5399
    switch (rB(ctx->opcode)) {
5400
    case 0:
5401
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5402
        gen_op_4xx_tlbre_hi();
5403
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5404
        break;
5405
    case 1:
5406
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5407
        gen_op_4xx_tlbre_lo();
5408
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5409
        break;
5410
    default:
5411
        GEN_EXCP_INVAL(ctx);
5412
        break;
5413
    }
5414
#endif
5415
}
5416

    
5417
/* tlbsx - tlbsx. */
5418
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5419
{
5420
#if defined(CONFIG_USER_ONLY)
5421
    GEN_EXCP_PRIVOPC(ctx);
5422
#else
5423
    if (unlikely(!ctx->supervisor)) {
5424
        GEN_EXCP_PRIVOPC(ctx);
5425
        return;
5426
    }
5427
    gen_addr_reg_index(cpu_T[0], ctx);
5428
    gen_op_4xx_tlbsx();
5429
    if (Rc(ctx->opcode))
5430
        gen_op_4xx_tlbsx_check();
5431
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5432
#endif
5433
}
5434

    
5435
/* tlbwe */
5436
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5437
{
5438
#if defined(CONFIG_USER_ONLY)
5439
    GEN_EXCP_PRIVOPC(ctx);
5440
#else
5441
    if (unlikely(!ctx->supervisor)) {
5442
        GEN_EXCP_PRIVOPC(ctx);
5443
        return;
5444
    }
5445
    switch (rB(ctx->opcode)) {
5446
    case 0:
5447
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5448
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5449
        gen_op_4xx_tlbwe_hi();
5450
        break;
5451
    case 1:
5452
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5453
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5454
        gen_op_4xx_tlbwe_lo();
5455
        break;
5456
    default:
5457
        GEN_EXCP_INVAL(ctx);
5458
        break;
5459
    }
5460
#endif
5461
}
5462

    
5463
/* TLB management - PowerPC 440 implementation */
5464
/* tlbre */
5465
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5466
{
5467
#if defined(CONFIG_USER_ONLY)
5468
    GEN_EXCP_PRIVOPC(ctx);
5469
#else
5470
    if (unlikely(!ctx->supervisor)) {
5471
        GEN_EXCP_PRIVOPC(ctx);
5472
        return;
5473
    }
5474
    switch (rB(ctx->opcode)) {
5475
    case 0:
5476
    case 1:
5477
    case 2:
5478
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5479
        gen_op_440_tlbre(rB(ctx->opcode));
5480
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5481
        break;
5482
    default:
5483
        GEN_EXCP_INVAL(ctx);
5484
        break;
5485
    }
5486
#endif
5487
}
5488

    
5489
/* tlbsx - tlbsx. */
5490
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5491
{
5492
#if defined(CONFIG_USER_ONLY)
5493
    GEN_EXCP_PRIVOPC(ctx);
5494
#else
5495
    if (unlikely(!ctx->supervisor)) {
5496
        GEN_EXCP_PRIVOPC(ctx);
5497
        return;
5498
    }
5499
    gen_addr_reg_index(cpu_T[0], ctx);
5500
    gen_op_440_tlbsx();
5501
    if (Rc(ctx->opcode))
5502
        gen_op_4xx_tlbsx_check();
5503
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5504
#endif
5505
}
5506

    
5507
/* tlbwe */
5508
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5509
{
5510
#if defined(CONFIG_USER_ONLY)
5511
    GEN_EXCP_PRIVOPC(ctx);
5512
#else
5513
    if (unlikely(!ctx->supervisor)) {
5514
        GEN_EXCP_PRIVOPC(ctx);
5515
        return;
5516
    }
5517
    switch (rB(ctx->opcode)) {
5518
    case 0:
5519
    case 1:
5520
    case 2:
5521
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5522
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5523
        gen_op_440_tlbwe(rB(ctx->opcode));
5524
        break;
5525
    default:
5526
        GEN_EXCP_INVAL(ctx);
5527
        break;
5528
    }
5529
#endif
5530
}
5531

    
5532
/* wrtee */
5533
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
5534
{
5535
#if defined(CONFIG_USER_ONLY)
5536
    GEN_EXCP_PRIVOPC(ctx);
5537
#else
5538
    if (unlikely(!ctx->supervisor)) {
5539
        GEN_EXCP_PRIVOPC(ctx);
5540
        return;
5541
    }
5542
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rD(ctx->opcode)]);
5543
    gen_op_wrte();
5544
    /* Stop translation to have a chance to raise an exception
5545
     * if we just set msr_ee to 1
5546
     */
5547
    GEN_STOP(ctx);
5548
#endif
5549
}
5550

    
5551
/* wrteei */
5552
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
5553
{
5554
#if defined(CONFIG_USER_ONLY)
5555
    GEN_EXCP_PRIVOPC(ctx);
5556
#else
5557
    if (unlikely(!ctx->supervisor)) {
5558
        GEN_EXCP_PRIVOPC(ctx);
5559
        return;
5560
    }
5561
    tcg_gen_movi_tl(cpu_T[0], ctx->opcode & 0x00010000);
5562
    gen_op_wrte();
5563
    /* Stop translation to have a chance to raise an exception
5564
     * if we just set msr_ee to 1
5565
     */
5566
    GEN_STOP(ctx);
5567
#endif
5568
}
5569

    
5570
/* PowerPC 440 specific instructions */
5571
/* dlmzb */
5572
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5573
{
5574
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
5575
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
5576
    gen_op_440_dlmzb();
5577
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
5578
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
5579
    tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
5580
    if (Rc(ctx->opcode)) {
5581
        gen_op_440_dlmzb_update_Rc();
5582
        tcg_gen_andi_i32(cpu_crf[0], cpu_T[0], 0xf);
5583
    }
5584
}
5585

    
5586
/* mbar replaces eieio on 440 */
5587
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5588
{
5589
    /* interpreted as no-op */
5590
}
5591

    
5592
/* msync replaces sync on 440 */
5593
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5594
{
5595
    /* interpreted as no-op */
5596
}
5597

    
5598
/* icbt */
5599
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5600
{
5601
    /* interpreted as no-op */
5602
    /* XXX: specification say this is treated as a load by the MMU
5603
     *      but does not generate any exception
5604
     */
5605
}
5606

    
5607
/***                      Altivec vector extension                         ***/
5608
/* Altivec registers moves */
5609

    
5610
static always_inline void gen_load_avr(int t, int reg) {
5611
    tcg_gen_mov_i64(cpu_AVRh[t], cpu_avrh[reg]);
5612
    tcg_gen_mov_i64(cpu_AVRl[t], cpu_avrl[reg]);
5613
}
5614

    
5615
static always_inline void gen_store_avr(int reg, int t) {
5616
    tcg_gen_mov_i64(cpu_avrh[reg], cpu_AVRh[t]);
5617
    tcg_gen_mov_i64(cpu_avrl[reg], cpu_AVRl[t]);
5618
}
5619

    
5620
#define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5621
#define OP_VR_LD_TABLE(name)                                                  \
5622
static GenOpFunc *gen_op_vr_l##name[NB_MEM_FUNCS] = {                         \
5623
    GEN_MEM_FUNCS(vr_l##name),                                                \
5624
};
5625
#define OP_VR_ST_TABLE(name)                                                  \
5626
static GenOpFunc *gen_op_vr_st##name[NB_MEM_FUNCS] = {                        \
5627
    GEN_MEM_FUNCS(vr_st##name),                                               \
5628
};
5629

    
5630
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5631
GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
5632
{                                                                             \
5633
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5634
        GEN_EXCP_NO_VR(ctx);                                                  \
5635
        return;                                                               \
5636
    }                                                                         \
5637
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
5638
    op_vr_ldst(vr_l##name);                                                   \
5639
    gen_store_avr(rD(ctx->opcode), 0);                                        \
5640
}
5641

    
5642
#define GEN_VR_STX(name, opc2, opc3)                                          \
5643
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
5644
{                                                                             \
5645
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5646
        GEN_EXCP_NO_VR(ctx);                                                  \
5647
        return;                                                               \
5648
    }                                                                         \
5649
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
5650
    gen_load_avr(0, rS(ctx->opcode));                                         \
5651
    op_vr_ldst(vr_st##name);                                                  \
5652
}
5653

    
5654
OP_VR_LD_TABLE(vx);
5655
GEN_VR_LDX(vx, 0x07, 0x03);
5656
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
5657
#define gen_op_vr_lvxl gen_op_vr_lvx
5658
GEN_VR_LDX(vxl, 0x07, 0x0B);
5659

    
5660
OP_VR_ST_TABLE(vx);
5661
GEN_VR_STX(vx, 0x07, 0x07);
5662
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
5663
#define gen_op_vr_stvxl gen_op_vr_stvx
5664
GEN_VR_STX(vxl, 0x07, 0x0F);
5665

    
5666
/***                           SPE extension                               ***/
5667
/* Register moves */
5668

    
5669
static always_inline void gen_load_gpr64(TCGv t, int reg) {
5670
#if defined(TARGET_PPC64)
5671
    tcg_gen_mov_i64(t, cpu_gpr[reg]);
5672
#else
5673
    tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
5674
#endif
5675
}
5676

    
5677
static always_inline void gen_store_gpr64(int reg, TCGv t) {
5678
#if defined(TARGET_PPC64)
5679
    tcg_gen_mov_i64(cpu_gpr[reg], t);
5680
#else
5681
    tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
5682
    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
5683
    tcg_gen_shri_i64(tmp, t, 32);
5684
    tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
5685
    tcg_temp_free(tmp);
5686
#endif
5687
}
5688

    
5689
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5690
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5691
{                                                                             \
5692
    if (Rc(ctx->opcode))                                                      \
5693
        gen_##name1(ctx);                                                     \
5694
    else                                                                      \
5695
        gen_##name0(ctx);                                                     \
5696
}
5697

    
5698
/* Handler for undefined SPE opcodes */
5699
static always_inline void gen_speundef (DisasContext *ctx)
5700
{
5701
    GEN_EXCP_INVAL(ctx);
5702
}
5703

    
5704
/* SPE load and stores */
5705
static always_inline void gen_addr_spe_imm_index (TCGv EA, DisasContext *ctx, int sh)
5706
{
5707
    target_long simm = rB(ctx->opcode);
5708

    
5709
    if (rA(ctx->opcode) == 0)
5710
        tcg_gen_movi_tl(EA, simm << sh);
5711
    else if (likely(simm != 0))
5712
        tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm << sh);
5713
    else
5714
        tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
5715
}
5716

    
5717
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5718
#define OP_SPE_LD_TABLE(name)                                                 \
5719
static GenOpFunc *gen_op_spe_l##name[NB_MEM_FUNCS] = {                        \
5720
    GEN_MEM_FUNCS(spe_l##name),                                               \
5721
};
5722
#define OP_SPE_ST_TABLE(name)                                                 \
5723
static GenOpFunc *gen_op_spe_st##name[NB_MEM_FUNCS] = {                       \
5724
    GEN_MEM_FUNCS(spe_st##name),                                              \
5725
};
5726

    
5727
#define GEN_SPE_LD(name, sh)                                                  \
5728
static always_inline void gen_evl##name (DisasContext *ctx)                   \
5729
{                                                                             \
5730
    if (unlikely(!ctx->spe_enabled)) {                                        \
5731
        GEN_EXCP_NO_AP(ctx);                                                  \
5732
        return;                                                               \
5733
    }                                                                         \
5734
    gen_addr_spe_imm_index(cpu_T[0], ctx, sh);                                \
5735
    op_spe_ldst(spe_l##name);                                                 \
5736
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[1]);                             \
5737
}
5738

    
5739
#define GEN_SPE_LDX(name)                                                     \
5740
static always_inline void gen_evl##name##x (DisasContext *ctx)                \
5741
{                                                                             \
5742
    if (unlikely(!ctx->spe_enabled)) {                                        \
5743
        GEN_EXCP_NO_AP(ctx);                                                  \
5744
        return;                                                               \
5745
    }                                                                         \
5746
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
5747
    op_spe_ldst(spe_l##name);                                                 \
5748
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[1]);                             \
5749
}
5750

    
5751
#define GEN_SPEOP_LD(name, sh)                                                \
5752
OP_SPE_LD_TABLE(name);                                                        \
5753
GEN_SPE_LD(name, sh);                                                         \
5754
GEN_SPE_LDX(name)
5755

    
5756
#define GEN_SPE_ST(name, sh)                                                  \
5757
static always_inline void gen_evst##name (DisasContext *ctx)                  \
5758
{                                                                             \
5759
    if (unlikely(!ctx->spe_enabled)) {                                        \
5760
        GEN_EXCP_NO_AP(ctx);                                                  \
5761
        return;                                                               \
5762
    }                                                                         \
5763
    gen_addr_spe_imm_index(cpu_T[0], ctx, sh);                                \
5764
    gen_load_gpr64(cpu_T64[1], rS(ctx->opcode));                              \
5765
    op_spe_ldst(spe_st##name);                                                \
5766
}
5767

    
5768
#define GEN_SPE_STX(name)                                                     \
5769
static always_inline void gen_evst##name##x (DisasContext *ctx)               \
5770
{                                                                             \
5771
    if (unlikely(!ctx->spe_enabled)) {                                        \
5772
        GEN_EXCP_NO_AP(ctx);                                                  \
5773
        return;                                                               \
5774
    }                                                                         \
5775
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
5776
    gen_load_gpr64(cpu_T64[1], rS(ctx->opcode));                              \
5777
    op_spe_ldst(spe_st##name);                                                \
5778
}
5779

    
5780
#define GEN_SPEOP_ST(name, sh)                                                \
5781
OP_SPE_ST_TABLE(name);                                                        \
5782
GEN_SPE_ST(name, sh);                                                         \
5783
GEN_SPE_STX(name)
5784

    
5785
#define GEN_SPEOP_LDST(name, sh)                                              \
5786
GEN_SPEOP_LD(name, sh);                                                       \
5787
GEN_SPEOP_ST(name, sh)
5788

    
5789
/* SPE arithmetic and logic */
5790
#define GEN_SPEOP_ARITH2(name)                                                \
5791
static always_inline void gen_##name (DisasContext *ctx)                      \
5792
{                                                                             \
5793
    if (unlikely(!ctx->spe_enabled)) {                                        \
5794
        GEN_EXCP_NO_AP(ctx);                                                  \
5795
        return;                                                               \
5796
    }                                                                         \
5797
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5798
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
5799
    gen_op_##name();                                                          \
5800
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5801
}
5802

    
5803
#define GEN_SPEOP_TCG_ARITH2(name, tcg_op)                                    \
5804
static always_inline void gen_##name (DisasContext *ctx)                      \
5805
{                                                                             \
5806
    if (unlikely(!ctx->spe_enabled)) {                                        \
5807
        GEN_EXCP_NO_AP(ctx);                                                  \
5808
        return;                                                               \
5809
    }                                                                         \
5810
    TCGv t0 = tcg_temp_new(TCG_TYPE_I64);                                     \
5811
    TCGv t1 = tcg_temp_new(TCG_TYPE_I64);                                     \
5812
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
5813
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
5814
    tcg_op(t0, t0, t1);                                                       \
5815
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
5816
    tcg_temp_free(t0);                                                        \
5817
    tcg_temp_free(t1);                                                        \
5818
}
5819

    
5820
#define GEN_SPEOP_ARITH1(name)                                                \
5821
static always_inline void gen_##name (DisasContext *ctx)                      \
5822
{                                                                             \
5823
    if (unlikely(!ctx->spe_enabled)) {                                        \
5824
        GEN_EXCP_NO_AP(ctx);                                                  \
5825
        return;                                                               \
5826
    }                                                                         \
5827
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5828
    gen_op_##name();                                                          \
5829
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5830
}
5831

    
5832
#define GEN_SPEOP_COMP(name)                                                  \
5833
static always_inline void gen_##name (DisasContext *ctx)                      \
5834
{                                                                             \
5835
    if (unlikely(!ctx->spe_enabled)) {                                        \
5836
        GEN_EXCP_NO_AP(ctx);                                                  \
5837
        return;                                                               \
5838
    }                                                                         \
5839
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5840
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
5841
    gen_op_##name();                                                          \
5842
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);              \
5843
}
5844

    
5845
/* Logical */
5846
GEN_SPEOP_TCG_ARITH2(evand, tcg_gen_and_i64);
5847
GEN_SPEOP_TCG_ARITH2(evandc, tcg_gen_andc_i64);
5848
GEN_SPEOP_TCG_ARITH2(evxor, tcg_gen_xor_i64);
5849
GEN_SPEOP_TCG_ARITH2(evor, tcg_gen_or_i64);
5850
GEN_SPEOP_TCG_ARITH2(evnor, tcg_gen_nor_i64);
5851
GEN_SPEOP_TCG_ARITH2(eveqv, tcg_gen_eqv_i64);
5852
GEN_SPEOP_TCG_ARITH2(evorc, tcg_gen_orc_i64);
5853
GEN_SPEOP_TCG_ARITH2(evnand, tcg_gen_nand_i64);
5854
GEN_SPEOP_ARITH2(evsrwu);
5855
GEN_SPEOP_ARITH2(evsrws);
5856
GEN_SPEOP_ARITH2(evslw);
5857
GEN_SPEOP_ARITH2(evrlw);
5858
GEN_SPEOP_ARITH2(evmergehi);
5859
GEN_SPEOP_ARITH2(evmergelo);
5860
GEN_SPEOP_ARITH2(evmergehilo);
5861
GEN_SPEOP_ARITH2(evmergelohi);
5862

    
5863
/* Arithmetic */
5864
GEN_SPEOP_ARITH2(evaddw);
5865
GEN_SPEOP_ARITH2(evsubfw);
5866
GEN_SPEOP_ARITH1(evabs);
5867
GEN_SPEOP_ARITH1(evneg);
5868
GEN_SPEOP_ARITH1(evextsb);
5869
GEN_SPEOP_ARITH1(evextsh);
5870
GEN_SPEOP_ARITH1(evrndw);
5871
GEN_SPEOP_ARITH1(evcntlzw);
5872
GEN_SPEOP_ARITH1(evcntlsw);
5873
static always_inline void gen_brinc (DisasContext *ctx)
5874
{
5875
    /* Note: brinc is usable even if SPE is disabled */
5876
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5877
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
5878
    gen_op_brinc();
5879
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5880
}
5881

    
5882
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5883
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5884
{                                                                             \
5885
    if (unlikely(!ctx->spe_enabled)) {                                        \
5886
        GEN_EXCP_NO_AP(ctx);                                                  \
5887
        return;                                                               \
5888
    }                                                                         \
5889
    gen_load_gpr64(cpu_T64[0], rB(ctx->opcode));                              \
5890
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5891
    gen_op_##name();                                                          \
5892
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5893
}
5894

    
5895
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5896
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5897
{                                                                             \
5898
    if (unlikely(!ctx->spe_enabled)) {                                        \
5899
        GEN_EXCP_NO_AP(ctx);                                                  \
5900
        return;                                                               \
5901
    }                                                                         \
5902
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5903
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5904
    gen_op_##name();                                                          \
5905
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5906
}
5907

    
5908
GEN_SPEOP_ARITH_IMM2(evaddw);
5909
#define gen_evaddiw gen_evaddwi
5910
GEN_SPEOP_ARITH_IMM2(evsubfw);
5911
#define gen_evsubifw gen_evsubfwi
5912
GEN_SPEOP_LOGIC_IMM2(evslw);
5913
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5914
#define gen_evsrwis gen_evsrwsi
5915
GEN_SPEOP_LOGIC_IMM2(evsrws);
5916
#define gen_evsrwiu gen_evsrwui
5917
GEN_SPEOP_LOGIC_IMM2(evrlw);
5918

    
5919
static always_inline void gen_evsplati (DisasContext *ctx)
5920
{
5921
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5922

    
5923
    gen_op_splatwi_T0_64(imm);
5924
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
5925
}
5926

    
5927
static always_inline void gen_evsplatfi (DisasContext *ctx)
5928
{
5929
    uint32_t imm = rA(ctx->opcode) << 27;
5930

    
5931
    gen_op_splatwi_T0_64(imm);
5932
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
5933
}
5934

    
5935
/* Comparison */
5936
GEN_SPEOP_COMP(evcmpgtu);
5937
GEN_SPEOP_COMP(evcmpgts);
5938
GEN_SPEOP_COMP(evcmpltu);
5939
GEN_SPEOP_COMP(evcmplts);
5940
GEN_SPEOP_COMP(evcmpeq);
5941

    
5942
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5943
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5944
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5945
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5946
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5947
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5948
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5949
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5950
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5951
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5952
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5953
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5954
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5955
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5956
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5957
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5958
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5959
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5960
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5961
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5962
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5963
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5964
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5965
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5966
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5967

    
5968
static always_inline void gen_evsel (DisasContext *ctx)
5969
{
5970
    if (unlikely(!ctx->spe_enabled)) {
5971
        GEN_EXCP_NO_AP(ctx);
5972
        return;
5973
    }
5974
    tcg_gen_mov_i32(cpu_T[0], cpu_crf[ctx->opcode & 0x7]);
5975
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));
5976
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));
5977
    gen_op_evsel();
5978
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
5979
}
5980

    
5981
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5982
{
5983
    gen_evsel(ctx);
5984
}
5985
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5986
{
5987
    gen_evsel(ctx);
5988
}
5989
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5990
{
5991
    gen_evsel(ctx);
5992
}
5993
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5994
{
5995
    gen_evsel(ctx);
5996
}
5997

    
5998
/* Load and stores */
5999
GEN_SPEOP_LDST(dd, 3);
6000
GEN_SPEOP_LDST(dw, 3);
6001
GEN_SPEOP_LDST(dh, 3);
6002
GEN_SPEOP_LDST(whe, 2);
6003
GEN_SPEOP_LD(whou, 2);
6004
GEN_SPEOP_LD(whos, 2);
6005
GEN_SPEOP_ST(who, 2);
6006

    
6007
#define _GEN_OP_SPE_STWWE(suffix)                                             \
6008
static always_inline void gen_op_spe_stwwe_##suffix (void)                    \
6009
{                                                                             \
6010
    gen_op_srli32_T1_64();                                                    \
6011
    gen_op_spe_stwwo_##suffix();                                              \
6012
}
6013
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
6014
static always_inline void gen_op_spe_stwwe_le_##suffix (void)                 \
6015
{                                                                             \
6016
    gen_op_srli32_T1_64();                                                    \
6017
    gen_op_spe_stwwo_le_##suffix();                                           \
6018
}
6019
#if defined(TARGET_PPC64)
6020
#define GEN_OP_SPE_STWWE(suffix)                                              \
6021
_GEN_OP_SPE_STWWE(suffix);                                                    \
6022
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
6023
static always_inline void gen_op_spe_stwwe_64_##suffix (void)                 \
6024
{                                                                             \
6025
    gen_op_srli32_T1_64();                                                    \
6026
    gen_op_spe_stwwo_64_##suffix();                                           \
6027
}                                                                             \
6028
static always_inline void gen_op_spe_stwwe_le_64_##suffix (void)              \
6029
{                                                                             \
6030
    gen_op_srli32_T1_64();                                                    \
6031
    gen_op_spe_stwwo_le_64_##suffix();                                        \
6032
}
6033
#else
6034
#define GEN_OP_SPE_STWWE(suffix)                                              \
6035
_GEN_OP_SPE_STWWE(suffix);                                                    \
6036
_GEN_OP_SPE_STWWE_LE(suffix)
6037
#endif
6038
#if defined(CONFIG_USER_ONLY)
6039
GEN_OP_SPE_STWWE(raw);
6040
#else /* defined(CONFIG_USER_ONLY) */
6041
GEN_OP_SPE_STWWE(user);
6042
GEN_OP_SPE_STWWE(kernel);
6043
GEN_OP_SPE_STWWE(hypv);
6044
#endif /* defined(CONFIG_USER_ONLY) */
6045
GEN_SPEOP_ST(wwe, 2);
6046
GEN_SPEOP_ST(wwo, 2);
6047

    
6048
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
6049
static always_inline void gen_op_spe_l##name##_##suffix (void)                \
6050
{                                                                             \
6051
    gen_op_##op##_##suffix();                                                 \
6052
    gen_op_splatw_T1_64();                                                    \
6053
}
6054

    
6055
#define GEN_OP_SPE_LHE(suffix)                                                \
6056
static always_inline void gen_op_spe_lhe_##suffix (void)                      \
6057
{                                                                             \
6058
    gen_op_spe_lh_##suffix();                                                 \
6059
    gen_op_sli16_T1_64();                                                     \
6060
}
6061

    
6062
#define GEN_OP_SPE_LHX(suffix)                                                \
6063
static always_inline void gen_op_spe_lhx_##suffix (void)                      \
6064
{                                                                             \
6065
    gen_op_spe_lh_##suffix();                                                 \
6066
    gen_op_extsh_T1_64();                                                     \
6067
}
6068

    
6069
#if defined(CONFIG_USER_ONLY)
6070
GEN_OP_SPE_LHE(raw);
6071
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
6072
GEN_OP_SPE_LHE(le_raw);
6073
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
6074
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
6075
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
6076
GEN_OP_SPE_LHX(raw);
6077
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
6078
GEN_OP_SPE_LHX(le_raw);
6079
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
6080
#if defined(TARGET_PPC64)
6081
GEN_OP_SPE_LHE(64_raw);
6082
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
6083
GEN_OP_SPE_LHE(le_64_raw);
6084
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
6085
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
6086
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
6087
GEN_OP_SPE_LHX(64_raw);
6088
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
6089
GEN_OP_SPE_LHX(le_64_raw);
6090
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
6091
#endif
6092
#else
6093
GEN_OP_SPE_LHE(user);
6094
GEN_OP_SPE_LHE(kernel);
6095
GEN_OP_SPE_LHE(hypv);
6096
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
6097
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
6098
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv);
6099
GEN_OP_SPE_LHE(le_user);
6100
GEN_OP_SPE_LHE(le_kernel);
6101
GEN_OP_SPE_LHE(le_hypv);
6102
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
6103
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
6104
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv);
6105
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
6106
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
6107
GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv);
6108
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
6109
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
6110
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv);
6111
GEN_OP_SPE_LHX(user);
6112
GEN_OP_SPE_LHX(kernel);
6113
GEN_OP_SPE_LHX(hypv);
6114
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
6115
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
6116
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv);
6117
GEN_OP_SPE_LHX(le_user);
6118
GEN_OP_SPE_LHX(le_kernel);
6119
GEN_OP_SPE_LHX(le_hypv);
6120
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
6121
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
6122
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv);
6123
#if defined(TARGET_PPC64)
6124
GEN_OP_SPE_LHE(64_user);
6125
GEN_OP_SPE_LHE(64_kernel);
6126
GEN_OP_SPE_LHE(64_hypv);
6127
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
6128
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
6129
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv);
6130
GEN_OP_SPE_LHE(le_64_user);
6131
GEN_OP_SPE_LHE(le_64_kernel);
6132
GEN_OP_SPE_LHE(le_64_hypv);
6133
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
6134
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
6135
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv);
6136
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
6137
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
6138
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv);
6139
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
6140
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
6141
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv);
6142
GEN_OP_SPE_LHX(64_user);
6143
GEN_OP_SPE_LHX(64_kernel);
6144
GEN_OP_SPE_LHX(64_hypv);
6145
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
6146
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
6147
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv);
6148
GEN_OP_SPE_LHX(le_64_user);
6149
GEN_OP_SPE_LHX(le_64_kernel);
6150
GEN_OP_SPE_LHX(le_64_hypv);
6151
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
6152
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
6153
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv);
6154
#endif
6155
#endif
6156
GEN_SPEOP_LD(hhesplat, 1);
6157
GEN_SPEOP_LD(hhousplat, 1);
6158
GEN_SPEOP_LD(hhossplat, 1);
6159
GEN_SPEOP_LD(wwsplat, 2);
6160
GEN_SPEOP_LD(whsplat, 2);
6161

    
6162
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
6163
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
6164
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
6165
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
6166
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
6167
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
6168
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
6169
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
6170
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
6171
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
6172
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
6173
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
6174
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
6175
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
6176
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
6177
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
6178
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
6179
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
6180

    
6181
/* Multiply and add - TODO */
6182
#if 0
6183
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
6184
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
6185
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
6186
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
6187
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
6188
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
6189
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
6190
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
6191
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
6192
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
6193
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
6194
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
6195

6196
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
6197
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
6198
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
6199
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
6200
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
6201
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
6202
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
6203
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
6204
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
6205
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
6206
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
6207
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
6208
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
6209
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
6210

6211
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
6212
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
6213
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
6214
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
6215
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
6216
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
6217

6218
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
6219
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
6220
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
6221
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
6222
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
6223
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
6224
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
6225
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
6226
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
6227
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
6228
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
6229
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
6230

6231
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
6232
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
6233
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
6234
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
6235
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
6236

6237
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
6238
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
6239
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
6240
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
6241
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
6242
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
6243
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
6244
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
6245
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
6246
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
6247
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
6248
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
6249

6250
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
6251
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
6252
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
6253
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
6254
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
6255
#endif
6256

    
6257
/***                      SPE floating-point extension                     ***/
6258
#define GEN_SPEFPUOP_CONV(name)                                               \
6259
static always_inline void gen_##name (DisasContext *ctx)                      \
6260
{                                                                             \
6261
    gen_load_gpr64(cpu_T64[0], rB(ctx->opcode));                              \
6262
    gen_op_##name();                                                          \
6263
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
6264
}
6265

    
6266
/* Single precision floating-point vectors operations */
6267
/* Arithmetic */
6268
GEN_SPEOP_ARITH2(evfsadd);
6269
GEN_SPEOP_ARITH2(evfssub);
6270
GEN_SPEOP_ARITH2(evfsmul);
6271
GEN_SPEOP_ARITH2(evfsdiv);
6272
GEN_SPEOP_ARITH1(evfsabs);
6273
GEN_SPEOP_ARITH1(evfsnabs);
6274
GEN_SPEOP_ARITH1(evfsneg);
6275
/* Conversion */
6276
GEN_SPEFPUOP_CONV(evfscfui);
6277
GEN_SPEFPUOP_CONV(evfscfsi);
6278
GEN_SPEFPUOP_CONV(evfscfuf);
6279
GEN_SPEFPUOP_CONV(evfscfsf);
6280
GEN_SPEFPUOP_CONV(evfsctui);
6281
GEN_SPEFPUOP_CONV(evfsctsi);
6282
GEN_SPEFPUOP_CONV(evfsctuf);
6283
GEN_SPEFPUOP_CONV(evfsctsf);
6284
GEN_SPEFPUOP_CONV(evfsctuiz);
6285
GEN_SPEFPUOP_CONV(evfsctsiz);
6286
/* Comparison */
6287
GEN_SPEOP_COMP(evfscmpgt);
6288
GEN_SPEOP_COMP(evfscmplt);
6289
GEN_SPEOP_COMP(evfscmpeq);
6290
GEN_SPEOP_COMP(evfststgt);
6291
GEN_SPEOP_COMP(evfststlt);
6292
GEN_SPEOP_COMP(evfststeq);
6293

    
6294
/* Opcodes definitions */
6295
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
6296
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
6297
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
6298
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
6299
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
6300
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
6301
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
6302
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
6303
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
6304
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
6305
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
6306
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
6307
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
6308
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
6309

    
6310
/* Single precision floating-point operations */
6311
/* Arithmetic */
6312
GEN_SPEOP_ARITH2(efsadd);
6313
GEN_SPEOP_ARITH2(efssub);
6314
GEN_SPEOP_ARITH2(efsmul);
6315
GEN_SPEOP_ARITH2(efsdiv);
6316
GEN_SPEOP_ARITH1(efsabs);
6317
GEN_SPEOP_ARITH1(efsnabs);
6318
GEN_SPEOP_ARITH1(efsneg);
6319
/* Conversion */
6320
GEN_SPEFPUOP_CONV(efscfui);
6321
GEN_SPEFPUOP_CONV(efscfsi);
6322
GEN_SPEFPUOP_CONV(efscfuf);
6323
GEN_SPEFPUOP_CONV(efscfsf);
6324
GEN_SPEFPUOP_CONV(efsctui);
6325
GEN_SPEFPUOP_CONV(efsctsi);
6326
GEN_SPEFPUOP_CONV(efsctuf);
6327
GEN_SPEFPUOP_CONV(efsctsf);
6328
GEN_SPEFPUOP_CONV(efsctuiz);
6329
GEN_SPEFPUOP_CONV(efsctsiz);
6330
GEN_SPEFPUOP_CONV(efscfd);
6331
/* Comparison */
6332
GEN_SPEOP_COMP(efscmpgt);
6333
GEN_SPEOP_COMP(efscmplt);
6334
GEN_SPEOP_COMP(efscmpeq);
6335
GEN_SPEOP_COMP(efststgt);
6336
GEN_SPEOP_COMP(efststlt);
6337
GEN_SPEOP_COMP(efststeq);
6338

    
6339
/* Opcodes definitions */
6340
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
6341
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
6342
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
6343
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
6344
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
6345
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
6346
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
6347
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
6348
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
6349
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
6350
GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
6351
GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPEFPU); //
6352
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
6353
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
6354

    
6355
/* Double precision floating-point operations */
6356
/* Arithmetic */
6357
GEN_SPEOP_ARITH2(efdadd);
6358
GEN_SPEOP_ARITH2(efdsub);
6359
GEN_SPEOP_ARITH2(efdmul);
6360
GEN_SPEOP_ARITH2(efddiv);
6361
GEN_SPEOP_ARITH1(efdabs);
6362
GEN_SPEOP_ARITH1(efdnabs);
6363
GEN_SPEOP_ARITH1(efdneg);
6364
/* Conversion */
6365

    
6366
GEN_SPEFPUOP_CONV(efdcfui);
6367
GEN_SPEFPUOP_CONV(efdcfsi);
6368
GEN_SPEFPUOP_CONV(efdcfuf);
6369
GEN_SPEFPUOP_CONV(efdcfsf);
6370
GEN_SPEFPUOP_CONV(efdctui);
6371
GEN_SPEFPUOP_CONV(efdctsi);
6372
GEN_SPEFPUOP_CONV(efdctuf);
6373
GEN_SPEFPUOP_CONV(efdctsf);
6374
GEN_SPEFPUOP_CONV(efdctuiz);
6375
GEN_SPEFPUOP_CONV(efdctsiz);
6376
GEN_SPEFPUOP_CONV(efdcfs);
6377
GEN_SPEFPUOP_CONV(efdcfuid);
6378
GEN_SPEFPUOP_CONV(efdcfsid);
6379
GEN_SPEFPUOP_CONV(efdctuidz);
6380
GEN_SPEFPUOP_CONV(efdctsidz);
6381
/* Comparison */
6382
GEN_SPEOP_COMP(efdcmpgt);
6383
GEN_SPEOP_COMP(efdcmplt);
6384
GEN_SPEOP_COMP(efdcmpeq);
6385
GEN_SPEOP_COMP(efdtstgt);
6386
GEN_SPEOP_COMP(efdtstlt);
6387
GEN_SPEOP_COMP(efdtsteq);
6388

    
6389
/* Opcodes definitions */
6390
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
6391
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
6392
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
6393
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
6394
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
6395
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
6396
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
6397
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
6398
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
6399
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
6400
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
6401
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
6402
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
6403
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
6404
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
6405
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6406

    
6407
/* End opcode list */
6408
GEN_OPCODE_MARK(end);
6409

    
6410
#include "translate_init.c"
6411
#include "helper_regs.h"
6412

    
6413
/*****************************************************************************/
6414
/* Misc PowerPC helpers */
6415
void cpu_dump_state (CPUState *env, FILE *f,
6416
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6417
                     int flags)
6418
{
6419
#define RGPL  4
6420
#define RFPL  4
6421

    
6422
    int i;
6423

    
6424
    cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
6425
                env->nip, env->lr, env->ctr, env->xer);
6426
    cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
6427
                env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
6428
#if !defined(NO_TIMER_DUMP)
6429
    cpu_fprintf(f, "TB %08x %08x "
6430
#if !defined(CONFIG_USER_ONLY)
6431
                "DECR %08x"
6432
#endif
6433
                "\n",
6434
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6435
#if !defined(CONFIG_USER_ONLY)
6436
                , cpu_ppc_load_decr(env)
6437
#endif
6438
                );
6439
#endif
6440
    for (i = 0; i < 32; i++) {
6441
        if ((i & (RGPL - 1)) == 0)
6442
            cpu_fprintf(f, "GPR%02d", i);
6443
        cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
6444
        if ((i & (RGPL - 1)) == (RGPL - 1))
6445
            cpu_fprintf(f, "\n");
6446
    }
6447
    cpu_fprintf(f, "CR ");
6448
    for (i = 0; i < 8; i++)
6449
        cpu_fprintf(f, "%01x", env->crf[i]);
6450
    cpu_fprintf(f, "  [");
6451
    for (i = 0; i < 8; i++) {
6452
        char a = '-';
6453
        if (env->crf[i] & 0x08)
6454
            a = 'L';
6455
        else if (env->crf[i] & 0x04)
6456
            a = 'G';
6457
        else if (env->crf[i] & 0x02)
6458
            a = 'E';
6459
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6460
    }
6461
    cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
6462
    for (i = 0; i < 32; i++) {
6463
        if ((i & (RFPL - 1)) == 0)
6464
            cpu_fprintf(f, "FPR%02d", i);
6465
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6466
        if ((i & (RFPL - 1)) == (RFPL - 1))
6467
            cpu_fprintf(f, "\n");
6468
    }
6469
#if !defined(CONFIG_USER_ONLY)
6470
    cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
6471
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6472
#endif
6473

    
6474
#undef RGPL
6475
#undef RFPL
6476
}
6477

    
6478
void cpu_dump_statistics (CPUState *env, FILE*f,
6479
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6480
                          int flags)
6481
{
6482
#if defined(DO_PPC_STATISTICS)
6483
    opc_handler_t **t1, **t2, **t3, *handler;
6484
    int op1, op2, op3;
6485

    
6486
    t1 = env->opcodes;
6487
    for (op1 = 0; op1 < 64; op1++) {
6488
        handler = t1[op1];
6489
        if (is_indirect_opcode(handler)) {
6490
            t2 = ind_table(handler);
6491
            for (op2 = 0; op2 < 32; op2++) {
6492
                handler = t2[op2];
6493
                if (is_indirect_opcode(handler)) {
6494
                    t3 = ind_table(handler);
6495
                    for (op3 = 0; op3 < 32; op3++) {
6496
                        handler = t3[op3];
6497
                        if (handler->count == 0)
6498
                            continue;
6499
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6500
                                    "%016llx %lld\n",
6501
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6502
                                    handler->oname,
6503
                                    handler->count, handler->count);
6504
                    }
6505
                } else {
6506
                    if (handler->count == 0)
6507
                        continue;
6508
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6509
                                "%016llx %lld\n",
6510
                                op1, op2, op1, op2, handler->oname,
6511
                                handler->count, handler->count);
6512
                }
6513
            }
6514
        } else {
6515
            if (handler->count == 0)
6516
                continue;
6517
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6518
                        op1, op1, handler->oname,
6519
                        handler->count, handler->count);
6520
        }
6521
    }
6522
#endif
6523
}
6524

    
6525
/*****************************************************************************/
6526
static always_inline void gen_intermediate_code_internal (CPUState *env,
6527
                                                          TranslationBlock *tb,
6528
                                                          int search_pc)
6529
{
6530
    DisasContext ctx, *ctxp = &ctx;
6531
    opc_handler_t **table, *handler;
6532
    target_ulong pc_start;
6533
    uint16_t *gen_opc_end;
6534
    int supervisor, little_endian;
6535
    int j, lj = -1;
6536
    int num_insns;
6537
    int max_insns;
6538

    
6539
    pc_start = tb->pc;
6540
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6541
#if defined(OPTIMIZE_FPRF_UPDATE)
6542
    gen_fprf_ptr = gen_fprf_buf;
6543
#endif
6544
    ctx.nip = pc_start;
6545
    ctx.tb = tb;
6546
    ctx.exception = POWERPC_EXCP_NONE;
6547
    ctx.spr_cb = env->spr_cb;
6548
    supervisor = env->mmu_idx;
6549
#if !defined(CONFIG_USER_ONLY)
6550
    ctx.supervisor = supervisor;
6551
#endif
6552
    little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
6553
#if defined(TARGET_PPC64)
6554
    ctx.sf_mode = msr_sf;
6555
    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
6556
#else
6557
    ctx.mem_idx = (supervisor << 1) | little_endian;
6558
#endif
6559
    ctx.dcache_line_size = env->dcache_line_size;
6560
    ctx.fpu_enabled = msr_fp;
6561
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
6562
        ctx.spe_enabled = msr_spe;
6563
    else
6564
        ctx.spe_enabled = 0;
6565
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
6566
        ctx.altivec_enabled = msr_vr;
6567
    else
6568
        ctx.altivec_enabled = 0;
6569
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6570
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
6571
    else
6572
        ctx.singlestep_enabled = 0;
6573
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
6574
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
6575
    if (unlikely(env->singlestep_enabled))
6576
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
6577
#if defined (DO_SINGLE_STEP) && 0
6578
    /* Single step trace mode */
6579
    msr_se = 1;
6580
#endif
6581
    num_insns = 0;
6582
    max_insns = tb->cflags & CF_COUNT_MASK;
6583
    if (max_insns == 0)
6584
        max_insns = CF_COUNT_MASK;
6585

    
6586
    gen_icount_start();
6587
    /* Set env in case of segfault during code fetch */
6588
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
6589
        if (unlikely(env->nb_breakpoints > 0)) {
6590
            for (j = 0; j < env->nb_breakpoints; j++) {
6591
                if (env->breakpoints[j] == ctx.nip) {
6592
                    gen_update_nip(&ctx, ctx.nip);
6593
                    gen_op_debug();
6594
                    break;
6595
                }
6596
            }
6597
        }
6598
        if (unlikely(search_pc)) {
6599
            j = gen_opc_ptr - gen_opc_buf;
6600
            if (lj < j) {
6601
                lj++;
6602
                while (lj < j)
6603
                    gen_opc_instr_start[lj++] = 0;
6604
                gen_opc_pc[lj] = ctx.nip;
6605
                gen_opc_instr_start[lj] = 1;
6606
                gen_opc_icount[lj] = num_insns;
6607
            }
6608
        }
6609
#if defined PPC_DEBUG_DISAS
6610
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6611
            fprintf(logfile, "----------------\n");
6612
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6613
                    ctx.nip, supervisor, (int)msr_ir);
6614
        }
6615
#endif
6616
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
6617
            gen_io_start();
6618
        if (unlikely(little_endian)) {
6619
            ctx.opcode = bswap32(ldl_code(ctx.nip));
6620
        } else {
6621
            ctx.opcode = ldl_code(ctx.nip);
6622
        }
6623
#if defined PPC_DEBUG_DISAS
6624
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6625
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6626
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6627
                    opc3(ctx.opcode), little_endian ? "little" : "big");
6628
        }
6629
#endif
6630
        ctx.nip += 4;
6631
        table = env->opcodes;
6632
        num_insns++;
6633
        handler = table[opc1(ctx.opcode)];
6634
        if (is_indirect_opcode(handler)) {
6635
            table = ind_table(handler);
6636
            handler = table[opc2(ctx.opcode)];
6637
            if (is_indirect_opcode(handler)) {
6638
                table = ind_table(handler);
6639
                handler = table[opc3(ctx.opcode)];
6640
            }
6641
        }
6642
        /* Is opcode *REALLY* valid ? */
6643
        if (unlikely(handler->handler == &gen_invalid)) {
6644
            if (loglevel != 0) {
6645
                fprintf(logfile, "invalid/unsupported opcode: "
6646
                        "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6647
                        opc1(ctx.opcode), opc2(ctx.opcode),
6648
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6649
            } else {
6650
                printf("invalid/unsupported opcode: "
6651
                       "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6652
                       opc1(ctx.opcode), opc2(ctx.opcode),
6653
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6654
            }
6655
        } else {
6656
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6657
                if (loglevel != 0) {
6658
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6659
                            "%02x - %02x - %02x (%08x) " ADDRX "\n",
6660
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6661
                            opc2(ctx.opcode), opc3(ctx.opcode),
6662
                            ctx.opcode, ctx.nip - 4);
6663
                } else {
6664
                    printf("invalid bits: %08x for opcode: "
6665
                           "%02x - %02x - %02x (%08x) " ADDRX "\n",
6666
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6667
                           opc2(ctx.opcode), opc3(ctx.opcode),
6668
                           ctx.opcode, ctx.nip - 4);
6669
                }
6670
                GEN_EXCP_INVAL(ctxp);
6671
                break;
6672
            }
6673
        }
6674
        (*(handler->handler))(&ctx);
6675
#if defined(DO_PPC_STATISTICS)
6676
        handler->count++;
6677
#endif
6678
        /* Check trace mode exceptions */
6679
        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
6680
                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
6681
                     ctx.exception != POWERPC_SYSCALL &&
6682
                     ctx.exception != POWERPC_EXCP_TRAP &&
6683
                     ctx.exception != POWERPC_EXCP_BRANCH)) {
6684
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6685
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6686
                            (env->singlestep_enabled) ||
6687
                            num_insns >= max_insns)) {
6688
            /* if we reach a page boundary or are single stepping, stop
6689
             * generation
6690
             */
6691
            break;
6692
        }
6693
#if defined (DO_SINGLE_STEP)
6694
        break;
6695
#endif
6696
    }
6697
    if (tb->cflags & CF_LAST_IO)
6698
        gen_io_end();
6699
    if (ctx.exception == POWERPC_EXCP_NONE) {
6700
        gen_goto_tb(&ctx, 0, ctx.nip);
6701
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6702
        if (unlikely(env->singlestep_enabled)) {
6703
            gen_update_nip(&ctx, ctx.nip);
6704
            gen_op_debug();
6705
        }
6706
        /* Generate the return instruction */
6707
        tcg_gen_exit_tb(0);
6708
    }
6709
    gen_icount_end(tb, num_insns);
6710
    *gen_opc_ptr = INDEX_op_end;
6711
    if (unlikely(search_pc)) {
6712
        j = gen_opc_ptr - gen_opc_buf;
6713
        lj++;
6714
        while (lj <= j)
6715
            gen_opc_instr_start[lj++] = 0;
6716
    } else {
6717
        tb->size = ctx.nip - pc_start;
6718
        tb->icount = num_insns;
6719
    }
6720
#if defined(DEBUG_DISAS)
6721
    if (loglevel & CPU_LOG_TB_CPU) {
6722
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6723
        cpu_dump_state(env, logfile, fprintf, 0);
6724
    }
6725
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6726
        int flags;
6727
        flags = env->bfd_mach;
6728
        flags |= little_endian << 16;
6729
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6730
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6731
        fprintf(logfile, "\n");
6732
    }
6733
#endif
6734
}
6735

    
6736
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6737
{
6738
    gen_intermediate_code_internal(env, tb, 0);
6739
}
6740

    
6741
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6742
{
6743
    gen_intermediate_code_internal(env, tb, 1);
6744
}
6745

    
6746
void gen_pc_load(CPUState *env, TranslationBlock *tb,
6747
                unsigned long searched_pc, int pc_pos, void *puc)
6748
{
6749
    int type, c;
6750
    /* for PPC, we need to look at the micro operation to get the
6751
     * access type */
6752
    env->nip = gen_opc_pc[pc_pos];
6753
    c = gen_opc_buf[pc_pos];
6754
    switch(c) {
6755
#if defined(CONFIG_USER_ONLY)
6756
#define CASE3(op)\
6757
    case INDEX_op_ ## op ## _raw
6758
#else
6759
#define CASE3(op)\
6760
    case INDEX_op_ ## op ## _user:\
6761
    case INDEX_op_ ## op ## _kernel:\
6762
    case INDEX_op_ ## op ## _hypv
6763
#endif
6764

    
6765
    CASE3(stfd):
6766
    CASE3(stfs):
6767
    CASE3(lfd):
6768
    CASE3(lfs):
6769
        type = ACCESS_FLOAT;
6770
        break;
6771
    CASE3(lwarx):
6772
        type = ACCESS_RES;
6773
        break;
6774
    CASE3(stwcx):
6775
        type = ACCESS_RES;
6776
        break;
6777
    CASE3(eciwx):
6778
    CASE3(ecowx):
6779
        type = ACCESS_EXT;
6780
        break;
6781
    default:
6782
        type = ACCESS_INT;
6783
        break;
6784
    }
6785
    env->access_type = type;
6786
}