Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 1d542695

History | View | Annotate | Download (228.6 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
    + 2*(10*6 + 22*7) /* AVRh, AVRl */];
54
static TCGv cpu_gpr[32];
55
#if !defined(TARGET_PPC64)
56
static TCGv cpu_gprh[32];
57
#endif
58
static TCGv cpu_avrh[32], cpu_avrl[32];
59

    
60
/* dyngen register indexes */
61
static TCGv cpu_T[3];
62
#if defined(TARGET_PPC64)
63
#define cpu_T64 cpu_T
64
#else
65
static TCGv cpu_T64[3];
66
#endif
67
static TCGv cpu_AVRh[3], cpu_AVRl[3];
68

    
69
#include "gen-icount.h"
70

    
71
void ppc_translate_init(void)
72
{
73
    int i;
74
    char* p;
75
    static int done_init = 0;
76

    
77
    if (done_init)
78
        return;
79

    
80
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
81
#if TARGET_LONG_BITS > HOST_LONG_BITS
82
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
83
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
84
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
85
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
86
    cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
87
                                  TCG_AREG0, offsetof(CPUState, t2), "T2");
88
#else
89
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
90
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
91
    cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
92
#endif
93
#if !defined(TARGET_PPC64)
94
    cpu_T64[0] = tcg_global_mem_new(TCG_TYPE_I64,
95
                                    TCG_AREG0, offsetof(CPUState, t0_64),
96
                                    "T0_64");
97
    cpu_T64[1] = tcg_global_mem_new(TCG_TYPE_I64,
98
                                    TCG_AREG0, offsetof(CPUState, t1_64),
99
                                    "T1_64");
100
    cpu_T64[2] = tcg_global_mem_new(TCG_TYPE_I64,
101
                                    TCG_AREG0, offsetof(CPUState, t2_64),
102
                                    "T2_64");
103
#endif
104
    cpu_AVRh[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
105
                                     offsetof(CPUState, avr0.u64[0]), "AVR0H");
106
    cpu_AVRl[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
107
                                     offsetof(CPUState, avr0.u64[1]), "AVR0L");
108
    cpu_AVRh[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
109
                                     offsetof(CPUState, avr1.u64[0]), "AVR1H");
110
    cpu_AVRl[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
111
                                     offsetof(CPUState, avr1.u64[1]), "AVR1L");
112
    cpu_AVRh[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
113
                                     offsetof(CPUState, avr2.u64[0]), "AVR2H");
114
    cpu_AVRl[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
115
                                     offsetof(CPUState, avr2.u64[1]), "AVR2L");
116

    
117
    p = cpu_reg_names;
118
    for (i = 0; i < 32; i++) {
119
        sprintf(p, "r%d", i);
120
        cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
121
                                        offsetof(CPUState, gpr[i]), p);
122
        p += (i < 10) ? 3 : 4;
123
#if !defined(TARGET_PPC64)
124
        sprintf(p, "r%dH", i);
125
        cpu_gprh[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
126
                                         offsetof(CPUState, gprh[i]), p);
127
        p += (i < 10) ? 4 : 5;
128
#endif
129

    
130
        sprintf(p, "avr%dH", i);
131
        cpu_avrh[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
132
                                         offsetof(CPUState, avr[i].u64[0]), p);
133
        p += (i < 10) ? 6 : 7;
134
        sprintf(p, "avr%dL", i);
135
        cpu_avrl[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
136
                                         offsetof(CPUState, avr[i].u64[1]), p);
137
        p += (i < 10) ? 6 : 7;
138
    }
139

    
140
    /* register helpers */
141
#undef DEF_HELPER
142
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
143
#include "helper.h"
144

    
145
    done_init = 1;
146
}
147

    
148
#if defined(OPTIMIZE_FPRF_UPDATE)
149
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
150
static uint16_t **gen_fprf_ptr;
151
#endif
152

    
153
#define GEN8(func, NAME)                                                      \
154
static GenOpFunc *NAME ## _table [8] = {                                      \
155
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
156
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
157
};                                                                            \
158
static always_inline void func (int n)                                        \
159
{                                                                             \
160
    NAME ## _table[n]();                                                      \
161
}
162

    
163
#define GEN16(func, NAME)                                                     \
164
static GenOpFunc *NAME ## _table [16] = {                                     \
165
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
166
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
167
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
168
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
169
};                                                                            \
170
static always_inline void func (int n)                                        \
171
{                                                                             \
172
    NAME ## _table[n]();                                                      \
173
}
174

    
175
#define GEN32(func, NAME)                                                     \
176
static GenOpFunc *NAME ## _table [32] = {                                     \
177
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
178
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
179
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
180
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
181
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
182
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
183
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
184
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
185
};                                                                            \
186
static always_inline void func (int n)                                        \
187
{                                                                             \
188
    NAME ## _table[n]();                                                      \
189
}
190

    
191
/* Condition register moves */
192
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
193
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
194
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
195
#if 0 // Unused
196
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
197
#endif
198

    
199
/* floating point registers moves */
200
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
201
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
202
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
203
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
204
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
205
#if 0 // unused
206
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
207
#endif
208

    
209
/* internal defines */
210
typedef struct DisasContext {
211
    struct TranslationBlock *tb;
212
    target_ulong nip;
213
    uint32_t opcode;
214
    uint32_t exception;
215
    /* Routine used to access memory */
216
    int mem_idx;
217
    /* Translation flags */
218
#if !defined(CONFIG_USER_ONLY)
219
    int supervisor;
220
#endif
221
#if defined(TARGET_PPC64)
222
    int sf_mode;
223
#endif
224
    int fpu_enabled;
225
    int altivec_enabled;
226
    int spe_enabled;
227
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
228
    int singlestep_enabled;
229
    int dcache_line_size;
230
} DisasContext;
231

    
232
struct opc_handler_t {
233
    /* invalid bits */
234
    uint32_t inval;
235
    /* instruction type */
236
    uint64_t type;
237
    /* handler */
238
    void (*handler)(DisasContext *ctx);
239
#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
240
    const unsigned char *oname;
241
#endif
242
#if defined(DO_PPC_STATISTICS)
243
    uint64_t count;
244
#endif
245
};
246

    
247
static always_inline void gen_set_Rc0 (DisasContext *ctx)
248
{
249
#if defined(TARGET_PPC64)
250
    if (ctx->sf_mode)
251
        gen_op_cmpi_64(0);
252
    else
253
#endif
254
        gen_op_cmpi(0);
255
    gen_op_set_Rc0();
256
}
257

    
258
static always_inline void gen_reset_fpstatus (void)
259
{
260
#ifdef CONFIG_SOFTFLOAT
261
    gen_op_reset_fpstatus();
262
#endif
263
}
264

    
265
static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
266
{
267
    if (set_fprf != 0) {
268
        /* This case might be optimized later */
269
#if defined(OPTIMIZE_FPRF_UPDATE)
270
        *gen_fprf_ptr++ = gen_opc_ptr;
271
#endif
272
        gen_op_compute_fprf(1);
273
        if (unlikely(set_rc))
274
            gen_op_store_T0_crf(1);
275
        gen_op_float_check_status();
276
    } else if (unlikely(set_rc)) {
277
        /* We always need to compute fpcc */
278
        gen_op_compute_fprf(0);
279
        gen_op_store_T0_crf(1);
280
        if (set_fprf)
281
            gen_op_float_check_status();
282
    }
283
}
284

    
285
static always_inline void gen_optimize_fprf (void)
286
{
287
#if defined(OPTIMIZE_FPRF_UPDATE)
288
    uint16_t **ptr;
289

    
290
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
291
        *ptr = INDEX_op_nop1;
292
    gen_fprf_ptr = gen_fprf_buf;
293
#endif
294
}
295

    
296
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
297
{
298
#if defined(TARGET_PPC64)
299
    if (ctx->sf_mode)
300
        gen_op_update_nip_64(nip >> 32, nip);
301
    else
302
#endif
303
        gen_op_update_nip(nip);
304
}
305

    
306
#define GEN_EXCP(ctx, excp, error)                                            \
307
do {                                                                          \
308
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
309
        gen_update_nip(ctx, (ctx)->nip);                                      \
310
    }                                                                         \
311
    gen_op_raise_exception_err((excp), (error));                              \
312
    ctx->exception = (excp);                                                  \
313
} while (0)
314

    
315
#define GEN_EXCP_INVAL(ctx)                                                   \
316
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
317
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
318

    
319
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
320
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
321
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
322

    
323
#define GEN_EXCP_PRIVREG(ctx)                                                 \
324
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
325
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
326

    
327
#define GEN_EXCP_NO_FP(ctx)                                                   \
328
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
329

    
330
#define GEN_EXCP_NO_AP(ctx)                                                   \
331
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
332

    
333
#define GEN_EXCP_NO_VR(ctx)                                                   \
334
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
335

    
336
/* Stop translation */
337
static always_inline void GEN_STOP (DisasContext *ctx)
338
{
339
    gen_update_nip(ctx, ctx->nip);
340
    ctx->exception = POWERPC_EXCP_STOP;
341
}
342

    
343
/* No need to update nip here, as execution flow will change */
344
static always_inline void GEN_SYNC (DisasContext *ctx)
345
{
346
    ctx->exception = POWERPC_EXCP_SYNC;
347
}
348

    
349
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
350
static void gen_##name (DisasContext *ctx);                                   \
351
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
352
static void gen_##name (DisasContext *ctx)
353

    
354
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
355
static void gen_##name (DisasContext *ctx);                                   \
356
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
357
static void gen_##name (DisasContext *ctx)
358

    
359
typedef struct opcode_t {
360
    unsigned char opc1, opc2, opc3;
361
#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
362
    unsigned char pad[5];
363
#else
364
    unsigned char pad[1];
365
#endif
366
    opc_handler_t handler;
367
    const unsigned char *oname;
368
} opcode_t;
369

    
370
/*****************************************************************************/
371
/***                           Instruction decoding                        ***/
372
#define EXTRACT_HELPER(name, shift, nb)                                       \
373
static always_inline uint32_t name (uint32_t opcode)                          \
374
{                                                                             \
375
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
376
}
377

    
378
#define EXTRACT_SHELPER(name, shift, nb)                                      \
379
static always_inline int32_t name (uint32_t opcode)                           \
380
{                                                                             \
381
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
382
}
383

    
384
/* Opcode part 1 */
385
EXTRACT_HELPER(opc1, 26, 6);
386
/* Opcode part 2 */
387
EXTRACT_HELPER(opc2, 1, 5);
388
/* Opcode part 3 */
389
EXTRACT_HELPER(opc3, 6, 5);
390
/* Update Cr0 flags */
391
EXTRACT_HELPER(Rc, 0, 1);
392
/* Destination */
393
EXTRACT_HELPER(rD, 21, 5);
394
/* Source */
395
EXTRACT_HELPER(rS, 21, 5);
396
/* First operand */
397
EXTRACT_HELPER(rA, 16, 5);
398
/* Second operand */
399
EXTRACT_HELPER(rB, 11, 5);
400
/* Third operand */
401
EXTRACT_HELPER(rC, 6, 5);
402
/***                               Get CRn                                 ***/
403
EXTRACT_HELPER(crfD, 23, 3);
404
EXTRACT_HELPER(crfS, 18, 3);
405
EXTRACT_HELPER(crbD, 21, 5);
406
EXTRACT_HELPER(crbA, 16, 5);
407
EXTRACT_HELPER(crbB, 11, 5);
408
/* SPR / TBL */
409
EXTRACT_HELPER(_SPR, 11, 10);
410
static always_inline uint32_t SPR (uint32_t opcode)
411
{
412
    uint32_t sprn = _SPR(opcode);
413

    
414
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
415
}
416
/***                              Get constants                            ***/
417
EXTRACT_HELPER(IMM, 12, 8);
418
/* 16 bits signed immediate value */
419
EXTRACT_SHELPER(SIMM, 0, 16);
420
/* 16 bits unsigned immediate value */
421
EXTRACT_HELPER(UIMM, 0, 16);
422
/* Bit count */
423
EXTRACT_HELPER(NB, 11, 5);
424
/* Shift count */
425
EXTRACT_HELPER(SH, 11, 5);
426
/* Mask start */
427
EXTRACT_HELPER(MB, 6, 5);
428
/* Mask end */
429
EXTRACT_HELPER(ME, 1, 5);
430
/* Trap operand */
431
EXTRACT_HELPER(TO, 21, 5);
432

    
433
EXTRACT_HELPER(CRM, 12, 8);
434
EXTRACT_HELPER(FM, 17, 8);
435
EXTRACT_HELPER(SR, 16, 4);
436
EXTRACT_HELPER(FPIMM, 12, 4);
437

    
438
/***                            Jump target decoding                       ***/
439
/* Displacement */
440
EXTRACT_SHELPER(d, 0, 16);
441
/* Immediate address */
442
static always_inline target_ulong LI (uint32_t opcode)
443
{
444
    return (opcode >> 0) & 0x03FFFFFC;
445
}
446

    
447
static always_inline uint32_t BD (uint32_t opcode)
448
{
449
    return (opcode >> 0) & 0xFFFC;
450
}
451

    
452
EXTRACT_HELPER(BO, 21, 5);
453
EXTRACT_HELPER(BI, 16, 5);
454
/* Absolute/relative address */
455
EXTRACT_HELPER(AA, 1, 1);
456
/* Link */
457
EXTRACT_HELPER(LK, 0, 1);
458

    
459
/* Create a mask between <start> and <end> bits */
460
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
461
{
462
    target_ulong ret;
463

    
464
#if defined(TARGET_PPC64)
465
    if (likely(start == 0)) {
466
        ret = UINT64_MAX << (63 - end);
467
    } else if (likely(end == 63)) {
468
        ret = UINT64_MAX >> start;
469
    }
470
#else
471
    if (likely(start == 0)) {
472
        ret = UINT32_MAX << (31  - end);
473
    } else if (likely(end == 31)) {
474
        ret = UINT32_MAX >> start;
475
    }
476
#endif
477
    else {
478
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
479
            (((target_ulong)(-1ULL) >> (end)) >> 1);
480
        if (unlikely(start > end))
481
            return ~ret;
482
    }
483

    
484
    return ret;
485
}
486

    
487
/*****************************************************************************/
488
/* PowerPC Instructions types definitions                                    */
489
enum {
490
    PPC_NONE           = 0x0000000000000000ULL,
491
    /* PowerPC base instructions set                                         */
492
    PPC_INSNS_BASE     = 0x0000000000000001ULL,
493
    /*   integer operations instructions                                     */
494
#define PPC_INTEGER PPC_INSNS_BASE
495
    /*   flow control instructions                                           */
496
#define PPC_FLOW    PPC_INSNS_BASE
497
    /*   virtual memory instructions                                         */
498
#define PPC_MEM     PPC_INSNS_BASE
499
    /*   ld/st with reservation instructions                                 */
500
#define PPC_RES     PPC_INSNS_BASE
501
    /*   spr/msr access instructions                                         */
502
#define PPC_MISC    PPC_INSNS_BASE
503
    /* Deprecated instruction sets                                           */
504
    /*   Original POWER instruction set                                      */
505
    PPC_POWER          = 0x0000000000000002ULL,
506
    /*   POWER2 instruction set extension                                    */
507
    PPC_POWER2         = 0x0000000000000004ULL,
508
    /*   Power RTC support                                                   */
509
    PPC_POWER_RTC      = 0x0000000000000008ULL,
510
    /*   Power-to-PowerPC bridge (601)                                       */
511
    PPC_POWER_BR       = 0x0000000000000010ULL,
512
    /* 64 bits PowerPC instruction set                                       */
513
    PPC_64B            = 0x0000000000000020ULL,
514
    /*   New 64 bits extensions (PowerPC 2.0x)                               */
515
    PPC_64BX           = 0x0000000000000040ULL,
516
    /*   64 bits hypervisor extensions                                       */
517
    PPC_64H            = 0x0000000000000080ULL,
518
    /*   New wait instruction (PowerPC 2.0x)                                 */
519
    PPC_WAIT           = 0x0000000000000100ULL,
520
    /*   Time base mftb instruction                                          */
521
    PPC_MFTB           = 0x0000000000000200ULL,
522

    
523
    /* Fixed-point unit extensions                                           */
524
    /*   PowerPC 602 specific                                                */
525
    PPC_602_SPEC       = 0x0000000000000400ULL,
526
    /*   isel instruction                                                    */
527
    PPC_ISEL           = 0x0000000000000800ULL,
528
    /*   popcntb instruction                                                 */
529
    PPC_POPCNTB        = 0x0000000000001000ULL,
530
    /*   string load / store                                                 */
531
    PPC_STRING         = 0x0000000000002000ULL,
532

    
533
    /* Floating-point unit extensions                                        */
534
    /*   Optional floating point instructions                                */
535
    PPC_FLOAT          = 0x0000000000010000ULL,
536
    /* New floating-point extensions (PowerPC 2.0x)                          */
537
    PPC_FLOAT_EXT      = 0x0000000000020000ULL,
538
    PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
539
    PPC_FLOAT_FRES     = 0x0000000000080000ULL,
540
    PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
541
    PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
542
    PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
543
    PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
544

    
545
    /* Vector/SIMD extensions                                                */
546
    /*   Altivec support                                                     */
547
    PPC_ALTIVEC        = 0x0000000001000000ULL,
548
    /*   PowerPC 2.03 SPE extension                                          */
549
    PPC_SPE            = 0x0000000002000000ULL,
550
    /*   PowerPC 2.03 SPE floating-point extension                           */
551
    PPC_SPEFPU         = 0x0000000004000000ULL,
552

    
553
    /* Optional memory control instructions                                  */
554
    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
555
    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
556
    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
557
    /*   sync instruction                                                    */
558
    PPC_MEM_SYNC       = 0x0000000080000000ULL,
559
    /*   eieio instruction                                                   */
560
    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
561

    
562
    /* Cache control instructions                                            */
563
    PPC_CACHE          = 0x0000000200000000ULL,
564
    /*   icbi instruction                                                    */
565
    PPC_CACHE_ICBI     = 0x0000000400000000ULL,
566
    /*   dcbz instruction with fixed cache line size                         */
567
    PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
568
    /*   dcbz instruction with tunable cache line size                       */
569
    PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
570
    /*   dcba instruction                                                    */
571
    PPC_CACHE_DCBA     = 0x0000002000000000ULL,
572
    /*   Freescale cache locking instructions                                */
573
    PPC_CACHE_LOCK     = 0x0000004000000000ULL,
574

    
575
    /* MMU related extensions                                                */
576
    /*   external control instructions                                       */
577
    PPC_EXTERN         = 0x0000010000000000ULL,
578
    /*   segment register access instructions                                */
579
    PPC_SEGMENT        = 0x0000020000000000ULL,
580
    /*   PowerPC 6xx TLB management instructions                             */
581
    PPC_6xx_TLB        = 0x0000040000000000ULL,
582
    /* PowerPC 74xx TLB management instructions                              */
583
    PPC_74xx_TLB       = 0x0000080000000000ULL,
584
    /*   PowerPC 40x TLB management instructions                             */
585
    PPC_40x_TLB        = 0x0000100000000000ULL,
586
    /*   segment register access instructions for PowerPC 64 "bridge"        */
587
    PPC_SEGMENT_64B    = 0x0000200000000000ULL,
588
    /*   SLB management                                                      */
589
    PPC_SLBI           = 0x0000400000000000ULL,
590

    
591
    /* Embedded PowerPC dedicated instructions                               */
592
    PPC_WRTEE          = 0x0001000000000000ULL,
593
    /* PowerPC 40x exception model                                           */
594
    PPC_40x_EXCP       = 0x0002000000000000ULL,
595
    /* PowerPC 405 Mac instructions                                          */
596
    PPC_405_MAC        = 0x0004000000000000ULL,
597
    /* PowerPC 440 specific instructions                                     */
598
    PPC_440_SPEC       = 0x0008000000000000ULL,
599
    /* BookE (embedded) PowerPC specification                                */
600
    PPC_BOOKE          = 0x0010000000000000ULL,
601
    /* mfapidi instruction                                                   */
602
    PPC_MFAPIDI        = 0x0020000000000000ULL,
603
    /* tlbiva instruction                                                    */
604
    PPC_TLBIVA         = 0x0040000000000000ULL,
605
    /* tlbivax instruction                                                   */
606
    PPC_TLBIVAX        = 0x0080000000000000ULL,
607
    /* PowerPC 4xx dedicated instructions                                    */
608
    PPC_4xx_COMMON     = 0x0100000000000000ULL,
609
    /* PowerPC 40x ibct instructions                                         */
610
    PPC_40x_ICBT       = 0x0200000000000000ULL,
611
    /* rfmci is not implemented in all BookE PowerPC                         */
612
    PPC_RFMCI          = 0x0400000000000000ULL,
613
    /* rfdi instruction                                                      */
614
    PPC_RFDI           = 0x0800000000000000ULL,
615
    /* DCR accesses                                                          */
616
    PPC_DCR            = 0x1000000000000000ULL,
617
    /* DCR extended accesse                                                  */
618
    PPC_DCRX           = 0x2000000000000000ULL,
619
    /* user-mode DCR access, implemented in PowerPC 460                      */
620
    PPC_DCRUX          = 0x4000000000000000ULL,
621
};
622

    
623
/*****************************************************************************/
624
/* PowerPC instructions table                                                */
625
#if HOST_LONG_BITS == 64
626
#define OPC_ALIGN 8
627
#else
628
#define OPC_ALIGN 4
629
#endif
630
#if defined(__APPLE__)
631
#define OPCODES_SECTION                                                       \
632
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
633
#else
634
#define OPCODES_SECTION                                                       \
635
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
636
#endif
637

    
638
#if defined(DO_PPC_STATISTICS)
639
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
640
OPCODES_SECTION opcode_t opc_##name = {                                       \
641
    .opc1 = op1,                                                              \
642
    .opc2 = op2,                                                              \
643
    .opc3 = op3,                                                              \
644
    .pad  = { 0, },                                                           \
645
    .handler = {                                                              \
646
        .inval   = invl,                                                      \
647
        .type = _typ,                                                         \
648
        .handler = &gen_##name,                                               \
649
        .oname = stringify(name),                                             \
650
    },                                                                        \
651
    .oname = stringify(name),                                                 \
652
}
653
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
654
OPCODES_SECTION opcode_t opc_##name = {                                       \
655
    .opc1 = op1,                                                              \
656
    .opc2 = op2,                                                              \
657
    .opc3 = op3,                                                              \
658
    .pad  = { 0, },                                                           \
659
    .handler = {                                                              \
660
        .inval   = invl,                                                      \
661
        .type = _typ,                                                         \
662
        .handler = &gen_##name,                                               \
663
        .oname = onam,                                                        \
664
    },                                                                        \
665
    .oname = onam,                                                            \
666
}
667
#else
668
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
669
OPCODES_SECTION opcode_t opc_##name = {                                       \
670
    .opc1 = op1,                                                              \
671
    .opc2 = op2,                                                              \
672
    .opc3 = op3,                                                              \
673
    .pad  = { 0, },                                                           \
674
    .handler = {                                                              \
675
        .inval   = invl,                                                      \
676
        .type = _typ,                                                         \
677
        .handler = &gen_##name,                                               \
678
    },                                                                        \
679
    .oname = stringify(name),                                                 \
680
}
681
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
682
OPCODES_SECTION opcode_t opc_##name = {                                       \
683
    .opc1 = op1,                                                              \
684
    .opc2 = op2,                                                              \
685
    .opc3 = op3,                                                              \
686
    .pad  = { 0, },                                                           \
687
    .handler = {                                                              \
688
        .inval   = invl,                                                      \
689
        .type = _typ,                                                         \
690
        .handler = &gen_##name,                                               \
691
    },                                                                        \
692
    .oname = onam,                                                            \
693
}
694
#endif
695

    
696
#define GEN_OPCODE_MARK(name)                                                 \
697
OPCODES_SECTION opcode_t opc_##name = {                                       \
698
    .opc1 = 0xFF,                                                             \
699
    .opc2 = 0xFF,                                                             \
700
    .opc3 = 0xFF,                                                             \
701
    .pad  = { 0, },                                                           \
702
    .handler = {                                                              \
703
        .inval   = 0x00000000,                                                \
704
        .type = 0x00,                                                         \
705
        .handler = NULL,                                                      \
706
    },                                                                        \
707
    .oname = stringify(name),                                                 \
708
}
709

    
710
/* Start opcode list */
711
GEN_OPCODE_MARK(start);
712

    
713
/* Invalid instruction */
714
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
715
{
716
    GEN_EXCP_INVAL(ctx);
717
}
718

    
719
static opc_handler_t invalid_handler = {
720
    .inval   = 0xFFFFFFFF,
721
    .type    = PPC_NONE,
722
    .handler = gen_invalid,
723
};
724

    
725
/***                           Integer arithmetic                          ***/
726
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
727
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
728
{                                                                             \
729
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
730
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
731
    gen_op_##name();                                                          \
732
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
733
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
734
        gen_set_Rc0(ctx);                                                     \
735
}
736

    
737
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
738
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
739
{                                                                             \
740
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
741
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
742
    gen_op_##name();                                                          \
743
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
744
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
745
        gen_set_Rc0(ctx);                                                     \
746
}
747

    
748
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
749
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
750
{                                                                             \
751
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
752
    gen_op_##name();                                                          \
753
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
754
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
755
        gen_set_Rc0(ctx);                                                     \
756
}
757
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
758
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
759
{                                                                             \
760
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
761
    gen_op_##name();                                                          \
762
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
763
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
764
        gen_set_Rc0(ctx);                                                     \
765
}
766

    
767
/* Two operands arithmetic functions */
768
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
769
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
770
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
771

    
772
/* Two operands arithmetic functions with no overflow allowed */
773
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
774
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
775

    
776
/* One operand arithmetic functions */
777
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
778
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
779
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
780

    
781
#if defined(TARGET_PPC64)
782
#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
783
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
784
{                                                                             \
785
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
786
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
787
    if (ctx->sf_mode)                                                         \
788
        gen_op_##name##_64();                                                 \
789
    else                                                                      \
790
        gen_op_##name();                                                      \
791
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
792
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
793
        gen_set_Rc0(ctx);                                                     \
794
}
795

    
796
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
797
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
798
{                                                                             \
799
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
800
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(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
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
811
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
812
{                                                                             \
813
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
814
    if (ctx->sf_mode)                                                         \
815
        gen_op_##name##_64();                                                 \
816
    else                                                                      \
817
        gen_op_##name();                                                      \
818
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
819
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
820
        gen_set_Rc0(ctx);                                                     \
821
}
822
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
823
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
824
{                                                                             \
825
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
826
    if (ctx->sf_mode)                                                         \
827
        gen_op_##name##_64();                                                 \
828
    else                                                                      \
829
        gen_op_##name();                                                      \
830
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
831
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
832
        gen_set_Rc0(ctx);                                                     \
833
}
834

    
835
/* Two operands arithmetic functions */
836
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
837
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
838
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
839

    
840
/* Two operands arithmetic functions with no overflow allowed */
841
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
842
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
843

    
844
/* One operand arithmetic functions */
845
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
846
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
847
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
848
#else
849
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
850
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
851
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
852
#endif
853

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

    
1044
    if (rA(ctx->opcode) == 0) {
1045
        /* li case */
1046
        tcg_gen_movi_tl(cpu_T[0], simm);
1047
    } else {
1048
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1049
        if (likely(simm != 0))
1050
            gen_op_addi(simm);
1051
    }
1052
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1053
}
1054
/* addic */
1055
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1056
{
1057
    target_long simm = SIMM(ctx->opcode);
1058

    
1059
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1060
    if (likely(simm != 0)) {
1061
        tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1062
        gen_op_addi(simm);
1063
#if defined(TARGET_PPC64)
1064
        if (ctx->sf_mode)
1065
            gen_op_check_addc_64();
1066
        else
1067
#endif
1068
            gen_op_check_addc();
1069
    } else {
1070
        gen_op_clear_xer_ca();
1071
    }
1072
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1073
}
1074
/* addic. */
1075
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1076
{
1077
    target_long simm = SIMM(ctx->opcode);
1078

    
1079
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1080
    if (likely(simm != 0)) {
1081
        tcg_gen_mov_tl(cpu_T[2], cpu_T[0]);
1082
        gen_op_addi(simm);
1083
#if defined(TARGET_PPC64)
1084
        if (ctx->sf_mode)
1085
            gen_op_check_addc_64();
1086
        else
1087
#endif
1088
            gen_op_check_addc();
1089
    } else {
1090
        gen_op_clear_xer_ca();
1091
    }
1092
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1093
    gen_set_Rc0(ctx);
1094
}
1095
/* addis */
1096
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1097
{
1098
    target_long simm = SIMM(ctx->opcode);
1099

    
1100
    if (rA(ctx->opcode) == 0) {
1101
        /* lis case */
1102
        tcg_gen_movi_tl(cpu_T[0], simm << 16);
1103
    } else {
1104
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1105
        if (likely(simm != 0))
1106
            gen_op_addi(simm << 16);
1107
    }
1108
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1109
}
1110
/* mulli */
1111
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1112
{
1113
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1114
    gen_op_mulli(SIMM(ctx->opcode));
1115
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1116
}
1117
/* subfic */
1118
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1119
{
1120
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1121
#if defined(TARGET_PPC64)
1122
    if (ctx->sf_mode)
1123
        gen_op_subfic_64(SIMM(ctx->opcode));
1124
    else
1125
#endif
1126
        gen_op_subfic(SIMM(ctx->opcode));
1127
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1128
}
1129

    
1130
#if defined(TARGET_PPC64)
1131
/* mulhd  mulhd.                   */
1132
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
1133
/* mulhdu mulhdu.                  */
1134
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
1135
/* mulld  mulld.  mulldo  mulldo.  */
1136
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
1137
/* divd   divd.   divdo   divdo.   */
1138
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
1139
/* divdu  divdu.  divduo  divduo.  */
1140
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
1141
#endif
1142

    
1143
/***                           Integer comparison                          ***/
1144
#if defined(TARGET_PPC64)
1145
#define GEN_CMP(name, opc, type)                                              \
1146
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1147
{                                                                             \
1148
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
1149
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
1150
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))                           \
1151
        gen_op_##name##_64();                                                 \
1152
    else                                                                      \
1153
        gen_op_##name();                                                      \
1154
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
1155
}
1156
#else
1157
#define GEN_CMP(name, opc, type)                                              \
1158
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1159
{                                                                             \
1160
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
1161
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
1162
    gen_op_##name();                                                          \
1163
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
1164
}
1165
#endif
1166

    
1167
/* cmp */
1168
GEN_CMP(cmp, 0x00, PPC_INTEGER);
1169
/* cmpi */
1170
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1171
{
1172
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1173
#if defined(TARGET_PPC64)
1174
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1175
        gen_op_cmpi_64(SIMM(ctx->opcode));
1176
    else
1177
#endif
1178
        gen_op_cmpi(SIMM(ctx->opcode));
1179
    gen_op_store_T0_crf(crfD(ctx->opcode));
1180
}
1181
/* cmpl */
1182
GEN_CMP(cmpl, 0x01, PPC_INTEGER);
1183
/* cmpli */
1184
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1185
{
1186
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1187
#if defined(TARGET_PPC64)
1188
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1189
        gen_op_cmpli_64(UIMM(ctx->opcode));
1190
    else
1191
#endif
1192
        gen_op_cmpli(UIMM(ctx->opcode));
1193
    gen_op_store_T0_crf(crfD(ctx->opcode));
1194
}
1195

    
1196
/* isel (PowerPC 2.03 specification) */
1197
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
1198
{
1199
    uint32_t bi = rC(ctx->opcode);
1200
    uint32_t mask;
1201

    
1202
    if (rA(ctx->opcode) == 0) {
1203
        tcg_gen_movi_tl(cpu_T[0], 0);
1204
    } else {
1205
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1206
    }
1207
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
1208
    mask = 1 << (3 - (bi & 0x03));
1209
    gen_op_load_crf_T0(bi >> 2);
1210
    gen_op_test_true(mask);
1211
    gen_op_isel();
1212
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1213
}
1214

    
1215
/***                            Integer logical                            ***/
1216
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1217
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1218
{                                                                             \
1219
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
1220
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
1221
    gen_op_##name();                                                          \
1222
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
1223
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1224
        gen_set_Rc0(ctx);                                                     \
1225
}
1226
#define GEN_LOGICAL2(name, opc, type)                                         \
1227
__GEN_LOGICAL2(name, 0x1C, opc, type)
1228

    
1229
#define GEN_LOGICAL1(name, opc, type)                                         \
1230
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1231
{                                                                             \
1232
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
1233
    gen_op_##name();                                                          \
1234
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
1235
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1236
        gen_set_Rc0(ctx);                                                     \
1237
}
1238

    
1239
/* and & and. */
1240
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1241
/* andc & andc. */
1242
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1243
/* andi. */
1244
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1245
{
1246
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1247
    gen_op_andi_T0(UIMM(ctx->opcode));
1248
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1249
    gen_set_Rc0(ctx);
1250
}
1251
/* andis. */
1252
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1253
{
1254
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1255
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
1256
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1257
    gen_set_Rc0(ctx);
1258
}
1259

    
1260
/* cntlzw */
1261
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1262
/* eqv & eqv. */
1263
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1264
/* extsb & extsb. */
1265
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1266
/* extsh & extsh. */
1267
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1268
/* nand & nand. */
1269
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1270
/* nor & nor. */
1271
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1272

    
1273
/* or & or. */
1274
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1275
{
1276
    int rs, ra, rb;
1277

    
1278
    rs = rS(ctx->opcode);
1279
    ra = rA(ctx->opcode);
1280
    rb = rB(ctx->opcode);
1281
    /* Optimisation for mr. ri case */
1282
    if (rs != ra || rs != rb) {
1283
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
1284
        if (rs != rb) {
1285
            tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]);
1286
            gen_op_or();
1287
        }
1288
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
1289
        if (unlikely(Rc(ctx->opcode) != 0))
1290
            gen_set_Rc0(ctx);
1291
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1292
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
1293
        gen_set_Rc0(ctx);
1294
#if defined(TARGET_PPC64)
1295
    } else {
1296
        switch (rs) {
1297
        case 1:
1298
            /* Set process priority to low */
1299
            gen_op_store_pri(2);
1300
            break;
1301
        case 6:
1302
            /* Set process priority to medium-low */
1303
            gen_op_store_pri(3);
1304
            break;
1305
        case 2:
1306
            /* Set process priority to normal */
1307
            gen_op_store_pri(4);
1308
            break;
1309
#if !defined(CONFIG_USER_ONLY)
1310
        case 31:
1311
            if (ctx->supervisor > 0) {
1312
                /* Set process priority to very low */
1313
                gen_op_store_pri(1);
1314
            }
1315
            break;
1316
        case 5:
1317
            if (ctx->supervisor > 0) {
1318
                /* Set process priority to medium-hight */
1319
                gen_op_store_pri(5);
1320
            }
1321
            break;
1322
        case 3:
1323
            if (ctx->supervisor > 0) {
1324
                /* Set process priority to high */
1325
                gen_op_store_pri(6);
1326
            }
1327
            break;
1328
        case 7:
1329
            if (ctx->supervisor > 1) {
1330
                /* Set process priority to very high */
1331
                gen_op_store_pri(7);
1332
            }
1333
            break;
1334
#endif
1335
        default:
1336
            /* nop */
1337
            break;
1338
        }
1339
#endif
1340
    }
1341
}
1342

    
1343
/* orc & orc. */
1344
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1345
/* xor & xor. */
1346
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1347
{
1348
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1349
    /* Optimisation for "set to zero" case */
1350
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1351
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1352
        gen_op_xor();
1353
    } else {
1354
        tcg_gen_movi_tl(cpu_T[0], 0);
1355
    }
1356
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1357
    if (unlikely(Rc(ctx->opcode) != 0))
1358
        gen_set_Rc0(ctx);
1359
}
1360
/* ori */
1361
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1362
{
1363
    target_ulong uimm = UIMM(ctx->opcode);
1364

    
1365
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1366
        /* NOP */
1367
        /* XXX: should handle special NOPs for POWER series */
1368
        return;
1369
    }
1370
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1371
    if (likely(uimm != 0))
1372
        gen_op_ori(uimm);
1373
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1374
}
1375
/* oris */
1376
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1377
{
1378
    target_ulong uimm = UIMM(ctx->opcode);
1379

    
1380
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1381
        /* NOP */
1382
        return;
1383
    }
1384
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1385
    if (likely(uimm != 0))
1386
        gen_op_ori(uimm << 16);
1387
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1388
}
1389
/* xori */
1390
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1391
{
1392
    target_ulong uimm = UIMM(ctx->opcode);
1393

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

    
1404
/* xoris */
1405
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1406
{
1407
    target_ulong uimm = UIMM(ctx->opcode);
1408

    
1409
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1410
        /* NOP */
1411
        return;
1412
    }
1413
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1414
    if (likely(uimm != 0))
1415
        gen_op_xori(uimm << 16);
1416
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1417
}
1418

    
1419
/* popcntb : PowerPC 2.03 specification */
1420
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
1421
{
1422
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1423
#if defined(TARGET_PPC64)
1424
    if (ctx->sf_mode)
1425
        gen_op_popcntb_64();
1426
    else
1427
#endif
1428
        gen_op_popcntb();
1429
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1430
}
1431

    
1432
#if defined(TARGET_PPC64)
1433
/* extsw & extsw. */
1434
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1435
/* cntlzd */
1436
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1437
#endif
1438

    
1439
/***                             Integer rotate                            ***/
1440
/* rlwimi & rlwimi. */
1441
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1442
{
1443
    target_ulong mask;
1444
    uint32_t mb, me, sh;
1445

    
1446
    mb = MB(ctx->opcode);
1447
    me = ME(ctx->opcode);
1448
    sh = SH(ctx->opcode);
1449
    if (likely(sh == 0)) {
1450
        if (likely(mb == 0 && me == 31)) {
1451
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1452
            goto do_store;
1453
        } else if (likely(mb == 31 && me == 0)) {
1454
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1455
            goto do_store;
1456
        }
1457
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1458
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1459
        goto do_mask;
1460
    }
1461
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1462
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1463
    gen_op_rotli32_T0(SH(ctx->opcode));
1464
 do_mask:
1465
#if defined(TARGET_PPC64)
1466
    mb += 32;
1467
    me += 32;
1468
#endif
1469
    mask = MASK(mb, me);
1470
    gen_op_andi_T0(mask);
1471
    gen_op_andi_T1(~mask);
1472
    gen_op_or();
1473
 do_store:
1474
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1475
    if (unlikely(Rc(ctx->opcode) != 0))
1476
        gen_set_Rc0(ctx);
1477
}
1478
/* rlwinm & rlwinm. */
1479
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1480
{
1481
    uint32_t mb, me, sh;
1482

    
1483
    sh = SH(ctx->opcode);
1484
    mb = MB(ctx->opcode);
1485
    me = ME(ctx->opcode);
1486
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1487
    if (likely(sh == 0)) {
1488
        goto do_mask;
1489
    }
1490
    if (likely(mb == 0)) {
1491
        if (likely(me == 31)) {
1492
            gen_op_rotli32_T0(sh);
1493
            goto do_store;
1494
        } else if (likely(me == (31 - sh))) {
1495
            gen_op_sli_T0(sh);
1496
            goto do_store;
1497
        }
1498
    } else if (likely(me == 31)) {
1499
        if (likely(sh == (32 - mb))) {
1500
            gen_op_srli_T0(mb);
1501
            goto do_store;
1502
        }
1503
    }
1504
    gen_op_rotli32_T0(sh);
1505
 do_mask:
1506
#if defined(TARGET_PPC64)
1507
    mb += 32;
1508
    me += 32;
1509
#endif
1510
    gen_op_andi_T0(MASK(mb, me));
1511
 do_store:
1512
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1513
    if (unlikely(Rc(ctx->opcode) != 0))
1514
        gen_set_Rc0(ctx);
1515
}
1516
/* rlwnm & rlwnm. */
1517
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1518
{
1519
    uint32_t mb, me;
1520

    
1521
    mb = MB(ctx->opcode);
1522
    me = ME(ctx->opcode);
1523
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1524
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1525
    gen_op_rotl32_T0_T1();
1526
    if (unlikely(mb != 0 || me != 31)) {
1527
#if defined(TARGET_PPC64)
1528
        mb += 32;
1529
        me += 32;
1530
#endif
1531
        gen_op_andi_T0(MASK(mb, me));
1532
    }
1533
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1534
    if (unlikely(Rc(ctx->opcode) != 0))
1535
        gen_set_Rc0(ctx);
1536
}
1537

    
1538
#if defined(TARGET_PPC64)
1539
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1540
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1541
{                                                                             \
1542
    gen_##name(ctx, 0);                                                       \
1543
}                                                                             \
1544
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1545
             PPC_64B)                                                         \
1546
{                                                                             \
1547
    gen_##name(ctx, 1);                                                       \
1548
}
1549
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1550
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1551
{                                                                             \
1552
    gen_##name(ctx, 0, 0);                                                    \
1553
}                                                                             \
1554
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
1555
             PPC_64B)                                                         \
1556
{                                                                             \
1557
    gen_##name(ctx, 0, 1);                                                    \
1558
}                                                                             \
1559
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1560
             PPC_64B)                                                         \
1561
{                                                                             \
1562
    gen_##name(ctx, 1, 0);                                                    \
1563
}                                                                             \
1564
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
1565
             PPC_64B)                                                         \
1566
{                                                                             \
1567
    gen_##name(ctx, 1, 1);                                                    \
1568
}
1569

    
1570
static always_inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1571
{
1572
    if (mask >> 32)
1573
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1574
    else
1575
        gen_op_andi_T0(mask);
1576
}
1577

    
1578
static always_inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1579
{
1580
    if (mask >> 32)
1581
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1582
    else
1583
        gen_op_andi_T1(mask);
1584
}
1585

    
1586
static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
1587
                                      uint32_t me, uint32_t sh)
1588
{
1589
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1590
    if (likely(sh == 0)) {
1591
        goto do_mask;
1592
    }
1593
    if (likely(mb == 0)) {
1594
        if (likely(me == 63)) {
1595
            gen_op_rotli64_T0(sh);
1596
            goto do_store;
1597
        } else if (likely(me == (63 - sh))) {
1598
            gen_op_sli_T0(sh);
1599
            goto do_store;
1600
        }
1601
    } else if (likely(me == 63)) {
1602
        if (likely(sh == (64 - mb))) {
1603
            gen_op_srli_T0_64(mb);
1604
            goto do_store;
1605
        }
1606
    }
1607
    gen_op_rotli64_T0(sh);
1608
 do_mask:
1609
    gen_andi_T0_64(ctx, MASK(mb, me));
1610
 do_store:
1611
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1612
    if (unlikely(Rc(ctx->opcode) != 0))
1613
        gen_set_Rc0(ctx);
1614
}
1615
/* rldicl - rldicl. */
1616
static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1617
{
1618
    uint32_t sh, mb;
1619

    
1620
    sh = SH(ctx->opcode) | (shn << 5);
1621
    mb = MB(ctx->opcode) | (mbn << 5);
1622
    gen_rldinm(ctx, mb, 63, sh);
1623
}
1624
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1625
/* rldicr - rldicr. */
1626
static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1627
{
1628
    uint32_t sh, me;
1629

    
1630
    sh = SH(ctx->opcode) | (shn << 5);
1631
    me = MB(ctx->opcode) | (men << 5);
1632
    gen_rldinm(ctx, 0, me, sh);
1633
}
1634
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1635
/* rldic - rldic. */
1636
static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1637
{
1638
    uint32_t sh, mb;
1639

    
1640
    sh = SH(ctx->opcode) | (shn << 5);
1641
    mb = MB(ctx->opcode) | (mbn << 5);
1642
    gen_rldinm(ctx, mb, 63 - sh, sh);
1643
}
1644
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1645

    
1646
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1647
                                     uint32_t me)
1648
{
1649
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1650
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1651
    gen_op_rotl64_T0_T1();
1652
    if (unlikely(mb != 0 || me != 63)) {
1653
        gen_andi_T0_64(ctx, MASK(mb, me));
1654
    }
1655
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1656
    if (unlikely(Rc(ctx->opcode) != 0))
1657
        gen_set_Rc0(ctx);
1658
}
1659

    
1660
/* rldcl - rldcl. */
1661
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1662
{
1663
    uint32_t mb;
1664

    
1665
    mb = MB(ctx->opcode) | (mbn << 5);
1666
    gen_rldnm(ctx, mb, 63);
1667
}
1668
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1669
/* rldcr - rldcr. */
1670
static always_inline void gen_rldcr (DisasContext *ctx, int men)
1671
{
1672
    uint32_t me;
1673

    
1674
    me = MB(ctx->opcode) | (men << 5);
1675
    gen_rldnm(ctx, 0, me);
1676
}
1677
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1678
/* rldimi - rldimi. */
1679
static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1680
{
1681
    uint64_t mask;
1682
    uint32_t sh, mb, me;
1683

    
1684
    sh = SH(ctx->opcode) | (shn << 5);
1685
    mb = MB(ctx->opcode) | (mbn << 5);
1686
    me = 63 - sh;
1687
    if (likely(sh == 0)) {
1688
        if (likely(mb == 0)) {
1689
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1690
            goto do_store;
1691
        }
1692
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1693
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1694
        goto do_mask;
1695
    }
1696
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1697
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1698
    gen_op_rotli64_T0(sh);
1699
 do_mask:
1700
    mask = MASK(mb, me);
1701
    gen_andi_T0_64(ctx, mask);
1702
    gen_andi_T1_64(ctx, ~mask);
1703
    gen_op_or();
1704
 do_store:
1705
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1706
    if (unlikely(Rc(ctx->opcode) != 0))
1707
        gen_set_Rc0(ctx);
1708
}
1709
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1710
#endif
1711

    
1712
/***                             Integer shift                             ***/
1713
/* slw & slw. */
1714
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1715
/* sraw & sraw. */
1716
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1717
/* srawi & srawi. */
1718
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1719
{
1720
    int mb, me;
1721
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1722
    if (SH(ctx->opcode) != 0) {
1723
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1724
        mb = 32 - SH(ctx->opcode);
1725
        me = 31;
1726
#if defined(TARGET_PPC64)
1727
        mb += 32;
1728
        me += 32;
1729
#endif
1730
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1731
    }
1732
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1733
    if (unlikely(Rc(ctx->opcode) != 0))
1734
        gen_set_Rc0(ctx);
1735
}
1736
/* srw & srw. */
1737
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1738

    
1739
#if defined(TARGET_PPC64)
1740
/* sld & sld. */
1741
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1742
/* srad & srad. */
1743
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1744
/* sradi & sradi. */
1745
static always_inline void gen_sradi (DisasContext *ctx, int n)
1746
{
1747
    uint64_t mask;
1748
    int sh, mb, me;
1749

    
1750
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1751
    sh = SH(ctx->opcode) + (n << 5);
1752
    if (sh != 0) {
1753
        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
1754
        mb = 64 - SH(ctx->opcode);
1755
        me = 63;
1756
        mask = MASK(mb, me);
1757
        gen_op_sradi(sh, mask >> 32, mask);
1758
    }
1759
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1760
    if (unlikely(Rc(ctx->opcode) != 0))
1761
        gen_set_Rc0(ctx);
1762
}
1763
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1764
{
1765
    gen_sradi(ctx, 0);
1766
}
1767
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1768
{
1769
    gen_sradi(ctx, 1);
1770
}
1771
/* srd & srd. */
1772
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1773
#endif
1774

    
1775
/***                       Floating-Point arithmetic                       ***/
1776
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1777
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1778
{                                                                             \
1779
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1780
        GEN_EXCP_NO_FP(ctx);                                                  \
1781
        return;                                                               \
1782
    }                                                                         \
1783
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1784
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1785
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1786
    gen_reset_fpstatus();                                                     \
1787
    gen_op_f##op();                                                           \
1788
    if (isfloat) {                                                            \
1789
        gen_op_frsp();                                                        \
1790
    }                                                                         \
1791
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1792
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1793
}
1794

    
1795
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1796
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1797
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1798

    
1799
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1800
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1801
{                                                                             \
1802
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1803
        GEN_EXCP_NO_FP(ctx);                                                  \
1804
        return;                                                               \
1805
    }                                                                         \
1806
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1807
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1808
    gen_reset_fpstatus();                                                     \
1809
    gen_op_f##op();                                                           \
1810
    if (isfloat) {                                                            \
1811
        gen_op_frsp();                                                        \
1812
    }                                                                         \
1813
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1814
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1815
}
1816
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
1817
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1818
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1819

    
1820
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1821
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1822
{                                                                             \
1823
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1824
        GEN_EXCP_NO_FP(ctx);                                                  \
1825
        return;                                                               \
1826
    }                                                                         \
1827
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1828
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1829
    gen_reset_fpstatus();                                                     \
1830
    gen_op_f##op();                                                           \
1831
    if (isfloat) {                                                            \
1832
        gen_op_frsp();                                                        \
1833
    }                                                                         \
1834
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1835
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1836
}
1837
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
1838
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1839
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1840

    
1841
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
1842
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1843
{                                                                             \
1844
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1845
        GEN_EXCP_NO_FP(ctx);                                                  \
1846
        return;                                                               \
1847
    }                                                                         \
1848
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1849
    gen_reset_fpstatus();                                                     \
1850
    gen_op_f##name();                                                         \
1851
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1852
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1853
}
1854

    
1855
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1856
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1857
{                                                                             \
1858
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1859
        GEN_EXCP_NO_FP(ctx);                                                  \
1860
        return;                                                               \
1861
    }                                                                         \
1862
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1863
    gen_reset_fpstatus();                                                     \
1864
    gen_op_f##name();                                                         \
1865
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1866
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1867
}
1868

    
1869
/* fadd - fadds */
1870
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1871
/* fdiv - fdivs */
1872
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1873
/* fmul - fmuls */
1874
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
1875

    
1876
/* fre */
1877
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1878

    
1879
/* fres */
1880
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1881

    
1882
/* frsqrte */
1883
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
1884

    
1885
/* frsqrtes */
1886
static always_inline void gen_op_frsqrtes (void)
1887
{
1888
    gen_op_frsqrte();
1889
    gen_op_frsp();
1890
}
1891
GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1892

    
1893
/* fsel */
1894
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1895
/* fsub - fsubs */
1896
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1897
/* Optional: */
1898
/* fsqrt */
1899
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1900
{
1901
    if (unlikely(!ctx->fpu_enabled)) {
1902
        GEN_EXCP_NO_FP(ctx);
1903
        return;
1904
    }
1905
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1906
    gen_reset_fpstatus();
1907
    gen_op_fsqrt();
1908
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1909
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1910
}
1911

    
1912
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1913
{
1914
    if (unlikely(!ctx->fpu_enabled)) {
1915
        GEN_EXCP_NO_FP(ctx);
1916
        return;
1917
    }
1918
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1919
    gen_reset_fpstatus();
1920
    gen_op_fsqrt();
1921
    gen_op_frsp();
1922
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1923
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1924
}
1925

    
1926
/***                     Floating-Point multiply-and-add                   ***/
1927
/* fmadd - fmadds */
1928
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1929
/* fmsub - fmsubs */
1930
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1931
/* fnmadd - fnmadds */
1932
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1933
/* fnmsub - fnmsubs */
1934
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1935

    
1936
/***                     Floating-Point round & convert                    ***/
1937
/* fctiw */
1938
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1939
/* fctiwz */
1940
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1941
/* frsp */
1942
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
1943
#if defined(TARGET_PPC64)
1944
/* fcfid */
1945
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
1946
/* fctid */
1947
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
1948
/* fctidz */
1949
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
1950
#endif
1951

    
1952
/* frin */
1953
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
1954
/* friz */
1955
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
1956
/* frip */
1957
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
1958
/* frim */
1959
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1960

    
1961
/***                         Floating-Point compare                        ***/
1962
/* fcmpo */
1963
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1964
{
1965
    if (unlikely(!ctx->fpu_enabled)) {
1966
        GEN_EXCP_NO_FP(ctx);
1967
        return;
1968
    }
1969
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1970
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1971
    gen_reset_fpstatus();
1972
    gen_op_fcmpo();
1973
    gen_op_store_T0_crf(crfD(ctx->opcode));
1974
    gen_op_float_check_status();
1975
}
1976

    
1977
/* fcmpu */
1978
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1979
{
1980
    if (unlikely(!ctx->fpu_enabled)) {
1981
        GEN_EXCP_NO_FP(ctx);
1982
        return;
1983
    }
1984
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1985
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1986
    gen_reset_fpstatus();
1987
    gen_op_fcmpu();
1988
    gen_op_store_T0_crf(crfD(ctx->opcode));
1989
    gen_op_float_check_status();
1990
}
1991

    
1992
/***                         Floating-point move                           ***/
1993
/* fabs */
1994
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
1995
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1996

    
1997
/* fmr  - fmr. */
1998
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1999
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
2000
{
2001
    if (unlikely(!ctx->fpu_enabled)) {
2002
        GEN_EXCP_NO_FP(ctx);
2003
        return;
2004
    }
2005
    gen_op_load_fpr_FT0(rB(ctx->opcode));
2006
    gen_op_store_FT0_fpr(rD(ctx->opcode));
2007
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2008
}
2009

    
2010
/* fnabs */
2011
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
2012
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
2013
/* fneg */
2014
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
2015
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
2016

    
2017
/***                  Floating-Point status & ctrl register                ***/
2018
/* mcrfs */
2019
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
2020
{
2021
    int bfa;
2022

    
2023
    if (unlikely(!ctx->fpu_enabled)) {
2024
        GEN_EXCP_NO_FP(ctx);
2025
        return;
2026
    }
2027
    gen_optimize_fprf();
2028
    bfa = 4 * (7 - crfS(ctx->opcode));
2029
    gen_op_load_fpscr_T0(bfa);
2030
    gen_op_store_T0_crf(crfD(ctx->opcode));
2031
    gen_op_fpscr_resetbit(~(0xF << bfa));
2032
}
2033

    
2034
/* mffs */
2035
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
2036
{
2037
    if (unlikely(!ctx->fpu_enabled)) {
2038
        GEN_EXCP_NO_FP(ctx);
2039
        return;
2040
    }
2041
    gen_optimize_fprf();
2042
    gen_reset_fpstatus();
2043
    gen_op_load_fpscr_FT0();
2044
    gen_op_store_FT0_fpr(rD(ctx->opcode));
2045
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2046
}
2047

    
2048
/* mtfsb0 */
2049
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
2050
{
2051
    uint8_t crb;
2052

    
2053
    if (unlikely(!ctx->fpu_enabled)) {
2054
        GEN_EXCP_NO_FP(ctx);
2055
        return;
2056
    }
2057
    crb = 32 - (crbD(ctx->opcode) >> 2);
2058
    gen_optimize_fprf();
2059
    gen_reset_fpstatus();
2060
    if (likely(crb != 30 && crb != 29))
2061
        gen_op_fpscr_resetbit(~(1 << crb));
2062
    if (unlikely(Rc(ctx->opcode) != 0)) {
2063
        gen_op_load_fpcc();
2064
        gen_op_set_Rc0();
2065
    }
2066
}
2067

    
2068
/* mtfsb1 */
2069
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2070
{
2071
    uint8_t crb;
2072

    
2073
    if (unlikely(!ctx->fpu_enabled)) {
2074
        GEN_EXCP_NO_FP(ctx);
2075
        return;
2076
    }
2077
    crb = 32 - (crbD(ctx->opcode) >> 2);
2078
    gen_optimize_fprf();
2079
    gen_reset_fpstatus();
2080
    /* XXX: we pretend we can only do IEEE floating-point computations */
2081
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
2082
        gen_op_fpscr_setbit(crb);
2083
    if (unlikely(Rc(ctx->opcode) != 0)) {
2084
        gen_op_load_fpcc();
2085
        gen_op_set_Rc0();
2086
    }
2087
    /* We can raise a differed exception */
2088
    gen_op_float_check_status();
2089
}
2090

    
2091
/* mtfsf */
2092
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2093
{
2094
    if (unlikely(!ctx->fpu_enabled)) {
2095
        GEN_EXCP_NO_FP(ctx);
2096
        return;
2097
    }
2098
    gen_optimize_fprf();
2099
    gen_op_load_fpr_FT0(rB(ctx->opcode));
2100
    gen_reset_fpstatus();
2101
    gen_op_store_fpscr(FM(ctx->opcode));
2102
    if (unlikely(Rc(ctx->opcode) != 0)) {
2103
        gen_op_load_fpcc();
2104
        gen_op_set_Rc0();
2105
    }
2106
    /* We can raise a differed exception */
2107
    gen_op_float_check_status();
2108
}
2109

    
2110
/* mtfsfi */
2111
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2112
{
2113
    int bf, sh;
2114

    
2115
    if (unlikely(!ctx->fpu_enabled)) {
2116
        GEN_EXCP_NO_FP(ctx);
2117
        return;
2118
    }
2119
    bf = crbD(ctx->opcode) >> 2;
2120
    sh = 7 - bf;
2121
    gen_optimize_fprf();
2122
    gen_op_set_FT0(FPIMM(ctx->opcode) << (4 * sh));
2123
    gen_reset_fpstatus();
2124
    gen_op_store_fpscr(1 << sh);
2125
    if (unlikely(Rc(ctx->opcode) != 0)) {
2126
        gen_op_load_fpcc();
2127
        gen_op_set_Rc0();
2128
    }
2129
    /* We can raise a differed exception */
2130
    gen_op_float_check_status();
2131
}
2132

    
2133
/***                           Addressing modes                            ***/
2134
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2135
static always_inline void gen_addr_imm_index (DisasContext *ctx,
2136
                                              target_long maskl)
2137
{
2138
    target_long simm = SIMM(ctx->opcode);
2139

    
2140
    simm &= ~maskl;
2141
    if (rA(ctx->opcode) == 0) {
2142
        tcg_gen_movi_tl(cpu_T[0], simm);
2143
    } else {
2144
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
2145
        if (likely(simm != 0))
2146
            gen_op_addi(simm);
2147
    }
2148
#ifdef DEBUG_MEMORY_ACCESSES
2149
    gen_op_print_mem_EA();
2150
#endif
2151
}
2152

    
2153
static always_inline void gen_addr_reg_index (DisasContext *ctx)
2154
{
2155
    if (rA(ctx->opcode) == 0) {
2156
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
2157
    } else {
2158
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
2159
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
2160
        gen_op_add();
2161
    }
2162
#ifdef DEBUG_MEMORY_ACCESSES
2163
    gen_op_print_mem_EA();
2164
#endif
2165
}
2166

    
2167
static always_inline void gen_addr_register (DisasContext *ctx)
2168
{
2169
    if (rA(ctx->opcode) == 0) {
2170
        tcg_gen_movi_tl(cpu_T[0], 0);
2171
    } else {
2172
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
2173
    }
2174
#ifdef DEBUG_MEMORY_ACCESSES
2175
    gen_op_print_mem_EA();
2176
#endif
2177
}
2178

    
2179
#if defined(TARGET_PPC64)
2180
#define _GEN_MEM_FUNCS(name, mode)                                            \
2181
    &gen_op_##name##_##mode,                                                  \
2182
    &gen_op_##name##_le_##mode,                                               \
2183
    &gen_op_##name##_64_##mode,                                               \
2184
    &gen_op_##name##_le_64_##mode
2185
#else
2186
#define _GEN_MEM_FUNCS(name, mode)                                            \
2187
    &gen_op_##name##_##mode,                                                  \
2188
    &gen_op_##name##_le_##mode
2189
#endif
2190
#if defined(CONFIG_USER_ONLY)
2191
#if defined(TARGET_PPC64)
2192
#define NB_MEM_FUNCS 4
2193
#else
2194
#define NB_MEM_FUNCS 2
2195
#endif
2196
#define GEN_MEM_FUNCS(name)                                                   \
2197
    _GEN_MEM_FUNCS(name, raw)
2198
#else
2199
#if defined(TARGET_PPC64)
2200
#define NB_MEM_FUNCS 12
2201
#else
2202
#define NB_MEM_FUNCS 6
2203
#endif
2204
#define GEN_MEM_FUNCS(name)                                                   \
2205
    _GEN_MEM_FUNCS(name, user),                                               \
2206
    _GEN_MEM_FUNCS(name, kernel),                                             \
2207
    _GEN_MEM_FUNCS(name, hypv)
2208
#endif
2209

    
2210
/***                             Integer load                              ***/
2211
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
2212
/* Byte access routine are endian safe */
2213
#define gen_op_lbz_le_raw       gen_op_lbz_raw
2214
#define gen_op_lbz_le_user      gen_op_lbz_user
2215
#define gen_op_lbz_le_kernel    gen_op_lbz_kernel
2216
#define gen_op_lbz_le_hypv      gen_op_lbz_hypv
2217
#define gen_op_lbz_le_64_raw    gen_op_lbz_64_raw
2218
#define gen_op_lbz_le_64_user   gen_op_lbz_64_user
2219
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
2220
#define gen_op_lbz_le_64_hypv   gen_op_lbz_64_hypv
2221
#define gen_op_stb_le_raw       gen_op_stb_raw
2222
#define gen_op_stb_le_user      gen_op_stb_user
2223
#define gen_op_stb_le_kernel    gen_op_stb_kernel
2224
#define gen_op_stb_le_hypv      gen_op_stb_hypv
2225
#define gen_op_stb_le_64_raw    gen_op_stb_64_raw
2226
#define gen_op_stb_le_64_user   gen_op_stb_64_user
2227
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
2228
#define gen_op_stb_le_64_hypv   gen_op_stb_64_hypv
2229
#define OP_LD_TABLE(width)                                                    \
2230
static GenOpFunc *gen_op_l##width[NB_MEM_FUNCS] = {                           \
2231
    GEN_MEM_FUNCS(l##width),                                                  \
2232
};
2233
#define OP_ST_TABLE(width)                                                    \
2234
static GenOpFunc *gen_op_st##width[NB_MEM_FUNCS] = {                          \
2235
    GEN_MEM_FUNCS(st##width),                                                 \
2236
};
2237

    
2238
#define GEN_LD(width, opc, type)                                              \
2239
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2240
{                                                                             \
2241
    gen_addr_imm_index(ctx, 0);                                               \
2242
    op_ldst(l##width);                                                        \
2243
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2244
}
2245

    
2246
#define GEN_LDU(width, opc, type)                                             \
2247
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, 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
    if (type == PPC_64B)                                                      \
2255
        gen_addr_imm_index(ctx, 0x03);                                        \
2256
    else                                                                      \
2257
        gen_addr_imm_index(ctx, 0);                                           \
2258
    op_ldst(l##width);                                                        \
2259
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2260
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2261
}
2262

    
2263
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2264
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2265
{                                                                             \
2266
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2267
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2268
        GEN_EXCP_INVAL(ctx);                                                  \
2269
        return;                                                               \
2270
    }                                                                         \
2271
    gen_addr_reg_index(ctx);                                                  \
2272
    op_ldst(l##width);                                                        \
2273
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2274
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2275
}
2276

    
2277
#define GEN_LDX(width, opc2, opc3, type)                                      \
2278
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2279
{                                                                             \
2280
    gen_addr_reg_index(ctx);                                                  \
2281
    op_ldst(l##width);                                                        \
2282
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2283
}
2284

    
2285
#define GEN_LDS(width, op, type)                                              \
2286
OP_LD_TABLE(width);                                                           \
2287
GEN_LD(width, op | 0x20, type);                                               \
2288
GEN_LDU(width, op | 0x21, type);                                              \
2289
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2290
GEN_LDX(width, 0x17, op | 0x00, type)
2291

    
2292
/* lbz lbzu lbzux lbzx */
2293
GEN_LDS(bz, 0x02, PPC_INTEGER);
2294
/* lha lhau lhaux lhax */
2295
GEN_LDS(ha, 0x0A, PPC_INTEGER);
2296
/* lhz lhzu lhzux lhzx */
2297
GEN_LDS(hz, 0x08, PPC_INTEGER);
2298
/* lwz lwzu lwzux lwzx */
2299
GEN_LDS(wz, 0x00, PPC_INTEGER);
2300
#if defined(TARGET_PPC64)
2301
OP_LD_TABLE(wa);
2302
OP_LD_TABLE(d);
2303
/* lwaux */
2304
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
2305
/* lwax */
2306
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
2307
/* ldux */
2308
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
2309
/* ldx */
2310
GEN_LDX(d, 0x15, 0x00, PPC_64B);
2311
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2312
{
2313
    if (Rc(ctx->opcode)) {
2314
        if (unlikely(rA(ctx->opcode) == 0 ||
2315
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2316
            GEN_EXCP_INVAL(ctx);
2317
            return;
2318
        }
2319
    }
2320
    gen_addr_imm_index(ctx, 0x03);
2321
    if (ctx->opcode & 0x02) {
2322
        /* lwa (lwau is undefined) */
2323
        op_ldst(lwa);
2324
    } else {
2325
        /* ld - ldu */
2326
        op_ldst(ld);
2327
    }
2328
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
2329
    if (Rc(ctx->opcode))
2330
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
2331
}
2332
/* lq */
2333
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2334
{
2335
#if defined(CONFIG_USER_ONLY)
2336
    GEN_EXCP_PRIVOPC(ctx);
2337
#else
2338
    int ra, rd;
2339

    
2340
    /* Restore CPU state */
2341
    if (unlikely(ctx->supervisor == 0)) {
2342
        GEN_EXCP_PRIVOPC(ctx);
2343
        return;
2344
    }
2345
    ra = rA(ctx->opcode);
2346
    rd = rD(ctx->opcode);
2347
    if (unlikely((rd & 1) || rd == ra)) {
2348
        GEN_EXCP_INVAL(ctx);
2349
        return;
2350
    }
2351
    if (unlikely(ctx->mem_idx & 1)) {
2352
        /* Little-endian mode is not handled */
2353
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2354
        return;
2355
    }
2356
    gen_addr_imm_index(ctx, 0x0F);
2357
    op_ldst(ld);
2358
    tcg_gen_mov_tl(cpu_gpr[rd], cpu_T[1]);
2359
    gen_op_addi(8);
2360
    op_ldst(ld);
2361
    tcg_gen_mov_tl(cpu_gpr[rd + 1], cpu_T[1]);
2362
#endif
2363
}
2364
#endif
2365

    
2366
/***                              Integer store                            ***/
2367
#define GEN_ST(width, opc, type)                                              \
2368
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2369
{                                                                             \
2370
    gen_addr_imm_index(ctx, 0);                                               \
2371
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2372
    op_ldst(st##width);                                                       \
2373
}
2374

    
2375
#define GEN_STU(width, opc, type)                                             \
2376
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2377
{                                                                             \
2378
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2379
        GEN_EXCP_INVAL(ctx);                                                  \
2380
        return;                                                               \
2381
    }                                                                         \
2382
    if (type == PPC_64B)                                                      \
2383
        gen_addr_imm_index(ctx, 0x03);                                        \
2384
    else                                                                      \
2385
        gen_addr_imm_index(ctx, 0);                                           \
2386
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2387
    op_ldst(st##width);                                                       \
2388
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2389
}
2390

    
2391
#define GEN_STUX(width, opc2, opc3, type)                                     \
2392
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2393
{                                                                             \
2394
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2395
        GEN_EXCP_INVAL(ctx);                                                  \
2396
        return;                                                               \
2397
    }                                                                         \
2398
    gen_addr_reg_index(ctx);                                                  \
2399
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2400
    op_ldst(st##width);                                                       \
2401
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2402
}
2403

    
2404
#define GEN_STX(width, opc2, opc3, type)                                      \
2405
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2406
{                                                                             \
2407
    gen_addr_reg_index(ctx);                                                  \
2408
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2409
    op_ldst(st##width);                                                       \
2410
}
2411

    
2412
#define GEN_STS(width, op, type)                                              \
2413
OP_ST_TABLE(width);                                                           \
2414
GEN_ST(width, op | 0x20, type);                                               \
2415
GEN_STU(width, op | 0x21, type);                                              \
2416
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2417
GEN_STX(width, 0x17, op | 0x00, type)
2418

    
2419
/* stb stbu stbux stbx */
2420
GEN_STS(b, 0x06, PPC_INTEGER);
2421
/* sth sthu sthux sthx */
2422
GEN_STS(h, 0x0C, PPC_INTEGER);
2423
/* stw stwu stwux stwx */
2424
GEN_STS(w, 0x04, PPC_INTEGER);
2425
#if defined(TARGET_PPC64)
2426
OP_ST_TABLE(d);
2427
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2428
GEN_STX(d, 0x15, 0x04, PPC_64B);
2429
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2430
{
2431
    int rs;
2432

    
2433
    rs = rS(ctx->opcode);
2434
    if ((ctx->opcode & 0x3) == 0x2) {
2435
#if defined(CONFIG_USER_ONLY)
2436
        GEN_EXCP_PRIVOPC(ctx);
2437
#else
2438
        /* stq */
2439
        if (unlikely(ctx->supervisor == 0)) {
2440
            GEN_EXCP_PRIVOPC(ctx);
2441
            return;
2442
        }
2443
        if (unlikely(rs & 1)) {
2444
            GEN_EXCP_INVAL(ctx);
2445
            return;
2446
        }
2447
        if (unlikely(ctx->mem_idx & 1)) {
2448
            /* Little-endian mode is not handled */
2449
            GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2450
            return;
2451
        }
2452
        gen_addr_imm_index(ctx, 0x03);
2453
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rs]);
2454
        op_ldst(std);
2455
        gen_op_addi(8);
2456
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rs + 1]);
2457
        op_ldst(std);
2458
#endif
2459
    } else {
2460
        /* std / stdu */
2461
        if (Rc(ctx->opcode)) {
2462
            if (unlikely(rA(ctx->opcode) == 0)) {
2463
                GEN_EXCP_INVAL(ctx);
2464
                return;
2465
            }
2466
        }
2467
        gen_addr_imm_index(ctx, 0x03);
2468
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rs]);
2469
        op_ldst(std);
2470
        if (Rc(ctx->opcode))
2471
            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
2472
    }
2473
}
2474
#endif
2475
/***                Integer load and store with byte reverse               ***/
2476
/* lhbrx */
2477
OP_LD_TABLE(hbr);
2478
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2479
/* lwbrx */
2480
OP_LD_TABLE(wbr);
2481
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2482
/* sthbrx */
2483
OP_ST_TABLE(hbr);
2484
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2485
/* stwbrx */
2486
OP_ST_TABLE(wbr);
2487
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2488

    
2489
/***                    Integer load and store multiple                    ***/
2490
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2491
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
2492
    GEN_MEM_FUNCS(lmw),
2493
};
2494
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
2495
    GEN_MEM_FUNCS(stmw),
2496
};
2497

    
2498
/* lmw */
2499
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2500
{
2501
    /* NIP cannot be restored if the memory exception comes from an helper */
2502
    gen_update_nip(ctx, ctx->nip - 4);
2503
    gen_addr_imm_index(ctx, 0);
2504
    op_ldstm(lmw, rD(ctx->opcode));
2505
}
2506

    
2507
/* stmw */
2508
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2509
{
2510
    /* NIP cannot be restored if the memory exception comes from an helper */
2511
    gen_update_nip(ctx, ctx->nip - 4);
2512
    gen_addr_imm_index(ctx, 0);
2513
    op_ldstm(stmw, rS(ctx->opcode));
2514
}
2515

    
2516
/***                    Integer load and store strings                     ***/
2517
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2518
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2519
/* string load & stores are by definition endian-safe */
2520
#define gen_op_lswi_le_raw       gen_op_lswi_raw
2521
#define gen_op_lswi_le_user      gen_op_lswi_user
2522
#define gen_op_lswi_le_kernel    gen_op_lswi_kernel
2523
#define gen_op_lswi_le_hypv      gen_op_lswi_hypv
2524
#define gen_op_lswi_le_64_raw    gen_op_lswi_raw
2525
#define gen_op_lswi_le_64_user   gen_op_lswi_user
2526
#define gen_op_lswi_le_64_kernel gen_op_lswi_kernel
2527
#define gen_op_lswi_le_64_hypv   gen_op_lswi_hypv
2528
static GenOpFunc1 *gen_op_lswi[NB_MEM_FUNCS] = {
2529
    GEN_MEM_FUNCS(lswi),
2530
};
2531
#define gen_op_lswx_le_raw       gen_op_lswx_raw
2532
#define gen_op_lswx_le_user      gen_op_lswx_user
2533
#define gen_op_lswx_le_kernel    gen_op_lswx_kernel
2534
#define gen_op_lswx_le_hypv      gen_op_lswx_hypv
2535
#define gen_op_lswx_le_64_raw    gen_op_lswx_raw
2536
#define gen_op_lswx_le_64_user   gen_op_lswx_user
2537
#define gen_op_lswx_le_64_kernel gen_op_lswx_kernel
2538
#define gen_op_lswx_le_64_hypv   gen_op_lswx_hypv
2539
static GenOpFunc3 *gen_op_lswx[NB_MEM_FUNCS] = {
2540
    GEN_MEM_FUNCS(lswx),
2541
};
2542
#define gen_op_stsw_le_raw       gen_op_stsw_raw
2543
#define gen_op_stsw_le_user      gen_op_stsw_user
2544
#define gen_op_stsw_le_kernel    gen_op_stsw_kernel
2545
#define gen_op_stsw_le_hypv      gen_op_stsw_hypv
2546
#define gen_op_stsw_le_64_raw    gen_op_stsw_raw
2547
#define gen_op_stsw_le_64_user   gen_op_stsw_user
2548
#define gen_op_stsw_le_64_kernel gen_op_stsw_kernel
2549
#define gen_op_stsw_le_64_hypv   gen_op_stsw_hypv
2550
static GenOpFunc1 *gen_op_stsw[NB_MEM_FUNCS] = {
2551
    GEN_MEM_FUNCS(stsw),
2552
};
2553

    
2554
/* lswi */
2555
/* PowerPC32 specification says we must generate an exception if
2556
 * rA is in the range of registers to be loaded.
2557
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2558
 * For now, I'll follow the spec...
2559
 */
2560
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
2561
{
2562
    int nb = NB(ctx->opcode);
2563
    int start = rD(ctx->opcode);
2564
    int ra = rA(ctx->opcode);
2565
    int nr;
2566

    
2567
    if (nb == 0)
2568
        nb = 32;
2569
    nr = nb / 4;
2570
    if (unlikely(((start + nr) > 32  &&
2571
                  start <= ra && (start + nr - 32) > ra) ||
2572
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2573
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
2574
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
2575
        return;
2576
    }
2577
    /* NIP cannot be restored if the memory exception comes from an helper */
2578
    gen_update_nip(ctx, ctx->nip - 4);
2579
    gen_addr_register(ctx);
2580
    tcg_gen_movi_tl(cpu_T[1], nb);
2581
    op_ldsts(lswi, start);
2582
}
2583

    
2584
/* lswx */
2585
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
2586
{
2587
    int ra = rA(ctx->opcode);
2588
    int rb = rB(ctx->opcode);
2589

    
2590
    /* NIP cannot be restored if the memory exception comes from an helper */
2591
    gen_update_nip(ctx, ctx->nip - 4);
2592
    gen_addr_reg_index(ctx);
2593
    if (ra == 0) {
2594
        ra = rb;
2595
    }
2596
    gen_op_load_xer_bc();
2597
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2598
}
2599

    
2600
/* stswi */
2601
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
2602
{
2603
    int nb = NB(ctx->opcode);
2604

    
2605
    /* NIP cannot be restored if the memory exception comes from an helper */
2606
    gen_update_nip(ctx, ctx->nip - 4);
2607
    gen_addr_register(ctx);
2608
    if (nb == 0)
2609
        nb = 32;
2610
    tcg_gen_movi_tl(cpu_T[1], nb);
2611
    op_ldsts(stsw, rS(ctx->opcode));
2612
}
2613

    
2614
/* stswx */
2615
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
2616
{
2617
    /* NIP cannot be restored if the memory exception comes from an helper */
2618
    gen_update_nip(ctx, ctx->nip - 4);
2619
    gen_addr_reg_index(ctx);
2620
    gen_op_load_xer_bc();
2621
    op_ldsts(stsw, rS(ctx->opcode));
2622
}
2623

    
2624
/***                        Memory synchronisation                         ***/
2625
/* eieio */
2626
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2627
{
2628
}
2629

    
2630
/* isync */
2631
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2632
{
2633
    GEN_STOP(ctx);
2634
}
2635

    
2636
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2637
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2638
static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
2639
    GEN_MEM_FUNCS(lwarx),
2640
};
2641
static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
2642
    GEN_MEM_FUNCS(stwcx),
2643
};
2644

    
2645
/* lwarx */
2646
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2647
{
2648
    /* NIP cannot be restored if the memory exception comes from an helper */
2649
    gen_update_nip(ctx, ctx->nip - 4);
2650
    gen_addr_reg_index(ctx);
2651
    op_lwarx();
2652
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
2653
}
2654

    
2655
/* stwcx. */
2656
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2657
{
2658
    /* NIP cannot be restored if the memory exception comes from an helper */
2659
    gen_update_nip(ctx, ctx->nip - 4);
2660
    gen_addr_reg_index(ctx);
2661
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
2662
    op_stwcx();
2663
}
2664

    
2665
#if defined(TARGET_PPC64)
2666
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2667
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2668
static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
2669
    GEN_MEM_FUNCS(ldarx),
2670
};
2671
static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
2672
    GEN_MEM_FUNCS(stdcx),
2673
};
2674

    
2675
/* ldarx */
2676
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2677
{
2678
    /* NIP cannot be restored if the memory exception comes from an helper */
2679
    gen_update_nip(ctx, ctx->nip - 4);
2680
    gen_addr_reg_index(ctx);
2681
    op_ldarx();
2682
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
2683
}
2684

    
2685
/* stdcx. */
2686
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2687
{
2688
    /* NIP cannot be restored if the memory exception comes from an helper */
2689
    gen_update_nip(ctx, ctx->nip - 4);
2690
    gen_addr_reg_index(ctx);
2691
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
2692
    op_stdcx();
2693
}
2694
#endif /* defined(TARGET_PPC64) */
2695

    
2696
/* sync */
2697
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
2698
{
2699
}
2700

    
2701
/* wait */
2702
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2703
{
2704
    /* Stop translation, as the CPU is supposed to sleep from now */
2705
    gen_op_wait();
2706
    GEN_EXCP(ctx, EXCP_HLT, 1);
2707
}
2708

    
2709
/***                         Floating-point load                           ***/
2710
#define GEN_LDF(width, opc, type)                                             \
2711
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2712
{                                                                             \
2713
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2714
        GEN_EXCP_NO_FP(ctx);                                                  \
2715
        return;                                                               \
2716
    }                                                                         \
2717
    gen_addr_imm_index(ctx, 0);                                               \
2718
    op_ldst(l##width);                                                        \
2719
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2720
}
2721

    
2722
#define GEN_LDUF(width, opc, type)                                            \
2723
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, 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_imm_index(ctx, 0);                                               \
2734
    op_ldst(l##width);                                                        \
2735
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2736
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2737
}
2738

    
2739
#define GEN_LDUXF(width, opc, type)                                           \
2740
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
2741
{                                                                             \
2742
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2743
        GEN_EXCP_NO_FP(ctx);                                                  \
2744
        return;                                                               \
2745
    }                                                                         \
2746
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2747
        GEN_EXCP_INVAL(ctx);                                                  \
2748
        return;                                                               \
2749
    }                                                                         \
2750
    gen_addr_reg_index(ctx);                                                  \
2751
    op_ldst(l##width);                                                        \
2752
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2753
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2754
}
2755

    
2756
#define GEN_LDXF(width, opc2, opc3, type)                                     \
2757
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2758
{                                                                             \
2759
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2760
        GEN_EXCP_NO_FP(ctx);                                                  \
2761
        return;                                                               \
2762
    }                                                                         \
2763
    gen_addr_reg_index(ctx);                                                  \
2764
    op_ldst(l##width);                                                        \
2765
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2766
}
2767

    
2768
#define GEN_LDFS(width, op, type)                                             \
2769
OP_LD_TABLE(width);                                                           \
2770
GEN_LDF(width, op | 0x20, type);                                              \
2771
GEN_LDUF(width, op | 0x21, type);                                             \
2772
GEN_LDUXF(width, op | 0x01, type);                                            \
2773
GEN_LDXF(width, 0x17, op | 0x00, type)
2774

    
2775
/* lfd lfdu lfdux lfdx */
2776
GEN_LDFS(fd, 0x12, PPC_FLOAT);
2777
/* lfs lfsu lfsux lfsx */
2778
GEN_LDFS(fs, 0x10, PPC_FLOAT);
2779

    
2780
/***                         Floating-point store                          ***/
2781
#define GEN_STF(width, opc, type)                                             \
2782
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2783
{                                                                             \
2784
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2785
        GEN_EXCP_NO_FP(ctx);                                                  \
2786
        return;                                                               \
2787
    }                                                                         \
2788
    gen_addr_imm_index(ctx, 0);                                               \
2789
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2790
    op_ldst(st##width);                                                       \
2791
}
2792

    
2793
#define GEN_STUF(width, opc, type)                                            \
2794
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, 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_imm_index(ctx, 0);                                               \
2805
    gen_op_load_fpr_FT0(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_STUXF(width, opc, type)                                           \
2811
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
2812
{                                                                             \
2813
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2814
        GEN_EXCP_NO_FP(ctx);                                                  \
2815
        return;                                                               \
2816
    }                                                                         \
2817
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2818
        GEN_EXCP_INVAL(ctx);                                                  \
2819
        return;                                                               \
2820
    }                                                                         \
2821
    gen_addr_reg_index(ctx);                                                  \
2822
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2823
    op_ldst(st##width);                                                       \
2824
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2825
}
2826

    
2827
#define GEN_STXF(width, opc2, opc3, type)                                     \
2828
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2829
{                                                                             \
2830
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2831
        GEN_EXCP_NO_FP(ctx);                                                  \
2832
        return;                                                               \
2833
    }                                                                         \
2834
    gen_addr_reg_index(ctx);                                                  \
2835
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2836
    op_ldst(st##width);                                                       \
2837
}
2838

    
2839
#define GEN_STFS(width, op, type)                                             \
2840
OP_ST_TABLE(width);                                                           \
2841
GEN_STF(width, op | 0x20, type);                                              \
2842
GEN_STUF(width, op | 0x21, type);                                             \
2843
GEN_STUXF(width, op | 0x01, type);                                            \
2844
GEN_STXF(width, 0x17, op | 0x00, type)
2845

    
2846
/* stfd stfdu stfdux stfdx */
2847
GEN_STFS(fd, 0x16, PPC_FLOAT);
2848
/* stfs stfsu stfsux stfsx */
2849
GEN_STFS(fs, 0x14, PPC_FLOAT);
2850

    
2851
/* Optional: */
2852
/* stfiwx */
2853
OP_ST_TABLE(fiw);
2854
GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2855

    
2856
/***                                Branch                                 ***/
2857
static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2858
                                       target_ulong dest)
2859
{
2860
    TranslationBlock *tb;
2861
    tb = ctx->tb;
2862
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2863
        likely(!ctx->singlestep_enabled)) {
2864
        tcg_gen_goto_tb(n);
2865
        tcg_gen_movi_tl(cpu_T[1], dest);
2866
#if defined(TARGET_PPC64)
2867
        if (ctx->sf_mode)
2868
            gen_op_b_T1_64();
2869
        else
2870
#endif
2871
            gen_op_b_T1();
2872
        tcg_gen_exit_tb((long)tb + n);
2873
    } else {
2874
        tcg_gen_movi_tl(cpu_T[1], dest);
2875
#if defined(TARGET_PPC64)
2876
        if (ctx->sf_mode)
2877
            gen_op_b_T1_64();
2878
        else
2879
#endif
2880
            gen_op_b_T1();
2881
        if (unlikely(ctx->singlestep_enabled)) {
2882
            if ((ctx->singlestep_enabled &
2883
                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
2884
                ctx->exception == POWERPC_EXCP_BRANCH) {
2885
                target_ulong tmp = ctx->nip;
2886
                ctx->nip = dest;
2887
                GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
2888
                ctx->nip = tmp;
2889
            }
2890
            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
2891
                gen_update_nip(ctx, dest);
2892
                gen_op_debug();
2893
            }
2894
        }
2895
        tcg_gen_exit_tb(0);
2896
    }
2897
}
2898

    
2899
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2900
{
2901
#if defined(TARGET_PPC64)
2902
    if (ctx->sf_mode != 0 && (nip >> 32))
2903
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2904
    else
2905
#endif
2906
        gen_op_setlr(ctx->nip);
2907
}
2908

    
2909
/* b ba bl bla */
2910
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2911
{
2912
    target_ulong li, target;
2913

    
2914
    ctx->exception = POWERPC_EXCP_BRANCH;
2915
    /* sign extend LI */
2916
#if defined(TARGET_PPC64)
2917
    if (ctx->sf_mode)
2918
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2919
    else
2920
#endif
2921
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2922
    if (likely(AA(ctx->opcode) == 0))
2923
        target = ctx->nip + li - 4;
2924
    else
2925
        target = li;
2926
#if defined(TARGET_PPC64)
2927
    if (!ctx->sf_mode)
2928
        target = (uint32_t)target;
2929
#endif
2930
    if (LK(ctx->opcode))
2931
        gen_setlr(ctx, ctx->nip);
2932
    gen_goto_tb(ctx, 0, target);
2933
}
2934

    
2935
#define BCOND_IM  0
2936
#define BCOND_LR  1
2937
#define BCOND_CTR 2
2938

    
2939
static always_inline void gen_bcond (DisasContext *ctx, int type)
2940
{
2941
    target_ulong target = 0;
2942
    target_ulong li;
2943
    uint32_t bo = BO(ctx->opcode);
2944
    uint32_t bi = BI(ctx->opcode);
2945
    uint32_t mask;
2946

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

    
3084
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3085
{
3086
    gen_bcond(ctx, BCOND_IM);
3087
}
3088

    
3089
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3090
{
3091
    gen_bcond(ctx, BCOND_CTR);
3092
}
3093

    
3094
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3095
{
3096
    gen_bcond(ctx, BCOND_LR);
3097
}
3098

    
3099
/***                      Condition register logical                       ***/
3100
#define GEN_CRLOGIC(op, opc)                                                  \
3101
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
3102
{                                                                             \
3103
    uint8_t bitmask;                                                          \
3104
    int sh;                                                                   \
3105
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
3106
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3107
    if (sh > 0)                                                               \
3108
        gen_op_srli_T0(sh);                                                   \
3109
    else if (sh < 0)                                                          \
3110
        gen_op_sli_T0(-sh);                                                   \
3111
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
3112
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3113
    if (sh > 0)                                                               \
3114
        gen_op_srli_T1(sh);                                                   \
3115
    else if (sh < 0)                                                          \
3116
        gen_op_sli_T1(-sh);                                                   \
3117
    gen_op_##op();                                                            \
3118
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3119
    gen_op_andi_T0(bitmask);                                                  \
3120
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
3121
    gen_op_andi_T1(~bitmask);                                                 \
3122
    gen_op_or();                                                              \
3123
    gen_op_store_T0_crf(crbD(ctx->opcode) >> 2);                              \
3124
}
3125

    
3126
/* crand */
3127
GEN_CRLOGIC(and, 0x08);
3128
/* crandc */
3129
GEN_CRLOGIC(andc, 0x04);
3130
/* creqv */
3131
GEN_CRLOGIC(eqv, 0x09);
3132
/* crnand */
3133
GEN_CRLOGIC(nand, 0x07);
3134
/* crnor */
3135
GEN_CRLOGIC(nor, 0x01);
3136
/* cror */
3137
GEN_CRLOGIC(or, 0x0E);
3138
/* crorc */
3139
GEN_CRLOGIC(orc, 0x0D);
3140
/* crxor */
3141
GEN_CRLOGIC(xor, 0x06);
3142
/* mcrf */
3143
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3144
{
3145
    gen_op_load_crf_T0(crfS(ctx->opcode));
3146
    gen_op_store_T0_crf(crfD(ctx->opcode));
3147
}
3148

    
3149
/***                           System linkage                              ***/
3150
/* rfi (supervisor only) */
3151
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3152
{
3153
#if defined(CONFIG_USER_ONLY)
3154
    GEN_EXCP_PRIVOPC(ctx);
3155
#else
3156
    /* Restore CPU state */
3157
    if (unlikely(!ctx->supervisor)) {
3158
        GEN_EXCP_PRIVOPC(ctx);
3159
        return;
3160
    }
3161
    gen_op_rfi();
3162
    GEN_SYNC(ctx);
3163
#endif
3164
}
3165

    
3166
#if defined(TARGET_PPC64)
3167
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3168
{
3169
#if defined(CONFIG_USER_ONLY)
3170
    GEN_EXCP_PRIVOPC(ctx);
3171
#else
3172
    /* Restore CPU state */
3173
    if (unlikely(!ctx->supervisor)) {
3174
        GEN_EXCP_PRIVOPC(ctx);
3175
        return;
3176
    }
3177
    gen_op_rfid();
3178
    GEN_SYNC(ctx);
3179
#endif
3180
}
3181

    
3182
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3183
{
3184
#if defined(CONFIG_USER_ONLY)
3185
    GEN_EXCP_PRIVOPC(ctx);
3186
#else
3187
    /* Restore CPU state */
3188
    if (unlikely(ctx->supervisor <= 1)) {
3189
        GEN_EXCP_PRIVOPC(ctx);
3190
        return;
3191
    }
3192
    gen_op_hrfid();
3193
    GEN_SYNC(ctx);
3194
#endif
3195
}
3196
#endif
3197

    
3198
/* sc */
3199
#if defined(CONFIG_USER_ONLY)
3200
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3201
#else
3202
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3203
#endif
3204
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3205
{
3206
    uint32_t lev;
3207

    
3208
    lev = (ctx->opcode >> 5) & 0x7F;
3209
    GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
3210
}
3211

    
3212
/***                                Trap                                   ***/
3213
/* tw */
3214
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3215
{
3216
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3217
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3218
    /* Update the nip since this might generate a trap exception */
3219
    gen_update_nip(ctx, ctx->nip);
3220
    gen_op_tw(TO(ctx->opcode));
3221
}
3222

    
3223
/* twi */
3224
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3225
{
3226
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3227
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3228
    /* Update the nip since this might generate a trap exception */
3229
    gen_update_nip(ctx, ctx->nip);
3230
    gen_op_tw(TO(ctx->opcode));
3231
}
3232

    
3233
#if defined(TARGET_PPC64)
3234
/* td */
3235
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3236
{
3237
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3238
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3239
    /* Update the nip since this might generate a trap exception */
3240
    gen_update_nip(ctx, ctx->nip);
3241
    gen_op_td(TO(ctx->opcode));
3242
}
3243

    
3244
/* tdi */
3245
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3246
{
3247
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3248
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3249
    /* Update the nip since this might generate a trap exception */
3250
    gen_update_nip(ctx, ctx->nip);
3251
    gen_op_td(TO(ctx->opcode));
3252
}
3253
#endif
3254

    
3255
/***                          Processor control                            ***/
3256
/* mcrxr */
3257
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3258
{
3259
    gen_op_load_xer_cr();
3260
    gen_op_store_T0_crf(crfD(ctx->opcode));
3261
    gen_op_clear_xer_ov();
3262
    gen_op_clear_xer_ca();
3263
}
3264

    
3265
/* mfcr */
3266
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3267
{
3268
    uint32_t crm, crn;
3269

    
3270
    if (likely(ctx->opcode & 0x00100000)) {
3271
        crm = CRM(ctx->opcode);
3272
        if (likely((crm ^ (crm - 1)) == 0)) {
3273
            crn = ffs(crm);
3274
            gen_op_load_cro(7 - crn);
3275
        }
3276
    } else {
3277
        gen_op_load_cr();
3278
    }
3279
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3280
}
3281

    
3282
/* mfmsr */
3283
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3284
{
3285
#if defined(CONFIG_USER_ONLY)
3286
    GEN_EXCP_PRIVREG(ctx);
3287
#else
3288
    if (unlikely(!ctx->supervisor)) {
3289
        GEN_EXCP_PRIVREG(ctx);
3290
        return;
3291
    }
3292
    gen_op_load_msr();
3293
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3294
#endif
3295
}
3296

    
3297
#if 1
3298
#define SPR_NOACCESS ((void *)(-1UL))
3299
#else
3300
static void spr_noaccess (void *opaque, int sprn)
3301
{
3302
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3303
    printf("ERROR: try to access SPR %d !\n", sprn);
3304
}
3305
#define SPR_NOACCESS (&spr_noaccess)
3306
#endif
3307

    
3308
/* mfspr */
3309
static always_inline void gen_op_mfspr (DisasContext *ctx)
3310
{
3311
    void (*read_cb)(void *opaque, int sprn);
3312
    uint32_t sprn = SPR(ctx->opcode);
3313

    
3314
#if !defined(CONFIG_USER_ONLY)
3315
    if (ctx->supervisor == 2)
3316
        read_cb = ctx->spr_cb[sprn].hea_read;
3317
    else if (ctx->supervisor)
3318
        read_cb = ctx->spr_cb[sprn].oea_read;
3319
    else
3320
#endif
3321
        read_cb = ctx->spr_cb[sprn].uea_read;
3322
    if (likely(read_cb != NULL)) {
3323
        if (likely(read_cb != SPR_NOACCESS)) {
3324
            (*read_cb)(ctx, sprn);
3325
            tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3326
        } else {
3327
            /* Privilege exception */
3328
            /* This is a hack to avoid warnings when running Linux:
3329
             * this OS breaks the PowerPC virtualisation model,
3330
             * allowing userland application to read the PVR
3331
             */
3332
            if (sprn != SPR_PVR) {
3333
                if (loglevel != 0) {
3334
                    fprintf(logfile, "Trying to read privileged spr %d %03x at "
3335
                            ADDRX "\n", sprn, sprn, ctx->nip);
3336
                }
3337
                printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
3338
                       sprn, sprn, ctx->nip);
3339
            }
3340
            GEN_EXCP_PRIVREG(ctx);
3341
        }
3342
    } else {
3343
        /* Not defined */
3344
        if (loglevel != 0) {
3345
            fprintf(logfile, "Trying to read invalid spr %d %03x at "
3346
                    ADDRX "\n", sprn, sprn, ctx->nip);
3347
        }
3348
        printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
3349
               sprn, sprn, ctx->nip);
3350
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3351
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3352
    }
3353
}
3354

    
3355
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3356
{
3357
    gen_op_mfspr(ctx);
3358
}
3359

    
3360
/* mftb */
3361
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3362
{
3363
    gen_op_mfspr(ctx);
3364
}
3365

    
3366
/* mtcrf */
3367
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3368
{
3369
    uint32_t crm, crn;
3370

    
3371
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3372
    crm = CRM(ctx->opcode);
3373
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3374
        crn = ffs(crm);
3375
        gen_op_srli_T0(crn * 4);
3376
        gen_op_andi_T0(0xF);
3377
        gen_op_store_cro(7 - crn);
3378
    } else {
3379
        gen_op_store_cr(crm);
3380
    }
3381
}
3382

    
3383
/* mtmsr */
3384
#if defined(TARGET_PPC64)
3385
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3386
{
3387
#if defined(CONFIG_USER_ONLY)
3388
    GEN_EXCP_PRIVREG(ctx);
3389
#else
3390
    if (unlikely(!ctx->supervisor)) {
3391
        GEN_EXCP_PRIVREG(ctx);
3392
        return;
3393
    }
3394
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3395
    if (ctx->opcode & 0x00010000) {
3396
        /* Special form that does not need any synchronisation */
3397
        gen_op_update_riee();
3398
    } else {
3399
        /* XXX: we need to update nip before the store
3400
         *      if we enter power saving mode, we will exit the loop
3401
         *      directly from ppc_store_msr
3402
         */
3403
        gen_update_nip(ctx, ctx->nip);
3404
        gen_op_store_msr();
3405
        /* Must stop the translation as machine state (may have) changed */
3406
        /* Note that mtmsr is not always defined as context-synchronizing */
3407
        ctx->exception = POWERPC_EXCP_STOP;
3408
    }
3409
#endif
3410
}
3411
#endif
3412

    
3413
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3414
{
3415
#if defined(CONFIG_USER_ONLY)
3416
    GEN_EXCP_PRIVREG(ctx);
3417
#else
3418
    if (unlikely(!ctx->supervisor)) {
3419
        GEN_EXCP_PRIVREG(ctx);
3420
        return;
3421
    }
3422
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3423
    if (ctx->opcode & 0x00010000) {
3424
        /* Special form that does not need any synchronisation */
3425
        gen_op_update_riee();
3426
    } else {
3427
        /* XXX: we need to update nip before the store
3428
         *      if we enter power saving mode, we will exit the loop
3429
         *      directly from ppc_store_msr
3430
         */
3431
        gen_update_nip(ctx, ctx->nip);
3432
#if defined(TARGET_PPC64)
3433
        if (!ctx->sf_mode)
3434
            gen_op_store_msr_32();
3435
        else
3436
#endif
3437
            gen_op_store_msr();
3438
        /* Must stop the translation as machine state (may have) changed */
3439
        /* Note that mtmsrd is not always defined as context-synchronizing */
3440
        ctx->exception = POWERPC_EXCP_STOP;
3441
    }
3442
#endif
3443
}
3444

    
3445
/* mtspr */
3446
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3447
{
3448
    void (*write_cb)(void *opaque, int sprn);
3449
    uint32_t sprn = SPR(ctx->opcode);
3450

    
3451
#if !defined(CONFIG_USER_ONLY)
3452
    if (ctx->supervisor == 2)
3453
        write_cb = ctx->spr_cb[sprn].hea_write;
3454
    else if (ctx->supervisor)
3455
        write_cb = ctx->spr_cb[sprn].oea_write;
3456
    else
3457
#endif
3458
        write_cb = ctx->spr_cb[sprn].uea_write;
3459
    if (likely(write_cb != NULL)) {
3460
        if (likely(write_cb != SPR_NOACCESS)) {
3461
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3462
            (*write_cb)(ctx, sprn);
3463
        } else {
3464
            /* Privilege exception */
3465
            if (loglevel != 0) {
3466
                fprintf(logfile, "Trying to write privileged spr %d %03x at "
3467
                        ADDRX "\n", sprn, sprn, ctx->nip);
3468
            }
3469
            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
3470
                   sprn, sprn, ctx->nip);
3471
            GEN_EXCP_PRIVREG(ctx);
3472
        }
3473
    } else {
3474
        /* Not defined */
3475
        if (loglevel != 0) {
3476
            fprintf(logfile, "Trying to write invalid spr %d %03x at "
3477
                    ADDRX "\n", sprn, sprn, ctx->nip);
3478
        }
3479
        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
3480
               sprn, sprn, ctx->nip);
3481
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3482
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3483
    }
3484
}
3485

    
3486
/***                         Cache management                              ***/
3487
/* dcbf */
3488
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3489
{
3490
    /* XXX: specification says this is treated as a load by the MMU */
3491
    gen_addr_reg_index(ctx);
3492
    op_ldst(lbz);
3493
}
3494

    
3495
/* dcbi (Supervisor only) */
3496
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3497
{
3498
#if defined(CONFIG_USER_ONLY)
3499
    GEN_EXCP_PRIVOPC(ctx);
3500
#else
3501
    if (unlikely(!ctx->supervisor)) {
3502
        GEN_EXCP_PRIVOPC(ctx);
3503
        return;
3504
    }
3505
    gen_addr_reg_index(ctx);
3506
    /* XXX: specification says this should be treated as a store by the MMU */
3507
    op_ldst(lbz);
3508
    op_ldst(stb);
3509
#endif
3510
}
3511

    
3512
/* dcdst */
3513
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3514
{
3515
    /* XXX: specification say this is treated as a load by the MMU */
3516
    gen_addr_reg_index(ctx);
3517
    op_ldst(lbz);
3518
}
3519

    
3520
/* dcbt */
3521
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3522
{
3523
    /* interpreted as no-op */
3524
    /* XXX: specification say this is treated as a load by the MMU
3525
     *      but does not generate any exception
3526
     */
3527
}
3528

    
3529
/* dcbtst */
3530
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3531
{
3532
    /* interpreted as no-op */
3533
    /* XXX: specification say this is treated as a load by the MMU
3534
     *      but does not generate any exception
3535
     */
3536
}
3537

    
3538
/* dcbz */
3539
#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
3540
static GenOpFunc *gen_op_dcbz[4][NB_MEM_FUNCS] = {
3541
    /* 32 bytes cache line size */
3542
    {
3543
#define gen_op_dcbz_l32_le_raw        gen_op_dcbz_l32_raw
3544
#define gen_op_dcbz_l32_le_user       gen_op_dcbz_l32_user
3545
#define gen_op_dcbz_l32_le_kernel     gen_op_dcbz_l32_kernel
3546
#define gen_op_dcbz_l32_le_hypv       gen_op_dcbz_l32_hypv
3547
#define gen_op_dcbz_l32_le_64_raw     gen_op_dcbz_l32_64_raw
3548
#define gen_op_dcbz_l32_le_64_user    gen_op_dcbz_l32_64_user
3549
#define gen_op_dcbz_l32_le_64_kernel  gen_op_dcbz_l32_64_kernel
3550
#define gen_op_dcbz_l32_le_64_hypv    gen_op_dcbz_l32_64_hypv
3551
        GEN_MEM_FUNCS(dcbz_l32),
3552
    },
3553
    /* 64 bytes cache line size */
3554
    {
3555
#define gen_op_dcbz_l64_le_raw        gen_op_dcbz_l64_raw
3556
#define gen_op_dcbz_l64_le_user       gen_op_dcbz_l64_user
3557
#define gen_op_dcbz_l64_le_kernel     gen_op_dcbz_l64_kernel
3558
#define gen_op_dcbz_l64_le_hypv       gen_op_dcbz_l64_hypv
3559
#define gen_op_dcbz_l64_le_64_raw     gen_op_dcbz_l64_64_raw
3560
#define gen_op_dcbz_l64_le_64_user    gen_op_dcbz_l64_64_user
3561
#define gen_op_dcbz_l64_le_64_kernel  gen_op_dcbz_l64_64_kernel
3562
#define gen_op_dcbz_l64_le_64_hypv    gen_op_dcbz_l64_64_hypv
3563
        GEN_MEM_FUNCS(dcbz_l64),
3564
    },
3565
    /* 128 bytes cache line size */
3566
    {
3567
#define gen_op_dcbz_l128_le_raw       gen_op_dcbz_l128_raw
3568
#define gen_op_dcbz_l128_le_user      gen_op_dcbz_l128_user
3569
#define gen_op_dcbz_l128_le_kernel    gen_op_dcbz_l128_kernel
3570
#define gen_op_dcbz_l128_le_hypv      gen_op_dcbz_l128_hypv
3571
#define gen_op_dcbz_l128_le_64_raw    gen_op_dcbz_l128_64_raw
3572
#define gen_op_dcbz_l128_le_64_user   gen_op_dcbz_l128_64_user
3573
#define gen_op_dcbz_l128_le_64_kernel gen_op_dcbz_l128_64_kernel
3574
#define gen_op_dcbz_l128_le_64_hypv   gen_op_dcbz_l128_64_hypv
3575
        GEN_MEM_FUNCS(dcbz_l128),
3576
    },
3577
    /* tunable cache line size */
3578
    {
3579
#define gen_op_dcbz_le_raw            gen_op_dcbz_raw
3580
#define gen_op_dcbz_le_user           gen_op_dcbz_user
3581
#define gen_op_dcbz_le_kernel         gen_op_dcbz_kernel
3582
#define gen_op_dcbz_le_hypv           gen_op_dcbz_hypv
3583
#define gen_op_dcbz_le_64_raw         gen_op_dcbz_64_raw
3584
#define gen_op_dcbz_le_64_user        gen_op_dcbz_64_user
3585
#define gen_op_dcbz_le_64_kernel      gen_op_dcbz_64_kernel
3586
#define gen_op_dcbz_le_64_hypv        gen_op_dcbz_64_hypv
3587
        GEN_MEM_FUNCS(dcbz),
3588
    },
3589
};
3590

    
3591
static always_inline void handler_dcbz (DisasContext *ctx,
3592
                                        int dcache_line_size)
3593
{
3594
    int n;
3595

    
3596
    switch (dcache_line_size) {
3597
    case 32:
3598
        n = 0;
3599
        break;
3600
    case 64:
3601
        n = 1;
3602
        break;
3603
    case 128:
3604
        n = 2;
3605
        break;
3606
    default:
3607
        n = 3;
3608
        break;
3609
    }
3610
    op_dcbz(n);
3611
}
3612

    
3613
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
3614
{
3615
    gen_addr_reg_index(ctx);
3616
    handler_dcbz(ctx, ctx->dcache_line_size);
3617
    gen_op_check_reservation();
3618
}
3619

    
3620
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
3621
{
3622
    gen_addr_reg_index(ctx);
3623
    if (ctx->opcode & 0x00200000)
3624
        handler_dcbz(ctx, ctx->dcache_line_size);
3625
    else
3626
        handler_dcbz(ctx, -1);
3627
    gen_op_check_reservation();
3628
}
3629

    
3630
/* icbi */
3631
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3632
#define gen_op_icbi_le_raw       gen_op_icbi_raw
3633
#define gen_op_icbi_le_user      gen_op_icbi_user
3634
#define gen_op_icbi_le_kernel    gen_op_icbi_kernel
3635
#define gen_op_icbi_le_hypv      gen_op_icbi_hypv
3636
#define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
3637
#define gen_op_icbi_le_64_user   gen_op_icbi_64_user
3638
#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
3639
#define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
3640
static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
3641
    GEN_MEM_FUNCS(icbi),
3642
};
3643

    
3644
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
3645
{
3646
    /* NIP cannot be restored if the memory exception comes from an helper */
3647
    gen_update_nip(ctx, ctx->nip - 4);
3648
    gen_addr_reg_index(ctx);
3649
    op_icbi();
3650
}
3651

    
3652
/* Optional: */
3653
/* dcba */
3654
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3655
{
3656
    /* interpreted as no-op */
3657
    /* XXX: specification say this is treated as a store by the MMU
3658
     *      but does not generate any exception
3659
     */
3660
}
3661

    
3662
/***                    Segment register manipulation                      ***/
3663
/* Supervisor only: */
3664
/* mfsr */
3665
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3666
{
3667
#if defined(CONFIG_USER_ONLY)
3668
    GEN_EXCP_PRIVREG(ctx);
3669
#else
3670
    if (unlikely(!ctx->supervisor)) {
3671
        GEN_EXCP_PRIVREG(ctx);
3672
        return;
3673
    }
3674
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3675
    gen_op_load_sr();
3676
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3677
#endif
3678
}
3679

    
3680
/* mfsrin */
3681
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3682
{
3683
#if defined(CONFIG_USER_ONLY)
3684
    GEN_EXCP_PRIVREG(ctx);
3685
#else
3686
    if (unlikely(!ctx->supervisor)) {
3687
        GEN_EXCP_PRIVREG(ctx);
3688
        return;
3689
    }
3690
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3691
    gen_op_srli_T1(28);
3692
    gen_op_load_sr();
3693
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3694
#endif
3695
}
3696

    
3697
/* mtsr */
3698
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3699
{
3700
#if defined(CONFIG_USER_ONLY)
3701
    GEN_EXCP_PRIVREG(ctx);
3702
#else
3703
    if (unlikely(!ctx->supervisor)) {
3704
        GEN_EXCP_PRIVREG(ctx);
3705
        return;
3706
    }
3707
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3708
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3709
    gen_op_store_sr();
3710
#endif
3711
}
3712

    
3713
/* mtsrin */
3714
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3715
{
3716
#if defined(CONFIG_USER_ONLY)
3717
    GEN_EXCP_PRIVREG(ctx);
3718
#else
3719
    if (unlikely(!ctx->supervisor)) {
3720
        GEN_EXCP_PRIVREG(ctx);
3721
        return;
3722
    }
3723
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3724
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3725
    gen_op_srli_T1(28);
3726
    gen_op_store_sr();
3727
#endif
3728
}
3729

    
3730
#if defined(TARGET_PPC64)
3731
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
3732
/* mfsr */
3733
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
3734
{
3735
#if defined(CONFIG_USER_ONLY)
3736
    GEN_EXCP_PRIVREG(ctx);
3737
#else
3738
    if (unlikely(!ctx->supervisor)) {
3739
        GEN_EXCP_PRIVREG(ctx);
3740
        return;
3741
    }
3742
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3743
    gen_op_load_slb();
3744
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3745
#endif
3746
}
3747

    
3748
/* mfsrin */
3749
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
3750
             PPC_SEGMENT_64B)
3751
{
3752
#if defined(CONFIG_USER_ONLY)
3753
    GEN_EXCP_PRIVREG(ctx);
3754
#else
3755
    if (unlikely(!ctx->supervisor)) {
3756
        GEN_EXCP_PRIVREG(ctx);
3757
        return;
3758
    }
3759
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3760
    gen_op_srli_T1(28);
3761
    gen_op_load_slb();
3762
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3763
#endif
3764
}
3765

    
3766
/* mtsr */
3767
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
3768
{
3769
#if defined(CONFIG_USER_ONLY)
3770
    GEN_EXCP_PRIVREG(ctx);
3771
#else
3772
    if (unlikely(!ctx->supervisor)) {
3773
        GEN_EXCP_PRIVREG(ctx);
3774
        return;
3775
    }
3776
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3777
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3778
    gen_op_store_slb();
3779
#endif
3780
}
3781

    
3782
/* mtsrin */
3783
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
3784
             PPC_SEGMENT_64B)
3785
{
3786
#if defined(CONFIG_USER_ONLY)
3787
    GEN_EXCP_PRIVREG(ctx);
3788
#else
3789
    if (unlikely(!ctx->supervisor)) {
3790
        GEN_EXCP_PRIVREG(ctx);
3791
        return;
3792
    }
3793
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3794
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3795
    gen_op_srli_T1(28);
3796
    gen_op_store_slb();
3797
#endif
3798
}
3799
#endif /* defined(TARGET_PPC64) */
3800

    
3801
/***                      Lookaside buffer management                      ***/
3802
/* Optional & supervisor only: */
3803
/* tlbia */
3804
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3805
{
3806
#if defined(CONFIG_USER_ONLY)
3807
    GEN_EXCP_PRIVOPC(ctx);
3808
#else
3809
    if (unlikely(!ctx->supervisor)) {
3810
        GEN_EXCP_PRIVOPC(ctx);
3811
        return;
3812
    }
3813
    gen_op_tlbia();
3814
#endif
3815
}
3816

    
3817
/* tlbie */
3818
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
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
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
3828
#if defined(TARGET_PPC64)
3829
    if (ctx->sf_mode)
3830
        gen_op_tlbie_64();
3831
    else
3832
#endif
3833
        gen_op_tlbie();
3834
#endif
3835
}
3836

    
3837
/* tlbsync */
3838
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3839
{
3840
#if defined(CONFIG_USER_ONLY)
3841
    GEN_EXCP_PRIVOPC(ctx);
3842
#else
3843
    if (unlikely(!ctx->supervisor)) {
3844
        GEN_EXCP_PRIVOPC(ctx);
3845
        return;
3846
    }
3847
    /* This has no effect: it should ensure that all previous
3848
     * tlbie have completed
3849
     */
3850
    GEN_STOP(ctx);
3851
#endif
3852
}
3853

    
3854
#if defined(TARGET_PPC64)
3855
/* slbia */
3856
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3857
{
3858
#if defined(CONFIG_USER_ONLY)
3859
    GEN_EXCP_PRIVOPC(ctx);
3860
#else
3861
    if (unlikely(!ctx->supervisor)) {
3862
        GEN_EXCP_PRIVOPC(ctx);
3863
        return;
3864
    }
3865
    gen_op_slbia();
3866
#endif
3867
}
3868

    
3869
/* slbie */
3870
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3871
{
3872
#if defined(CONFIG_USER_ONLY)
3873
    GEN_EXCP_PRIVOPC(ctx);
3874
#else
3875
    if (unlikely(!ctx->supervisor)) {
3876
        GEN_EXCP_PRIVOPC(ctx);
3877
        return;
3878
    }
3879
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
3880
    gen_op_slbie();
3881
#endif
3882
}
3883
#endif
3884

    
3885
/***                              External control                         ***/
3886
/* Optional: */
3887
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3888
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3889
static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
3890
    GEN_MEM_FUNCS(eciwx),
3891
};
3892
static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
3893
    GEN_MEM_FUNCS(ecowx),
3894
};
3895

    
3896
/* eciwx */
3897
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3898
{
3899
    /* Should check EAR[E] & alignment ! */
3900
    gen_addr_reg_index(ctx);
3901
    op_eciwx();
3902
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3903
}
3904

    
3905
/* ecowx */
3906
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3907
{
3908
    /* Should check EAR[E] & alignment ! */
3909
    gen_addr_reg_index(ctx);
3910
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
3911
    op_ecowx();
3912
}
3913

    
3914
/* PowerPC 601 specific instructions */
3915
/* abs - abs. */
3916
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3917
{
3918
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3919
    gen_op_POWER_abs();
3920
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3921
    if (unlikely(Rc(ctx->opcode) != 0))
3922
        gen_set_Rc0(ctx);
3923
}
3924

    
3925
/* abso - abso. */
3926
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3927
{
3928
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3929
    gen_op_POWER_abso();
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
/* clcs */
3936
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3937
{
3938
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3939
    gen_op_POWER_clcs();
3940
    /* Rc=1 sets CR0 to an undefined state */
3941
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3942
}
3943

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

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

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

    
3977
/* divso - divso. */
3978
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3979
{
3980
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3981
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3982
    gen_op_POWER_divso();
3983
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3984
    if (unlikely(Rc(ctx->opcode) != 0))
3985
        gen_set_Rc0(ctx);
3986
}
3987

    
3988
/* doz - doz. */
3989
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3990
{
3991
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3992
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3993
    gen_op_POWER_doz();
3994
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3995
    if (unlikely(Rc(ctx->opcode) != 0))
3996
        gen_set_Rc0(ctx);
3997
}
3998

    
3999
/* dozo - dozo. */
4000
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
4001
{
4002
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4003
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4004
    gen_op_POWER_dozo();
4005
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4006
    if (unlikely(Rc(ctx->opcode) != 0))
4007
        gen_set_Rc0(ctx);
4008
}
4009

    
4010
/* dozi */
4011
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4012
{
4013
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4014
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
4015
    gen_op_POWER_doz();
4016
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4017
}
4018

    
4019
/* As lscbx load from memory byte after byte, it's always endian safe.
4020
 * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones
4021
 */
4022
#define op_POWER_lscbx(start, ra, rb)                                         \
4023
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
4024
#define gen_op_POWER_lscbx_64_raw       gen_op_POWER_lscbx_raw
4025
#define gen_op_POWER_lscbx_64_user      gen_op_POWER_lscbx_user
4026
#define gen_op_POWER_lscbx_64_kernel    gen_op_POWER_lscbx_kernel
4027
#define gen_op_POWER_lscbx_64_hypv      gen_op_POWER_lscbx_hypv
4028
#define gen_op_POWER_lscbx_le_raw       gen_op_POWER_lscbx_raw
4029
#define gen_op_POWER_lscbx_le_user      gen_op_POWER_lscbx_user
4030
#define gen_op_POWER_lscbx_le_kernel    gen_op_POWER_lscbx_kernel
4031
#define gen_op_POWER_lscbx_le_hypv      gen_op_POWER_lscbx_hypv
4032
#define gen_op_POWER_lscbx_le_64_raw    gen_op_POWER_lscbx_raw
4033
#define gen_op_POWER_lscbx_le_64_user   gen_op_POWER_lscbx_user
4034
#define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel
4035
#define gen_op_POWER_lscbx_le_64_hypv   gen_op_POWER_lscbx_hypv
4036
static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = {
4037
    GEN_MEM_FUNCS(POWER_lscbx),
4038
};
4039

    
4040
/* lscbx - lscbx. */
4041
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
4042
{
4043
    int ra = rA(ctx->opcode);
4044
    int rb = rB(ctx->opcode);
4045

    
4046
    gen_addr_reg_index(ctx);
4047
    if (ra == 0) {
4048
        ra = rb;
4049
    }
4050
    /* NIP cannot be restored if the memory exception comes from an helper */
4051
    gen_update_nip(ctx, ctx->nip - 4);
4052
    gen_op_load_xer_bc();
4053
    gen_op_load_xer_cmp();
4054
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
4055
    gen_op_store_xer_bc();
4056
    if (unlikely(Rc(ctx->opcode) != 0))
4057
        gen_set_Rc0(ctx);
4058
}
4059

    
4060
/* maskg - maskg. */
4061
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
4062
{
4063
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4064
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4065
    gen_op_POWER_maskg();
4066
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4067
    if (unlikely(Rc(ctx->opcode) != 0))
4068
        gen_set_Rc0(ctx);
4069
}
4070

    
4071
/* maskir - maskir. */
4072
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4073
{
4074
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4075
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4076
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4077
    gen_op_POWER_maskir();
4078
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4079
    if (unlikely(Rc(ctx->opcode) != 0))
4080
        gen_set_Rc0(ctx);
4081
}
4082

    
4083
/* mul - mul. */
4084
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4085
{
4086
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4087
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4088
    gen_op_POWER_mul();
4089
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4090
    if (unlikely(Rc(ctx->opcode) != 0))
4091
        gen_set_Rc0(ctx);
4092
}
4093

    
4094
/* mulo - mulo. */
4095
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4096
{
4097
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4098
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4099
    gen_op_POWER_mulo();
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
/* nabs - nabs. */
4106
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4107
{
4108
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4109
    gen_op_POWER_nabs();
4110
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4111
    if (unlikely(Rc(ctx->opcode) != 0))
4112
        gen_set_Rc0(ctx);
4113
}
4114

    
4115
/* nabso - nabso. */
4116
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4117
{
4118
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4119
    gen_op_POWER_nabso();
4120
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4121
    if (unlikely(Rc(ctx->opcode) != 0))
4122
        gen_set_Rc0(ctx);
4123
}
4124

    
4125
/* rlmi - rlmi. */
4126
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4127
{
4128
    uint32_t mb, me;
4129

    
4130
    mb = MB(ctx->opcode);
4131
    me = ME(ctx->opcode);
4132
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4133
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4134
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4135
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4136
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4137
    if (unlikely(Rc(ctx->opcode) != 0))
4138
        gen_set_Rc0(ctx);
4139
}
4140

    
4141
/* rrib - rrib. */
4142
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4143
{
4144
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4145
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4146
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4147
    gen_op_POWER_rrib();
4148
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4149
    if (unlikely(Rc(ctx->opcode) != 0))
4150
        gen_set_Rc0(ctx);
4151
}
4152

    
4153
/* sle - sle. */
4154
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4155
{
4156
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4157
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4158
    gen_op_POWER_sle();
4159
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4160
    if (unlikely(Rc(ctx->opcode) != 0))
4161
        gen_set_Rc0(ctx);
4162
}
4163

    
4164
/* sleq - sleq. */
4165
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4166
{
4167
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4168
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4169
    gen_op_POWER_sleq();
4170
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4171
    if (unlikely(Rc(ctx->opcode) != 0))
4172
        gen_set_Rc0(ctx);
4173
}
4174

    
4175
/* sliq - sliq. */
4176
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4177
{
4178
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4179
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4180
    gen_op_POWER_sle();
4181
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4182
    if (unlikely(Rc(ctx->opcode) != 0))
4183
        gen_set_Rc0(ctx);
4184
}
4185

    
4186
/* slliq - slliq. */
4187
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4188
{
4189
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4190
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4191
    gen_op_POWER_sleq();
4192
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4193
    if (unlikely(Rc(ctx->opcode) != 0))
4194
        gen_set_Rc0(ctx);
4195
}
4196

    
4197
/* sllq - sllq. */
4198
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4199
{
4200
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4201
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4202
    gen_op_POWER_sllq();
4203
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4204
    if (unlikely(Rc(ctx->opcode) != 0))
4205
        gen_set_Rc0(ctx);
4206
}
4207

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

    
4219
/* sraiq - sraiq. */
4220
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4221
{
4222
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4223
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4224
    gen_op_POWER_sraq();
4225
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4226
    if (unlikely(Rc(ctx->opcode) != 0))
4227
        gen_set_Rc0(ctx);
4228
}
4229

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

    
4241
/* sre - sre. */
4242
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4243
{
4244
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4245
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4246
    gen_op_POWER_sre();
4247
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4248
    if (unlikely(Rc(ctx->opcode) != 0))
4249
        gen_set_Rc0(ctx);
4250
}
4251

    
4252
/* srea - srea. */
4253
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4254
{
4255
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4256
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4257
    gen_op_POWER_srea();
4258
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4259
    if (unlikely(Rc(ctx->opcode) != 0))
4260
        gen_set_Rc0(ctx);
4261
}
4262

    
4263
/* sreq */
4264
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4265
{
4266
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4267
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4268
    gen_op_POWER_sreq();
4269
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4270
    if (unlikely(Rc(ctx->opcode) != 0))
4271
        gen_set_Rc0(ctx);
4272
}
4273

    
4274
/* sriq */
4275
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4276
{
4277
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4278
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4279
    gen_op_POWER_srq();
4280
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4281
    if (unlikely(Rc(ctx->opcode) != 0))
4282
        gen_set_Rc0(ctx);
4283
}
4284

    
4285
/* srliq */
4286
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4287
{
4288
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4289
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4290
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4291
    gen_op_POWER_srlq();
4292
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4293
    if (unlikely(Rc(ctx->opcode) != 0))
4294
        gen_set_Rc0(ctx);
4295
}
4296

    
4297
/* srlq */
4298
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4299
{
4300
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4301
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4302
    gen_op_POWER_srlq();
4303
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4304
    if (unlikely(Rc(ctx->opcode) != 0))
4305
        gen_set_Rc0(ctx);
4306
}
4307

    
4308
/* srq */
4309
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4310
{
4311
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4312
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4313
    gen_op_POWER_srq();
4314
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4315
    if (unlikely(Rc(ctx->opcode) != 0))
4316
        gen_set_Rc0(ctx);
4317
}
4318

    
4319
/* PowerPC 602 specific instructions */
4320
/* dsa  */
4321
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4322
{
4323
    /* XXX: TODO */
4324
    GEN_EXCP_INVAL(ctx);
4325
}
4326

    
4327
/* esa */
4328
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4329
{
4330
    /* XXX: TODO */
4331
    GEN_EXCP_INVAL(ctx);
4332
}
4333

    
4334
/* mfrom */
4335
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4336
{
4337
#if defined(CONFIG_USER_ONLY)
4338
    GEN_EXCP_PRIVOPC(ctx);
4339
#else
4340
    if (unlikely(!ctx->supervisor)) {
4341
        GEN_EXCP_PRIVOPC(ctx);
4342
        return;
4343
    }
4344
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4345
    gen_op_602_mfrom();
4346
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4347
#endif
4348
}
4349

    
4350
/* 602 - 603 - G2 TLB management */
4351
/* tlbld */
4352
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4353
{
4354
#if defined(CONFIG_USER_ONLY)
4355
    GEN_EXCP_PRIVOPC(ctx);
4356
#else
4357
    if (unlikely(!ctx->supervisor)) {
4358
        GEN_EXCP_PRIVOPC(ctx);
4359
        return;
4360
    }
4361
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4362
    gen_op_6xx_tlbld();
4363
#endif
4364
}
4365

    
4366
/* tlbli */
4367
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4368
{
4369
#if defined(CONFIG_USER_ONLY)
4370
    GEN_EXCP_PRIVOPC(ctx);
4371
#else
4372
    if (unlikely(!ctx->supervisor)) {
4373
        GEN_EXCP_PRIVOPC(ctx);
4374
        return;
4375
    }
4376
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4377
    gen_op_6xx_tlbli();
4378
#endif
4379
}
4380

    
4381
/* 74xx TLB management */
4382
/* tlbld */
4383
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4384
{
4385
#if defined(CONFIG_USER_ONLY)
4386
    GEN_EXCP_PRIVOPC(ctx);
4387
#else
4388
    if (unlikely(!ctx->supervisor)) {
4389
        GEN_EXCP_PRIVOPC(ctx);
4390
        return;
4391
    }
4392
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4393
    gen_op_74xx_tlbld();
4394
#endif
4395
}
4396

    
4397
/* tlbli */
4398
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4399
{
4400
#if defined(CONFIG_USER_ONLY)
4401
    GEN_EXCP_PRIVOPC(ctx);
4402
#else
4403
    if (unlikely(!ctx->supervisor)) {
4404
        GEN_EXCP_PRIVOPC(ctx);
4405
        return;
4406
    }
4407
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4408
    gen_op_74xx_tlbli();
4409
#endif
4410
}
4411

    
4412
/* POWER instructions not in PowerPC 601 */
4413
/* clf */
4414
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4415
{
4416
    /* Cache line flush: implemented as no-op */
4417
}
4418

    
4419
/* cli */
4420
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4421
{
4422
    /* Cache line invalidate: privileged and treated as no-op */
4423
#if defined(CONFIG_USER_ONLY)
4424
    GEN_EXCP_PRIVOPC(ctx);
4425
#else
4426
    if (unlikely(!ctx->supervisor)) {
4427
        GEN_EXCP_PRIVOPC(ctx);
4428
        return;
4429
    }
4430
#endif
4431
}
4432

    
4433
/* dclst */
4434
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4435
{
4436
    /* Data cache line store: treated as no-op */
4437
}
4438

    
4439
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 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
    int ra = rA(ctx->opcode);
4449
    int rd = rD(ctx->opcode);
4450

    
4451
    gen_addr_reg_index(ctx);
4452
    gen_op_POWER_mfsri();
4453
    tcg_gen_mov_tl(cpu_gpr[rd], cpu_T[0]);
4454
    if (ra != 0 && ra != rd)
4455
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[1]);
4456
#endif
4457
}
4458

    
4459
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4460
{
4461
#if defined(CONFIG_USER_ONLY)
4462
    GEN_EXCP_PRIVOPC(ctx);
4463
#else
4464
    if (unlikely(!ctx->supervisor)) {
4465
        GEN_EXCP_PRIVOPC(ctx);
4466
        return;
4467
    }
4468
    gen_addr_reg_index(ctx);
4469
    gen_op_POWER_rac();
4470
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4471
#endif
4472
}
4473

    
4474
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4475
{
4476
#if defined(CONFIG_USER_ONLY)
4477
    GEN_EXCP_PRIVOPC(ctx);
4478
#else
4479
    if (unlikely(!ctx->supervisor)) {
4480
        GEN_EXCP_PRIVOPC(ctx);
4481
        return;
4482
    }
4483
    gen_op_POWER_rfsvc();
4484
    GEN_SYNC(ctx);
4485
#endif
4486
}
4487

    
4488
/* svc is not implemented for now */
4489

    
4490
/* POWER2 specific instructions */
4491
/* Quad manipulation (load/store two floats at a time) */
4492
/* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
4493
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4494
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4495
#define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
4496
#define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
4497
#define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
4498
#define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
4499
#define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
4500
#define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
4501
#define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
4502
#define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
4503
#define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
4504
#define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
4505
#define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
4506
#define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
4507
#define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
4508
#define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
4509
#define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
4510
#define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
4511
static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
4512
    GEN_MEM_FUNCS(POWER2_lfq),
4513
};
4514
static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
4515
    GEN_MEM_FUNCS(POWER2_stfq),
4516
};
4517

    
4518
/* lfq */
4519
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4520
{
4521
    /* NIP cannot be restored if the memory exception comes from an helper */
4522
    gen_update_nip(ctx, ctx->nip - 4);
4523
    gen_addr_imm_index(ctx, 0);
4524
    op_POWER2_lfq();
4525
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4526
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4527
}
4528

    
4529
/* lfqu */
4530
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4531
{
4532
    int ra = rA(ctx->opcode);
4533

    
4534
    /* NIP cannot be restored if the memory exception comes from an helper */
4535
    gen_update_nip(ctx, ctx->nip - 4);
4536
    gen_addr_imm_index(ctx, 0);
4537
    op_POWER2_lfq();
4538
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4539
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4540
    if (ra != 0)
4541
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4542
}
4543

    
4544
/* lfqux */
4545
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4546
{
4547
    int ra = rA(ctx->opcode);
4548

    
4549
    /* NIP cannot be restored if the memory exception comes from an helper */
4550
    gen_update_nip(ctx, ctx->nip - 4);
4551
    gen_addr_reg_index(ctx);
4552
    op_POWER2_lfq();
4553
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4554
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4555
    if (ra != 0)
4556
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4557
}
4558

    
4559
/* lfqx */
4560
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4561
{
4562
    /* NIP cannot be restored if the memory exception comes from an helper */
4563
    gen_update_nip(ctx, ctx->nip - 4);
4564
    gen_addr_reg_index(ctx);
4565
    op_POWER2_lfq();
4566
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4567
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4568
}
4569

    
4570
/* stfq */
4571
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4572
{
4573
    /* NIP cannot be restored if the memory exception comes from an helper */
4574
    gen_update_nip(ctx, ctx->nip - 4);
4575
    gen_addr_imm_index(ctx, 0);
4576
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4577
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4578
    op_POWER2_stfq();
4579
}
4580

    
4581
/* stfqu */
4582
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4583
{
4584
    int ra = rA(ctx->opcode);
4585

    
4586
    /* NIP cannot be restored if the memory exception comes from an helper */
4587
    gen_update_nip(ctx, ctx->nip - 4);
4588
    gen_addr_imm_index(ctx, 0);
4589
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4590
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4591
    op_POWER2_stfq();
4592
    if (ra != 0)
4593
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4594
}
4595

    
4596
/* stfqux */
4597
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4598
{
4599
    int ra = rA(ctx->opcode);
4600

    
4601
    /* NIP cannot be restored if the memory exception comes from an helper */
4602
    gen_update_nip(ctx, ctx->nip - 4);
4603
    gen_addr_reg_index(ctx);
4604
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4605
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4606
    op_POWER2_stfq();
4607
    if (ra != 0)
4608
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4609
}
4610

    
4611
/* stfqx */
4612
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4613
{
4614
    /* NIP cannot be restored if the memory exception comes from an helper */
4615
    gen_update_nip(ctx, ctx->nip - 4);
4616
    gen_addr_reg_index(ctx);
4617
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4618
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4619
    op_POWER2_stfq();
4620
}
4621

    
4622
/* BookE specific instructions */
4623
/* XXX: not implemented on 440 ? */
4624
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
4625
{
4626
    /* XXX: TODO */
4627
    GEN_EXCP_INVAL(ctx);
4628
}
4629

    
4630
/* XXX: not implemented on 440 ? */
4631
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
4632
{
4633
#if defined(CONFIG_USER_ONLY)
4634
    GEN_EXCP_PRIVOPC(ctx);
4635
#else
4636
    if (unlikely(!ctx->supervisor)) {
4637
        GEN_EXCP_PRIVOPC(ctx);
4638
        return;
4639
    }
4640
    gen_addr_reg_index(ctx);
4641
    /* Use the same micro-ops as for tlbie */
4642
#if defined(TARGET_PPC64)
4643
    if (ctx->sf_mode)
4644
        gen_op_tlbie_64();
4645
    else
4646
#endif
4647
        gen_op_tlbie();
4648
#endif
4649
}
4650

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

    
4733
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4734
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4735
{                                                                             \
4736
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4737
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4738
}
4739

    
4740
/* macchw    - macchw.    */
4741
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4742
/* macchwo   - macchwo.   */
4743
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4744
/* macchws   - macchws.   */
4745
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4746
/* macchwso  - macchwso.  */
4747
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4748
/* macchwsu  - macchwsu.  */
4749
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4750
/* macchwsuo - macchwsuo. */
4751
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4752
/* macchwu   - macchwu.   */
4753
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4754
/* macchwuo  - macchwuo.  */
4755
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4756
/* machhw    - machhw.    */
4757
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4758
/* machhwo   - machhwo.   */
4759
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4760
/* machhws   - machhws.   */
4761
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4762
/* machhwso  - machhwso.  */
4763
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4764
/* machhwsu  - machhwsu.  */
4765
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4766
/* machhwsuo - machhwsuo. */
4767
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4768
/* machhwu   - machhwu.   */
4769
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4770
/* machhwuo  - machhwuo.  */
4771
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4772
/* maclhw    - maclhw.    */
4773
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4774
/* maclhwo   - maclhwo.   */
4775
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4776
/* maclhws   - maclhws.   */
4777
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4778
/* maclhwso  - maclhwso.  */
4779
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4780
/* maclhwu   - maclhwu.   */
4781
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4782
/* maclhwuo  - maclhwuo.  */
4783
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4784
/* maclhwsu  - maclhwsu.  */
4785
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4786
/* maclhwsuo - maclhwsuo. */
4787
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4788
/* nmacchw   - nmacchw.   */
4789
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4790
/* nmacchwo  - nmacchwo.  */
4791
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4792
/* nmacchws  - nmacchws.  */
4793
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4794
/* nmacchwso - nmacchwso. */
4795
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4796
/* nmachhw   - nmachhw.   */
4797
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4798
/* nmachhwo  - nmachhwo.  */
4799
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4800
/* nmachhws  - nmachhws.  */
4801
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4802
/* nmachhwso - nmachhwso. */
4803
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4804
/* nmaclhw   - nmaclhw.   */
4805
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4806
/* nmaclhwo  - nmaclhwo.  */
4807
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4808
/* nmaclhws  - nmaclhws.  */
4809
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4810
/* nmaclhwso - nmaclhwso. */
4811
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4812

    
4813
/* mulchw  - mulchw.  */
4814
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4815
/* mulchwu - mulchwu. */
4816
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4817
/* mulhhw  - mulhhw.  */
4818
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4819
/* mulhhwu - mulhhwu. */
4820
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4821
/* mullhw  - mullhw.  */
4822
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4823
/* mullhwu - mullhwu. */
4824
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4825

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

    
4834
    if (unlikely(!ctx->supervisor)) {
4835
        GEN_EXCP_PRIVREG(ctx);
4836
        return;
4837
    }
4838
    tcg_gen_movi_tl(cpu_T[0], dcrn);
4839
    gen_op_load_dcr();
4840
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4841
#endif
4842
}
4843

    
4844
/* mtdcr */
4845
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
4846
{
4847
#if defined(CONFIG_USER_ONLY)
4848
    GEN_EXCP_PRIVREG(ctx);
4849
#else
4850
    uint32_t dcrn = SPR(ctx->opcode);
4851

    
4852
    if (unlikely(!ctx->supervisor)) {
4853
        GEN_EXCP_PRIVREG(ctx);
4854
        return;
4855
    }
4856
    tcg_gen_movi_tl(cpu_T[0], dcrn);
4857
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4858
    gen_op_store_dcr();
4859
#endif
4860
}
4861

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

    
4880
/* mtdcrx */
4881
/* XXX: not implemented on 440 ? */
4882
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
4883
{
4884
#if defined(CONFIG_USER_ONLY)
4885
    GEN_EXCP_PRIVREG(ctx);
4886
#else
4887
    if (unlikely(!ctx->supervisor)) {
4888
        GEN_EXCP_PRIVREG(ctx);
4889
        return;
4890
    }
4891
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4892
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4893
    gen_op_store_dcr();
4894
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4895
#endif
4896
}
4897

    
4898
/* mfdcrux (PPC 460) : user-mode access to DCR */
4899
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4900
{
4901
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4902
    gen_op_load_dcr();
4903
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4904
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4905
}
4906

    
4907
/* mtdcrux (PPC 460) : user-mode access to DCR */
4908
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4909
{
4910
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4911
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4912
    gen_op_store_dcr();
4913
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4914
}
4915

    
4916
/* dccci */
4917
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4918
{
4919
#if defined(CONFIG_USER_ONLY)
4920
    GEN_EXCP_PRIVOPC(ctx);
4921
#else
4922
    if (unlikely(!ctx->supervisor)) {
4923
        GEN_EXCP_PRIVOPC(ctx);
4924
        return;
4925
    }
4926
    /* interpreted as no-op */
4927
#endif
4928
}
4929

    
4930
/* dcread */
4931
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4932
{
4933
#if defined(CONFIG_USER_ONLY)
4934
    GEN_EXCP_PRIVOPC(ctx);
4935
#else
4936
    if (unlikely(!ctx->supervisor)) {
4937
        GEN_EXCP_PRIVOPC(ctx);
4938
        return;
4939
    }
4940
    gen_addr_reg_index(ctx);
4941
    op_ldst(lwz);
4942
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4943
#endif
4944
}
4945

    
4946
/* icbt */
4947
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4948
{
4949
    /* interpreted as no-op */
4950
    /* XXX: specification say this is treated as a load by the MMU
4951
     *      but does not generate any exception
4952
     */
4953
}
4954

    
4955
/* iccci */
4956
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4957
{
4958
#if defined(CONFIG_USER_ONLY)
4959
    GEN_EXCP_PRIVOPC(ctx);
4960
#else
4961
    if (unlikely(!ctx->supervisor)) {
4962
        GEN_EXCP_PRIVOPC(ctx);
4963
        return;
4964
    }
4965
    /* interpreted as no-op */
4966
#endif
4967
}
4968

    
4969
/* icread */
4970
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4971
{
4972
#if defined(CONFIG_USER_ONLY)
4973
    GEN_EXCP_PRIVOPC(ctx);
4974
#else
4975
    if (unlikely(!ctx->supervisor)) {
4976
        GEN_EXCP_PRIVOPC(ctx);
4977
        return;
4978
    }
4979
    /* interpreted as no-op */
4980
#endif
4981
}
4982

    
4983
/* rfci (supervisor only) */
4984
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4985
{
4986
#if defined(CONFIG_USER_ONLY)
4987
    GEN_EXCP_PRIVOPC(ctx);
4988
#else
4989
    if (unlikely(!ctx->supervisor)) {
4990
        GEN_EXCP_PRIVOPC(ctx);
4991
        return;
4992
    }
4993
    /* Restore CPU state */
4994
    gen_op_40x_rfci();
4995
    GEN_SYNC(ctx);
4996
#endif
4997
}
4998

    
4999
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
5000
{
5001
#if defined(CONFIG_USER_ONLY)
5002
    GEN_EXCP_PRIVOPC(ctx);
5003
#else
5004
    if (unlikely(!ctx->supervisor)) {
5005
        GEN_EXCP_PRIVOPC(ctx);
5006
        return;
5007
    }
5008
    /* Restore CPU state */
5009
    gen_op_rfci();
5010
    GEN_SYNC(ctx);
5011
#endif
5012
}
5013

    
5014
/* BookE specific */
5015
/* XXX: not implemented on 440 ? */
5016
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
5017
{
5018
#if defined(CONFIG_USER_ONLY)
5019
    GEN_EXCP_PRIVOPC(ctx);
5020
#else
5021
    if (unlikely(!ctx->supervisor)) {
5022
        GEN_EXCP_PRIVOPC(ctx);
5023
        return;
5024
    }
5025
    /* Restore CPU state */
5026
    gen_op_rfdi();
5027
    GEN_SYNC(ctx);
5028
#endif
5029
}
5030

    
5031
/* XXX: not implemented on 440 ? */
5032
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
5033
{
5034
#if defined(CONFIG_USER_ONLY)
5035
    GEN_EXCP_PRIVOPC(ctx);
5036
#else
5037
    if (unlikely(!ctx->supervisor)) {
5038
        GEN_EXCP_PRIVOPC(ctx);
5039
        return;
5040
    }
5041
    /* Restore CPU state */
5042
    gen_op_rfmci();
5043
    GEN_SYNC(ctx);
5044
#endif
5045
}
5046

    
5047
/* TLB management - PowerPC 405 implementation */
5048
/* tlbre */
5049
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
5050
{
5051
#if defined(CONFIG_USER_ONLY)
5052
    GEN_EXCP_PRIVOPC(ctx);
5053
#else
5054
    if (unlikely(!ctx->supervisor)) {
5055
        GEN_EXCP_PRIVOPC(ctx);
5056
        return;
5057
    }
5058
    switch (rB(ctx->opcode)) {
5059
    case 0:
5060
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5061
        gen_op_4xx_tlbre_hi();
5062
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5063
        break;
5064
    case 1:
5065
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5066
        gen_op_4xx_tlbre_lo();
5067
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5068
        break;
5069
    default:
5070
        GEN_EXCP_INVAL(ctx);
5071
        break;
5072
    }
5073
#endif
5074
}
5075

    
5076
/* tlbsx - tlbsx. */
5077
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5078
{
5079
#if defined(CONFIG_USER_ONLY)
5080
    GEN_EXCP_PRIVOPC(ctx);
5081
#else
5082
    if (unlikely(!ctx->supervisor)) {
5083
        GEN_EXCP_PRIVOPC(ctx);
5084
        return;
5085
    }
5086
    gen_addr_reg_index(ctx);
5087
    gen_op_4xx_tlbsx();
5088
    if (Rc(ctx->opcode))
5089
        gen_op_4xx_tlbsx_check();
5090
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5091
#endif
5092
}
5093

    
5094
/* tlbwe */
5095
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5096
{
5097
#if defined(CONFIG_USER_ONLY)
5098
    GEN_EXCP_PRIVOPC(ctx);
5099
#else
5100
    if (unlikely(!ctx->supervisor)) {
5101
        GEN_EXCP_PRIVOPC(ctx);
5102
        return;
5103
    }
5104
    switch (rB(ctx->opcode)) {
5105
    case 0:
5106
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5107
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5108
        gen_op_4xx_tlbwe_hi();
5109
        break;
5110
    case 1:
5111
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5112
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5113
        gen_op_4xx_tlbwe_lo();
5114
        break;
5115
    default:
5116
        GEN_EXCP_INVAL(ctx);
5117
        break;
5118
    }
5119
#endif
5120
}
5121

    
5122
/* TLB management - PowerPC 440 implementation */
5123
/* tlbre */
5124
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5125
{
5126
#if defined(CONFIG_USER_ONLY)
5127
    GEN_EXCP_PRIVOPC(ctx);
5128
#else
5129
    if (unlikely(!ctx->supervisor)) {
5130
        GEN_EXCP_PRIVOPC(ctx);
5131
        return;
5132
    }
5133
    switch (rB(ctx->opcode)) {
5134
    case 0:
5135
    case 1:
5136
    case 2:
5137
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5138
        gen_op_440_tlbre(rB(ctx->opcode));
5139
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5140
        break;
5141
    default:
5142
        GEN_EXCP_INVAL(ctx);
5143
        break;
5144
    }
5145
#endif
5146
}
5147

    
5148
/* tlbsx - tlbsx. */
5149
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5150
{
5151
#if defined(CONFIG_USER_ONLY)
5152
    GEN_EXCP_PRIVOPC(ctx);
5153
#else
5154
    if (unlikely(!ctx->supervisor)) {
5155
        GEN_EXCP_PRIVOPC(ctx);
5156
        return;
5157
    }
5158
    gen_addr_reg_index(ctx);
5159
    gen_op_440_tlbsx();
5160
    if (Rc(ctx->opcode))
5161
        gen_op_4xx_tlbsx_check();
5162
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5163
#endif
5164
}
5165

    
5166
/* tlbwe */
5167
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5168
{
5169
#if defined(CONFIG_USER_ONLY)
5170
    GEN_EXCP_PRIVOPC(ctx);
5171
#else
5172
    if (unlikely(!ctx->supervisor)) {
5173
        GEN_EXCP_PRIVOPC(ctx);
5174
        return;
5175
    }
5176
    switch (rB(ctx->opcode)) {
5177
    case 0:
5178
    case 1:
5179
    case 2:
5180
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5181
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5182
        gen_op_440_tlbwe(rB(ctx->opcode));
5183
        break;
5184
    default:
5185
        GEN_EXCP_INVAL(ctx);
5186
        break;
5187
    }
5188
#endif
5189
}
5190

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

    
5210
/* wrteei */
5211
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
5212
{
5213
#if defined(CONFIG_USER_ONLY)
5214
    GEN_EXCP_PRIVOPC(ctx);
5215
#else
5216
    if (unlikely(!ctx->supervisor)) {
5217
        GEN_EXCP_PRIVOPC(ctx);
5218
        return;
5219
    }
5220
    tcg_gen_movi_tl(cpu_T[0], ctx->opcode & 0x00010000);
5221
    gen_op_wrte();
5222
    /* Stop translation to have a chance to raise an exception
5223
     * if we just set msr_ee to 1
5224
     */
5225
    GEN_STOP(ctx);
5226
#endif
5227
}
5228

    
5229
/* PowerPC 440 specific instructions */
5230
/* dlmzb */
5231
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5232
{
5233
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
5234
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
5235
    gen_op_440_dlmzb();
5236
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
5237
    gen_op_store_xer_bc();
5238
    if (Rc(ctx->opcode)) {
5239
        gen_op_440_dlmzb_update_Rc();
5240
        gen_op_store_T0_crf(0);
5241
    }
5242
}
5243

    
5244
/* mbar replaces eieio on 440 */
5245
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5246
{
5247
    /* interpreted as no-op */
5248
}
5249

    
5250
/* msync replaces sync on 440 */
5251
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5252
{
5253
    /* interpreted as no-op */
5254
}
5255

    
5256
/* icbt */
5257
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5258
{
5259
    /* interpreted as no-op */
5260
    /* XXX: specification say this is treated as a load by the MMU
5261
     *      but does not generate any exception
5262
     */
5263
}
5264

    
5265
/***                      Altivec vector extension                         ***/
5266
/* Altivec registers moves */
5267

    
5268
static always_inline void gen_load_avr(int t, int reg) {
5269
    tcg_gen_mov_i64(cpu_AVRh[t], cpu_avrh[reg]);
5270
    tcg_gen_mov_i64(cpu_AVRl[t], cpu_avrl[reg]);
5271
}
5272

    
5273
static always_inline void gen_store_avr(int reg, int t) {
5274
    tcg_gen_mov_i64(cpu_avrh[reg], cpu_AVRh[t]);
5275
    tcg_gen_mov_i64(cpu_avrl[reg], cpu_AVRl[t]);
5276
}
5277

    
5278
#define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5279
#define OP_VR_LD_TABLE(name)                                                  \
5280
static GenOpFunc *gen_op_vr_l##name[NB_MEM_FUNCS] = {                         \
5281
    GEN_MEM_FUNCS(vr_l##name),                                                \
5282
};
5283
#define OP_VR_ST_TABLE(name)                                                  \
5284
static GenOpFunc *gen_op_vr_st##name[NB_MEM_FUNCS] = {                        \
5285
    GEN_MEM_FUNCS(vr_st##name),                                               \
5286
};
5287

    
5288
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5289
GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
5290
{                                                                             \
5291
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5292
        GEN_EXCP_NO_VR(ctx);                                                  \
5293
        return;                                                               \
5294
    }                                                                         \
5295
    gen_addr_reg_index(ctx);                                                  \
5296
    op_vr_ldst(vr_l##name);                                                   \
5297
    gen_store_avr(rD(ctx->opcode), 0);                                        \
5298
}
5299

    
5300
#define GEN_VR_STX(name, opc2, opc3)                                          \
5301
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
5302
{                                                                             \
5303
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5304
        GEN_EXCP_NO_VR(ctx);                                                  \
5305
        return;                                                               \
5306
    }                                                                         \
5307
    gen_addr_reg_index(ctx);                                                  \
5308
    gen_load_avr(0, rS(ctx->opcode));                                         \
5309
    op_vr_ldst(vr_st##name);                                                  \
5310
}
5311

    
5312
OP_VR_LD_TABLE(vx);
5313
GEN_VR_LDX(vx, 0x07, 0x03);
5314
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
5315
#define gen_op_vr_lvxl gen_op_vr_lvx
5316
GEN_VR_LDX(vxl, 0x07, 0x0B);
5317

    
5318
OP_VR_ST_TABLE(vx);
5319
GEN_VR_STX(vx, 0x07, 0x07);
5320
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
5321
#define gen_op_vr_stvxl gen_op_vr_stvx
5322
GEN_VR_STX(vxl, 0x07, 0x0F);
5323

    
5324
/***                           SPE extension                               ***/
5325
/* Register moves */
5326

    
5327
static always_inline void gen_load_gpr64(TCGv t, int reg) {
5328
#if defined(TARGET_PPC64)
5329
    tcg_gen_mov_i64(t, cpu_gpr[reg]);
5330
#else
5331
    tcg_gen_extu_i32_i64(t, cpu_gprh[reg]);
5332
    tcg_gen_shli_i64(t, t, 32);
5333
    TCGv tmp = tcg_temp_local_new(TCG_TYPE_I64);
5334
    tcg_gen_extu_i32_i64(tmp, cpu_gpr[reg]);
5335
    tcg_gen_or_i64(t, t, tmp);
5336
    tcg_temp_free(tmp);
5337
#endif
5338
}
5339

    
5340
static always_inline void gen_store_gpr64(int reg, TCGv t) {
5341
#if defined(TARGET_PPC64)
5342
    tcg_gen_mov_i64(cpu_gpr[reg], t);
5343
#else
5344
    tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
5345
    TCGv tmp = tcg_temp_local_new(TCG_TYPE_I64);
5346
    tcg_gen_shri_i64(tmp, t, 32);
5347
    tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
5348
    tcg_temp_free(tmp);
5349
#endif
5350
}
5351

    
5352
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5353
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5354
{                                                                             \
5355
    if (Rc(ctx->opcode))                                                      \
5356
        gen_##name1(ctx);                                                     \
5357
    else                                                                      \
5358
        gen_##name0(ctx);                                                     \
5359
}
5360

    
5361
/* Handler for undefined SPE opcodes */
5362
static always_inline void gen_speundef (DisasContext *ctx)
5363
{
5364
    GEN_EXCP_INVAL(ctx);
5365
}
5366

    
5367
/* SPE load and stores */
5368
static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5369
{
5370
    target_long simm = rB(ctx->opcode);
5371

    
5372
    if (rA(ctx->opcode) == 0) {
5373
        tcg_gen_movi_tl(cpu_T[0], simm << sh);
5374
    } else {
5375
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5376
        if (likely(simm != 0))
5377
            gen_op_addi(simm << sh);
5378
    }
5379
}
5380

    
5381
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5382
#define OP_SPE_LD_TABLE(name)                                                 \
5383
static GenOpFunc *gen_op_spe_l##name[NB_MEM_FUNCS] = {                        \
5384
    GEN_MEM_FUNCS(spe_l##name),                                               \
5385
};
5386
#define OP_SPE_ST_TABLE(name)                                                 \
5387
static GenOpFunc *gen_op_spe_st##name[NB_MEM_FUNCS] = {                       \
5388
    GEN_MEM_FUNCS(spe_st##name),                                              \
5389
};
5390

    
5391
#define GEN_SPE_LD(name, sh)                                                  \
5392
static always_inline void gen_evl##name (DisasContext *ctx)                   \
5393
{                                                                             \
5394
    if (unlikely(!ctx->spe_enabled)) {                                        \
5395
        GEN_EXCP_NO_AP(ctx);                                                  \
5396
        return;                                                               \
5397
    }                                                                         \
5398
    gen_addr_spe_imm_index(ctx, sh);                                          \
5399
    op_spe_ldst(spe_l##name);                                                 \
5400
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[1]);                             \
5401
}
5402

    
5403
#define GEN_SPE_LDX(name)                                                     \
5404
static always_inline void gen_evl##name##x (DisasContext *ctx)                \
5405
{                                                                             \
5406
    if (unlikely(!ctx->spe_enabled)) {                                        \
5407
        GEN_EXCP_NO_AP(ctx);                                                  \
5408
        return;                                                               \
5409
    }                                                                         \
5410
    gen_addr_reg_index(ctx);                                                  \
5411
    op_spe_ldst(spe_l##name);                                                 \
5412
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[1]);                             \
5413
}
5414

    
5415
#define GEN_SPEOP_LD(name, sh)                                                \
5416
OP_SPE_LD_TABLE(name);                                                        \
5417
GEN_SPE_LD(name, sh);                                                         \
5418
GEN_SPE_LDX(name)
5419

    
5420
#define GEN_SPE_ST(name, sh)                                                  \
5421
static always_inline void gen_evst##name (DisasContext *ctx)                  \
5422
{                                                                             \
5423
    if (unlikely(!ctx->spe_enabled)) {                                        \
5424
        GEN_EXCP_NO_AP(ctx);                                                  \
5425
        return;                                                               \
5426
    }                                                                         \
5427
    gen_addr_spe_imm_index(ctx, sh);                                          \
5428
    gen_load_gpr64(cpu_T64[1], rS(ctx->opcode));                              \
5429
    op_spe_ldst(spe_st##name);                                                \
5430
}
5431

    
5432
#define GEN_SPE_STX(name)                                                     \
5433
static always_inline void gen_evst##name##x (DisasContext *ctx)               \
5434
{                                                                             \
5435
    if (unlikely(!ctx->spe_enabled)) {                                        \
5436
        GEN_EXCP_NO_AP(ctx);                                                  \
5437
        return;                                                               \
5438
    }                                                                         \
5439
    gen_addr_reg_index(ctx);                                                  \
5440
    gen_load_gpr64(cpu_T64[1], rS(ctx->opcode));                              \
5441
    op_spe_ldst(spe_st##name);                                                \
5442
}
5443

    
5444
#define GEN_SPEOP_ST(name, sh)                                                \
5445
OP_SPE_ST_TABLE(name);                                                        \
5446
GEN_SPE_ST(name, sh);                                                         \
5447
GEN_SPE_STX(name)
5448

    
5449
#define GEN_SPEOP_LDST(name, sh)                                              \
5450
GEN_SPEOP_LD(name, sh);                                                       \
5451
GEN_SPEOP_ST(name, sh)
5452

    
5453
/* SPE arithmetic and logic */
5454
#define GEN_SPEOP_ARITH2(name)                                                \
5455
static always_inline void gen_##name (DisasContext *ctx)                      \
5456
{                                                                             \
5457
    if (unlikely(!ctx->spe_enabled)) {                                        \
5458
        GEN_EXCP_NO_AP(ctx);                                                  \
5459
        return;                                                               \
5460
    }                                                                         \
5461
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5462
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
5463
    gen_op_##name();                                                          \
5464
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5465
}
5466

    
5467
#define GEN_SPEOP_ARITH1(name)                                                \
5468
static always_inline void gen_##name (DisasContext *ctx)                      \
5469
{                                                                             \
5470
    if (unlikely(!ctx->spe_enabled)) {                                        \
5471
        GEN_EXCP_NO_AP(ctx);                                                  \
5472
        return;                                                               \
5473
    }                                                                         \
5474
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5475
    gen_op_##name();                                                          \
5476
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5477
}
5478

    
5479
#define GEN_SPEOP_COMP(name)                                                  \
5480
static always_inline void gen_##name (DisasContext *ctx)                      \
5481
{                                                                             \
5482
    if (unlikely(!ctx->spe_enabled)) {                                        \
5483
        GEN_EXCP_NO_AP(ctx);                                                  \
5484
        return;                                                               \
5485
    }                                                                         \
5486
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5487
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
5488
    gen_op_##name();                                                          \
5489
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5490
}
5491

    
5492
/* Logical */
5493
GEN_SPEOP_ARITH2(evand);
5494
GEN_SPEOP_ARITH2(evandc);
5495
GEN_SPEOP_ARITH2(evxor);
5496
GEN_SPEOP_ARITH2(evor);
5497
GEN_SPEOP_ARITH2(evnor);
5498
GEN_SPEOP_ARITH2(eveqv);
5499
GEN_SPEOP_ARITH2(evorc);
5500
GEN_SPEOP_ARITH2(evnand);
5501
GEN_SPEOP_ARITH2(evsrwu);
5502
GEN_SPEOP_ARITH2(evsrws);
5503
GEN_SPEOP_ARITH2(evslw);
5504
GEN_SPEOP_ARITH2(evrlw);
5505
GEN_SPEOP_ARITH2(evmergehi);
5506
GEN_SPEOP_ARITH2(evmergelo);
5507
GEN_SPEOP_ARITH2(evmergehilo);
5508
GEN_SPEOP_ARITH2(evmergelohi);
5509

    
5510
/* Arithmetic */
5511
GEN_SPEOP_ARITH2(evaddw);
5512
GEN_SPEOP_ARITH2(evsubfw);
5513
GEN_SPEOP_ARITH1(evabs);
5514
GEN_SPEOP_ARITH1(evneg);
5515
GEN_SPEOP_ARITH1(evextsb);
5516
GEN_SPEOP_ARITH1(evextsh);
5517
GEN_SPEOP_ARITH1(evrndw);
5518
GEN_SPEOP_ARITH1(evcntlzw);
5519
GEN_SPEOP_ARITH1(evcntlsw);
5520
static always_inline void gen_brinc (DisasContext *ctx)
5521
{
5522
    /* Note: brinc is usable even if SPE is disabled */
5523
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5524
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
5525
    gen_op_brinc();
5526
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5527
}
5528

    
5529
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5530
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5531
{                                                                             \
5532
    if (unlikely(!ctx->spe_enabled)) {                                        \
5533
        GEN_EXCP_NO_AP(ctx);                                                  \
5534
        return;                                                               \
5535
    }                                                                         \
5536
    gen_load_gpr64(cpu_T64[0], rB(ctx->opcode));                              \
5537
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5538
    gen_op_##name();                                                          \
5539
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5540
}
5541

    
5542
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5543
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5544
{                                                                             \
5545
    if (unlikely(!ctx->spe_enabled)) {                                        \
5546
        GEN_EXCP_NO_AP(ctx);                                                  \
5547
        return;                                                               \
5548
    }                                                                         \
5549
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
5550
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5551
    gen_op_##name();                                                          \
5552
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5553
}
5554

    
5555
GEN_SPEOP_ARITH_IMM2(evaddw);
5556
#define gen_evaddiw gen_evaddwi
5557
GEN_SPEOP_ARITH_IMM2(evsubfw);
5558
#define gen_evsubifw gen_evsubfwi
5559
GEN_SPEOP_LOGIC_IMM2(evslw);
5560
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5561
#define gen_evsrwis gen_evsrwsi
5562
GEN_SPEOP_LOGIC_IMM2(evsrws);
5563
#define gen_evsrwiu gen_evsrwui
5564
GEN_SPEOP_LOGIC_IMM2(evrlw);
5565

    
5566
static always_inline void gen_evsplati (DisasContext *ctx)
5567
{
5568
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5569

    
5570
    gen_op_splatwi_T0_64(imm);
5571
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
5572
}
5573

    
5574
static always_inline void gen_evsplatfi (DisasContext *ctx)
5575
{
5576
    uint32_t imm = rA(ctx->opcode) << 27;
5577

    
5578
    gen_op_splatwi_T0_64(imm);
5579
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
5580
}
5581

    
5582
/* Comparison */
5583
GEN_SPEOP_COMP(evcmpgtu);
5584
GEN_SPEOP_COMP(evcmpgts);
5585
GEN_SPEOP_COMP(evcmpltu);
5586
GEN_SPEOP_COMP(evcmplts);
5587
GEN_SPEOP_COMP(evcmpeq);
5588

    
5589
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5590
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5591
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5592
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5593
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5594
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5595
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5596
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5597
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5598
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5599
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5600
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5601
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5602
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5603
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5604
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5605
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5606
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5607
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5608
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5609
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5610
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5611
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5612
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5613
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5614

    
5615
static always_inline void gen_evsel (DisasContext *ctx)
5616
{
5617
    if (unlikely(!ctx->spe_enabled)) {
5618
        GEN_EXCP_NO_AP(ctx);
5619
        return;
5620
    }
5621
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5622
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));
5623
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));
5624
    gen_op_evsel();
5625
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
5626
}
5627

    
5628
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5629
{
5630
    gen_evsel(ctx);
5631
}
5632
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5633
{
5634
    gen_evsel(ctx);
5635
}
5636
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5637
{
5638
    gen_evsel(ctx);
5639
}
5640
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5641
{
5642
    gen_evsel(ctx);
5643
}
5644

    
5645
/* Load and stores */
5646
#if defined(TARGET_PPC64)
5647
/* In that case, we already have 64 bits load & stores
5648
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5649
 */
5650
#define gen_op_spe_ldd_raw           gen_op_ld_raw
5651
#define gen_op_spe_ldd_user          gen_op_ld_user
5652
#define gen_op_spe_ldd_kernel        gen_op_ld_kernel
5653
#define gen_op_spe_ldd_hypv          gen_op_ld_hypv
5654
#define gen_op_spe_ldd_64_raw        gen_op_ld_64_raw
5655
#define gen_op_spe_ldd_64_user       gen_op_ld_64_user
5656
#define gen_op_spe_ldd_64_kernel     gen_op_ld_64_kernel
5657
#define gen_op_spe_ldd_64_hypv       gen_op_ld_64_hypv
5658
#define gen_op_spe_ldd_le_raw        gen_op_ld_le_raw
5659
#define gen_op_spe_ldd_le_user       gen_op_ld_le_user
5660
#define gen_op_spe_ldd_le_kernel     gen_op_ld_le_kernel
5661
#define gen_op_spe_ldd_le_hypv       gen_op_ld_le_hypv
5662
#define gen_op_spe_ldd_le_64_raw     gen_op_ld_le_64_raw
5663
#define gen_op_spe_ldd_le_64_user    gen_op_ld_le_64_user
5664
#define gen_op_spe_ldd_le_64_kernel  gen_op_ld_le_64_kernel
5665
#define gen_op_spe_ldd_le_64_hypv    gen_op_ld_le_64_hypv
5666
#define gen_op_spe_stdd_raw          gen_op_std_raw
5667
#define gen_op_spe_stdd_user         gen_op_std_user
5668
#define gen_op_spe_stdd_kernel       gen_op_std_kernel
5669
#define gen_op_spe_stdd_hypv         gen_op_std_hypv
5670
#define gen_op_spe_stdd_64_raw       gen_op_std_64_raw
5671
#define gen_op_spe_stdd_64_user      gen_op_std_64_user
5672
#define gen_op_spe_stdd_64_kernel    gen_op_std_64_kernel
5673
#define gen_op_spe_stdd_64_hypv      gen_op_std_64_hypv
5674
#define gen_op_spe_stdd_le_raw       gen_op_std_le_raw
5675
#define gen_op_spe_stdd_le_user      gen_op_std_le_user
5676
#define gen_op_spe_stdd_le_kernel    gen_op_std_le_kernel
5677
#define gen_op_spe_stdd_le_hypv      gen_op_std_le_hypv
5678
#define gen_op_spe_stdd_le_64_raw    gen_op_std_le_64_raw
5679
#define gen_op_spe_stdd_le_64_user   gen_op_std_le_64_user
5680
#define gen_op_spe_stdd_le_64_kernel gen_op_std_le_64_kernel
5681
#define gen_op_spe_stdd_le_64_hypv   gen_op_std_le_64_hypv
5682
#endif /* defined(TARGET_PPC64) */
5683
GEN_SPEOP_LDST(dd, 3);
5684
GEN_SPEOP_LDST(dw, 3);
5685
GEN_SPEOP_LDST(dh, 3);
5686
GEN_SPEOP_LDST(whe, 2);
5687
GEN_SPEOP_LD(whou, 2);
5688
GEN_SPEOP_LD(whos, 2);
5689
GEN_SPEOP_ST(who, 2);
5690

    
5691
#if defined(TARGET_PPC64)
5692
/* In that case, spe_stwwo is equivalent to stw */
5693
#define gen_op_spe_stwwo_raw          gen_op_stw_raw
5694
#define gen_op_spe_stwwo_user         gen_op_stw_user
5695
#define gen_op_spe_stwwo_kernel       gen_op_stw_kernel
5696
#define gen_op_spe_stwwo_hypv         gen_op_stw_hypv
5697
#define gen_op_spe_stwwo_le_raw       gen_op_stw_le_raw
5698
#define gen_op_spe_stwwo_le_user      gen_op_stw_le_user
5699
#define gen_op_spe_stwwo_le_kernel    gen_op_stw_le_kernel
5700
#define gen_op_spe_stwwo_le_hypv      gen_op_stw_le_hypv
5701
#define gen_op_spe_stwwo_64_raw       gen_op_stw_64_raw
5702
#define gen_op_spe_stwwo_64_user      gen_op_stw_64_user
5703
#define gen_op_spe_stwwo_64_kernel    gen_op_stw_64_kernel
5704
#define gen_op_spe_stwwo_64_hypv      gen_op_stw_64_hypv
5705
#define gen_op_spe_stwwo_le_64_raw    gen_op_stw_le_64_raw
5706
#define gen_op_spe_stwwo_le_64_user   gen_op_stw_le_64_user
5707
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5708
#define gen_op_spe_stwwo_le_64_hypv   gen_op_stw_le_64_hypv
5709
#endif
5710
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5711
static always_inline void gen_op_spe_stwwe_##suffix (void)                    \
5712
{                                                                             \
5713
    gen_op_srli32_T1_64();                                                    \
5714
    gen_op_spe_stwwo_##suffix();                                              \
5715
}
5716
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5717
static always_inline void gen_op_spe_stwwe_le_##suffix (void)                 \
5718
{                                                                             \
5719
    gen_op_srli32_T1_64();                                                    \
5720
    gen_op_spe_stwwo_le_##suffix();                                           \
5721
}
5722
#if defined(TARGET_PPC64)
5723
#define GEN_OP_SPE_STWWE(suffix)                                              \
5724
_GEN_OP_SPE_STWWE(suffix);                                                    \
5725
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5726
static always_inline void gen_op_spe_stwwe_64_##suffix (void)                 \
5727
{                                                                             \
5728
    gen_op_srli32_T1_64();                                                    \
5729
    gen_op_spe_stwwo_64_##suffix();                                           \
5730
}                                                                             \
5731
static always_inline void gen_op_spe_stwwe_le_64_##suffix (void)              \
5732
{                                                                             \
5733
    gen_op_srli32_T1_64();                                                    \
5734
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5735
}
5736
#else
5737
#define GEN_OP_SPE_STWWE(suffix)                                              \
5738
_GEN_OP_SPE_STWWE(suffix);                                                    \
5739
_GEN_OP_SPE_STWWE_LE(suffix)
5740
#endif
5741
#if defined(CONFIG_USER_ONLY)
5742
GEN_OP_SPE_STWWE(raw);
5743
#else /* defined(CONFIG_USER_ONLY) */
5744
GEN_OP_SPE_STWWE(user);
5745
GEN_OP_SPE_STWWE(kernel);
5746
GEN_OP_SPE_STWWE(hypv);
5747
#endif /* defined(CONFIG_USER_ONLY) */
5748
GEN_SPEOP_ST(wwe, 2);
5749
GEN_SPEOP_ST(wwo, 2);
5750

    
5751
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5752
static always_inline void gen_op_spe_l##name##_##suffix (void)                \
5753
{                                                                             \
5754
    gen_op_##op##_##suffix();                                                 \
5755
    gen_op_splatw_T1_64();                                                    \
5756
}
5757

    
5758
#define GEN_OP_SPE_LHE(suffix)                                                \
5759
static always_inline void gen_op_spe_lhe_##suffix (void)                      \
5760
{                                                                             \
5761
    gen_op_spe_lh_##suffix();                                                 \
5762
    gen_op_sli16_T1_64();                                                     \
5763
}
5764

    
5765
#define GEN_OP_SPE_LHX(suffix)                                                \
5766
static always_inline void gen_op_spe_lhx_##suffix (void)                      \
5767
{                                                                             \
5768
    gen_op_spe_lh_##suffix();                                                 \
5769
    gen_op_extsh_T1_64();                                                     \
5770
}
5771

    
5772
#if defined(CONFIG_USER_ONLY)
5773
GEN_OP_SPE_LHE(raw);
5774
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5775
GEN_OP_SPE_LHE(le_raw);
5776
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5777
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5778
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5779
GEN_OP_SPE_LHX(raw);
5780
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5781
GEN_OP_SPE_LHX(le_raw);
5782
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5783
#if defined(TARGET_PPC64)
5784
GEN_OP_SPE_LHE(64_raw);
5785
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5786
GEN_OP_SPE_LHE(le_64_raw);
5787
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5788
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5789
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5790
GEN_OP_SPE_LHX(64_raw);
5791
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5792
GEN_OP_SPE_LHX(le_64_raw);
5793
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5794
#endif
5795
#else
5796
GEN_OP_SPE_LHE(user);
5797
GEN_OP_SPE_LHE(kernel);
5798
GEN_OP_SPE_LHE(hypv);
5799
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5800
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5801
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv);
5802
GEN_OP_SPE_LHE(le_user);
5803
GEN_OP_SPE_LHE(le_kernel);
5804
GEN_OP_SPE_LHE(le_hypv);
5805
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5806
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5807
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv);
5808
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5809
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5810
GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv);
5811
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5812
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5813
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv);
5814
GEN_OP_SPE_LHX(user);
5815
GEN_OP_SPE_LHX(kernel);
5816
GEN_OP_SPE_LHX(hypv);
5817
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5818
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5819
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv);
5820
GEN_OP_SPE_LHX(le_user);
5821
GEN_OP_SPE_LHX(le_kernel);
5822
GEN_OP_SPE_LHX(le_hypv);
5823
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5824
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5825
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv);
5826
#if defined(TARGET_PPC64)
5827
GEN_OP_SPE_LHE(64_user);
5828
GEN_OP_SPE_LHE(64_kernel);
5829
GEN_OP_SPE_LHE(64_hypv);
5830
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5831
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5832
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv);
5833
GEN_OP_SPE_LHE(le_64_user);
5834
GEN_OP_SPE_LHE(le_64_kernel);
5835
GEN_OP_SPE_LHE(le_64_hypv);
5836
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5837
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5838
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv);
5839
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5840
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5841
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv);
5842
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5843
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5844
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv);
5845
GEN_OP_SPE_LHX(64_user);
5846
GEN_OP_SPE_LHX(64_kernel);
5847
GEN_OP_SPE_LHX(64_hypv);
5848
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5849
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5850
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv);
5851
GEN_OP_SPE_LHX(le_64_user);
5852
GEN_OP_SPE_LHX(le_64_kernel);
5853
GEN_OP_SPE_LHX(le_64_hypv);
5854
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5855
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5856
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv);
5857
#endif
5858
#endif
5859
GEN_SPEOP_LD(hhesplat, 1);
5860
GEN_SPEOP_LD(hhousplat, 1);
5861
GEN_SPEOP_LD(hhossplat, 1);
5862
GEN_SPEOP_LD(wwsplat, 2);
5863
GEN_SPEOP_LD(whsplat, 2);
5864

    
5865
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5866
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5867
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5868
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5869
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5870
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5871
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5872
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5873
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5874
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5875
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5876
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5877
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5878
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5879
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5880
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5881
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5882
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5883

    
5884
/* Multiply and add - TODO */
5885
#if 0
5886
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5887
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5888
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5889
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5890
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5891
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5892
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5893
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5894
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5895
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5896
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5897
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5898

5899
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5900
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5901
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5902
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5903
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5904
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5905
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5906
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5907
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5908
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5909
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5910
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5911
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5912
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5913

5914
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5915
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5916
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5917
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5918
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5919
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5920

5921
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5922
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5923
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5924
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5925
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5926
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5927
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5928
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5929
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5930
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5931
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5932
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5933

5934
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5935
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5936
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5937
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5938
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5939

5940
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5941
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5942
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5943
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5944
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5945
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5946
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5947
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5948
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5949
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5950
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5951
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5952

5953
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5954
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5955
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5956
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5957
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5958
#endif
5959

    
5960
/***                      SPE floating-point extension                     ***/
5961
#define GEN_SPEFPUOP_CONV(name)                                               \
5962
static always_inline void gen_##name (DisasContext *ctx)                      \
5963
{                                                                             \
5964
    gen_load_gpr64(cpu_T64[0], rB(ctx->opcode));                              \
5965
    gen_op_##name();                                                          \
5966
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
5967
}
5968

    
5969
/* Single precision floating-point vectors operations */
5970
/* Arithmetic */
5971
GEN_SPEOP_ARITH2(evfsadd);
5972
GEN_SPEOP_ARITH2(evfssub);
5973
GEN_SPEOP_ARITH2(evfsmul);
5974
GEN_SPEOP_ARITH2(evfsdiv);
5975
GEN_SPEOP_ARITH1(evfsabs);
5976
GEN_SPEOP_ARITH1(evfsnabs);
5977
GEN_SPEOP_ARITH1(evfsneg);
5978
/* Conversion */
5979
GEN_SPEFPUOP_CONV(evfscfui);
5980
GEN_SPEFPUOP_CONV(evfscfsi);
5981
GEN_SPEFPUOP_CONV(evfscfuf);
5982
GEN_SPEFPUOP_CONV(evfscfsf);
5983
GEN_SPEFPUOP_CONV(evfsctui);
5984
GEN_SPEFPUOP_CONV(evfsctsi);
5985
GEN_SPEFPUOP_CONV(evfsctuf);
5986
GEN_SPEFPUOP_CONV(evfsctsf);
5987
GEN_SPEFPUOP_CONV(evfsctuiz);
5988
GEN_SPEFPUOP_CONV(evfsctsiz);
5989
/* Comparison */
5990
GEN_SPEOP_COMP(evfscmpgt);
5991
GEN_SPEOP_COMP(evfscmplt);
5992
GEN_SPEOP_COMP(evfscmpeq);
5993
GEN_SPEOP_COMP(evfststgt);
5994
GEN_SPEOP_COMP(evfststlt);
5995
GEN_SPEOP_COMP(evfststeq);
5996

    
5997
/* Opcodes definitions */
5998
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5999
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
6000
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
6001
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
6002
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
6003
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
6004
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
6005
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
6006
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
6007
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
6008
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
6009
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
6010
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
6011
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
6012

    
6013
/* Single precision floating-point operations */
6014
/* Arithmetic */
6015
GEN_SPEOP_ARITH2(efsadd);
6016
GEN_SPEOP_ARITH2(efssub);
6017
GEN_SPEOP_ARITH2(efsmul);
6018
GEN_SPEOP_ARITH2(efsdiv);
6019
GEN_SPEOP_ARITH1(efsabs);
6020
GEN_SPEOP_ARITH1(efsnabs);
6021
GEN_SPEOP_ARITH1(efsneg);
6022
/* Conversion */
6023
GEN_SPEFPUOP_CONV(efscfui);
6024
GEN_SPEFPUOP_CONV(efscfsi);
6025
GEN_SPEFPUOP_CONV(efscfuf);
6026
GEN_SPEFPUOP_CONV(efscfsf);
6027
GEN_SPEFPUOP_CONV(efsctui);
6028
GEN_SPEFPUOP_CONV(efsctsi);
6029
GEN_SPEFPUOP_CONV(efsctuf);
6030
GEN_SPEFPUOP_CONV(efsctsf);
6031
GEN_SPEFPUOP_CONV(efsctuiz);
6032
GEN_SPEFPUOP_CONV(efsctsiz);
6033
GEN_SPEFPUOP_CONV(efscfd);
6034
/* Comparison */
6035
GEN_SPEOP_COMP(efscmpgt);
6036
GEN_SPEOP_COMP(efscmplt);
6037
GEN_SPEOP_COMP(efscmpeq);
6038
GEN_SPEOP_COMP(efststgt);
6039
GEN_SPEOP_COMP(efststlt);
6040
GEN_SPEOP_COMP(efststeq);
6041

    
6042
/* Opcodes definitions */
6043
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
6044
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
6045
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
6046
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
6047
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
6048
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
6049
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
6050
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
6051
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
6052
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
6053
GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
6054
GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPEFPU); //
6055
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
6056
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
6057

    
6058
/* Double precision floating-point operations */
6059
/* Arithmetic */
6060
GEN_SPEOP_ARITH2(efdadd);
6061
GEN_SPEOP_ARITH2(efdsub);
6062
GEN_SPEOP_ARITH2(efdmul);
6063
GEN_SPEOP_ARITH2(efddiv);
6064
GEN_SPEOP_ARITH1(efdabs);
6065
GEN_SPEOP_ARITH1(efdnabs);
6066
GEN_SPEOP_ARITH1(efdneg);
6067
/* Conversion */
6068

    
6069
GEN_SPEFPUOP_CONV(efdcfui);
6070
GEN_SPEFPUOP_CONV(efdcfsi);
6071
GEN_SPEFPUOP_CONV(efdcfuf);
6072
GEN_SPEFPUOP_CONV(efdcfsf);
6073
GEN_SPEFPUOP_CONV(efdctui);
6074
GEN_SPEFPUOP_CONV(efdctsi);
6075
GEN_SPEFPUOP_CONV(efdctuf);
6076
GEN_SPEFPUOP_CONV(efdctsf);
6077
GEN_SPEFPUOP_CONV(efdctuiz);
6078
GEN_SPEFPUOP_CONV(efdctsiz);
6079
GEN_SPEFPUOP_CONV(efdcfs);
6080
GEN_SPEFPUOP_CONV(efdcfuid);
6081
GEN_SPEFPUOP_CONV(efdcfsid);
6082
GEN_SPEFPUOP_CONV(efdctuidz);
6083
GEN_SPEFPUOP_CONV(efdctsidz);
6084
/* Comparison */
6085
GEN_SPEOP_COMP(efdcmpgt);
6086
GEN_SPEOP_COMP(efdcmplt);
6087
GEN_SPEOP_COMP(efdcmpeq);
6088
GEN_SPEOP_COMP(efdtstgt);
6089
GEN_SPEOP_COMP(efdtstlt);
6090
GEN_SPEOP_COMP(efdtsteq);
6091

    
6092
/* Opcodes definitions */
6093
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
6094
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
6095
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
6096
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
6097
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
6098
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
6099
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
6100
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
6101
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
6102
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
6103
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
6104
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
6105
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
6106
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
6107
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
6108
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6109

    
6110
/* End opcode list */
6111
GEN_OPCODE_MARK(end);
6112

    
6113
#include "translate_init.c"
6114
#include "helper_regs.h"
6115

    
6116
/*****************************************************************************/
6117
/* Misc PowerPC helpers */
6118
void cpu_dump_state (CPUState *env, FILE *f,
6119
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6120
                     int flags)
6121
{
6122
#define RGPL  4
6123
#define RFPL  4
6124

    
6125
    int i;
6126

    
6127
    cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
6128
                env->nip, env->lr, env->ctr, hreg_load_xer(env));
6129
    cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
6130
                env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
6131
#if !defined(NO_TIMER_DUMP)
6132
    cpu_fprintf(f, "TB %08x %08x "
6133
#if !defined(CONFIG_USER_ONLY)
6134
                "DECR %08x"
6135
#endif
6136
                "\n",
6137
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6138
#if !defined(CONFIG_USER_ONLY)
6139
                , cpu_ppc_load_decr(env)
6140
#endif
6141
                );
6142
#endif
6143
    for (i = 0; i < 32; i++) {
6144
        if ((i & (RGPL - 1)) == 0)
6145
            cpu_fprintf(f, "GPR%02d", i);
6146
        cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
6147
        if ((i & (RGPL - 1)) == (RGPL - 1))
6148
            cpu_fprintf(f, "\n");
6149
    }
6150
    cpu_fprintf(f, "CR ");
6151
    for (i = 0; i < 8; i++)
6152
        cpu_fprintf(f, "%01x", env->crf[i]);
6153
    cpu_fprintf(f, "  [");
6154
    for (i = 0; i < 8; i++) {
6155
        char a = '-';
6156
        if (env->crf[i] & 0x08)
6157
            a = 'L';
6158
        else if (env->crf[i] & 0x04)
6159
            a = 'G';
6160
        else if (env->crf[i] & 0x02)
6161
            a = 'E';
6162
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6163
    }
6164
    cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
6165
    for (i = 0; i < 32; i++) {
6166
        if ((i & (RFPL - 1)) == 0)
6167
            cpu_fprintf(f, "FPR%02d", i);
6168
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6169
        if ((i & (RFPL - 1)) == (RFPL - 1))
6170
            cpu_fprintf(f, "\n");
6171
    }
6172
#if !defined(CONFIG_USER_ONLY)
6173
    cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
6174
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6175
#endif
6176

    
6177
#undef RGPL
6178
#undef RFPL
6179
}
6180

    
6181
void cpu_dump_statistics (CPUState *env, FILE*f,
6182
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6183
                          int flags)
6184
{
6185
#if defined(DO_PPC_STATISTICS)
6186
    opc_handler_t **t1, **t2, **t3, *handler;
6187
    int op1, op2, op3;
6188

    
6189
    t1 = env->opcodes;
6190
    for (op1 = 0; op1 < 64; op1++) {
6191
        handler = t1[op1];
6192
        if (is_indirect_opcode(handler)) {
6193
            t2 = ind_table(handler);
6194
            for (op2 = 0; op2 < 32; op2++) {
6195
                handler = t2[op2];
6196
                if (is_indirect_opcode(handler)) {
6197
                    t3 = ind_table(handler);
6198
                    for (op3 = 0; op3 < 32; op3++) {
6199
                        handler = t3[op3];
6200
                        if (handler->count == 0)
6201
                            continue;
6202
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6203
                                    "%016llx %lld\n",
6204
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6205
                                    handler->oname,
6206
                                    handler->count, handler->count);
6207
                    }
6208
                } else {
6209
                    if (handler->count == 0)
6210
                        continue;
6211
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6212
                                "%016llx %lld\n",
6213
                                op1, op2, op1, op2, handler->oname,
6214
                                handler->count, handler->count);
6215
                }
6216
            }
6217
        } else {
6218
            if (handler->count == 0)
6219
                continue;
6220
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6221
                        op1, op1, handler->oname,
6222
                        handler->count, handler->count);
6223
        }
6224
    }
6225
#endif
6226
}
6227

    
6228
/*****************************************************************************/
6229
static always_inline void gen_intermediate_code_internal (CPUState *env,
6230
                                                          TranslationBlock *tb,
6231
                                                          int search_pc)
6232
{
6233
    DisasContext ctx, *ctxp = &ctx;
6234
    opc_handler_t **table, *handler;
6235
    target_ulong pc_start;
6236
    uint16_t *gen_opc_end;
6237
    int supervisor, little_endian;
6238
    int j, lj = -1;
6239
    int num_insns;
6240
    int max_insns;
6241

    
6242
    pc_start = tb->pc;
6243
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6244
#if defined(OPTIMIZE_FPRF_UPDATE)
6245
    gen_fprf_ptr = gen_fprf_buf;
6246
#endif
6247
    ctx.nip = pc_start;
6248
    ctx.tb = tb;
6249
    ctx.exception = POWERPC_EXCP_NONE;
6250
    ctx.spr_cb = env->spr_cb;
6251
    supervisor = env->mmu_idx;
6252
#if !defined(CONFIG_USER_ONLY)
6253
    ctx.supervisor = supervisor;
6254
#endif
6255
    little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
6256
#if defined(TARGET_PPC64)
6257
    ctx.sf_mode = msr_sf;
6258
    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
6259
#else
6260
    ctx.mem_idx = (supervisor << 1) | little_endian;
6261
#endif
6262
    ctx.dcache_line_size = env->dcache_line_size;
6263
    ctx.fpu_enabled = msr_fp;
6264
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
6265
        ctx.spe_enabled = msr_spe;
6266
    else
6267
        ctx.spe_enabled = 0;
6268
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
6269
        ctx.altivec_enabled = msr_vr;
6270
    else
6271
        ctx.altivec_enabled = 0;
6272
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6273
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
6274
    else
6275
        ctx.singlestep_enabled = 0;
6276
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
6277
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
6278
    if (unlikely(env->singlestep_enabled))
6279
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
6280
#if defined (DO_SINGLE_STEP) && 0
6281
    /* Single step trace mode */
6282
    msr_se = 1;
6283
#endif
6284
    num_insns = 0;
6285
    max_insns = tb->cflags & CF_COUNT_MASK;
6286
    if (max_insns == 0)
6287
        max_insns = CF_COUNT_MASK;
6288

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

    
6439
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6440
{
6441
    gen_intermediate_code_internal(env, tb, 0);
6442
}
6443

    
6444
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6445
{
6446
    gen_intermediate_code_internal(env, tb, 1);
6447
}
6448

    
6449
void gen_pc_load(CPUState *env, TranslationBlock *tb,
6450
                unsigned long searched_pc, int pc_pos, void *puc)
6451
{
6452
    int type, c;
6453
    /* for PPC, we need to look at the micro operation to get the
6454
     * access type */
6455
    env->nip = gen_opc_pc[pc_pos];
6456
    c = gen_opc_buf[pc_pos];
6457
    switch(c) {
6458
#if defined(CONFIG_USER_ONLY)
6459
#define CASE3(op)\
6460
    case INDEX_op_ ## op ## _raw
6461
#else
6462
#define CASE3(op)\
6463
    case INDEX_op_ ## op ## _user:\
6464
    case INDEX_op_ ## op ## _kernel:\
6465
    case INDEX_op_ ## op ## _hypv
6466
#endif
6467

    
6468
    CASE3(stfd):
6469
    CASE3(stfs):
6470
    CASE3(lfd):
6471
    CASE3(lfs):
6472
        type = ACCESS_FLOAT;
6473
        break;
6474
    CASE3(lwarx):
6475
        type = ACCESS_RES;
6476
        break;
6477
    CASE3(stwcx):
6478
        type = ACCESS_RES;
6479
        break;
6480
    CASE3(eciwx):
6481
    CASE3(ecowx):
6482
        type = ACCESS_EXT;
6483
        break;
6484
    default:
6485
        type = ACCESS_INT;
6486
        break;
6487
    }
6488
    env->access_type = type;
6489
}