Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 7c417963

History | View | Annotate | Download (228.1 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 DEBUG_MEMORY_ACCESSES
41
//#define DO_PPC_STATISTICS
42
//#define OPTIMIZE_FPRF_UPDATE
43

    
44
/*****************************************************************************/
45
/* Code translation helpers                                                  */
46

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

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

    
75
#include "gen-icount.h"
76

    
77
void ppc_translate_init(void)
78
{
79
    int i;
80
    char* p;
81
    static int done_init = 0;
82

    
83
    if (done_init)
84
        return;
85

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

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

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

    
131
    p = cpu_reg_names;
132

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

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

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

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

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

    
168
    cpu_nip = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
169
                                 offsetof(CPUState, nip), "nip");
170

    
171
    /* register helpers */
172
#undef DEF_HELPER
173
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
174
#include "helper.h"
175

    
176
    done_init = 1;
177
}
178

    
179
#if defined(OPTIMIZE_FPRF_UPDATE)
180
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
181
static uint16_t **gen_fprf_ptr;
182
#endif
183

    
184
/* internal defines */
185
typedef struct DisasContext {
186
    struct TranslationBlock *tb;
187
    target_ulong nip;
188
    uint32_t opcode;
189
    uint32_t exception;
190
    /* Routine used to access memory */
191
    int mem_idx;
192
    /* Translation flags */
193
#if !defined(CONFIG_USER_ONLY)
194
    int supervisor;
195
#endif
196
#if defined(TARGET_PPC64)
197
    int sf_mode;
198
#endif
199
    int fpu_enabled;
200
    int altivec_enabled;
201
    int spe_enabled;
202
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
203
    int singlestep_enabled;
204
    int dcache_line_size;
205
} DisasContext;
206

    
207
struct opc_handler_t {
208
    /* invalid bits */
209
    uint32_t inval;
210
    /* instruction type */
211
    uint64_t type;
212
    /* handler */
213
    void (*handler)(DisasContext *ctx);
214
#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
215
    const unsigned char *oname;
216
#endif
217
#if defined(DO_PPC_STATISTICS)
218
    uint64_t count;
219
#endif
220
};
221

    
222
static always_inline void gen_set_Rc0 (DisasContext *ctx)
223
{
224
#if defined(TARGET_PPC64)
225
    if (ctx->sf_mode)
226
        gen_op_cmpi_64(0);
227
    else
228
#endif
229
        gen_op_cmpi(0);
230
    gen_op_set_Rc0();
231
}
232

    
233
static always_inline void gen_reset_fpstatus (void)
234
{
235
#ifdef CONFIG_SOFTFLOAT
236
    gen_op_reset_fpstatus();
237
#endif
238
}
239

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

    
260
static always_inline void gen_optimize_fprf (void)
261
{
262
#if defined(OPTIMIZE_FPRF_UPDATE)
263
    uint16_t **ptr;
264

    
265
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
266
        *ptr = INDEX_op_nop1;
267
    gen_fprf_ptr = gen_fprf_buf;
268
#endif
269
}
270

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

    
281
#define GEN_EXCP(ctx, excp, error)                                            \
282
do {                                                                          \
283
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
284
        gen_update_nip(ctx, (ctx)->nip);                                      \
285
    }                                                                         \
286
    gen_op_raise_exception_err((excp), (error));                              \
287
    ctx->exception = (excp);                                                  \
288
} while (0)
289

    
290
#define GEN_EXCP_INVAL(ctx)                                                   \
291
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
292
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
293

    
294
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
295
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
296
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
297

    
298
#define GEN_EXCP_PRIVREG(ctx)                                                 \
299
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
300
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
301

    
302
#define GEN_EXCP_NO_FP(ctx)                                                   \
303
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
304

    
305
#define GEN_EXCP_NO_AP(ctx)                                                   \
306
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
307

    
308
#define GEN_EXCP_NO_VR(ctx)                                                   \
309
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
310

    
311
/* Stop translation */
312
static always_inline void GEN_STOP (DisasContext *ctx)
313
{
314
    gen_update_nip(ctx, ctx->nip);
315
    ctx->exception = POWERPC_EXCP_STOP;
316
}
317

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

    
324
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
325
static void gen_##name (DisasContext *ctx);                                   \
326
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
327
static void gen_##name (DisasContext *ctx)
328

    
329
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
330
static void gen_##name (DisasContext *ctx);                                   \
331
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
332
static void gen_##name (DisasContext *ctx)
333

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

    
345
/*****************************************************************************/
346
/***                           Instruction decoding                        ***/
347
#define EXTRACT_HELPER(name, shift, nb)                                       \
348
static always_inline uint32_t name (uint32_t opcode)                          \
349
{                                                                             \
350
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
351
}
352

    
353
#define EXTRACT_SHELPER(name, shift, nb)                                      \
354
static always_inline int32_t name (uint32_t opcode)                           \
355
{                                                                             \
356
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
357
}
358

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

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

    
408
EXTRACT_HELPER(CRM, 12, 8);
409
EXTRACT_HELPER(FM, 17, 8);
410
EXTRACT_HELPER(SR, 16, 4);
411
EXTRACT_HELPER(FPIMM, 12, 4);
412

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

    
422
static always_inline uint32_t BD (uint32_t opcode)
423
{
424
    return (opcode >> 0) & 0xFFFC;
425
}
426

    
427
EXTRACT_HELPER(BO, 21, 5);
428
EXTRACT_HELPER(BI, 16, 5);
429
/* Absolute/relative address */
430
EXTRACT_HELPER(AA, 1, 1);
431
/* Link */
432
EXTRACT_HELPER(LK, 0, 1);
433

    
434
/* Create a mask between <start> and <end> bits */
435
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
436
{
437
    target_ulong ret;
438

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

    
459
    return ret;
460
}
461

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

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

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

    
520
    /* Vector/SIMD extensions                                                */
521
    /*   Altivec support                                                     */
522
    PPC_ALTIVEC        = 0x0000000001000000ULL,
523
    /*   PowerPC 2.03 SPE extension                                          */
524
    PPC_SPE            = 0x0000000002000000ULL,
525
    /*   PowerPC 2.03 SPE floating-point extension                           */
526
    PPC_SPEFPU         = 0x0000000004000000ULL,
527

    
528
    /* Optional memory control instructions                                  */
529
    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
530
    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
531
    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
532
    /*   sync instruction                                                    */
533
    PPC_MEM_SYNC       = 0x0000000080000000ULL,
534
    /*   eieio instruction                                                   */
535
    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
536

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

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

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

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

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

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

    
685
/* Start opcode list */
686
GEN_OPCODE_MARK(start);
687

    
688
/* Invalid instruction */
689
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
690
{
691
    GEN_EXCP_INVAL(ctx);
692
}
693

    
694
static opc_handler_t invalid_handler = {
695
    .inval   = 0xFFFFFFFF,
696
    .type    = PPC_NONE,
697
    .handler = gen_invalid,
698
};
699

    
700
/***                           Integer arithmetic                          ***/
701
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
702
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
703
{                                                                             \
704
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
705
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
706
    gen_op_##name();                                                          \
707
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
708
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
709
        gen_set_Rc0(ctx);                                                     \
710
}
711

    
712
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
713
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
714
{                                                                             \
715
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
716
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
717
    gen_op_##name();                                                          \
718
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
719
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
720
        gen_set_Rc0(ctx);                                                     \
721
}
722

    
723
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
724
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
725
{                                                                             \
726
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
727
    gen_op_##name();                                                          \
728
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
729
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
730
        gen_set_Rc0(ctx);                                                     \
731
}
732
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
733
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
734
{                                                                             \
735
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
736
    gen_op_##name();                                                          \
737
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
738
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
739
        gen_set_Rc0(ctx);                                                     \
740
}
741

    
742
/* Two operands arithmetic functions */
743
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
744
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
745
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
746

    
747
/* Two operands arithmetic functions with no overflow allowed */
748
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
749
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
750

    
751
/* One operand arithmetic functions */
752
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
753
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
754
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
755

    
756
#if defined(TARGET_PPC64)
757
#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
758
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
759
{                                                                             \
760
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
761
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
762
    if (ctx->sf_mode)                                                         \
763
        gen_op_##name##_64();                                                 \
764
    else                                                                      \
765
        gen_op_##name();                                                      \
766
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
767
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
768
        gen_set_Rc0(ctx);                                                     \
769
}
770

    
771
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
772
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
773
{                                                                             \
774
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
775
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
776
    if (ctx->sf_mode)                                                         \
777
        gen_op_##name##_64();                                                 \
778
    else                                                                      \
779
        gen_op_##name();                                                      \
780
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
781
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
782
        gen_set_Rc0(ctx);                                                     \
783
}
784

    
785
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
786
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
787
{                                                                             \
788
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
789
    if (ctx->sf_mode)                                                         \
790
        gen_op_##name##_64();                                                 \
791
    else                                                                      \
792
        gen_op_##name();                                                      \
793
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
794
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
795
        gen_set_Rc0(ctx);                                                     \
796
}
797
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
798
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
799
{                                                                             \
800
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
801
    if (ctx->sf_mode)                                                         \
802
        gen_op_##name##_64();                                                 \
803
    else                                                                      \
804
        gen_op_##name();                                                      \
805
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
806
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
807
        gen_set_Rc0(ctx);                                                     \
808
}
809

    
810
/* Two operands arithmetic functions */
811
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
812
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
813
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
814

    
815
/* Two operands arithmetic functions with no overflow allowed */
816
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
817
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
818

    
819
/* One operand arithmetic functions */
820
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
821
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
822
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
823
#else
824
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
825
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
826
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
827
#endif
828

    
829
/* add    add.    addo    addo.    */
830
static always_inline void gen_op_add (void)
831
{
832
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
833
}
834
static always_inline void gen_op_addo (void)
835
{
836
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
837
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
838
    gen_op_check_addo();
839
}
840
#if defined(TARGET_PPC64)
841
#define gen_op_add_64 gen_op_add
842
static always_inline void gen_op_addo_64 (void)
843
{
844
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
845
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
846
    gen_op_check_addo_64();
847
}
848
#endif
849
GEN_INT_ARITH2_64 (add,    0x1F, 0x0A, 0x08, PPC_INTEGER);
850
/* addc   addc.   addco   addco.   */
851
static always_inline void gen_op_addc (void)
852
{
853
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
854
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
855
    gen_op_check_addc();
856
}
857
static always_inline void gen_op_addco (void)
858
{
859
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
860
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
861
    gen_op_check_addc();
862
    gen_op_check_addo();
863
}
864
#if defined(TARGET_PPC64)
865
static always_inline void gen_op_addc_64 (void)
866
{
867
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
868
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
869
    gen_op_check_addc_64();
870
}
871
static always_inline void gen_op_addco_64 (void)
872
{
873
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
874
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
875
    gen_op_check_addc_64();
876
    gen_op_check_addo_64();
877
}
878
#endif
879
GEN_INT_ARITH2_64 (addc,   0x1F, 0x0A, 0x00, PPC_INTEGER);
880
/* adde   adde.   addeo   addeo.   */
881
static always_inline void gen_op_addeo (void)
882
{
883
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
884
    gen_op_adde();
885
    gen_op_check_addo();
886
}
887
#if defined(TARGET_PPC64)
888
static always_inline void gen_op_addeo_64 (void)
889
{
890
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
891
    gen_op_adde_64();
892
    gen_op_check_addo_64();
893
}
894
#endif
895
GEN_INT_ARITH2_64 (adde,   0x1F, 0x0A, 0x04, PPC_INTEGER);
896
/* addme  addme.  addmeo  addmeo.  */
897
static always_inline void gen_op_addme (void)
898
{
899
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
900
    gen_op_add_me();
901
}
902
#if defined(TARGET_PPC64)
903
static always_inline void gen_op_addme_64 (void)
904
{
905
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
906
    gen_op_add_me_64();
907
}
908
#endif
909
GEN_INT_ARITH1_64 (addme,  0x1F, 0x0A, 0x07, PPC_INTEGER);
910
/* addze  addze.  addzeo  addzeo.  */
911
static always_inline void gen_op_addze (void)
912
{
913
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
914
    gen_op_add_ze();
915
    gen_op_check_addc();
916
}
917
static always_inline void gen_op_addzeo (void)
918
{
919
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
920
    gen_op_add_ze();
921
    gen_op_check_addc();
922
    gen_op_check_addo();
923
}
924
#if defined(TARGET_PPC64)
925
static always_inline void gen_op_addze_64 (void)
926
{
927
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
928
    gen_op_add_ze();
929
    gen_op_check_addc_64();
930
}
931
static always_inline void gen_op_addzeo_64 (void)
932
{
933
    tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
934
    gen_op_add_ze();
935
    gen_op_check_addc_64();
936
    gen_op_check_addo_64();
937
}
938
#endif
939
GEN_INT_ARITH1_64 (addze,  0x1F, 0x0A, 0x06, PPC_INTEGER);
940
/* divw   divw.   divwo   divwo.   */
941
GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F, PPC_INTEGER);
942
/* divwu  divwu.  divwuo  divwuo.  */
943
GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E, PPC_INTEGER);
944
/* mulhw  mulhw.                   */
945
GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02, PPC_INTEGER);
946
/* mulhwu mulhwu.                  */
947
GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);
948
/* mullw  mullw.  mullwo  mullwo.  */
949
GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07, PPC_INTEGER);
950
/* neg    neg.    nego    nego.    */
951
GEN_INT_ARITH1_64 (neg,    0x1F, 0x08, 0x03, PPC_INTEGER);
952
/* subf   subf.   subfo   subfo.   */
953
static always_inline void gen_op_subf (void)
954
{
955
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
956
}
957
static always_inline void gen_op_subfo (void)
958
{
959
    tcg_gen_not_tl(cpu_T[2], cpu_T[0]);
960
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
961
    gen_op_check_addo();
962
}
963
#if defined(TARGET_PPC64)
964
#define gen_op_subf_64 gen_op_subf
965
static always_inline void gen_op_subfo_64 (void)
966
{
967
    tcg_gen_not_i64(cpu_T[2], cpu_T[0]);
968
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
969
    gen_op_check_addo_64();
970
}
971
#endif
972
GEN_INT_ARITH2_64 (subf,   0x1F, 0x08, 0x01, PPC_INTEGER);
973
/* subfc  subfc.  subfco  subfco.  */
974
static always_inline void gen_op_subfc (void)
975
{
976
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
977
    gen_op_check_subfc();
978
}
979
static always_inline void gen_op_subfco (void)
980
{
981
    tcg_gen_not_tl(cpu_T[2], cpu_T[0]);
982
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
983
    gen_op_check_subfc();
984
    gen_op_check_addo();
985
}
986
#if defined(TARGET_PPC64)
987
static always_inline void gen_op_subfc_64 (void)
988
{
989
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
990
    gen_op_check_subfc_64();
991
}
992
static always_inline void gen_op_subfco_64 (void)
993
{
994
    tcg_gen_not_i64(cpu_T[2], cpu_T[0]);
995
    tcg_gen_sub_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
996
    gen_op_check_subfc_64();
997
    gen_op_check_addo_64();
998
}
999
#endif
1000
GEN_INT_ARITH2_64 (subfc,  0x1F, 0x08, 0x00, PPC_INTEGER);
1001
/* subfe  subfe.  subfeo  subfeo.  */
1002
static always_inline void gen_op_subfeo (void)
1003
{
1004
    tcg_gen_not_tl(cpu_T[2], cpu_T[0]);
1005
    gen_op_subfe();
1006
    gen_op_check_addo();
1007
}
1008
#if defined(TARGET_PPC64)
1009
#define gen_op_subfe_64 gen_op_subfe
1010
static always_inline void gen_op_subfeo_64 (void)
1011
{
1012
    tcg_gen_not_i64(cpu_T[2], cpu_T[0]);
1013
    gen_op_subfe_64();
1014
    gen_op_check_addo_64();
1015
}
1016
#endif
1017
GEN_INT_ARITH2_64 (subfe,  0x1F, 0x08, 0x04, PPC_INTEGER);
1018
/* subfme subfme. subfmeo subfmeo. */
1019
GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);
1020
/* subfze subfze. subfzeo subfzeo. */
1021
GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);
1022
/* addi */
1023
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1024
{
1025
    target_long simm = SIMM(ctx->opcode);
1026

    
1027
    if (rA(ctx->opcode) == 0) {
1028
        /* li case */
1029
        tcg_gen_movi_tl(cpu_T[0], simm);
1030
    } else {
1031
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1032
        if (likely(simm != 0))
1033
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);
1034
    }
1035
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1036
}
1037
/* addic */
1038
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1039
{
1040
    target_long simm = SIMM(ctx->opcode);
1041

    
1042
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1043
    if (likely(simm != 0)) {
1044
        tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1045
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);
1046
#if defined(TARGET_PPC64)
1047
        if (ctx->sf_mode)
1048
            gen_op_check_addc_64();
1049
        else
1050
#endif
1051
            gen_op_check_addc();
1052
    } else {
1053
        gen_op_clear_xer_ca();
1054
    }
1055
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1056
}
1057
/* addic. */
1058
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1059
{
1060
    target_long simm = SIMM(ctx->opcode);
1061

    
1062
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1063
    if (likely(simm != 0)) {
1064
        tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1065
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);
1066
#if defined(TARGET_PPC64)
1067
        if (ctx->sf_mode)
1068
            gen_op_check_addc_64();
1069
        else
1070
#endif
1071
            gen_op_check_addc();
1072
    } else {
1073
        gen_op_clear_xer_ca();
1074
    }
1075
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1076
    gen_set_Rc0(ctx);
1077
}
1078
/* addis */
1079
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1080
{
1081
    target_long simm = SIMM(ctx->opcode);
1082

    
1083
    if (rA(ctx->opcode) == 0) {
1084
        /* lis case */
1085
        tcg_gen_movi_tl(cpu_T[0], simm << 16);
1086
    } else {
1087
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1088
        if (likely(simm != 0))
1089
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm << 16);
1090
    }
1091
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1092
}
1093
/* mulli */
1094
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1095
{
1096
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1097
    gen_op_mulli(SIMM(ctx->opcode));
1098
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1099
}
1100
/* subfic */
1101
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1102
{
1103
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1104
#if defined(TARGET_PPC64)
1105
    if (ctx->sf_mode)
1106
        gen_op_subfic_64(SIMM(ctx->opcode));
1107
    else
1108
#endif
1109
        gen_op_subfic(SIMM(ctx->opcode));
1110
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1111
}
1112

    
1113
#if defined(TARGET_PPC64)
1114
/* mulhd  mulhd.                   */
1115
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
1116
/* mulhdu mulhdu.                  */
1117
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
1118
/* mulld  mulld.  mulldo  mulldo.  */
1119
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
1120
/* divd   divd.   divdo   divdo.   */
1121
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
1122
/* divdu  divdu.  divduo  divduo.  */
1123
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
1124
#endif
1125

    
1126
/***                           Integer comparison                          ***/
1127
#if defined(TARGET_PPC64)
1128
#define GEN_CMP(name, opc, type)                                              \
1129
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1130
{                                                                             \
1131
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
1132
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
1133
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))                           \
1134
        gen_op_##name##_64();                                                 \
1135
    else                                                                      \
1136
        gen_op_##name();                                                      \
1137
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);              \
1138
}
1139
#else
1140
#define GEN_CMP(name, opc, type)                                              \
1141
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1142
{                                                                             \
1143
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
1144
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
1145
    gen_op_##name();                                                          \
1146
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);              \
1147
}
1148
#endif
1149

    
1150
/* cmp */
1151
GEN_CMP(cmp, 0x00, PPC_INTEGER);
1152
/* cmpi */
1153
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1154
{
1155
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1156
#if defined(TARGET_PPC64)
1157
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1158
        gen_op_cmpi_64(SIMM(ctx->opcode));
1159
    else
1160
#endif
1161
        gen_op_cmpi(SIMM(ctx->opcode));
1162
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
1163
}
1164
/* cmpl */
1165
GEN_CMP(cmpl, 0x01, PPC_INTEGER);
1166
/* cmpli */
1167
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1168
{
1169
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1170
#if defined(TARGET_PPC64)
1171
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1172
        gen_op_cmpli_64(UIMM(ctx->opcode));
1173
    else
1174
#endif
1175
        gen_op_cmpli(UIMM(ctx->opcode));
1176
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
1177
}
1178

    
1179
/* isel (PowerPC 2.03 specification) */
1180
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
1181
{
1182
    uint32_t bi = rC(ctx->opcode);
1183
    uint32_t mask;
1184

    
1185
    if (rA(ctx->opcode) == 0) {
1186
        tcg_gen_movi_tl(cpu_T[0], 0);
1187
    } else {
1188
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1189
    }
1190
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
1191
    mask = 1 << (3 - (bi & 0x03));
1192
    tcg_gen_mov_i32(cpu_T[0], cpu_crf[bi >> 2]);
1193
    gen_op_test_true(mask);
1194
    gen_op_isel();
1195
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1196
}
1197

    
1198
/***                            Integer logical                            ***/
1199
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1200
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1201
{                                                                             \
1202
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
1203
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
1204
    gen_op_##name();                                                          \
1205
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
1206
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1207
        gen_set_Rc0(ctx);                                                     \
1208
}
1209
#define GEN_LOGICAL2(name, opc, type)                                         \
1210
__GEN_LOGICAL2(name, 0x1C, opc, type)
1211

    
1212
#define GEN_LOGICAL1(name, opc, type)                                         \
1213
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1214
{                                                                             \
1215
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
1216
    gen_op_##name();                                                          \
1217
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
1218
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1219
        gen_set_Rc0(ctx);                                                     \
1220
}
1221

    
1222
/* and & and. */
1223
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1224
/* andc & andc. */
1225
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1226
/* andi. */
1227
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1228
{
1229
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1230
    gen_op_andi_T0(UIMM(ctx->opcode));
1231
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1232
    gen_set_Rc0(ctx);
1233
}
1234
/* andis. */
1235
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1236
{
1237
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1238
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
1239
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1240
    gen_set_Rc0(ctx);
1241
}
1242

    
1243
/* cntlzw */
1244
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1245
/* eqv & eqv. */
1246
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1247
/* extsb & extsb. */
1248
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1249
/* extsh & extsh. */
1250
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1251
/* nand & nand. */
1252
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1253
/* nor & nor. */
1254
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1255

    
1256
/* or & or. */
1257
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1258
{
1259
    int rs, ra, rb;
1260

    
1261
    rs = rS(ctx->opcode);
1262
    ra = rA(ctx->opcode);
1263
    rb = rB(ctx->opcode);
1264
    /* Optimisation for mr. ri case */
1265
    if (rs != ra || rs != rb) {
1266
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
1267
        if (rs != rb) {
1268
            tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]);
1269
            gen_op_or();
1270
        }
1271
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
1272
        if (unlikely(Rc(ctx->opcode) != 0))
1273
            gen_set_Rc0(ctx);
1274
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1275
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
1276
        gen_set_Rc0(ctx);
1277
#if defined(TARGET_PPC64)
1278
    } else {
1279
        switch (rs) {
1280
        case 1:
1281
            /* Set process priority to low */
1282
            gen_op_store_pri(2);
1283
            break;
1284
        case 6:
1285
            /* Set process priority to medium-low */
1286
            gen_op_store_pri(3);
1287
            break;
1288
        case 2:
1289
            /* Set process priority to normal */
1290
            gen_op_store_pri(4);
1291
            break;
1292
#if !defined(CONFIG_USER_ONLY)
1293
        case 31:
1294
            if (ctx->supervisor > 0) {
1295
                /* Set process priority to very low */
1296
                gen_op_store_pri(1);
1297
            }
1298
            break;
1299
        case 5:
1300
            if (ctx->supervisor > 0) {
1301
                /* Set process priority to medium-hight */
1302
                gen_op_store_pri(5);
1303
            }
1304
            break;
1305
        case 3:
1306
            if (ctx->supervisor > 0) {
1307
                /* Set process priority to high */
1308
                gen_op_store_pri(6);
1309
            }
1310
            break;
1311
        case 7:
1312
            if (ctx->supervisor > 1) {
1313
                /* Set process priority to very high */
1314
                gen_op_store_pri(7);
1315
            }
1316
            break;
1317
#endif
1318
        default:
1319
            /* nop */
1320
            break;
1321
        }
1322
#endif
1323
    }
1324
}
1325

    
1326
/* orc & orc. */
1327
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1328
/* xor & xor. */
1329
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1330
{
1331
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1332
    /* Optimisation for "set to zero" case */
1333
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1334
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1335
        gen_op_xor();
1336
    } else {
1337
        tcg_gen_movi_tl(cpu_T[0], 0);
1338
    }
1339
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1340
    if (unlikely(Rc(ctx->opcode) != 0))
1341
        gen_set_Rc0(ctx);
1342
}
1343
/* ori */
1344
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1345
{
1346
    target_ulong uimm = UIMM(ctx->opcode);
1347

    
1348
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1349
        /* NOP */
1350
        /* XXX: should handle special NOPs for POWER series */
1351
        return;
1352
    }
1353
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1354
    if (likely(uimm != 0))
1355
        gen_op_ori(uimm);
1356
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1357
}
1358
/* oris */
1359
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1360
{
1361
    target_ulong uimm = UIMM(ctx->opcode);
1362

    
1363
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1364
        /* NOP */
1365
        return;
1366
    }
1367
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1368
    if (likely(uimm != 0))
1369
        gen_op_ori(uimm << 16);
1370
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1371
}
1372
/* xori */
1373
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1374
{
1375
    target_ulong uimm = UIMM(ctx->opcode);
1376

    
1377
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1378
        /* NOP */
1379
        return;
1380
    }
1381
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1382
    if (likely(uimm != 0))
1383
        gen_op_xori(uimm);
1384
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1385
}
1386

    
1387
/* xoris */
1388
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1389
{
1390
    target_ulong uimm = UIMM(ctx->opcode);
1391

    
1392
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1393
        /* NOP */
1394
        return;
1395
    }
1396
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1397
    if (likely(uimm != 0))
1398
        gen_op_xori(uimm << 16);
1399
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1400
}
1401

    
1402
/* popcntb : PowerPC 2.03 specification */
1403
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
1404
{
1405
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1406
#if defined(TARGET_PPC64)
1407
    if (ctx->sf_mode)
1408
        gen_op_popcntb_64();
1409
    else
1410
#endif
1411
        gen_op_popcntb();
1412
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1413
}
1414

    
1415
#if defined(TARGET_PPC64)
1416
/* extsw & extsw. */
1417
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1418
/* cntlzd */
1419
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1420
#endif
1421

    
1422
/***                             Integer rotate                            ***/
1423
/* rlwimi & rlwimi. */
1424
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1425
{
1426
    target_ulong mask;
1427
    uint32_t mb, me, sh;
1428

    
1429
    mb = MB(ctx->opcode);
1430
    me = ME(ctx->opcode);
1431
    sh = SH(ctx->opcode);
1432
    if (likely(sh == 0)) {
1433
        if (likely(mb == 0 && me == 31)) {
1434
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1435
            goto do_store;
1436
        } else if (likely(mb == 31 && me == 0)) {
1437
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1438
            goto do_store;
1439
        }
1440
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1441
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1442
        goto do_mask;
1443
    }
1444
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1445
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1446
    gen_op_rotli32_T0(SH(ctx->opcode));
1447
 do_mask:
1448
#if defined(TARGET_PPC64)
1449
    mb += 32;
1450
    me += 32;
1451
#endif
1452
    mask = MASK(mb, me);
1453
    gen_op_andi_T0(mask);
1454
    gen_op_andi_T1(~mask);
1455
    gen_op_or();
1456
 do_store:
1457
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1458
    if (unlikely(Rc(ctx->opcode) != 0))
1459
        gen_set_Rc0(ctx);
1460
}
1461
/* rlwinm & rlwinm. */
1462
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1463
{
1464
    uint32_t mb, me, sh;
1465

    
1466
    sh = SH(ctx->opcode);
1467
    mb = MB(ctx->opcode);
1468
    me = ME(ctx->opcode);
1469
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1470
    if (likely(sh == 0)) {
1471
        goto do_mask;
1472
    }
1473
    if (likely(mb == 0)) {
1474
        if (likely(me == 31)) {
1475
            gen_op_rotli32_T0(sh);
1476
            goto do_store;
1477
        } else if (likely(me == (31 - sh))) {
1478
            gen_op_sli_T0(sh);
1479
            goto do_store;
1480
        }
1481
    } else if (likely(me == 31)) {
1482
        if (likely(sh == (32 - mb))) {
1483
            gen_op_srli_T0(mb);
1484
            goto do_store;
1485
        }
1486
    }
1487
    gen_op_rotli32_T0(sh);
1488
 do_mask:
1489
#if defined(TARGET_PPC64)
1490
    mb += 32;
1491
    me += 32;
1492
#endif
1493
    gen_op_andi_T0(MASK(mb, me));
1494
 do_store:
1495
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1496
    if (unlikely(Rc(ctx->opcode) != 0))
1497
        gen_set_Rc0(ctx);
1498
}
1499
/* rlwnm & rlwnm. */
1500
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1501
{
1502
    uint32_t mb, me;
1503

    
1504
    mb = MB(ctx->opcode);
1505
    me = ME(ctx->opcode);
1506
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1507
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1508
    gen_op_rotl32_T0_T1();
1509
    if (unlikely(mb != 0 || me != 31)) {
1510
#if defined(TARGET_PPC64)
1511
        mb += 32;
1512
        me += 32;
1513
#endif
1514
        gen_op_andi_T0(MASK(mb, me));
1515
    }
1516
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1517
    if (unlikely(Rc(ctx->opcode) != 0))
1518
        gen_set_Rc0(ctx);
1519
}
1520

    
1521
#if defined(TARGET_PPC64)
1522
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1523
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1524
{                                                                             \
1525
    gen_##name(ctx, 0);                                                       \
1526
}                                                                             \
1527
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1528
             PPC_64B)                                                         \
1529
{                                                                             \
1530
    gen_##name(ctx, 1);                                                       \
1531
}
1532
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1533
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1534
{                                                                             \
1535
    gen_##name(ctx, 0, 0);                                                    \
1536
}                                                                             \
1537
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
1538
             PPC_64B)                                                         \
1539
{                                                                             \
1540
    gen_##name(ctx, 0, 1);                                                    \
1541
}                                                                             \
1542
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1543
             PPC_64B)                                                         \
1544
{                                                                             \
1545
    gen_##name(ctx, 1, 0);                                                    \
1546
}                                                                             \
1547
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
1548
             PPC_64B)                                                         \
1549
{                                                                             \
1550
    gen_##name(ctx, 1, 1);                                                    \
1551
}
1552

    
1553
static always_inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1554
{
1555
    if (mask >> 32)
1556
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1557
    else
1558
        gen_op_andi_T0(mask);
1559
}
1560

    
1561
static always_inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1562
{
1563
    if (mask >> 32)
1564
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1565
    else
1566
        gen_op_andi_T1(mask);
1567
}
1568

    
1569
static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
1570
                                      uint32_t me, uint32_t sh)
1571
{
1572
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1573
    if (likely(sh == 0)) {
1574
        goto do_mask;
1575
    }
1576
    if (likely(mb == 0)) {
1577
        if (likely(me == 63)) {
1578
            gen_op_rotli64_T0(sh);
1579
            goto do_store;
1580
        } else if (likely(me == (63 - sh))) {
1581
            gen_op_sli_T0(sh);
1582
            goto do_store;
1583
        }
1584
    } else if (likely(me == 63)) {
1585
        if (likely(sh == (64 - mb))) {
1586
            gen_op_srli_T0_64(mb);
1587
            goto do_store;
1588
        }
1589
    }
1590
    gen_op_rotli64_T0(sh);
1591
 do_mask:
1592
    gen_andi_T0_64(ctx, MASK(mb, me));
1593
 do_store:
1594
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1595
    if (unlikely(Rc(ctx->opcode) != 0))
1596
        gen_set_Rc0(ctx);
1597
}
1598
/* rldicl - rldicl. */
1599
static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1600
{
1601
    uint32_t sh, mb;
1602

    
1603
    sh = SH(ctx->opcode) | (shn << 5);
1604
    mb = MB(ctx->opcode) | (mbn << 5);
1605
    gen_rldinm(ctx, mb, 63, sh);
1606
}
1607
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1608
/* rldicr - rldicr. */
1609
static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1610
{
1611
    uint32_t sh, me;
1612

    
1613
    sh = SH(ctx->opcode) | (shn << 5);
1614
    me = MB(ctx->opcode) | (men << 5);
1615
    gen_rldinm(ctx, 0, me, sh);
1616
}
1617
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1618
/* rldic - rldic. */
1619
static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1620
{
1621
    uint32_t sh, mb;
1622

    
1623
    sh = SH(ctx->opcode) | (shn << 5);
1624
    mb = MB(ctx->opcode) | (mbn << 5);
1625
    gen_rldinm(ctx, mb, 63 - sh, sh);
1626
}
1627
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1628

    
1629
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1630
                                     uint32_t me)
1631
{
1632
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1633
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1634
    gen_op_rotl64_T0_T1();
1635
    if (unlikely(mb != 0 || me != 63)) {
1636
        gen_andi_T0_64(ctx, MASK(mb, me));
1637
    }
1638
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1639
    if (unlikely(Rc(ctx->opcode) != 0))
1640
        gen_set_Rc0(ctx);
1641
}
1642

    
1643
/* rldcl - rldcl. */
1644
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1645
{
1646
    uint32_t mb;
1647

    
1648
    mb = MB(ctx->opcode) | (mbn << 5);
1649
    gen_rldnm(ctx, mb, 63);
1650
}
1651
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1652
/* rldcr - rldcr. */
1653
static always_inline void gen_rldcr (DisasContext *ctx, int men)
1654
{
1655
    uint32_t me;
1656

    
1657
    me = MB(ctx->opcode) | (men << 5);
1658
    gen_rldnm(ctx, 0, me);
1659
}
1660
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1661
/* rldimi - rldimi. */
1662
static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1663
{
1664
    uint64_t mask;
1665
    uint32_t sh, mb, me;
1666

    
1667
    sh = SH(ctx->opcode) | (shn << 5);
1668
    mb = MB(ctx->opcode) | (mbn << 5);
1669
    me = 63 - sh;
1670
    if (likely(sh == 0)) {
1671
        if (likely(mb == 0)) {
1672
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1673
            goto do_store;
1674
        }
1675
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1676
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1677
        goto do_mask;
1678
    }
1679
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1680
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1681
    gen_op_rotli64_T0(sh);
1682
 do_mask:
1683
    mask = MASK(mb, me);
1684
    gen_andi_T0_64(ctx, mask);
1685
    gen_andi_T1_64(ctx, ~mask);
1686
    gen_op_or();
1687
 do_store:
1688
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1689
    if (unlikely(Rc(ctx->opcode) != 0))
1690
        gen_set_Rc0(ctx);
1691
}
1692
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1693
#endif
1694

    
1695
/***                             Integer shift                             ***/
1696
/* slw & slw. */
1697
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1698
/* sraw & sraw. */
1699
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1700
/* srawi & srawi. */
1701
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1702
{
1703
    int mb, me;
1704
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1705
    if (SH(ctx->opcode) != 0) {
1706
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1707
        mb = 32 - SH(ctx->opcode);
1708
        me = 31;
1709
#if defined(TARGET_PPC64)
1710
        mb += 32;
1711
        me += 32;
1712
#endif
1713
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1714
    }
1715
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1716
    if (unlikely(Rc(ctx->opcode) != 0))
1717
        gen_set_Rc0(ctx);
1718
}
1719
/* srw & srw. */
1720
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1721

    
1722
#if defined(TARGET_PPC64)
1723
/* sld & sld. */
1724
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1725
/* srad & srad. */
1726
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1727
/* sradi & sradi. */
1728
static always_inline void gen_sradi (DisasContext *ctx, int n)
1729
{
1730
    uint64_t mask;
1731
    int sh, mb, me;
1732

    
1733
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1734
    sh = SH(ctx->opcode) + (n << 5);
1735
    if (sh != 0) {
1736
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1737
        mb = 64 - SH(ctx->opcode);
1738
        me = 63;
1739
        mask = MASK(mb, me);
1740
        gen_op_sradi(sh, mask >> 32, mask);
1741
    }
1742
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1743
    if (unlikely(Rc(ctx->opcode) != 0))
1744
        gen_set_Rc0(ctx);
1745
}
1746
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1747
{
1748
    gen_sradi(ctx, 0);
1749
}
1750
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1751
{
1752
    gen_sradi(ctx, 1);
1753
}
1754
/* srd & srd. */
1755
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1756
#endif
1757

    
1758
/***                       Floating-Point arithmetic                       ***/
1759
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1760
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1761
{                                                                             \
1762
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1763
        GEN_EXCP_NO_FP(ctx);                                                  \
1764
        return;                                                               \
1765
    }                                                                         \
1766
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
1767
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rC(ctx->opcode)]);                     \
1768
    tcg_gen_mov_i64(cpu_FT[2], cpu_fpr[rB(ctx->opcode)]);                     \
1769
    gen_reset_fpstatus();                                                     \
1770
    gen_op_f##op();                                                           \
1771
    if (isfloat) {                                                            \
1772
        gen_op_frsp();                                                        \
1773
    }                                                                         \
1774
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1775
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1776
}
1777

    
1778
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1779
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1780
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1781

    
1782
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1783
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1784
{                                                                             \
1785
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1786
        GEN_EXCP_NO_FP(ctx);                                                  \
1787
        return;                                                               \
1788
    }                                                                         \
1789
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
1790
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);                     \
1791
    gen_reset_fpstatus();                                                     \
1792
    gen_op_f##op();                                                           \
1793
    if (isfloat) {                                                            \
1794
        gen_op_frsp();                                                        \
1795
    }                                                                         \
1796
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1797
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1798
}
1799
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
1800
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1801
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1802

    
1803
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1804
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1805
{                                                                             \
1806
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1807
        GEN_EXCP_NO_FP(ctx);                                                  \
1808
        return;                                                               \
1809
    }                                                                         \
1810
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
1811
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rC(ctx->opcode)]);                     \
1812
    gen_reset_fpstatus();                                                     \
1813
    gen_op_f##op();                                                           \
1814
    if (isfloat) {                                                            \
1815
        gen_op_frsp();                                                        \
1816
    }                                                                         \
1817
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1818
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1819
}
1820
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
1821
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1822
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1823

    
1824
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
1825
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, 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[rB(ctx->opcode)]);                     \
1832
    gen_reset_fpstatus();                                                     \
1833
    gen_op_f##name();                                                         \
1834
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1835
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1836
}
1837

    
1838
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1839
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1840
{                                                                             \
1841
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1842
        GEN_EXCP_NO_FP(ctx);                                                  \
1843
        return;                                                               \
1844
    }                                                                         \
1845
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);                     \
1846
    gen_reset_fpstatus();                                                     \
1847
    gen_op_f##name();                                                         \
1848
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1849
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1850
}
1851

    
1852
/* fadd - fadds */
1853
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1854
/* fdiv - fdivs */
1855
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1856
/* fmul - fmuls */
1857
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
1858

    
1859
/* fre */
1860
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1861

    
1862
/* fres */
1863
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1864

    
1865
/* frsqrte */
1866
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
1867

    
1868
/* frsqrtes */
1869
static always_inline void gen_op_frsqrtes (void)
1870
{
1871
    gen_op_frsqrte();
1872
    gen_op_frsp();
1873
}
1874
GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1875

    
1876
/* fsel */
1877
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1878
/* fsub - fsubs */
1879
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1880
/* Optional: */
1881
/* fsqrt */
1882
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1883
{
1884
    if (unlikely(!ctx->fpu_enabled)) {
1885
        GEN_EXCP_NO_FP(ctx);
1886
        return;
1887
    }
1888
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
1889
    gen_reset_fpstatus();
1890
    gen_op_fsqrt();
1891
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
1892
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1893
}
1894

    
1895
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1896
{
1897
    if (unlikely(!ctx->fpu_enabled)) {
1898
        GEN_EXCP_NO_FP(ctx);
1899
        return;
1900
    }
1901
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
1902
    gen_reset_fpstatus();
1903
    gen_op_fsqrt();
1904
    gen_op_frsp();
1905
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
1906
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1907
}
1908

    
1909
/***                     Floating-Point multiply-and-add                   ***/
1910
/* fmadd - fmadds */
1911
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1912
/* fmsub - fmsubs */
1913
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1914
/* fnmadd - fnmadds */
1915
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1916
/* fnmsub - fnmsubs */
1917
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1918

    
1919
/***                     Floating-Point round & convert                    ***/
1920
/* fctiw */
1921
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1922
/* fctiwz */
1923
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1924
/* frsp */
1925
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
1926
#if defined(TARGET_PPC64)
1927
/* fcfid */
1928
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
1929
/* fctid */
1930
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
1931
/* fctidz */
1932
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
1933
#endif
1934

    
1935
/* frin */
1936
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
1937
/* friz */
1938
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
1939
/* frip */
1940
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
1941
/* frim */
1942
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1943

    
1944
/***                         Floating-Point compare                        ***/
1945
/* fcmpo */
1946
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1947
{
1948
    if (unlikely(!ctx->fpu_enabled)) {
1949
        GEN_EXCP_NO_FP(ctx);
1950
        return;
1951
    }
1952
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
1953
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
1954
    gen_reset_fpstatus();
1955
    gen_op_fcmpo();
1956
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
1957
    gen_op_float_check_status();
1958
}
1959

    
1960
/* fcmpu */
1961
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1962
{
1963
    if (unlikely(!ctx->fpu_enabled)) {
1964
        GEN_EXCP_NO_FP(ctx);
1965
        return;
1966
    }
1967
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
1968
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
1969
    gen_reset_fpstatus();
1970
    gen_op_fcmpu();
1971
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
1972
    gen_op_float_check_status();
1973
}
1974

    
1975
/***                         Floating-point move                           ***/
1976
/* fabs */
1977
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
1978
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1979

    
1980
/* fmr  - fmr. */
1981
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1982
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1983
{
1984
    if (unlikely(!ctx->fpu_enabled)) {
1985
        GEN_EXCP_NO_FP(ctx);
1986
        return;
1987
    }
1988
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
1989
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
1990
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1991
}
1992

    
1993
/* fnabs */
1994
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
1995
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1996
/* fneg */
1997
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
1998
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1999

    
2000
/***                  Floating-Point status & ctrl register                ***/
2001
/* mcrfs */
2002
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
2003
{
2004
    int bfa;
2005

    
2006
    if (unlikely(!ctx->fpu_enabled)) {
2007
        GEN_EXCP_NO_FP(ctx);
2008
        return;
2009
    }
2010
    gen_optimize_fprf();
2011
    bfa = 4 * (7 - crfS(ctx->opcode));
2012
    gen_op_load_fpscr_T0(bfa);
2013
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
2014
    gen_op_fpscr_resetbit(~(0xF << bfa));
2015
}
2016

    
2017
/* mffs */
2018
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
2019
{
2020
    if (unlikely(!ctx->fpu_enabled)) {
2021
        GEN_EXCP_NO_FP(ctx);
2022
        return;
2023
    }
2024
    gen_optimize_fprf();
2025
    gen_reset_fpstatus();
2026
    gen_op_load_fpscr_FT0();
2027
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2028
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2029
}
2030

    
2031
/* mtfsb0 */
2032
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
2033
{
2034
    uint8_t crb;
2035

    
2036
    if (unlikely(!ctx->fpu_enabled)) {
2037
        GEN_EXCP_NO_FP(ctx);
2038
        return;
2039
    }
2040
    crb = 32 - (crbD(ctx->opcode) >> 2);
2041
    gen_optimize_fprf();
2042
    gen_reset_fpstatus();
2043
    if (likely(crb != 30 && crb != 29))
2044
        gen_op_fpscr_resetbit(~(1 << crb));
2045
    if (unlikely(Rc(ctx->opcode) != 0)) {
2046
        gen_op_load_fpcc();
2047
        gen_op_set_Rc0();
2048
    }
2049
}
2050

    
2051
/* mtfsb1 */
2052
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2053
{
2054
    uint8_t crb;
2055

    
2056
    if (unlikely(!ctx->fpu_enabled)) {
2057
        GEN_EXCP_NO_FP(ctx);
2058
        return;
2059
    }
2060
    crb = 32 - (crbD(ctx->opcode) >> 2);
2061
    gen_optimize_fprf();
2062
    gen_reset_fpstatus();
2063
    /* XXX: we pretend we can only do IEEE floating-point computations */
2064
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
2065
        gen_op_fpscr_setbit(crb);
2066
    if (unlikely(Rc(ctx->opcode) != 0)) {
2067
        gen_op_load_fpcc();
2068
        gen_op_set_Rc0();
2069
    }
2070
    /* We can raise a differed exception */
2071
    gen_op_float_check_status();
2072
}
2073

    
2074
/* mtfsf */
2075
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2076
{
2077
    if (unlikely(!ctx->fpu_enabled)) {
2078
        GEN_EXCP_NO_FP(ctx);
2079
        return;
2080
    }
2081
    gen_optimize_fprf();
2082
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2083
    gen_reset_fpstatus();
2084
    gen_op_store_fpscr(FM(ctx->opcode));
2085
    if (unlikely(Rc(ctx->opcode) != 0)) {
2086
        gen_op_load_fpcc();
2087
        gen_op_set_Rc0();
2088
    }
2089
    /* We can raise a differed exception */
2090
    gen_op_float_check_status();
2091
}
2092

    
2093
/* mtfsfi */
2094
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2095
{
2096
    int bf, sh;
2097

    
2098
    if (unlikely(!ctx->fpu_enabled)) {
2099
        GEN_EXCP_NO_FP(ctx);
2100
        return;
2101
    }
2102
    bf = crbD(ctx->opcode) >> 2;
2103
    sh = 7 - bf;
2104
    gen_optimize_fprf();
2105
    tcg_gen_movi_i64(cpu_FT[0], FPIMM(ctx->opcode) << (4 * sh));
2106
    gen_reset_fpstatus();
2107
    gen_op_store_fpscr(1 << sh);
2108
    if (unlikely(Rc(ctx->opcode) != 0)) {
2109
        gen_op_load_fpcc();
2110
        gen_op_set_Rc0();
2111
    }
2112
    /* We can raise a differed exception */
2113
    gen_op_float_check_status();
2114
}
2115

    
2116
/***                           Addressing modes                            ***/
2117
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2118
static always_inline void gen_addr_imm_index (DisasContext *ctx,
2119
                                              target_long maskl)
2120
{
2121
    target_long simm = SIMM(ctx->opcode);
2122

    
2123
    simm &= ~maskl;
2124
    if (rA(ctx->opcode) == 0) {
2125
        tcg_gen_movi_tl(cpu_T[0], simm);
2126
    } else {
2127
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
2128
        if (likely(simm != 0))
2129
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm);
2130
    }
2131
#ifdef DEBUG_MEMORY_ACCESSES
2132
    gen_op_print_mem_EA();
2133
#endif
2134
}
2135

    
2136
static always_inline void gen_addr_reg_index (DisasContext *ctx)
2137
{
2138
    if (rA(ctx->opcode) == 0) {
2139
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
2140
    } else {
2141
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
2142
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
2143
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2144
    }
2145
#ifdef DEBUG_MEMORY_ACCESSES
2146
    gen_op_print_mem_EA();
2147
#endif
2148
}
2149

    
2150
static always_inline void gen_addr_register (DisasContext *ctx)
2151
{
2152
    if (rA(ctx->opcode) == 0) {
2153
        tcg_gen_movi_tl(cpu_T[0], 0);
2154
    } else {
2155
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
2156
    }
2157
#ifdef DEBUG_MEMORY_ACCESSES
2158
    gen_op_print_mem_EA();
2159
#endif
2160
}
2161

    
2162
#if defined(TARGET_PPC64)
2163
#define _GEN_MEM_FUNCS(name, mode)                                            \
2164
    &gen_op_##name##_##mode,                                                  \
2165
    &gen_op_##name##_le_##mode,                                               \
2166
    &gen_op_##name##_64_##mode,                                               \
2167
    &gen_op_##name##_le_64_##mode
2168
#else
2169
#define _GEN_MEM_FUNCS(name, mode)                                            \
2170
    &gen_op_##name##_##mode,                                                  \
2171
    &gen_op_##name##_le_##mode
2172
#endif
2173
#if defined(CONFIG_USER_ONLY)
2174
#if defined(TARGET_PPC64)
2175
#define NB_MEM_FUNCS 4
2176
#else
2177
#define NB_MEM_FUNCS 2
2178
#endif
2179
#define GEN_MEM_FUNCS(name)                                                   \
2180
    _GEN_MEM_FUNCS(name, raw)
2181
#else
2182
#if defined(TARGET_PPC64)
2183
#define NB_MEM_FUNCS 12
2184
#else
2185
#define NB_MEM_FUNCS 6
2186
#endif
2187
#define GEN_MEM_FUNCS(name)                                                   \
2188
    _GEN_MEM_FUNCS(name, user),                                               \
2189
    _GEN_MEM_FUNCS(name, kernel),                                             \
2190
    _GEN_MEM_FUNCS(name, hypv)
2191
#endif
2192

    
2193
/***                             Integer load                              ***/
2194
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
2195
/* Byte access routine are endian safe */
2196
#define gen_op_lbz_le_raw       gen_op_lbz_raw
2197
#define gen_op_lbz_le_user      gen_op_lbz_user
2198
#define gen_op_lbz_le_kernel    gen_op_lbz_kernel
2199
#define gen_op_lbz_le_hypv      gen_op_lbz_hypv
2200
#define gen_op_lbz_le_64_raw    gen_op_lbz_64_raw
2201
#define gen_op_lbz_le_64_user   gen_op_lbz_64_user
2202
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
2203
#define gen_op_lbz_le_64_hypv   gen_op_lbz_64_hypv
2204
#define gen_op_stb_le_raw       gen_op_stb_raw
2205
#define gen_op_stb_le_user      gen_op_stb_user
2206
#define gen_op_stb_le_kernel    gen_op_stb_kernel
2207
#define gen_op_stb_le_hypv      gen_op_stb_hypv
2208
#define gen_op_stb_le_64_raw    gen_op_stb_64_raw
2209
#define gen_op_stb_le_64_user   gen_op_stb_64_user
2210
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
2211
#define gen_op_stb_le_64_hypv   gen_op_stb_64_hypv
2212
#define OP_LD_TABLE(width)                                                    \
2213
static GenOpFunc *gen_op_l##width[NB_MEM_FUNCS] = {                           \
2214
    GEN_MEM_FUNCS(l##width),                                                  \
2215
};
2216
#define OP_ST_TABLE(width)                                                    \
2217
static GenOpFunc *gen_op_st##width[NB_MEM_FUNCS] = {                          \
2218
    GEN_MEM_FUNCS(st##width),                                                 \
2219
};
2220

    
2221
#define GEN_LD(width, opc, type)                                              \
2222
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2223
{                                                                             \
2224
    gen_addr_imm_index(ctx, 0);                                               \
2225
    op_ldst(l##width);                                                        \
2226
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2227
}
2228

    
2229
#define GEN_LDU(width, opc, type)                                             \
2230
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2231
{                                                                             \
2232
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2233
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2234
        GEN_EXCP_INVAL(ctx);                                                  \
2235
        return;                                                               \
2236
    }                                                                         \
2237
    if (type == PPC_64B)                                                      \
2238
        gen_addr_imm_index(ctx, 0x03);                                        \
2239
    else                                                                      \
2240
        gen_addr_imm_index(ctx, 0);                                           \
2241
    op_ldst(l##width);                                                        \
2242
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2243
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2244
}
2245

    
2246
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2247
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2248
{                                                                             \
2249
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2250
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2251
        GEN_EXCP_INVAL(ctx);                                                  \
2252
        return;                                                               \
2253
    }                                                                         \
2254
    gen_addr_reg_index(ctx);                                                  \
2255
    op_ldst(l##width);                                                        \
2256
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2257
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2258
}
2259

    
2260
#define GEN_LDX(width, opc2, opc3, type)                                      \
2261
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2262
{                                                                             \
2263
    gen_addr_reg_index(ctx);                                                  \
2264
    op_ldst(l##width);                                                        \
2265
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2266
}
2267

    
2268
#define GEN_LDS(width, op, type)                                              \
2269
OP_LD_TABLE(width);                                                           \
2270
GEN_LD(width, op | 0x20, type);                                               \
2271
GEN_LDU(width, op | 0x21, type);                                              \
2272
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2273
GEN_LDX(width, 0x17, op | 0x00, type)
2274

    
2275
/* lbz lbzu lbzux lbzx */
2276
GEN_LDS(bz, 0x02, PPC_INTEGER);
2277
/* lha lhau lhaux lhax */
2278
GEN_LDS(ha, 0x0A, PPC_INTEGER);
2279
/* lhz lhzu lhzux lhzx */
2280
GEN_LDS(hz, 0x08, PPC_INTEGER);
2281
/* lwz lwzu lwzux lwzx */
2282
GEN_LDS(wz, 0x00, PPC_INTEGER);
2283
#if defined(TARGET_PPC64)
2284
OP_LD_TABLE(wa);
2285
OP_LD_TABLE(d);
2286
/* lwaux */
2287
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
2288
/* lwax */
2289
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
2290
/* ldux */
2291
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
2292
/* ldx */
2293
GEN_LDX(d, 0x15, 0x00, PPC_64B);
2294
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2295
{
2296
    if (Rc(ctx->opcode)) {
2297
        if (unlikely(rA(ctx->opcode) == 0 ||
2298
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2299
            GEN_EXCP_INVAL(ctx);
2300
            return;
2301
        }
2302
    }
2303
    gen_addr_imm_index(ctx, 0x03);
2304
    if (ctx->opcode & 0x02) {
2305
        /* lwa (lwau is undefined) */
2306
        op_ldst(lwa);
2307
    } else {
2308
        /* ld - ldu */
2309
        op_ldst(ld);
2310
    }
2311
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
2312
    if (Rc(ctx->opcode))
2313
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
2314
}
2315
/* lq */
2316
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2317
{
2318
#if defined(CONFIG_USER_ONLY)
2319
    GEN_EXCP_PRIVOPC(ctx);
2320
#else
2321
    int ra, rd;
2322

    
2323
    /* Restore CPU state */
2324
    if (unlikely(ctx->supervisor == 0)) {
2325
        GEN_EXCP_PRIVOPC(ctx);
2326
        return;
2327
    }
2328
    ra = rA(ctx->opcode);
2329
    rd = rD(ctx->opcode);
2330
    if (unlikely((rd & 1) || rd == ra)) {
2331
        GEN_EXCP_INVAL(ctx);
2332
        return;
2333
    }
2334
    if (unlikely(ctx->mem_idx & 1)) {
2335
        /* Little-endian mode is not handled */
2336
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2337
        return;
2338
    }
2339
    gen_addr_imm_index(ctx, 0x0F);
2340
    op_ldst(ld);
2341
    tcg_gen_mov_tl(cpu_gpr[rd], cpu_T[1]);
2342
    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 8);
2343
    op_ldst(ld);
2344
    tcg_gen_mov_tl(cpu_gpr[rd + 1], cpu_T[1]);
2345
#endif
2346
}
2347
#endif
2348

    
2349
/***                              Integer store                            ***/
2350
#define GEN_ST(width, opc, type)                                              \
2351
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2352
{                                                                             \
2353
    gen_addr_imm_index(ctx, 0);                                               \
2354
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2355
    op_ldst(st##width);                                                       \
2356
}
2357

    
2358
#define GEN_STU(width, opc, type)                                             \
2359
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2360
{                                                                             \
2361
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2362
        GEN_EXCP_INVAL(ctx);                                                  \
2363
        return;                                                               \
2364
    }                                                                         \
2365
    if (type == PPC_64B)                                                      \
2366
        gen_addr_imm_index(ctx, 0x03);                                        \
2367
    else                                                                      \
2368
        gen_addr_imm_index(ctx, 0);                                           \
2369
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2370
    op_ldst(st##width);                                                       \
2371
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2372
}
2373

    
2374
#define GEN_STUX(width, opc2, opc3, type)                                     \
2375
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2376
{                                                                             \
2377
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2378
        GEN_EXCP_INVAL(ctx);                                                  \
2379
        return;                                                               \
2380
    }                                                                         \
2381
    gen_addr_reg_index(ctx);                                                  \
2382
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2383
    op_ldst(st##width);                                                       \
2384
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2385
}
2386

    
2387
#define GEN_STX(width, opc2, opc3, type)                                      \
2388
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2389
{                                                                             \
2390
    gen_addr_reg_index(ctx);                                                  \
2391
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2392
    op_ldst(st##width);                                                       \
2393
}
2394

    
2395
#define GEN_STS(width, op, type)                                              \
2396
OP_ST_TABLE(width);                                                           \
2397
GEN_ST(width, op | 0x20, type);                                               \
2398
GEN_STU(width, op | 0x21, type);                                              \
2399
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2400
GEN_STX(width, 0x17, op | 0x00, type)
2401

    
2402
/* stb stbu stbux stbx */
2403
GEN_STS(b, 0x06, PPC_INTEGER);
2404
/* sth sthu sthux sthx */
2405
GEN_STS(h, 0x0C, PPC_INTEGER);
2406
/* stw stwu stwux stwx */
2407
GEN_STS(w, 0x04, PPC_INTEGER);
2408
#if defined(TARGET_PPC64)
2409
OP_ST_TABLE(d);
2410
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2411
GEN_STX(d, 0x15, 0x04, PPC_64B);
2412
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2413
{
2414
    int rs;
2415

    
2416
    rs = rS(ctx->opcode);
2417
    if ((ctx->opcode & 0x3) == 0x2) {
2418
#if defined(CONFIG_USER_ONLY)
2419
        GEN_EXCP_PRIVOPC(ctx);
2420
#else
2421
        /* stq */
2422
        if (unlikely(ctx->supervisor == 0)) {
2423
            GEN_EXCP_PRIVOPC(ctx);
2424
            return;
2425
        }
2426
        if (unlikely(rs & 1)) {
2427
            GEN_EXCP_INVAL(ctx);
2428
            return;
2429
        }
2430
        if (unlikely(ctx->mem_idx & 1)) {
2431
            /* Little-endian mode is not handled */
2432
            GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2433
            return;
2434
        }
2435
        gen_addr_imm_index(ctx, 0x03);
2436
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rs]);
2437
        op_ldst(std);
2438
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 8);
2439
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rs + 1]);
2440
        op_ldst(std);
2441
#endif
2442
    } else {
2443
        /* std / stdu */
2444
        if (Rc(ctx->opcode)) {
2445
            if (unlikely(rA(ctx->opcode) == 0)) {
2446
                GEN_EXCP_INVAL(ctx);
2447
                return;
2448
            }
2449
        }
2450
        gen_addr_imm_index(ctx, 0x03);
2451
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rs]);
2452
        op_ldst(std);
2453
        if (Rc(ctx->opcode))
2454
            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
2455
    }
2456
}
2457
#endif
2458
/***                Integer load and store with byte reverse               ***/
2459
/* lhbrx */
2460
OP_LD_TABLE(hbr);
2461
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2462
/* lwbrx */
2463
OP_LD_TABLE(wbr);
2464
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2465
/* sthbrx */
2466
OP_ST_TABLE(hbr);
2467
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2468
/* stwbrx */
2469
OP_ST_TABLE(wbr);
2470
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2471

    
2472
/***                    Integer load and store multiple                    ***/
2473
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2474
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
2475
    GEN_MEM_FUNCS(lmw),
2476
};
2477
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
2478
    GEN_MEM_FUNCS(stmw),
2479
};
2480

    
2481
/* lmw */
2482
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2483
{
2484
    /* NIP cannot be restored if the memory exception comes from an helper */
2485
    gen_update_nip(ctx, ctx->nip - 4);
2486
    gen_addr_imm_index(ctx, 0);
2487
    op_ldstm(lmw, rD(ctx->opcode));
2488
}
2489

    
2490
/* stmw */
2491
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2492
{
2493
    /* NIP cannot be restored if the memory exception comes from an helper */
2494
    gen_update_nip(ctx, ctx->nip - 4);
2495
    gen_addr_imm_index(ctx, 0);
2496
    op_ldstm(stmw, rS(ctx->opcode));
2497
}
2498

    
2499
/***                    Integer load and store strings                     ***/
2500
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2501
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2502
/* string load & stores are by definition endian-safe */
2503
#define gen_op_lswi_le_raw       gen_op_lswi_raw
2504
#define gen_op_lswi_le_user      gen_op_lswi_user
2505
#define gen_op_lswi_le_kernel    gen_op_lswi_kernel
2506
#define gen_op_lswi_le_hypv      gen_op_lswi_hypv
2507
#define gen_op_lswi_le_64_raw    gen_op_lswi_raw
2508
#define gen_op_lswi_le_64_user   gen_op_lswi_user
2509
#define gen_op_lswi_le_64_kernel gen_op_lswi_kernel
2510
#define gen_op_lswi_le_64_hypv   gen_op_lswi_hypv
2511
static GenOpFunc1 *gen_op_lswi[NB_MEM_FUNCS] = {
2512
    GEN_MEM_FUNCS(lswi),
2513
};
2514
#define gen_op_lswx_le_raw       gen_op_lswx_raw
2515
#define gen_op_lswx_le_user      gen_op_lswx_user
2516
#define gen_op_lswx_le_kernel    gen_op_lswx_kernel
2517
#define gen_op_lswx_le_hypv      gen_op_lswx_hypv
2518
#define gen_op_lswx_le_64_raw    gen_op_lswx_raw
2519
#define gen_op_lswx_le_64_user   gen_op_lswx_user
2520
#define gen_op_lswx_le_64_kernel gen_op_lswx_kernel
2521
#define gen_op_lswx_le_64_hypv   gen_op_lswx_hypv
2522
static GenOpFunc3 *gen_op_lswx[NB_MEM_FUNCS] = {
2523
    GEN_MEM_FUNCS(lswx),
2524
};
2525
#define gen_op_stsw_le_raw       gen_op_stsw_raw
2526
#define gen_op_stsw_le_user      gen_op_stsw_user
2527
#define gen_op_stsw_le_kernel    gen_op_stsw_kernel
2528
#define gen_op_stsw_le_hypv      gen_op_stsw_hypv
2529
#define gen_op_stsw_le_64_raw    gen_op_stsw_raw
2530
#define gen_op_stsw_le_64_user   gen_op_stsw_user
2531
#define gen_op_stsw_le_64_kernel gen_op_stsw_kernel
2532
#define gen_op_stsw_le_64_hypv   gen_op_stsw_hypv
2533
static GenOpFunc1 *gen_op_stsw[NB_MEM_FUNCS] = {
2534
    GEN_MEM_FUNCS(stsw),
2535
};
2536

    
2537
/* lswi */
2538
/* PowerPC32 specification says we must generate an exception if
2539
 * rA is in the range of registers to be loaded.
2540
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2541
 * For now, I'll follow the spec...
2542
 */
2543
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
2544
{
2545
    int nb = NB(ctx->opcode);
2546
    int start = rD(ctx->opcode);
2547
    int ra = rA(ctx->opcode);
2548
    int nr;
2549

    
2550
    if (nb == 0)
2551
        nb = 32;
2552
    nr = nb / 4;
2553
    if (unlikely(((start + nr) > 32  &&
2554
                  start <= ra && (start + nr - 32) > ra) ||
2555
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2556
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
2557
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
2558
        return;
2559
    }
2560
    /* NIP cannot be restored if the memory exception comes from an helper */
2561
    gen_update_nip(ctx, ctx->nip - 4);
2562
    gen_addr_register(ctx);
2563
    tcg_gen_movi_tl(cpu_T[1], nb);
2564
    op_ldsts(lswi, start);
2565
}
2566

    
2567
/* lswx */
2568
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
2569
{
2570
    int ra = rA(ctx->opcode);
2571
    int rb = rB(ctx->opcode);
2572

    
2573
    /* NIP cannot be restored if the memory exception comes from an helper */
2574
    gen_update_nip(ctx, ctx->nip - 4);
2575
    gen_addr_reg_index(ctx);
2576
    if (ra == 0) {
2577
        ra = rb;
2578
    }
2579
    gen_op_load_xer_bc();
2580
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2581
}
2582

    
2583
/* stswi */
2584
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
2585
{
2586
    int nb = NB(ctx->opcode);
2587

    
2588
    /* NIP cannot be restored if the memory exception comes from an helper */
2589
    gen_update_nip(ctx, ctx->nip - 4);
2590
    gen_addr_register(ctx);
2591
    if (nb == 0)
2592
        nb = 32;
2593
    tcg_gen_movi_tl(cpu_T[1], nb);
2594
    op_ldsts(stsw, rS(ctx->opcode));
2595
}
2596

    
2597
/* stswx */
2598
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
2599
{
2600
    /* NIP cannot be restored if the memory exception comes from an helper */
2601
    gen_update_nip(ctx, ctx->nip - 4);
2602
    gen_addr_reg_index(ctx);
2603
    gen_op_load_xer_bc();
2604
    op_ldsts(stsw, rS(ctx->opcode));
2605
}
2606

    
2607
/***                        Memory synchronisation                         ***/
2608
/* eieio */
2609
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2610
{
2611
}
2612

    
2613
/* isync */
2614
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2615
{
2616
    GEN_STOP(ctx);
2617
}
2618

    
2619
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2620
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2621
static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
2622
    GEN_MEM_FUNCS(lwarx),
2623
};
2624
static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
2625
    GEN_MEM_FUNCS(stwcx),
2626
};
2627

    
2628
/* lwarx */
2629
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2630
{
2631
    /* NIP cannot be restored if the memory exception comes from an helper */
2632
    gen_update_nip(ctx, ctx->nip - 4);
2633
    gen_addr_reg_index(ctx);
2634
    op_lwarx();
2635
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
2636
}
2637

    
2638
/* stwcx. */
2639
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2640
{
2641
    /* NIP cannot be restored if the memory exception comes from an helper */
2642
    gen_update_nip(ctx, ctx->nip - 4);
2643
    gen_addr_reg_index(ctx);
2644
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
2645
    op_stwcx();
2646
}
2647

    
2648
#if defined(TARGET_PPC64)
2649
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2650
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2651
static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
2652
    GEN_MEM_FUNCS(ldarx),
2653
};
2654
static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
2655
    GEN_MEM_FUNCS(stdcx),
2656
};
2657

    
2658
/* ldarx */
2659
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2660
{
2661
    /* NIP cannot be restored if the memory exception comes from an helper */
2662
    gen_update_nip(ctx, ctx->nip - 4);
2663
    gen_addr_reg_index(ctx);
2664
    op_ldarx();
2665
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
2666
}
2667

    
2668
/* stdcx. */
2669
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2670
{
2671
    /* NIP cannot be restored if the memory exception comes from an helper */
2672
    gen_update_nip(ctx, ctx->nip - 4);
2673
    gen_addr_reg_index(ctx);
2674
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
2675
    op_stdcx();
2676
}
2677
#endif /* defined(TARGET_PPC64) */
2678

    
2679
/* sync */
2680
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
2681
{
2682
}
2683

    
2684
/* wait */
2685
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2686
{
2687
    /* Stop translation, as the CPU is supposed to sleep from now */
2688
    gen_op_wait();
2689
    GEN_EXCP(ctx, EXCP_HLT, 1);
2690
}
2691

    
2692
/***                         Floating-point load                           ***/
2693
#define GEN_LDF(width, opc, type)                                             \
2694
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2695
{                                                                             \
2696
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2697
        GEN_EXCP_NO_FP(ctx);                                                  \
2698
        return;                                                               \
2699
    }                                                                         \
2700
    gen_addr_imm_index(ctx, 0);                                               \
2701
    op_ldst(l##width);                                                        \
2702
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2703
}
2704

    
2705
#define GEN_LDUF(width, opc, type)                                            \
2706
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2707
{                                                                             \
2708
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2709
        GEN_EXCP_NO_FP(ctx);                                                  \
2710
        return;                                                               \
2711
    }                                                                         \
2712
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2713
        GEN_EXCP_INVAL(ctx);                                                  \
2714
        return;                                                               \
2715
    }                                                                         \
2716
    gen_addr_imm_index(ctx, 0);                                               \
2717
    op_ldst(l##width);                                                        \
2718
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2719
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2720
}
2721

    
2722
#define GEN_LDUXF(width, opc, type)                                           \
2723
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
2724
{                                                                             \
2725
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2726
        GEN_EXCP_NO_FP(ctx);                                                  \
2727
        return;                                                               \
2728
    }                                                                         \
2729
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2730
        GEN_EXCP_INVAL(ctx);                                                  \
2731
        return;                                                               \
2732
    }                                                                         \
2733
    gen_addr_reg_index(ctx);                                                  \
2734
    op_ldst(l##width);                                                        \
2735
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2736
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2737
}
2738

    
2739
#define GEN_LDXF(width, opc2, opc3, type)                                     \
2740
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2741
{                                                                             \
2742
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2743
        GEN_EXCP_NO_FP(ctx);                                                  \
2744
        return;                                                               \
2745
    }                                                                         \
2746
    gen_addr_reg_index(ctx);                                                  \
2747
    op_ldst(l##width);                                                        \
2748
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2749
}
2750

    
2751
#define GEN_LDFS(width, op, type)                                             \
2752
OP_LD_TABLE(width);                                                           \
2753
GEN_LDF(width, op | 0x20, type);                                              \
2754
GEN_LDUF(width, op | 0x21, type);                                             \
2755
GEN_LDUXF(width, op | 0x01, type);                                            \
2756
GEN_LDXF(width, 0x17, op | 0x00, type)
2757

    
2758
/* lfd lfdu lfdux lfdx */
2759
GEN_LDFS(fd, 0x12, PPC_FLOAT);
2760
/* lfs lfsu lfsux lfsx */
2761
GEN_LDFS(fs, 0x10, PPC_FLOAT);
2762

    
2763
/***                         Floating-point store                          ***/
2764
#define GEN_STF(width, opc, type)                                             \
2765
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2766
{                                                                             \
2767
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2768
        GEN_EXCP_NO_FP(ctx);                                                  \
2769
        return;                                                               \
2770
    }                                                                         \
2771
    gen_addr_imm_index(ctx, 0);                                               \
2772
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
2773
    op_ldst(st##width);                                                       \
2774
}
2775

    
2776
#define GEN_STUF(width, opc, type)                                            \
2777
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2778
{                                                                             \
2779
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2780
        GEN_EXCP_NO_FP(ctx);                                                  \
2781
        return;                                                               \
2782
    }                                                                         \
2783
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2784
        GEN_EXCP_INVAL(ctx);                                                  \
2785
        return;                                                               \
2786
    }                                                                         \
2787
    gen_addr_imm_index(ctx, 0);                                               \
2788
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
2789
    op_ldst(st##width);                                                       \
2790
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2791
}
2792

    
2793
#define GEN_STUXF(width, opc, type)                                           \
2794
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
2795
{                                                                             \
2796
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2797
        GEN_EXCP_NO_FP(ctx);                                                  \
2798
        return;                                                               \
2799
    }                                                                         \
2800
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2801
        GEN_EXCP_INVAL(ctx);                                                  \
2802
        return;                                                               \
2803
    }                                                                         \
2804
    gen_addr_reg_index(ctx);                                                  \
2805
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
2806
    op_ldst(st##width);                                                       \
2807
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2808
}
2809

    
2810
#define GEN_STXF(width, opc2, opc3, type)                                     \
2811
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2812
{                                                                             \
2813
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2814
        GEN_EXCP_NO_FP(ctx);                                                  \
2815
        return;                                                               \
2816
    }                                                                         \
2817
    gen_addr_reg_index(ctx);                                                  \
2818
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
2819
    op_ldst(st##width);                                                       \
2820
}
2821

    
2822
#define GEN_STFS(width, op, type)                                             \
2823
OP_ST_TABLE(width);                                                           \
2824
GEN_STF(width, op | 0x20, type);                                              \
2825
GEN_STUF(width, op | 0x21, type);                                             \
2826
GEN_STUXF(width, op | 0x01, type);                                            \
2827
GEN_STXF(width, 0x17, op | 0x00, type)
2828

    
2829
/* stfd stfdu stfdux stfdx */
2830
GEN_STFS(fd, 0x16, PPC_FLOAT);
2831
/* stfs stfsu stfsux stfsx */
2832
GEN_STFS(fs, 0x14, PPC_FLOAT);
2833

    
2834
/* Optional: */
2835
/* stfiwx */
2836
OP_ST_TABLE(fiw);
2837
GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2838

    
2839
/***                                Branch                                 ***/
2840
static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2841
                                       target_ulong dest)
2842
{
2843
    TranslationBlock *tb;
2844
    tb = ctx->tb;
2845
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2846
        likely(!ctx->singlestep_enabled)) {
2847
        tcg_gen_goto_tb(n);
2848
        tcg_gen_movi_tl(cpu_T[1], dest);
2849
#if defined(TARGET_PPC64)
2850
        if (ctx->sf_mode)
2851
            tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3);
2852
        else
2853
#endif
2854
            tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3);
2855
        tcg_gen_exit_tb((long)tb + n);
2856
    } else {
2857
        tcg_gen_movi_tl(cpu_T[1], dest);
2858
#if defined(TARGET_PPC64)
2859
        if (ctx->sf_mode)
2860
            tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3);
2861
        else
2862
#endif
2863
            tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3);
2864
        if (unlikely(ctx->singlestep_enabled)) {
2865
            if ((ctx->singlestep_enabled &
2866
                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
2867
                ctx->exception == POWERPC_EXCP_BRANCH) {
2868
                target_ulong tmp = ctx->nip;
2869
                ctx->nip = dest;
2870
                GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
2871
                ctx->nip = tmp;
2872
            }
2873
            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
2874
                gen_update_nip(ctx, dest);
2875
                gen_op_debug();
2876
            }
2877
        }
2878
        tcg_gen_exit_tb(0);
2879
    }
2880
}
2881

    
2882
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2883
{
2884
#if defined(TARGET_PPC64)
2885
    if (ctx->sf_mode != 0 && (nip >> 32))
2886
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2887
    else
2888
#endif
2889
        gen_op_setlr(ctx->nip);
2890
}
2891

    
2892
/* b ba bl bla */
2893
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2894
{
2895
    target_ulong li, target;
2896

    
2897
    ctx->exception = POWERPC_EXCP_BRANCH;
2898
    /* sign extend LI */
2899
#if defined(TARGET_PPC64)
2900
    if (ctx->sf_mode)
2901
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2902
    else
2903
#endif
2904
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2905
    if (likely(AA(ctx->opcode) == 0))
2906
        target = ctx->nip + li - 4;
2907
    else
2908
        target = li;
2909
#if defined(TARGET_PPC64)
2910
    if (!ctx->sf_mode)
2911
        target = (uint32_t)target;
2912
#endif
2913
    if (LK(ctx->opcode))
2914
        gen_setlr(ctx, ctx->nip);
2915
    gen_goto_tb(ctx, 0, target);
2916
}
2917

    
2918
#define BCOND_IM  0
2919
#define BCOND_LR  1
2920
#define BCOND_CTR 2
2921

    
2922
static always_inline void gen_bcond (DisasContext *ctx, int type)
2923
{
2924
    target_ulong target = 0;
2925
    target_ulong li;
2926
    uint32_t bo = BO(ctx->opcode);
2927
    uint32_t bi = BI(ctx->opcode);
2928
    uint32_t mask;
2929

    
2930
    ctx->exception = POWERPC_EXCP_BRANCH;
2931
    if ((bo & 0x4) == 0)
2932
        gen_op_dec_ctr();
2933
    switch(type) {
2934
    case BCOND_IM:
2935
        li = (target_long)((int16_t)(BD(ctx->opcode)));
2936
        if (likely(AA(ctx->opcode) == 0)) {
2937
            target = ctx->nip + li - 4;
2938
        } else {
2939
            target = li;
2940
        }
2941
#if defined(TARGET_PPC64)
2942
        if (!ctx->sf_mode)
2943
            target = (uint32_t)target;
2944
#endif
2945
        break;
2946
    case BCOND_CTR:
2947
        gen_op_movl_T1_ctr();
2948
        break;
2949
    default:
2950
    case BCOND_LR:
2951
        gen_op_movl_T1_lr();
2952
        break;
2953
    }
2954
    if (LK(ctx->opcode))
2955
        gen_setlr(ctx, ctx->nip);
2956
    if (bo & 0x10) {
2957
        /* No CR condition */
2958
        switch (bo & 0x6) {
2959
        case 0:
2960
#if defined(TARGET_PPC64)
2961
            if (ctx->sf_mode)
2962
                gen_op_test_ctr_64();
2963
            else
2964
#endif
2965
                gen_op_test_ctr();
2966
            break;
2967
        case 2:
2968
#if defined(TARGET_PPC64)
2969
            if (ctx->sf_mode)
2970
                gen_op_test_ctrz_64();
2971
            else
2972
#endif
2973
                gen_op_test_ctrz();
2974
            break;
2975
        default:
2976
        case 4:
2977
        case 6:
2978
            if (type == BCOND_IM) {
2979
                gen_goto_tb(ctx, 0, target);
2980
                return;
2981
            } else {
2982
#if defined(TARGET_PPC64)
2983
                if (ctx->sf_mode)
2984
                    tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3);
2985
                else
2986
#endif
2987
                    tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3);
2988
                goto no_test;
2989
            }
2990
            break;
2991
        }
2992
    } else {
2993
        mask = 1 << (3 - (bi & 0x03));
2994
        tcg_gen_mov_i32(cpu_T[0], cpu_crf[bi >> 2]);
2995
        if (bo & 0x8) {
2996
            switch (bo & 0x6) {
2997
            case 0:
2998
#if defined(TARGET_PPC64)
2999
                if (ctx->sf_mode)
3000
                    gen_op_test_ctr_true_64(mask);
3001
                else
3002
#endif
3003
                    gen_op_test_ctr_true(mask);
3004
                break;
3005
            case 2:
3006
#if defined(TARGET_PPC64)
3007
                if (ctx->sf_mode)
3008
                    gen_op_test_ctrz_true_64(mask);
3009
                else
3010
#endif
3011
                    gen_op_test_ctrz_true(mask);
3012
                break;
3013
            default:
3014
            case 4:
3015
            case 6:
3016
                gen_op_test_true(mask);
3017
                break;
3018
            }
3019
        } else {
3020
            switch (bo & 0x6) {
3021
            case 0:
3022
#if defined(TARGET_PPC64)
3023
                if (ctx->sf_mode)
3024
                    gen_op_test_ctr_false_64(mask);
3025
                else
3026
#endif
3027
                    gen_op_test_ctr_false(mask);
3028
                break;
3029
            case 2:
3030
#if defined(TARGET_PPC64)
3031
                if (ctx->sf_mode)
3032
                    gen_op_test_ctrz_false_64(mask);
3033
                else
3034
#endif
3035
                    gen_op_test_ctrz_false(mask);
3036
                break;
3037
            default:
3038
            case 4:
3039
            case 6:
3040
                gen_op_test_false(mask);
3041
                break;
3042
            }
3043
        }
3044
    }
3045
    if (type == BCOND_IM) {
3046
        int l1 = gen_new_label();
3047
        gen_op_jz_T0(l1);
3048
        gen_goto_tb(ctx, 0, target);
3049
        gen_set_label(l1);
3050
        gen_goto_tb(ctx, 1, ctx->nip);
3051
    } else {
3052
#if defined(TARGET_PPC64)
3053
        if (ctx->sf_mode)
3054
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
3055
        else
3056
#endif
3057
            gen_op_btest_T1(ctx->nip);
3058
    no_test:
3059
        if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3060
            gen_update_nip(ctx, ctx->nip);
3061
            gen_op_debug();
3062
        }
3063
        tcg_gen_exit_tb(0);
3064
    }
3065
}
3066

    
3067
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3068
{
3069
    gen_bcond(ctx, BCOND_IM);
3070
}
3071

    
3072
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3073
{
3074
    gen_bcond(ctx, BCOND_CTR);
3075
}
3076

    
3077
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3078
{
3079
    gen_bcond(ctx, BCOND_LR);
3080
}
3081

    
3082
/***                      Condition register logical                       ***/
3083
#define GEN_CRLOGIC(op, opc)                                                  \
3084
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
3085
{                                                                             \
3086
    uint8_t bitmask;                                                          \
3087
    int sh;                                                                   \
3088
    tcg_gen_mov_i32(cpu_T[0], cpu_crf[crbA(ctx->opcode) >> 2]);               \
3089
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3090
    if (sh > 0)                                                               \
3091
        gen_op_srli_T0(sh);                                                   \
3092
    else if (sh < 0)                                                          \
3093
        gen_op_sli_T0(-sh);                                                   \
3094
    tcg_gen_mov_i32(cpu_T[1], cpu_crf[crbB(ctx->opcode) >> 2]);               \
3095
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3096
    if (sh > 0)                                                               \
3097
        gen_op_srli_T1(sh);                                                   \
3098
    else if (sh < 0)                                                          \
3099
        gen_op_sli_T1(-sh);                                                   \
3100
    gen_op_##op();                                                            \
3101
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3102
    gen_op_andi_T0(bitmask);                                                  \
3103
    tcg_gen_andi_i32(cpu_T[1], cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);    \
3104
    gen_op_or();                                                              \
3105
    tcg_gen_andi_i32(cpu_crf[crbD(ctx->opcode) >> 2], cpu_T[0], 0xf);         \
3106
}
3107

    
3108
/* crand */
3109
GEN_CRLOGIC(and, 0x08);
3110
/* crandc */
3111
GEN_CRLOGIC(andc, 0x04);
3112
/* creqv */
3113
GEN_CRLOGIC(eqv, 0x09);
3114
/* crnand */
3115
GEN_CRLOGIC(nand, 0x07);
3116
/* crnor */
3117
GEN_CRLOGIC(nor, 0x01);
3118
/* cror */
3119
GEN_CRLOGIC(or, 0x0E);
3120
/* crorc */
3121
GEN_CRLOGIC(orc, 0x0D);
3122
/* crxor */
3123
GEN_CRLOGIC(xor, 0x06);
3124
/* mcrf */
3125
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3126
{
3127
    tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
3128
}
3129

    
3130
/***                           System linkage                              ***/
3131
/* rfi (supervisor only) */
3132
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3133
{
3134
#if defined(CONFIG_USER_ONLY)
3135
    GEN_EXCP_PRIVOPC(ctx);
3136
#else
3137
    /* Restore CPU state */
3138
    if (unlikely(!ctx->supervisor)) {
3139
        GEN_EXCP_PRIVOPC(ctx);
3140
        return;
3141
    }
3142
    gen_op_rfi();
3143
    GEN_SYNC(ctx);
3144
#endif
3145
}
3146

    
3147
#if defined(TARGET_PPC64)
3148
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3149
{
3150
#if defined(CONFIG_USER_ONLY)
3151
    GEN_EXCP_PRIVOPC(ctx);
3152
#else
3153
    /* Restore CPU state */
3154
    if (unlikely(!ctx->supervisor)) {
3155
        GEN_EXCP_PRIVOPC(ctx);
3156
        return;
3157
    }
3158
    gen_op_rfid();
3159
    GEN_SYNC(ctx);
3160
#endif
3161
}
3162

    
3163
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3164
{
3165
#if defined(CONFIG_USER_ONLY)
3166
    GEN_EXCP_PRIVOPC(ctx);
3167
#else
3168
    /* Restore CPU state */
3169
    if (unlikely(ctx->supervisor <= 1)) {
3170
        GEN_EXCP_PRIVOPC(ctx);
3171
        return;
3172
    }
3173
    gen_op_hrfid();
3174
    GEN_SYNC(ctx);
3175
#endif
3176
}
3177
#endif
3178

    
3179
/* sc */
3180
#if defined(CONFIG_USER_ONLY)
3181
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3182
#else
3183
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3184
#endif
3185
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3186
{
3187
    uint32_t lev;
3188

    
3189
    lev = (ctx->opcode >> 5) & 0x7F;
3190
    GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
3191
}
3192

    
3193
/***                                Trap                                   ***/
3194
/* tw */
3195
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3196
{
3197
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3198
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3199
    /* Update the nip since this might generate a trap exception */
3200
    gen_update_nip(ctx, ctx->nip);
3201
    gen_op_tw(TO(ctx->opcode));
3202
}
3203

    
3204
/* twi */
3205
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3206
{
3207
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3208
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3209
    /* Update the nip since this might generate a trap exception */
3210
    gen_update_nip(ctx, ctx->nip);
3211
    gen_op_tw(TO(ctx->opcode));
3212
}
3213

    
3214
#if defined(TARGET_PPC64)
3215
/* td */
3216
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3217
{
3218
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3219
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3220
    /* Update the nip since this might generate a trap exception */
3221
    gen_update_nip(ctx, ctx->nip);
3222
    gen_op_td(TO(ctx->opcode));
3223
}
3224

    
3225
/* tdi */
3226
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3227
{
3228
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3229
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3230
    /* Update the nip since this might generate a trap exception */
3231
    gen_update_nip(ctx, ctx->nip);
3232
    gen_op_td(TO(ctx->opcode));
3233
}
3234
#endif
3235

    
3236
/***                          Processor control                            ***/
3237
/* mcrxr */
3238
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3239
{
3240
    gen_op_load_xer_cr();
3241
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
3242
    gen_op_clear_xer_ov();
3243
    gen_op_clear_xer_ca();
3244
}
3245

    
3246
/* mfcr */
3247
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3248
{
3249
    uint32_t crm, crn;
3250

    
3251
    if (likely(ctx->opcode & 0x00100000)) {
3252
        crm = CRM(ctx->opcode);
3253
        if (likely((crm ^ (crm - 1)) == 0)) {
3254
            crn = ffs(crm);
3255
            tcg_gen_mov_i32(cpu_T[0], cpu_crf[7 - crn]);
3256
        }
3257
    } else {
3258
        gen_op_load_cr();
3259
    }
3260
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3261
}
3262

    
3263
/* mfmsr */
3264
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3265
{
3266
#if defined(CONFIG_USER_ONLY)
3267
    GEN_EXCP_PRIVREG(ctx);
3268
#else
3269
    if (unlikely(!ctx->supervisor)) {
3270
        GEN_EXCP_PRIVREG(ctx);
3271
        return;
3272
    }
3273
    gen_op_load_msr();
3274
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3275
#endif
3276
}
3277

    
3278
#if 1
3279
#define SPR_NOACCESS ((void *)(-1UL))
3280
#else
3281
static void spr_noaccess (void *opaque, int sprn)
3282
{
3283
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3284
    printf("ERROR: try to access SPR %d !\n", sprn);
3285
}
3286
#define SPR_NOACCESS (&spr_noaccess)
3287
#endif
3288

    
3289
/* mfspr */
3290
static always_inline void gen_op_mfspr (DisasContext *ctx)
3291
{
3292
    void (*read_cb)(void *opaque, int sprn);
3293
    uint32_t sprn = SPR(ctx->opcode);
3294

    
3295
#if !defined(CONFIG_USER_ONLY)
3296
    if (ctx->supervisor == 2)
3297
        read_cb = ctx->spr_cb[sprn].hea_read;
3298
    else if (ctx->supervisor)
3299
        read_cb = ctx->spr_cb[sprn].oea_read;
3300
    else
3301
#endif
3302
        read_cb = ctx->spr_cb[sprn].uea_read;
3303
    if (likely(read_cb != NULL)) {
3304
        if (likely(read_cb != SPR_NOACCESS)) {
3305
            (*read_cb)(ctx, sprn);
3306
            tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3307
        } else {
3308
            /* Privilege exception */
3309
            /* This is a hack to avoid warnings when running Linux:
3310
             * this OS breaks the PowerPC virtualisation model,
3311
             * allowing userland application to read the PVR
3312
             */
3313
            if (sprn != SPR_PVR) {
3314
                if (loglevel != 0) {
3315
                    fprintf(logfile, "Trying to read privileged spr %d %03x at "
3316
                            ADDRX "\n", sprn, sprn, ctx->nip);
3317
                }
3318
                printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
3319
                       sprn, sprn, ctx->nip);
3320
            }
3321
            GEN_EXCP_PRIVREG(ctx);
3322
        }
3323
    } else {
3324
        /* Not defined */
3325
        if (loglevel != 0) {
3326
            fprintf(logfile, "Trying to read invalid spr %d %03x at "
3327
                    ADDRX "\n", sprn, sprn, ctx->nip);
3328
        }
3329
        printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
3330
               sprn, sprn, ctx->nip);
3331
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3332
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3333
    }
3334
}
3335

    
3336
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3337
{
3338
    gen_op_mfspr(ctx);
3339
}
3340

    
3341
/* mftb */
3342
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3343
{
3344
    gen_op_mfspr(ctx);
3345
}
3346

    
3347
/* mtcrf */
3348
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3349
{
3350
    uint32_t crm, crn;
3351

    
3352
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3353
    crm = CRM(ctx->opcode);
3354
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3355
        crn = ffs(crm);
3356
        gen_op_srli_T0(crn * 4);
3357
        tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_T[0], 0xf);
3358
    } else {
3359
        gen_op_store_cr(crm);
3360
    }
3361
}
3362

    
3363
/* mtmsr */
3364
#if defined(TARGET_PPC64)
3365
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3366
{
3367
#if defined(CONFIG_USER_ONLY)
3368
    GEN_EXCP_PRIVREG(ctx);
3369
#else
3370
    if (unlikely(!ctx->supervisor)) {
3371
        GEN_EXCP_PRIVREG(ctx);
3372
        return;
3373
    }
3374
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3375
    if (ctx->opcode & 0x00010000) {
3376
        /* Special form that does not need any synchronisation */
3377
        gen_op_update_riee();
3378
    } else {
3379
        /* XXX: we need to update nip before the store
3380
         *      if we enter power saving mode, we will exit the loop
3381
         *      directly from ppc_store_msr
3382
         */
3383
        gen_update_nip(ctx, ctx->nip);
3384
        gen_op_store_msr();
3385
        /* Must stop the translation as machine state (may have) changed */
3386
        /* Note that mtmsr is not always defined as context-synchronizing */
3387
        ctx->exception = POWERPC_EXCP_STOP;
3388
    }
3389
#endif
3390
}
3391
#endif
3392

    
3393
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3394
{
3395
#if defined(CONFIG_USER_ONLY)
3396
    GEN_EXCP_PRIVREG(ctx);
3397
#else
3398
    if (unlikely(!ctx->supervisor)) {
3399
        GEN_EXCP_PRIVREG(ctx);
3400
        return;
3401
    }
3402
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3403
    if (ctx->opcode & 0x00010000) {
3404
        /* Special form that does not need any synchronisation */
3405
        gen_op_update_riee();
3406
    } else {
3407
        /* XXX: we need to update nip before the store
3408
         *      if we enter power saving mode, we will exit the loop
3409
         *      directly from ppc_store_msr
3410
         */
3411
        gen_update_nip(ctx, ctx->nip);
3412
#if defined(TARGET_PPC64)
3413
        if (!ctx->sf_mode)
3414
            gen_op_store_msr_32();
3415
        else
3416
#endif
3417
            gen_op_store_msr();
3418
        /* Must stop the translation as machine state (may have) changed */
3419
        /* Note that mtmsrd is not always defined as context-synchronizing */
3420
        ctx->exception = POWERPC_EXCP_STOP;
3421
    }
3422
#endif
3423
}
3424

    
3425
/* mtspr */
3426
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3427
{
3428
    void (*write_cb)(void *opaque, int sprn);
3429
    uint32_t sprn = SPR(ctx->opcode);
3430

    
3431
#if !defined(CONFIG_USER_ONLY)
3432
    if (ctx->supervisor == 2)
3433
        write_cb = ctx->spr_cb[sprn].hea_write;
3434
    else if (ctx->supervisor)
3435
        write_cb = ctx->spr_cb[sprn].oea_write;
3436
    else
3437
#endif
3438
        write_cb = ctx->spr_cb[sprn].uea_write;
3439
    if (likely(write_cb != NULL)) {
3440
        if (likely(write_cb != SPR_NOACCESS)) {
3441
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3442
            (*write_cb)(ctx, sprn);
3443
        } else {
3444
            /* Privilege exception */
3445
            if (loglevel != 0) {
3446
                fprintf(logfile, "Trying to write privileged spr %d %03x at "
3447
                        ADDRX "\n", sprn, sprn, ctx->nip);
3448
            }
3449
            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
3450
                   sprn, sprn, ctx->nip);
3451
            GEN_EXCP_PRIVREG(ctx);
3452
        }
3453
    } else {
3454
        /* Not defined */
3455
        if (loglevel != 0) {
3456
            fprintf(logfile, "Trying to write invalid spr %d %03x at "
3457
                    ADDRX "\n", sprn, sprn, ctx->nip);
3458
        }
3459
        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
3460
               sprn, sprn, ctx->nip);
3461
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3462
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3463
    }
3464
}
3465

    
3466
/***                         Cache management                              ***/
3467
/* dcbf */
3468
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3469
{
3470
    /* XXX: specification says this is treated as a load by the MMU */
3471
    gen_addr_reg_index(ctx);
3472
    op_ldst(lbz);
3473
}
3474

    
3475
/* dcbi (Supervisor only) */
3476
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3477
{
3478
#if defined(CONFIG_USER_ONLY)
3479
    GEN_EXCP_PRIVOPC(ctx);
3480
#else
3481
    if (unlikely(!ctx->supervisor)) {
3482
        GEN_EXCP_PRIVOPC(ctx);
3483
        return;
3484
    }
3485
    gen_addr_reg_index(ctx);
3486
    /* XXX: specification says this should be treated as a store by the MMU */
3487
    op_ldst(lbz);
3488
    op_ldst(stb);
3489
#endif
3490
}
3491

    
3492
/* dcdst */
3493
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3494
{
3495
    /* XXX: specification say this is treated as a load by the MMU */
3496
    gen_addr_reg_index(ctx);
3497
    op_ldst(lbz);
3498
}
3499

    
3500
/* dcbt */
3501
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3502
{
3503
    /* interpreted as no-op */
3504
    /* XXX: specification say this is treated as a load by the MMU
3505
     *      but does not generate any exception
3506
     */
3507
}
3508

    
3509
/* dcbtst */
3510
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3511
{
3512
    /* interpreted as no-op */
3513
    /* XXX: specification say this is treated as a load by the MMU
3514
     *      but does not generate any exception
3515
     */
3516
}
3517

    
3518
/* dcbz */
3519
#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
3520
static GenOpFunc *gen_op_dcbz[4][NB_MEM_FUNCS] = {
3521
    /* 32 bytes cache line size */
3522
    {
3523
#define gen_op_dcbz_l32_le_raw        gen_op_dcbz_l32_raw
3524
#define gen_op_dcbz_l32_le_user       gen_op_dcbz_l32_user
3525
#define gen_op_dcbz_l32_le_kernel     gen_op_dcbz_l32_kernel
3526
#define gen_op_dcbz_l32_le_hypv       gen_op_dcbz_l32_hypv
3527
#define gen_op_dcbz_l32_le_64_raw     gen_op_dcbz_l32_64_raw
3528
#define gen_op_dcbz_l32_le_64_user    gen_op_dcbz_l32_64_user
3529
#define gen_op_dcbz_l32_le_64_kernel  gen_op_dcbz_l32_64_kernel
3530
#define gen_op_dcbz_l32_le_64_hypv    gen_op_dcbz_l32_64_hypv
3531
        GEN_MEM_FUNCS(dcbz_l32),
3532
    },
3533
    /* 64 bytes cache line size */
3534
    {
3535
#define gen_op_dcbz_l64_le_raw        gen_op_dcbz_l64_raw
3536
#define gen_op_dcbz_l64_le_user       gen_op_dcbz_l64_user
3537
#define gen_op_dcbz_l64_le_kernel     gen_op_dcbz_l64_kernel
3538
#define gen_op_dcbz_l64_le_hypv       gen_op_dcbz_l64_hypv
3539
#define gen_op_dcbz_l64_le_64_raw     gen_op_dcbz_l64_64_raw
3540
#define gen_op_dcbz_l64_le_64_user    gen_op_dcbz_l64_64_user
3541
#define gen_op_dcbz_l64_le_64_kernel  gen_op_dcbz_l64_64_kernel
3542
#define gen_op_dcbz_l64_le_64_hypv    gen_op_dcbz_l64_64_hypv
3543
        GEN_MEM_FUNCS(dcbz_l64),
3544
    },
3545
    /* 128 bytes cache line size */
3546
    {
3547
#define gen_op_dcbz_l128_le_raw       gen_op_dcbz_l128_raw
3548
#define gen_op_dcbz_l128_le_user      gen_op_dcbz_l128_user
3549
#define gen_op_dcbz_l128_le_kernel    gen_op_dcbz_l128_kernel
3550
#define gen_op_dcbz_l128_le_hypv      gen_op_dcbz_l128_hypv
3551
#define gen_op_dcbz_l128_le_64_raw    gen_op_dcbz_l128_64_raw
3552
#define gen_op_dcbz_l128_le_64_user   gen_op_dcbz_l128_64_user
3553
#define gen_op_dcbz_l128_le_64_kernel gen_op_dcbz_l128_64_kernel
3554
#define gen_op_dcbz_l128_le_64_hypv   gen_op_dcbz_l128_64_hypv
3555
        GEN_MEM_FUNCS(dcbz_l128),
3556
    },
3557
    /* tunable cache line size */
3558
    {
3559
#define gen_op_dcbz_le_raw            gen_op_dcbz_raw
3560
#define gen_op_dcbz_le_user           gen_op_dcbz_user
3561
#define gen_op_dcbz_le_kernel         gen_op_dcbz_kernel
3562
#define gen_op_dcbz_le_hypv           gen_op_dcbz_hypv
3563
#define gen_op_dcbz_le_64_raw         gen_op_dcbz_64_raw
3564
#define gen_op_dcbz_le_64_user        gen_op_dcbz_64_user
3565
#define gen_op_dcbz_le_64_kernel      gen_op_dcbz_64_kernel
3566
#define gen_op_dcbz_le_64_hypv        gen_op_dcbz_64_hypv
3567
        GEN_MEM_FUNCS(dcbz),
3568
    },
3569
};
3570

    
3571
static always_inline void handler_dcbz (DisasContext *ctx,
3572
                                        int dcache_line_size)
3573
{
3574
    int n;
3575

    
3576
    switch (dcache_line_size) {
3577
    case 32:
3578
        n = 0;
3579
        break;
3580
    case 64:
3581
        n = 1;
3582
        break;
3583
    case 128:
3584
        n = 2;
3585
        break;
3586
    default:
3587
        n = 3;
3588
        break;
3589
    }
3590
    op_dcbz(n);
3591
}
3592

    
3593
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
3594
{
3595
    gen_addr_reg_index(ctx);
3596
    handler_dcbz(ctx, ctx->dcache_line_size);
3597
    gen_op_check_reservation();
3598
}
3599

    
3600
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
3601
{
3602
    gen_addr_reg_index(ctx);
3603
    if (ctx->opcode & 0x00200000)
3604
        handler_dcbz(ctx, ctx->dcache_line_size);
3605
    else
3606
        handler_dcbz(ctx, -1);
3607
    gen_op_check_reservation();
3608
}
3609

    
3610
/* icbi */
3611
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3612
#define gen_op_icbi_le_raw       gen_op_icbi_raw
3613
#define gen_op_icbi_le_user      gen_op_icbi_user
3614
#define gen_op_icbi_le_kernel    gen_op_icbi_kernel
3615
#define gen_op_icbi_le_hypv      gen_op_icbi_hypv
3616
#define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
3617
#define gen_op_icbi_le_64_user   gen_op_icbi_64_user
3618
#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
3619
#define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
3620
static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
3621
    GEN_MEM_FUNCS(icbi),
3622
};
3623

    
3624
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
3625
{
3626
    /* NIP cannot be restored if the memory exception comes from an helper */
3627
    gen_update_nip(ctx, ctx->nip - 4);
3628
    gen_addr_reg_index(ctx);
3629
    op_icbi();
3630
}
3631

    
3632
/* Optional: */
3633
/* dcba */
3634
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3635
{
3636
    /* interpreted as no-op */
3637
    /* XXX: specification say this is treated as a store by the MMU
3638
     *      but does not generate any exception
3639
     */
3640
}
3641

    
3642
/***                    Segment register manipulation                      ***/
3643
/* Supervisor only: */
3644
/* mfsr */
3645
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3646
{
3647
#if defined(CONFIG_USER_ONLY)
3648
    GEN_EXCP_PRIVREG(ctx);
3649
#else
3650
    if (unlikely(!ctx->supervisor)) {
3651
        GEN_EXCP_PRIVREG(ctx);
3652
        return;
3653
    }
3654
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3655
    gen_op_load_sr();
3656
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3657
#endif
3658
}
3659

    
3660
/* mfsrin */
3661
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3662
{
3663
#if defined(CONFIG_USER_ONLY)
3664
    GEN_EXCP_PRIVREG(ctx);
3665
#else
3666
    if (unlikely(!ctx->supervisor)) {
3667
        GEN_EXCP_PRIVREG(ctx);
3668
        return;
3669
    }
3670
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3671
    gen_op_srli_T1(28);
3672
    gen_op_load_sr();
3673
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3674
#endif
3675
}
3676

    
3677
/* mtsr */
3678
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3679
{
3680
#if defined(CONFIG_USER_ONLY)
3681
    GEN_EXCP_PRIVREG(ctx);
3682
#else
3683
    if (unlikely(!ctx->supervisor)) {
3684
        GEN_EXCP_PRIVREG(ctx);
3685
        return;
3686
    }
3687
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3688
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3689
    gen_op_store_sr();
3690
#endif
3691
}
3692

    
3693
/* mtsrin */
3694
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3695
{
3696
#if defined(CONFIG_USER_ONLY)
3697
    GEN_EXCP_PRIVREG(ctx);
3698
#else
3699
    if (unlikely(!ctx->supervisor)) {
3700
        GEN_EXCP_PRIVREG(ctx);
3701
        return;
3702
    }
3703
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3704
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3705
    gen_op_srli_T1(28);
3706
    gen_op_store_sr();
3707
#endif
3708
}
3709

    
3710
#if defined(TARGET_PPC64)
3711
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
3712
/* mfsr */
3713
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
3714
{
3715
#if defined(CONFIG_USER_ONLY)
3716
    GEN_EXCP_PRIVREG(ctx);
3717
#else
3718
    if (unlikely(!ctx->supervisor)) {
3719
        GEN_EXCP_PRIVREG(ctx);
3720
        return;
3721
    }
3722
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3723
    gen_op_load_slb();
3724
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3725
#endif
3726
}
3727

    
3728
/* mfsrin */
3729
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
3730
             PPC_SEGMENT_64B)
3731
{
3732
#if defined(CONFIG_USER_ONLY)
3733
    GEN_EXCP_PRIVREG(ctx);
3734
#else
3735
    if (unlikely(!ctx->supervisor)) {
3736
        GEN_EXCP_PRIVREG(ctx);
3737
        return;
3738
    }
3739
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3740
    gen_op_srli_T1(28);
3741
    gen_op_load_slb();
3742
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3743
#endif
3744
}
3745

    
3746
/* mtsr */
3747
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
3748
{
3749
#if defined(CONFIG_USER_ONLY)
3750
    GEN_EXCP_PRIVREG(ctx);
3751
#else
3752
    if (unlikely(!ctx->supervisor)) {
3753
        GEN_EXCP_PRIVREG(ctx);
3754
        return;
3755
    }
3756
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3757
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3758
    gen_op_store_slb();
3759
#endif
3760
}
3761

    
3762
/* mtsrin */
3763
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
3764
             PPC_SEGMENT_64B)
3765
{
3766
#if defined(CONFIG_USER_ONLY)
3767
    GEN_EXCP_PRIVREG(ctx);
3768
#else
3769
    if (unlikely(!ctx->supervisor)) {
3770
        GEN_EXCP_PRIVREG(ctx);
3771
        return;
3772
    }
3773
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3774
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3775
    gen_op_srli_T1(28);
3776
    gen_op_store_slb();
3777
#endif
3778
}
3779
#endif /* defined(TARGET_PPC64) */
3780

    
3781
/***                      Lookaside buffer management                      ***/
3782
/* Optional & supervisor only: */
3783
/* tlbia */
3784
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3785
{
3786
#if defined(CONFIG_USER_ONLY)
3787
    GEN_EXCP_PRIVOPC(ctx);
3788
#else
3789
    if (unlikely(!ctx->supervisor)) {
3790
        GEN_EXCP_PRIVOPC(ctx);
3791
        return;
3792
    }
3793
    gen_op_tlbia();
3794
#endif
3795
}
3796

    
3797
/* tlbie */
3798
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3799
{
3800
#if defined(CONFIG_USER_ONLY)
3801
    GEN_EXCP_PRIVOPC(ctx);
3802
#else
3803
    if (unlikely(!ctx->supervisor)) {
3804
        GEN_EXCP_PRIVOPC(ctx);
3805
        return;
3806
    }
3807
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
3808
#if defined(TARGET_PPC64)
3809
    if (ctx->sf_mode)
3810
        gen_op_tlbie_64();
3811
    else
3812
#endif
3813
        gen_op_tlbie();
3814
#endif
3815
}
3816

    
3817
/* tlbsync */
3818
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3819
{
3820
#if defined(CONFIG_USER_ONLY)
3821
    GEN_EXCP_PRIVOPC(ctx);
3822
#else
3823
    if (unlikely(!ctx->supervisor)) {
3824
        GEN_EXCP_PRIVOPC(ctx);
3825
        return;
3826
    }
3827
    /* This has no effect: it should ensure that all previous
3828
     * tlbie have completed
3829
     */
3830
    GEN_STOP(ctx);
3831
#endif
3832
}
3833

    
3834
#if defined(TARGET_PPC64)
3835
/* slbia */
3836
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3837
{
3838
#if defined(CONFIG_USER_ONLY)
3839
    GEN_EXCP_PRIVOPC(ctx);
3840
#else
3841
    if (unlikely(!ctx->supervisor)) {
3842
        GEN_EXCP_PRIVOPC(ctx);
3843
        return;
3844
    }
3845
    gen_op_slbia();
3846
#endif
3847
}
3848

    
3849
/* slbie */
3850
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3851
{
3852
#if defined(CONFIG_USER_ONLY)
3853
    GEN_EXCP_PRIVOPC(ctx);
3854
#else
3855
    if (unlikely(!ctx->supervisor)) {
3856
        GEN_EXCP_PRIVOPC(ctx);
3857
        return;
3858
    }
3859
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
3860
    gen_op_slbie();
3861
#endif
3862
}
3863
#endif
3864

    
3865
/***                              External control                         ***/
3866
/* Optional: */
3867
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3868
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3869
static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
3870
    GEN_MEM_FUNCS(eciwx),
3871
};
3872
static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
3873
    GEN_MEM_FUNCS(ecowx),
3874
};
3875

    
3876
/* eciwx */
3877
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3878
{
3879
    /* Should check EAR[E] & alignment ! */
3880
    gen_addr_reg_index(ctx);
3881
    op_eciwx();
3882
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3883
}
3884

    
3885
/* ecowx */
3886
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3887
{
3888
    /* Should check EAR[E] & alignment ! */
3889
    gen_addr_reg_index(ctx);
3890
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
3891
    op_ecowx();
3892
}
3893

    
3894
/* PowerPC 601 specific instructions */
3895
/* abs - abs. */
3896
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3897
{
3898
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3899
    gen_op_POWER_abs();
3900
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3901
    if (unlikely(Rc(ctx->opcode) != 0))
3902
        gen_set_Rc0(ctx);
3903
}
3904

    
3905
/* abso - abso. */
3906
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3907
{
3908
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3909
    gen_op_POWER_abso();
3910
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3911
    if (unlikely(Rc(ctx->opcode) != 0))
3912
        gen_set_Rc0(ctx);
3913
}
3914

    
3915
/* clcs */
3916
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3917
{
3918
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3919
    gen_op_POWER_clcs();
3920
    /* Rc=1 sets CR0 to an undefined state */
3921
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3922
}
3923

    
3924
/* div - div. */
3925
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3926
{
3927
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3928
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3929
    gen_op_POWER_div();
3930
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3931
    if (unlikely(Rc(ctx->opcode) != 0))
3932
        gen_set_Rc0(ctx);
3933
}
3934

    
3935
/* divo - divo. */
3936
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3937
{
3938
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3939
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3940
    gen_op_POWER_divo();
3941
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3942
    if (unlikely(Rc(ctx->opcode) != 0))
3943
        gen_set_Rc0(ctx);
3944
}
3945

    
3946
/* divs - divs. */
3947
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3948
{
3949
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3950
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3951
    gen_op_POWER_divs();
3952
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3953
    if (unlikely(Rc(ctx->opcode) != 0))
3954
        gen_set_Rc0(ctx);
3955
}
3956

    
3957
/* divso - divso. */
3958
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3959
{
3960
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3961
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3962
    gen_op_POWER_divso();
3963
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3964
    if (unlikely(Rc(ctx->opcode) != 0))
3965
        gen_set_Rc0(ctx);
3966
}
3967

    
3968
/* doz - doz. */
3969
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3970
{
3971
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3972
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3973
    gen_op_POWER_doz();
3974
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3975
    if (unlikely(Rc(ctx->opcode) != 0))
3976
        gen_set_Rc0(ctx);
3977
}
3978

    
3979
/* dozo - dozo. */
3980
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3981
{
3982
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3983
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3984
    gen_op_POWER_dozo();
3985
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3986
    if (unlikely(Rc(ctx->opcode) != 0))
3987
        gen_set_Rc0(ctx);
3988
}
3989

    
3990
/* dozi */
3991
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3992
{
3993
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3994
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3995
    gen_op_POWER_doz();
3996
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3997
}
3998

    
3999
/* As lscbx load from memory byte after byte, it's always endian safe.
4000
 * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones
4001
 */
4002
#define op_POWER_lscbx(start, ra, rb)                                         \
4003
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
4004
#define gen_op_POWER_lscbx_64_raw       gen_op_POWER_lscbx_raw
4005
#define gen_op_POWER_lscbx_64_user      gen_op_POWER_lscbx_user
4006
#define gen_op_POWER_lscbx_64_kernel    gen_op_POWER_lscbx_kernel
4007
#define gen_op_POWER_lscbx_64_hypv      gen_op_POWER_lscbx_hypv
4008
#define gen_op_POWER_lscbx_le_raw       gen_op_POWER_lscbx_raw
4009
#define gen_op_POWER_lscbx_le_user      gen_op_POWER_lscbx_user
4010
#define gen_op_POWER_lscbx_le_kernel    gen_op_POWER_lscbx_kernel
4011
#define gen_op_POWER_lscbx_le_hypv      gen_op_POWER_lscbx_hypv
4012
#define gen_op_POWER_lscbx_le_64_raw    gen_op_POWER_lscbx_raw
4013
#define gen_op_POWER_lscbx_le_64_user   gen_op_POWER_lscbx_user
4014
#define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel
4015
#define gen_op_POWER_lscbx_le_64_hypv   gen_op_POWER_lscbx_hypv
4016
static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = {
4017
    GEN_MEM_FUNCS(POWER_lscbx),
4018
};
4019

    
4020
/* lscbx - lscbx. */
4021
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
4022
{
4023
    int ra = rA(ctx->opcode);
4024
    int rb = rB(ctx->opcode);
4025

    
4026
    gen_addr_reg_index(ctx);
4027
    if (ra == 0) {
4028
        ra = rb;
4029
    }
4030
    /* NIP cannot be restored if the memory exception comes from an helper */
4031
    gen_update_nip(ctx, ctx->nip - 4);
4032
    gen_op_load_xer_bc();
4033
    gen_op_load_xer_cmp();
4034
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
4035
    gen_op_store_xer_bc();
4036
    if (unlikely(Rc(ctx->opcode) != 0))
4037
        gen_set_Rc0(ctx);
4038
}
4039

    
4040
/* maskg - maskg. */
4041
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
4042
{
4043
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4044
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4045
    gen_op_POWER_maskg();
4046
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4047
    if (unlikely(Rc(ctx->opcode) != 0))
4048
        gen_set_Rc0(ctx);
4049
}
4050

    
4051
/* maskir - maskir. */
4052
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4053
{
4054
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4055
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4056
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4057
    gen_op_POWER_maskir();
4058
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4059
    if (unlikely(Rc(ctx->opcode) != 0))
4060
        gen_set_Rc0(ctx);
4061
}
4062

    
4063
/* mul - mul. */
4064
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4065
{
4066
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4067
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4068
    gen_op_POWER_mul();
4069
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4070
    if (unlikely(Rc(ctx->opcode) != 0))
4071
        gen_set_Rc0(ctx);
4072
}
4073

    
4074
/* mulo - mulo. */
4075
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4076
{
4077
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4078
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4079
    gen_op_POWER_mulo();
4080
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4081
    if (unlikely(Rc(ctx->opcode) != 0))
4082
        gen_set_Rc0(ctx);
4083
}
4084

    
4085
/* nabs - nabs. */
4086
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4087
{
4088
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4089
    gen_op_POWER_nabs();
4090
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4091
    if (unlikely(Rc(ctx->opcode) != 0))
4092
        gen_set_Rc0(ctx);
4093
}
4094

    
4095
/* nabso - nabso. */
4096
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4097
{
4098
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4099
    gen_op_POWER_nabso();
4100
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4101
    if (unlikely(Rc(ctx->opcode) != 0))
4102
        gen_set_Rc0(ctx);
4103
}
4104

    
4105
/* rlmi - rlmi. */
4106
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4107
{
4108
    uint32_t mb, me;
4109

    
4110
    mb = MB(ctx->opcode);
4111
    me = ME(ctx->opcode);
4112
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4113
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4114
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4115
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4116
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4117
    if (unlikely(Rc(ctx->opcode) != 0))
4118
        gen_set_Rc0(ctx);
4119
}
4120

    
4121
/* rrib - rrib. */
4122
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4123
{
4124
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4125
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4126
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4127
    gen_op_POWER_rrib();
4128
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4129
    if (unlikely(Rc(ctx->opcode) != 0))
4130
        gen_set_Rc0(ctx);
4131
}
4132

    
4133
/* sle - sle. */
4134
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4135
{
4136
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4137
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4138
    gen_op_POWER_sle();
4139
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4140
    if (unlikely(Rc(ctx->opcode) != 0))
4141
        gen_set_Rc0(ctx);
4142
}
4143

    
4144
/* sleq - sleq. */
4145
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4146
{
4147
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4148
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4149
    gen_op_POWER_sleq();
4150
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4151
    if (unlikely(Rc(ctx->opcode) != 0))
4152
        gen_set_Rc0(ctx);
4153
}
4154

    
4155
/* sliq - sliq. */
4156
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4157
{
4158
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4159
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4160
    gen_op_POWER_sle();
4161
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4162
    if (unlikely(Rc(ctx->opcode) != 0))
4163
        gen_set_Rc0(ctx);
4164
}
4165

    
4166
/* slliq - slliq. */
4167
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4168
{
4169
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4170
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4171
    gen_op_POWER_sleq();
4172
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4173
    if (unlikely(Rc(ctx->opcode) != 0))
4174
        gen_set_Rc0(ctx);
4175
}
4176

    
4177
/* sllq - sllq. */
4178
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4179
{
4180
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4181
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4182
    gen_op_POWER_sllq();
4183
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4184
    if (unlikely(Rc(ctx->opcode) != 0))
4185
        gen_set_Rc0(ctx);
4186
}
4187

    
4188
/* slq - slq. */
4189
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4190
{
4191
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4192
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4193
    gen_op_POWER_slq();
4194
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4195
    if (unlikely(Rc(ctx->opcode) != 0))
4196
        gen_set_Rc0(ctx);
4197
}
4198

    
4199
/* sraiq - sraiq. */
4200
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4201
{
4202
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4203
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4204
    gen_op_POWER_sraq();
4205
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4206
    if (unlikely(Rc(ctx->opcode) != 0))
4207
        gen_set_Rc0(ctx);
4208
}
4209

    
4210
/* sraq - sraq. */
4211
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4212
{
4213
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4214
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4215
    gen_op_POWER_sraq();
4216
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4217
    if (unlikely(Rc(ctx->opcode) != 0))
4218
        gen_set_Rc0(ctx);
4219
}
4220

    
4221
/* sre - sre. */
4222
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4223
{
4224
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4225
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4226
    gen_op_POWER_sre();
4227
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4228
    if (unlikely(Rc(ctx->opcode) != 0))
4229
        gen_set_Rc0(ctx);
4230
}
4231

    
4232
/* srea - srea. */
4233
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4234
{
4235
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4236
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4237
    gen_op_POWER_srea();
4238
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4239
    if (unlikely(Rc(ctx->opcode) != 0))
4240
        gen_set_Rc0(ctx);
4241
}
4242

    
4243
/* sreq */
4244
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4245
{
4246
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4247
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4248
    gen_op_POWER_sreq();
4249
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4250
    if (unlikely(Rc(ctx->opcode) != 0))
4251
        gen_set_Rc0(ctx);
4252
}
4253

    
4254
/* sriq */
4255
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4256
{
4257
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4258
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4259
    gen_op_POWER_srq();
4260
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4261
    if (unlikely(Rc(ctx->opcode) != 0))
4262
        gen_set_Rc0(ctx);
4263
}
4264

    
4265
/* srliq */
4266
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4267
{
4268
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4269
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4270
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4271
    gen_op_POWER_srlq();
4272
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4273
    if (unlikely(Rc(ctx->opcode) != 0))
4274
        gen_set_Rc0(ctx);
4275
}
4276

    
4277
/* srlq */
4278
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4279
{
4280
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4281
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4282
    gen_op_POWER_srlq();
4283
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4284
    if (unlikely(Rc(ctx->opcode) != 0))
4285
        gen_set_Rc0(ctx);
4286
}
4287

    
4288
/* srq */
4289
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4290
{
4291
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4292
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4293
    gen_op_POWER_srq();
4294
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4295
    if (unlikely(Rc(ctx->opcode) != 0))
4296
        gen_set_Rc0(ctx);
4297
}
4298

    
4299
/* PowerPC 602 specific instructions */
4300
/* dsa  */
4301
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4302
{
4303
    /* XXX: TODO */
4304
    GEN_EXCP_INVAL(ctx);
4305
}
4306

    
4307
/* esa */
4308
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4309
{
4310
    /* XXX: TODO */
4311
    GEN_EXCP_INVAL(ctx);
4312
}
4313

    
4314
/* mfrom */
4315
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4316
{
4317
#if defined(CONFIG_USER_ONLY)
4318
    GEN_EXCP_PRIVOPC(ctx);
4319
#else
4320
    if (unlikely(!ctx->supervisor)) {
4321
        GEN_EXCP_PRIVOPC(ctx);
4322
        return;
4323
    }
4324
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4325
    gen_op_602_mfrom();
4326
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4327
#endif
4328
}
4329

    
4330
/* 602 - 603 - G2 TLB management */
4331
/* tlbld */
4332
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4333
{
4334
#if defined(CONFIG_USER_ONLY)
4335
    GEN_EXCP_PRIVOPC(ctx);
4336
#else
4337
    if (unlikely(!ctx->supervisor)) {
4338
        GEN_EXCP_PRIVOPC(ctx);
4339
        return;
4340
    }
4341
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4342
    gen_op_6xx_tlbld();
4343
#endif
4344
}
4345

    
4346
/* tlbli */
4347
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4348
{
4349
#if defined(CONFIG_USER_ONLY)
4350
    GEN_EXCP_PRIVOPC(ctx);
4351
#else
4352
    if (unlikely(!ctx->supervisor)) {
4353
        GEN_EXCP_PRIVOPC(ctx);
4354
        return;
4355
    }
4356
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4357
    gen_op_6xx_tlbli();
4358
#endif
4359
}
4360

    
4361
/* 74xx TLB management */
4362
/* tlbld */
4363
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4364
{
4365
#if defined(CONFIG_USER_ONLY)
4366
    GEN_EXCP_PRIVOPC(ctx);
4367
#else
4368
    if (unlikely(!ctx->supervisor)) {
4369
        GEN_EXCP_PRIVOPC(ctx);
4370
        return;
4371
    }
4372
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4373
    gen_op_74xx_tlbld();
4374
#endif
4375
}
4376

    
4377
/* tlbli */
4378
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4379
{
4380
#if defined(CONFIG_USER_ONLY)
4381
    GEN_EXCP_PRIVOPC(ctx);
4382
#else
4383
    if (unlikely(!ctx->supervisor)) {
4384
        GEN_EXCP_PRIVOPC(ctx);
4385
        return;
4386
    }
4387
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4388
    gen_op_74xx_tlbli();
4389
#endif
4390
}
4391

    
4392
/* POWER instructions not in PowerPC 601 */
4393
/* clf */
4394
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4395
{
4396
    /* Cache line flush: implemented as no-op */
4397
}
4398

    
4399
/* cli */
4400
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4401
{
4402
    /* Cache line invalidate: privileged and treated as no-op */
4403
#if defined(CONFIG_USER_ONLY)
4404
    GEN_EXCP_PRIVOPC(ctx);
4405
#else
4406
    if (unlikely(!ctx->supervisor)) {
4407
        GEN_EXCP_PRIVOPC(ctx);
4408
        return;
4409
    }
4410
#endif
4411
}
4412

    
4413
/* dclst */
4414
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4415
{
4416
    /* Data cache line store: treated as no-op */
4417
}
4418

    
4419
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4420
{
4421
#if defined(CONFIG_USER_ONLY)
4422
    GEN_EXCP_PRIVOPC(ctx);
4423
#else
4424
    if (unlikely(!ctx->supervisor)) {
4425
        GEN_EXCP_PRIVOPC(ctx);
4426
        return;
4427
    }
4428
    int ra = rA(ctx->opcode);
4429
    int rd = rD(ctx->opcode);
4430

    
4431
    gen_addr_reg_index(ctx);
4432
    gen_op_POWER_mfsri();
4433
    tcg_gen_mov_tl(cpu_gpr[rd], cpu_T[0]);
4434
    if (ra != 0 && ra != rd)
4435
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[1]);
4436
#endif
4437
}
4438

    
4439
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4440
{
4441
#if defined(CONFIG_USER_ONLY)
4442
    GEN_EXCP_PRIVOPC(ctx);
4443
#else
4444
    if (unlikely(!ctx->supervisor)) {
4445
        GEN_EXCP_PRIVOPC(ctx);
4446
        return;
4447
    }
4448
    gen_addr_reg_index(ctx);
4449
    gen_op_POWER_rac();
4450
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4451
#endif
4452
}
4453

    
4454
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4455
{
4456
#if defined(CONFIG_USER_ONLY)
4457
    GEN_EXCP_PRIVOPC(ctx);
4458
#else
4459
    if (unlikely(!ctx->supervisor)) {
4460
        GEN_EXCP_PRIVOPC(ctx);
4461
        return;
4462
    }
4463
    gen_op_POWER_rfsvc();
4464
    GEN_SYNC(ctx);
4465
#endif
4466
}
4467

    
4468
/* svc is not implemented for now */
4469

    
4470
/* POWER2 specific instructions */
4471
/* Quad manipulation (load/store two floats at a time) */
4472
/* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
4473
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4474
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4475
#define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
4476
#define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
4477
#define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
4478
#define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
4479
#define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
4480
#define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
4481
#define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
4482
#define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
4483
#define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
4484
#define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
4485
#define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
4486
#define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
4487
#define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
4488
#define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
4489
#define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
4490
#define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
4491
static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
4492
    GEN_MEM_FUNCS(POWER2_lfq),
4493
};
4494
static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
4495
    GEN_MEM_FUNCS(POWER2_stfq),
4496
};
4497

    
4498
/* lfq */
4499
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4500
{
4501
    /* NIP cannot be restored if the memory exception comes from an helper */
4502
    gen_update_nip(ctx, ctx->nip - 4);
4503
    gen_addr_imm_index(ctx, 0);
4504
    op_POWER2_lfq();
4505
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4506
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4507
}
4508

    
4509
/* lfqu */
4510
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4511
{
4512
    int ra = rA(ctx->opcode);
4513

    
4514
    /* NIP cannot be restored if the memory exception comes from an helper */
4515
    gen_update_nip(ctx, ctx->nip - 4);
4516
    gen_addr_imm_index(ctx, 0);
4517
    op_POWER2_lfq();
4518
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4519
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4520
    if (ra != 0)
4521
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4522
}
4523

    
4524
/* lfqux */
4525
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4526
{
4527
    int ra = rA(ctx->opcode);
4528

    
4529
    /* NIP cannot be restored if the memory exception comes from an helper */
4530
    gen_update_nip(ctx, ctx->nip - 4);
4531
    gen_addr_reg_index(ctx);
4532
    op_POWER2_lfq();
4533
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4534
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4535
    if (ra != 0)
4536
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4537
}
4538

    
4539
/* lfqx */
4540
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4541
{
4542
    /* NIP cannot be restored if the memory exception comes from an helper */
4543
    gen_update_nip(ctx, ctx->nip - 4);
4544
    gen_addr_reg_index(ctx);
4545
    op_POWER2_lfq();
4546
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4547
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4548
}
4549

    
4550
/* stfq */
4551
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4552
{
4553
    /* NIP cannot be restored if the memory exception comes from an helper */
4554
    gen_update_nip(ctx, ctx->nip - 4);
4555
    gen_addr_imm_index(ctx, 0);
4556
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4557
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4558
    op_POWER2_stfq();
4559
}
4560

    
4561
/* stfqu */
4562
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4563
{
4564
    int ra = rA(ctx->opcode);
4565

    
4566
    /* NIP cannot be restored if the memory exception comes from an helper */
4567
    gen_update_nip(ctx, ctx->nip - 4);
4568
    gen_addr_imm_index(ctx, 0);
4569
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4570
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4571
    op_POWER2_stfq();
4572
    if (ra != 0)
4573
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4574
}
4575

    
4576
/* stfqux */
4577
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4578
{
4579
    int ra = rA(ctx->opcode);
4580

    
4581
    /* NIP cannot be restored if the memory exception comes from an helper */
4582
    gen_update_nip(ctx, ctx->nip - 4);
4583
    gen_addr_reg_index(ctx);
4584
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4585
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4586
    op_POWER2_stfq();
4587
    if (ra != 0)
4588
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4589
}
4590

    
4591
/* stfqx */
4592
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4593
{
4594
    /* NIP cannot be restored if the memory exception comes from an helper */
4595
    gen_update_nip(ctx, ctx->nip - 4);
4596
    gen_addr_reg_index(ctx);
4597
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4598
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4599
    op_POWER2_stfq();
4600
}
4601

    
4602
/* BookE specific instructions */
4603
/* XXX: not implemented on 440 ? */
4604
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
4605
{
4606
    /* XXX: TODO */
4607
    GEN_EXCP_INVAL(ctx);
4608
}
4609

    
4610
/* XXX: not implemented on 440 ? */
4611
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
4612
{
4613
#if defined(CONFIG_USER_ONLY)
4614
    GEN_EXCP_PRIVOPC(ctx);
4615
#else
4616
    if (unlikely(!ctx->supervisor)) {
4617
        GEN_EXCP_PRIVOPC(ctx);
4618
        return;
4619
    }
4620
    gen_addr_reg_index(ctx);
4621
    /* Use the same micro-ops as for tlbie */
4622
#if defined(TARGET_PPC64)
4623
    if (ctx->sf_mode)
4624
        gen_op_tlbie_64();
4625
    else
4626
#endif
4627
        gen_op_tlbie();
4628
#endif
4629
}
4630

    
4631
/* All 405 MAC instructions are translated here */
4632
static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
4633
                                                int opc2, int opc3,
4634
                                                int ra, int rb, int rt, int Rc)
4635
{
4636
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[ra]);
4637
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]);
4638
    switch (opc3 & 0x0D) {
4639
    case 0x05:
4640
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4641
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4642
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4643
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4644
        /* mulchw - mulchw. */
4645
        gen_op_405_mulchw();
4646
        break;
4647
    case 0x04:
4648
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4649
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4650
        /* mulchwu - mulchwu. */
4651
        gen_op_405_mulchwu();
4652
        break;
4653
    case 0x01:
4654
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4655
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4656
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4657
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4658
        /* mulhhw - mulhhw. */
4659
        gen_op_405_mulhhw();
4660
        break;
4661
    case 0x00:
4662
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4663
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4664
        /* mulhhwu - mulhhwu. */
4665
        gen_op_405_mulhhwu();
4666
        break;
4667
    case 0x0D:
4668
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4669
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4670
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4671
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4672
        /* mullhw - mullhw. */
4673
        gen_op_405_mullhw();
4674
        break;
4675
    case 0x0C:
4676
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4677
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4678
        /* mullhwu - mullhwu. */
4679
        gen_op_405_mullhwu();
4680
        break;
4681
    }
4682
    if (opc2 & 0x02) {
4683
        /* nmultiply-and-accumulate (0x0E) */
4684
        gen_op_neg();
4685
    }
4686
    if (opc2 & 0x04) {
4687
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4688
        tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rt]);
4689
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
4690
        gen_op_405_add_T0_T2();
4691
    }
4692
    if (opc3 & 0x10) {
4693
        /* Check overflow */
4694
        if (opc3 & 0x01)
4695
            gen_op_check_addo();
4696
        else
4697
            gen_op_405_check_ovu();
4698
    }
4699
    if (opc3 & 0x02) {
4700
        /* Saturate */
4701
        if (opc3 & 0x01)
4702
            gen_op_405_check_sat();
4703
        else
4704
            gen_op_405_check_satu();
4705
    }
4706
    tcg_gen_mov_tl(cpu_gpr[rt], cpu_T[0]);
4707
    if (unlikely(Rc) != 0) {
4708
        /* Update Rc0 */
4709
        gen_set_Rc0(ctx);
4710
    }
4711
}
4712

    
4713
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4714
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4715
{                                                                             \
4716
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4717
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4718
}
4719

    
4720
/* macchw    - macchw.    */
4721
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4722
/* macchwo   - macchwo.   */
4723
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4724
/* macchws   - macchws.   */
4725
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4726
/* macchwso  - macchwso.  */
4727
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4728
/* macchwsu  - macchwsu.  */
4729
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4730
/* macchwsuo - macchwsuo. */
4731
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4732
/* macchwu   - macchwu.   */
4733
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4734
/* macchwuo  - macchwuo.  */
4735
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4736
/* machhw    - machhw.    */
4737
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4738
/* machhwo   - machhwo.   */
4739
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4740
/* machhws   - machhws.   */
4741
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4742
/* machhwso  - machhwso.  */
4743
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4744
/* machhwsu  - machhwsu.  */
4745
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4746
/* machhwsuo - machhwsuo. */
4747
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4748
/* machhwu   - machhwu.   */
4749
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4750
/* machhwuo  - machhwuo.  */
4751
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4752
/* maclhw    - maclhw.    */
4753
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4754
/* maclhwo   - maclhwo.   */
4755
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4756
/* maclhws   - maclhws.   */
4757
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4758
/* maclhwso  - maclhwso.  */
4759
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4760
/* maclhwu   - maclhwu.   */
4761
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4762
/* maclhwuo  - maclhwuo.  */
4763
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4764
/* maclhwsu  - maclhwsu.  */
4765
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4766
/* maclhwsuo - maclhwsuo. */
4767
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4768
/* nmacchw   - nmacchw.   */
4769
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4770
/* nmacchwo  - nmacchwo.  */
4771
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4772
/* nmacchws  - nmacchws.  */
4773
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4774
/* nmacchwso - nmacchwso. */
4775
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4776
/* nmachhw   - nmachhw.   */
4777
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4778
/* nmachhwo  - nmachhwo.  */
4779
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4780
/* nmachhws  - nmachhws.  */
4781
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4782
/* nmachhwso - nmachhwso. */
4783
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4784
/* nmaclhw   - nmaclhw.   */
4785
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4786
/* nmaclhwo  - nmaclhwo.  */
4787
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4788
/* nmaclhws  - nmaclhws.  */
4789
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4790
/* nmaclhwso - nmaclhwso. */
4791
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4792

    
4793
/* mulchw  - mulchw.  */
4794
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4795
/* mulchwu - mulchwu. */
4796
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4797
/* mulhhw  - mulhhw.  */
4798
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4799
/* mulhhwu - mulhhwu. */
4800
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4801
/* mullhw  - mullhw.  */
4802
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4803
/* mullhwu - mullhwu. */
4804
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4805

    
4806
/* mfdcr */
4807
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
4808
{
4809
#if defined(CONFIG_USER_ONLY)
4810
    GEN_EXCP_PRIVREG(ctx);
4811
#else
4812
    uint32_t dcrn = SPR(ctx->opcode);
4813

    
4814
    if (unlikely(!ctx->supervisor)) {
4815
        GEN_EXCP_PRIVREG(ctx);
4816
        return;
4817
    }
4818
    tcg_gen_movi_tl(cpu_T[0], dcrn);
4819
    gen_op_load_dcr();
4820
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4821
#endif
4822
}
4823

    
4824
/* mtdcr */
4825
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
4826
{
4827
#if defined(CONFIG_USER_ONLY)
4828
    GEN_EXCP_PRIVREG(ctx);
4829
#else
4830
    uint32_t dcrn = SPR(ctx->opcode);
4831

    
4832
    if (unlikely(!ctx->supervisor)) {
4833
        GEN_EXCP_PRIVREG(ctx);
4834
        return;
4835
    }
4836
    tcg_gen_movi_tl(cpu_T[0], dcrn);
4837
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4838
    gen_op_store_dcr();
4839
#endif
4840
}
4841

    
4842
/* mfdcrx */
4843
/* XXX: not implemented on 440 ? */
4844
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
4845
{
4846
#if defined(CONFIG_USER_ONLY)
4847
    GEN_EXCP_PRIVREG(ctx);
4848
#else
4849
    if (unlikely(!ctx->supervisor)) {
4850
        GEN_EXCP_PRIVREG(ctx);
4851
        return;
4852
    }
4853
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4854
    gen_op_load_dcr();
4855
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4856
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4857
#endif
4858
}
4859

    
4860
/* mtdcrx */
4861
/* XXX: not implemented on 440 ? */
4862
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
4863
{
4864
#if defined(CONFIG_USER_ONLY)
4865
    GEN_EXCP_PRIVREG(ctx);
4866
#else
4867
    if (unlikely(!ctx->supervisor)) {
4868
        GEN_EXCP_PRIVREG(ctx);
4869
        return;
4870
    }
4871
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4872
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4873
    gen_op_store_dcr();
4874
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4875
#endif
4876
}
4877

    
4878
/* mfdcrux (PPC 460) : user-mode access to DCR */
4879
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4880
{
4881
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4882
    gen_op_load_dcr();
4883
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4884
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4885
}
4886

    
4887
/* mtdcrux (PPC 460) : user-mode access to DCR */
4888
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4889
{
4890
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4891
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4892
    gen_op_store_dcr();
4893
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4894
}
4895

    
4896
/* dccci */
4897
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4898
{
4899
#if defined(CONFIG_USER_ONLY)
4900
    GEN_EXCP_PRIVOPC(ctx);
4901
#else
4902
    if (unlikely(!ctx->supervisor)) {
4903
        GEN_EXCP_PRIVOPC(ctx);
4904
        return;
4905
    }
4906
    /* interpreted as no-op */
4907
#endif
4908
}
4909

    
4910
/* dcread */
4911
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4912
{
4913
#if defined(CONFIG_USER_ONLY)
4914
    GEN_EXCP_PRIVOPC(ctx);
4915
#else
4916
    if (unlikely(!ctx->supervisor)) {
4917
        GEN_EXCP_PRIVOPC(ctx);
4918
        return;
4919
    }
4920
    gen_addr_reg_index(ctx);
4921
    op_ldst(lwz);
4922
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4923
#endif
4924
}
4925

    
4926
/* icbt */
4927
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4928
{
4929
    /* interpreted as no-op */
4930
    /* XXX: specification say this is treated as a load by the MMU
4931
     *      but does not generate any exception
4932
     */
4933
}
4934

    
4935
/* iccci */
4936
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4937
{
4938
#if defined(CONFIG_USER_ONLY)
4939
    GEN_EXCP_PRIVOPC(ctx);
4940
#else
4941
    if (unlikely(!ctx->supervisor)) {
4942
        GEN_EXCP_PRIVOPC(ctx);
4943
        return;
4944
    }
4945
    /* interpreted as no-op */
4946
#endif
4947
}
4948

    
4949
/* icread */
4950
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4951
{
4952
#if defined(CONFIG_USER_ONLY)
4953
    GEN_EXCP_PRIVOPC(ctx);
4954
#else
4955
    if (unlikely(!ctx->supervisor)) {
4956
        GEN_EXCP_PRIVOPC(ctx);
4957
        return;
4958
    }
4959
    /* interpreted as no-op */
4960
#endif
4961
}
4962

    
4963
/* rfci (supervisor only) */
4964
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4965
{
4966
#if defined(CONFIG_USER_ONLY)
4967
    GEN_EXCP_PRIVOPC(ctx);
4968
#else
4969
    if (unlikely(!ctx->supervisor)) {
4970
        GEN_EXCP_PRIVOPC(ctx);
4971
        return;
4972
    }
4973
    /* Restore CPU state */
4974
    gen_op_40x_rfci();
4975
    GEN_SYNC(ctx);
4976
#endif
4977
}
4978

    
4979
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4980
{
4981
#if defined(CONFIG_USER_ONLY)
4982
    GEN_EXCP_PRIVOPC(ctx);
4983
#else
4984
    if (unlikely(!ctx->supervisor)) {
4985
        GEN_EXCP_PRIVOPC(ctx);
4986
        return;
4987
    }
4988
    /* Restore CPU state */
4989
    gen_op_rfci();
4990
    GEN_SYNC(ctx);
4991
#endif
4992
}
4993

    
4994
/* BookE specific */
4995
/* XXX: not implemented on 440 ? */
4996
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
4997
{
4998
#if defined(CONFIG_USER_ONLY)
4999
    GEN_EXCP_PRIVOPC(ctx);
5000
#else
5001
    if (unlikely(!ctx->supervisor)) {
5002
        GEN_EXCP_PRIVOPC(ctx);
5003
        return;
5004
    }
5005
    /* Restore CPU state */
5006
    gen_op_rfdi();
5007
    GEN_SYNC(ctx);
5008
#endif
5009
}
5010

    
5011
/* XXX: not implemented on 440 ? */
5012
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
5013
{
5014
#if defined(CONFIG_USER_ONLY)
5015
    GEN_EXCP_PRIVOPC(ctx);
5016
#else
5017
    if (unlikely(!ctx->supervisor)) {
5018
        GEN_EXCP_PRIVOPC(ctx);
5019
        return;
5020
    }
5021
    /* Restore CPU state */
5022
    gen_op_rfmci();
5023
    GEN_SYNC(ctx);
5024
#endif
5025
}
5026

    
5027
/* TLB management - PowerPC 405 implementation */
5028
/* tlbre */
5029
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
5030
{
5031
#if defined(CONFIG_USER_ONLY)
5032
    GEN_EXCP_PRIVOPC(ctx);
5033
#else
5034
    if (unlikely(!ctx->supervisor)) {
5035
        GEN_EXCP_PRIVOPC(ctx);
5036
        return;
5037
    }
5038
    switch (rB(ctx->opcode)) {
5039
    case 0:
5040
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5041
        gen_op_4xx_tlbre_hi();
5042
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5043
        break;
5044
    case 1:
5045
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5046
        gen_op_4xx_tlbre_lo();
5047
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5048
        break;
5049
    default:
5050
        GEN_EXCP_INVAL(ctx);
5051
        break;
5052
    }
5053
#endif
5054
}
5055

    
5056
/* tlbsx - tlbsx. */
5057
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5058
{
5059
#if defined(CONFIG_USER_ONLY)
5060
    GEN_EXCP_PRIVOPC(ctx);
5061
#else
5062
    if (unlikely(!ctx->supervisor)) {
5063
        GEN_EXCP_PRIVOPC(ctx);
5064
        return;
5065
    }
5066
    gen_addr_reg_index(ctx);
5067
    gen_op_4xx_tlbsx();
5068
    if (Rc(ctx->opcode))
5069
        gen_op_4xx_tlbsx_check();
5070
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5071
#endif
5072
}
5073

    
5074
/* tlbwe */
5075
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5076
{
5077
#if defined(CONFIG_USER_ONLY)
5078
    GEN_EXCP_PRIVOPC(ctx);
5079
#else
5080
    if (unlikely(!ctx->supervisor)) {
5081
        GEN_EXCP_PRIVOPC(ctx);
5082
        return;
5083
    }
5084
    switch (rB(ctx->opcode)) {
5085
    case 0:
5086
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5087
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5088
        gen_op_4xx_tlbwe_hi();
5089
        break;
5090
    case 1:
5091
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5092
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5093
        gen_op_4xx_tlbwe_lo();
5094
        break;
5095
    default:
5096
        GEN_EXCP_INVAL(ctx);
5097
        break;
5098
    }
5099
#endif
5100
}
5101

    
5102
/* TLB management - PowerPC 440 implementation */
5103
/* tlbre */
5104
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5105
{
5106
#if defined(CONFIG_USER_ONLY)
5107
    GEN_EXCP_PRIVOPC(ctx);
5108
#else
5109
    if (unlikely(!ctx->supervisor)) {
5110
        GEN_EXCP_PRIVOPC(ctx);
5111
        return;
5112
    }
5113
    switch (rB(ctx->opcode)) {
5114
    case 0:
5115
    case 1:
5116
    case 2:
5117
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5118
        gen_op_440_tlbre(rB(ctx->opcode));
5119
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5120
        break;
5121
    default:
5122
        GEN_EXCP_INVAL(ctx);
5123
        break;
5124
    }
5125
#endif
5126
}
5127

    
5128
/* tlbsx - tlbsx. */
5129
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5130
{
5131
#if defined(CONFIG_USER_ONLY)
5132
    GEN_EXCP_PRIVOPC(ctx);
5133
#else
5134
    if (unlikely(!ctx->supervisor)) {
5135
        GEN_EXCP_PRIVOPC(ctx);
5136
        return;
5137
    }
5138
    gen_addr_reg_index(ctx);
5139
    gen_op_440_tlbsx();
5140
    if (Rc(ctx->opcode))
5141
        gen_op_4xx_tlbsx_check();
5142
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5143
#endif
5144
}
5145

    
5146
/* tlbwe */
5147
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5148
{
5149
#if defined(CONFIG_USER_ONLY)
5150
    GEN_EXCP_PRIVOPC(ctx);
5151
#else
5152
    if (unlikely(!ctx->supervisor)) {
5153
        GEN_EXCP_PRIVOPC(ctx);
5154
        return;
5155
    }
5156
    switch (rB(ctx->opcode)) {
5157
    case 0:
5158
    case 1:
5159
    case 2:
5160
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5161
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5162
        gen_op_440_tlbwe(rB(ctx->opcode));
5163
        break;
5164
    default:
5165
        GEN_EXCP_INVAL(ctx);
5166
        break;
5167
    }
5168
#endif
5169
}
5170

    
5171
/* wrtee */
5172
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
5173
{
5174
#if defined(CONFIG_USER_ONLY)
5175
    GEN_EXCP_PRIVOPC(ctx);
5176
#else
5177
    if (unlikely(!ctx->supervisor)) {
5178
        GEN_EXCP_PRIVOPC(ctx);
5179
        return;
5180
    }
5181
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rD(ctx->opcode)]);
5182
    gen_op_wrte();
5183
    /* Stop translation to have a chance to raise an exception
5184
     * if we just set msr_ee to 1
5185
     */
5186
    GEN_STOP(ctx);
5187
#endif
5188
}
5189

    
5190
/* wrteei */
5191
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
5192
{
5193
#if defined(CONFIG_USER_ONLY)
5194
    GEN_EXCP_PRIVOPC(ctx);
5195
#else
5196
    if (unlikely(!ctx->supervisor)) {
5197
        GEN_EXCP_PRIVOPC(ctx);
5198
        return;
5199
    }
5200
    tcg_gen_movi_tl(cpu_T[0], ctx->opcode & 0x00010000);
5201
    gen_op_wrte();
5202
    /* Stop translation to have a chance to raise an exception
5203
     * if we just set msr_ee to 1
5204
     */
5205
    GEN_STOP(ctx);
5206
#endif
5207
}
5208

    
5209
/* PowerPC 440 specific instructions */
5210
/* dlmzb */
5211
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5212
{
5213
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
5214
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
5215
    gen_op_440_dlmzb();
5216
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
5217
    gen_op_store_xer_bc();
5218
    if (Rc(ctx->opcode)) {
5219
        gen_op_440_dlmzb_update_Rc();
5220
        tcg_gen_andi_i32(cpu_crf[0], cpu_T[0], 0xf);
5221
    }
5222
}
5223

    
5224
/* mbar replaces eieio on 440 */
5225
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5226
{
5227
    /* interpreted as no-op */
5228
}
5229

    
5230
/* msync replaces sync on 440 */
5231
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5232
{
5233
    /* interpreted as no-op */
5234
}
5235

    
5236
/* icbt */
5237
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5238
{
5239
    /* interpreted as no-op */
5240
    /* XXX: specification say this is treated as a load by the MMU
5241
     *      but does not generate any exception
5242
     */
5243
}
5244

    
5245
/***                      Altivec vector extension                         ***/
5246
/* Altivec registers moves */
5247

    
5248
static always_inline void gen_load_avr(int t, int reg) {
5249
    tcg_gen_mov_i64(cpu_AVRh[t], cpu_avrh[reg]);
5250
    tcg_gen_mov_i64(cpu_AVRl[t], cpu_avrl[reg]);
5251
}
5252

    
5253
static always_inline void gen_store_avr(int reg, int t) {
5254
    tcg_gen_mov_i64(cpu_avrh[reg], cpu_AVRh[t]);
5255
    tcg_gen_mov_i64(cpu_avrl[reg], cpu_AVRl[t]);
5256
}
5257

    
5258
#define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5259
#define OP_VR_LD_TABLE(name)                                                  \
5260
static GenOpFunc *gen_op_vr_l##name[NB_MEM_FUNCS] = {                         \
5261
    GEN_MEM_FUNCS(vr_l##name),                                                \
5262
};
5263
#define OP_VR_ST_TABLE(name)                                                  \
5264
static GenOpFunc *gen_op_vr_st##name[NB_MEM_FUNCS] = {                        \
5265
    GEN_MEM_FUNCS(vr_st##name),                                               \
5266
};
5267

    
5268
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5269
GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
5270
{                                                                             \
5271
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5272
        GEN_EXCP_NO_VR(ctx);                                                  \
5273
        return;                                                               \
5274
    }                                                                         \
5275
    gen_addr_reg_index(ctx);                                                  \
5276
    op_vr_ldst(vr_l##name);                                                   \
5277
    gen_store_avr(rD(ctx->opcode), 0);                                        \
5278
}
5279

    
5280
#define GEN_VR_STX(name, opc2, opc3)                                          \
5281
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
5282
{                                                                             \
5283
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5284
        GEN_EXCP_NO_VR(ctx);                                                  \
5285
        return;                                                               \
5286
    }                                                                         \
5287
    gen_addr_reg_index(ctx);                                                  \
5288
    gen_load_avr(0, rS(ctx->opcode));                                         \
5289
    op_vr_ldst(vr_st##name);                                                  \
5290
}
5291

    
5292
OP_VR_LD_TABLE(vx);
5293
GEN_VR_LDX(vx, 0x07, 0x03);
5294
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
5295
#define gen_op_vr_lvxl gen_op_vr_lvx
5296
GEN_VR_LDX(vxl, 0x07, 0x0B);
5297

    
5298
OP_VR_ST_TABLE(vx);
5299
GEN_VR_STX(vx, 0x07, 0x07);
5300
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
5301
#define gen_op_vr_stvxl gen_op_vr_stvx
5302
GEN_VR_STX(vxl, 0x07, 0x0F);
5303

    
5304
/***                           SPE extension                               ***/
5305
/* Register moves */
5306

    
5307
static always_inline void gen_load_gpr64(TCGv t, int reg) {
5308
#if defined(TARGET_PPC64)
5309
    tcg_gen_mov_i64(t, cpu_gpr[reg]);
5310
#else
5311
    tcg_gen_extu_i32_i64(t, cpu_gprh[reg]);
5312
    tcg_gen_shli_i64(t, t, 32);
5313
    TCGv tmp = tcg_temp_local_new(TCG_TYPE_I64);
5314
    tcg_gen_extu_i32_i64(tmp, cpu_gpr[reg]);
5315
    tcg_gen_or_i64(t, t, tmp);
5316
    tcg_temp_free(tmp);
5317
#endif
5318
}
5319

    
5320
static always_inline void gen_store_gpr64(int reg, TCGv t) {
5321
#if defined(TARGET_PPC64)
5322
    tcg_gen_mov_i64(cpu_gpr[reg], t);
5323
#else
5324
    tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
5325
    TCGv tmp = tcg_temp_local_new(TCG_TYPE_I64);
5326
    tcg_gen_shri_i64(tmp, t, 32);
5327
    tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
5328
    tcg_temp_free(tmp);
5329
#endif
5330
}
5331

    
5332
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5333
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5334
{                                                                             \
5335
    if (Rc(ctx->opcode))                                                      \
5336
        gen_##name1(ctx);                                                     \
5337
    else                                                                      \
5338
        gen_##name0(ctx);                                                     \
5339
}
5340

    
5341
/* Handler for undefined SPE opcodes */
5342
static always_inline void gen_speundef (DisasContext *ctx)
5343
{
5344
    GEN_EXCP_INVAL(ctx);
5345
}
5346

    
5347
/* SPE load and stores */
5348
static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5349
{
5350
    target_long simm = rB(ctx->opcode);
5351

    
5352
    if (rA(ctx->opcode) == 0) {
5353
        tcg_gen_movi_tl(cpu_T[0], simm << sh);
5354
    } else {
5355
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5356
        if (likely(simm != 0))
5357
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], simm << sh);
5358
    }
5359
}
5360

    
5361
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5362
#define OP_SPE_LD_TABLE(name)                                                 \
5363
static GenOpFunc *gen_op_spe_l##name[NB_MEM_FUNCS] = {                        \
5364
    GEN_MEM_FUNCS(spe_l##name),                                               \
5365
};
5366
#define OP_SPE_ST_TABLE(name)                                                 \
5367
static GenOpFunc *gen_op_spe_st##name[NB_MEM_FUNCS] = {                       \
5368
    GEN_MEM_FUNCS(spe_st##name),                                              \
5369
};
5370

    
5371
#define GEN_SPE_LD(name, sh)                                                  \
5372
static always_inline void gen_evl##name (DisasContext *ctx)                   \
5373
{                                                                             \
5374
    if (unlikely(!ctx->spe_enabled)) {                                        \
5375
        GEN_EXCP_NO_AP(ctx);                                                  \
5376
        return;                                                               \
5377
    }                                                                         \
5378
    gen_addr_spe_imm_index(ctx, sh);                                          \
5379
    op_spe_ldst(spe_l##name);                                                 \
5380
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[1]);                             \
5381
}
5382

    
5383
#define GEN_SPE_LDX(name)                                                     \
5384
static always_inline void gen_evl##name##x (DisasContext *ctx)                \
5385
{                                                                             \
5386
    if (unlikely(!ctx->spe_enabled)) {                                        \
5387
        GEN_EXCP_NO_AP(ctx);                                                  \
5388
        return;                                                               \
5389
    }                                                                         \
5390
    gen_addr_reg_index(ctx);                                                  \
5391
    op_spe_ldst(spe_l##name);                                                 \
5392
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[1]);                             \
5393
}
5394

    
5395
#define GEN_SPEOP_LD(name, sh)                                                \
5396
OP_SPE_LD_TABLE(name);                                                        \
5397
GEN_SPE_LD(name, sh);                                                         \
5398
GEN_SPE_LDX(name)
5399

    
5400
#define GEN_SPE_ST(name, sh)                                                  \
5401
static always_inline void gen_evst##name (DisasContext *ctx)                  \
5402
{                                                                             \
5403
    if (unlikely(!ctx->spe_enabled)) {                                        \
5404
        GEN_EXCP_NO_AP(ctx);                                                  \
5405
        return;                                                               \
5406
    }                                                                         \
5407
    gen_addr_spe_imm_index(ctx, sh);                                          \
5408
    gen_load_gpr64(cpu_T64[1], rS(ctx->opcode));                              \
5409
    op_spe_ldst(spe_st##name);                                                \
5410
}
5411

    
5412
#define GEN_SPE_STX(name)                                                     \
5413
static always_inline void gen_evst##name##x (DisasContext *ctx)               \
5414
{                                                                             \
5415
    if (unlikely(!ctx->spe_enabled)) {                                        \
5416
        GEN_EXCP_NO_AP(ctx);                                                  \
5417
        return;                                                               \
5418
    }                                                                         \
5419
    gen_addr_reg_index(ctx);                                                  \
5420
    gen_load_gpr64(cpu_T64[1], rS(ctx->opcode));                              \
5421
    op_spe_ldst(spe_st##name);                                                \
5422
}
5423

    
5424
#define GEN_SPEOP_ST(name, sh)                                                \
5425
OP_SPE_ST_TABLE(name);                                                        \
5426
GEN_SPE_ST(name, sh);                                                         \
5427
GEN_SPE_STX(name)
5428

    
5429
#define GEN_SPEOP_LDST(name, sh)                                              \
5430
GEN_SPEOP_LD(name, sh);                                                       \
5431
GEN_SPEOP_ST(name, sh)
5432

    
5433
/* SPE arithmetic and logic */
5434
#define GEN_SPEOP_ARITH2(name)                                                \
5435
static always_inline void gen_##name (DisasContext *ctx)                      \
5436
{                                                                             \
5437
    if (unlikely(!ctx->spe_enabled)) {                                        \
5438
        GEN_EXCP_NO_AP(ctx);                                                  \
5439
        return;                                                               \
5440
    }                                                                         \
5441
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5442
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
5443
    gen_op_##name();                                                          \
5444
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5445
}
5446

    
5447
#define GEN_SPEOP_ARITH1(name)                                                \
5448
static always_inline void gen_##name (DisasContext *ctx)                      \
5449
{                                                                             \
5450
    if (unlikely(!ctx->spe_enabled)) {                                        \
5451
        GEN_EXCP_NO_AP(ctx);                                                  \
5452
        return;                                                               \
5453
    }                                                                         \
5454
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5455
    gen_op_##name();                                                          \
5456
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5457
}
5458

    
5459
#define GEN_SPEOP_COMP(name)                                                  \
5460
static always_inline void gen_##name (DisasContext *ctx)                      \
5461
{                                                                             \
5462
    if (unlikely(!ctx->spe_enabled)) {                                        \
5463
        GEN_EXCP_NO_AP(ctx);                                                  \
5464
        return;                                                               \
5465
    }                                                                         \
5466
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5467
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
5468
    gen_op_##name();                                                          \
5469
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);              \
5470
}
5471

    
5472
/* Logical */
5473
GEN_SPEOP_ARITH2(evand);
5474
GEN_SPEOP_ARITH2(evandc);
5475
GEN_SPEOP_ARITH2(evxor);
5476
GEN_SPEOP_ARITH2(evor);
5477
GEN_SPEOP_ARITH2(evnor);
5478
GEN_SPEOP_ARITH2(eveqv);
5479
GEN_SPEOP_ARITH2(evorc);
5480
GEN_SPEOP_ARITH2(evnand);
5481
GEN_SPEOP_ARITH2(evsrwu);
5482
GEN_SPEOP_ARITH2(evsrws);
5483
GEN_SPEOP_ARITH2(evslw);
5484
GEN_SPEOP_ARITH2(evrlw);
5485
GEN_SPEOP_ARITH2(evmergehi);
5486
GEN_SPEOP_ARITH2(evmergelo);
5487
GEN_SPEOP_ARITH2(evmergehilo);
5488
GEN_SPEOP_ARITH2(evmergelohi);
5489

    
5490
/* Arithmetic */
5491
GEN_SPEOP_ARITH2(evaddw);
5492
GEN_SPEOP_ARITH2(evsubfw);
5493
GEN_SPEOP_ARITH1(evabs);
5494
GEN_SPEOP_ARITH1(evneg);
5495
GEN_SPEOP_ARITH1(evextsb);
5496
GEN_SPEOP_ARITH1(evextsh);
5497
GEN_SPEOP_ARITH1(evrndw);
5498
GEN_SPEOP_ARITH1(evcntlzw);
5499
GEN_SPEOP_ARITH1(evcntlsw);
5500
static always_inline void gen_brinc (DisasContext *ctx)
5501
{
5502
    /* Note: brinc is usable even if SPE is disabled */
5503
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5504
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
5505
    gen_op_brinc();
5506
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5507
}
5508

    
5509
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5510
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5511
{                                                                             \
5512
    if (unlikely(!ctx->spe_enabled)) {                                        \
5513
        GEN_EXCP_NO_AP(ctx);                                                  \
5514
        return;                                                               \
5515
    }                                                                         \
5516
    gen_load_gpr64(cpu_T64[0], rB(ctx->opcode));                              \
5517
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5518
    gen_op_##name();                                                          \
5519
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5520
}
5521

    
5522
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5523
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5524
{                                                                             \
5525
    if (unlikely(!ctx->spe_enabled)) {                                        \
5526
        GEN_EXCP_NO_AP(ctx);                                                  \
5527
        return;                                                               \
5528
    }                                                                         \
5529
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5530
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5531
    gen_op_##name();                                                          \
5532
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5533
}
5534

    
5535
GEN_SPEOP_ARITH_IMM2(evaddw);
5536
#define gen_evaddiw gen_evaddwi
5537
GEN_SPEOP_ARITH_IMM2(evsubfw);
5538
#define gen_evsubifw gen_evsubfwi
5539
GEN_SPEOP_LOGIC_IMM2(evslw);
5540
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5541
#define gen_evsrwis gen_evsrwsi
5542
GEN_SPEOP_LOGIC_IMM2(evsrws);
5543
#define gen_evsrwiu gen_evsrwui
5544
GEN_SPEOP_LOGIC_IMM2(evrlw);
5545

    
5546
static always_inline void gen_evsplati (DisasContext *ctx)
5547
{
5548
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5549

    
5550
    gen_op_splatwi_T0_64(imm);
5551
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
5552
}
5553

    
5554
static always_inline void gen_evsplatfi (DisasContext *ctx)
5555
{
5556
    uint32_t imm = rA(ctx->opcode) << 27;
5557

    
5558
    gen_op_splatwi_T0_64(imm);
5559
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
5560
}
5561

    
5562
/* Comparison */
5563
GEN_SPEOP_COMP(evcmpgtu);
5564
GEN_SPEOP_COMP(evcmpgts);
5565
GEN_SPEOP_COMP(evcmpltu);
5566
GEN_SPEOP_COMP(evcmplts);
5567
GEN_SPEOP_COMP(evcmpeq);
5568

    
5569
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5570
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5571
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5572
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5573
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5574
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5575
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5576
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5577
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5578
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5579
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5580
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5581
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5582
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5583
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5584
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5585
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5586
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5587
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5588
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5589
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5590
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5591
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5592
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5593
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5594

    
5595
static always_inline void gen_evsel (DisasContext *ctx)
5596
{
5597
    if (unlikely(!ctx->spe_enabled)) {
5598
        GEN_EXCP_NO_AP(ctx);
5599
        return;
5600
    }
5601
    tcg_gen_mov_i32(cpu_T[0], cpu_crf[ctx->opcode & 0x7]);
5602
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));
5603
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));
5604
    gen_op_evsel();
5605
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
5606
}
5607

    
5608
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5609
{
5610
    gen_evsel(ctx);
5611
}
5612
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5613
{
5614
    gen_evsel(ctx);
5615
}
5616
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5617
{
5618
    gen_evsel(ctx);
5619
}
5620
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5621
{
5622
    gen_evsel(ctx);
5623
}
5624

    
5625
/* Load and stores */
5626
#if defined(TARGET_PPC64)
5627
/* In that case, we already have 64 bits load & stores
5628
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5629
 */
5630
#define gen_op_spe_ldd_raw           gen_op_ld_raw
5631
#define gen_op_spe_ldd_user          gen_op_ld_user
5632
#define gen_op_spe_ldd_kernel        gen_op_ld_kernel
5633
#define gen_op_spe_ldd_hypv          gen_op_ld_hypv
5634
#define gen_op_spe_ldd_64_raw        gen_op_ld_64_raw
5635
#define gen_op_spe_ldd_64_user       gen_op_ld_64_user
5636
#define gen_op_spe_ldd_64_kernel     gen_op_ld_64_kernel
5637
#define gen_op_spe_ldd_64_hypv       gen_op_ld_64_hypv
5638
#define gen_op_spe_ldd_le_raw        gen_op_ld_le_raw
5639
#define gen_op_spe_ldd_le_user       gen_op_ld_le_user
5640
#define gen_op_spe_ldd_le_kernel     gen_op_ld_le_kernel
5641
#define gen_op_spe_ldd_le_hypv       gen_op_ld_le_hypv
5642
#define gen_op_spe_ldd_le_64_raw     gen_op_ld_le_64_raw
5643
#define gen_op_spe_ldd_le_64_user    gen_op_ld_le_64_user
5644
#define gen_op_spe_ldd_le_64_kernel  gen_op_ld_le_64_kernel
5645
#define gen_op_spe_ldd_le_64_hypv    gen_op_ld_le_64_hypv
5646
#define gen_op_spe_stdd_raw          gen_op_std_raw
5647
#define gen_op_spe_stdd_user         gen_op_std_user
5648
#define gen_op_spe_stdd_kernel       gen_op_std_kernel
5649
#define gen_op_spe_stdd_hypv         gen_op_std_hypv
5650
#define gen_op_spe_stdd_64_raw       gen_op_std_64_raw
5651
#define gen_op_spe_stdd_64_user      gen_op_std_64_user
5652
#define gen_op_spe_stdd_64_kernel    gen_op_std_64_kernel
5653
#define gen_op_spe_stdd_64_hypv      gen_op_std_64_hypv
5654
#define gen_op_spe_stdd_le_raw       gen_op_std_le_raw
5655
#define gen_op_spe_stdd_le_user      gen_op_std_le_user
5656
#define gen_op_spe_stdd_le_kernel    gen_op_std_le_kernel
5657
#define gen_op_spe_stdd_le_hypv      gen_op_std_le_hypv
5658
#define gen_op_spe_stdd_le_64_raw    gen_op_std_le_64_raw
5659
#define gen_op_spe_stdd_le_64_user   gen_op_std_le_64_user
5660
#define gen_op_spe_stdd_le_64_kernel gen_op_std_le_64_kernel
5661
#define gen_op_spe_stdd_le_64_hypv   gen_op_std_le_64_hypv
5662
#endif /* defined(TARGET_PPC64) */
5663
GEN_SPEOP_LDST(dd, 3);
5664
GEN_SPEOP_LDST(dw, 3);
5665
GEN_SPEOP_LDST(dh, 3);
5666
GEN_SPEOP_LDST(whe, 2);
5667
GEN_SPEOP_LD(whou, 2);
5668
GEN_SPEOP_LD(whos, 2);
5669
GEN_SPEOP_ST(who, 2);
5670

    
5671
#if defined(TARGET_PPC64)
5672
/* In that case, spe_stwwo is equivalent to stw */
5673
#define gen_op_spe_stwwo_raw          gen_op_stw_raw
5674
#define gen_op_spe_stwwo_user         gen_op_stw_user
5675
#define gen_op_spe_stwwo_kernel       gen_op_stw_kernel
5676
#define gen_op_spe_stwwo_hypv         gen_op_stw_hypv
5677
#define gen_op_spe_stwwo_le_raw       gen_op_stw_le_raw
5678
#define gen_op_spe_stwwo_le_user      gen_op_stw_le_user
5679
#define gen_op_spe_stwwo_le_kernel    gen_op_stw_le_kernel
5680
#define gen_op_spe_stwwo_le_hypv      gen_op_stw_le_hypv
5681
#define gen_op_spe_stwwo_64_raw       gen_op_stw_64_raw
5682
#define gen_op_spe_stwwo_64_user      gen_op_stw_64_user
5683
#define gen_op_spe_stwwo_64_kernel    gen_op_stw_64_kernel
5684
#define gen_op_spe_stwwo_64_hypv      gen_op_stw_64_hypv
5685
#define gen_op_spe_stwwo_le_64_raw    gen_op_stw_le_64_raw
5686
#define gen_op_spe_stwwo_le_64_user   gen_op_stw_le_64_user
5687
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5688
#define gen_op_spe_stwwo_le_64_hypv   gen_op_stw_le_64_hypv
5689
#endif
5690
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5691
static always_inline void gen_op_spe_stwwe_##suffix (void)                    \
5692
{                                                                             \
5693
    gen_op_srli32_T1_64();                                                    \
5694
    gen_op_spe_stwwo_##suffix();                                              \
5695
}
5696
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5697
static always_inline void gen_op_spe_stwwe_le_##suffix (void)                 \
5698
{                                                                             \
5699
    gen_op_srli32_T1_64();                                                    \
5700
    gen_op_spe_stwwo_le_##suffix();                                           \
5701
}
5702
#if defined(TARGET_PPC64)
5703
#define GEN_OP_SPE_STWWE(suffix)                                              \
5704
_GEN_OP_SPE_STWWE(suffix);                                                    \
5705
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5706
static always_inline void gen_op_spe_stwwe_64_##suffix (void)                 \
5707
{                                                                             \
5708
    gen_op_srli32_T1_64();                                                    \
5709
    gen_op_spe_stwwo_64_##suffix();                                           \
5710
}                                                                             \
5711
static always_inline void gen_op_spe_stwwe_le_64_##suffix (void)              \
5712
{                                                                             \
5713
    gen_op_srli32_T1_64();                                                    \
5714
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5715
}
5716
#else
5717
#define GEN_OP_SPE_STWWE(suffix)                                              \
5718
_GEN_OP_SPE_STWWE(suffix);                                                    \
5719
_GEN_OP_SPE_STWWE_LE(suffix)
5720
#endif
5721
#if defined(CONFIG_USER_ONLY)
5722
GEN_OP_SPE_STWWE(raw);
5723
#else /* defined(CONFIG_USER_ONLY) */
5724
GEN_OP_SPE_STWWE(user);
5725
GEN_OP_SPE_STWWE(kernel);
5726
GEN_OP_SPE_STWWE(hypv);
5727
#endif /* defined(CONFIG_USER_ONLY) */
5728
GEN_SPEOP_ST(wwe, 2);
5729
GEN_SPEOP_ST(wwo, 2);
5730

    
5731
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5732
static always_inline void gen_op_spe_l##name##_##suffix (void)                \
5733
{                                                                             \
5734
    gen_op_##op##_##suffix();                                                 \
5735
    gen_op_splatw_T1_64();                                                    \
5736
}
5737

    
5738
#define GEN_OP_SPE_LHE(suffix)                                                \
5739
static always_inline void gen_op_spe_lhe_##suffix (void)                      \
5740
{                                                                             \
5741
    gen_op_spe_lh_##suffix();                                                 \
5742
    gen_op_sli16_T1_64();                                                     \
5743
}
5744

    
5745
#define GEN_OP_SPE_LHX(suffix)                                                \
5746
static always_inline void gen_op_spe_lhx_##suffix (void)                      \
5747
{                                                                             \
5748
    gen_op_spe_lh_##suffix();                                                 \
5749
    gen_op_extsh_T1_64();                                                     \
5750
}
5751

    
5752
#if defined(CONFIG_USER_ONLY)
5753
GEN_OP_SPE_LHE(raw);
5754
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5755
GEN_OP_SPE_LHE(le_raw);
5756
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5757
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5758
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5759
GEN_OP_SPE_LHX(raw);
5760
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5761
GEN_OP_SPE_LHX(le_raw);
5762
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5763
#if defined(TARGET_PPC64)
5764
GEN_OP_SPE_LHE(64_raw);
5765
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5766
GEN_OP_SPE_LHE(le_64_raw);
5767
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5768
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5769
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5770
GEN_OP_SPE_LHX(64_raw);
5771
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5772
GEN_OP_SPE_LHX(le_64_raw);
5773
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5774
#endif
5775
#else
5776
GEN_OP_SPE_LHE(user);
5777
GEN_OP_SPE_LHE(kernel);
5778
GEN_OP_SPE_LHE(hypv);
5779
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5780
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5781
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv);
5782
GEN_OP_SPE_LHE(le_user);
5783
GEN_OP_SPE_LHE(le_kernel);
5784
GEN_OP_SPE_LHE(le_hypv);
5785
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5786
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5787
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv);
5788
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5789
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5790
GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv);
5791
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5792
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5793
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv);
5794
GEN_OP_SPE_LHX(user);
5795
GEN_OP_SPE_LHX(kernel);
5796
GEN_OP_SPE_LHX(hypv);
5797
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5798
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5799
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv);
5800
GEN_OP_SPE_LHX(le_user);
5801
GEN_OP_SPE_LHX(le_kernel);
5802
GEN_OP_SPE_LHX(le_hypv);
5803
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5804
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5805
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv);
5806
#if defined(TARGET_PPC64)
5807
GEN_OP_SPE_LHE(64_user);
5808
GEN_OP_SPE_LHE(64_kernel);
5809
GEN_OP_SPE_LHE(64_hypv);
5810
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5811
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5812
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv);
5813
GEN_OP_SPE_LHE(le_64_user);
5814
GEN_OP_SPE_LHE(le_64_kernel);
5815
GEN_OP_SPE_LHE(le_64_hypv);
5816
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5817
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5818
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv);
5819
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5820
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5821
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv);
5822
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5823
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5824
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv);
5825
GEN_OP_SPE_LHX(64_user);
5826
GEN_OP_SPE_LHX(64_kernel);
5827
GEN_OP_SPE_LHX(64_hypv);
5828
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5829
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5830
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv);
5831
GEN_OP_SPE_LHX(le_64_user);
5832
GEN_OP_SPE_LHX(le_64_kernel);
5833
GEN_OP_SPE_LHX(le_64_hypv);
5834
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5835
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5836
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv);
5837
#endif
5838
#endif
5839
GEN_SPEOP_LD(hhesplat, 1);
5840
GEN_SPEOP_LD(hhousplat, 1);
5841
GEN_SPEOP_LD(hhossplat, 1);
5842
GEN_SPEOP_LD(wwsplat, 2);
5843
GEN_SPEOP_LD(whsplat, 2);
5844

    
5845
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5846
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5847
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5848
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5849
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5850
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5851
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5852
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5853
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5854
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5855
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5856
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5857
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5858
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5859
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5860
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5861
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5862
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5863

    
5864
/* Multiply and add - TODO */
5865
#if 0
5866
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5867
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5868
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5869
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5870
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5871
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5872
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5873
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5874
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5875
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5876
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5877
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5878

5879
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5880
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5881
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5882
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5883
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5884
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5885
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5886
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5887
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5888
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5889
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5890
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5891
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5892
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5893

5894
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5895
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5896
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5897
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5898
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5899
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5900

5901
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5902
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5903
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5904
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5905
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5906
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5907
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5908
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5909
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5910
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5911
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5912
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5913

5914
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5915
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5916
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5917
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5918
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5919

5920
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5921
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5922
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5923
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5924
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5925
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5926
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5927
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5928
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5929
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5930
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5931
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5932

5933
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5934
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5935
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5936
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5937
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5938
#endif
5939

    
5940
/***                      SPE floating-point extension                     ***/
5941
#define GEN_SPEFPUOP_CONV(name)                                               \
5942
static always_inline void gen_##name (DisasContext *ctx)                      \
5943
{                                                                             \
5944
    gen_load_gpr64(cpu_T64[0], rB(ctx->opcode));                              \
5945
    gen_op_##name();                                                          \
5946
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5947
}
5948

    
5949
/* Single precision floating-point vectors operations */
5950
/* Arithmetic */
5951
GEN_SPEOP_ARITH2(evfsadd);
5952
GEN_SPEOP_ARITH2(evfssub);
5953
GEN_SPEOP_ARITH2(evfsmul);
5954
GEN_SPEOP_ARITH2(evfsdiv);
5955
GEN_SPEOP_ARITH1(evfsabs);
5956
GEN_SPEOP_ARITH1(evfsnabs);
5957
GEN_SPEOP_ARITH1(evfsneg);
5958
/* Conversion */
5959
GEN_SPEFPUOP_CONV(evfscfui);
5960
GEN_SPEFPUOP_CONV(evfscfsi);
5961
GEN_SPEFPUOP_CONV(evfscfuf);
5962
GEN_SPEFPUOP_CONV(evfscfsf);
5963
GEN_SPEFPUOP_CONV(evfsctui);
5964
GEN_SPEFPUOP_CONV(evfsctsi);
5965
GEN_SPEFPUOP_CONV(evfsctuf);
5966
GEN_SPEFPUOP_CONV(evfsctsf);
5967
GEN_SPEFPUOP_CONV(evfsctuiz);
5968
GEN_SPEFPUOP_CONV(evfsctsiz);
5969
/* Comparison */
5970
GEN_SPEOP_COMP(evfscmpgt);
5971
GEN_SPEOP_COMP(evfscmplt);
5972
GEN_SPEOP_COMP(evfscmpeq);
5973
GEN_SPEOP_COMP(evfststgt);
5974
GEN_SPEOP_COMP(evfststlt);
5975
GEN_SPEOP_COMP(evfststeq);
5976

    
5977
/* Opcodes definitions */
5978
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5979
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5980
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5981
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5982
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5983
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5984
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5985
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5986
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5987
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5988
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5989
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5990
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5991
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5992

    
5993
/* Single precision floating-point operations */
5994
/* Arithmetic */
5995
GEN_SPEOP_ARITH2(efsadd);
5996
GEN_SPEOP_ARITH2(efssub);
5997
GEN_SPEOP_ARITH2(efsmul);
5998
GEN_SPEOP_ARITH2(efsdiv);
5999
GEN_SPEOP_ARITH1(efsabs);
6000
GEN_SPEOP_ARITH1(efsnabs);
6001
GEN_SPEOP_ARITH1(efsneg);
6002
/* Conversion */
6003
GEN_SPEFPUOP_CONV(efscfui);
6004
GEN_SPEFPUOP_CONV(efscfsi);
6005
GEN_SPEFPUOP_CONV(efscfuf);
6006
GEN_SPEFPUOP_CONV(efscfsf);
6007
GEN_SPEFPUOP_CONV(efsctui);
6008
GEN_SPEFPUOP_CONV(efsctsi);
6009
GEN_SPEFPUOP_CONV(efsctuf);
6010
GEN_SPEFPUOP_CONV(efsctsf);
6011
GEN_SPEFPUOP_CONV(efsctuiz);
6012
GEN_SPEFPUOP_CONV(efsctsiz);
6013
GEN_SPEFPUOP_CONV(efscfd);
6014
/* Comparison */
6015
GEN_SPEOP_COMP(efscmpgt);
6016
GEN_SPEOP_COMP(efscmplt);
6017
GEN_SPEOP_COMP(efscmpeq);
6018
GEN_SPEOP_COMP(efststgt);
6019
GEN_SPEOP_COMP(efststlt);
6020
GEN_SPEOP_COMP(efststeq);
6021

    
6022
/* Opcodes definitions */
6023
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
6024
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
6025
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
6026
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
6027
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
6028
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
6029
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
6030
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
6031
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
6032
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
6033
GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
6034
GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPEFPU); //
6035
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
6036
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
6037

    
6038
/* Double precision floating-point operations */
6039
/* Arithmetic */
6040
GEN_SPEOP_ARITH2(efdadd);
6041
GEN_SPEOP_ARITH2(efdsub);
6042
GEN_SPEOP_ARITH2(efdmul);
6043
GEN_SPEOP_ARITH2(efddiv);
6044
GEN_SPEOP_ARITH1(efdabs);
6045
GEN_SPEOP_ARITH1(efdnabs);
6046
GEN_SPEOP_ARITH1(efdneg);
6047
/* Conversion */
6048

    
6049
GEN_SPEFPUOP_CONV(efdcfui);
6050
GEN_SPEFPUOP_CONV(efdcfsi);
6051
GEN_SPEFPUOP_CONV(efdcfuf);
6052
GEN_SPEFPUOP_CONV(efdcfsf);
6053
GEN_SPEFPUOP_CONV(efdctui);
6054
GEN_SPEFPUOP_CONV(efdctsi);
6055
GEN_SPEFPUOP_CONV(efdctuf);
6056
GEN_SPEFPUOP_CONV(efdctsf);
6057
GEN_SPEFPUOP_CONV(efdctuiz);
6058
GEN_SPEFPUOP_CONV(efdctsiz);
6059
GEN_SPEFPUOP_CONV(efdcfs);
6060
GEN_SPEFPUOP_CONV(efdcfuid);
6061
GEN_SPEFPUOP_CONV(efdcfsid);
6062
GEN_SPEFPUOP_CONV(efdctuidz);
6063
GEN_SPEFPUOP_CONV(efdctsidz);
6064
/* Comparison */
6065
GEN_SPEOP_COMP(efdcmpgt);
6066
GEN_SPEOP_COMP(efdcmplt);
6067
GEN_SPEOP_COMP(efdcmpeq);
6068
GEN_SPEOP_COMP(efdtstgt);
6069
GEN_SPEOP_COMP(efdtstlt);
6070
GEN_SPEOP_COMP(efdtsteq);
6071

    
6072
/* Opcodes definitions */
6073
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
6074
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
6075
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
6076
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
6077
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
6078
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
6079
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
6080
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
6081
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
6082
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
6083
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
6084
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
6085
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
6086
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
6087
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
6088
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6089

    
6090
/* End opcode list */
6091
GEN_OPCODE_MARK(end);
6092

    
6093
#include "translate_init.c"
6094
#include "helper_regs.h"
6095

    
6096
/*****************************************************************************/
6097
/* Misc PowerPC helpers */
6098
void cpu_dump_state (CPUState *env, FILE *f,
6099
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6100
                     int flags)
6101
{
6102
#define RGPL  4
6103
#define RFPL  4
6104

    
6105
    int i;
6106

    
6107
    cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
6108
                env->nip, env->lr, env->ctr, hreg_load_xer(env));
6109
    cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
6110
                env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
6111
#if !defined(NO_TIMER_DUMP)
6112
    cpu_fprintf(f, "TB %08x %08x "
6113
#if !defined(CONFIG_USER_ONLY)
6114
                "DECR %08x"
6115
#endif
6116
                "\n",
6117
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6118
#if !defined(CONFIG_USER_ONLY)
6119
                , cpu_ppc_load_decr(env)
6120
#endif
6121
                );
6122
#endif
6123
    for (i = 0; i < 32; i++) {
6124
        if ((i & (RGPL - 1)) == 0)
6125
            cpu_fprintf(f, "GPR%02d", i);
6126
        cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
6127
        if ((i & (RGPL - 1)) == (RGPL - 1))
6128
            cpu_fprintf(f, "\n");
6129
    }
6130
    cpu_fprintf(f, "CR ");
6131
    for (i = 0; i < 8; i++)
6132
        cpu_fprintf(f, "%01x", env->crf[i]);
6133
    cpu_fprintf(f, "  [");
6134
    for (i = 0; i < 8; i++) {
6135
        char a = '-';
6136
        if (env->crf[i] & 0x08)
6137
            a = 'L';
6138
        else if (env->crf[i] & 0x04)
6139
            a = 'G';
6140
        else if (env->crf[i] & 0x02)
6141
            a = 'E';
6142
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6143
    }
6144
    cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
6145
    for (i = 0; i < 32; i++) {
6146
        if ((i & (RFPL - 1)) == 0)
6147
            cpu_fprintf(f, "FPR%02d", i);
6148
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6149
        if ((i & (RFPL - 1)) == (RFPL - 1))
6150
            cpu_fprintf(f, "\n");
6151
    }
6152
#if !defined(CONFIG_USER_ONLY)
6153
    cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
6154
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6155
#endif
6156

    
6157
#undef RGPL
6158
#undef RFPL
6159
}
6160

    
6161
void cpu_dump_statistics (CPUState *env, FILE*f,
6162
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6163
                          int flags)
6164
{
6165
#if defined(DO_PPC_STATISTICS)
6166
    opc_handler_t **t1, **t2, **t3, *handler;
6167
    int op1, op2, op3;
6168

    
6169
    t1 = env->opcodes;
6170
    for (op1 = 0; op1 < 64; op1++) {
6171
        handler = t1[op1];
6172
        if (is_indirect_opcode(handler)) {
6173
            t2 = ind_table(handler);
6174
            for (op2 = 0; op2 < 32; op2++) {
6175
                handler = t2[op2];
6176
                if (is_indirect_opcode(handler)) {
6177
                    t3 = ind_table(handler);
6178
                    for (op3 = 0; op3 < 32; op3++) {
6179
                        handler = t3[op3];
6180
                        if (handler->count == 0)
6181
                            continue;
6182
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6183
                                    "%016llx %lld\n",
6184
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6185
                                    handler->oname,
6186
                                    handler->count, handler->count);
6187
                    }
6188
                } else {
6189
                    if (handler->count == 0)
6190
                        continue;
6191
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6192
                                "%016llx %lld\n",
6193
                                op1, op2, op1, op2, handler->oname,
6194
                                handler->count, handler->count);
6195
                }
6196
            }
6197
        } else {
6198
            if (handler->count == 0)
6199
                continue;
6200
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6201
                        op1, op1, handler->oname,
6202
                        handler->count, handler->count);
6203
        }
6204
    }
6205
#endif
6206
}
6207

    
6208
/*****************************************************************************/
6209
static always_inline void gen_intermediate_code_internal (CPUState *env,
6210
                                                          TranslationBlock *tb,
6211
                                                          int search_pc)
6212
{
6213
    DisasContext ctx, *ctxp = &ctx;
6214
    opc_handler_t **table, *handler;
6215
    target_ulong pc_start;
6216
    uint16_t *gen_opc_end;
6217
    int supervisor, little_endian;
6218
    int j, lj = -1;
6219
    int num_insns;
6220
    int max_insns;
6221

    
6222
    pc_start = tb->pc;
6223
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6224
#if defined(OPTIMIZE_FPRF_UPDATE)
6225
    gen_fprf_ptr = gen_fprf_buf;
6226
#endif
6227
    ctx.nip = pc_start;
6228
    ctx.tb = tb;
6229
    ctx.exception = POWERPC_EXCP_NONE;
6230
    ctx.spr_cb = env->spr_cb;
6231
    supervisor = env->mmu_idx;
6232
#if !defined(CONFIG_USER_ONLY)
6233
    ctx.supervisor = supervisor;
6234
#endif
6235
    little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
6236
#if defined(TARGET_PPC64)
6237
    ctx.sf_mode = msr_sf;
6238
    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
6239
#else
6240
    ctx.mem_idx = (supervisor << 1) | little_endian;
6241
#endif
6242
    ctx.dcache_line_size = env->dcache_line_size;
6243
    ctx.fpu_enabled = msr_fp;
6244
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
6245
        ctx.spe_enabled = msr_spe;
6246
    else
6247
        ctx.spe_enabled = 0;
6248
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
6249
        ctx.altivec_enabled = msr_vr;
6250
    else
6251
        ctx.altivec_enabled = 0;
6252
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6253
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
6254
    else
6255
        ctx.singlestep_enabled = 0;
6256
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
6257
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
6258
    if (unlikely(env->singlestep_enabled))
6259
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
6260
#if defined (DO_SINGLE_STEP) && 0
6261
    /* Single step trace mode */
6262
    msr_se = 1;
6263
#endif
6264
    num_insns = 0;
6265
    max_insns = tb->cflags & CF_COUNT_MASK;
6266
    if (max_insns == 0)
6267
        max_insns = CF_COUNT_MASK;
6268

    
6269
    gen_icount_start();
6270
    /* Set env in case of segfault during code fetch */
6271
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
6272
        if (unlikely(env->nb_breakpoints > 0)) {
6273
            for (j = 0; j < env->nb_breakpoints; j++) {
6274
                if (env->breakpoints[j] == ctx.nip) {
6275
                    gen_update_nip(&ctx, ctx.nip);
6276
                    gen_op_debug();
6277
                    break;
6278
                }
6279
            }
6280
        }
6281
        if (unlikely(search_pc)) {
6282
            j = gen_opc_ptr - gen_opc_buf;
6283
            if (lj < j) {
6284
                lj++;
6285
                while (lj < j)
6286
                    gen_opc_instr_start[lj++] = 0;
6287
                gen_opc_pc[lj] = ctx.nip;
6288
                gen_opc_instr_start[lj] = 1;
6289
                gen_opc_icount[lj] = num_insns;
6290
            }
6291
        }
6292
#if defined PPC_DEBUG_DISAS
6293
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6294
            fprintf(logfile, "----------------\n");
6295
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6296
                    ctx.nip, supervisor, (int)msr_ir);
6297
        }
6298
#endif
6299
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
6300
            gen_io_start();
6301
        if (unlikely(little_endian)) {
6302
            ctx.opcode = bswap32(ldl_code(ctx.nip));
6303
        } else {
6304
            ctx.opcode = ldl_code(ctx.nip);
6305
        }
6306
#if defined PPC_DEBUG_DISAS
6307
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6308
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6309
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6310
                    opc3(ctx.opcode), little_endian ? "little" : "big");
6311
        }
6312
#endif
6313
        ctx.nip += 4;
6314
        table = env->opcodes;
6315
        num_insns++;
6316
        handler = table[opc1(ctx.opcode)];
6317
        if (is_indirect_opcode(handler)) {
6318
            table = ind_table(handler);
6319
            handler = table[opc2(ctx.opcode)];
6320
            if (is_indirect_opcode(handler)) {
6321
                table = ind_table(handler);
6322
                handler = table[opc3(ctx.opcode)];
6323
            }
6324
        }
6325
        /* Is opcode *REALLY* valid ? */
6326
        if (unlikely(handler->handler == &gen_invalid)) {
6327
            if (loglevel != 0) {
6328
                fprintf(logfile, "invalid/unsupported opcode: "
6329
                        "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6330
                        opc1(ctx.opcode), opc2(ctx.opcode),
6331
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6332
            } else {
6333
                printf("invalid/unsupported opcode: "
6334
                       "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6335
                       opc1(ctx.opcode), opc2(ctx.opcode),
6336
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6337
            }
6338
        } else {
6339
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6340
                if (loglevel != 0) {
6341
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6342
                            "%02x - %02x - %02x (%08x) " ADDRX "\n",
6343
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6344
                            opc2(ctx.opcode), opc3(ctx.opcode),
6345
                            ctx.opcode, ctx.nip - 4);
6346
                } else {
6347
                    printf("invalid bits: %08x for opcode: "
6348
                           "%02x - %02x - %02x (%08x) " ADDRX "\n",
6349
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6350
                           opc2(ctx.opcode), opc3(ctx.opcode),
6351
                           ctx.opcode, ctx.nip - 4);
6352
                }
6353
                GEN_EXCP_INVAL(ctxp);
6354
                break;
6355
            }
6356
        }
6357
        (*(handler->handler))(&ctx);
6358
#if defined(DO_PPC_STATISTICS)
6359
        handler->count++;
6360
#endif
6361
        /* Check trace mode exceptions */
6362
        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
6363
                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
6364
                     ctx.exception != POWERPC_SYSCALL &&
6365
                     ctx.exception != POWERPC_EXCP_TRAP &&
6366
                     ctx.exception != POWERPC_EXCP_BRANCH)) {
6367
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6368
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6369
                            (env->singlestep_enabled) ||
6370
                            num_insns >= max_insns)) {
6371
            /* if we reach a page boundary or are single stepping, stop
6372
             * generation
6373
             */
6374
            break;
6375
        }
6376
#if defined (DO_SINGLE_STEP)
6377
        break;
6378
#endif
6379
    }
6380
    if (tb->cflags & CF_LAST_IO)
6381
        gen_io_end();
6382
    if (ctx.exception == POWERPC_EXCP_NONE) {
6383
        gen_goto_tb(&ctx, 0, ctx.nip);
6384
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6385
        if (unlikely(env->singlestep_enabled)) {
6386
            gen_update_nip(&ctx, ctx.nip);
6387
            gen_op_debug();
6388
        }
6389
        /* Generate the return instruction */
6390
        tcg_gen_exit_tb(0);
6391
    }
6392
    gen_icount_end(tb, num_insns);
6393
    *gen_opc_ptr = INDEX_op_end;
6394
    if (unlikely(search_pc)) {
6395
        j = gen_opc_ptr - gen_opc_buf;
6396
        lj++;
6397
        while (lj <= j)
6398
            gen_opc_instr_start[lj++] = 0;
6399
    } else {
6400
        tb->size = ctx.nip - pc_start;
6401
        tb->icount = num_insns;
6402
    }
6403
#if defined(DEBUG_DISAS)
6404
    if (loglevel & CPU_LOG_TB_CPU) {
6405
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6406
        cpu_dump_state(env, logfile, fprintf, 0);
6407
    }
6408
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6409
        int flags;
6410
        flags = env->bfd_mach;
6411
        flags |= little_endian << 16;
6412
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6413
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6414
        fprintf(logfile, "\n");
6415
    }
6416
#endif
6417
}
6418

    
6419
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6420
{
6421
    gen_intermediate_code_internal(env, tb, 0);
6422
}
6423

    
6424
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6425
{
6426
    gen_intermediate_code_internal(env, tb, 1);
6427
}
6428

    
6429
void gen_pc_load(CPUState *env, TranslationBlock *tb,
6430
                unsigned long searched_pc, int pc_pos, void *puc)
6431
{
6432
    int type, c;
6433
    /* for PPC, we need to look at the micro operation to get the
6434
     * access type */
6435
    env->nip = gen_opc_pc[pc_pos];
6436
    c = gen_opc_buf[pc_pos];
6437
    switch(c) {
6438
#if defined(CONFIG_USER_ONLY)
6439
#define CASE3(op)\
6440
    case INDEX_op_ ## op ## _raw
6441
#else
6442
#define CASE3(op)\
6443
    case INDEX_op_ ## op ## _user:\
6444
    case INDEX_op_ ## op ## _kernel:\
6445
    case INDEX_op_ ## op ## _hypv
6446
#endif
6447

    
6448
    CASE3(stfd):
6449
    CASE3(stfs):
6450
    CASE3(lfd):
6451
    CASE3(lfs):
6452
        type = ACCESS_FLOAT;
6453
        break;
6454
    CASE3(lwarx):
6455
        type = ACCESS_RES;
6456
        break;
6457
    CASE3(stwcx):
6458
        type = ACCESS_RES;
6459
        break;
6460
    CASE3(eciwx):
6461
    CASE3(ecowx):
6462
        type = ACCESS_EXT;
6463
        break;
6464
    default:
6465
        type = ACCESS_INT;
6466
        break;
6467
    }
6468
    env->access_type = type;
6469
}