Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ ec6469a3

History | View | Annotate | Download (248.4 kB)

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

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

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

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

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

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

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

    
78
#include "gen-icount.h"
79

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

    
86
    if (done_init)
87
        return;
88

    
89
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
90
#if TARGET_LONG_BITS > HOST_LONG_BITS
91
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
92
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
93
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
94
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
95
    cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
96
                                  TCG_AREG0, offsetof(CPUState, t2), "T2");
97
#else
98
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
99
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
100
#ifdef HOST_I386
101
    /* XXX: This is a temporary workaround for i386.
102
     *      On i386 qemu_st32 runs out of registers.
103
     *      The proper fix is to remove cpu_T.
104
     */
105
    cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
106
                                  TCG_AREG0, offsetof(CPUState, t2), "T2");
107
#else
108
    cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
109
#endif
110
#endif
111
#if !defined(TARGET_PPC64)
112
    cpu_T64[0] = tcg_global_mem_new(TCG_TYPE_I64,
113
                                    TCG_AREG0, offsetof(CPUState, t0_64),
114
                                    "T0_64");
115
    cpu_T64[1] = tcg_global_mem_new(TCG_TYPE_I64,
116
                                    TCG_AREG0, offsetof(CPUState, t1_64),
117
                                    "T1_64");
118
    cpu_T64[2] = tcg_global_mem_new(TCG_TYPE_I64,
119
                                    TCG_AREG0, offsetof(CPUState, t2_64),
120
                                    "T2_64");
121
#endif
122

    
123
    cpu_FT[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
124
                                   offsetof(CPUState, ft0), "FT0");
125
    cpu_FT[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
126
                                   offsetof(CPUState, ft1), "FT1");
127
    cpu_FT[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
128
                                   offsetof(CPUState, ft2), "FT2");
129

    
130
    cpu_AVRh[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
131
                                     offsetof(CPUState, avr0.u64[0]), "AVR0H");
132
    cpu_AVRl[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
133
                                     offsetof(CPUState, avr0.u64[1]), "AVR0L");
134
    cpu_AVRh[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
135
                                     offsetof(CPUState, avr1.u64[0]), "AVR1H");
136
    cpu_AVRl[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
137
                                     offsetof(CPUState, avr1.u64[1]), "AVR1L");
138
    cpu_AVRh[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
139
                                     offsetof(CPUState, avr2.u64[0]), "AVR2H");
140
    cpu_AVRl[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
141
                                     offsetof(CPUState, avr2.u64[1]), "AVR2L");
142

    
143
    p = cpu_reg_names;
144

    
145
    for (i = 0; i < 8; i++) {
146
        sprintf(p, "crf%d", i);
147
        cpu_crf[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
148
                                        offsetof(CPUState, crf[i]), p);
149
        p += 5;
150
    }
151

    
152
    for (i = 0; i < 32; i++) {
153
        sprintf(p, "r%d", i);
154
        cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
155
                                        offsetof(CPUState, gpr[i]), p);
156
        p += (i < 10) ? 3 : 4;
157
#if !defined(TARGET_PPC64)
158
        sprintf(p, "r%dH", i);
159
        cpu_gprh[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
160
                                         offsetof(CPUState, gprh[i]), p);
161
        p += (i < 10) ? 4 : 5;
162
#endif
163

    
164
        sprintf(p, "fp%d", i);
165
        cpu_fpr[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
166
                                        offsetof(CPUState, fpr[i]), p);
167
        p += (i < 10) ? 4 : 5;
168

    
169
        sprintf(p, "avr%dH", i);
170
        cpu_avrh[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
171
                                         offsetof(CPUState, avr[i].u64[0]), p);
172
        p += (i < 10) ? 6 : 7;
173

    
174
        sprintf(p, "avr%dL", i);
175
        cpu_avrl[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
176
                                         offsetof(CPUState, avr[i].u64[1]), p);
177
        p += (i < 10) ? 6 : 7;
178
    }
179

    
180
    cpu_nip = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
181
                                 offsetof(CPUState, nip), "nip");
182

    
183
    cpu_ctr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
184
                                 offsetof(CPUState, ctr), "ctr");
185

    
186
    cpu_lr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
187
                                offsetof(CPUState, lr), "lr");
188

    
189
    cpu_xer = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
190
                                 offsetof(CPUState, xer), "xer");
191

    
192
    cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
193
                                   offsetof(CPUState, fpscr), "fpscr");
194

    
195
    /* register helpers */
196
#undef DEF_HELPER
197
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
198
#include "helper.h"
199

    
200
    done_init = 1;
201
}
202

    
203
#if defined(OPTIMIZE_FPRF_UPDATE)
204
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
205
static uint16_t **gen_fprf_ptr;
206
#endif
207

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

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

    
246
static always_inline void gen_reset_fpstatus (void)
247
{
248
#ifdef CONFIG_SOFTFLOAT
249
    gen_op_reset_fpstatus();
250
#endif
251
}
252

    
253
static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
254
{
255
    if (set_fprf != 0) {
256
        /* This case might be optimized later */
257
#if defined(OPTIMIZE_FPRF_UPDATE)
258
        *gen_fprf_ptr++ = gen_opc_ptr;
259
#endif
260
        gen_op_compute_fprf(1);
261
        if (unlikely(set_rc))
262
            tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
263
        gen_op_float_check_status();
264
    } else if (unlikely(set_rc)) {
265
        /* We always need to compute fpcc */
266
        gen_op_compute_fprf(0);
267
        tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
268
        if (set_fprf)
269
            gen_op_float_check_status();
270
    }
271
}
272

    
273
static always_inline void gen_optimize_fprf (void)
274
{
275
#if defined(OPTIMIZE_FPRF_UPDATE)
276
    uint16_t **ptr;
277

    
278
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
279
        *ptr = INDEX_op_nop1;
280
    gen_fprf_ptr = gen_fprf_buf;
281
#endif
282
}
283

    
284
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
285
{
286
#if defined(TARGET_PPC64)
287
    if (ctx->sf_mode)
288
        tcg_gen_movi_tl(cpu_nip, nip);
289
    else
290
#endif
291
        tcg_gen_movi_tl(cpu_nip, (uint32_t)nip);
292
}
293

    
294
#define GEN_EXCP(ctx, excp, error)                                            \
295
do {                                                                          \
296
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
297
        gen_update_nip(ctx, (ctx)->nip);                                      \
298
    }                                                                         \
299
    gen_op_raise_exception_err((excp), (error));                              \
300
    ctx->exception = (excp);                                                  \
301
} while (0)
302

    
303
#define GEN_EXCP_INVAL(ctx)                                                   \
304
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
305
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
306

    
307
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
308
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
309
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
310

    
311
#define GEN_EXCP_PRIVREG(ctx)                                                 \
312
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
313
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
314

    
315
#define GEN_EXCP_NO_FP(ctx)                                                   \
316
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
317

    
318
#define GEN_EXCP_NO_AP(ctx)                                                   \
319
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
320

    
321
#define GEN_EXCP_NO_VR(ctx)                                                   \
322
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
323

    
324
/* Stop translation */
325
static always_inline void GEN_STOP (DisasContext *ctx)
326
{
327
    gen_update_nip(ctx, ctx->nip);
328
    ctx->exception = POWERPC_EXCP_STOP;
329
}
330

    
331
/* No need to update nip here, as execution flow will change */
332
static always_inline void GEN_SYNC (DisasContext *ctx)
333
{
334
    ctx->exception = POWERPC_EXCP_SYNC;
335
}
336

    
337
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
338
static void gen_##name (DisasContext *ctx);                                   \
339
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
340
static void gen_##name (DisasContext *ctx)
341

    
342
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
343
static void gen_##name (DisasContext *ctx);                                   \
344
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
345
static void gen_##name (DisasContext *ctx)
346

    
347
typedef struct opcode_t {
348
    unsigned char opc1, opc2, opc3;
349
#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
350
    unsigned char pad[5];
351
#else
352
    unsigned char pad[1];
353
#endif
354
    opc_handler_t handler;
355
    const char *oname;
356
} opcode_t;
357

    
358
/*****************************************************************************/
359
/***                           Instruction decoding                        ***/
360
#define EXTRACT_HELPER(name, shift, nb)                                       \
361
static always_inline uint32_t name (uint32_t opcode)                          \
362
{                                                                             \
363
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
364
}
365

    
366
#define EXTRACT_SHELPER(name, shift, nb)                                      \
367
static always_inline int32_t name (uint32_t opcode)                           \
368
{                                                                             \
369
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
370
}
371

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

    
402
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
403
}
404
/***                              Get constants                            ***/
405
EXTRACT_HELPER(IMM, 12, 8);
406
/* 16 bits signed immediate value */
407
EXTRACT_SHELPER(SIMM, 0, 16);
408
/* 16 bits unsigned immediate value */
409
EXTRACT_HELPER(UIMM, 0, 16);
410
/* Bit count */
411
EXTRACT_HELPER(NB, 11, 5);
412
/* Shift count */
413
EXTRACT_HELPER(SH, 11, 5);
414
/* Mask start */
415
EXTRACT_HELPER(MB, 6, 5);
416
/* Mask end */
417
EXTRACT_HELPER(ME, 1, 5);
418
/* Trap operand */
419
EXTRACT_HELPER(TO, 21, 5);
420

    
421
EXTRACT_HELPER(CRM, 12, 8);
422
EXTRACT_HELPER(FM, 17, 8);
423
EXTRACT_HELPER(SR, 16, 4);
424
EXTRACT_HELPER(FPIMM, 12, 4);
425

    
426
/***                            Jump target decoding                       ***/
427
/* Displacement */
428
EXTRACT_SHELPER(d, 0, 16);
429
/* Immediate address */
430
static always_inline target_ulong LI (uint32_t opcode)
431
{
432
    return (opcode >> 0) & 0x03FFFFFC;
433
}
434

    
435
static always_inline uint32_t BD (uint32_t opcode)
436
{
437
    return (opcode >> 0) & 0xFFFC;
438
}
439

    
440
EXTRACT_HELPER(BO, 21, 5);
441
EXTRACT_HELPER(BI, 16, 5);
442
/* Absolute/relative address */
443
EXTRACT_HELPER(AA, 1, 1);
444
/* Link */
445
EXTRACT_HELPER(LK, 0, 1);
446

    
447
/* Create a mask between <start> and <end> bits */
448
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
449
{
450
    target_ulong ret;
451

    
452
#if defined(TARGET_PPC64)
453
    if (likely(start == 0)) {
454
        ret = UINT64_MAX << (63 - end);
455
    } else if (likely(end == 63)) {
456
        ret = UINT64_MAX >> start;
457
    }
458
#else
459
    if (likely(start == 0)) {
460
        ret = UINT32_MAX << (31  - end);
461
    } else if (likely(end == 31)) {
462
        ret = UINT32_MAX >> start;
463
    }
464
#endif
465
    else {
466
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
467
            (((target_ulong)(-1ULL) >> (end)) >> 1);
468
        if (unlikely(start > end))
469
            return ~ret;
470
    }
471

    
472
    return ret;
473
}
474

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

    
511
    /* Fixed-point unit extensions                                           */
512
    /*   PowerPC 602 specific                                                */
513
    PPC_602_SPEC       = 0x0000000000000400ULL,
514
    /*   isel instruction                                                    */
515
    PPC_ISEL           = 0x0000000000000800ULL,
516
    /*   popcntb instruction                                                 */
517
    PPC_POPCNTB        = 0x0000000000001000ULL,
518
    /*   string load / store                                                 */
519
    PPC_STRING         = 0x0000000000002000ULL,
520

    
521
    /* Floating-point unit extensions                                        */
522
    /*   Optional floating point instructions                                */
523
    PPC_FLOAT          = 0x0000000000010000ULL,
524
    /* New floating-point extensions (PowerPC 2.0x)                          */
525
    PPC_FLOAT_EXT      = 0x0000000000020000ULL,
526
    PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
527
    PPC_FLOAT_FRES     = 0x0000000000080000ULL,
528
    PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
529
    PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
530
    PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
531
    PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
532

    
533
    /* Vector/SIMD extensions                                                */
534
    /*   Altivec support                                                     */
535
    PPC_ALTIVEC        = 0x0000000001000000ULL,
536
    /*   PowerPC 2.03 SPE extension                                          */
537
    PPC_SPE            = 0x0000000002000000ULL,
538
    /*   PowerPC 2.03 SPE floating-point extension                           */
539
    PPC_SPEFPU         = 0x0000000004000000ULL,
540

    
541
    /* Optional memory control instructions                                  */
542
    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
543
    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
544
    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
545
    /*   sync instruction                                                    */
546
    PPC_MEM_SYNC       = 0x0000000080000000ULL,
547
    /*   eieio instruction                                                   */
548
    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
549

    
550
    /* Cache control instructions                                            */
551
    PPC_CACHE          = 0x0000000200000000ULL,
552
    /*   icbi instruction                                                    */
553
    PPC_CACHE_ICBI     = 0x0000000400000000ULL,
554
    /*   dcbz instruction with fixed cache line size                         */
555
    PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
556
    /*   dcbz instruction with tunable cache line size                       */
557
    PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
558
    /*   dcba instruction                                                    */
559
    PPC_CACHE_DCBA     = 0x0000002000000000ULL,
560
    /*   Freescale cache locking instructions                                */
561
    PPC_CACHE_LOCK     = 0x0000004000000000ULL,
562

    
563
    /* MMU related extensions                                                */
564
    /*   external control instructions                                       */
565
    PPC_EXTERN         = 0x0000010000000000ULL,
566
    /*   segment register access instructions                                */
567
    PPC_SEGMENT        = 0x0000020000000000ULL,
568
    /*   PowerPC 6xx TLB management instructions                             */
569
    PPC_6xx_TLB        = 0x0000040000000000ULL,
570
    /* PowerPC 74xx TLB management instructions                              */
571
    PPC_74xx_TLB       = 0x0000080000000000ULL,
572
    /*   PowerPC 40x TLB management instructions                             */
573
    PPC_40x_TLB        = 0x0000100000000000ULL,
574
    /*   segment register access instructions for PowerPC 64 "bridge"        */
575
    PPC_SEGMENT_64B    = 0x0000200000000000ULL,
576
    /*   SLB management                                                      */
577
    PPC_SLBI           = 0x0000400000000000ULL,
578

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

    
611
/*****************************************************************************/
612
/* PowerPC instructions table                                                */
613
#if HOST_LONG_BITS == 64
614
#define OPC_ALIGN 8
615
#else
616
#define OPC_ALIGN 4
617
#endif
618
#if defined(__APPLE__)
619
#define OPCODES_SECTION                                                       \
620
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
621
#else
622
#define OPCODES_SECTION                                                       \
623
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
624
#endif
625

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

    
684
#define GEN_OPCODE_MARK(name)                                                 \
685
OPCODES_SECTION opcode_t opc_##name = {                                       \
686
    .opc1 = 0xFF,                                                             \
687
    .opc2 = 0xFF,                                                             \
688
    .opc3 = 0xFF,                                                             \
689
    .pad  = { 0, },                                                           \
690
    .handler = {                                                              \
691
        .inval   = 0x00000000,                                                \
692
        .type = 0x00,                                                         \
693
        .handler = NULL,                                                      \
694
    },                                                                        \
695
    .oname = stringify(name),                                                 \
696
}
697

    
698
/* Start opcode list */
699
GEN_OPCODE_MARK(start);
700

    
701
/* Invalid instruction */
702
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
703
{
704
    GEN_EXCP_INVAL(ctx);
705
}
706

    
707
static opc_handler_t invalid_handler = {
708
    .inval   = 0xFFFFFFFF,
709
    .type    = PPC_NONE,
710
    .handler = gen_invalid,
711
};
712

    
713
/***                           Integer comparison                          ***/
714

    
715
static always_inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
716
{
717
    int l1, l2, l3;
718

    
719
    tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_xer);
720
    tcg_gen_shri_i32(cpu_crf[crf], cpu_crf[crf], XER_SO);
721
    tcg_gen_andi_i32(cpu_crf[crf], cpu_crf[crf], 1);
722

    
723
    l1 = gen_new_label();
724
    l2 = gen_new_label();
725
    l3 = gen_new_label();
726
    if (s) {
727
        tcg_gen_brcond_tl(TCG_COND_LT, arg0, arg1, l1);
728
        tcg_gen_brcond_tl(TCG_COND_GT, arg0, arg1, l2);
729
    } else {
730
        tcg_gen_brcond_tl(TCG_COND_LTU, arg0, arg1, l1);
731
        tcg_gen_brcond_tl(TCG_COND_GTU, arg0, arg1, l2);
732
    }
733
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_EQ);
734
    tcg_gen_br(l3);
735
    gen_set_label(l1);
736
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_LT);
737
    tcg_gen_br(l3);
738
    gen_set_label(l2);
739
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_GT);
740
    gen_set_label(l3);
741
}
742

    
743
static always_inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
744
{
745
    TCGv t0 = tcg_const_local_tl(arg1);
746
    gen_op_cmp(arg0, t0, s, crf);
747
    tcg_temp_free(t0);
748
}
749

    
750
#if defined(TARGET_PPC64)
751
static always_inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
752
{
753
    TCGv t0, t1;
754
    t0 = tcg_temp_local_new(TCG_TYPE_TL);
755
    t1 = tcg_temp_local_new(TCG_TYPE_TL);
756
    if (s) {
757
        tcg_gen_ext32s_tl(t0, arg0);
758
        tcg_gen_ext32s_tl(t1, arg1);
759
    } else {
760
        tcg_gen_ext32u_tl(t0, arg0);
761
        tcg_gen_ext32u_tl(t1, arg1);
762
    }
763
    gen_op_cmp(t0, t1, s, crf);
764
    tcg_temp_free(t1);
765
    tcg_temp_free(t0);
766
}
767

    
768
static always_inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
769
{
770
    TCGv t0 = tcg_const_local_tl(arg1);
771
    gen_op_cmp32(arg0, t0, s, crf);
772
    tcg_temp_free(t0);
773
}
774
#endif
775

    
776
static always_inline void gen_set_Rc0 (DisasContext *ctx, TCGv reg)
777
{
778
#if defined(TARGET_PPC64)
779
    if (!(ctx->sf_mode))
780
        gen_op_cmpi32(reg, 0, 1, 0);
781
    else
782
#endif
783
        gen_op_cmpi(reg, 0, 1, 0);
784
}
785

    
786
/* cmp */
787
GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER)
788
{
789
#if defined(TARGET_PPC64)
790
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
791
        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
792
                     1, crfD(ctx->opcode));
793
    else
794
#endif
795
        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
796
                   1, crfD(ctx->opcode));
797
}
798

    
799
/* cmpi */
800
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
801
{
802
#if defined(TARGET_PPC64)
803
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
804
        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
805
                      1, crfD(ctx->opcode));
806
    else
807
#endif
808
        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
809
                    1, crfD(ctx->opcode));
810
}
811

    
812
/* cmpl */
813
GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER)
814
{
815
#if defined(TARGET_PPC64)
816
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
817
        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
818
                     0, crfD(ctx->opcode));
819
    else
820
#endif
821
        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
822
                   0, crfD(ctx->opcode));
823
}
824

    
825
/* cmpli */
826
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
827
{
828
#if defined(TARGET_PPC64)
829
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
830
        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
831
                      0, crfD(ctx->opcode));
832
    else
833
#endif
834
        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
835
                    0, crfD(ctx->opcode));
836
}
837

    
838
/* isel (PowerPC 2.03 specification) */
839
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
840
{
841
    int l1, l2;
842
    uint32_t bi = rC(ctx->opcode);
843
    uint32_t mask;
844
    TCGv t0;
845

    
846
    l1 = gen_new_label();
847
    l2 = gen_new_label();
848

    
849
    mask = 1 << (3 - (bi & 0x03));
850
    t0 = tcg_temp_new(TCG_TYPE_I32);
851
    tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
852
    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
853
    if (rA(ctx->opcode) == 0)
854
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
855
    else
856
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
857
    tcg_gen_br(l2);
858
    gen_set_label(l1);
859
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
860
    gen_set_label(l2);
861
}
862

    
863
/***                           Integer arithmetic                          ***/
864

    
865
static always_inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0, TCGv arg1, TCGv arg2, int sub)
866
{
867
    int l1;
868
    TCGv t0;
869

    
870
    l1 = gen_new_label();
871
    /* Start with XER OV disabled, the most likely case */
872
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
873
    t0 = tcg_temp_local_new(TCG_TYPE_TL);
874
    tcg_gen_xor_tl(t0, arg0, arg1);
875
#if defined(TARGET_PPC64)
876
    if (!ctx->sf_mode)
877
        tcg_gen_ext32s_tl(t0, t0);
878
#endif
879
    if (sub)
880
        tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
881
    else
882
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
883
    tcg_gen_xor_tl(t0, arg1, arg2);
884
#if defined(TARGET_PPC64)
885
    if (!ctx->sf_mode)
886
        tcg_gen_ext32s_tl(t0, t0);
887
#endif
888
    if (sub)
889
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
890
    else
891
        tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
892
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
893
    gen_set_label(l1);
894
    tcg_temp_free(t0);
895
}
896

    
897
static always_inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1, TCGv arg2, int sub)
898
{
899
    int l1 = gen_new_label();
900

    
901
#if defined(TARGET_PPC64)
902
    if (!(ctx->sf_mode)) {
903
        TCGv t0, t1;
904
        t0 = tcg_temp_new(TCG_TYPE_TL);
905
        t1 = tcg_temp_new(TCG_TYPE_TL);
906

    
907
        tcg_gen_ext32u_tl(t0, arg1);
908
        tcg_gen_ext32u_tl(t1, arg2);
909
        if (sub) {
910
            tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
911
        } else {
912
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
913
        }
914
    } else
915
#endif
916
    if (sub) {
917
        tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
918
    } else {
919
        tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
920
    }
921
    tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
922
    gen_set_label(l1);
923
}
924

    
925
/* Common add function */
926
static always_inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
927
                                           int add_ca, int compute_ca, int compute_ov)
928
{
929
    TCGv t0, t1;
930

    
931
    if ((!compute_ca && !compute_ov) ||
932
        (GET_TCGV(ret) != GET_TCGV(arg1) && GET_TCGV(ret) != GET_TCGV(arg2)))  {
933
        t0 = ret;
934
    } else {
935
        t0 = tcg_temp_local_new(TCG_TYPE_TL);
936
    }
937

    
938
    if (add_ca) {
939
        t1 = tcg_temp_local_new(TCG_TYPE_TL);
940
        tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
941
        tcg_gen_shri_tl(t1, t1, XER_CA);
942
    }
943

    
944
    if (compute_ca && compute_ov) {
945
        /* Start with XER CA and OV disabled, the most likely case */
946
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
947
    } else if (compute_ca) {
948
        /* Start with XER CA disabled, the most likely case */
949
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
950
    } else if (compute_ov) {
951
        /* Start with XER OV disabled, the most likely case */
952
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
953
    }
954

    
955
    tcg_gen_add_tl(t0, arg1, arg2);
956

    
957
    if (compute_ca) {
958
        gen_op_arith_compute_ca(ctx, t0, arg1, 0);
959
    }
960
    if (add_ca) {
961
        tcg_gen_add_tl(t0, t0, t1);
962
        gen_op_arith_compute_ca(ctx, t0, t1, 0);
963
        tcg_temp_free(t1);
964
    }
965
    if (compute_ov) {
966
        gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
967
    }
968

    
969
    if (unlikely(Rc(ctx->opcode) != 0))
970
        gen_set_Rc0(ctx, t0);
971

    
972
    if (GET_TCGV(t0) != GET_TCGV(ret)) {
973
        tcg_gen_mov_tl(ret, t0);
974
        tcg_temp_free(t0);
975
    }
976
}
977
/* Add functions with two operands */
978
#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
979
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER)                  \
980
{                                                                             \
981
    gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
982
                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
983
                     add_ca, compute_ca, compute_ov);                         \
984
}
985
/* Add functions with one operand and one immediate */
986
#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
987
                                add_ca, compute_ca, compute_ov)               \
988
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER)                  \
989
{                                                                             \
990
    TCGv t0 = tcg_const_local_tl(const_val);                                  \
991
    gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
992
                     cpu_gpr[rA(ctx->opcode)], t0,                            \
993
                     add_ca, compute_ca, compute_ov);                         \
994
    tcg_temp_free(t0);                                                        \
995
}
996

    
997
/* add  add.  addo  addo. */
998
GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
999
GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
1000
/* addc  addc.  addco  addco. */
1001
GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
1002
GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
1003
/* adde  adde.  addeo  addeo. */
1004
GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
1005
GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
1006
/* addme  addme.  addmeo  addmeo.  */
1007
GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
1008
GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
1009
/* addze  addze.  addzeo  addzeo.*/
1010
GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
1011
GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
1012
/* addi */
1013
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1014
{
1015
    target_long simm = SIMM(ctx->opcode);
1016

    
1017
    if (rA(ctx->opcode) == 0) {
1018
        /* li case */
1019
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
1020
    } else {
1021
        tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm);
1022
    }
1023
}
1024
/* addic  addic.*/
1025
static always_inline void gen_op_addic (DisasContext *ctx, TCGv ret, TCGv arg1,
1026
                                        int compute_Rc0)
1027
{
1028
    target_long simm = SIMM(ctx->opcode);
1029

    
1030
    /* Start with XER CA and OV disabled, the most likely case */
1031
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1032

    
1033
    if (likely(simm != 0)) {
1034
        TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1035
        tcg_gen_addi_tl(t0, arg1, simm);
1036
        gen_op_arith_compute_ca(ctx, t0, arg1, 0);
1037
        tcg_gen_mov_tl(ret, t0);
1038
        tcg_temp_free(t0);
1039
    } else {
1040
        tcg_gen_mov_tl(ret, arg1);
1041
    }
1042
    if (compute_Rc0) {
1043
        gen_set_Rc0(ctx, ret);
1044
    }
1045
}
1046
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1047
{
1048
    gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
1049
}
1050
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1051
{
1052
    gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
1053
}
1054
/* addis */
1055
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1056
{
1057
    target_long simm = SIMM(ctx->opcode);
1058

    
1059
    if (rA(ctx->opcode) == 0) {
1060
        /* lis case */
1061
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
1062
    } else {
1063
        tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm << 16);
1064
    }
1065
}
1066

    
1067
static always_inline void gen_op_arith_divw (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
1068
                                             int sign, int compute_ov)
1069
{
1070
    int l1 = gen_new_label();
1071
    int l2 = gen_new_label();
1072
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_I32);
1073
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_I32);
1074

    
1075
    tcg_gen_trunc_tl_i32(t0, arg1);
1076
    tcg_gen_trunc_tl_i32(t1, arg2);
1077
    tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
1078
    if (sign) {
1079
        int l3 = gen_new_label();
1080
        tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
1081
        tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
1082
        gen_set_label(l3);
1083
        tcg_gen_div_i32(t0, t0, t1);
1084
    } else {
1085
        tcg_gen_divu_i32(t0, t0, t1);
1086
    }
1087
    if (compute_ov) {
1088
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1089
    }
1090
    tcg_gen_br(l2);
1091
    gen_set_label(l1);
1092
    if (sign) {
1093
        tcg_gen_sari_i32(t0, t0, 31);
1094
    } else {
1095
        tcg_gen_movi_i32(t0, 0);
1096
    }
1097
    if (compute_ov) {
1098
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
1099
    }
1100
    gen_set_label(l2);
1101
    tcg_gen_extu_i32_tl(ret, t0);
1102
    tcg_temp_free(t0);
1103
    tcg_temp_free(t1);
1104
    if (unlikely(Rc(ctx->opcode) != 0))
1105
        gen_set_Rc0(ctx, ret);
1106
}
1107
/* Div functions */
1108
#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
1109
GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)                  \
1110
{                                                                             \
1111
    gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1112
                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
1113
                     sign, compute_ov);                                       \
1114
}
1115
/* divwu  divwu.  divwuo  divwuo.   */
1116
GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
1117
GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
1118
/* divw  divw.  divwo  divwo.   */
1119
GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
1120
GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
1121
#if defined(TARGET_PPC64)
1122
static always_inline void gen_op_arith_divd (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
1123
                                             int sign, int compute_ov)
1124
{
1125
    int l1 = gen_new_label();
1126
    int l2 = gen_new_label();
1127

    
1128
    tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
1129
    if (sign) {
1130
        int l3 = gen_new_label();
1131
        tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
1132
        tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
1133
        gen_set_label(l3);
1134
        tcg_gen_div_i64(ret, arg1, arg2);
1135
    } else {
1136
        tcg_gen_divu_i64(ret, arg1, arg2);
1137
    }
1138
    if (compute_ov) {
1139
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1140
    }
1141
    tcg_gen_br(l2);
1142
    gen_set_label(l1);
1143
    if (sign) {
1144
        tcg_gen_sari_i64(ret, arg1, 63);
1145
    } else {
1146
        tcg_gen_movi_i64(ret, 0);
1147
    }
1148
    if (compute_ov) {
1149
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
1150
    }
1151
    gen_set_label(l2);
1152
    if (unlikely(Rc(ctx->opcode) != 0))
1153
        gen_set_Rc0(ctx, ret);
1154
}
1155
#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
1156
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)                      \
1157
{                                                                             \
1158
    gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1159
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1160
                      sign, compute_ov);                                      \
1161
}
1162
/* divwu  divwu.  divwuo  divwuo.   */
1163
GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
1164
GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
1165
/* divw  divw.  divwo  divwo.   */
1166
GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
1167
GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1168
#endif
1169

    
1170
/* mulhw  mulhw. */
1171
GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER)
1172
{
1173
    TCGv t0, t1;
1174

    
1175
    t0 = tcg_temp_new(TCG_TYPE_I64);
1176
    t1 = tcg_temp_new(TCG_TYPE_I64);
1177
#if defined(TARGET_PPC64)
1178
    tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
1179
    tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
1180
    tcg_gen_mul_i64(t0, t0, t1);
1181
    tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
1182
#else
1183
    tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1184
    tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1185
    tcg_gen_mul_i64(t0, t0, t1);
1186
    tcg_gen_shri_i64(t0, t0, 32);
1187
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1188
#endif
1189
    tcg_temp_free(t0);
1190
    tcg_temp_free(t1);
1191
    if (unlikely(Rc(ctx->opcode) != 0))
1192
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1193
}
1194
/* mulhwu  mulhwu.  */
1195
GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER)
1196
{
1197
    TCGv t0, t1;
1198

    
1199
    t0 = tcg_temp_new(TCG_TYPE_I64);
1200
    t1 = tcg_temp_new(TCG_TYPE_I64);
1201
#if defined(TARGET_PPC64)
1202
    tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1203
    tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1204
    tcg_gen_mul_i64(t0, t0, t1);
1205
    tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
1206
#else
1207
    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1208
    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1209
    tcg_gen_mul_i64(t0, t0, t1);
1210
    tcg_gen_shri_i64(t0, t0, 32);
1211
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1212
#endif
1213
    tcg_temp_free(t0);
1214
    tcg_temp_free(t1);
1215
    if (unlikely(Rc(ctx->opcode) != 0))
1216
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1217
}
1218
/* mullw  mullw. */
1219
GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER)
1220
{
1221
    tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1222
                   cpu_gpr[rB(ctx->opcode)]);
1223
    tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)]);
1224
    if (unlikely(Rc(ctx->opcode) != 0))
1225
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1226
}
1227
/* mullwo  mullwo. */
1228
GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER)
1229
{
1230
    int l1;
1231
    TCGv t0, t1;
1232

    
1233
    t0 = tcg_temp_local_new(TCG_TYPE_I64);
1234
    t1 = tcg_temp_local_new(TCG_TYPE_I64);
1235
    l1 = gen_new_label();
1236
    /* Start with XER OV disabled, the most likely case */
1237
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1238
#if defined(TARGET_PPC64)
1239
    tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1240
    tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1241
#else
1242
    tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1243
    tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1244
#endif
1245
    tcg_gen_mul_i64(t0, t0, t1);
1246
#if defined(TARGET_PPC64)
1247
    tcg_gen_ext32s_i64(cpu_gpr[rD(ctx->opcode)], t0);
1248
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, cpu_gpr[rD(ctx->opcode)], l1);
1249
#else
1250
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1251
    tcg_gen_ext32s_i64(t1, t0);
1252
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
1253
#endif
1254
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
1255
    gen_set_label(l1);
1256
    if (unlikely(Rc(ctx->opcode) != 0))
1257
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1258
}
1259
/* mulli */
1260
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1261
{
1262
    tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1263
                    SIMM(ctx->opcode));
1264
}
1265
#if defined(TARGET_PPC64)
1266
#define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
1267
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)                      \
1268
{                                                                             \
1269
    tcg_gen_helper_1_2(helper_##name, cpu_gpr[rD(ctx->opcode)],               \
1270
                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);   \
1271
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1272
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
1273
}
1274
/* mulhd  mulhd. */
1275
GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00);
1276
/* mulhdu  mulhdu. */
1277
GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02);
1278
/* mulld  mulld. */
1279
GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B)
1280
{
1281
    tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1282
                   cpu_gpr[rB(ctx->opcode)]);
1283
    if (unlikely(Rc(ctx->opcode) != 0))
1284
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1285
}
1286
/* mulldo  mulldo. */
1287
GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17);
1288
#endif
1289

    
1290
/* neg neg. nego nego. */
1291
static always_inline void gen_op_arith_neg (DisasContext *ctx, TCGv ret, TCGv arg1, int ov_check)
1292
{
1293
    int l1 = gen_new_label();
1294
    int l2 = gen_new_label();
1295
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1296
#if defined(TARGET_PPC64)
1297
    if (ctx->sf_mode) {
1298
        tcg_gen_movi_tl(t0, arg1);
1299
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
1300
    } else
1301
#endif
1302
    {
1303
        tcg_gen_ext32s_tl(t0, arg1);
1304
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
1305
    }
1306
    tcg_gen_neg_tl(ret, arg1);
1307
    if (ov_check) {
1308
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1309
    }
1310
    tcg_gen_br(l2);
1311
    gen_set_label(l1);
1312
    tcg_gen_mov_tl(ret, t0);
1313
    if (ov_check) {
1314
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
1315
    }
1316
    gen_set_label(l2);
1317
    tcg_temp_free(t0);
1318
    if (unlikely(Rc(ctx->opcode) != 0))
1319
        gen_set_Rc0(ctx, ret);
1320
}
1321
GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER)
1322
{
1323
    gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
1324
}
1325
GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER)
1326
{
1327
    gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
1328
}
1329

    
1330
/* Common subf function */
1331
static always_inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
1332
                                            int add_ca, int compute_ca, int compute_ov)
1333
{
1334
    TCGv t0, t1;
1335

    
1336
    if ((!compute_ca && !compute_ov) ||
1337
        (GET_TCGV(ret) != GET_TCGV(arg1) && GET_TCGV(ret) != GET_TCGV(arg2)))  {
1338
        t0 = ret;
1339
    } else {
1340
        t0 = tcg_temp_local_new(TCG_TYPE_TL);
1341
    }
1342

    
1343
    if (add_ca) {
1344
        t1 = tcg_temp_local_new(TCG_TYPE_TL);
1345
        tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
1346
        tcg_gen_shri_tl(t1, t1, XER_CA);
1347
    }
1348

    
1349
    if (compute_ca && compute_ov) {
1350
        /* Start with XER CA and OV disabled, the most likely case */
1351
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
1352
    } else if (compute_ca) {
1353
        /* Start with XER CA disabled, the most likely case */
1354
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1355
    } else if (compute_ov) {
1356
        /* Start with XER OV disabled, the most likely case */
1357
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1358
    }
1359

    
1360
    if (add_ca) {
1361
        tcg_gen_not_tl(t0, arg1);
1362
        tcg_gen_add_tl(t0, t0, arg2);
1363
        gen_op_arith_compute_ca(ctx, t0, arg2, 0);
1364
        tcg_gen_add_tl(t0, t0, t1);
1365
        gen_op_arith_compute_ca(ctx, t0, t1, 0);
1366
        tcg_temp_free(t1);
1367
    } else {
1368
        tcg_gen_sub_tl(t0, arg2, arg1);
1369
        if (compute_ca) {
1370
            gen_op_arith_compute_ca(ctx, t0, arg2, 1);
1371
        }
1372
    }
1373
    if (compute_ov) {
1374
        gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
1375
    }
1376

    
1377
    if (unlikely(Rc(ctx->opcode) != 0))
1378
        gen_set_Rc0(ctx, t0);
1379

    
1380
    if (GET_TCGV(t0) != GET_TCGV(ret)) {
1381
        tcg_gen_mov_tl(ret, t0);
1382
        tcg_temp_free(t0);
1383
    }
1384
}
1385
/* Sub functions with Two operands functions */
1386
#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
1387
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER)                  \
1388
{                                                                             \
1389
    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1390
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1391
                      add_ca, compute_ca, compute_ov);                        \
1392
}
1393
/* Sub functions with one operand and one immediate */
1394
#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
1395
                                add_ca, compute_ca, compute_ov)               \
1396
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER)                  \
1397
{                                                                             \
1398
    TCGv t0 = tcg_const_local_tl(const_val);                                  \
1399
    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1400
                      cpu_gpr[rA(ctx->opcode)], t0,                           \
1401
                      add_ca, compute_ca, compute_ov);                        \
1402
    tcg_temp_free(t0);                                                        \
1403
}
1404
/* subf  subf.  subfo  subfo. */
1405
GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
1406
GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
1407
/* subfc  subfc.  subfco  subfco. */
1408
GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
1409
GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
1410
/* subfe  subfe.  subfeo  subfo. */
1411
GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
1412
GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
1413
/* subfme  subfme.  subfmeo  subfmeo.  */
1414
GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
1415
GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
1416
/* subfze  subfze.  subfzeo  subfzeo.*/
1417
GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
1418
GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1419
/* subfic */
1420
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1421
{
1422
    /* Start with XER CA and OV disabled, the most likely case */
1423
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1424
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1425
    TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
1426
    tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
1427
    gen_op_arith_compute_ca(ctx, t0, t1, 1);
1428
    tcg_temp_free(t1);
1429
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
1430
    tcg_temp_free(t0);
1431
}
1432

    
1433
/***                            Integer logical                            ***/
1434
#define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
1435
GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)                          \
1436
{                                                                             \
1437
    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
1438
       cpu_gpr[rB(ctx->opcode)]);                                             \
1439
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1440
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1441
}
1442

    
1443
#define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1444
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1445
{                                                                             \
1446
    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1447
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1448
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1449
}
1450

    
1451
/* and & and. */
1452
GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1453
/* andc & andc. */
1454
GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1455
/* andi. */
1456
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1457
{
1458
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
1459
    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1460
}
1461
/* andis. */
1462
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1463
{
1464
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
1465
    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1466
}
1467
/* cntlzw */
1468
GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER)
1469
{
1470
    tcg_gen_helper_1_1(helper_cntlzw, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1471
    if (unlikely(Rc(ctx->opcode) != 0))
1472
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1473
}
1474
/* eqv & eqv. */
1475
GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1476
/* extsb & extsb. */
1477
GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1478
/* extsh & extsh. */
1479
GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1480
/* nand & nand. */
1481
GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1482
/* nor & nor. */
1483
GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1484
/* or & or. */
1485
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1486
{
1487
    int rs, ra, rb;
1488

    
1489
    rs = rS(ctx->opcode);
1490
    ra = rA(ctx->opcode);
1491
    rb = rB(ctx->opcode);
1492
    /* Optimisation for mr. ri case */
1493
    if (rs != ra || rs != rb) {
1494
        if (rs != rb)
1495
            tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
1496
        else
1497
            tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1498
        if (unlikely(Rc(ctx->opcode) != 0))
1499
            gen_set_Rc0(ctx, cpu_gpr[ra]);
1500
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1501
        gen_set_Rc0(ctx, cpu_gpr[rs]);
1502
#if defined(TARGET_PPC64)
1503
    } else {
1504
        int prio = 0;
1505

    
1506
        switch (rs) {
1507
        case 1:
1508
            /* Set process priority to low */
1509
            prio = 2;
1510
            break;
1511
        case 6:
1512
            /* Set process priority to medium-low */
1513
            prio = 3;
1514
            break;
1515
        case 2:
1516
            /* Set process priority to normal */
1517
            prio = 4;
1518
            break;
1519
#if !defined(CONFIG_USER_ONLY)
1520
        case 31:
1521
            if (ctx->supervisor > 0) {
1522
                /* Set process priority to very low */
1523
                prio = 1;
1524
            }
1525
            break;
1526
        case 5:
1527
            if (ctx->supervisor > 0) {
1528
                /* Set process priority to medium-hight */
1529
                prio = 5;
1530
            }
1531
            break;
1532
        case 3:
1533
            if (ctx->supervisor > 0) {
1534
                /* Set process priority to high */
1535
                prio = 6;
1536
            }
1537
            break;
1538
        case 7:
1539
            if (ctx->supervisor > 1) {
1540
                /* Set process priority to very high */
1541
                prio = 7;
1542
            }
1543
            break;
1544
#endif
1545
        default:
1546
            /* nop */
1547
            break;
1548
        }
1549
        if (prio) {
1550
            TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
1551
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
1552
            tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
1553
            tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
1554
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
1555
            tcg_temp_free(t0);
1556
        }
1557
#endif
1558
    }
1559
}
1560
/* orc & orc. */
1561
GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1562
/* xor & xor. */
1563
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1564
{
1565
    /* Optimisation for "set to zero" case */
1566
    if (rS(ctx->opcode) != rB(ctx->opcode))
1567
        tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1568
    else
1569
        tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1570
    if (unlikely(Rc(ctx->opcode) != 0))
1571
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1572
}
1573
/* ori */
1574
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1575
{
1576
    target_ulong uimm = UIMM(ctx->opcode);
1577

    
1578
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1579
        /* NOP */
1580
        /* XXX: should handle special NOPs for POWER series */
1581
        return;
1582
    }
1583
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1584
}
1585
/* oris */
1586
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1587
{
1588
    target_ulong uimm = UIMM(ctx->opcode);
1589

    
1590
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1591
        /* NOP */
1592
        return;
1593
    }
1594
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1595
}
1596
/* xori */
1597
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1598
{
1599
    target_ulong uimm = UIMM(ctx->opcode);
1600

    
1601
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1602
        /* NOP */
1603
        return;
1604
    }
1605
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1606
}
1607
/* xoris */
1608
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1609
{
1610
    target_ulong uimm = UIMM(ctx->opcode);
1611

    
1612
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1613
        /* NOP */
1614
        return;
1615
    }
1616
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1617
}
1618
/* popcntb : PowerPC 2.03 specification */
1619
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
1620
{
1621
#if defined(TARGET_PPC64)
1622
    if (ctx->sf_mode)
1623
        tcg_gen_helper_1_1(helper_popcntb_64, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1624
    else
1625
#endif
1626
        tcg_gen_helper_1_1(helper_popcntb, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1627
}
1628

    
1629
#if defined(TARGET_PPC64)
1630
/* extsw & extsw. */
1631
GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1632
/* cntlzd */
1633
GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B)
1634
{
1635
    tcg_gen_helper_1_1(helper_cntlzd, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1636
    if (unlikely(Rc(ctx->opcode) != 0))
1637
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1638
}
1639
#endif
1640

    
1641
/***                             Integer rotate                            ***/
1642
/* rlwimi & rlwimi. */
1643
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1644
{
1645
    uint32_t mb, me, sh;
1646

    
1647
    mb = MB(ctx->opcode);
1648
    me = ME(ctx->opcode);
1649
    sh = SH(ctx->opcode);
1650
    if (likely(sh == 0 && mb == 0 && me == 31)) {
1651
        tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1652
    } else {
1653
        TCGv t0, t1;
1654
        target_ulong mask;
1655

    
1656
        t0 = tcg_temp_new(TCG_TYPE_TL);
1657
#if defined(TARGET_PPC64)
1658
        t1 = tcg_temp_new(TCG_TYPE_I32);
1659
        tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1660
        tcg_gen_rotli_i32(t1, t1, sh);
1661
        tcg_gen_extu_i32_i64(t0, t1);
1662
        tcg_temp_free(t1);
1663
#else
1664
        tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1665
#endif
1666
#if defined(TARGET_PPC64)
1667
        mb += 32;
1668
        me += 32;
1669
#endif
1670
        mask = MASK(mb, me);
1671
        t1 = tcg_temp_new(TCG_TYPE_TL);
1672
        tcg_gen_andi_tl(t0, t0, mask);
1673
        tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1674
        tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1675
        tcg_temp_free(t0);
1676
        tcg_temp_free(t1);
1677
    }
1678
    if (unlikely(Rc(ctx->opcode) != 0))
1679
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1680
}
1681
/* rlwinm & rlwinm. */
1682
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1683
{
1684
    uint32_t mb, me, sh;
1685

    
1686
    sh = SH(ctx->opcode);
1687
    mb = MB(ctx->opcode);
1688
    me = ME(ctx->opcode);
1689

    
1690
    if (likely(mb == 0 && me == (31 - sh))) {
1691
        if (likely(sh == 0)) {
1692
            tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1693
        } else {
1694
            TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
1695
            tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1696
            tcg_gen_shli_tl(t0, t0, sh);
1697
            tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1698
            tcg_temp_free(t0);
1699
        }
1700
    } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
1701
        TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
1702
        tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1703
        tcg_gen_shri_tl(t0, t0, mb);
1704
        tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1705
        tcg_temp_free(t0);
1706
    } else {
1707
        TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
1708
#if defined(TARGET_PPC64)
1709
        TCGv t1 = tcg_temp_new(TCG_TYPE_I32);
1710
        tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1711
        tcg_gen_rotli_i32(t1, t1, sh);
1712
        tcg_gen_extu_i32_i64(t0, t1);
1713
        tcg_temp_free(t1);
1714
#else
1715
        tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1716
#endif
1717
#if defined(TARGET_PPC64)
1718
        mb += 32;
1719
        me += 32;
1720
#endif
1721
        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1722
        tcg_temp_free(t0);
1723
    }
1724
    if (unlikely(Rc(ctx->opcode) != 0))
1725
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1726
}
1727
/* rlwnm & rlwnm. */
1728
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1729
{
1730
    uint32_t mb, me;
1731
    TCGv t0;
1732
#if defined(TARGET_PPC64)
1733
    TCGv t1, t2;
1734
#endif
1735

    
1736
    mb = MB(ctx->opcode);
1737
    me = ME(ctx->opcode);
1738
    t0 = tcg_temp_new(TCG_TYPE_TL);
1739
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
1740
#if defined(TARGET_PPC64)
1741
    t1 = tcg_temp_new(TCG_TYPE_I32);
1742
    t2 = tcg_temp_new(TCG_TYPE_I32);
1743
    tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1744
    tcg_gen_trunc_i64_i32(t2, t0);
1745
    tcg_gen_rotl_i32(t1, t1, t2);
1746
    tcg_gen_extu_i32_i64(t0, t1);
1747
    tcg_temp_free(t1);
1748
    tcg_temp_free(t2);
1749
#else
1750
    tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
1751
#endif
1752
    if (unlikely(mb != 0 || me != 31)) {
1753
#if defined(TARGET_PPC64)
1754
        mb += 32;
1755
        me += 32;
1756
#endif
1757
        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1758
    } else {
1759
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1760
    }
1761
    tcg_temp_free(t0);
1762
    if (unlikely(Rc(ctx->opcode) != 0))
1763
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1764
}
1765

    
1766
#if defined(TARGET_PPC64)
1767
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1768
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1769
{                                                                             \
1770
    gen_##name(ctx, 0);                                                       \
1771
}                                                                             \
1772
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1773
             PPC_64B)                                                         \
1774
{                                                                             \
1775
    gen_##name(ctx, 1);                                                       \
1776
}
1777
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1778
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1779
{                                                                             \
1780
    gen_##name(ctx, 0, 0);                                                    \
1781
}                                                                             \
1782
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
1783
             PPC_64B)                                                         \
1784
{                                                                             \
1785
    gen_##name(ctx, 0, 1);                                                    \
1786
}                                                                             \
1787
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1788
             PPC_64B)                                                         \
1789
{                                                                             \
1790
    gen_##name(ctx, 1, 0);                                                    \
1791
}                                                                             \
1792
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
1793
             PPC_64B)                                                         \
1794
{                                                                             \
1795
    gen_##name(ctx, 1, 1);                                                    \
1796
}
1797

    
1798
static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
1799
                                      uint32_t me, uint32_t sh)
1800
{
1801
    if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
1802
        tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
1803
    } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
1804
        tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
1805
    } else {
1806
        TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
1807
        tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1808
        if (likely(mb == 0 && me == 63)) {
1809
            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1810
        } else {
1811
            tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1812
        }
1813
        tcg_temp_free(t0);
1814
    }
1815
    if (unlikely(Rc(ctx->opcode) != 0))
1816
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1817
}
1818
/* rldicl - rldicl. */
1819
static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1820
{
1821
    uint32_t sh, mb;
1822

    
1823
    sh = SH(ctx->opcode) | (shn << 5);
1824
    mb = MB(ctx->opcode) | (mbn << 5);
1825
    gen_rldinm(ctx, mb, 63, sh);
1826
}
1827
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1828
/* rldicr - rldicr. */
1829
static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1830
{
1831
    uint32_t sh, me;
1832

    
1833
    sh = SH(ctx->opcode) | (shn << 5);
1834
    me = MB(ctx->opcode) | (men << 5);
1835
    gen_rldinm(ctx, 0, me, sh);
1836
}
1837
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1838
/* rldic - rldic. */
1839
static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1840
{
1841
    uint32_t sh, mb;
1842

    
1843
    sh = SH(ctx->opcode) | (shn << 5);
1844
    mb = MB(ctx->opcode) | (mbn << 5);
1845
    gen_rldinm(ctx, mb, 63 - sh, sh);
1846
}
1847
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1848

    
1849
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1850
                                     uint32_t me)
1851
{
1852
    TCGv t0;
1853

    
1854
    mb = MB(ctx->opcode);
1855
    me = ME(ctx->opcode);
1856
    t0 = tcg_temp_new(TCG_TYPE_TL);
1857
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
1858
    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1859
    if (unlikely(mb != 0 || me != 63)) {
1860
        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1861
    } else {
1862
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1863
    }
1864
    tcg_temp_free(t0);
1865
    if (unlikely(Rc(ctx->opcode) != 0))
1866
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1867
}
1868

    
1869
/* rldcl - rldcl. */
1870
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1871
{
1872
    uint32_t mb;
1873

    
1874
    mb = MB(ctx->opcode) | (mbn << 5);
1875
    gen_rldnm(ctx, mb, 63);
1876
}
1877
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1878
/* rldcr - rldcr. */
1879
static always_inline void gen_rldcr (DisasContext *ctx, int men)
1880
{
1881
    uint32_t me;
1882

    
1883
    me = MB(ctx->opcode) | (men << 5);
1884
    gen_rldnm(ctx, 0, me);
1885
}
1886
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1887
/* rldimi - rldimi. */
1888
static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1889
{
1890
    uint32_t sh, mb, me;
1891

    
1892
    sh = SH(ctx->opcode) | (shn << 5);
1893
    mb = MB(ctx->opcode) | (mbn << 5);
1894
    me = 63 - sh;
1895
    if (unlikely(sh == 0 && mb == 0)) {
1896
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1897
    } else {
1898
        TCGv t0, t1;
1899
        target_ulong mask;
1900

    
1901
        t0 = tcg_temp_new(TCG_TYPE_TL);
1902
        tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1903
        t1 = tcg_temp_new(TCG_TYPE_TL);
1904
        mask = MASK(mb, me);
1905
        tcg_gen_andi_tl(t0, t0, mask);
1906
        tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1907
        tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1908
        tcg_temp_free(t0);
1909
        tcg_temp_free(t1);
1910
    }
1911
    if (unlikely(Rc(ctx->opcode) != 0))
1912
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1913
}
1914
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1915
#endif
1916

    
1917
/***                             Integer shift                             ***/
1918
/* slw & slw. */
1919
GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER)
1920
{
1921
    TCGv t0;
1922
    int l1, l2;
1923
    l1 = gen_new_label();
1924
    l2 = gen_new_label();
1925

    
1926
    t0 = tcg_temp_local_new(TCG_TYPE_TL);
1927
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
1928
    tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
1929
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1930
    tcg_gen_br(l2);
1931
    gen_set_label(l1);
1932
    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t0);
1933
    tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1934
    gen_set_label(l2);
1935
    tcg_temp_free(t0);
1936
    if (unlikely(Rc(ctx->opcode) != 0))
1937
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1938
}
1939
/* sraw & sraw. */
1940
GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER)
1941
{
1942
    tcg_gen_helper_1_2(helper_sraw, cpu_gpr[rA(ctx->opcode)],
1943
                       cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1944
    if (unlikely(Rc(ctx->opcode) != 0))
1945
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1946
}
1947
/* srawi & srawi. */
1948
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1949
{
1950
    int sh = SH(ctx->opcode);
1951
    if (sh != 0) {
1952
        int l1, l2;
1953
        TCGv t0;
1954
        l1 = gen_new_label();
1955
        l2 = gen_new_label();
1956
        t0 = tcg_temp_local_new(TCG_TYPE_TL);
1957
        tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1958
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
1959
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
1960
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1961
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
1962
        tcg_gen_br(l2);
1963
        gen_set_label(l1);
1964
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1965
        gen_set_label(l2);
1966
        tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1967
        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], t0, sh);
1968
        tcg_temp_free(t0);
1969
    } else {
1970
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1971
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1972
    }
1973
    if (unlikely(Rc(ctx->opcode) != 0))
1974
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1975
}
1976
/* srw & srw. */
1977
GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER)
1978
{
1979
    TCGv t0, t1;
1980
    int l1, l2;
1981
    l1 = gen_new_label();
1982
    l2 = gen_new_label();
1983

    
1984
    t0 = tcg_temp_local_new(TCG_TYPE_TL);
1985
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
1986
    tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
1987
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1988
    tcg_gen_br(l2);
1989
    gen_set_label(l1);
1990
    t1 = tcg_temp_new(TCG_TYPE_TL);
1991
    tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
1992
    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t1, t0);
1993
    tcg_temp_free(t1);
1994
    gen_set_label(l2);
1995
    tcg_temp_free(t0);
1996
    if (unlikely(Rc(ctx->opcode) != 0))
1997
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1998
}
1999
#if defined(TARGET_PPC64)
2000
/* sld & sld. */
2001
GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B)
2002
{
2003
    TCGv t0;
2004
    int l1, l2;
2005
    l1 = gen_new_label();
2006
    l2 = gen_new_label();
2007

    
2008
    t0 = tcg_temp_local_new(TCG_TYPE_TL);
2009
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
2010
    tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
2011
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
2012
    tcg_gen_br(l2);
2013
    gen_set_label(l1);
2014
    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t0);
2015
    gen_set_label(l2);
2016
    tcg_temp_free(t0);
2017
    if (unlikely(Rc(ctx->opcode) != 0))
2018
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2019
}
2020
/* srad & srad. */
2021
GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B)
2022
{
2023
    tcg_gen_helper_1_2(helper_srad, cpu_gpr[rA(ctx->opcode)],
2024
                       cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2025
    if (unlikely(Rc(ctx->opcode) != 0))
2026
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2027
}
2028
/* sradi & sradi. */
2029
static always_inline void gen_sradi (DisasContext *ctx, int n)
2030
{
2031
    int sh = SH(ctx->opcode) + (n << 5);
2032
    if (sh != 0) {
2033
        int l1, l2;
2034
        TCGv t0;
2035
        l1 = gen_new_label();
2036
        l2 = gen_new_label();
2037
        tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
2038
        t0 = tcg_temp_new(TCG_TYPE_TL);
2039
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
2040
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2041
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
2042
        tcg_gen_br(l2);
2043
        gen_set_label(l1);
2044
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
2045
        gen_set_label(l2);
2046
        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
2047
    } else {
2048
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
2049
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
2050
    }
2051
    if (unlikely(Rc(ctx->opcode) != 0))
2052
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2053
}
2054
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
2055
{
2056
    gen_sradi(ctx, 0);
2057
}
2058
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
2059
{
2060
    gen_sradi(ctx, 1);
2061
}
2062
/* srd & srd. */
2063
GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B)
2064
{
2065
    TCGv t0;
2066
    int l1, l2;
2067
    l1 = gen_new_label();
2068
    l2 = gen_new_label();
2069

    
2070
    t0 = tcg_temp_local_new(TCG_TYPE_TL);
2071
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
2072
    tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
2073
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
2074
    tcg_gen_br(l2);
2075
    gen_set_label(l1);
2076
    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t0);
2077
    gen_set_label(l2);
2078
    tcg_temp_free(t0);
2079
    if (unlikely(Rc(ctx->opcode) != 0))
2080
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2081
}
2082
#endif
2083

    
2084
/***                       Floating-Point arithmetic                       ***/
2085
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
2086
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
2087
{                                                                             \
2088
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2089
        GEN_EXCP_NO_FP(ctx);                                                  \
2090
        return;                                                               \
2091
    }                                                                         \
2092
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
2093
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rC(ctx->opcode)]);                     \
2094
    tcg_gen_mov_i64(cpu_FT[2], cpu_fpr[rB(ctx->opcode)]);                     \
2095
    gen_reset_fpstatus();                                                     \
2096
    gen_op_f##op();                                                           \
2097
    if (isfloat) {                                                            \
2098
        gen_op_frsp();                                                        \
2099
    }                                                                         \
2100
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2101
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
2102
}
2103

    
2104
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
2105
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
2106
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
2107

    
2108
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2109
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
2110
{                                                                             \
2111
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2112
        GEN_EXCP_NO_FP(ctx);                                                  \
2113
        return;                                                               \
2114
    }                                                                         \
2115
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
2116
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);                     \
2117
    gen_reset_fpstatus();                                                     \
2118
    gen_op_f##op();                                                           \
2119
    if (isfloat) {                                                            \
2120
        gen_op_frsp();                                                        \
2121
    }                                                                         \
2122
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2123
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
2124
}
2125
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
2126
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2127
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2128

    
2129
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2130
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
2131
{                                                                             \
2132
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2133
        GEN_EXCP_NO_FP(ctx);                                                  \
2134
        return;                                                               \
2135
    }                                                                         \
2136
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
2137
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rC(ctx->opcode)]);                     \
2138
    gen_reset_fpstatus();                                                     \
2139
    gen_op_f##op();                                                           \
2140
    if (isfloat) {                                                            \
2141
        gen_op_frsp();                                                        \
2142
    }                                                                         \
2143
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2144
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
2145
}
2146
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
2147
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2148
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2149

    
2150
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
2151
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
2152
{                                                                             \
2153
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2154
        GEN_EXCP_NO_FP(ctx);                                                  \
2155
        return;                                                               \
2156
    }                                                                         \
2157
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);                     \
2158
    gen_reset_fpstatus();                                                     \
2159
    gen_op_f##name();                                                         \
2160
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2161
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
2162
}
2163

    
2164
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
2165
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
2166
{                                                                             \
2167
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2168
        GEN_EXCP_NO_FP(ctx);                                                  \
2169
        return;                                                               \
2170
    }                                                                         \
2171
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);                     \
2172
    gen_reset_fpstatus();                                                     \
2173
    gen_op_f##name();                                                         \
2174
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2175
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
2176
}
2177

    
2178
/* fadd - fadds */
2179
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
2180
/* fdiv - fdivs */
2181
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
2182
/* fmul - fmuls */
2183
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
2184

    
2185
/* fre */
2186
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
2187

    
2188
/* fres */
2189
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
2190

    
2191
/* frsqrte */
2192
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
2193

    
2194
/* frsqrtes */
2195
static always_inline void gen_op_frsqrtes (void)
2196
{
2197
    gen_op_frsqrte();
2198
    gen_op_frsp();
2199
}
2200
GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
2201

    
2202
/* fsel */
2203
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
2204
/* fsub - fsubs */
2205
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
2206
/* Optional: */
2207
/* fsqrt */
2208
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
2209
{
2210
    if (unlikely(!ctx->fpu_enabled)) {
2211
        GEN_EXCP_NO_FP(ctx);
2212
        return;
2213
    }
2214
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2215
    gen_reset_fpstatus();
2216
    gen_op_fsqrt();
2217
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2218
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
2219
}
2220

    
2221
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
2222
{
2223
    if (unlikely(!ctx->fpu_enabled)) {
2224
        GEN_EXCP_NO_FP(ctx);
2225
        return;
2226
    }
2227
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2228
    gen_reset_fpstatus();
2229
    gen_op_fsqrt();
2230
    gen_op_frsp();
2231
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2232
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
2233
}
2234

    
2235
/***                     Floating-Point multiply-and-add                   ***/
2236
/* fmadd - fmadds */
2237
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
2238
/* fmsub - fmsubs */
2239
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
2240
/* fnmadd - fnmadds */
2241
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
2242
/* fnmsub - fnmsubs */
2243
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
2244

    
2245
/***                     Floating-Point round & convert                    ***/
2246
/* fctiw */
2247
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
2248
/* fctiwz */
2249
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
2250
/* frsp */
2251
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
2252
#if defined(TARGET_PPC64)
2253
/* fcfid */
2254
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
2255
/* fctid */
2256
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
2257
/* fctidz */
2258
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
2259
#endif
2260

    
2261
/* frin */
2262
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
2263
/* friz */
2264
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
2265
/* frip */
2266
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
2267
/* frim */
2268
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
2269

    
2270
/***                         Floating-Point compare                        ***/
2271
/* fcmpo */
2272
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
2273
{
2274
    if (unlikely(!ctx->fpu_enabled)) {
2275
        GEN_EXCP_NO_FP(ctx);
2276
        return;
2277
    }
2278
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
2279
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
2280
    gen_reset_fpstatus();
2281
    tcg_gen_helper_1_0(helper_fcmpo, cpu_crf[crfD(ctx->opcode)]);
2282
    gen_op_float_check_status();
2283
}
2284

    
2285
/* fcmpu */
2286
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
2287
{
2288
    if (unlikely(!ctx->fpu_enabled)) {
2289
        GEN_EXCP_NO_FP(ctx);
2290
        return;
2291
    }
2292
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
2293
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
2294
    gen_reset_fpstatus();
2295
    tcg_gen_helper_1_0(helper_fcmpu, cpu_crf[crfD(ctx->opcode)]);
2296
    gen_op_float_check_status();
2297
}
2298

    
2299
/***                         Floating-point move                           ***/
2300
/* fabs */
2301
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
2302
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
2303

    
2304
/* fmr  - fmr. */
2305
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
2306
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
2307
{
2308
    if (unlikely(!ctx->fpu_enabled)) {
2309
        GEN_EXCP_NO_FP(ctx);
2310
        return;
2311
    }
2312
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2313
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2314
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2315
}
2316

    
2317
/* fnabs */
2318
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
2319
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
2320
/* fneg */
2321
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
2322
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
2323

    
2324
/***                  Floating-Point status & ctrl register                ***/
2325
/* mcrfs */
2326
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
2327
{
2328
    int bfa;
2329

    
2330
    if (unlikely(!ctx->fpu_enabled)) {
2331
        GEN_EXCP_NO_FP(ctx);
2332
        return;
2333
    }
2334
    gen_optimize_fprf();
2335
    bfa = 4 * (7 - crfS(ctx->opcode));
2336
    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
2337
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
2338
    gen_op_fpscr_resetbit(~(0xF << bfa));
2339
}
2340

    
2341
/* mffs */
2342
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
2343
{
2344
    if (unlikely(!ctx->fpu_enabled)) {
2345
        GEN_EXCP_NO_FP(ctx);
2346
        return;
2347
    }
2348
    gen_optimize_fprf();
2349
    gen_reset_fpstatus();
2350
    gen_op_load_fpscr_FT0();
2351
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2352
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2353
}
2354

    
2355
/* mtfsb0 */
2356
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
2357
{
2358
    uint8_t crb;
2359

    
2360
    if (unlikely(!ctx->fpu_enabled)) {
2361
        GEN_EXCP_NO_FP(ctx);
2362
        return;
2363
    }
2364
    crb = 32 - (crbD(ctx->opcode) >> 2);
2365
    gen_optimize_fprf();
2366
    gen_reset_fpstatus();
2367
    if (likely(crb != 30 && crb != 29))
2368
        gen_op_fpscr_resetbit(~(1 << crb));
2369
    if (unlikely(Rc(ctx->opcode) != 0)) {
2370
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2371
    }
2372
}
2373

    
2374
/* mtfsb1 */
2375
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2376
{
2377
    uint8_t crb;
2378

    
2379
    if (unlikely(!ctx->fpu_enabled)) {
2380
        GEN_EXCP_NO_FP(ctx);
2381
        return;
2382
    }
2383
    crb = 32 - (crbD(ctx->opcode) >> 2);
2384
    gen_optimize_fprf();
2385
    gen_reset_fpstatus();
2386
    /* XXX: we pretend we can only do IEEE floating-point computations */
2387
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
2388
        gen_op_fpscr_setbit(crb);
2389
    if (unlikely(Rc(ctx->opcode) != 0)) {
2390
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2391
    }
2392
    /* We can raise a differed exception */
2393
    gen_op_float_check_status();
2394
}
2395

    
2396
/* mtfsf */
2397
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2398
{
2399
    if (unlikely(!ctx->fpu_enabled)) {
2400
        GEN_EXCP_NO_FP(ctx);
2401
        return;
2402
    }
2403
    gen_optimize_fprf();
2404
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2405
    gen_reset_fpstatus();
2406
    gen_op_store_fpscr(FM(ctx->opcode));
2407
    if (unlikely(Rc(ctx->opcode) != 0)) {
2408
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2409
    }
2410
    /* We can raise a differed exception */
2411
    gen_op_float_check_status();
2412
}
2413

    
2414
/* mtfsfi */
2415
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2416
{
2417
    int bf, sh;
2418

    
2419
    if (unlikely(!ctx->fpu_enabled)) {
2420
        GEN_EXCP_NO_FP(ctx);
2421
        return;
2422
    }
2423
    bf = crbD(ctx->opcode) >> 2;
2424
    sh = 7 - bf;
2425
    gen_optimize_fprf();
2426
    tcg_gen_movi_i64(cpu_FT[0], FPIMM(ctx->opcode) << (4 * sh));
2427
    gen_reset_fpstatus();
2428
    gen_op_store_fpscr(1 << sh);
2429
    if (unlikely(Rc(ctx->opcode) != 0)) {
2430
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2431
    }
2432
    /* We can raise a differed exception */
2433
    gen_op_float_check_status();
2434
}
2435

    
2436
/***                           Addressing modes                            ***/
2437
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2438
static always_inline void gen_addr_imm_index (TCGv EA,
2439
                                              DisasContext *ctx,
2440
                                              target_long maskl)
2441
{
2442
    target_long simm = SIMM(ctx->opcode);
2443

    
2444
    simm &= ~maskl;
2445
    if (rA(ctx->opcode) == 0)
2446
        tcg_gen_movi_tl(EA, simm);
2447
    else if (likely(simm != 0))
2448
        tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2449
    else
2450
        tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2451
}
2452

    
2453
static always_inline void gen_addr_reg_index (TCGv EA,
2454
                                              DisasContext *ctx)
2455
{
2456
    if (rA(ctx->opcode) == 0)
2457
        tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2458
    else
2459
        tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2460
}
2461

    
2462
static always_inline void gen_addr_register (TCGv EA,
2463
                                             DisasContext *ctx)
2464
{
2465
    if (rA(ctx->opcode) == 0)
2466
        tcg_gen_movi_tl(EA, 0);
2467
    else
2468
        tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2469
}
2470

    
2471
#if defined(TARGET_PPC64)
2472
#define _GEN_MEM_FUNCS(name, mode)                                            \
2473
    &gen_op_##name##_##mode,                                                  \
2474
    &gen_op_##name##_le_##mode,                                               \
2475
    &gen_op_##name##_64_##mode,                                               \
2476
    &gen_op_##name##_le_64_##mode
2477
#else
2478
#define _GEN_MEM_FUNCS(name, mode)                                            \
2479
    &gen_op_##name##_##mode,                                                  \
2480
    &gen_op_##name##_le_##mode
2481
#endif
2482
#if defined(CONFIG_USER_ONLY)
2483
#if defined(TARGET_PPC64)
2484
#define NB_MEM_FUNCS 4
2485
#else
2486
#define NB_MEM_FUNCS 2
2487
#endif
2488
#define GEN_MEM_FUNCS(name)                                                   \
2489
    _GEN_MEM_FUNCS(name, raw)
2490
#else
2491
#if defined(TARGET_PPC64)
2492
#define NB_MEM_FUNCS 12
2493
#else
2494
#define NB_MEM_FUNCS 6
2495
#endif
2496
#define GEN_MEM_FUNCS(name)                                                   \
2497
    _GEN_MEM_FUNCS(name, user),                                               \
2498
    _GEN_MEM_FUNCS(name, kernel),                                             \
2499
    _GEN_MEM_FUNCS(name, hypv)
2500
#endif
2501

    
2502
/***                             Integer load                              ***/
2503
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
2504
#define OP_LD_TABLE(width)                                                    \
2505
static GenOpFunc *gen_op_l##width[NB_MEM_FUNCS] = {                           \
2506
    GEN_MEM_FUNCS(l##width),                                                  \
2507
};
2508
#define OP_ST_TABLE(width)                                                    \
2509
static GenOpFunc *gen_op_st##width[NB_MEM_FUNCS] = {                          \
2510
    GEN_MEM_FUNCS(st##width),                                                 \
2511
};
2512

    
2513

    
2514
#if defined(TARGET_PPC64)
2515
#define GEN_QEMU_LD_PPC64(width)                                                 \
2516
static always_inline void gen_qemu_ld##width##_ppc64(TCGv t0, TCGv t1, int flags)\
2517
{                                                                                \
2518
    if (likely(flags & 2))                                                       \
2519
        tcg_gen_qemu_ld##width(t0, t1, flags >> 2);                              \
2520
    else {                                                                       \
2521
        TCGv addr = tcg_temp_new(TCG_TYPE_TL);                                   \
2522
        tcg_gen_ext32u_tl(addr, t1);                                             \
2523
        tcg_gen_qemu_ld##width(t0, addr, flags >> 2);                            \
2524
        tcg_temp_free(addr);                                                     \
2525
    }                                                                            \
2526
}
2527
GEN_QEMU_LD_PPC64(8u)
2528
GEN_QEMU_LD_PPC64(8s)
2529
GEN_QEMU_LD_PPC64(16u)
2530
GEN_QEMU_LD_PPC64(16s)
2531
GEN_QEMU_LD_PPC64(32u)
2532
GEN_QEMU_LD_PPC64(32s)
2533
GEN_QEMU_LD_PPC64(64)
2534

    
2535
#define GEN_QEMU_ST_PPC64(width)                                                 \
2536
static always_inline void gen_qemu_st##width##_ppc64(TCGv t0, TCGv t1, int flags)\
2537
{                                                                                \
2538
    if (likely(flags & 2))                                                       \
2539
        tcg_gen_qemu_st##width(t0, t1, flags >> 2);                              \
2540
    else {                                                                       \
2541
        TCGv addr = tcg_temp_new(TCG_TYPE_TL);                                   \
2542
        tcg_gen_ext32u_tl(addr, t1);                                             \
2543
        tcg_gen_qemu_st##width(t0, addr, flags >> 2);                            \
2544
        tcg_temp_free(addr);                                                     \
2545
    }                                                                            \
2546
}
2547
GEN_QEMU_ST_PPC64(8)
2548
GEN_QEMU_ST_PPC64(16)
2549
GEN_QEMU_ST_PPC64(32)
2550
GEN_QEMU_ST_PPC64(64)
2551

    
2552
static always_inline void gen_qemu_ld8u(TCGv arg0, TCGv arg1, int flags)
2553
{
2554
    gen_qemu_ld8u_ppc64(arg0, arg1, flags);
2555
}
2556

    
2557
static always_inline void gen_qemu_ld8s(TCGv arg0, TCGv arg1, int flags)
2558
{
2559
    gen_qemu_ld8s_ppc64(arg0, arg1, flags);
2560
}
2561

    
2562
static always_inline void gen_qemu_ld16u(TCGv arg0, TCGv arg1, int flags)
2563
{
2564
    if (unlikely(flags & 1)) {
2565
        TCGv t0;
2566
        gen_qemu_ld16u_ppc64(arg0, arg1, flags);
2567
        t0 = tcg_temp_new(TCG_TYPE_I32);
2568
        tcg_gen_trunc_tl_i32(t0, arg0);
2569
        tcg_gen_bswap16_i32(t0, t0);
2570
        tcg_gen_extu_i32_tl(arg0, t0);
2571
        tcg_temp_free(t0);
2572
    } else
2573
        gen_qemu_ld16u_ppc64(arg0, arg1, flags);
2574
}
2575

    
2576
static always_inline void gen_qemu_ld16s(TCGv arg0, TCGv arg1, int flags)
2577
{
2578
    if (unlikely(flags & 1)) {
2579
        TCGv t0;
2580
        gen_qemu_ld16u_ppc64(arg0, arg1, flags);
2581
        t0 = tcg_temp_new(TCG_TYPE_I32);
2582
        tcg_gen_trunc_tl_i32(t0, arg0);
2583
        tcg_gen_bswap16_i32(t0, t0);
2584
        tcg_gen_extu_i32_tl(arg0, t0);
2585
        tcg_gen_ext16s_tl(arg0, arg0);
2586
        tcg_temp_free(t0);
2587
    } else
2588
        gen_qemu_ld16s_ppc64(arg0, arg1, flags);
2589
}
2590

    
2591
static always_inline void gen_qemu_ld32u(TCGv arg0, TCGv arg1, int flags)
2592
{
2593
    if (unlikely(flags & 1)) {
2594
        TCGv t0;
2595
        gen_qemu_ld32u_ppc64(arg0, arg1, flags);
2596
        t0 = tcg_temp_new(TCG_TYPE_I32);
2597
        tcg_gen_trunc_tl_i32(t0, arg0);
2598
        tcg_gen_bswap_i32(t0, t0);
2599
        tcg_gen_extu_i32_tl(arg0, t0);
2600
        tcg_temp_free(t0);
2601
    } else
2602
        gen_qemu_ld32u_ppc64(arg0, arg1, flags);
2603
}
2604

    
2605
static always_inline void gen_qemu_ld32s(TCGv arg0, TCGv arg1, int flags)
2606
{
2607
    if (unlikely(flags & 1)) {
2608
        TCGv t0;
2609
        gen_qemu_ld32u_ppc64(arg0, arg1, flags);
2610
        t0 = tcg_temp_new(TCG_TYPE_I32);
2611
        tcg_gen_trunc_tl_i32(t0, arg0);
2612
        tcg_gen_bswap_i32(t0, t0);
2613
        tcg_gen_ext_i32_tl(arg0, t0);
2614
        tcg_temp_free(t0);
2615
    } else
2616
        gen_qemu_ld32s_ppc64(arg0, arg1, flags);
2617
}
2618

    
2619
static always_inline void gen_qemu_ld64(TCGv arg0, TCGv arg1, int flags)
2620
{
2621
    gen_qemu_ld64_ppc64(arg0, arg1, flags);
2622
    if (unlikely(flags & 1))
2623
        tcg_gen_bswap_i64(arg0, arg0);
2624
}
2625

    
2626
static always_inline void gen_qemu_st8(TCGv arg0, TCGv arg1, int flags)
2627
{
2628
    gen_qemu_st8_ppc64(arg0, arg1, flags);
2629
}
2630

    
2631
static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
2632
{
2633
    if (unlikely(flags & 1)) {
2634
        TCGv t0, t1;
2635
        t0 = tcg_temp_new(TCG_TYPE_I32);
2636
        tcg_gen_trunc_tl_i32(t0, arg0);
2637
        tcg_gen_ext16u_i32(t0, t0);
2638
        tcg_gen_bswap16_i32(t0, t0);
2639
        t1 = tcg_temp_new(TCG_TYPE_I64);
2640
        tcg_gen_extu_i32_tl(t1, t0);
2641
        tcg_temp_free(t0);
2642
        gen_qemu_st16_ppc64(t1, arg1, flags);
2643
        tcg_temp_free(t1);
2644
    } else
2645
        gen_qemu_st16_ppc64(arg0, arg1, flags);
2646
}
2647

    
2648
static always_inline void gen_qemu_st32(TCGv arg0, TCGv arg1, int flags)
2649
{
2650
    if (unlikely(flags & 1)) {
2651
        TCGv t0, t1;
2652
        t0 = tcg_temp_new(TCG_TYPE_I32);
2653
        tcg_gen_trunc_tl_i32(t0, arg0);
2654
        tcg_gen_bswap_i32(t0, t0);
2655
        t1 = tcg_temp_new(TCG_TYPE_I64);
2656
        tcg_gen_extu_i32_tl(t1, t0);
2657
        tcg_temp_free(t0);
2658
        gen_qemu_st32_ppc64(t1, arg1, flags);
2659
        tcg_temp_free(t1);
2660
    } else
2661
        gen_qemu_st32_ppc64(arg0, arg1, flags);
2662
}
2663

    
2664
static always_inline void gen_qemu_st64(TCGv arg0, TCGv arg1, int flags)
2665
{
2666
    if (unlikely(flags & 1)) {
2667
        TCGv t0 = tcg_temp_new(TCG_TYPE_I64);
2668
        tcg_gen_bswap_i64(t0, arg0);
2669
        gen_qemu_st64_ppc64(t0, arg1, flags);
2670
        tcg_temp_free(t0);
2671
    } else
2672
        gen_qemu_st64_ppc64(arg0, arg1, flags);
2673
}
2674

    
2675

    
2676
#else /* defined(TARGET_PPC64) */
2677
#define GEN_QEMU_LD_PPC32(width)                                                 \
2678
static always_inline void gen_qemu_ld##width##_ppc32(TCGv arg0, TCGv arg1, int flags)\
2679
{                                                                                \
2680
    tcg_gen_qemu_ld##width(arg0, arg1, flags >> 1);                                  \
2681
}
2682
GEN_QEMU_LD_PPC32(8u)
2683
GEN_QEMU_LD_PPC32(8s)
2684
GEN_QEMU_LD_PPC32(16u)
2685
GEN_QEMU_LD_PPC32(16s)
2686
GEN_QEMU_LD_PPC32(32u)
2687
GEN_QEMU_LD_PPC32(32s)
2688
GEN_QEMU_LD_PPC32(64)
2689

    
2690
#define GEN_QEMU_ST_PPC32(width)                                                 \
2691
static always_inline void gen_qemu_st##width##_ppc32(TCGv arg0, TCGv arg1, int flags)\
2692
{                                                                                \
2693
    tcg_gen_qemu_st##width(arg0, arg1, flags >> 1);                                  \
2694
}
2695
GEN_QEMU_ST_PPC32(8)
2696
GEN_QEMU_ST_PPC32(16)
2697
GEN_QEMU_ST_PPC32(32)
2698
GEN_QEMU_ST_PPC32(64)
2699

    
2700
static always_inline void gen_qemu_ld8u(TCGv arg0, TCGv arg1, int flags)
2701
{
2702
    gen_qemu_ld8u_ppc32(arg0, arg1, flags >> 1);
2703
}
2704

    
2705
static always_inline void gen_qemu_ld8s(TCGv arg0, TCGv arg1, int flags)
2706
{
2707
    gen_qemu_ld8s_ppc32(arg0, arg1, flags >> 1);
2708
}
2709

    
2710
static always_inline void gen_qemu_ld16u(TCGv arg0, TCGv arg1, int flags)
2711
{
2712
    gen_qemu_ld16u_ppc32(arg0, arg1, flags >> 1);
2713
    if (unlikely(flags & 1))
2714
        tcg_gen_bswap16_i32(arg0, arg0);
2715
}
2716

    
2717
static always_inline void gen_qemu_ld16s(TCGv arg0, TCGv arg1, int flags)
2718
{
2719
    if (unlikely(flags & 1)) {
2720
        gen_qemu_ld16u_ppc32(arg0, arg1, flags);
2721
        tcg_gen_bswap16_i32(arg0, arg0);
2722
        tcg_gen_ext16s_i32(arg0, arg0);
2723
    } else
2724
        gen_qemu_ld16s_ppc32(arg0, arg1, flags);
2725
}
2726

    
2727
static always_inline void gen_qemu_ld32u(TCGv arg0, TCGv arg1, int flags)
2728
{
2729
    gen_qemu_ld32u_ppc32(arg0, arg1, flags);
2730
    if (unlikely(flags & 1))
2731
        tcg_gen_bswap_i32(arg0, arg0);
2732
}
2733

    
2734
static always_inline void gen_qemu_ld64(TCGv arg0, TCGv arg1, int flags)
2735
{
2736
    gen_qemu_ld64_ppc32(arg0, arg1, flags);
2737
    if (unlikely(flags & 1))
2738
        tcg_gen_bswap_i64(arg0, arg0);
2739
}
2740

    
2741
static always_inline void gen_qemu_st8(TCGv arg0, TCGv arg1, int flags)
2742
{
2743
    gen_qemu_st8_ppc32(arg0, arg1, flags);
2744
}
2745

    
2746
static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
2747
{
2748
    if (unlikely(flags & 1)) {
2749
        TCGv temp = tcg_temp_new(TCG_TYPE_I32);
2750
        tcg_gen_ext16u_i32(temp, arg0);
2751
        tcg_gen_bswap16_i32(temp, temp);
2752
        gen_qemu_st16_ppc32(temp, arg1, flags);
2753
        tcg_temp_free(temp);
2754
    } else
2755
        gen_qemu_st16_ppc32(arg0, arg1, flags);
2756
}
2757

    
2758
static always_inline void gen_qemu_st32(TCGv arg0, TCGv arg1, int flags)
2759
{
2760
    if (unlikely(flags & 1)) {
2761
        TCGv temp = tcg_temp_new(TCG_TYPE_I32);
2762
        tcg_gen_bswap_i32(temp, arg0);
2763
        gen_qemu_st32_ppc32(temp, arg1, flags);
2764
        tcg_temp_free(temp);
2765
    } else
2766
        gen_qemu_st32_ppc32(arg0, arg1, flags);
2767
}
2768

    
2769
static always_inline void gen_qemu_st64(TCGv arg0, TCGv arg1, int flags)
2770
{
2771
    if (unlikely(flags & 1)) {
2772
        TCGv temp = tcg_temp_new(TCG_TYPE_I64);
2773
        tcg_gen_bswap_i64(temp, arg0);
2774
        gen_qemu_st64_ppc32(temp, arg1, flags);
2775
        tcg_temp_free(temp);
2776
    } else
2777
        gen_qemu_st64_ppc32(arg0, arg1, flags);
2778
}
2779

    
2780
#endif
2781

    
2782
#define GEN_LD(width, opc, type)                                              \
2783
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2784
{                                                                             \
2785
    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
2786
    gen_addr_imm_index(EA, ctx, 0);                                           \
2787
    gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
2788
    tcg_temp_free(EA);                                                        \
2789
}
2790

    
2791
#define GEN_LDU(width, opc, type)                                             \
2792
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2793
{                                                                             \
2794
    TCGv EA;                                                                  \
2795
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2796
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2797
        GEN_EXCP_INVAL(ctx);                                                  \
2798
        return;                                                               \
2799
    }                                                                         \
2800
    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
2801
    if (type == PPC_64B)                                                      \
2802
        gen_addr_imm_index(EA, ctx, 0x03);                                    \
2803
    else                                                                      \
2804
        gen_addr_imm_index(EA, ctx, 0);                                       \
2805
    gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
2806
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2807
    tcg_temp_free(EA);                                                        \
2808
}
2809

    
2810
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2811
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2812
{                                                                             \
2813
    TCGv EA;                                                                  \
2814
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2815
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2816
        GEN_EXCP_INVAL(ctx);                                                  \
2817
        return;                                                               \
2818
    }                                                                         \
2819
    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
2820
    gen_addr_reg_index(EA, ctx);                                              \
2821
    gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
2822
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2823
    tcg_temp_free(EA);                                                        \
2824
}
2825

    
2826
#define GEN_LDX(width, opc2, opc3, type)                                      \
2827
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2828
{                                                                             \
2829
    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
2830
    gen_addr_reg_index(EA, ctx);                                              \
2831
    gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
2832
    tcg_temp_free(EA);                                                        \
2833
}
2834

    
2835
#define GEN_LDS(width, op, type)                                              \
2836
GEN_LD(width, op | 0x20, type);                                               \
2837
GEN_LDU(width, op | 0x21, type);                                              \
2838
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2839
GEN_LDX(width, 0x17, op | 0x00, type)
2840

    
2841
/* lbz lbzu lbzux lbzx */
2842
GEN_LDS(8u, 0x02, PPC_INTEGER);
2843
/* lha lhau lhaux lhax */
2844
GEN_LDS(16s, 0x0A, PPC_INTEGER);
2845
/* lhz lhzu lhzux lhzx */
2846
GEN_LDS(16u, 0x08, PPC_INTEGER);
2847
/* lwz lwzu lwzux lwzx */
2848
GEN_LDS(32u, 0x00, PPC_INTEGER);
2849
#if defined(TARGET_PPC64)
2850
/* lwaux */
2851
GEN_LDUX(32s, 0x15, 0x0B, PPC_64B);
2852
/* lwax */
2853
GEN_LDX(32s, 0x15, 0x0A, PPC_64B);
2854
/* ldux */
2855
GEN_LDUX(64, 0x15, 0x01, PPC_64B);
2856
/* ldx */
2857
GEN_LDX(64, 0x15, 0x00, PPC_64B);
2858
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2859
{
2860
    TCGv EA;
2861
    if (Rc(ctx->opcode)) {
2862
        if (unlikely(rA(ctx->opcode) == 0 ||
2863
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2864
            GEN_EXCP_INVAL(ctx);
2865
            return;
2866
        }
2867
    }
2868
    EA = tcg_temp_new(TCG_TYPE_TL);
2869
    gen_addr_imm_index(EA, ctx, 0x03);
2870
    if (ctx->opcode & 0x02) {
2871
        /* lwa (lwau is undefined) */
2872
        gen_qemu_ld32s(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);
2873
    } else {
2874
        /* ld - ldu */
2875
        gen_qemu_ld64(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);
2876
    }
2877
    if (Rc(ctx->opcode))
2878
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2879
    tcg_temp_free(EA);
2880
}
2881
/* lq */
2882
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2883
{
2884
#if defined(CONFIG_USER_ONLY)
2885
    GEN_EXCP_PRIVOPC(ctx);
2886
#else
2887
    int ra, rd;
2888
    TCGv EA;
2889

    
2890
    /* Restore CPU state */
2891
    if (unlikely(ctx->supervisor == 0)) {
2892
        GEN_EXCP_PRIVOPC(ctx);
2893
        return;
2894
    }
2895
    ra = rA(ctx->opcode);
2896
    rd = rD(ctx->opcode);
2897
    if (unlikely((rd & 1) || rd == ra)) {
2898
        GEN_EXCP_INVAL(ctx);
2899
        return;
2900
    }
2901
    if (unlikely(ctx->mem_idx & 1)) {
2902
        /* Little-endian mode is not handled */
2903
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2904
        return;
2905
    }
2906
    EA = tcg_temp_new(TCG_TYPE_TL);
2907
    gen_addr_imm_index(EA, ctx, 0x0F);
2908
    gen_qemu_ld64(cpu_gpr[rd], EA, ctx->mem_idx);
2909
    tcg_gen_addi_tl(EA, EA, 8);
2910
    gen_qemu_ld64(cpu_gpr[rd+1], EA, ctx->mem_idx);
2911
    tcg_temp_free(EA);
2912
#endif
2913
}
2914
#endif
2915

    
2916
/***                              Integer store                            ***/
2917
#define GEN_ST(width, opc, type)                                              \
2918
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2919
{                                                                             \
2920
    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
2921
    gen_addr_imm_index(EA, ctx, 0);                                           \
2922
    gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);       \
2923
    tcg_temp_free(EA);                                                        \
2924
}
2925

    
2926
#define GEN_STU(width, opc, type)                                             \
2927
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2928
{                                                                             \
2929
    TCGv EA;                                                                  \
2930
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2931
        GEN_EXCP_INVAL(ctx);                                                  \
2932
        return;                                                               \
2933
    }                                                                         \
2934
    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
2935
    if (type == PPC_64B)                                                      \
2936
        gen_addr_imm_index(EA, ctx, 0x03);                                    \
2937
    else                                                                      \
2938
        gen_addr_imm_index(EA, ctx, 0);                                       \
2939
    gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);           \
2940
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2941
    tcg_temp_free(EA);                                                        \
2942
}
2943

    
2944
#define GEN_STUX(width, opc2, opc3, type)                                     \
2945
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2946
{                                                                             \
2947
    TCGv EA;                                                                  \
2948
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2949
        GEN_EXCP_INVAL(ctx);                                                  \
2950
        return;                                                               \
2951
    }                                                                         \
2952
    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
2953
    gen_addr_reg_index(EA, ctx);                                              \
2954
    gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);           \
2955
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2956
    tcg_temp_free(EA);                                                        \
2957
}
2958

    
2959
#define GEN_STX(width, opc2, opc3, type)                                      \
2960
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2961
{                                                                             \
2962
    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
2963
    gen_addr_reg_index(EA, ctx);                                              \
2964
    gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);           \
2965
    tcg_temp_free(EA);                                                        \
2966
}
2967

    
2968
#define GEN_STS(width, op, type)                                              \
2969
GEN_ST(width, op | 0x20, type);                                               \
2970
GEN_STU(width, op | 0x21, type);                                              \
2971
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2972
GEN_STX(width, 0x17, op | 0x00, type)
2973

    
2974
/* stb stbu stbux stbx */
2975
GEN_STS(8, 0x06, PPC_INTEGER);
2976
/* sth sthu sthux sthx */
2977
GEN_STS(16, 0x0C, PPC_INTEGER);
2978
/* stw stwu stwux stwx */
2979
GEN_STS(32, 0x04, PPC_INTEGER);
2980
#if defined(TARGET_PPC64)
2981
GEN_STUX(64, 0x15, 0x05, PPC_64B);
2982
GEN_STX(64, 0x15, 0x04, PPC_64B);
2983
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2984
{
2985
    int rs;
2986
    TCGv EA;
2987

    
2988
    rs = rS(ctx->opcode);
2989
    if ((ctx->opcode & 0x3) == 0x2) {
2990
#if defined(CONFIG_USER_ONLY)
2991
        GEN_EXCP_PRIVOPC(ctx);
2992
#else
2993
        /* stq */
2994
        if (unlikely(ctx->supervisor == 0)) {
2995
            GEN_EXCP_PRIVOPC(ctx);
2996
            return;
2997
        }
2998
        if (unlikely(rs & 1)) {
2999
            GEN_EXCP_INVAL(ctx);
3000
            return;
3001
        }
3002
        if (unlikely(ctx->mem_idx & 1)) {
3003
            /* Little-endian mode is not handled */
3004
            GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
3005
            return;
3006
        }
3007
        EA = tcg_temp_new(TCG_TYPE_TL);
3008
        gen_addr_imm_index(EA, ctx, 0x03);
3009
        gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
3010
        tcg_gen_addi_tl(EA, EA, 8);
3011
        gen_qemu_st64(cpu_gpr[rs+1], EA, ctx->mem_idx);
3012
        tcg_temp_free(EA);
3013
#endif
3014
    } else {
3015
        /* std / stdu */
3016
        if (Rc(ctx->opcode)) {
3017
            if (unlikely(rA(ctx->opcode) == 0)) {
3018
                GEN_EXCP_INVAL(ctx);
3019
                return;
3020
            }
3021
        }
3022
        EA = tcg_temp_new(TCG_TYPE_TL);
3023
        gen_addr_imm_index(EA, ctx, 0x03);
3024
        gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
3025
        if (Rc(ctx->opcode))
3026
            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
3027
        tcg_temp_free(EA);
3028
    }
3029
}
3030
#endif
3031
/***                Integer load and store with byte reverse               ***/
3032
/* lhbrx */
3033
void always_inline gen_qemu_ld16ur(TCGv t0, TCGv t1, int flags)
3034
{
3035
    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
3036
    gen_qemu_ld16u(temp, t1, flags);
3037
    tcg_gen_bswap16_i32(temp, temp);
3038
    tcg_gen_extu_i32_tl(t0, temp);
3039
    tcg_temp_free(temp);
3040
}
3041
GEN_LDX(16ur, 0x16, 0x18, PPC_INTEGER);
3042

    
3043
/* lwbrx */
3044
void always_inline gen_qemu_ld32ur(TCGv t0, TCGv t1, int flags)
3045
{
3046
    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
3047
    gen_qemu_ld32u(temp, t1, flags);
3048
    tcg_gen_bswap_i32(temp, temp);
3049
    tcg_gen_extu_i32_tl(t0, temp);
3050
    tcg_temp_free(temp);
3051
}
3052
GEN_LDX(32ur, 0x16, 0x10, PPC_INTEGER);
3053

    
3054
/* sthbrx */
3055
void always_inline gen_qemu_st16r(TCGv t0, TCGv t1, int flags)
3056
{
3057
    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
3058
    tcg_gen_trunc_tl_i32(temp, t0);
3059
    tcg_gen_ext16u_i32(temp, temp);
3060
    tcg_gen_bswap16_i32(temp, temp);
3061
    gen_qemu_st16(temp, t1, flags);
3062
    tcg_temp_free(temp);
3063
}
3064
GEN_STX(16r, 0x16, 0x1C, PPC_INTEGER);
3065

    
3066
/* stwbrx */
3067
void always_inline gen_qemu_st32r(TCGv t0, TCGv t1, int flags)
3068
{
3069
    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
3070
    tcg_gen_trunc_tl_i32(temp, t0);
3071
    tcg_gen_bswap_i32(temp, temp);
3072
    gen_qemu_st32(temp, t1, flags);
3073
    tcg_temp_free(temp);
3074
}
3075
GEN_STX(32r, 0x16, 0x14, PPC_INTEGER);
3076

    
3077
/***                    Integer load and store multiple                    ***/
3078
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
3079
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
3080
    GEN_MEM_FUNCS(lmw),
3081
};
3082
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
3083
    GEN_MEM_FUNCS(stmw),
3084
};
3085

    
3086
/* lmw */
3087
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
3088
{
3089
    /* NIP cannot be restored if the memory exception comes from an helper */
3090
    gen_update_nip(ctx, ctx->nip - 4);
3091
    gen_addr_imm_index(cpu_T[0], ctx, 0);
3092
    op_ldstm(lmw, rD(ctx->opcode));
3093
}
3094

    
3095
/* stmw */
3096
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
3097
{
3098
    /* NIP cannot be restored if the memory exception comes from an helper */
3099
    gen_update_nip(ctx, ctx->nip - 4);
3100
    gen_addr_imm_index(cpu_T[0], ctx, 0);
3101
    op_ldstm(stmw, rS(ctx->opcode));
3102
}
3103

    
3104
/***                    Integer load and store strings                     ***/
3105
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
3106
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
3107
/* string load & stores are by definition endian-safe */
3108
#define gen_op_lswi_le_raw       gen_op_lswi_raw
3109
#define gen_op_lswi_le_user      gen_op_lswi_user
3110
#define gen_op_lswi_le_kernel    gen_op_lswi_kernel
3111
#define gen_op_lswi_le_hypv      gen_op_lswi_hypv
3112
#define gen_op_lswi_le_64_raw    gen_op_lswi_raw
3113
#define gen_op_lswi_le_64_user   gen_op_lswi_user
3114
#define gen_op_lswi_le_64_kernel gen_op_lswi_kernel
3115
#define gen_op_lswi_le_64_hypv   gen_op_lswi_hypv
3116
static GenOpFunc1 *gen_op_lswi[NB_MEM_FUNCS] = {
3117
    GEN_MEM_FUNCS(lswi),
3118
};
3119
#define gen_op_lswx_le_raw       gen_op_lswx_raw
3120
#define gen_op_lswx_le_user      gen_op_lswx_user
3121
#define gen_op_lswx_le_kernel    gen_op_lswx_kernel
3122
#define gen_op_lswx_le_hypv      gen_op_lswx_hypv
3123
#define gen_op_lswx_le_64_raw    gen_op_lswx_raw
3124
#define gen_op_lswx_le_64_user   gen_op_lswx_user
3125
#define gen_op_lswx_le_64_kernel gen_op_lswx_kernel
3126
#define gen_op_lswx_le_64_hypv   gen_op_lswx_hypv
3127
static GenOpFunc3 *gen_op_lswx[NB_MEM_FUNCS] = {
3128
    GEN_MEM_FUNCS(lswx),
3129
};
3130
#define gen_op_stsw_le_raw       gen_op_stsw_raw
3131
#define gen_op_stsw_le_user      gen_op_stsw_user
3132
#define gen_op_stsw_le_kernel    gen_op_stsw_kernel
3133
#define gen_op_stsw_le_hypv      gen_op_stsw_hypv
3134
#define gen_op_stsw_le_64_raw    gen_op_stsw_raw
3135
#define gen_op_stsw_le_64_user   gen_op_stsw_user
3136
#define gen_op_stsw_le_64_kernel gen_op_stsw_kernel
3137
#define gen_op_stsw_le_64_hypv   gen_op_stsw_hypv
3138
static GenOpFunc1 *gen_op_stsw[NB_MEM_FUNCS] = {
3139
    GEN_MEM_FUNCS(stsw),
3140
};
3141

    
3142
/* lswi */
3143
/* PowerPC32 specification says we must generate an exception if
3144
 * rA is in the range of registers to be loaded.
3145
 * In an other hand, IBM says this is valid, but rA won't be loaded.
3146
 * For now, I'll follow the spec...
3147
 */
3148
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
3149
{
3150
    int nb = NB(ctx->opcode);
3151
    int start = rD(ctx->opcode);
3152
    int ra = rA(ctx->opcode);
3153
    int nr;
3154

    
3155
    if (nb == 0)
3156
        nb = 32;
3157
    nr = nb / 4;
3158
    if (unlikely(((start + nr) > 32  &&
3159
                  start <= ra && (start + nr - 32) > ra) ||
3160
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
3161
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3162
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
3163
        return;
3164
    }
3165
    /* NIP cannot be restored if the memory exception comes from an helper */
3166
    gen_update_nip(ctx, ctx->nip - 4);
3167
    gen_addr_register(cpu_T[0], ctx);
3168
    tcg_gen_movi_tl(cpu_T[1], nb);
3169
    op_ldsts(lswi, start);
3170
}
3171

    
3172
/* lswx */
3173
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
3174
{
3175
    int ra = rA(ctx->opcode);
3176
    int rb = rB(ctx->opcode);
3177

    
3178
    /* NIP cannot be restored if the memory exception comes from an helper */
3179
    gen_update_nip(ctx, ctx->nip - 4);
3180
    gen_addr_reg_index(cpu_T[0], ctx);
3181
    if (ra == 0) {
3182
        ra = rb;
3183
    }
3184
    tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
3185
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
3186
}
3187

    
3188
/* stswi */
3189
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
3190
{
3191
    int nb = NB(ctx->opcode);
3192

    
3193
    /* NIP cannot be restored if the memory exception comes from an helper */
3194
    gen_update_nip(ctx, ctx->nip - 4);
3195
    gen_addr_register(cpu_T[0], ctx);
3196
    if (nb == 0)
3197
        nb = 32;
3198
    tcg_gen_movi_tl(cpu_T[1], nb);
3199
    op_ldsts(stsw, rS(ctx->opcode));
3200
}
3201

    
3202
/* stswx */
3203
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
3204
{
3205
    /* NIP cannot be restored if the memory exception comes from an helper */
3206
    gen_update_nip(ctx, ctx->nip - 4);
3207
    gen_addr_reg_index(cpu_T[0], ctx);
3208
    tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
3209
    op_ldsts(stsw, rS(ctx->opcode));
3210
}
3211

    
3212
/***                        Memory synchronisation                         ***/
3213
/* eieio */
3214
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
3215
{
3216
}
3217

    
3218
/* isync */
3219
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
3220
{
3221
    GEN_STOP(ctx);
3222
}
3223

    
3224
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
3225
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
3226
static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
3227
    GEN_MEM_FUNCS(lwarx),
3228
};
3229
static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
3230
    GEN_MEM_FUNCS(stwcx),
3231
};
3232

    
3233
/* lwarx */
3234
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
3235
{
3236
    /* NIP cannot be restored if the memory exception comes from an helper */
3237
    gen_update_nip(ctx, ctx->nip - 4);
3238
    gen_addr_reg_index(cpu_T[0], ctx);
3239
    op_lwarx();
3240
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
3241
}
3242

    
3243
/* stwcx. */
3244
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
3245
{
3246
    /* NIP cannot be restored if the memory exception comes from an helper */
3247
    gen_update_nip(ctx, ctx->nip - 4);
3248
    gen_addr_reg_index(cpu_T[0], ctx);
3249
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
3250
    op_stwcx();
3251
}
3252

    
3253
#if defined(TARGET_PPC64)
3254
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
3255
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
3256
static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
3257
    GEN_MEM_FUNCS(ldarx),
3258
};
3259
static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
3260
    GEN_MEM_FUNCS(stdcx),
3261
};
3262

    
3263
/* ldarx */
3264
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
3265
{
3266
    /* NIP cannot be restored if the memory exception comes from an helper */
3267
    gen_update_nip(ctx, ctx->nip - 4);
3268
    gen_addr_reg_index(cpu_T[0], ctx);
3269
    op_ldarx();
3270
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
3271
}
3272

    
3273
/* stdcx. */
3274
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
3275
{
3276
    /* NIP cannot be restored if the memory exception comes from an helper */
3277
    gen_update_nip(ctx, ctx->nip - 4);
3278
    gen_addr_reg_index(cpu_T[0], ctx);
3279
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
3280
    op_stdcx();
3281
}
3282
#endif /* defined(TARGET_PPC64) */
3283

    
3284
/* sync */
3285
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
3286
{
3287
}
3288

    
3289
/* wait */
3290
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
3291
{
3292
    /* Stop translation, as the CPU is supposed to sleep from now */
3293
    gen_op_wait();
3294
    GEN_EXCP(ctx, EXCP_HLT, 1);
3295
}
3296

    
3297
/***                         Floating-point load                           ***/
3298
#define GEN_LDF(width, opc, type)                                             \
3299
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
3300
{                                                                             \
3301
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3302
        GEN_EXCP_NO_FP(ctx);                                                  \
3303
        return;                                                               \
3304
    }                                                                         \
3305
    gen_addr_imm_index(cpu_T[0], ctx, 0);                                     \
3306
    op_ldst(l##width);                                                        \
3307
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
3308
}
3309

    
3310
#define GEN_LDUF(width, opc, type)                                            \
3311
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
3312
{                                                                             \
3313
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3314
        GEN_EXCP_NO_FP(ctx);                                                  \
3315
        return;                                                               \
3316
    }                                                                         \
3317
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3318
        GEN_EXCP_INVAL(ctx);                                                  \
3319
        return;                                                               \
3320
    }                                                                         \
3321
    gen_addr_imm_index(cpu_T[0], ctx, 0);                                     \
3322
    op_ldst(l##width);                                                        \
3323
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
3324
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
3325
}
3326

    
3327
#define GEN_LDUXF(width, opc, type)                                           \
3328
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
3329
{                                                                             \
3330
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3331
        GEN_EXCP_NO_FP(ctx);                                                  \
3332
        return;                                                               \
3333
    }                                                                         \
3334
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3335
        GEN_EXCP_INVAL(ctx);                                                  \
3336
        return;                                                               \
3337
    }                                                                         \
3338
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
3339
    op_ldst(l##width);                                                        \
3340
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
3341
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
3342
}
3343

    
3344
#define GEN_LDXF(width, opc2, opc3, type)                                     \
3345
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
3346
{                                                                             \
3347
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3348
        GEN_EXCP_NO_FP(ctx);                                                  \
3349
        return;                                                               \
3350
    }                                                                         \
3351
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
3352
    op_ldst(l##width);                                                        \
3353
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
3354
}
3355

    
3356
#define GEN_LDFS(width, op, type)                                             \
3357
OP_LD_TABLE(width);                                                           \
3358
GEN_LDF(width, op | 0x20, type);                                              \
3359
GEN_LDUF(width, op | 0x21, type);                                             \
3360
GEN_LDUXF(width, op | 0x01, type);                                            \
3361
GEN_LDXF(width, 0x17, op | 0x00, type)
3362

    
3363
/* lfd lfdu lfdux lfdx */
3364
GEN_LDFS(fd, 0x12, PPC_FLOAT);
3365
/* lfs lfsu lfsux lfsx */
3366
GEN_LDFS(fs, 0x10, PPC_FLOAT);
3367

    
3368
/***                         Floating-point store                          ***/
3369
#define GEN_STF(width, opc, type)                                             \
3370
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
3371
{                                                                             \
3372
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3373
        GEN_EXCP_NO_FP(ctx);                                                  \
3374
        return;                                                               \
3375
    }                                                                         \
3376
    gen_addr_imm_index(cpu_T[0], ctx, 0);                                     \
3377
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
3378
    op_ldst(st##width);                                                       \
3379
}
3380

    
3381
#define GEN_STUF(width, opc, type)                                            \
3382
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
3383
{                                                                             \
3384
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3385
        GEN_EXCP_NO_FP(ctx);                                                  \
3386
        return;                                                               \
3387
    }                                                                         \
3388
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3389
        GEN_EXCP_INVAL(ctx);                                                  \
3390
        return;                                                               \
3391
    }                                                                         \
3392
    gen_addr_imm_index(cpu_T[0], ctx, 0);                                     \
3393
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
3394
    op_ldst(st##width);                                                       \
3395
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
3396
}
3397

    
3398
#define GEN_STUXF(width, opc, type)                                           \
3399
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
3400
{                                                                             \
3401
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3402
        GEN_EXCP_NO_FP(ctx);                                                  \
3403
        return;                                                               \
3404
    }                                                                         \
3405
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3406
        GEN_EXCP_INVAL(ctx);                                                  \
3407
        return;                                                               \
3408
    }                                                                         \
3409
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
3410
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
3411
    op_ldst(st##width);                                                       \
3412
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
3413
}
3414

    
3415
#define GEN_STXF(width, opc2, opc3, type)                                     \
3416
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
3417
{                                                                             \
3418
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3419
        GEN_EXCP_NO_FP(ctx);                                                  \
3420
        return;                                                               \
3421
    }                                                                         \
3422
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
3423
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
3424
    op_ldst(st##width);                                                       \
3425
}
3426

    
3427
#define GEN_STFS(width, op, type)                                             \
3428
OP_ST_TABLE(width);                                                           \
3429
GEN_STF(width, op | 0x20, type);                                              \
3430
GEN_STUF(width, op | 0x21, type);                                             \
3431
GEN_STUXF(width, op | 0x01, type);                                            \
3432
GEN_STXF(width, 0x17, op | 0x00, type)
3433

    
3434
/* stfd stfdu stfdux stfdx */
3435
GEN_STFS(fd, 0x16, PPC_FLOAT);
3436
/* stfs stfsu stfsux stfsx */
3437
GEN_STFS(fs, 0x14, PPC_FLOAT);
3438

    
3439
/* Optional: */
3440
/* stfiwx */
3441
OP_ST_TABLE(fiw);
3442
GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
3443

    
3444
/***                                Branch                                 ***/
3445
static always_inline void gen_goto_tb (DisasContext *ctx, int n,
3446
                                       target_ulong dest)
3447
{
3448
    TranslationBlock *tb;
3449
    tb = ctx->tb;
3450
#if defined(TARGET_PPC64)
3451
    if (!ctx->sf_mode)
3452
        dest = (uint32_t) dest;
3453
#endif
3454
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3455
        likely(!ctx->singlestep_enabled)) {
3456
        tcg_gen_goto_tb(n);
3457
        tcg_gen_movi_tl(cpu_nip, dest & ~3);
3458
        tcg_gen_exit_tb((long)tb + n);
3459
    } else {
3460
        tcg_gen_movi_tl(cpu_nip, dest & ~3);
3461
        if (unlikely(ctx->singlestep_enabled)) {
3462
            if ((ctx->singlestep_enabled &
3463
                (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
3464
                ctx->exception == POWERPC_EXCP_BRANCH) {
3465
                target_ulong tmp = ctx->nip;
3466
                ctx->nip = dest;
3467
                GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
3468
                ctx->nip = tmp;
3469
            }
3470
            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3471
                gen_update_nip(ctx, dest);
3472
                gen_op_debug();
3473
            }
3474
        }
3475
        tcg_gen_exit_tb(0);
3476
    }
3477
}
3478

    
3479
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
3480
{
3481
#if defined(TARGET_PPC64)
3482
    if (ctx->sf_mode == 0)
3483
        tcg_gen_movi_tl(cpu_lr, (uint32_t)nip);
3484
    else
3485
#endif
3486
        tcg_gen_movi_tl(cpu_lr, nip);
3487
}
3488

    
3489
/* b ba bl bla */
3490
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3491
{
3492
    target_ulong li, target;
3493

    
3494
    ctx->exception = POWERPC_EXCP_BRANCH;
3495
    /* sign extend LI */
3496
#if defined(TARGET_PPC64)
3497
    if (ctx->sf_mode)
3498
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
3499
    else
3500
#endif
3501
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
3502
    if (likely(AA(ctx->opcode) == 0))
3503
        target = ctx->nip + li - 4;
3504
    else
3505
        target = li;
3506
    if (LK(ctx->opcode))
3507
        gen_setlr(ctx, ctx->nip);
3508
    gen_goto_tb(ctx, 0, target);
3509
}
3510

    
3511
#define BCOND_IM  0
3512
#define BCOND_LR  1
3513
#define BCOND_CTR 2
3514

    
3515
static always_inline void gen_bcond (DisasContext *ctx, int type)
3516
{
3517
    uint32_t bo = BO(ctx->opcode);
3518
    int l1 = gen_new_label();
3519
    TCGv target;
3520

    
3521
    ctx->exception = POWERPC_EXCP_BRANCH;
3522
    if (type == BCOND_LR || type == BCOND_CTR) {
3523
        target = tcg_temp_local_new(TCG_TYPE_TL);
3524
        if (type == BCOND_CTR)
3525
            tcg_gen_mov_tl(target, cpu_ctr);
3526
        else
3527
            tcg_gen_mov_tl(target, cpu_lr);
3528
    }
3529
    if (LK(ctx->opcode))
3530
        gen_setlr(ctx, ctx->nip);
3531
    l1 = gen_new_label();
3532
    if ((bo & 0x4) == 0) {
3533
        /* Decrement and test CTR */
3534
        TCGv temp = tcg_temp_new(TCG_TYPE_TL);
3535
        if (unlikely(type == BCOND_CTR)) {
3536
            GEN_EXCP_INVAL(ctx);
3537
            return;
3538
        }
3539
        tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3540
#if defined(TARGET_PPC64)
3541
        if (!ctx->sf_mode)
3542
            tcg_gen_ext32u_tl(temp, cpu_ctr);
3543
        else
3544
#endif
3545
            tcg_gen_mov_tl(temp, cpu_ctr);
3546
        if (bo & 0x2) {
3547
            tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3548
        } else {
3549
            tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3550
        }
3551
    }
3552
    if ((bo & 0x10) == 0) {
3553
        /* Test CR */
3554
        uint32_t bi = BI(ctx->opcode);
3555
        uint32_t mask = 1 << (3 - (bi & 0x03));
3556
        TCGv temp = tcg_temp_new(TCG_TYPE_I32);
3557

    
3558
        if (bo & 0x8) {
3559
            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3560
            tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
3561
        } else {
3562
            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3563
            tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
3564
        }
3565
    }
3566
    if (type == BCOND_IM) {
3567
        target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
3568
        if (likely(AA(ctx->opcode) == 0)) {
3569
            gen_goto_tb(ctx, 0, ctx->nip + li - 4);
3570
        } else {
3571
            gen_goto_tb(ctx, 0, li);
3572
        }
3573
        gen_set_label(l1);
3574
        gen_goto_tb(ctx, 1, ctx->nip);
3575
    } else {
3576
#if defined(TARGET_PPC64)
3577
        if (!(ctx->sf_mode))
3578
            tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
3579
        else
3580
#endif
3581
            tcg_gen_andi_tl(cpu_nip, target, ~3);
3582
        tcg_gen_exit_tb(0);
3583
        gen_set_label(l1);
3584
#if defined(TARGET_PPC64)
3585
        if (!(ctx->sf_mode))
3586
            tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip);
3587
        else
3588
#endif
3589
            tcg_gen_movi_tl(cpu_nip, ctx->nip);
3590
        tcg_gen_exit_tb(0);
3591
    }
3592
}
3593

    
3594
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3595
{
3596
    gen_bcond(ctx, BCOND_IM);
3597
}
3598

    
3599
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3600
{
3601
    gen_bcond(ctx, BCOND_CTR);
3602
}
3603

    
3604
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3605
{
3606
    gen_bcond(ctx, BCOND_LR);
3607
}
3608

    
3609
/***                      Condition register logical                       ***/
3610
#define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3611
GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                   \
3612
{                                                                             \
3613
    uint8_t bitmask;                                                          \
3614
    int sh;                                                                   \
3615
    TCGv t0, t1;                                                              \
3616
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3617
    t0 = tcg_temp_new(TCG_TYPE_I32);                                          \
3618
    if (sh > 0)                                                               \
3619
        tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
3620
    else if (sh < 0)                                                          \
3621
        tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
3622
    else                                                                      \
3623
        tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
3624
    t1 = tcg_temp_new(TCG_TYPE_I32);                                          \
3625
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3626
    if (sh > 0)                                                               \
3627
        tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
3628
    else if (sh < 0)                                                          \
3629
        tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
3630
    else                                                                      \
3631
        tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
3632
    tcg_op(t0, t0, t1);                                                       \
3633
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3634
    tcg_gen_andi_i32(t0, t0, bitmask);                                        \
3635
    tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
3636
    tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
3637
    tcg_temp_free(t0);                                                        \
3638
    tcg_temp_free(t1);                                                        \
3639
}
3640

    
3641
/* crand */
3642
GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
3643
/* crandc */
3644
GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
3645
/* creqv */
3646
GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
3647
/* crnand */
3648
GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
3649
/* crnor */
3650
GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
3651
/* cror */
3652
GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
3653
/* crorc */
3654
GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
3655
/* crxor */
3656
GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
3657
/* mcrf */
3658
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3659
{
3660
    tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
3661
}
3662

    
3663
/***                           System linkage                              ***/
3664
/* rfi (supervisor only) */
3665
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3666
{
3667
#if defined(CONFIG_USER_ONLY)
3668
    GEN_EXCP_PRIVOPC(ctx);
3669
#else
3670
    /* Restore CPU state */
3671
    if (unlikely(!ctx->supervisor)) {
3672
        GEN_EXCP_PRIVOPC(ctx);
3673
        return;
3674
    }
3675
    gen_op_rfi();
3676
    GEN_SYNC(ctx);
3677
#endif
3678
}
3679

    
3680
#if defined(TARGET_PPC64)
3681
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3682
{
3683
#if defined(CONFIG_USER_ONLY)
3684
    GEN_EXCP_PRIVOPC(ctx);
3685
#else
3686
    /* Restore CPU state */
3687
    if (unlikely(!ctx->supervisor)) {
3688
        GEN_EXCP_PRIVOPC(ctx);
3689
        return;
3690
    }
3691
    gen_op_rfid();
3692
    GEN_SYNC(ctx);
3693
#endif
3694
}
3695

    
3696
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3697
{
3698
#if defined(CONFIG_USER_ONLY)
3699
    GEN_EXCP_PRIVOPC(ctx);
3700
#else
3701
    /* Restore CPU state */
3702
    if (unlikely(ctx->supervisor <= 1)) {
3703
        GEN_EXCP_PRIVOPC(ctx);
3704
        return;
3705
    }
3706
    gen_op_hrfid();
3707
    GEN_SYNC(ctx);
3708
#endif
3709
}
3710
#endif
3711

    
3712
/* sc */
3713
#if defined(CONFIG_USER_ONLY)
3714
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3715
#else
3716
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3717
#endif
3718
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3719
{
3720
    uint32_t lev;
3721

    
3722
    lev = (ctx->opcode >> 5) & 0x7F;
3723
    GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
3724
}
3725

    
3726
/***                                Trap                                   ***/
3727
/* tw */
3728
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3729
{
3730
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3731
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3732
    /* Update the nip since this might generate a trap exception */
3733
    gen_update_nip(ctx, ctx->nip);
3734
    gen_op_tw(TO(ctx->opcode));
3735
}
3736

    
3737
/* twi */
3738
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3739
{
3740
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3741
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3742
    /* Update the nip since this might generate a trap exception */
3743
    gen_update_nip(ctx, ctx->nip);
3744
    gen_op_tw(TO(ctx->opcode));
3745
}
3746

    
3747
#if defined(TARGET_PPC64)
3748
/* td */
3749
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3750
{
3751
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3752
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3753
    /* Update the nip since this might generate a trap exception */
3754
    gen_update_nip(ctx, ctx->nip);
3755
    gen_op_td(TO(ctx->opcode));
3756
}
3757

    
3758
/* tdi */
3759
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3760
{
3761
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3762
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3763
    /* Update the nip since this might generate a trap exception */
3764
    gen_update_nip(ctx, ctx->nip);
3765
    gen_op_td(TO(ctx->opcode));
3766
}
3767
#endif
3768

    
3769
/***                          Processor control                            ***/
3770
/* mcrxr */
3771
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3772
{
3773
    tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
3774
    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
3775
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
3776
}
3777

    
3778
/* mfcr */
3779
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3780
{
3781
    uint32_t crm, crn;
3782

    
3783
    if (likely(ctx->opcode & 0x00100000)) {
3784
        crm = CRM(ctx->opcode);
3785
        if (likely((crm ^ (crm - 1)) == 0)) {
3786
            crn = ffs(crm);
3787
            tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
3788
        }
3789
    } else {
3790
        tcg_gen_helper_1_0(helper_load_cr, cpu_gpr[rD(ctx->opcode)]);
3791
    }
3792
}
3793

    
3794
/* mfmsr */
3795
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3796
{
3797
#if defined(CONFIG_USER_ONLY)
3798
    GEN_EXCP_PRIVREG(ctx);
3799
#else
3800
    if (unlikely(!ctx->supervisor)) {
3801
        GEN_EXCP_PRIVREG(ctx);
3802
        return;
3803
    }
3804
    gen_op_load_msr();
3805
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3806
#endif
3807
}
3808

    
3809
#if 1
3810
#define SPR_NOACCESS ((void *)(-1UL))
3811
#else
3812
static void spr_noaccess (void *opaque, int sprn)
3813
{
3814
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3815
    printf("ERROR: try to access SPR %d !\n", sprn);
3816
}
3817
#define SPR_NOACCESS (&spr_noaccess)
3818
#endif
3819

    
3820
/* mfspr */
3821
static always_inline void gen_op_mfspr (DisasContext *ctx)
3822
{
3823
    void (*read_cb)(void *opaque, int sprn);
3824
    uint32_t sprn = SPR(ctx->opcode);
3825

    
3826
#if !defined(CONFIG_USER_ONLY)
3827
    if (ctx->supervisor == 2)
3828
        read_cb = ctx->spr_cb[sprn].hea_read;
3829
    else if (ctx->supervisor)
3830
        read_cb = ctx->spr_cb[sprn].oea_read;
3831
    else
3832
#endif
3833
        read_cb = ctx->spr_cb[sprn].uea_read;
3834
    if (likely(read_cb != NULL)) {
3835
        if (likely(read_cb != SPR_NOACCESS)) {
3836
            (*read_cb)(ctx, sprn);
3837
            tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3838
        } else {
3839
            /* Privilege exception */
3840
            /* This is a hack to avoid warnings when running Linux:
3841
             * this OS breaks the PowerPC virtualisation model,
3842
             * allowing userland application to read the PVR
3843
             */
3844
            if (sprn != SPR_PVR) {
3845
                if (loglevel != 0) {
3846
                    fprintf(logfile, "Trying to read privileged spr %d %03x at "
3847
                            ADDRX "\n", sprn, sprn, ctx->nip);
3848
                }
3849
                printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
3850
                       sprn, sprn, ctx->nip);
3851
            }
3852
            GEN_EXCP_PRIVREG(ctx);
3853
        }
3854
    } else {
3855
        /* Not defined */
3856
        if (loglevel != 0) {
3857
            fprintf(logfile, "Trying to read invalid spr %d %03x at "
3858
                    ADDRX "\n", sprn, sprn, ctx->nip);
3859
        }
3860
        printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
3861
               sprn, sprn, ctx->nip);
3862
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3863
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3864
    }
3865
}
3866

    
3867
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3868
{
3869
    gen_op_mfspr(ctx);
3870
}
3871

    
3872
/* mftb */
3873
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3874
{
3875
    gen_op_mfspr(ctx);
3876
}
3877

    
3878
/* mtcrf */
3879
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3880
{
3881
    uint32_t crm, crn;
3882

    
3883
    crm = CRM(ctx->opcode);
3884
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3885
        crn = ffs(crm);
3886
        tcg_gen_shri_i32(cpu_crf[7 - crn], cpu_gpr[rS(ctx->opcode)], crn * 4);
3887
        tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
3888
    } else {
3889
        TCGv t0 = tcg_const_tl(crm);
3890
        tcg_gen_helper_0_2(helper_store_cr, cpu_gpr[rS(ctx->opcode)], t0);
3891
        tcg_temp_free(t0);
3892
    }
3893
}
3894

    
3895
/* mtmsr */
3896
#if defined(TARGET_PPC64)
3897
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3898
{
3899
#if defined(CONFIG_USER_ONLY)
3900
    GEN_EXCP_PRIVREG(ctx);
3901
#else
3902
    if (unlikely(!ctx->supervisor)) {
3903
        GEN_EXCP_PRIVREG(ctx);
3904
        return;
3905
    }
3906
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3907
    if (ctx->opcode & 0x00010000) {
3908
        /* Special form that does not need any synchronisation */
3909
        gen_op_update_riee();
3910
    } else {
3911
        /* XXX: we need to update nip before the store
3912
         *      if we enter power saving mode, we will exit the loop
3913
         *      directly from ppc_store_msr
3914
         */
3915
        gen_update_nip(ctx, ctx->nip);
3916
        gen_op_store_msr();
3917
        /* Must stop the translation as machine state (may have) changed */
3918
        /* Note that mtmsr is not always defined as context-synchronizing */
3919
        ctx->exception = POWERPC_EXCP_STOP;
3920
    }
3921
#endif
3922
}
3923
#endif
3924

    
3925
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3926
{
3927
#if defined(CONFIG_USER_ONLY)
3928
    GEN_EXCP_PRIVREG(ctx);
3929
#else
3930
    if (unlikely(!ctx->supervisor)) {
3931
        GEN_EXCP_PRIVREG(ctx);
3932
        return;
3933
    }
3934
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3935
    if (ctx->opcode & 0x00010000) {
3936
        /* Special form that does not need any synchronisation */
3937
        gen_op_update_riee();
3938
    } else {
3939
        /* XXX: we need to update nip before the store
3940
         *      if we enter power saving mode, we will exit the loop
3941
         *      directly from ppc_store_msr
3942
         */
3943
        gen_update_nip(ctx, ctx->nip);
3944
#if defined(TARGET_PPC64)
3945
        if (!ctx->sf_mode)
3946
            gen_op_store_msr_32();
3947
        else
3948
#endif
3949
            gen_op_store_msr();
3950
        /* Must stop the translation as machine state (may have) changed */
3951
        /* Note that mtmsrd is not always defined as context-synchronizing */
3952
        ctx->exception = POWERPC_EXCP_STOP;
3953
    }
3954
#endif
3955
}
3956

    
3957
/* mtspr */
3958
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3959
{
3960
    void (*write_cb)(void *opaque, int sprn);
3961
    uint32_t sprn = SPR(ctx->opcode);
3962

    
3963
#if !defined(CONFIG_USER_ONLY)
3964
    if (ctx->supervisor == 2)
3965
        write_cb = ctx->spr_cb[sprn].hea_write;
3966
    else if (ctx->supervisor)
3967
        write_cb = ctx->spr_cb[sprn].oea_write;
3968
    else
3969
#endif
3970
        write_cb = ctx->spr_cb[sprn].uea_write;
3971
    if (likely(write_cb != NULL)) {
3972
        if (likely(write_cb != SPR_NOACCESS)) {
3973
            tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3974
            (*write_cb)(ctx, sprn);
3975
        } else {
3976
            /* Privilege exception */
3977
            if (loglevel != 0) {
3978
                fprintf(logfile, "Trying to write privileged spr %d %03x at "
3979
                        ADDRX "\n", sprn, sprn, ctx->nip);
3980
            }
3981
            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
3982
                   sprn, sprn, ctx->nip);
3983
            GEN_EXCP_PRIVREG(ctx);
3984
        }
3985
    } else {
3986
        /* Not defined */
3987
        if (loglevel != 0) {
3988
            fprintf(logfile, "Trying to write invalid spr %d %03x at "
3989
                    ADDRX "\n", sprn, sprn, ctx->nip);
3990
        }
3991
        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
3992
               sprn, sprn, ctx->nip);
3993
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3994
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3995
    }
3996
}
3997

    
3998
/***                         Cache management                              ***/
3999
/* dcbf */
4000
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
4001
{
4002
    /* XXX: specification says this is treated as a load by the MMU */
4003
    TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
4004
    gen_addr_reg_index(t0, ctx);
4005
    gen_qemu_ld8u(t0, t0, ctx->mem_idx);
4006
    tcg_temp_free(t0);
4007
}
4008

    
4009
/* dcbi (Supervisor only) */
4010
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
4011
{
4012
#if defined(CONFIG_USER_ONLY)
4013
    GEN_EXCP_PRIVOPC(ctx);
4014
#else
4015
    TCGv EA, val;
4016
    if (unlikely(!ctx->supervisor)) {
4017
        GEN_EXCP_PRIVOPC(ctx);
4018
        return;
4019
    }
4020
    EA = tcg_temp_new(TCG_TYPE_TL);
4021
    gen_addr_reg_index(EA, ctx);
4022
    val = tcg_temp_new(TCG_TYPE_TL);
4023
    /* XXX: specification says this should be treated as a store by the MMU */
4024
    gen_qemu_ld8u(val, EA, ctx->mem_idx);
4025
    gen_qemu_st8(val, EA, ctx->mem_idx);
4026
    tcg_temp_free(val);
4027
    tcg_temp_free(EA);
4028
#endif
4029
}
4030

    
4031
/* dcdst */
4032
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
4033
{
4034
    /* XXX: specification say this is treated as a load by the MMU */
4035
    TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
4036
    gen_addr_reg_index(t0, ctx);
4037
    gen_qemu_ld8u(t0, t0, ctx->mem_idx);
4038
    tcg_temp_free(t0);
4039
}
4040

    
4041
/* dcbt */
4042
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
4043
{
4044
    /* interpreted as no-op */
4045
    /* XXX: specification say this is treated as a load by the MMU
4046
     *      but does not generate any exception
4047
     */
4048
}
4049

    
4050
/* dcbtst */
4051
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
4052
{
4053
    /* interpreted as no-op */
4054
    /* XXX: specification say this is treated as a load by the MMU
4055
     *      but does not generate any exception
4056
     */
4057
}
4058

    
4059
/* dcbz */
4060
#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
4061
static GenOpFunc *gen_op_dcbz[4][NB_MEM_FUNCS] = {
4062
    /* 32 bytes cache line size */
4063
    {
4064
#define gen_op_dcbz_l32_le_raw        gen_op_dcbz_l32_raw
4065
#define gen_op_dcbz_l32_le_user       gen_op_dcbz_l32_user
4066
#define gen_op_dcbz_l32_le_kernel     gen_op_dcbz_l32_kernel
4067
#define gen_op_dcbz_l32_le_hypv       gen_op_dcbz_l32_hypv
4068
#define gen_op_dcbz_l32_le_64_raw     gen_op_dcbz_l32_64_raw
4069
#define gen_op_dcbz_l32_le_64_user    gen_op_dcbz_l32_64_user
4070
#define gen_op_dcbz_l32_le_64_kernel  gen_op_dcbz_l32_64_kernel
4071
#define gen_op_dcbz_l32_le_64_hypv    gen_op_dcbz_l32_64_hypv
4072
        GEN_MEM_FUNCS(dcbz_l32),
4073
    },
4074
    /* 64 bytes cache line size */
4075
    {
4076
#define gen_op_dcbz_l64_le_raw        gen_op_dcbz_l64_raw
4077
#define gen_op_dcbz_l64_le_user       gen_op_dcbz_l64_user
4078
#define gen_op_dcbz_l64_le_kernel     gen_op_dcbz_l64_kernel
4079
#define gen_op_dcbz_l64_le_hypv       gen_op_dcbz_l64_hypv
4080
#define gen_op_dcbz_l64_le_64_raw     gen_op_dcbz_l64_64_raw
4081
#define gen_op_dcbz_l64_le_64_user    gen_op_dcbz_l64_64_user
4082
#define gen_op_dcbz_l64_le_64_kernel  gen_op_dcbz_l64_64_kernel
4083
#define gen_op_dcbz_l64_le_64_hypv    gen_op_dcbz_l64_64_hypv
4084
        GEN_MEM_FUNCS(dcbz_l64),
4085
    },
4086
    /* 128 bytes cache line size */
4087
    {
4088
#define gen_op_dcbz_l128_le_raw       gen_op_dcbz_l128_raw
4089
#define gen_op_dcbz_l128_le_user      gen_op_dcbz_l128_user
4090
#define gen_op_dcbz_l128_le_kernel    gen_op_dcbz_l128_kernel
4091
#define gen_op_dcbz_l128_le_hypv      gen_op_dcbz_l128_hypv
4092
#define gen_op_dcbz_l128_le_64_raw    gen_op_dcbz_l128_64_raw
4093
#define gen_op_dcbz_l128_le_64_user   gen_op_dcbz_l128_64_user
4094
#define gen_op_dcbz_l128_le_64_kernel gen_op_dcbz_l128_64_kernel
4095
#define gen_op_dcbz_l128_le_64_hypv   gen_op_dcbz_l128_64_hypv
4096
        GEN_MEM_FUNCS(dcbz_l128),
4097
    },
4098
    /* tunable cache line size */
4099
    {
4100
#define gen_op_dcbz_le_raw            gen_op_dcbz_raw
4101
#define gen_op_dcbz_le_user           gen_op_dcbz_user
4102
#define gen_op_dcbz_le_kernel         gen_op_dcbz_kernel
4103
#define gen_op_dcbz_le_hypv           gen_op_dcbz_hypv
4104
#define gen_op_dcbz_le_64_raw         gen_op_dcbz_64_raw
4105
#define gen_op_dcbz_le_64_user        gen_op_dcbz_64_user
4106
#define gen_op_dcbz_le_64_kernel      gen_op_dcbz_64_kernel
4107
#define gen_op_dcbz_le_64_hypv        gen_op_dcbz_64_hypv
4108
        GEN_MEM_FUNCS(dcbz),
4109
    },
4110
};
4111

    
4112
static always_inline void handler_dcbz (DisasContext *ctx,
4113
                                        int dcache_line_size)
4114
{
4115
    int n;
4116

    
4117
    switch (dcache_line_size) {
4118
    case 32:
4119
        n = 0;
4120
        break;
4121
    case 64:
4122
        n = 1;
4123
        break;
4124
    case 128:
4125
        n = 2;
4126
        break;
4127
    default:
4128
        n = 3;
4129
        break;
4130
    }
4131
    op_dcbz(n);
4132
}
4133

    
4134
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
4135
{
4136
    gen_addr_reg_index(cpu_T[0], ctx);
4137
    handler_dcbz(ctx, ctx->dcache_line_size);
4138
    gen_op_check_reservation();
4139
}
4140

    
4141
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
4142
{
4143
    gen_addr_reg_index(cpu_T[0], ctx);
4144
    if (ctx->opcode & 0x00200000)
4145
        handler_dcbz(ctx, ctx->dcache_line_size);
4146
    else
4147
        handler_dcbz(ctx, -1);
4148
    gen_op_check_reservation();
4149
}
4150

    
4151
/* icbi */
4152
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
4153
#define gen_op_icbi_le_raw       gen_op_icbi_raw
4154
#define gen_op_icbi_le_user      gen_op_icbi_user
4155
#define gen_op_icbi_le_kernel    gen_op_icbi_kernel
4156
#define gen_op_icbi_le_hypv      gen_op_icbi_hypv
4157
#define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
4158
#define gen_op_icbi_le_64_user   gen_op_icbi_64_user
4159
#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
4160
#define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
4161
static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
4162
    GEN_MEM_FUNCS(icbi),
4163
};
4164

    
4165
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
4166
{
4167
    /* NIP cannot be restored if the memory exception comes from an helper */
4168
    gen_update_nip(ctx, ctx->nip - 4);
4169
    gen_addr_reg_index(cpu_T[0], ctx);
4170
    op_icbi();
4171
}
4172

    
4173
/* Optional: */
4174
/* dcba */
4175
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
4176
{
4177
    /* interpreted as no-op */
4178
    /* XXX: specification say this is treated as a store by the MMU
4179
     *      but does not generate any exception
4180
     */
4181
}
4182

    
4183
/***                    Segment register manipulation                      ***/
4184
/* Supervisor only: */
4185
/* mfsr */
4186
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
4187
{
4188
#if defined(CONFIG_USER_ONLY)
4189
    GEN_EXCP_PRIVREG(ctx);
4190
#else
4191
    if (unlikely(!ctx->supervisor)) {
4192
        GEN_EXCP_PRIVREG(ctx);
4193
        return;
4194
    }
4195
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4196
    gen_op_load_sr();
4197
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4198
#endif
4199
}
4200

    
4201
/* mfsrin */
4202
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
4203
{
4204
#if defined(CONFIG_USER_ONLY)
4205
    GEN_EXCP_PRIVREG(ctx);
4206
#else
4207
    if (unlikely(!ctx->supervisor)) {
4208
        GEN_EXCP_PRIVREG(ctx);
4209
        return;
4210
    }
4211
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4212
    gen_op_srli_T1(28);
4213
    gen_op_load_sr();
4214
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4215
#endif
4216
}
4217

    
4218
/* mtsr */
4219
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
4220
{
4221
#if defined(CONFIG_USER_ONLY)
4222
    GEN_EXCP_PRIVREG(ctx);
4223
#else
4224
    if (unlikely(!ctx->supervisor)) {
4225
        GEN_EXCP_PRIVREG(ctx);
4226
        return;
4227
    }
4228
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4229
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4230
    gen_op_store_sr();
4231
#endif
4232
}
4233

    
4234
/* mtsrin */
4235
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
4236
{
4237
#if defined(CONFIG_USER_ONLY)
4238
    GEN_EXCP_PRIVREG(ctx);
4239
#else
4240
    if (unlikely(!ctx->supervisor)) {
4241
        GEN_EXCP_PRIVREG(ctx);
4242
        return;
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_srli_T1(28);
4247
    gen_op_store_sr();
4248
#endif
4249
}
4250

    
4251
#if defined(TARGET_PPC64)
4252
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4253
/* mfsr */
4254
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
4255
{
4256
#if defined(CONFIG_USER_ONLY)
4257
    GEN_EXCP_PRIVREG(ctx);
4258
#else
4259
    if (unlikely(!ctx->supervisor)) {
4260
        GEN_EXCP_PRIVREG(ctx);
4261
        return;
4262
    }
4263
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4264
    gen_op_load_slb();
4265
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4266
#endif
4267
}
4268

    
4269
/* mfsrin */
4270
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
4271
             PPC_SEGMENT_64B)
4272
{
4273
#if defined(CONFIG_USER_ONLY)
4274
    GEN_EXCP_PRIVREG(ctx);
4275
#else
4276
    if (unlikely(!ctx->supervisor)) {
4277
        GEN_EXCP_PRIVREG(ctx);
4278
        return;
4279
    }
4280
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4281
    gen_op_srli_T1(28);
4282
    gen_op_load_slb();
4283
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4284
#endif
4285
}
4286

    
4287
/* mtsr */
4288
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
4289
{
4290
#if defined(CONFIG_USER_ONLY)
4291
    GEN_EXCP_PRIVREG(ctx);
4292
#else
4293
    if (unlikely(!ctx->supervisor)) {
4294
        GEN_EXCP_PRIVREG(ctx);
4295
        return;
4296
    }
4297
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4298
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
4299
    gen_op_store_slb();
4300
#endif
4301
}
4302

    
4303
/* mtsrin */
4304
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
4305
             PPC_SEGMENT_64B)
4306
{
4307
#if defined(CONFIG_USER_ONLY)
4308
    GEN_EXCP_PRIVREG(ctx);
4309
#else
4310
    if (unlikely(!ctx->supervisor)) {
4311
        GEN_EXCP_PRIVREG(ctx);
4312
        return;
4313
    }
4314
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4315
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4316
    gen_op_srli_T1(28);
4317
    gen_op_store_slb();
4318
#endif
4319
}
4320
#endif /* defined(TARGET_PPC64) */
4321

    
4322
/***                      Lookaside buffer management                      ***/
4323
/* Optional & supervisor only: */
4324
/* tlbia */
4325
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
4326
{
4327
#if defined(CONFIG_USER_ONLY)
4328
    GEN_EXCP_PRIVOPC(ctx);
4329
#else
4330
    if (unlikely(!ctx->supervisor)) {
4331
        GEN_EXCP_PRIVOPC(ctx);
4332
        return;
4333
    }
4334
    gen_op_tlbia();
4335
#endif
4336
}
4337

    
4338
/* tlbie */
4339
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
4340
{
4341
#if defined(CONFIG_USER_ONLY)
4342
    GEN_EXCP_PRIVOPC(ctx);
4343
#else
4344
    if (unlikely(!ctx->supervisor)) {
4345
        GEN_EXCP_PRIVOPC(ctx);
4346
        return;
4347
    }
4348
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4349
#if defined(TARGET_PPC64)
4350
    if (ctx->sf_mode)
4351
        gen_op_tlbie_64();
4352
    else
4353
#endif
4354
        gen_op_tlbie();
4355
#endif
4356
}
4357

    
4358
/* tlbsync */
4359
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
4360
{
4361
#if defined(CONFIG_USER_ONLY)
4362
    GEN_EXCP_PRIVOPC(ctx);
4363
#else
4364
    if (unlikely(!ctx->supervisor)) {
4365
        GEN_EXCP_PRIVOPC(ctx);
4366
        return;
4367
    }
4368
    /* This has no effect: it should ensure that all previous
4369
     * tlbie have completed
4370
     */
4371
    GEN_STOP(ctx);
4372
#endif
4373
}
4374

    
4375
#if defined(TARGET_PPC64)
4376
/* slbia */
4377
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
4378
{
4379
#if defined(CONFIG_USER_ONLY)
4380
    GEN_EXCP_PRIVOPC(ctx);
4381
#else
4382
    if (unlikely(!ctx->supervisor)) {
4383
        GEN_EXCP_PRIVOPC(ctx);
4384
        return;
4385
    }
4386
    gen_op_slbia();
4387
#endif
4388
}
4389

    
4390
/* slbie */
4391
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
4392
{
4393
#if defined(CONFIG_USER_ONLY)
4394
    GEN_EXCP_PRIVOPC(ctx);
4395
#else
4396
    if (unlikely(!ctx->supervisor)) {
4397
        GEN_EXCP_PRIVOPC(ctx);
4398
        return;
4399
    }
4400
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4401
    gen_op_slbie();
4402
#endif
4403
}
4404
#endif
4405

    
4406
/***                              External control                         ***/
4407
/* Optional: */
4408
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
4409
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
4410
static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
4411
    GEN_MEM_FUNCS(eciwx),
4412
};
4413
static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
4414
    GEN_MEM_FUNCS(ecowx),
4415
};
4416

    
4417
/* eciwx */
4418
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
4419
{
4420
    /* Should check EAR[E] & alignment ! */
4421
    gen_addr_reg_index(cpu_T[0], ctx);
4422
    op_eciwx();
4423
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4424
}
4425

    
4426
/* ecowx */
4427
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
4428
{
4429
    /* Should check EAR[E] & alignment ! */
4430
    gen_addr_reg_index(cpu_T[0], ctx);
4431
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4432
    op_ecowx();
4433
}
4434

    
4435
/* PowerPC 601 specific instructions */
4436
/* abs - abs. */
4437
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
4438
{
4439
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4440
    gen_op_POWER_abs();
4441
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4442
    if (unlikely(Rc(ctx->opcode) != 0))
4443
        gen_set_Rc0(ctx, cpu_T[0]);
4444
}
4445

    
4446
/* abso - abso. */
4447
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
4448
{
4449
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4450
    gen_op_POWER_abso();
4451
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4452
    if (unlikely(Rc(ctx->opcode) != 0))
4453
        gen_set_Rc0(ctx, cpu_T[0]);
4454
}
4455

    
4456
/* clcs */
4457
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
4458
{
4459
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4460
    gen_op_POWER_clcs();
4461
    /* Rc=1 sets CR0 to an undefined state */
4462
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4463
}
4464

    
4465
/* div - div. */
4466
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
4467
{
4468
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4469
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4470
    gen_op_POWER_div();
4471
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4472
    if (unlikely(Rc(ctx->opcode) != 0))
4473
        gen_set_Rc0(ctx, cpu_T[0]);
4474
}
4475

    
4476
/* divo - divo. */
4477
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
4478
{
4479
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4480
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4481
    gen_op_POWER_divo();
4482
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4483
    if (unlikely(Rc(ctx->opcode) != 0))
4484
        gen_set_Rc0(ctx, cpu_T[0]);
4485
}
4486

    
4487
/* divs - divs. */
4488
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
4489
{
4490
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4491
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4492
    gen_op_POWER_divs();
4493
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4494
    if (unlikely(Rc(ctx->opcode) != 0))
4495
        gen_set_Rc0(ctx, cpu_T[0]);
4496
}
4497

    
4498
/* divso - divso. */
4499
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
4500
{
4501
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4502
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4503
    gen_op_POWER_divso();
4504
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4505
    if (unlikely(Rc(ctx->opcode) != 0))
4506
        gen_set_Rc0(ctx, cpu_T[0]);
4507
}
4508

    
4509
/* doz - doz. */
4510
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
4511
{
4512
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4513
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4514
    gen_op_POWER_doz();
4515
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4516
    if (unlikely(Rc(ctx->opcode) != 0))
4517
        gen_set_Rc0(ctx, cpu_T[0]);
4518
}
4519

    
4520
/* dozo - dozo. */
4521
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
4522
{
4523
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4524
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4525
    gen_op_POWER_dozo();
4526
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4527
    if (unlikely(Rc(ctx->opcode) != 0))
4528
        gen_set_Rc0(ctx, cpu_T[0]);
4529
}
4530

    
4531
/* dozi */
4532
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4533
{
4534
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4535
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
4536
    gen_op_POWER_doz();
4537
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4538
}
4539

    
4540
/* As lscbx load from memory byte after byte, it's always endian safe.
4541
 * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones
4542
 */
4543
#define op_POWER_lscbx(start, ra, rb)                                         \
4544
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
4545
#define gen_op_POWER_lscbx_64_raw       gen_op_POWER_lscbx_raw
4546
#define gen_op_POWER_lscbx_64_user      gen_op_POWER_lscbx_user
4547
#define gen_op_POWER_lscbx_64_kernel    gen_op_POWER_lscbx_kernel
4548
#define gen_op_POWER_lscbx_64_hypv      gen_op_POWER_lscbx_hypv
4549
#define gen_op_POWER_lscbx_le_raw       gen_op_POWER_lscbx_raw
4550
#define gen_op_POWER_lscbx_le_user      gen_op_POWER_lscbx_user
4551
#define gen_op_POWER_lscbx_le_kernel    gen_op_POWER_lscbx_kernel
4552
#define gen_op_POWER_lscbx_le_hypv      gen_op_POWER_lscbx_hypv
4553
#define gen_op_POWER_lscbx_le_64_raw    gen_op_POWER_lscbx_raw
4554
#define gen_op_POWER_lscbx_le_64_user   gen_op_POWER_lscbx_user
4555
#define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel
4556
#define gen_op_POWER_lscbx_le_64_hypv   gen_op_POWER_lscbx_hypv
4557
static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = {
4558
    GEN_MEM_FUNCS(POWER_lscbx),
4559
};
4560

    
4561
/* lscbx - lscbx. */
4562
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
4563
{
4564
    int ra = rA(ctx->opcode);
4565
    int rb = rB(ctx->opcode);
4566

    
4567
    gen_addr_reg_index(cpu_T[0], ctx);
4568
    if (ra == 0) {
4569
        ra = rb;
4570
    }
4571
    /* NIP cannot be restored if the memory exception comes from an helper */
4572
    gen_update_nip(ctx, ctx->nip - 4);
4573
    tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
4574
    tcg_gen_shri_tl(cpu_T[2], cpu_xer, XER_CMP);
4575
    tcg_gen_andi_tl(cpu_T[2], cpu_T[2], 0xFF);
4576
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
4577
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
4578
    tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
4579
    if (unlikely(Rc(ctx->opcode) != 0))
4580
        gen_set_Rc0(ctx, cpu_T[0]);
4581
}
4582

    
4583
/* maskg - maskg. */
4584
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
4585
{
4586
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4587
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4588
    gen_op_POWER_maskg();
4589
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4590
    if (unlikely(Rc(ctx->opcode) != 0))
4591
        gen_set_Rc0(ctx, cpu_T[0]);
4592
}
4593

    
4594
/* maskir - maskir. */
4595
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4596
{
4597
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4598
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4599
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4600
    gen_op_POWER_maskir();
4601
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4602
    if (unlikely(Rc(ctx->opcode) != 0))
4603
        gen_set_Rc0(ctx, cpu_T[0]);
4604
}
4605

    
4606
/* mul - mul. */
4607
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4608
{
4609
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4610
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4611
    gen_op_POWER_mul();
4612
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4613
    if (unlikely(Rc(ctx->opcode) != 0))
4614
        gen_set_Rc0(ctx, cpu_T[0]);
4615
}
4616

    
4617
/* mulo - mulo. */
4618
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4619
{
4620
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4621
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4622
    gen_op_POWER_mulo();
4623
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4624
    if (unlikely(Rc(ctx->opcode) != 0))
4625
        gen_set_Rc0(ctx, cpu_T[0]);
4626
}
4627

    
4628
/* nabs - nabs. */
4629
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4630
{
4631
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4632
    gen_op_POWER_nabs();
4633
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4634
    if (unlikely(Rc(ctx->opcode) != 0))
4635
        gen_set_Rc0(ctx, cpu_T[0]);
4636
}
4637

    
4638
/* nabso - nabso. */
4639
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4640
{
4641
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4642
    gen_op_POWER_nabso();
4643
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4644
    if (unlikely(Rc(ctx->opcode) != 0))
4645
        gen_set_Rc0(ctx, cpu_T[0]);
4646
}
4647

    
4648
/* rlmi - rlmi. */
4649
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4650
{
4651
    uint32_t mb, me;
4652

    
4653
    mb = MB(ctx->opcode);
4654
    me = ME(ctx->opcode);
4655
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4656
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4657
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4658
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4659
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4660
    if (unlikely(Rc(ctx->opcode) != 0))
4661
        gen_set_Rc0(ctx, cpu_T[0]);
4662
}
4663

    
4664
/* rrib - rrib. */
4665
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4666
{
4667
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4668
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4669
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4670
    gen_op_POWER_rrib();
4671
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4672
    if (unlikely(Rc(ctx->opcode) != 0))
4673
        gen_set_Rc0(ctx, cpu_T[0]);
4674
}
4675

    
4676
/* sle - sle. */
4677
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4678
{
4679
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4680
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4681
    gen_op_POWER_sle();
4682
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4683
    if (unlikely(Rc(ctx->opcode) != 0))
4684
        gen_set_Rc0(ctx, cpu_T[0]);
4685
}
4686

    
4687
/* sleq - sleq. */
4688
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4689
{
4690
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4691
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4692
    gen_op_POWER_sleq();
4693
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4694
    if (unlikely(Rc(ctx->opcode) != 0))
4695
        gen_set_Rc0(ctx, cpu_T[0]);
4696
}
4697

    
4698
/* sliq - sliq. */
4699
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4700
{
4701
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4702
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4703
    gen_op_POWER_sle();
4704
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4705
    if (unlikely(Rc(ctx->opcode) != 0))
4706
        gen_set_Rc0(ctx, cpu_T[0]);
4707
}
4708

    
4709
/* slliq - slliq. */
4710
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4711
{
4712
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4713
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4714
    gen_op_POWER_sleq();
4715
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4716
    if (unlikely(Rc(ctx->opcode) != 0))
4717
        gen_set_Rc0(ctx, cpu_T[0]);
4718
}
4719

    
4720
/* sllq - sllq. */
4721
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4722
{
4723
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4724
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4725
    gen_op_POWER_sllq();
4726
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4727
    if (unlikely(Rc(ctx->opcode) != 0))
4728
        gen_set_Rc0(ctx, cpu_T[0]);
4729
}
4730

    
4731
/* slq - slq. */
4732
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4733
{
4734
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4735
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4736
    gen_op_POWER_slq();
4737
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4738
    if (unlikely(Rc(ctx->opcode) != 0))
4739
        gen_set_Rc0(ctx, cpu_T[0]);
4740
}
4741

    
4742
/* sraiq - sraiq. */
4743
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4744
{
4745
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4746
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4747
    gen_op_POWER_sraq();
4748
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4749
    if (unlikely(Rc(ctx->opcode) != 0))
4750
        gen_set_Rc0(ctx, cpu_T[0]);
4751
}
4752

    
4753
/* sraq - sraq. */
4754
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4755
{
4756
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4757
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4758
    gen_op_POWER_sraq();
4759
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4760
    if (unlikely(Rc(ctx->opcode) != 0))
4761
        gen_set_Rc0(ctx, cpu_T[0]);
4762
}
4763

    
4764
/* sre - sre. */
4765
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4766
{
4767
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4768
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4769
    gen_op_POWER_sre();
4770
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4771
    if (unlikely(Rc(ctx->opcode) != 0))
4772
        gen_set_Rc0(ctx, cpu_T[0]);
4773
}
4774

    
4775
/* srea - srea. */
4776
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4777
{
4778
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4779
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4780
    gen_op_POWER_srea();
4781
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4782
    if (unlikely(Rc(ctx->opcode) != 0))
4783
        gen_set_Rc0(ctx, cpu_T[0]);
4784
}
4785

    
4786
/* sreq */
4787
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4788
{
4789
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4790
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4791
    gen_op_POWER_sreq();
4792
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4793
    if (unlikely(Rc(ctx->opcode) != 0))
4794
        gen_set_Rc0(ctx, cpu_T[0]);
4795
}
4796

    
4797
/* sriq */
4798
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4799
{
4800
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4801
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4802
    gen_op_POWER_srq();
4803
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4804
    if (unlikely(Rc(ctx->opcode) != 0))
4805
        gen_set_Rc0(ctx, cpu_T[0]);
4806
}
4807

    
4808
/* srliq */
4809
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4810
{
4811
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4812
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4813
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4814
    gen_op_POWER_srlq();
4815
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4816
    if (unlikely(Rc(ctx->opcode) != 0))
4817
        gen_set_Rc0(ctx, cpu_T[0]);
4818
}
4819

    
4820
/* srlq */
4821
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4822
{
4823
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4824
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4825
    gen_op_POWER_srlq();
4826
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4827
    if (unlikely(Rc(ctx->opcode) != 0))
4828
        gen_set_Rc0(ctx, cpu_T[0]);
4829
}
4830

    
4831
/* srq */
4832
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4833
{
4834
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4835
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4836
    gen_op_POWER_srq();
4837
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4838
    if (unlikely(Rc(ctx->opcode) != 0))
4839
        gen_set_Rc0(ctx, cpu_T[0]);
4840
}
4841

    
4842
/* PowerPC 602 specific instructions */
4843
/* dsa  */
4844
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4845
{
4846
    /* XXX: TODO */
4847
    GEN_EXCP_INVAL(ctx);
4848
}
4849

    
4850
/* esa */
4851
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4852
{
4853
    /* XXX: TODO */
4854
    GEN_EXCP_INVAL(ctx);
4855
}
4856

    
4857
/* mfrom */
4858
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4859
{
4860
#if defined(CONFIG_USER_ONLY)
4861
    GEN_EXCP_PRIVOPC(ctx);
4862
#else
4863
    if (unlikely(!ctx->supervisor)) {
4864
        GEN_EXCP_PRIVOPC(ctx);
4865
        return;
4866
    }
4867
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4868
    gen_op_602_mfrom();
4869
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4870
#endif
4871
}
4872

    
4873
/* 602 - 603 - G2 TLB management */
4874
/* tlbld */
4875
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4876
{
4877
#if defined(CONFIG_USER_ONLY)
4878
    GEN_EXCP_PRIVOPC(ctx);
4879
#else
4880
    if (unlikely(!ctx->supervisor)) {
4881
        GEN_EXCP_PRIVOPC(ctx);
4882
        return;
4883
    }
4884
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4885
    gen_op_6xx_tlbld();
4886
#endif
4887
}
4888

    
4889
/* tlbli */
4890
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4891
{
4892
#if defined(CONFIG_USER_ONLY)
4893
    GEN_EXCP_PRIVOPC(ctx);
4894
#else
4895
    if (unlikely(!ctx->supervisor)) {
4896
        GEN_EXCP_PRIVOPC(ctx);
4897
        return;
4898
    }
4899
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4900
    gen_op_6xx_tlbli();
4901
#endif
4902
}
4903

    
4904
/* 74xx TLB management */
4905
/* tlbld */
4906
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4907
{
4908
#if defined(CONFIG_USER_ONLY)
4909
    GEN_EXCP_PRIVOPC(ctx);
4910
#else
4911
    if (unlikely(!ctx->supervisor)) {
4912
        GEN_EXCP_PRIVOPC(ctx);
4913
        return;
4914
    }
4915
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4916
    gen_op_74xx_tlbld();
4917
#endif
4918
}
4919

    
4920
/* tlbli */
4921
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4922
{
4923
#if defined(CONFIG_USER_ONLY)
4924
    GEN_EXCP_PRIVOPC(ctx);
4925
#else
4926
    if (unlikely(!ctx->supervisor)) {
4927
        GEN_EXCP_PRIVOPC(ctx);
4928
        return;
4929
    }
4930
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4931
    gen_op_74xx_tlbli();
4932
#endif
4933
}
4934

    
4935
/* POWER instructions not in PowerPC 601 */
4936
/* clf */
4937
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4938
{
4939
    /* Cache line flush: implemented as no-op */
4940
}
4941

    
4942
/* cli */
4943
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4944
{
4945
    /* Cache line invalidate: privileged and treated as no-op */
4946
#if defined(CONFIG_USER_ONLY)
4947
    GEN_EXCP_PRIVOPC(ctx);
4948
#else
4949
    if (unlikely(!ctx->supervisor)) {
4950
        GEN_EXCP_PRIVOPC(ctx);
4951
        return;
4952
    }
4953
#endif
4954
}
4955

    
4956
/* dclst */
4957
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4958
{
4959
    /* Data cache line store: treated as no-op */
4960
}
4961

    
4962
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4963
{
4964
#if defined(CONFIG_USER_ONLY)
4965
    GEN_EXCP_PRIVOPC(ctx);
4966
#else
4967
    if (unlikely(!ctx->supervisor)) {
4968
        GEN_EXCP_PRIVOPC(ctx);
4969
        return;
4970
    }
4971
    int ra = rA(ctx->opcode);
4972
    int rd = rD(ctx->opcode);
4973

    
4974
    gen_addr_reg_index(cpu_T[0], ctx);
4975
    gen_op_POWER_mfsri();
4976
    tcg_gen_mov_tl(cpu_gpr[rd], cpu_T[0]);
4977
    if (ra != 0 && ra != rd)
4978
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[1]);
4979
#endif
4980
}
4981

    
4982
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4983
{
4984
#if defined(CONFIG_USER_ONLY)
4985
    GEN_EXCP_PRIVOPC(ctx);
4986
#else
4987
    if (unlikely(!ctx->supervisor)) {
4988
        GEN_EXCP_PRIVOPC(ctx);
4989
        return;
4990
    }
4991
    gen_addr_reg_index(cpu_T[0], ctx);
4992
    gen_op_POWER_rac();
4993
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4994
#endif
4995
}
4996

    
4997
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4998
{
4999
#if defined(CONFIG_USER_ONLY)
5000
    GEN_EXCP_PRIVOPC(ctx);
5001
#else
5002
    if (unlikely(!ctx->supervisor)) {
5003
        GEN_EXCP_PRIVOPC(ctx);
5004
        return;
5005
    }
5006
    gen_op_POWER_rfsvc();
5007
    GEN_SYNC(ctx);
5008
#endif
5009
}
5010

    
5011
/* svc is not implemented for now */
5012

    
5013
/* POWER2 specific instructions */
5014
/* Quad manipulation (load/store two floats at a time) */
5015
/* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
5016
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
5017
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
5018
#define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
5019
#define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
5020
#define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
5021
#define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
5022
#define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
5023
#define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
5024
#define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
5025
#define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
5026
#define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
5027
#define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
5028
#define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
5029
#define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
5030
#define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
5031
#define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
5032
#define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
5033
#define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
5034
static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
5035
    GEN_MEM_FUNCS(POWER2_lfq),
5036
};
5037
static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
5038
    GEN_MEM_FUNCS(POWER2_stfq),
5039
};
5040

    
5041
/* lfq */
5042
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
5043
{
5044
    /* NIP cannot be restored if the memory exception comes from an helper */
5045
    gen_update_nip(ctx, ctx->nip - 4);
5046
    gen_addr_imm_index(cpu_T[0], ctx, 0);
5047
    op_POWER2_lfq();
5048
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
5049
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
5050
}
5051

    
5052
/* lfqu */
5053
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
5054
{
5055
    int ra = rA(ctx->opcode);
5056

    
5057
    /* NIP cannot be restored if the memory exception comes from an helper */
5058
    gen_update_nip(ctx, ctx->nip - 4);
5059
    gen_addr_imm_index(cpu_T[0], ctx, 0);
5060
    op_POWER2_lfq();
5061
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
5062
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
5063
    if (ra != 0)
5064
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
5065
}
5066

    
5067
/* lfqux */
5068
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
5069
{
5070
    int ra = rA(ctx->opcode);
5071

    
5072
    /* NIP cannot be restored if the memory exception comes from an helper */
5073
    gen_update_nip(ctx, ctx->nip - 4);
5074
    gen_addr_reg_index(cpu_T[0], ctx);
5075
    op_POWER2_lfq();
5076
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
5077
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
5078
    if (ra != 0)
5079
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
5080
}
5081

    
5082
/* lfqx */
5083
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
5084
{
5085
    /* NIP cannot be restored if the memory exception comes from an helper */
5086
    gen_update_nip(ctx, ctx->nip - 4);
5087
    gen_addr_reg_index(cpu_T[0], ctx);
5088
    op_POWER2_lfq();
5089
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
5090
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
5091
}
5092

    
5093
/* stfq */
5094
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
5095
{
5096
    /* NIP cannot be restored if the memory exception comes from an helper */
5097
    gen_update_nip(ctx, ctx->nip - 4);
5098
    gen_addr_imm_index(cpu_T[0], ctx, 0);
5099
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
5100
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
5101
    op_POWER2_stfq();
5102
}
5103

    
5104
/* stfqu */
5105
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
5106
{
5107
    int ra = rA(ctx->opcode);
5108

    
5109
    /* NIP cannot be restored if the memory exception comes from an helper */
5110
    gen_update_nip(ctx, ctx->nip - 4);
5111
    gen_addr_imm_index(cpu_T[0], ctx, 0);
5112
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
5113
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
5114
    op_POWER2_stfq();
5115
    if (ra != 0)
5116
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
5117
}
5118

    
5119
/* stfqux */
5120
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
5121
{
5122
    int ra = rA(ctx->opcode);
5123

    
5124
    /* NIP cannot be restored if the memory exception comes from an helper */
5125
    gen_update_nip(ctx, ctx->nip - 4);
5126
    gen_addr_reg_index(cpu_T[0], ctx);
5127
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
5128
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
5129
    op_POWER2_stfq();
5130
    if (ra != 0)
5131
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
5132
}
5133

    
5134
/* stfqx */
5135
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
5136
{
5137
    /* NIP cannot be restored if the memory exception comes from an helper */
5138
    gen_update_nip(ctx, ctx->nip - 4);
5139
    gen_addr_reg_index(cpu_T[0], ctx);
5140
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
5141
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
5142
    op_POWER2_stfq();
5143
}
5144

    
5145
/* BookE specific instructions */
5146
/* XXX: not implemented on 440 ? */
5147
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
5148
{
5149
    /* XXX: TODO */
5150
    GEN_EXCP_INVAL(ctx);
5151
}
5152

    
5153
/* XXX: not implemented on 440 ? */
5154
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
5155
{
5156
#if defined(CONFIG_USER_ONLY)
5157
    GEN_EXCP_PRIVOPC(ctx);
5158
#else
5159
    if (unlikely(!ctx->supervisor)) {
5160
        GEN_EXCP_PRIVOPC(ctx);
5161
        return;
5162
    }
5163
    gen_addr_reg_index(cpu_T[0], ctx);
5164
    /* Use the same micro-ops as for tlbie */
5165
#if defined(TARGET_PPC64)
5166
    if (ctx->sf_mode)
5167
        gen_op_tlbie_64();
5168
    else
5169
#endif
5170
        gen_op_tlbie();
5171
#endif
5172
}
5173

    
5174
/* All 405 MAC instructions are translated here */
5175
static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
5176
                                                int opc2, int opc3,
5177
                                                int ra, int rb, int rt, int Rc)
5178
{
5179
    TCGv t0, t1;
5180

    
5181
    t0 = tcg_temp_local_new(TCG_TYPE_TL);
5182
    t1 = tcg_temp_local_new(TCG_TYPE_TL);
5183

    
5184
    switch (opc3 & 0x0D) {
5185
    case 0x05:
5186
        /* macchw    - macchw.    - macchwo   - macchwo.   */
5187
        /* macchws   - macchws.   - macchwso  - macchwso.  */
5188
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5189
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5190
        /* mulchw - mulchw. */
5191
        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5192
        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5193
        tcg_gen_ext16s_tl(t1, t1);
5194
        break;
5195
    case 0x04:
5196
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5197
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5198
        /* mulchwu - mulchwu. */
5199
        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5200
        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5201
        tcg_gen_ext16u_tl(t1, t1);
5202
        break;
5203
    case 0x01:
5204
        /* machhw    - machhw.    - machhwo   - machhwo.   */
5205
        /* machhws   - machhws.   - machhwso  - machhwso.  */
5206
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5207
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5208
        /* mulhhw - mulhhw. */
5209
        tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
5210
        tcg_gen_ext16s_tl(t0, t0);
5211
        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5212
        tcg_gen_ext16s_tl(t1, t1);
5213
        break;
5214
    case 0x00:
5215
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5216
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5217
        /* mulhhwu - mulhhwu. */
5218
        tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
5219
        tcg_gen_ext16u_tl(t0, t0);
5220
        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5221
        tcg_gen_ext16u_tl(t1, t1);
5222
        break;
5223
    case 0x0D:
5224
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5225
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5226
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5227
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5228
        /* mullhw - mullhw. */
5229
        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5230
        tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
5231
        break;
5232
    case 0x0C:
5233
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5234
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5235
        /* mullhwu - mullhwu. */
5236
        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5237
        tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
5238
        break;
5239
    }
5240
    if (opc2 & 0x04) {
5241
        /* (n)multiply-and-accumulate (0x0C / 0x0E) */
5242
        tcg_gen_mul_tl(t1, t0, t1);
5243
        if (opc2 & 0x02) {
5244
            /* nmultiply-and-accumulate (0x0E) */
5245
            tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
5246
        } else {
5247
            /* multiply-and-accumulate (0x0C) */
5248
            tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
5249
        }
5250

    
5251
        if (opc3 & 0x12) {
5252
            /* Check overflow and/or saturate */
5253
            int l1 = gen_new_label();
5254

    
5255
            if (opc3 & 0x10) {
5256
                /* Start with XER OV disabled, the most likely case */
5257
                tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
5258
            }
5259
            if (opc3 & 0x01) {
5260
                /* Signed */
5261
                tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
5262
                tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
5263
                tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
5264
                tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
5265
                if (opc3 & 0x02) {
5266
                    /* Saturate */
5267
                    tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
5268
                    tcg_gen_xori_tl(t0, t0, 0x7fffffff);
5269
                }
5270
            } else {
5271
                /* Unsigned */
5272
                tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5273
                if (opc3 & 0x02) {
5274
                    /* Saturate */
5275
                    tcg_gen_movi_tl(t0, UINT32_MAX);
5276
                }
5277
            }
5278
            if (opc3 & 0x10) {
5279
                /* Check overflow */
5280
                tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
5281
            }
5282
            gen_set_label(l1);
5283
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
5284
        }
5285
    } else {
5286
        tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
5287
    }
5288
    tcg_temp_free(t0);
5289
    tcg_temp_free(t1);
5290
    if (unlikely(Rc) != 0) {
5291
        /* Update Rc0 */
5292
        gen_set_Rc0(ctx, cpu_gpr[rt]);
5293
    }
5294
}
5295

    
5296
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
5297
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
5298
{                                                                             \
5299
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
5300
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
5301
}
5302

    
5303
/* macchw    - macchw.    */
5304
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
5305
/* macchwo   - macchwo.   */
5306
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
5307
/* macchws   - macchws.   */
5308
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
5309
/* macchwso  - macchwso.  */
5310
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
5311
/* macchwsu  - macchwsu.  */
5312
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
5313
/* macchwsuo - macchwsuo. */
5314
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
5315
/* macchwu   - macchwu.   */
5316
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
5317
/* macchwuo  - macchwuo.  */
5318
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
5319
/* machhw    - machhw.    */
5320
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
5321
/* machhwo   - machhwo.   */
5322
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
5323
/* machhws   - machhws.   */
5324
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
5325
/* machhwso  - machhwso.  */
5326
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
5327
/* machhwsu  - machhwsu.  */
5328
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
5329
/* machhwsuo - machhwsuo. */
5330
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
5331
/* machhwu   - machhwu.   */
5332
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
5333
/* machhwuo  - machhwuo.  */
5334
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
5335
/* maclhw    - maclhw.    */
5336
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
5337
/* maclhwo   - maclhwo.   */
5338
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
5339
/* maclhws   - maclhws.   */
5340
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
5341
/* maclhwso  - maclhwso.  */
5342
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
5343
/* maclhwu   - maclhwu.   */
5344
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
5345
/* maclhwuo  - maclhwuo.  */
5346
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
5347
/* maclhwsu  - maclhwsu.  */
5348
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
5349
/* maclhwsuo - maclhwsuo. */
5350
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
5351
/* nmacchw   - nmacchw.   */
5352
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
5353
/* nmacchwo  - nmacchwo.  */
5354
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
5355
/* nmacchws  - nmacchws.  */
5356
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
5357
/* nmacchwso - nmacchwso. */
5358
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
5359
/* nmachhw   - nmachhw.   */
5360
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
5361
/* nmachhwo  - nmachhwo.  */
5362
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
5363
/* nmachhws  - nmachhws.  */
5364
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
5365
/* nmachhwso - nmachhwso. */
5366
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
5367
/* nmaclhw   - nmaclhw.   */
5368
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
5369
/* nmaclhwo  - nmaclhwo.  */
5370
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
5371
/* nmaclhws  - nmaclhws.  */
5372
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
5373
/* nmaclhwso - nmaclhwso. */
5374
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
5375

    
5376
/* mulchw  - mulchw.  */
5377
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
5378
/* mulchwu - mulchwu. */
5379
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
5380
/* mulhhw  - mulhhw.  */
5381
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
5382
/* mulhhwu - mulhhwu. */
5383
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
5384
/* mullhw  - mullhw.  */
5385
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
5386
/* mullhwu - mullhwu. */
5387
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
5388

    
5389
/* mfdcr */
5390
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
5391
{
5392
#if defined(CONFIG_USER_ONLY)
5393
    GEN_EXCP_PRIVREG(ctx);
5394
#else
5395
    uint32_t dcrn = SPR(ctx->opcode);
5396

    
5397
    if (unlikely(!ctx->supervisor)) {
5398
        GEN_EXCP_PRIVREG(ctx);
5399
        return;
5400
    }
5401
    tcg_gen_movi_tl(cpu_T[0], dcrn);
5402
    gen_op_load_dcr();
5403
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5404
#endif
5405
}
5406

    
5407
/* mtdcr */
5408
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
5409
{
5410
#if defined(CONFIG_USER_ONLY)
5411
    GEN_EXCP_PRIVREG(ctx);
5412
#else
5413
    uint32_t dcrn = SPR(ctx->opcode);
5414

    
5415
    if (unlikely(!ctx->supervisor)) {
5416
        GEN_EXCP_PRIVREG(ctx);
5417
        return;
5418
    }
5419
    tcg_gen_movi_tl(cpu_T[0], dcrn);
5420
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5421
    gen_op_store_dcr();
5422
#endif
5423
}
5424

    
5425
/* mfdcrx */
5426
/* XXX: not implemented on 440 ? */
5427
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
5428
{
5429
#if defined(CONFIG_USER_ONLY)
5430
    GEN_EXCP_PRIVREG(ctx);
5431
#else
5432
    if (unlikely(!ctx->supervisor)) {
5433
        GEN_EXCP_PRIVREG(ctx);
5434
        return;
5435
    }
5436
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5437
    gen_op_load_dcr();
5438
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5439
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5440
#endif
5441
}
5442

    
5443
/* mtdcrx */
5444
/* XXX: not implemented on 440 ? */
5445
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
5446
{
5447
#if defined(CONFIG_USER_ONLY)
5448
    GEN_EXCP_PRIVREG(ctx);
5449
#else
5450
    if (unlikely(!ctx->supervisor)) {
5451
        GEN_EXCP_PRIVREG(ctx);
5452
        return;
5453
    }
5454
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5455
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5456
    gen_op_store_dcr();
5457
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5458
#endif
5459
}
5460

    
5461
/* mfdcrux (PPC 460) : user-mode access to DCR */
5462
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
5463
{
5464
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5465
    gen_op_load_dcr();
5466
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5467
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5468
}
5469

    
5470
/* mtdcrux (PPC 460) : user-mode access to DCR */
5471
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
5472
{
5473
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5474
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5475
    gen_op_store_dcr();
5476
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5477
}
5478

    
5479
/* dccci */
5480
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
5481
{
5482
#if defined(CONFIG_USER_ONLY)
5483
    GEN_EXCP_PRIVOPC(ctx);
5484
#else
5485
    if (unlikely(!ctx->supervisor)) {
5486
        GEN_EXCP_PRIVOPC(ctx);
5487
        return;
5488
    }
5489
    /* interpreted as no-op */
5490
#endif
5491
}
5492

    
5493
/* dcread */
5494
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
5495
{
5496
#if defined(CONFIG_USER_ONLY)
5497
    GEN_EXCP_PRIVOPC(ctx);
5498
#else
5499
    TCGv EA, val;
5500
    if (unlikely(!ctx->supervisor)) {
5501
        GEN_EXCP_PRIVOPC(ctx);
5502
        return;
5503
    }
5504
    EA = tcg_temp_new(TCG_TYPE_TL);
5505
    gen_addr_reg_index(EA, ctx);
5506
    val = tcg_temp_new(TCG_TYPE_TL);
5507
    gen_qemu_ld32u(val, EA, ctx->mem_idx);
5508
    tcg_temp_free(val);
5509
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
5510
    tcg_temp_free(EA);
5511
#endif
5512
}
5513

    
5514
/* icbt */
5515
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
5516
{
5517
    /* interpreted as no-op */
5518
    /* XXX: specification say this is treated as a load by the MMU
5519
     *      but does not generate any exception
5520
     */
5521
}
5522

    
5523
/* iccci */
5524
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
5525
{
5526
#if defined(CONFIG_USER_ONLY)
5527
    GEN_EXCP_PRIVOPC(ctx);
5528
#else
5529
    if (unlikely(!ctx->supervisor)) {
5530
        GEN_EXCP_PRIVOPC(ctx);
5531
        return;
5532
    }
5533
    /* interpreted as no-op */
5534
#endif
5535
}
5536

    
5537
/* icread */
5538
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
5539
{
5540
#if defined(CONFIG_USER_ONLY)
5541
    GEN_EXCP_PRIVOPC(ctx);
5542
#else
5543
    if (unlikely(!ctx->supervisor)) {
5544
        GEN_EXCP_PRIVOPC(ctx);
5545
        return;
5546
    }
5547
    /* interpreted as no-op */
5548
#endif
5549
}
5550

    
5551
/* rfci (supervisor only) */
5552
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
5553
{
5554
#if defined(CONFIG_USER_ONLY)
5555
    GEN_EXCP_PRIVOPC(ctx);
5556
#else
5557
    if (unlikely(!ctx->supervisor)) {
5558
        GEN_EXCP_PRIVOPC(ctx);
5559
        return;
5560
    }
5561
    /* Restore CPU state */
5562
    gen_op_40x_rfci();
5563
    GEN_SYNC(ctx);
5564
#endif
5565
}
5566

    
5567
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
5568
{
5569
#if defined(CONFIG_USER_ONLY)
5570
    GEN_EXCP_PRIVOPC(ctx);
5571
#else
5572
    if (unlikely(!ctx->supervisor)) {
5573
        GEN_EXCP_PRIVOPC(ctx);
5574
        return;
5575
    }
5576
    /* Restore CPU state */
5577
    gen_op_rfci();
5578
    GEN_SYNC(ctx);
5579
#endif
5580
}
5581

    
5582
/* BookE specific */
5583
/* XXX: not implemented on 440 ? */
5584
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
5585
{
5586
#if defined(CONFIG_USER_ONLY)
5587
    GEN_EXCP_PRIVOPC(ctx);
5588
#else
5589
    if (unlikely(!ctx->supervisor)) {
5590
        GEN_EXCP_PRIVOPC(ctx);
5591
        return;
5592
    }
5593
    /* Restore CPU state */
5594
    gen_op_rfdi();
5595
    GEN_SYNC(ctx);
5596
#endif
5597
}
5598

    
5599
/* XXX: not implemented on 440 ? */
5600
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
5601
{
5602
#if defined(CONFIG_USER_ONLY)
5603
    GEN_EXCP_PRIVOPC(ctx);
5604
#else
5605
    if (unlikely(!ctx->supervisor)) {
5606
        GEN_EXCP_PRIVOPC(ctx);
5607
        return;
5608
    }
5609
    /* Restore CPU state */
5610
    gen_op_rfmci();
5611
    GEN_SYNC(ctx);
5612
#endif
5613
}
5614

    
5615
/* TLB management - PowerPC 405 implementation */
5616
/* tlbre */
5617
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
5618
{
5619
#if defined(CONFIG_USER_ONLY)
5620
    GEN_EXCP_PRIVOPC(ctx);
5621
#else
5622
    if (unlikely(!ctx->supervisor)) {
5623
        GEN_EXCP_PRIVOPC(ctx);
5624
        return;
5625
    }
5626
    switch (rB(ctx->opcode)) {
5627
    case 0:
5628
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5629
        gen_op_4xx_tlbre_hi();
5630
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5631
        break;
5632
    case 1:
5633
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5634
        gen_op_4xx_tlbre_lo();
5635
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5636
        break;
5637
    default:
5638
        GEN_EXCP_INVAL(ctx);
5639
        break;
5640
    }
5641
#endif
5642
}
5643

    
5644
/* tlbsx - tlbsx. */
5645
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5646
{
5647
#if defined(CONFIG_USER_ONLY)
5648
    GEN_EXCP_PRIVOPC(ctx);
5649
#else
5650
    if (unlikely(!ctx->supervisor)) {
5651
        GEN_EXCP_PRIVOPC(ctx);
5652
        return;
5653
    }
5654
    gen_addr_reg_index(cpu_T[0], ctx);
5655
    gen_op_4xx_tlbsx();
5656
    if (Rc(ctx->opcode))
5657
        gen_op_4xx_tlbsx_check();
5658
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5659
#endif
5660
}
5661

    
5662
/* tlbwe */
5663
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5664
{
5665
#if defined(CONFIG_USER_ONLY)
5666
    GEN_EXCP_PRIVOPC(ctx);
5667
#else
5668
    if (unlikely(!ctx->supervisor)) {
5669
        GEN_EXCP_PRIVOPC(ctx);
5670
        return;
5671
    }
5672
    switch (rB(ctx->opcode)) {
5673
    case 0:
5674
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5675
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5676
        gen_op_4xx_tlbwe_hi();
5677
        break;
5678
    case 1:
5679
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5680
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5681
        gen_op_4xx_tlbwe_lo();
5682
        break;
5683
    default:
5684
        GEN_EXCP_INVAL(ctx);
5685
        break;
5686
    }
5687
#endif
5688
}
5689

    
5690
/* TLB management - PowerPC 440 implementation */
5691
/* tlbre */
5692
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5693
{
5694
#if defined(CONFIG_USER_ONLY)
5695
    GEN_EXCP_PRIVOPC(ctx);
5696
#else
5697
    if (unlikely(!ctx->supervisor)) {
5698
        GEN_EXCP_PRIVOPC(ctx);
5699
        return;
5700
    }
5701
    switch (rB(ctx->opcode)) {
5702
    case 0:
5703
    case 1:
5704
    case 2:
5705
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5706
        gen_op_440_tlbre(rB(ctx->opcode));
5707
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5708
        break;
5709
    default:
5710
        GEN_EXCP_INVAL(ctx);
5711
        break;
5712
    }
5713
#endif
5714
}
5715

    
5716
/* tlbsx - tlbsx. */
5717
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5718
{
5719
#if defined(CONFIG_USER_ONLY)
5720
    GEN_EXCP_PRIVOPC(ctx);
5721
#else
5722
    if (unlikely(!ctx->supervisor)) {
5723
        GEN_EXCP_PRIVOPC(ctx);
5724
        return;
5725
    }
5726
    gen_addr_reg_index(cpu_T[0], ctx);
5727
    gen_op_440_tlbsx();
5728
    if (Rc(ctx->opcode))
5729
        gen_op_4xx_tlbsx_check();
5730
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
5731
#endif
5732
}
5733

    
5734
/* tlbwe */
5735
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5736
{
5737
#if defined(CONFIG_USER_ONLY)
5738
    GEN_EXCP_PRIVOPC(ctx);
5739
#else
5740
    if (unlikely(!ctx->supervisor)) {
5741
        GEN_EXCP_PRIVOPC(ctx);
5742
        return;
5743
    }
5744
    switch (rB(ctx->opcode)) {
5745
    case 0:
5746
    case 1:
5747
    case 2:
5748
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
5749
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
5750
        gen_op_440_tlbwe(rB(ctx->opcode));
5751
        break;
5752
    default:
5753
        GEN_EXCP_INVAL(ctx);
5754
        break;
5755
    }
5756
#endif
5757
}
5758

    
5759
/* wrtee */
5760
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
5761
{
5762
#if defined(CONFIG_USER_ONLY)
5763
    GEN_EXCP_PRIVOPC(ctx);
5764
#else
5765
    if (unlikely(!ctx->supervisor)) {
5766
        GEN_EXCP_PRIVOPC(ctx);
5767
        return;
5768
    }
5769
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rD(ctx->opcode)]);
5770
    gen_op_wrte();
5771
    /* Stop translation to have a chance to raise an exception
5772
     * if we just set msr_ee to 1
5773
     */
5774
    GEN_STOP(ctx);
5775
#endif
5776
}
5777

    
5778
/* wrteei */
5779
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
5780
{
5781
#if defined(CONFIG_USER_ONLY)
5782
    GEN_EXCP_PRIVOPC(ctx);
5783
#else
5784
    if (unlikely(!ctx->supervisor)) {
5785
        GEN_EXCP_PRIVOPC(ctx);
5786
        return;
5787
    }
5788
    tcg_gen_movi_tl(cpu_T[0], ctx->opcode & 0x00010000);
5789
    gen_op_wrte();
5790
    /* Stop translation to have a chance to raise an exception
5791
     * if we just set msr_ee to 1
5792
     */
5793
    GEN_STOP(ctx);
5794
#endif
5795
}
5796

    
5797
/* PowerPC 440 specific instructions */
5798
/* dlmzb */
5799
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5800
{
5801
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
5802
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
5803
    gen_op_440_dlmzb();
5804
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
5805
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
5806
    tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
5807
    if (Rc(ctx->opcode)) {
5808
        gen_op_440_dlmzb_update_Rc();
5809
        tcg_gen_andi_i32(cpu_crf[0], cpu_T[0], 0xf);
5810
    }
5811
}
5812

    
5813
/* mbar replaces eieio on 440 */
5814
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5815
{
5816
    /* interpreted as no-op */
5817
}
5818

    
5819
/* msync replaces sync on 440 */
5820
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5821
{
5822
    /* interpreted as no-op */
5823
}
5824

    
5825
/* icbt */
5826
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5827
{
5828
    /* interpreted as no-op */
5829
    /* XXX: specification say this is treated as a load by the MMU
5830
     *      but does not generate any exception
5831
     */
5832
}
5833

    
5834
/***                      Altivec vector extension                         ***/
5835
/* Altivec registers moves */
5836

    
5837
static always_inline void gen_load_avr(int t, int reg) {
5838
    tcg_gen_mov_i64(cpu_AVRh[t], cpu_avrh[reg]);
5839
    tcg_gen_mov_i64(cpu_AVRl[t], cpu_avrl[reg]);
5840
}
5841

    
5842
static always_inline void gen_store_avr(int reg, int t) {
5843
    tcg_gen_mov_i64(cpu_avrh[reg], cpu_AVRh[t]);
5844
    tcg_gen_mov_i64(cpu_avrl[reg], cpu_AVRl[t]);
5845
}
5846

    
5847
#define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5848
#define OP_VR_LD_TABLE(name)                                                  \
5849
static GenOpFunc *gen_op_vr_l##name[NB_MEM_FUNCS] = {                         \
5850
    GEN_MEM_FUNCS(vr_l##name),                                                \
5851
};
5852
#define OP_VR_ST_TABLE(name)                                                  \
5853
static GenOpFunc *gen_op_vr_st##name[NB_MEM_FUNCS] = {                        \
5854
    GEN_MEM_FUNCS(vr_st##name),                                               \
5855
};
5856

    
5857
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5858
GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
5859
{                                                                             \
5860
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5861
        GEN_EXCP_NO_VR(ctx);                                                  \
5862
        return;                                                               \
5863
    }                                                                         \
5864
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
5865
    op_vr_ldst(vr_l##name);                                                   \
5866
    gen_store_avr(rD(ctx->opcode), 0);                                        \
5867
}
5868

    
5869
#define GEN_VR_STX(name, opc2, opc3)                                          \
5870
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
5871
{                                                                             \
5872
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5873
        GEN_EXCP_NO_VR(ctx);                                                  \
5874
        return;                                                               \
5875
    }                                                                         \
5876
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
5877
    gen_load_avr(0, rS(ctx->opcode));                                         \
5878
    op_vr_ldst(vr_st##name);                                                  \
5879
}
5880

    
5881
OP_VR_LD_TABLE(vx);
5882
GEN_VR_LDX(vx, 0x07, 0x03);
5883
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
5884
#define gen_op_vr_lvxl gen_op_vr_lvx
5885
GEN_VR_LDX(vxl, 0x07, 0x0B);
5886

    
5887
OP_VR_ST_TABLE(vx);
5888
GEN_VR_STX(vx, 0x07, 0x07);
5889
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
5890
#define gen_op_vr_stvxl gen_op_vr_stvx
5891
GEN_VR_STX(vxl, 0x07, 0x0F);
5892

    
5893
/***                           SPE extension                               ***/
5894
/* Register moves */
5895

    
5896
static always_inline void gen_load_gpr64(TCGv t, int reg) {
5897
#if defined(TARGET_PPC64)
5898
    tcg_gen_mov_i64(t, cpu_gpr[reg]);
5899
#else
5900
    tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
5901
#endif
5902
}
5903

    
5904
static always_inline void gen_store_gpr64(int reg, TCGv t) {
5905
#if defined(TARGET_PPC64)
5906
    tcg_gen_mov_i64(cpu_gpr[reg], t);
5907
#else
5908
    tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
5909
    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
5910
    tcg_gen_shri_i64(tmp, t, 32);
5911
    tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
5912
    tcg_temp_free(tmp);
5913
#endif
5914
}
5915

    
5916
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5917
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5918
{                                                                             \
5919
    if (Rc(ctx->opcode))                                                      \
5920
        gen_##name1(ctx);                                                     \
5921
    else                                                                      \
5922
        gen_##name0(ctx);                                                     \
5923
}
5924

    
5925
/* Handler for undefined SPE opcodes */
5926
static always_inline void gen_speundef (DisasContext *ctx)
5927
{
5928
    GEN_EXCP_INVAL(ctx);
5929
}
5930

    
5931
/* SPE load and stores */
5932
static always_inline void gen_addr_spe_imm_index (TCGv EA, DisasContext *ctx, int sh)
5933
{
5934
    target_long simm = rB(ctx->opcode);
5935

    
5936
    if (rA(ctx->opcode) == 0)
5937
        tcg_gen_movi_tl(EA, simm << sh);
5938
    else if (likely(simm != 0))
5939
        tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm << sh);
5940
    else
5941
        tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
5942
}
5943

    
5944
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5945
#define OP_SPE_LD_TABLE(name)                                                 \
5946
static GenOpFunc *gen_op_spe_l##name[NB_MEM_FUNCS] = {                        \
5947
    GEN_MEM_FUNCS(spe_l##name),                                               \
5948
};
5949
#define OP_SPE_ST_TABLE(name)                                                 \
5950
static GenOpFunc *gen_op_spe_st##name[NB_MEM_FUNCS] = {                       \
5951
    GEN_MEM_FUNCS(spe_st##name),                                              \
5952
};
5953

    
5954
#define GEN_SPE_LD(name, sh)                                                  \
5955
static always_inline void gen_evl##name (DisasContext *ctx)                   \
5956
{                                                                             \
5957
    if (unlikely(!ctx->spe_enabled)) {                                        \
5958
        GEN_EXCP_NO_AP(ctx);                                                  \
5959
        return;                                                               \
5960
    }                                                                         \
5961
    gen_addr_spe_imm_index(cpu_T[0], ctx, sh);                                \
5962
    op_spe_ldst(spe_l##name);                                                 \
5963
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[1]);                             \
5964
}
5965

    
5966
#define GEN_SPE_LDX(name)                                                     \
5967
static always_inline void gen_evl##name##x (DisasContext *ctx)                \
5968
{                                                                             \
5969
    if (unlikely(!ctx->spe_enabled)) {                                        \
5970
        GEN_EXCP_NO_AP(ctx);                                                  \
5971
        return;                                                               \
5972
    }                                                                         \
5973
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
5974
    op_spe_ldst(spe_l##name);                                                 \
5975
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[1]);                             \
5976
}
5977

    
5978
#define GEN_SPEOP_LD(name, sh)                                                \
5979
OP_SPE_LD_TABLE(name);                                                        \
5980
GEN_SPE_LD(name, sh);                                                         \
5981
GEN_SPE_LDX(name)
5982

    
5983
#define GEN_SPE_ST(name, sh)                                                  \
5984
static always_inline void gen_evst##name (DisasContext *ctx)                  \
5985
{                                                                             \
5986
    if (unlikely(!ctx->spe_enabled)) {                                        \
5987
        GEN_EXCP_NO_AP(ctx);                                                  \
5988
        return;                                                               \
5989
    }                                                                         \
5990
    gen_addr_spe_imm_index(cpu_T[0], ctx, sh);                                \
5991
    gen_load_gpr64(cpu_T64[1], rS(ctx->opcode));                              \
5992
    op_spe_ldst(spe_st##name);                                                \
5993
}
5994

    
5995
#define GEN_SPE_STX(name)                                                     \
5996
static always_inline void gen_evst##name##x (DisasContext *ctx)               \
5997
{                                                                             \
5998
    if (unlikely(!ctx->spe_enabled)) {                                        \
5999
        GEN_EXCP_NO_AP(ctx);                                                  \
6000
        return;                                                               \
6001
    }                                                                         \
6002
    gen_addr_reg_index(cpu_T[0], ctx);                                        \
6003
    gen_load_gpr64(cpu_T64[1], rS(ctx->opcode));                              \
6004
    op_spe_ldst(spe_st##name);                                                \
6005
}
6006

    
6007
#define GEN_SPEOP_ST(name, sh)                                                \
6008
OP_SPE_ST_TABLE(name);                                                        \
6009
GEN_SPE_ST(name, sh);                                                         \
6010
GEN_SPE_STX(name)
6011

    
6012
#define GEN_SPEOP_LDST(name, sh)                                              \
6013
GEN_SPEOP_LD(name, sh);                                                       \
6014
GEN_SPEOP_ST(name, sh)
6015

    
6016
/* SPE arithmetic and logic */
6017
#define GEN_SPEOP_ARITH2(name)                                                \
6018
static always_inline void gen_##name (DisasContext *ctx)                      \
6019
{                                                                             \
6020
    if (unlikely(!ctx->spe_enabled)) {                                        \
6021
        GEN_EXCP_NO_AP(ctx);                                                  \
6022
        return;                                                               \
6023
    }                                                                         \
6024
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
6025
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
6026
    gen_op_##name();                                                          \
6027
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
6028
}
6029

    
6030
#define GEN_SPEOP_TCG_ARITH2(name, tcg_op)                                    \
6031
static always_inline void gen_##name (DisasContext *ctx)                      \
6032
{                                                                             \
6033
    if (unlikely(!ctx->spe_enabled)) {                                        \
6034
        GEN_EXCP_NO_AP(ctx);                                                  \
6035
        return;                                                               \
6036
    }                                                                         \
6037
    TCGv t0 = tcg_temp_new(TCG_TYPE_I64);                                     \
6038
    TCGv t1 = tcg_temp_new(TCG_TYPE_I64);                                     \
6039
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
6040
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
6041
    tcg_op(t0, t0, t1);                                                       \
6042
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
6043
    tcg_temp_free(t0);                                                        \
6044
    tcg_temp_free(t1);                                                        \
6045
}
6046

    
6047
#define GEN_SPEOP_ARITH1(name)                                                \
6048
static always_inline void gen_##name (DisasContext *ctx)                      \
6049
{                                                                             \
6050
    if (unlikely(!ctx->spe_enabled)) {                                        \
6051
        GEN_EXCP_NO_AP(ctx);                                                  \
6052
        return;                                                               \
6053
    }                                                                         \
6054
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
6055
    gen_op_##name();                                                          \
6056
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
6057
}
6058

    
6059
#define GEN_SPEOP_COMP(name)                                                  \
6060
static always_inline void gen_##name (DisasContext *ctx)                      \
6061
{                                                                             \
6062
    if (unlikely(!ctx->spe_enabled)) {                                        \
6063
        GEN_EXCP_NO_AP(ctx);                                                  \
6064
        return;                                                               \
6065
    }                                                                         \
6066
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
6067
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
6068
    gen_op_##name();                                                          \
6069
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);              \
6070
}
6071

    
6072
/* Logical */
6073
GEN_SPEOP_TCG_ARITH2(evand, tcg_gen_and_i64);
6074
GEN_SPEOP_TCG_ARITH2(evandc, tcg_gen_andc_i64);
6075
GEN_SPEOP_TCG_ARITH2(evxor, tcg_gen_xor_i64);
6076
GEN_SPEOP_TCG_ARITH2(evor, tcg_gen_or_i64);
6077
GEN_SPEOP_TCG_ARITH2(evnor, tcg_gen_nor_i64);
6078
GEN_SPEOP_TCG_ARITH2(eveqv, tcg_gen_eqv_i64);
6079
GEN_SPEOP_TCG_ARITH2(evorc, tcg_gen_orc_i64);
6080
GEN_SPEOP_TCG_ARITH2(evnand, tcg_gen_nand_i64);
6081
GEN_SPEOP_ARITH2(evsrwu);
6082
GEN_SPEOP_ARITH2(evsrws);
6083
GEN_SPEOP_ARITH2(evslw);
6084
GEN_SPEOP_ARITH2(evrlw);
6085
GEN_SPEOP_ARITH2(evmergehi);
6086
GEN_SPEOP_ARITH2(evmergelo);
6087
GEN_SPEOP_ARITH2(evmergehilo);
6088
GEN_SPEOP_ARITH2(evmergelohi);
6089

    
6090
/* Arithmetic */
6091
GEN_SPEOP_ARITH2(evaddw);
6092
GEN_SPEOP_ARITH2(evsubfw);
6093
GEN_SPEOP_ARITH1(evabs);
6094
GEN_SPEOP_ARITH1(evneg);
6095
GEN_SPEOP_ARITH1(evextsb);
6096
GEN_SPEOP_ARITH1(evextsh);
6097
GEN_SPEOP_ARITH1(evrndw);
6098
GEN_SPEOP_ARITH1(evcntlzw);
6099
GEN_SPEOP_ARITH1(evcntlsw);
6100
static always_inline void gen_brinc (DisasContext *ctx)
6101
{
6102
    /* Note: brinc is usable even if SPE is disabled */
6103
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
6104
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
6105
    gen_op_brinc();
6106
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
6107
}
6108

    
6109
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
6110
static always_inline void gen_##name##i (DisasContext *ctx)                   \
6111
{                                                                             \
6112
    if (unlikely(!ctx->spe_enabled)) {                                        \
6113
        GEN_EXCP_NO_AP(ctx);                                                  \
6114
        return;                                                               \
6115
    }                                                                         \
6116
    gen_load_gpr64(cpu_T64[0], rB(ctx->opcode));                              \
6117
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
6118
    gen_op_##name();                                                          \
6119
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
6120
}
6121

    
6122
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
6123
static always_inline void gen_##name##i (DisasContext *ctx)                   \
6124
{                                                                             \
6125
    if (unlikely(!ctx->spe_enabled)) {                                        \
6126
        GEN_EXCP_NO_AP(ctx);                                                  \
6127
        return;                                                               \
6128
    }                                                                         \
6129
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
6130
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
6131
    gen_op_##name();                                                          \
6132
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
6133
}
6134

    
6135
GEN_SPEOP_ARITH_IMM2(evaddw);
6136
#define gen_evaddiw gen_evaddwi
6137
GEN_SPEOP_ARITH_IMM2(evsubfw);
6138
#define gen_evsubifw gen_evsubfwi
6139
GEN_SPEOP_LOGIC_IMM2(evslw);
6140
GEN_SPEOP_LOGIC_IMM2(evsrwu);
6141
#define gen_evsrwis gen_evsrwsi
6142
GEN_SPEOP_LOGIC_IMM2(evsrws);
6143
#define gen_evsrwiu gen_evsrwui
6144
GEN_SPEOP_LOGIC_IMM2(evrlw);
6145

    
6146
static always_inline void gen_evsplati (DisasContext *ctx)
6147
{
6148
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
6149

    
6150
    gen_op_splatwi_T0_64(imm);
6151
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
6152
}
6153

    
6154
static always_inline void gen_evsplatfi (DisasContext *ctx)
6155
{
6156
    uint32_t imm = rA(ctx->opcode) << 27;
6157

    
6158
    gen_op_splatwi_T0_64(imm);
6159
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
6160
}
6161

    
6162
/* Comparison */
6163
GEN_SPEOP_COMP(evcmpgtu);
6164
GEN_SPEOP_COMP(evcmpgts);
6165
GEN_SPEOP_COMP(evcmpltu);
6166
GEN_SPEOP_COMP(evcmplts);
6167
GEN_SPEOP_COMP(evcmpeq);
6168

    
6169
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
6170
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
6171
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
6172
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
6173
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
6174
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
6175
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
6176
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
6177
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
6178
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
6179
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
6180
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
6181
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
6182
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
6183
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
6184
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
6185
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
6186
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
6187
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
6188
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
6189
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
6190
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
6191
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
6192
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
6193
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
6194

    
6195
static always_inline void gen_evsel (DisasContext *ctx)
6196
{
6197
    if (unlikely(!ctx->spe_enabled)) {
6198
        GEN_EXCP_NO_AP(ctx);
6199
        return;
6200
    }
6201
    tcg_gen_mov_i32(cpu_T[0], cpu_crf[ctx->opcode & 0x7]);
6202
    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));
6203
    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));
6204
    gen_op_evsel();
6205
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
6206
}
6207

    
6208
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
6209
{
6210
    gen_evsel(ctx);
6211
}
6212
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
6213
{
6214
    gen_evsel(ctx);
6215
}
6216
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
6217
{
6218
    gen_evsel(ctx);
6219
}
6220
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
6221
{
6222
    gen_evsel(ctx);
6223
}
6224

    
6225
/* Load and stores */
6226
GEN_SPEOP_LDST(dd, 3);
6227
GEN_SPEOP_LDST(dw, 3);
6228
GEN_SPEOP_LDST(dh, 3);
6229
GEN_SPEOP_LDST(whe, 2);
6230
GEN_SPEOP_LD(whou, 2);
6231
GEN_SPEOP_LD(whos, 2);
6232
GEN_SPEOP_ST(who, 2);
6233

    
6234
#define _GEN_OP_SPE_STWWE(suffix)                                             \
6235
static always_inline void gen_op_spe_stwwe_##suffix (void)                    \
6236
{                                                                             \
6237
    gen_op_srli32_T1_64();                                                    \
6238
    gen_op_spe_stwwo_##suffix();                                              \
6239
}
6240
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
6241
static always_inline void gen_op_spe_stwwe_le_##suffix (void)                 \
6242
{                                                                             \
6243
    gen_op_srli32_T1_64();                                                    \
6244
    gen_op_spe_stwwo_le_##suffix();                                           \
6245
}
6246
#if defined(TARGET_PPC64)
6247
#define GEN_OP_SPE_STWWE(suffix)                                              \
6248
_GEN_OP_SPE_STWWE(suffix);                                                    \
6249
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
6250
static always_inline void gen_op_spe_stwwe_64_##suffix (void)                 \
6251
{                                                                             \
6252
    gen_op_srli32_T1_64();                                                    \
6253
    gen_op_spe_stwwo_64_##suffix();                                           \
6254
}                                                                             \
6255
static always_inline void gen_op_spe_stwwe_le_64_##suffix (void)              \
6256
{                                                                             \
6257
    gen_op_srli32_T1_64();                                                    \
6258
    gen_op_spe_stwwo_le_64_##suffix();                                        \
6259
}
6260
#else
6261
#define GEN_OP_SPE_STWWE(suffix)                                              \
6262
_GEN_OP_SPE_STWWE(suffix);                                                    \
6263
_GEN_OP_SPE_STWWE_LE(suffix)
6264
#endif
6265
#if defined(CONFIG_USER_ONLY)
6266
GEN_OP_SPE_STWWE(raw);
6267
#else /* defined(CONFIG_USER_ONLY) */
6268
GEN_OP_SPE_STWWE(user);
6269
GEN_OP_SPE_STWWE(kernel);
6270
GEN_OP_SPE_STWWE(hypv);
6271
#endif /* defined(CONFIG_USER_ONLY) */
6272
GEN_SPEOP_ST(wwe, 2);
6273
GEN_SPEOP_ST(wwo, 2);
6274

    
6275
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
6276
static always_inline void gen_op_spe_l##name##_##suffix (void)                \
6277
{                                                                             \
6278
    gen_op_##op##_##suffix();                                                 \
6279
    gen_op_splatw_T1_64();                                                    \
6280
}
6281

    
6282
#define GEN_OP_SPE_LHE(suffix)                                                \
6283
static always_inline void gen_op_spe_lhe_##suffix (void)                      \
6284
{                                                                             \
6285
    gen_op_spe_lh_##suffix();                                                 \
6286
    gen_op_sli16_T1_64();                                                     \
6287
}
6288

    
6289
#define GEN_OP_SPE_LHX(suffix)                                                \
6290
static always_inline void gen_op_spe_lhx_##suffix (void)                      \
6291
{                                                                             \
6292
    gen_op_spe_lh_##suffix();                                                 \
6293
    gen_op_extsh_T1_64();                                                     \
6294
}
6295

    
6296
#if defined(CONFIG_USER_ONLY)
6297
GEN_OP_SPE_LHE(raw);
6298
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
6299
GEN_OP_SPE_LHE(le_raw);
6300
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
6301
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
6302
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
6303
GEN_OP_SPE_LHX(raw);
6304
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
6305
GEN_OP_SPE_LHX(le_raw);
6306
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
6307
#if defined(TARGET_PPC64)
6308
GEN_OP_SPE_LHE(64_raw);
6309
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
6310
GEN_OP_SPE_LHE(le_64_raw);
6311
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
6312
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
6313
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
6314
GEN_OP_SPE_LHX(64_raw);
6315
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
6316
GEN_OP_SPE_LHX(le_64_raw);
6317
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
6318
#endif
6319
#else
6320
GEN_OP_SPE_LHE(user);
6321
GEN_OP_SPE_LHE(kernel);
6322
GEN_OP_SPE_LHE(hypv);
6323
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
6324
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
6325
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv);
6326
GEN_OP_SPE_LHE(le_user);
6327
GEN_OP_SPE_LHE(le_kernel);
6328
GEN_OP_SPE_LHE(le_hypv);
6329
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
6330
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
6331
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv);
6332
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
6333
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
6334
GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv);
6335
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
6336
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
6337
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv);
6338
GEN_OP_SPE_LHX(user);
6339
GEN_OP_SPE_LHX(kernel);
6340
GEN_OP_SPE_LHX(hypv);
6341
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
6342
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
6343
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv);
6344
GEN_OP_SPE_LHX(le_user);
6345
GEN_OP_SPE_LHX(le_kernel);
6346
GEN_OP_SPE_LHX(le_hypv);
6347
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
6348
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
6349
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv);
6350
#if defined(TARGET_PPC64)
6351
GEN_OP_SPE_LHE(64_user);
6352
GEN_OP_SPE_LHE(64_kernel);
6353
GEN_OP_SPE_LHE(64_hypv);
6354
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
6355
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
6356
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv);
6357
GEN_OP_SPE_LHE(le_64_user);
6358
GEN_OP_SPE_LHE(le_64_kernel);
6359
GEN_OP_SPE_LHE(le_64_hypv);
6360
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
6361
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
6362
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv);
6363
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
6364
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
6365
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv);
6366
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
6367
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
6368
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv);
6369
GEN_OP_SPE_LHX(64_user);
6370
GEN_OP_SPE_LHX(64_kernel);
6371
GEN_OP_SPE_LHX(64_hypv);
6372
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
6373
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
6374
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv);
6375
GEN_OP_SPE_LHX(le_64_user);
6376
GEN_OP_SPE_LHX(le_64_kernel);
6377
GEN_OP_SPE_LHX(le_64_hypv);
6378
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
6379
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
6380
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv);
6381
#endif
6382
#endif
6383
GEN_SPEOP_LD(hhesplat, 1);
6384
GEN_SPEOP_LD(hhousplat, 1);
6385
GEN_SPEOP_LD(hhossplat, 1);
6386
GEN_SPEOP_LD(wwsplat, 2);
6387
GEN_SPEOP_LD(whsplat, 2);
6388

    
6389
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
6390
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
6391
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
6392
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
6393
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
6394
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
6395
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
6396
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
6397
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
6398
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
6399
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
6400
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
6401
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
6402
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
6403
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
6404
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
6405
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
6406
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
6407

    
6408
/* Multiply and add - TODO */
6409
#if 0
6410
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
6411
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
6412
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
6413
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
6414
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
6415
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
6416
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
6417
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
6418
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
6419
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
6420
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
6421
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
6422

6423
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
6424
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
6425
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
6426
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
6427
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
6428
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
6429
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
6430
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
6431
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
6432
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
6433
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
6434
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
6435
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
6436
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
6437

6438
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
6439
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
6440
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
6441
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
6442
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
6443
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
6444

6445
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
6446
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
6447
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
6448
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
6449
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
6450
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
6451
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
6452
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
6453
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
6454
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
6455
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
6456
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
6457

6458
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
6459
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
6460
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
6461
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
6462
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
6463

6464
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
6465
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
6466
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
6467
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
6468
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
6469
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
6470
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
6471
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
6472
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
6473
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
6474
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
6475
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
6476

6477
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
6478
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
6479
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
6480
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
6481
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
6482
#endif
6483

    
6484
/***                      SPE floating-point extension                     ***/
6485
#define GEN_SPEFPUOP_CONV(name)                                               \
6486
static always_inline void gen_##name (DisasContext *ctx)                      \
6487
{                                                                             \
6488
    gen_load_gpr64(cpu_T64[0], rB(ctx->opcode));                              \
6489
    gen_op_##name();                                                          \
6490
    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
6491
}
6492

    
6493
/* Single precision floating-point vectors operations */
6494
/* Arithmetic */
6495
GEN_SPEOP_ARITH2(evfsadd);
6496
GEN_SPEOP_ARITH2(evfssub);
6497
GEN_SPEOP_ARITH2(evfsmul);
6498
GEN_SPEOP_ARITH2(evfsdiv);
6499
GEN_SPEOP_ARITH1(evfsabs);
6500
GEN_SPEOP_ARITH1(evfsnabs);
6501
GEN_SPEOP_ARITH1(evfsneg);
6502
/* Conversion */
6503
GEN_SPEFPUOP_CONV(evfscfui);
6504
GEN_SPEFPUOP_CONV(evfscfsi);
6505
GEN_SPEFPUOP_CONV(evfscfuf);
6506
GEN_SPEFPUOP_CONV(evfscfsf);
6507
GEN_SPEFPUOP_CONV(evfsctui);
6508
GEN_SPEFPUOP_CONV(evfsctsi);
6509
GEN_SPEFPUOP_CONV(evfsctuf);
6510
GEN_SPEFPUOP_CONV(evfsctsf);
6511
GEN_SPEFPUOP_CONV(evfsctuiz);
6512
GEN_SPEFPUOP_CONV(evfsctsiz);
6513
/* Comparison */
6514
GEN_SPEOP_COMP(evfscmpgt);
6515
GEN_SPEOP_COMP(evfscmplt);
6516
GEN_SPEOP_COMP(evfscmpeq);
6517
GEN_SPEOP_COMP(evfststgt);
6518
GEN_SPEOP_COMP(evfststlt);
6519
GEN_SPEOP_COMP(evfststeq);
6520

    
6521
/* Opcodes definitions */
6522
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
6523
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
6524
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
6525
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
6526
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
6527
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
6528
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
6529
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
6530
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
6531
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
6532
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
6533
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
6534
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
6535
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
6536

    
6537
/* Single precision floating-point operations */
6538
/* Arithmetic */
6539
GEN_SPEOP_ARITH2(efsadd);
6540
GEN_SPEOP_ARITH2(efssub);
6541
GEN_SPEOP_ARITH2(efsmul);
6542
GEN_SPEOP_ARITH2(efsdiv);
6543
GEN_SPEOP_ARITH1(efsabs);
6544
GEN_SPEOP_ARITH1(efsnabs);
6545
GEN_SPEOP_ARITH1(efsneg);
6546
/* Conversion */
6547
GEN_SPEFPUOP_CONV(efscfui);
6548
GEN_SPEFPUOP_CONV(efscfsi);
6549
GEN_SPEFPUOP_CONV(efscfuf);
6550
GEN_SPEFPUOP_CONV(efscfsf);
6551
GEN_SPEFPUOP_CONV(efsctui);
6552
GEN_SPEFPUOP_CONV(efsctsi);
6553
GEN_SPEFPUOP_CONV(efsctuf);
6554
GEN_SPEFPUOP_CONV(efsctsf);
6555
GEN_SPEFPUOP_CONV(efsctuiz);
6556
GEN_SPEFPUOP_CONV(efsctsiz);
6557
GEN_SPEFPUOP_CONV(efscfd);
6558
/* Comparison */
6559
GEN_SPEOP_COMP(efscmpgt);
6560
GEN_SPEOP_COMP(efscmplt);
6561
GEN_SPEOP_COMP(efscmpeq);
6562
GEN_SPEOP_COMP(efststgt);
6563
GEN_SPEOP_COMP(efststlt);
6564
GEN_SPEOP_COMP(efststeq);
6565

    
6566
/* Opcodes definitions */
6567
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
6568
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
6569
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
6570
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
6571
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
6572
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
6573
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
6574
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
6575
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
6576
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
6577
GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
6578
GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPEFPU); //
6579
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
6580
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
6581

    
6582
/* Double precision floating-point operations */
6583
/* Arithmetic */
6584
GEN_SPEOP_ARITH2(efdadd);
6585
GEN_SPEOP_ARITH2(efdsub);
6586
GEN_SPEOP_ARITH2(efdmul);
6587
GEN_SPEOP_ARITH2(efddiv);
6588
GEN_SPEOP_ARITH1(efdabs);
6589
GEN_SPEOP_ARITH1(efdnabs);
6590
GEN_SPEOP_ARITH1(efdneg);
6591
/* Conversion */
6592

    
6593
GEN_SPEFPUOP_CONV(efdcfui);
6594
GEN_SPEFPUOP_CONV(efdcfsi);
6595
GEN_SPEFPUOP_CONV(efdcfuf);
6596
GEN_SPEFPUOP_CONV(efdcfsf);
6597
GEN_SPEFPUOP_CONV(efdctui);
6598
GEN_SPEFPUOP_CONV(efdctsi);
6599
GEN_SPEFPUOP_CONV(efdctuf);
6600
GEN_SPEFPUOP_CONV(efdctsf);
6601
GEN_SPEFPUOP_CONV(efdctuiz);
6602
GEN_SPEFPUOP_CONV(efdctsiz);
6603
GEN_SPEFPUOP_CONV(efdcfs);
6604
GEN_SPEFPUOP_CONV(efdcfuid);
6605
GEN_SPEFPUOP_CONV(efdcfsid);
6606
GEN_SPEFPUOP_CONV(efdctuidz);
6607
GEN_SPEFPUOP_CONV(efdctsidz);
6608
/* Comparison */
6609
GEN_SPEOP_COMP(efdcmpgt);
6610
GEN_SPEOP_COMP(efdcmplt);
6611
GEN_SPEOP_COMP(efdcmpeq);
6612
GEN_SPEOP_COMP(efdtstgt);
6613
GEN_SPEOP_COMP(efdtstlt);
6614
GEN_SPEOP_COMP(efdtsteq);
6615

    
6616
/* Opcodes definitions */
6617
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
6618
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
6619
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
6620
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
6621
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
6622
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
6623
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
6624
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
6625
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
6626
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
6627
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
6628
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
6629
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
6630
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
6631
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
6632
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6633

    
6634
/* End opcode list */
6635
GEN_OPCODE_MARK(end);
6636

    
6637
#include "translate_init.c"
6638
#include "helper_regs.h"
6639

    
6640
/*****************************************************************************/
6641
/* Misc PowerPC helpers */
6642
void cpu_dump_state (CPUState *env, FILE *f,
6643
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6644
                     int flags)
6645
{
6646
#define RGPL  4
6647
#define RFPL  4
6648

    
6649
    int i;
6650

    
6651
    cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
6652
                env->nip, env->lr, env->ctr, env->xer);
6653
    cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
6654
                env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
6655
#if !defined(NO_TIMER_DUMP)
6656
    cpu_fprintf(f, "TB %08x %08x "
6657
#if !defined(CONFIG_USER_ONLY)
6658
                "DECR %08x"
6659
#endif
6660
                "\n",
6661
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6662
#if !defined(CONFIG_USER_ONLY)
6663
                , cpu_ppc_load_decr(env)
6664
#endif
6665
                );
6666
#endif
6667
    for (i = 0; i < 32; i++) {
6668
        if ((i & (RGPL - 1)) == 0)
6669
            cpu_fprintf(f, "GPR%02d", i);
6670
        cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
6671
        if ((i & (RGPL - 1)) == (RGPL - 1))
6672
            cpu_fprintf(f, "\n");
6673
    }
6674
    cpu_fprintf(f, "CR ");
6675
    for (i = 0; i < 8; i++)
6676
        cpu_fprintf(f, "%01x", env->crf[i]);
6677
    cpu_fprintf(f, "  [");
6678
    for (i = 0; i < 8; i++) {
6679
        char a = '-';
6680
        if (env->crf[i] & 0x08)
6681
            a = 'L';
6682
        else if (env->crf[i] & 0x04)
6683
            a = 'G';
6684
        else if (env->crf[i] & 0x02)
6685
            a = 'E';
6686
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6687
    }
6688
    cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
6689
    for (i = 0; i < 32; i++) {
6690
        if ((i & (RFPL - 1)) == 0)
6691
            cpu_fprintf(f, "FPR%02d", i);
6692
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6693
        if ((i & (RFPL - 1)) == (RFPL - 1))
6694
            cpu_fprintf(f, "\n");
6695
    }
6696
#if !defined(CONFIG_USER_ONLY)
6697
    cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
6698
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6699
#endif
6700

    
6701
#undef RGPL
6702
#undef RFPL
6703
}
6704

    
6705
void cpu_dump_statistics (CPUState *env, FILE*f,
6706
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6707
                          int flags)
6708
{
6709
#if defined(DO_PPC_STATISTICS)
6710
    opc_handler_t **t1, **t2, **t3, *handler;
6711
    int op1, op2, op3;
6712

    
6713
    t1 = env->opcodes;
6714
    for (op1 = 0; op1 < 64; op1++) {
6715
        handler = t1[op1];
6716
        if (is_indirect_opcode(handler)) {
6717
            t2 = ind_table(handler);
6718
            for (op2 = 0; op2 < 32; op2++) {
6719
                handler = t2[op2];
6720
                if (is_indirect_opcode(handler)) {
6721
                    t3 = ind_table(handler);
6722
                    for (op3 = 0; op3 < 32; op3++) {
6723
                        handler = t3[op3];
6724
                        if (handler->count == 0)
6725
                            continue;
6726
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6727
                                    "%016llx %lld\n",
6728
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6729
                                    handler->oname,
6730
                                    handler->count, handler->count);
6731
                    }
6732
                } else {
6733
                    if (handler->count == 0)
6734
                        continue;
6735
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6736
                                "%016llx %lld\n",
6737
                                op1, op2, op1, op2, handler->oname,
6738
                                handler->count, handler->count);
6739
                }
6740
            }
6741
        } else {
6742
            if (handler->count == 0)
6743
                continue;
6744
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6745
                        op1, op1, handler->oname,
6746
                        handler->count, handler->count);
6747
        }
6748
    }
6749
#endif
6750
}
6751

    
6752
/*****************************************************************************/
6753
static always_inline void gen_intermediate_code_internal (CPUState *env,
6754
                                                          TranslationBlock *tb,
6755
                                                          int search_pc)
6756
{
6757
    DisasContext ctx, *ctxp = &ctx;
6758
    opc_handler_t **table, *handler;
6759
    target_ulong pc_start;
6760
    uint16_t *gen_opc_end;
6761
    int supervisor, little_endian;
6762
    int j, lj = -1;
6763
    int num_insns;
6764
    int max_insns;
6765

    
6766
    pc_start = tb->pc;
6767
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6768
#if defined(OPTIMIZE_FPRF_UPDATE)
6769
    gen_fprf_ptr = gen_fprf_buf;
6770
#endif
6771
    ctx.nip = pc_start;
6772
    ctx.tb = tb;
6773
    ctx.exception = POWERPC_EXCP_NONE;
6774
    ctx.spr_cb = env->spr_cb;
6775
    supervisor = env->mmu_idx;
6776
#if !defined(CONFIG_USER_ONLY)
6777
    ctx.supervisor = supervisor;
6778
#endif
6779
    little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
6780
#if defined(TARGET_PPC64)
6781
    ctx.sf_mode = msr_sf;
6782
    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
6783
#else
6784
    ctx.mem_idx = (supervisor << 1) | little_endian;
6785
#endif
6786
    ctx.dcache_line_size = env->dcache_line_size;
6787
    ctx.fpu_enabled = msr_fp;
6788
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
6789
        ctx.spe_enabled = msr_spe;
6790
    else
6791
        ctx.spe_enabled = 0;
6792
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
6793
        ctx.altivec_enabled = msr_vr;
6794
    else
6795
        ctx.altivec_enabled = 0;
6796
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6797
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
6798
    else
6799
        ctx.singlestep_enabled = 0;
6800
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
6801
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
6802
    if (unlikely(env->singlestep_enabled))
6803
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
6804
#if defined (DO_SINGLE_STEP) && 0
6805
    /* Single step trace mode */
6806
    msr_se = 1;
6807
#endif
6808
    num_insns = 0;
6809
    max_insns = tb->cflags & CF_COUNT_MASK;
6810
    if (max_insns == 0)
6811
        max_insns = CF_COUNT_MASK;
6812

    
6813
    gen_icount_start();
6814
    /* Set env in case of segfault during code fetch */
6815
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
6816
        if (unlikely(env->nb_breakpoints > 0)) {
6817
            for (j = 0; j < env->nb_breakpoints; j++) {
6818
                if (env->breakpoints[j] == ctx.nip) {
6819
                    gen_update_nip(&ctx, ctx.nip);
6820
                    gen_op_debug();
6821
                    break;
6822
                }
6823
            }
6824
        }
6825
        if (unlikely(search_pc)) {
6826
            j = gen_opc_ptr - gen_opc_buf;
6827
            if (lj < j) {
6828
                lj++;
6829
                while (lj < j)
6830
                    gen_opc_instr_start[lj++] = 0;
6831
                gen_opc_pc[lj] = ctx.nip;
6832
                gen_opc_instr_start[lj] = 1;
6833
                gen_opc_icount[lj] = num_insns;
6834
            }
6835
        }
6836
#if defined PPC_DEBUG_DISAS
6837
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6838
            fprintf(logfile, "----------------\n");
6839
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6840
                    ctx.nip, supervisor, (int)msr_ir);
6841
        }
6842
#endif
6843
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
6844
            gen_io_start();
6845
        if (unlikely(little_endian)) {
6846
            ctx.opcode = bswap32(ldl_code(ctx.nip));
6847
        } else {
6848
            ctx.opcode = ldl_code(ctx.nip);
6849
        }
6850
#if defined PPC_DEBUG_DISAS
6851
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6852
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6853
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6854
                    opc3(ctx.opcode), little_endian ? "little" : "big");
6855
        }
6856
#endif
6857
        ctx.nip += 4;
6858
        table = env->opcodes;
6859
        num_insns++;
6860
        handler = table[opc1(ctx.opcode)];
6861
        if (is_indirect_opcode(handler)) {
6862
            table = ind_table(handler);
6863
            handler = table[opc2(ctx.opcode)];
6864
            if (is_indirect_opcode(handler)) {
6865
                table = ind_table(handler);
6866
                handler = table[opc3(ctx.opcode)];
6867
            }
6868
        }
6869
        /* Is opcode *REALLY* valid ? */
6870
        if (unlikely(handler->handler == &gen_invalid)) {
6871
            if (loglevel != 0) {
6872
                fprintf(logfile, "invalid/unsupported opcode: "
6873
                        "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6874
                        opc1(ctx.opcode), opc2(ctx.opcode),
6875
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6876
            } else {
6877
                printf("invalid/unsupported opcode: "
6878
                       "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6879
                       opc1(ctx.opcode), opc2(ctx.opcode),
6880
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6881
            }
6882
        } else {
6883
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6884
                if (loglevel != 0) {
6885
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6886
                            "%02x - %02x - %02x (%08x) " ADDRX "\n",
6887
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6888
                            opc2(ctx.opcode), opc3(ctx.opcode),
6889
                            ctx.opcode, ctx.nip - 4);
6890
                } else {
6891
                    printf("invalid bits: %08x for opcode: "
6892
                           "%02x - %02x - %02x (%08x) " ADDRX "\n",
6893
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6894
                           opc2(ctx.opcode), opc3(ctx.opcode),
6895
                           ctx.opcode, ctx.nip - 4);
6896
                }
6897
                GEN_EXCP_INVAL(ctxp);
6898
                break;
6899
            }
6900
        }
6901
        (*(handler->handler))(&ctx);
6902
#if defined(DO_PPC_STATISTICS)
6903
        handler->count++;
6904
#endif
6905
        /* Check trace mode exceptions */
6906
        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
6907
                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
6908
                     ctx.exception != POWERPC_SYSCALL &&
6909
                     ctx.exception != POWERPC_EXCP_TRAP &&
6910
                     ctx.exception != POWERPC_EXCP_BRANCH)) {
6911
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6912
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6913
                            (env->singlestep_enabled) ||
6914
                            num_insns >= max_insns)) {
6915
            /* if we reach a page boundary or are single stepping, stop
6916
             * generation
6917
             */
6918
            break;
6919
        }
6920
#if defined (DO_SINGLE_STEP)
6921
        break;
6922
#endif
6923
    }
6924
    if (tb->cflags & CF_LAST_IO)
6925
        gen_io_end();
6926
    if (ctx.exception == POWERPC_EXCP_NONE) {
6927
        gen_goto_tb(&ctx, 0, ctx.nip);
6928
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6929
        if (unlikely(env->singlestep_enabled)) {
6930
            gen_update_nip(&ctx, ctx.nip);
6931
            gen_op_debug();
6932
        }
6933
        /* Generate the return instruction */
6934
        tcg_gen_exit_tb(0);
6935
    }
6936
    gen_icount_end(tb, num_insns);
6937
    *gen_opc_ptr = INDEX_op_end;
6938
    if (unlikely(search_pc)) {
6939
        j = gen_opc_ptr - gen_opc_buf;
6940
        lj++;
6941
        while (lj <= j)
6942
            gen_opc_instr_start[lj++] = 0;
6943
    } else {
6944
        tb->size = ctx.nip - pc_start;
6945
        tb->icount = num_insns;
6946
    }
6947
#if defined(DEBUG_DISAS)
6948
    if (loglevel & CPU_LOG_TB_CPU) {
6949
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6950
        cpu_dump_state(env, logfile, fprintf, 0);
6951
    }
6952
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6953
        int flags;
6954
        flags = env->bfd_mach;
6955
        flags |= little_endian << 16;
6956
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6957
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6958
        fprintf(logfile, "\n");
6959
    }
6960
#endif
6961
}
6962

    
6963
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6964
{
6965
    gen_intermediate_code_internal(env, tb, 0);
6966
}
6967

    
6968
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6969
{
6970
    gen_intermediate_code_internal(env, tb, 1);
6971
}
6972

    
6973
void gen_pc_load(CPUState *env, TranslationBlock *tb,
6974
                unsigned long searched_pc, int pc_pos, void *puc)
6975
{
6976
    int type, c;
6977
    /* for PPC, we need to look at the micro operation to get the
6978
     * access type */
6979
    env->nip = gen_opc_pc[pc_pos];
6980
    c = gen_opc_buf[pc_pos];
6981
    switch(c) {
6982
#if defined(CONFIG_USER_ONLY)
6983
#define CASE3(op)\
6984
    case INDEX_op_ ## op ## _raw
6985
#else
6986
#define CASE3(op)\
6987
    case INDEX_op_ ## op ## _user:\
6988
    case INDEX_op_ ## op ## _kernel:\
6989
    case INDEX_op_ ## op ## _hypv
6990
#endif
6991

    
6992
    CASE3(stfd):
6993
    CASE3(stfs):
6994
    CASE3(lfd):
6995
    CASE3(lfs):
6996
        type = ACCESS_FLOAT;
6997
        break;
6998
    CASE3(lwarx):
6999
        type = ACCESS_RES;
7000
        break;
7001
    CASE3(stwcx):
7002
        type = ACCESS_RES;
7003
        break;
7004
    CASE3(eciwx):
7005
    CASE3(ecowx):
7006
        type = ACCESS_EXT;
7007
        break;
7008
    default:
7009
        type = ACCESS_INT;
7010
        break;
7011
    }
7012
    env->access_type = type;
7013
}