Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ ec1ac72d

History | View | Annotate | Download (229.3 kB)

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

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

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

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

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

    
47
/* global register indexes */
48
static TCGv cpu_env;
49
static char cpu_reg_names[10*3 + 22*4 /* GPR */
50
#if !defined(TARGET_PPC64)
51
    + 10*4 + 22*5 /* SPE GPRh */
52
#endif
53
    + 10*4 + 22*5 /* FPR */
54
    + 2*(10*6 + 22*7) /* AVRh, AVRl */];
55
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

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

    
72
#include "gen-icount.h"
73

    
74
void ppc_translate_init(void)
75
{
76
    int i;
77
    char* p;
78
    static int done_init = 0;
79

    
80
    if (done_init)
81
        return;
82

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

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

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

    
128
    p = cpu_reg_names;
129
    for (i = 0; i < 32; i++) {
130
        sprintf(p, "r%d", i);
131
        cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
132
                                        offsetof(CPUState, gpr[i]), p);
133
        p += (i < 10) ? 3 : 4;
134
#if !defined(TARGET_PPC64)
135
        sprintf(p, "r%dH", i);
136
        cpu_gprh[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
137
                                         offsetof(CPUState, gprh[i]), p);
138
        p += (i < 10) ? 4 : 5;
139
#endif
140

    
141
        sprintf(p, "fp%d", i);
142
        cpu_fpr[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
143
                                        offsetof(CPUState, fpr[i]), p);
144
        p += (i < 10) ? 4 : 5;
145

    
146
        sprintf(p, "avr%dH", i);
147
        cpu_avrh[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
148
                                         offsetof(CPUState, avr[i].u64[0]), p);
149
        p += (i < 10) ? 6 : 7;
150

    
151
        sprintf(p, "avr%dL", i);
152
        cpu_avrl[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
153
                                         offsetof(CPUState, avr[i].u64[1]), p);
154
        p += (i < 10) ? 6 : 7;
155
    }
156

    
157
    /* register helpers */
158
#undef DEF_HELPER
159
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
160
#include "helper.h"
161

    
162
    done_init = 1;
163
}
164

    
165
#if defined(OPTIMIZE_FPRF_UPDATE)
166
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
167
static uint16_t **gen_fprf_ptr;
168
#endif
169

    
170
#define GEN8(func, NAME)                                                      \
171
static GenOpFunc *NAME ## _table [8] = {                                      \
172
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
173
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
174
};                                                                            \
175
static always_inline void func (int n)                                        \
176
{                                                                             \
177
    NAME ## _table[n]();                                                      \
178
}
179

    
180
#define GEN16(func, NAME)                                                     \
181
static GenOpFunc *NAME ## _table [16] = {                                     \
182
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
183
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
184
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
185
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
186
};                                                                            \
187
static always_inline void func (int n)                                        \
188
{                                                                             \
189
    NAME ## _table[n]();                                                      \
190
}
191

    
192
#define GEN32(func, NAME)                                                     \
193
static GenOpFunc *NAME ## _table [32] = {                                     \
194
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
195
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
196
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
197
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
198
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
199
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
200
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
201
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
202
};                                                                            \
203
static always_inline void func (int n)                                        \
204
{                                                                             \
205
    NAME ## _table[n]();                                                      \
206
}
207

    
208
/* Condition register moves */
209
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
210
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
211
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
212
#if 0 // Unused
213
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
214
#endif
215

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

    
239
struct opc_handler_t {
240
    /* invalid bits */
241
    uint32_t inval;
242
    /* instruction type */
243
    uint64_t type;
244
    /* handler */
245
    void (*handler)(DisasContext *ctx);
246
#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
247
    const unsigned char *oname;
248
#endif
249
#if defined(DO_PPC_STATISTICS)
250
    uint64_t count;
251
#endif
252
};
253

    
254
static always_inline void gen_set_Rc0 (DisasContext *ctx)
255
{
256
#if defined(TARGET_PPC64)
257
    if (ctx->sf_mode)
258
        gen_op_cmpi_64(0);
259
    else
260
#endif
261
        gen_op_cmpi(0);
262
    gen_op_set_Rc0();
263
}
264

    
265
static always_inline void gen_reset_fpstatus (void)
266
{
267
#ifdef CONFIG_SOFTFLOAT
268
    gen_op_reset_fpstatus();
269
#endif
270
}
271

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

    
292
static always_inline void gen_optimize_fprf (void)
293
{
294
#if defined(OPTIMIZE_FPRF_UPDATE)
295
    uint16_t **ptr;
296

    
297
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
298
        *ptr = INDEX_op_nop1;
299
    gen_fprf_ptr = gen_fprf_buf;
300
#endif
301
}
302

    
303
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
304
{
305
#if defined(TARGET_PPC64)
306
    if (ctx->sf_mode)
307
        gen_op_update_nip_64(nip >> 32, nip);
308
    else
309
#endif
310
        gen_op_update_nip(nip);
311
}
312

    
313
#define GEN_EXCP(ctx, excp, error)                                            \
314
do {                                                                          \
315
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
316
        gen_update_nip(ctx, (ctx)->nip);                                      \
317
    }                                                                         \
318
    gen_op_raise_exception_err((excp), (error));                              \
319
    ctx->exception = (excp);                                                  \
320
} while (0)
321

    
322
#define GEN_EXCP_INVAL(ctx)                                                   \
323
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
324
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
325

    
326
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
327
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
328
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
329

    
330
#define GEN_EXCP_PRIVREG(ctx)                                                 \
331
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
332
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
333

    
334
#define GEN_EXCP_NO_FP(ctx)                                                   \
335
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
336

    
337
#define GEN_EXCP_NO_AP(ctx)                                                   \
338
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
339

    
340
#define GEN_EXCP_NO_VR(ctx)                                                   \
341
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
342

    
343
/* Stop translation */
344
static always_inline void GEN_STOP (DisasContext *ctx)
345
{
346
    gen_update_nip(ctx, ctx->nip);
347
    ctx->exception = POWERPC_EXCP_STOP;
348
}
349

    
350
/* No need to update nip here, as execution flow will change */
351
static always_inline void GEN_SYNC (DisasContext *ctx)
352
{
353
    ctx->exception = POWERPC_EXCP_SYNC;
354
}
355

    
356
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
357
static void gen_##name (DisasContext *ctx);                                   \
358
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
359
static void gen_##name (DisasContext *ctx)
360

    
361
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
362
static void gen_##name (DisasContext *ctx);                                   \
363
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
364
static void gen_##name (DisasContext *ctx)
365

    
366
typedef struct opcode_t {
367
    unsigned char opc1, opc2, opc3;
368
#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
369
    unsigned char pad[5];
370
#else
371
    unsigned char pad[1];
372
#endif
373
    opc_handler_t handler;
374
    const unsigned char *oname;
375
} opcode_t;
376

    
377
/*****************************************************************************/
378
/***                           Instruction decoding                        ***/
379
#define EXTRACT_HELPER(name, shift, nb)                                       \
380
static always_inline uint32_t name (uint32_t opcode)                          \
381
{                                                                             \
382
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
383
}
384

    
385
#define EXTRACT_SHELPER(name, shift, nb)                                      \
386
static always_inline int32_t name (uint32_t opcode)                           \
387
{                                                                             \
388
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
389
}
390

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

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

    
440
EXTRACT_HELPER(CRM, 12, 8);
441
EXTRACT_HELPER(FM, 17, 8);
442
EXTRACT_HELPER(SR, 16, 4);
443
EXTRACT_HELPER(FPIMM, 12, 4);
444

    
445
/***                            Jump target decoding                       ***/
446
/* Displacement */
447
EXTRACT_SHELPER(d, 0, 16);
448
/* Immediate address */
449
static always_inline target_ulong LI (uint32_t opcode)
450
{
451
    return (opcode >> 0) & 0x03FFFFFC;
452
}
453

    
454
static always_inline uint32_t BD (uint32_t opcode)
455
{
456
    return (opcode >> 0) & 0xFFFC;
457
}
458

    
459
EXTRACT_HELPER(BO, 21, 5);
460
EXTRACT_HELPER(BI, 16, 5);
461
/* Absolute/relative address */
462
EXTRACT_HELPER(AA, 1, 1);
463
/* Link */
464
EXTRACT_HELPER(LK, 0, 1);
465

    
466
/* Create a mask between <start> and <end> bits */
467
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
468
{
469
    target_ulong ret;
470

    
471
#if defined(TARGET_PPC64)
472
    if (likely(start == 0)) {
473
        ret = UINT64_MAX << (63 - end);
474
    } else if (likely(end == 63)) {
475
        ret = UINT64_MAX >> start;
476
    }
477
#else
478
    if (likely(start == 0)) {
479
        ret = UINT32_MAX << (31  - end);
480
    } else if (likely(end == 31)) {
481
        ret = UINT32_MAX >> start;
482
    }
483
#endif
484
    else {
485
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
486
            (((target_ulong)(-1ULL) >> (end)) >> 1);
487
        if (unlikely(start > end))
488
            return ~ret;
489
    }
490

    
491
    return ret;
492
}
493

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

    
530
    /* Fixed-point unit extensions                                           */
531
    /*   PowerPC 602 specific                                                */
532
    PPC_602_SPEC       = 0x0000000000000400ULL,
533
    /*   isel instruction                                                    */
534
    PPC_ISEL           = 0x0000000000000800ULL,
535
    /*   popcntb instruction                                                 */
536
    PPC_POPCNTB        = 0x0000000000001000ULL,
537
    /*   string load / store                                                 */
538
    PPC_STRING         = 0x0000000000002000ULL,
539

    
540
    /* Floating-point unit extensions                                        */
541
    /*   Optional floating point instructions                                */
542
    PPC_FLOAT          = 0x0000000000010000ULL,
543
    /* New floating-point extensions (PowerPC 2.0x)                          */
544
    PPC_FLOAT_EXT      = 0x0000000000020000ULL,
545
    PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
546
    PPC_FLOAT_FRES     = 0x0000000000080000ULL,
547
    PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
548
    PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
549
    PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
550
    PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
551

    
552
    /* Vector/SIMD extensions                                                */
553
    /*   Altivec support                                                     */
554
    PPC_ALTIVEC        = 0x0000000001000000ULL,
555
    /*   PowerPC 2.03 SPE extension                                          */
556
    PPC_SPE            = 0x0000000002000000ULL,
557
    /*   PowerPC 2.03 SPE floating-point extension                           */
558
    PPC_SPEFPU         = 0x0000000004000000ULL,
559

    
560
    /* Optional memory control instructions                                  */
561
    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
562
    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
563
    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
564
    /*   sync instruction                                                    */
565
    PPC_MEM_SYNC       = 0x0000000080000000ULL,
566
    /*   eieio instruction                                                   */
567
    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
568

    
569
    /* Cache control instructions                                            */
570
    PPC_CACHE          = 0x0000000200000000ULL,
571
    /*   icbi instruction                                                    */
572
    PPC_CACHE_ICBI     = 0x0000000400000000ULL,
573
    /*   dcbz instruction with fixed cache line size                         */
574
    PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
575
    /*   dcbz instruction with tunable cache line size                       */
576
    PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
577
    /*   dcba instruction                                                    */
578
    PPC_CACHE_DCBA     = 0x0000002000000000ULL,
579
    /*   Freescale cache locking instructions                                */
580
    PPC_CACHE_LOCK     = 0x0000004000000000ULL,
581

    
582
    /* MMU related extensions                                                */
583
    /*   external control instructions                                       */
584
    PPC_EXTERN         = 0x0000010000000000ULL,
585
    /*   segment register access instructions                                */
586
    PPC_SEGMENT        = 0x0000020000000000ULL,
587
    /*   PowerPC 6xx TLB management instructions                             */
588
    PPC_6xx_TLB        = 0x0000040000000000ULL,
589
    /* PowerPC 74xx TLB management instructions                              */
590
    PPC_74xx_TLB       = 0x0000080000000000ULL,
591
    /*   PowerPC 40x TLB management instructions                             */
592
    PPC_40x_TLB        = 0x0000100000000000ULL,
593
    /*   segment register access instructions for PowerPC 64 "bridge"        */
594
    PPC_SEGMENT_64B    = 0x0000200000000000ULL,
595
    /*   SLB management                                                      */
596
    PPC_SLBI           = 0x0000400000000000ULL,
597

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

    
630
/*****************************************************************************/
631
/* PowerPC instructions table                                                */
632
#if HOST_LONG_BITS == 64
633
#define OPC_ALIGN 8
634
#else
635
#define OPC_ALIGN 4
636
#endif
637
#if defined(__APPLE__)
638
#define OPCODES_SECTION                                                       \
639
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
640
#else
641
#define OPCODES_SECTION                                                       \
642
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
643
#endif
644

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

    
703
#define GEN_OPCODE_MARK(name)                                                 \
704
OPCODES_SECTION opcode_t opc_##name = {                                       \
705
    .opc1 = 0xFF,                                                             \
706
    .opc2 = 0xFF,                                                             \
707
    .opc3 = 0xFF,                                                             \
708
    .pad  = { 0, },                                                           \
709
    .handler = {                                                              \
710
        .inval   = 0x00000000,                                                \
711
        .type = 0x00,                                                         \
712
        .handler = NULL,                                                      \
713
    },                                                                        \
714
    .oname = stringify(name),                                                 \
715
}
716

    
717
/* Start opcode list */
718
GEN_OPCODE_MARK(start);
719

    
720
/* Invalid instruction */
721
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
722
{
723
    GEN_EXCP_INVAL(ctx);
724
}
725

    
726
static opc_handler_t invalid_handler = {
727
    .inval   = 0xFFFFFFFF,
728
    .type    = PPC_NONE,
729
    .handler = gen_invalid,
730
};
731

    
732
/***                           Integer arithmetic                          ***/
733
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
734
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
735
{                                                                             \
736
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
737
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
738
    gen_op_##name();                                                          \
739
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
740
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
741
        gen_set_Rc0(ctx);                                                     \
742
}
743

    
744
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
745
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
746
{                                                                             \
747
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
748
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
749
    gen_op_##name();                                                          \
750
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
751
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
752
        gen_set_Rc0(ctx);                                                     \
753
}
754

    
755
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
756
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
757
{                                                                             \
758
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
759
    gen_op_##name();                                                          \
760
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
761
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
762
        gen_set_Rc0(ctx);                                                     \
763
}
764
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
765
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
766
{                                                                             \
767
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
768
    gen_op_##name();                                                          \
769
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
770
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
771
        gen_set_Rc0(ctx);                                                     \
772
}
773

    
774
/* Two operands arithmetic functions */
775
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
776
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
777
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
778

    
779
/* Two operands arithmetic functions with no overflow allowed */
780
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
781
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
782

    
783
/* One operand arithmetic functions */
784
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
785
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
786
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
787

    
788
#if defined(TARGET_PPC64)
789
#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
790
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
791
{                                                                             \
792
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
793
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
794
    if (ctx->sf_mode)                                                         \
795
        gen_op_##name##_64();                                                 \
796
    else                                                                      \
797
        gen_op_##name();                                                      \
798
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
799
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
800
        gen_set_Rc0(ctx);                                                     \
801
}
802

    
803
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
804
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
805
{                                                                             \
806
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
807
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
808
    if (ctx->sf_mode)                                                         \
809
        gen_op_##name##_64();                                                 \
810
    else                                                                      \
811
        gen_op_##name();                                                      \
812
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
813
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
814
        gen_set_Rc0(ctx);                                                     \
815
}
816

    
817
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
818
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
819
{                                                                             \
820
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
821
    if (ctx->sf_mode)                                                         \
822
        gen_op_##name##_64();                                                 \
823
    else                                                                      \
824
        gen_op_##name();                                                      \
825
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
826
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
827
        gen_set_Rc0(ctx);                                                     \
828
}
829
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
830
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
831
{                                                                             \
832
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);                       \
833
    if (ctx->sf_mode)                                                         \
834
        gen_op_##name##_64();                                                 \
835
    else                                                                      \
836
        gen_op_##name();                                                      \
837
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);                       \
838
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
839
        gen_set_Rc0(ctx);                                                     \
840
}
841

    
842
/* Two operands arithmetic functions */
843
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
844
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
845
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
846

    
847
/* Two operands arithmetic functions with no overflow allowed */
848
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
849
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
850

    
851
/* One operand arithmetic functions */
852
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
853
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
854
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
855
#else
856
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
857
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
858
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
859
#endif
860

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

    
1051
    if (rA(ctx->opcode) == 0) {
1052
        /* li case */
1053
        tcg_gen_movi_tl(cpu_T[0], simm);
1054
    } else {
1055
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
1056
        if (likely(simm != 0))
1057
            gen_op_addi(simm);
1058
    }
1059
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1060
}
1061
/* addic */
1062
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1063
{
1064
    target_long simm = SIMM(ctx->opcode);
1065

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

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

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

    
1137
#if defined(TARGET_PPC64)
1138
/* mulhd  mulhd.                   */
1139
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
1140
/* mulhdu mulhdu.                  */
1141
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
1142
/* mulld  mulld.  mulldo  mulldo.  */
1143
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
1144
/* divd   divd.   divdo   divdo.   */
1145
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
1146
/* divdu  divdu.  divduo  divduo.  */
1147
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
1148
#endif
1149

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

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

    
1203
/* isel (PowerPC 2.03 specification) */
1204
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
1205
{
1206
    uint32_t bi = rC(ctx->opcode);
1207
    uint32_t mask;
1208

    
1209
    if (rA(ctx->opcode) == 0) {
1210
        tcg_gen_movi_tl(cpu_T[0], 0);
1211
    } else {
1212
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
1213
    }
1214
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
1215
    mask = 1 << (3 - (bi & 0x03));
1216
    gen_op_load_crf_T0(bi >> 2);
1217
    gen_op_test_true(mask);
1218
    gen_op_isel();
1219
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
1220
}
1221

    
1222
/***                            Integer logical                            ***/
1223
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1224
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1225
{                                                                             \
1226
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
1227
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
1228
    gen_op_##name();                                                          \
1229
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
1230
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1231
        gen_set_Rc0(ctx);                                                     \
1232
}
1233
#define GEN_LOGICAL2(name, opc, type)                                         \
1234
__GEN_LOGICAL2(name, 0x1C, opc, type)
1235

    
1236
#define GEN_LOGICAL1(name, opc, type)                                         \
1237
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1238
{                                                                             \
1239
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
1240
    gen_op_##name();                                                          \
1241
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
1242
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1243
        gen_set_Rc0(ctx);                                                     \
1244
}
1245

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

    
1267
/* cntlzw */
1268
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1269
/* eqv & eqv. */
1270
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1271
/* extsb & extsb. */
1272
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1273
/* extsh & extsh. */
1274
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1275
/* nand & nand. */
1276
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1277
/* nor & nor. */
1278
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1279

    
1280
/* or & or. */
1281
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1282
{
1283
    int rs, ra, rb;
1284

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

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

    
1372
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1373
        /* NOP */
1374
        /* XXX: should handle special NOPs for POWER series */
1375
        return;
1376
    }
1377
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1378
    if (likely(uimm != 0))
1379
        gen_op_ori(uimm);
1380
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1381
}
1382
/* oris */
1383
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1384
{
1385
    target_ulong uimm = UIMM(ctx->opcode);
1386

    
1387
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1388
        /* NOP */
1389
        return;
1390
    }
1391
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1392
    if (likely(uimm != 0))
1393
        gen_op_ori(uimm << 16);
1394
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1395
}
1396
/* xori */
1397
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1398
{
1399
    target_ulong uimm = UIMM(ctx->opcode);
1400

    
1401
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1402
        /* NOP */
1403
        return;
1404
    }
1405
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1406
    if (likely(uimm != 0))
1407
        gen_op_xori(uimm);
1408
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1409
}
1410

    
1411
/* xoris */
1412
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1413
{
1414
    target_ulong uimm = UIMM(ctx->opcode);
1415

    
1416
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1417
        /* NOP */
1418
        return;
1419
    }
1420
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1421
    if (likely(uimm != 0))
1422
        gen_op_xori(uimm << 16);
1423
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1424
}
1425

    
1426
/* popcntb : PowerPC 2.03 specification */
1427
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
1428
{
1429
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1430
#if defined(TARGET_PPC64)
1431
    if (ctx->sf_mode)
1432
        gen_op_popcntb_64();
1433
    else
1434
#endif
1435
        gen_op_popcntb();
1436
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1437
}
1438

    
1439
#if defined(TARGET_PPC64)
1440
/* extsw & extsw. */
1441
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1442
/* cntlzd */
1443
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1444
#endif
1445

    
1446
/***                             Integer rotate                            ***/
1447
/* rlwimi & rlwimi. */
1448
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1449
{
1450
    target_ulong mask;
1451
    uint32_t mb, me, sh;
1452

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

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

    
1528
    mb = MB(ctx->opcode);
1529
    me = ME(ctx->opcode);
1530
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1531
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1532
    gen_op_rotl32_T0_T1();
1533
    if (unlikely(mb != 0 || me != 31)) {
1534
#if defined(TARGET_PPC64)
1535
        mb += 32;
1536
        me += 32;
1537
#endif
1538
        gen_op_andi_T0(MASK(mb, me));
1539
    }
1540
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1541
    if (unlikely(Rc(ctx->opcode) != 0))
1542
        gen_set_Rc0(ctx);
1543
}
1544

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

    
1577
static always_inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1578
{
1579
    if (mask >> 32)
1580
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1581
    else
1582
        gen_op_andi_T0(mask);
1583
}
1584

    
1585
static always_inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1586
{
1587
    if (mask >> 32)
1588
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1589
    else
1590
        gen_op_andi_T1(mask);
1591
}
1592

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

    
1627
    sh = SH(ctx->opcode) | (shn << 5);
1628
    mb = MB(ctx->opcode) | (mbn << 5);
1629
    gen_rldinm(ctx, mb, 63, sh);
1630
}
1631
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1632
/* rldicr - rldicr. */
1633
static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1634
{
1635
    uint32_t sh, me;
1636

    
1637
    sh = SH(ctx->opcode) | (shn << 5);
1638
    me = MB(ctx->opcode) | (men << 5);
1639
    gen_rldinm(ctx, 0, me, sh);
1640
}
1641
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1642
/* rldic - rldic. */
1643
static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1644
{
1645
    uint32_t sh, mb;
1646

    
1647
    sh = SH(ctx->opcode) | (shn << 5);
1648
    mb = MB(ctx->opcode) | (mbn << 5);
1649
    gen_rldinm(ctx, mb, 63 - sh, sh);
1650
}
1651
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1652

    
1653
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1654
                                     uint32_t me)
1655
{
1656
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
1657
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
1658
    gen_op_rotl64_T0_T1();
1659
    if (unlikely(mb != 0 || me != 63)) {
1660
        gen_andi_T0_64(ctx, MASK(mb, me));
1661
    }
1662
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
1663
    if (unlikely(Rc(ctx->opcode) != 0))
1664
        gen_set_Rc0(ctx);
1665
}
1666

    
1667
/* rldcl - rldcl. */
1668
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1669
{
1670
    uint32_t mb;
1671

    
1672
    mb = MB(ctx->opcode) | (mbn << 5);
1673
    gen_rldnm(ctx, mb, 63);
1674
}
1675
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1676
/* rldcr - rldcr. */
1677
static always_inline void gen_rldcr (DisasContext *ctx, int men)
1678
{
1679
    uint32_t me;
1680

    
1681
    me = MB(ctx->opcode) | (men << 5);
1682
    gen_rldnm(ctx, 0, me);
1683
}
1684
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1685
/* rldimi - rldimi. */
1686
static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1687
{
1688
    uint64_t mask;
1689
    uint32_t sh, mb, me;
1690

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

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

    
1746
#if defined(TARGET_PPC64)
1747
/* sld & sld. */
1748
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1749
/* srad & srad. */
1750
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1751
/* sradi & sradi. */
1752
static always_inline void gen_sradi (DisasContext *ctx, int n)
1753
{
1754
    uint64_t mask;
1755
    int sh, mb, me;
1756

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

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

    
1802
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1803
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1804
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1805

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

    
1827
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1828
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1829
{                                                                             \
1830
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1831
        GEN_EXCP_NO_FP(ctx);                                                  \
1832
        return;                                                               \
1833
    }                                                                         \
1834
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);                     \
1835
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rC(ctx->opcode)]);                     \
1836
    gen_reset_fpstatus();                                                     \
1837
    gen_op_f##op();                                                           \
1838
    if (isfloat) {                                                            \
1839
        gen_op_frsp();                                                        \
1840
    }                                                                         \
1841
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1842
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1843
}
1844
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
1845
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1846
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1847

    
1848
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
1849
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1850
{                                                                             \
1851
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1852
        GEN_EXCP_NO_FP(ctx);                                                  \
1853
        return;                                                               \
1854
    }                                                                         \
1855
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);                     \
1856
    gen_reset_fpstatus();                                                     \
1857
    gen_op_f##name();                                                         \
1858
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1859
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1860
}
1861

    
1862
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1863
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1864
{                                                                             \
1865
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1866
        GEN_EXCP_NO_FP(ctx);                                                  \
1867
        return;                                                               \
1868
    }                                                                         \
1869
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);                     \
1870
    gen_reset_fpstatus();                                                     \
1871
    gen_op_f##name();                                                         \
1872
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
1873
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1874
}
1875

    
1876
/* fadd - fadds */
1877
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1878
/* fdiv - fdivs */
1879
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1880
/* fmul - fmuls */
1881
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
1882

    
1883
/* fre */
1884
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1885

    
1886
/* fres */
1887
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1888

    
1889
/* frsqrte */
1890
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
1891

    
1892
/* frsqrtes */
1893
static always_inline void gen_op_frsqrtes (void)
1894
{
1895
    gen_op_frsqrte();
1896
    gen_op_frsp();
1897
}
1898
GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1899

    
1900
/* fsel */
1901
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1902
/* fsub - fsubs */
1903
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1904
/* Optional: */
1905
/* fsqrt */
1906
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1907
{
1908
    if (unlikely(!ctx->fpu_enabled)) {
1909
        GEN_EXCP_NO_FP(ctx);
1910
        return;
1911
    }
1912
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
1913
    gen_reset_fpstatus();
1914
    gen_op_fsqrt();
1915
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
1916
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1917
}
1918

    
1919
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1920
{
1921
    if (unlikely(!ctx->fpu_enabled)) {
1922
        GEN_EXCP_NO_FP(ctx);
1923
        return;
1924
    }
1925
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
1926
    gen_reset_fpstatus();
1927
    gen_op_fsqrt();
1928
    gen_op_frsp();
1929
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
1930
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1931
}
1932

    
1933
/***                     Floating-Point multiply-and-add                   ***/
1934
/* fmadd - fmadds */
1935
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1936
/* fmsub - fmsubs */
1937
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1938
/* fnmadd - fnmadds */
1939
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1940
/* fnmsub - fnmsubs */
1941
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1942

    
1943
/***                     Floating-Point round & convert                    ***/
1944
/* fctiw */
1945
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1946
/* fctiwz */
1947
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1948
/* frsp */
1949
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
1950
#if defined(TARGET_PPC64)
1951
/* fcfid */
1952
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
1953
/* fctid */
1954
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
1955
/* fctidz */
1956
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
1957
#endif
1958

    
1959
/* frin */
1960
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
1961
/* friz */
1962
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
1963
/* frip */
1964
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
1965
/* frim */
1966
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1967

    
1968
/***                         Floating-Point compare                        ***/
1969
/* fcmpo */
1970
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1971
{
1972
    if (unlikely(!ctx->fpu_enabled)) {
1973
        GEN_EXCP_NO_FP(ctx);
1974
        return;
1975
    }
1976
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
1977
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
1978
    gen_reset_fpstatus();
1979
    gen_op_fcmpo();
1980
    gen_op_store_T0_crf(crfD(ctx->opcode));
1981
    gen_op_float_check_status();
1982
}
1983

    
1984
/* fcmpu */
1985
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1986
{
1987
    if (unlikely(!ctx->fpu_enabled)) {
1988
        GEN_EXCP_NO_FP(ctx);
1989
        return;
1990
    }
1991
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
1992
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
1993
    gen_reset_fpstatus();
1994
    gen_op_fcmpu();
1995
    gen_op_store_T0_crf(crfD(ctx->opcode));
1996
    gen_op_float_check_status();
1997
}
1998

    
1999
/***                         Floating-point move                           ***/
2000
/* fabs */
2001
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
2002
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
2003

    
2004
/* fmr  - fmr. */
2005
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
2006
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
2007
{
2008
    if (unlikely(!ctx->fpu_enabled)) {
2009
        GEN_EXCP_NO_FP(ctx);
2010
        return;
2011
    }
2012
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2013
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2014
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2015
}
2016

    
2017
/* fnabs */
2018
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
2019
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
2020
/* fneg */
2021
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
2022
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
2023

    
2024
/***                  Floating-Point status & ctrl register                ***/
2025
/* mcrfs */
2026
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
2027
{
2028
    int bfa;
2029

    
2030
    if (unlikely(!ctx->fpu_enabled)) {
2031
        GEN_EXCP_NO_FP(ctx);
2032
        return;
2033
    }
2034
    gen_optimize_fprf();
2035
    bfa = 4 * (7 - crfS(ctx->opcode));
2036
    gen_op_load_fpscr_T0(bfa);
2037
    gen_op_store_T0_crf(crfD(ctx->opcode));
2038
    gen_op_fpscr_resetbit(~(0xF << bfa));
2039
}
2040

    
2041
/* mffs */
2042
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
2043
{
2044
    if (unlikely(!ctx->fpu_enabled)) {
2045
        GEN_EXCP_NO_FP(ctx);
2046
        return;
2047
    }
2048
    gen_optimize_fprf();
2049
    gen_reset_fpstatus();
2050
    gen_op_load_fpscr_FT0();
2051
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
2052
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2053
}
2054

    
2055
/* mtfsb0 */
2056
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
2057
{
2058
    uint8_t crb;
2059

    
2060
    if (unlikely(!ctx->fpu_enabled)) {
2061
        GEN_EXCP_NO_FP(ctx);
2062
        return;
2063
    }
2064
    crb = 32 - (crbD(ctx->opcode) >> 2);
2065
    gen_optimize_fprf();
2066
    gen_reset_fpstatus();
2067
    if (likely(crb != 30 && crb != 29))
2068
        gen_op_fpscr_resetbit(~(1 << crb));
2069
    if (unlikely(Rc(ctx->opcode) != 0)) {
2070
        gen_op_load_fpcc();
2071
        gen_op_set_Rc0();
2072
    }
2073
}
2074

    
2075
/* mtfsb1 */
2076
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2077
{
2078
    uint8_t crb;
2079

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

    
2098
/* mtfsf */
2099
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2100
{
2101
    if (unlikely(!ctx->fpu_enabled)) {
2102
        GEN_EXCP_NO_FP(ctx);
2103
        return;
2104
    }
2105
    gen_optimize_fprf();
2106
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rB(ctx->opcode)]);
2107
    gen_reset_fpstatus();
2108
    gen_op_store_fpscr(FM(ctx->opcode));
2109
    if (unlikely(Rc(ctx->opcode) != 0)) {
2110
        gen_op_load_fpcc();
2111
        gen_op_set_Rc0();
2112
    }
2113
    /* We can raise a differed exception */
2114
    gen_op_float_check_status();
2115
}
2116

    
2117
/* mtfsfi */
2118
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2119
{
2120
    int bf, sh;
2121

    
2122
    if (unlikely(!ctx->fpu_enabled)) {
2123
        GEN_EXCP_NO_FP(ctx);
2124
        return;
2125
    }
2126
    bf = crbD(ctx->opcode) >> 2;
2127
    sh = 7 - bf;
2128
    gen_optimize_fprf();
2129
    gen_op_set_FT0(FPIMM(ctx->opcode) << (4 * sh));
2130
    gen_reset_fpstatus();
2131
    gen_op_store_fpscr(1 << sh);
2132
    if (unlikely(Rc(ctx->opcode) != 0)) {
2133
        gen_op_load_fpcc();
2134
        gen_op_set_Rc0();
2135
    }
2136
    /* We can raise a differed exception */
2137
    gen_op_float_check_status();
2138
}
2139

    
2140
/***                           Addressing modes                            ***/
2141
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2142
static always_inline void gen_addr_imm_index (DisasContext *ctx,
2143
                                              target_long maskl)
2144
{
2145
    target_long simm = SIMM(ctx->opcode);
2146

    
2147
    simm &= ~maskl;
2148
    if (rA(ctx->opcode) == 0) {
2149
        tcg_gen_movi_tl(cpu_T[0], simm);
2150
    } else {
2151
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
2152
        if (likely(simm != 0))
2153
            gen_op_addi(simm);
2154
    }
2155
#ifdef DEBUG_MEMORY_ACCESSES
2156
    gen_op_print_mem_EA();
2157
#endif
2158
}
2159

    
2160
static always_inline void gen_addr_reg_index (DisasContext *ctx)
2161
{
2162
    if (rA(ctx->opcode) == 0) {
2163
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
2164
    } else {
2165
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
2166
        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
2167
        gen_op_add();
2168
    }
2169
#ifdef DEBUG_MEMORY_ACCESSES
2170
    gen_op_print_mem_EA();
2171
#endif
2172
}
2173

    
2174
static always_inline void gen_addr_register (DisasContext *ctx)
2175
{
2176
    if (rA(ctx->opcode) == 0) {
2177
        tcg_gen_movi_tl(cpu_T[0], 0);
2178
    } else {
2179
        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
2180
    }
2181
#ifdef DEBUG_MEMORY_ACCESSES
2182
    gen_op_print_mem_EA();
2183
#endif
2184
}
2185

    
2186
#if defined(TARGET_PPC64)
2187
#define _GEN_MEM_FUNCS(name, mode)                                            \
2188
    &gen_op_##name##_##mode,                                                  \
2189
    &gen_op_##name##_le_##mode,                                               \
2190
    &gen_op_##name##_64_##mode,                                               \
2191
    &gen_op_##name##_le_64_##mode
2192
#else
2193
#define _GEN_MEM_FUNCS(name, mode)                                            \
2194
    &gen_op_##name##_##mode,                                                  \
2195
    &gen_op_##name##_le_##mode
2196
#endif
2197
#if defined(CONFIG_USER_ONLY)
2198
#if defined(TARGET_PPC64)
2199
#define NB_MEM_FUNCS 4
2200
#else
2201
#define NB_MEM_FUNCS 2
2202
#endif
2203
#define GEN_MEM_FUNCS(name)                                                   \
2204
    _GEN_MEM_FUNCS(name, raw)
2205
#else
2206
#if defined(TARGET_PPC64)
2207
#define NB_MEM_FUNCS 12
2208
#else
2209
#define NB_MEM_FUNCS 6
2210
#endif
2211
#define GEN_MEM_FUNCS(name)                                                   \
2212
    _GEN_MEM_FUNCS(name, user),                                               \
2213
    _GEN_MEM_FUNCS(name, kernel),                                             \
2214
    _GEN_MEM_FUNCS(name, hypv)
2215
#endif
2216

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

    
2245
#define GEN_LD(width, opc, type)                                              \
2246
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2247
{                                                                             \
2248
    gen_addr_imm_index(ctx, 0);                                               \
2249
    op_ldst(l##width);                                                        \
2250
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2251
}
2252

    
2253
#define GEN_LDU(width, opc, type)                                             \
2254
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2255
{                                                                             \
2256
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2257
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2258
        GEN_EXCP_INVAL(ctx);                                                  \
2259
        return;                                                               \
2260
    }                                                                         \
2261
    if (type == PPC_64B)                                                      \
2262
        gen_addr_imm_index(ctx, 0x03);                                        \
2263
    else                                                                      \
2264
        gen_addr_imm_index(ctx, 0);                                           \
2265
    op_ldst(l##width);                                                        \
2266
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2267
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2268
}
2269

    
2270
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2271
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2272
{                                                                             \
2273
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2274
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2275
        GEN_EXCP_INVAL(ctx);                                                  \
2276
        return;                                                               \
2277
    }                                                                         \
2278
    gen_addr_reg_index(ctx);                                                  \
2279
    op_ldst(l##width);                                                        \
2280
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2281
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2282
}
2283

    
2284
#define GEN_LDX(width, opc2, opc3, type)                                      \
2285
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2286
{                                                                             \
2287
    gen_addr_reg_index(ctx);                                                  \
2288
    op_ldst(l##width);                                                        \
2289
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);                       \
2290
}
2291

    
2292
#define GEN_LDS(width, op, type)                                              \
2293
OP_LD_TABLE(width);                                                           \
2294
GEN_LD(width, op | 0x20, type);                                               \
2295
GEN_LDU(width, op | 0x21, type);                                              \
2296
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2297
GEN_LDX(width, 0x17, op | 0x00, type)
2298

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

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

    
2373
/***                              Integer store                            ***/
2374
#define GEN_ST(width, opc, type)                                              \
2375
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2376
{                                                                             \
2377
    gen_addr_imm_index(ctx, 0);                                               \
2378
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2379
    op_ldst(st##width);                                                       \
2380
}
2381

    
2382
#define GEN_STU(width, opc, type)                                             \
2383
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2384
{                                                                             \
2385
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2386
        GEN_EXCP_INVAL(ctx);                                                  \
2387
        return;                                                               \
2388
    }                                                                         \
2389
    if (type == PPC_64B)                                                      \
2390
        gen_addr_imm_index(ctx, 0x03);                                        \
2391
    else                                                                      \
2392
        gen_addr_imm_index(ctx, 0);                                           \
2393
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2394
    op_ldst(st##width);                                                       \
2395
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2396
}
2397

    
2398
#define GEN_STUX(width, opc2, opc3, type)                                     \
2399
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2400
{                                                                             \
2401
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2402
        GEN_EXCP_INVAL(ctx);                                                  \
2403
        return;                                                               \
2404
    }                                                                         \
2405
    gen_addr_reg_index(ctx);                                                  \
2406
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2407
    op_ldst(st##width);                                                       \
2408
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2409
}
2410

    
2411
#define GEN_STX(width, opc2, opc3, type)                                      \
2412
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2413
{                                                                             \
2414
    gen_addr_reg_index(ctx);                                                  \
2415
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);                       \
2416
    op_ldst(st##width);                                                       \
2417
}
2418

    
2419
#define GEN_STS(width, op, type)                                              \
2420
OP_ST_TABLE(width);                                                           \
2421
GEN_ST(width, op | 0x20, type);                                               \
2422
GEN_STU(width, op | 0x21, type);                                              \
2423
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2424
GEN_STX(width, 0x17, op | 0x00, type)
2425

    
2426
/* stb stbu stbux stbx */
2427
GEN_STS(b, 0x06, PPC_INTEGER);
2428
/* sth sthu sthux sthx */
2429
GEN_STS(h, 0x0C, PPC_INTEGER);
2430
/* stw stwu stwux stwx */
2431
GEN_STS(w, 0x04, PPC_INTEGER);
2432
#if defined(TARGET_PPC64)
2433
OP_ST_TABLE(d);
2434
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2435
GEN_STX(d, 0x15, 0x04, PPC_64B);
2436
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2437
{
2438
    int rs;
2439

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

    
2496
/***                    Integer load and store multiple                    ***/
2497
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2498
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
2499
    GEN_MEM_FUNCS(lmw),
2500
};
2501
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
2502
    GEN_MEM_FUNCS(stmw),
2503
};
2504

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

    
2514
/* stmw */
2515
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2516
{
2517
    /* NIP cannot be restored if the memory exception comes from an helper */
2518
    gen_update_nip(ctx, ctx->nip - 4);
2519
    gen_addr_imm_index(ctx, 0);
2520
    op_ldstm(stmw, rS(ctx->opcode));
2521
}
2522

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

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

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

    
2591
/* lswx */
2592
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
2593
{
2594
    int ra = rA(ctx->opcode);
2595
    int rb = rB(ctx->opcode);
2596

    
2597
    /* NIP cannot be restored if the memory exception comes from an helper */
2598
    gen_update_nip(ctx, ctx->nip - 4);
2599
    gen_addr_reg_index(ctx);
2600
    if (ra == 0) {
2601
        ra = rb;
2602
    }
2603
    gen_op_load_xer_bc();
2604
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2605
}
2606

    
2607
/* stswi */
2608
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
2609
{
2610
    int nb = NB(ctx->opcode);
2611

    
2612
    /* NIP cannot be restored if the memory exception comes from an helper */
2613
    gen_update_nip(ctx, ctx->nip - 4);
2614
    gen_addr_register(ctx);
2615
    if (nb == 0)
2616
        nb = 32;
2617
    tcg_gen_movi_tl(cpu_T[1], nb);
2618
    op_ldsts(stsw, rS(ctx->opcode));
2619
}
2620

    
2621
/* stswx */
2622
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
2623
{
2624
    /* NIP cannot be restored if the memory exception comes from an helper */
2625
    gen_update_nip(ctx, ctx->nip - 4);
2626
    gen_addr_reg_index(ctx);
2627
    gen_op_load_xer_bc();
2628
    op_ldsts(stsw, rS(ctx->opcode));
2629
}
2630

    
2631
/***                        Memory synchronisation                         ***/
2632
/* eieio */
2633
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2634
{
2635
}
2636

    
2637
/* isync */
2638
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2639
{
2640
    GEN_STOP(ctx);
2641
}
2642

    
2643
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2644
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2645
static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
2646
    GEN_MEM_FUNCS(lwarx),
2647
};
2648
static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
2649
    GEN_MEM_FUNCS(stwcx),
2650
};
2651

    
2652
/* lwarx */
2653
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2654
{
2655
    /* NIP cannot be restored if the memory exception comes from an helper */
2656
    gen_update_nip(ctx, ctx->nip - 4);
2657
    gen_addr_reg_index(ctx);
2658
    op_lwarx();
2659
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
2660
}
2661

    
2662
/* stwcx. */
2663
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2664
{
2665
    /* NIP cannot be restored if the memory exception comes from an helper */
2666
    gen_update_nip(ctx, ctx->nip - 4);
2667
    gen_addr_reg_index(ctx);
2668
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
2669
    op_stwcx();
2670
}
2671

    
2672
#if defined(TARGET_PPC64)
2673
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2674
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2675
static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
2676
    GEN_MEM_FUNCS(ldarx),
2677
};
2678
static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
2679
    GEN_MEM_FUNCS(stdcx),
2680
};
2681

    
2682
/* ldarx */
2683
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2684
{
2685
    /* NIP cannot be restored if the memory exception comes from an helper */
2686
    gen_update_nip(ctx, ctx->nip - 4);
2687
    gen_addr_reg_index(ctx);
2688
    op_ldarx();
2689
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
2690
}
2691

    
2692
/* stdcx. */
2693
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2694
{
2695
    /* NIP cannot be restored if the memory exception comes from an helper */
2696
    gen_update_nip(ctx, ctx->nip - 4);
2697
    gen_addr_reg_index(ctx);
2698
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
2699
    op_stdcx();
2700
}
2701
#endif /* defined(TARGET_PPC64) */
2702

    
2703
/* sync */
2704
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
2705
{
2706
}
2707

    
2708
/* wait */
2709
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2710
{
2711
    /* Stop translation, as the CPU is supposed to sleep from now */
2712
    gen_op_wait();
2713
    GEN_EXCP(ctx, EXCP_HLT, 1);
2714
}
2715

    
2716
/***                         Floating-point load                           ***/
2717
#define GEN_LDF(width, opc, type)                                             \
2718
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2719
{                                                                             \
2720
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2721
        GEN_EXCP_NO_FP(ctx);                                                  \
2722
        return;                                                               \
2723
    }                                                                         \
2724
    gen_addr_imm_index(ctx, 0);                                               \
2725
    op_ldst(l##width);                                                        \
2726
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2727
}
2728

    
2729
#define GEN_LDUF(width, opc, type)                                            \
2730
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2731
{                                                                             \
2732
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2733
        GEN_EXCP_NO_FP(ctx);                                                  \
2734
        return;                                                               \
2735
    }                                                                         \
2736
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2737
        GEN_EXCP_INVAL(ctx);                                                  \
2738
        return;                                                               \
2739
    }                                                                         \
2740
    gen_addr_imm_index(ctx, 0);                                               \
2741
    op_ldst(l##width);                                                        \
2742
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2743
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2744
}
2745

    
2746
#define GEN_LDUXF(width, opc, type)                                           \
2747
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
2748
{                                                                             \
2749
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2750
        GEN_EXCP_NO_FP(ctx);                                                  \
2751
        return;                                                               \
2752
    }                                                                         \
2753
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2754
        GEN_EXCP_INVAL(ctx);                                                  \
2755
        return;                                                               \
2756
    }                                                                         \
2757
    gen_addr_reg_index(ctx);                                                  \
2758
    op_ldst(l##width);                                                        \
2759
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2760
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2761
}
2762

    
2763
#define GEN_LDXF(width, opc2, opc3, type)                                     \
2764
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2765
{                                                                             \
2766
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2767
        GEN_EXCP_NO_FP(ctx);                                                  \
2768
        return;                                                               \
2769
    }                                                                         \
2770
    gen_addr_reg_index(ctx);                                                  \
2771
    op_ldst(l##width);                                                        \
2772
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);                     \
2773
}
2774

    
2775
#define GEN_LDFS(width, op, type)                                             \
2776
OP_LD_TABLE(width);                                                           \
2777
GEN_LDF(width, op | 0x20, type);                                              \
2778
GEN_LDUF(width, op | 0x21, type);                                             \
2779
GEN_LDUXF(width, op | 0x01, type);                                            \
2780
GEN_LDXF(width, 0x17, op | 0x00, type)
2781

    
2782
/* lfd lfdu lfdux lfdx */
2783
GEN_LDFS(fd, 0x12, PPC_FLOAT);
2784
/* lfs lfsu lfsux lfsx */
2785
GEN_LDFS(fs, 0x10, PPC_FLOAT);
2786

    
2787
/***                         Floating-point store                          ***/
2788
#define GEN_STF(width, opc, type)                                             \
2789
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2790
{                                                                             \
2791
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2792
        GEN_EXCP_NO_FP(ctx);                                                  \
2793
        return;                                                               \
2794
    }                                                                         \
2795
    gen_addr_imm_index(ctx, 0);                                               \
2796
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
2797
    op_ldst(st##width);                                                       \
2798
}
2799

    
2800
#define GEN_STUF(width, opc, type)                                            \
2801
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2802
{                                                                             \
2803
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2804
        GEN_EXCP_NO_FP(ctx);                                                  \
2805
        return;                                                               \
2806
    }                                                                         \
2807
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2808
        GEN_EXCP_INVAL(ctx);                                                  \
2809
        return;                                                               \
2810
    }                                                                         \
2811
    gen_addr_imm_index(ctx, 0);                                               \
2812
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
2813
    op_ldst(st##width);                                                       \
2814
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2815
}
2816

    
2817
#define GEN_STUXF(width, opc, type)                                           \
2818
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
2819
{                                                                             \
2820
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2821
        GEN_EXCP_NO_FP(ctx);                                                  \
2822
        return;                                                               \
2823
    }                                                                         \
2824
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2825
        GEN_EXCP_INVAL(ctx);                                                  \
2826
        return;                                                               \
2827
    }                                                                         \
2828
    gen_addr_reg_index(ctx);                                                  \
2829
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
2830
    op_ldst(st##width);                                                       \
2831
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
2832
}
2833

    
2834
#define GEN_STXF(width, opc2, opc3, type)                                     \
2835
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2836
{                                                                             \
2837
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2838
        GEN_EXCP_NO_FP(ctx);                                                  \
2839
        return;                                                               \
2840
    }                                                                         \
2841
    gen_addr_reg_index(ctx);                                                  \
2842
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);                     \
2843
    op_ldst(st##width);                                                       \
2844
}
2845

    
2846
#define GEN_STFS(width, op, type)                                             \
2847
OP_ST_TABLE(width);                                                           \
2848
GEN_STF(width, op | 0x20, type);                                              \
2849
GEN_STUF(width, op | 0x21, type);                                             \
2850
GEN_STUXF(width, op | 0x01, type);                                            \
2851
GEN_STXF(width, 0x17, op | 0x00, type)
2852

    
2853
/* stfd stfdu stfdux stfdx */
2854
GEN_STFS(fd, 0x16, PPC_FLOAT);
2855
/* stfs stfsu stfsux stfsx */
2856
GEN_STFS(fs, 0x14, PPC_FLOAT);
2857

    
2858
/* Optional: */
2859
/* stfiwx */
2860
OP_ST_TABLE(fiw);
2861
GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2862

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

    
2906
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2907
{
2908
#if defined(TARGET_PPC64)
2909
    if (ctx->sf_mode != 0 && (nip >> 32))
2910
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2911
    else
2912
#endif
2913
        gen_op_setlr(ctx->nip);
2914
}
2915

    
2916
/* b ba bl bla */
2917
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2918
{
2919
    target_ulong li, target;
2920

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

    
2942
#define BCOND_IM  0
2943
#define BCOND_LR  1
2944
#define BCOND_CTR 2
2945

    
2946
static always_inline void gen_bcond (DisasContext *ctx, int type)
2947
{
2948
    target_ulong target = 0;
2949
    target_ulong li;
2950
    uint32_t bo = BO(ctx->opcode);
2951
    uint32_t bi = BI(ctx->opcode);
2952
    uint32_t mask;
2953

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

    
3091
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3092
{
3093
    gen_bcond(ctx, BCOND_IM);
3094
}
3095

    
3096
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3097
{
3098
    gen_bcond(ctx, BCOND_CTR);
3099
}
3100

    
3101
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3102
{
3103
    gen_bcond(ctx, BCOND_LR);
3104
}
3105

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

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

    
3156
/***                           System linkage                              ***/
3157
/* rfi (supervisor only) */
3158
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3159
{
3160
#if defined(CONFIG_USER_ONLY)
3161
    GEN_EXCP_PRIVOPC(ctx);
3162
#else
3163
    /* Restore CPU state */
3164
    if (unlikely(!ctx->supervisor)) {
3165
        GEN_EXCP_PRIVOPC(ctx);
3166
        return;
3167
    }
3168
    gen_op_rfi();
3169
    GEN_SYNC(ctx);
3170
#endif
3171
}
3172

    
3173
#if defined(TARGET_PPC64)
3174
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3175
{
3176
#if defined(CONFIG_USER_ONLY)
3177
    GEN_EXCP_PRIVOPC(ctx);
3178
#else
3179
    /* Restore CPU state */
3180
    if (unlikely(!ctx->supervisor)) {
3181
        GEN_EXCP_PRIVOPC(ctx);
3182
        return;
3183
    }
3184
    gen_op_rfid();
3185
    GEN_SYNC(ctx);
3186
#endif
3187
}
3188

    
3189
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3190
{
3191
#if defined(CONFIG_USER_ONLY)
3192
    GEN_EXCP_PRIVOPC(ctx);
3193
#else
3194
    /* Restore CPU state */
3195
    if (unlikely(ctx->supervisor <= 1)) {
3196
        GEN_EXCP_PRIVOPC(ctx);
3197
        return;
3198
    }
3199
    gen_op_hrfid();
3200
    GEN_SYNC(ctx);
3201
#endif
3202
}
3203
#endif
3204

    
3205
/* sc */
3206
#if defined(CONFIG_USER_ONLY)
3207
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3208
#else
3209
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3210
#endif
3211
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3212
{
3213
    uint32_t lev;
3214

    
3215
    lev = (ctx->opcode >> 5) & 0x7F;
3216
    GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
3217
}
3218

    
3219
/***                                Trap                                   ***/
3220
/* tw */
3221
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3222
{
3223
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3224
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3225
    /* Update the nip since this might generate a trap exception */
3226
    gen_update_nip(ctx, ctx->nip);
3227
    gen_op_tw(TO(ctx->opcode));
3228
}
3229

    
3230
/* twi */
3231
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3232
{
3233
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3234
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3235
    /* Update the nip since this might generate a trap exception */
3236
    gen_update_nip(ctx, ctx->nip);
3237
    gen_op_tw(TO(ctx->opcode));
3238
}
3239

    
3240
#if defined(TARGET_PPC64)
3241
/* td */
3242
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3243
{
3244
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3245
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3246
    /* Update the nip since this might generate a trap exception */
3247
    gen_update_nip(ctx, ctx->nip);
3248
    gen_op_td(TO(ctx->opcode));
3249
}
3250

    
3251
/* tdi */
3252
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3253
{
3254
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3255
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
3256
    /* Update the nip since this might generate a trap exception */
3257
    gen_update_nip(ctx, ctx->nip);
3258
    gen_op_td(TO(ctx->opcode));
3259
}
3260
#endif
3261

    
3262
/***                          Processor control                            ***/
3263
/* mcrxr */
3264
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3265
{
3266
    gen_op_load_xer_cr();
3267
    gen_op_store_T0_crf(crfD(ctx->opcode));
3268
    gen_op_clear_xer_ov();
3269
    gen_op_clear_xer_ca();
3270
}
3271

    
3272
/* mfcr */
3273
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3274
{
3275
    uint32_t crm, crn;
3276

    
3277
    if (likely(ctx->opcode & 0x00100000)) {
3278
        crm = CRM(ctx->opcode);
3279
        if (likely((crm ^ (crm - 1)) == 0)) {
3280
            crn = ffs(crm);
3281
            gen_op_load_cro(7 - crn);
3282
        }
3283
    } else {
3284
        gen_op_load_cr();
3285
    }
3286
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3287
}
3288

    
3289
/* mfmsr */
3290
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3291
{
3292
#if defined(CONFIG_USER_ONLY)
3293
    GEN_EXCP_PRIVREG(ctx);
3294
#else
3295
    if (unlikely(!ctx->supervisor)) {
3296
        GEN_EXCP_PRIVREG(ctx);
3297
        return;
3298
    }
3299
    gen_op_load_msr();
3300
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3301
#endif
3302
}
3303

    
3304
#if 1
3305
#define SPR_NOACCESS ((void *)(-1UL))
3306
#else
3307
static void spr_noaccess (void *opaque, int sprn)
3308
{
3309
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3310
    printf("ERROR: try to access SPR %d !\n", sprn);
3311
}
3312
#define SPR_NOACCESS (&spr_noaccess)
3313
#endif
3314

    
3315
/* mfspr */
3316
static always_inline void gen_op_mfspr (DisasContext *ctx)
3317
{
3318
    void (*read_cb)(void *opaque, int sprn);
3319
    uint32_t sprn = SPR(ctx->opcode);
3320

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

    
3362
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3363
{
3364
    gen_op_mfspr(ctx);
3365
}
3366

    
3367
/* mftb */
3368
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3369
{
3370
    gen_op_mfspr(ctx);
3371
}
3372

    
3373
/* mtcrf */
3374
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3375
{
3376
    uint32_t crm, crn;
3377

    
3378
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3379
    crm = CRM(ctx->opcode);
3380
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3381
        crn = ffs(crm);
3382
        gen_op_srli_T0(crn * 4);
3383
        gen_op_andi_T0(0xF);
3384
        gen_op_store_cro(7 - crn);
3385
    } else {
3386
        gen_op_store_cr(crm);
3387
    }
3388
}
3389

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

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

    
3452
/* mtspr */
3453
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3454
{
3455
    void (*write_cb)(void *opaque, int sprn);
3456
    uint32_t sprn = SPR(ctx->opcode);
3457

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

    
3493
/***                         Cache management                              ***/
3494
/* dcbf */
3495
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3496
{
3497
    /* XXX: specification says this is treated as a load by the MMU */
3498
    gen_addr_reg_index(ctx);
3499
    op_ldst(lbz);
3500
}
3501

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

    
3519
/* dcdst */
3520
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3521
{
3522
    /* XXX: specification say this is treated as a load by the MMU */
3523
    gen_addr_reg_index(ctx);
3524
    op_ldst(lbz);
3525
}
3526

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

    
3536
/* dcbtst */
3537
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3538
{
3539
    /* interpreted as no-op */
3540
    /* XXX: specification say this is treated as a load by the MMU
3541
     *      but does not generate any exception
3542
     */
3543
}
3544

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

    
3598
static always_inline void handler_dcbz (DisasContext *ctx,
3599
                                        int dcache_line_size)
3600
{
3601
    int n;
3602

    
3603
    switch (dcache_line_size) {
3604
    case 32:
3605
        n = 0;
3606
        break;
3607
    case 64:
3608
        n = 1;
3609
        break;
3610
    case 128:
3611
        n = 2;
3612
        break;
3613
    default:
3614
        n = 3;
3615
        break;
3616
    }
3617
    op_dcbz(n);
3618
}
3619

    
3620
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
3621
{
3622
    gen_addr_reg_index(ctx);
3623
    handler_dcbz(ctx, ctx->dcache_line_size);
3624
    gen_op_check_reservation();
3625
}
3626

    
3627
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
3628
{
3629
    gen_addr_reg_index(ctx);
3630
    if (ctx->opcode & 0x00200000)
3631
        handler_dcbz(ctx, ctx->dcache_line_size);
3632
    else
3633
        handler_dcbz(ctx, -1);
3634
    gen_op_check_reservation();
3635
}
3636

    
3637
/* icbi */
3638
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3639
#define gen_op_icbi_le_raw       gen_op_icbi_raw
3640
#define gen_op_icbi_le_user      gen_op_icbi_user
3641
#define gen_op_icbi_le_kernel    gen_op_icbi_kernel
3642
#define gen_op_icbi_le_hypv      gen_op_icbi_hypv
3643
#define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
3644
#define gen_op_icbi_le_64_user   gen_op_icbi_64_user
3645
#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
3646
#define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
3647
static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
3648
    GEN_MEM_FUNCS(icbi),
3649
};
3650

    
3651
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
3652
{
3653
    /* NIP cannot be restored if the memory exception comes from an helper */
3654
    gen_update_nip(ctx, ctx->nip - 4);
3655
    gen_addr_reg_index(ctx);
3656
    op_icbi();
3657
}
3658

    
3659
/* Optional: */
3660
/* dcba */
3661
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3662
{
3663
    /* interpreted as no-op */
3664
    /* XXX: specification say this is treated as a store by the MMU
3665
     *      but does not generate any exception
3666
     */
3667
}
3668

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

    
3687
/* mfsrin */
3688
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3689
{
3690
#if defined(CONFIG_USER_ONLY)
3691
    GEN_EXCP_PRIVREG(ctx);
3692
#else
3693
    if (unlikely(!ctx->supervisor)) {
3694
        GEN_EXCP_PRIVREG(ctx);
3695
        return;
3696
    }
3697
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3698
    gen_op_srli_T1(28);
3699
    gen_op_load_sr();
3700
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3701
#endif
3702
}
3703

    
3704
/* mtsr */
3705
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3706
{
3707
#if defined(CONFIG_USER_ONLY)
3708
    GEN_EXCP_PRIVREG(ctx);
3709
#else
3710
    if (unlikely(!ctx->supervisor)) {
3711
        GEN_EXCP_PRIVREG(ctx);
3712
        return;
3713
    }
3714
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3715
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3716
    gen_op_store_sr();
3717
#endif
3718
}
3719

    
3720
/* mtsrin */
3721
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3722
{
3723
#if defined(CONFIG_USER_ONLY)
3724
    GEN_EXCP_PRIVREG(ctx);
3725
#else
3726
    if (unlikely(!ctx->supervisor)) {
3727
        GEN_EXCP_PRIVREG(ctx);
3728
        return;
3729
    }
3730
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3731
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3732
    gen_op_srli_T1(28);
3733
    gen_op_store_sr();
3734
#endif
3735
}
3736

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

    
3755
/* mfsrin */
3756
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
3757
             PPC_SEGMENT_64B)
3758
{
3759
#if defined(CONFIG_USER_ONLY)
3760
    GEN_EXCP_PRIVREG(ctx);
3761
#else
3762
    if (unlikely(!ctx->supervisor)) {
3763
        GEN_EXCP_PRIVREG(ctx);
3764
        return;
3765
    }
3766
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3767
    gen_op_srli_T1(28);
3768
    gen_op_load_slb();
3769
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3770
#endif
3771
}
3772

    
3773
/* mtsr */
3774
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
3775
{
3776
#if defined(CONFIG_USER_ONLY)
3777
    GEN_EXCP_PRIVREG(ctx);
3778
#else
3779
    if (unlikely(!ctx->supervisor)) {
3780
        GEN_EXCP_PRIVREG(ctx);
3781
        return;
3782
    }
3783
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
3784
    tcg_gen_movi_tl(cpu_T[1], SR(ctx->opcode));
3785
    gen_op_store_slb();
3786
#endif
3787
}
3788

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

    
3808
/***                      Lookaside buffer management                      ***/
3809
/* Optional & supervisor only: */
3810
/* tlbia */
3811
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3812
{
3813
#if defined(CONFIG_USER_ONLY)
3814
    GEN_EXCP_PRIVOPC(ctx);
3815
#else
3816
    if (unlikely(!ctx->supervisor)) {
3817
        GEN_EXCP_PRIVOPC(ctx);
3818
        return;
3819
    }
3820
    gen_op_tlbia();
3821
#endif
3822
}
3823

    
3824
/* tlbie */
3825
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3826
{
3827
#if defined(CONFIG_USER_ONLY)
3828
    GEN_EXCP_PRIVOPC(ctx);
3829
#else
3830
    if (unlikely(!ctx->supervisor)) {
3831
        GEN_EXCP_PRIVOPC(ctx);
3832
        return;
3833
    }
3834
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
3835
#if defined(TARGET_PPC64)
3836
    if (ctx->sf_mode)
3837
        gen_op_tlbie_64();
3838
    else
3839
#endif
3840
        gen_op_tlbie();
3841
#endif
3842
}
3843

    
3844
/* tlbsync */
3845
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3846
{
3847
#if defined(CONFIG_USER_ONLY)
3848
    GEN_EXCP_PRIVOPC(ctx);
3849
#else
3850
    if (unlikely(!ctx->supervisor)) {
3851
        GEN_EXCP_PRIVOPC(ctx);
3852
        return;
3853
    }
3854
    /* This has no effect: it should ensure that all previous
3855
     * tlbie have completed
3856
     */
3857
    GEN_STOP(ctx);
3858
#endif
3859
}
3860

    
3861
#if defined(TARGET_PPC64)
3862
/* slbia */
3863
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3864
{
3865
#if defined(CONFIG_USER_ONLY)
3866
    GEN_EXCP_PRIVOPC(ctx);
3867
#else
3868
    if (unlikely(!ctx->supervisor)) {
3869
        GEN_EXCP_PRIVOPC(ctx);
3870
        return;
3871
    }
3872
    gen_op_slbia();
3873
#endif
3874
}
3875

    
3876
/* slbie */
3877
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3878
{
3879
#if defined(CONFIG_USER_ONLY)
3880
    GEN_EXCP_PRIVOPC(ctx);
3881
#else
3882
    if (unlikely(!ctx->supervisor)) {
3883
        GEN_EXCP_PRIVOPC(ctx);
3884
        return;
3885
    }
3886
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
3887
    gen_op_slbie();
3888
#endif
3889
}
3890
#endif
3891

    
3892
/***                              External control                         ***/
3893
/* Optional: */
3894
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3895
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3896
static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
3897
    GEN_MEM_FUNCS(eciwx),
3898
};
3899
static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
3900
    GEN_MEM_FUNCS(ecowx),
3901
};
3902

    
3903
/* eciwx */
3904
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3905
{
3906
    /* Should check EAR[E] & alignment ! */
3907
    gen_addr_reg_index(ctx);
3908
    op_eciwx();
3909
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3910
}
3911

    
3912
/* ecowx */
3913
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3914
{
3915
    /* Should check EAR[E] & alignment ! */
3916
    gen_addr_reg_index(ctx);
3917
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
3918
    op_ecowx();
3919
}
3920

    
3921
/* PowerPC 601 specific instructions */
3922
/* abs - abs. */
3923
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3924
{
3925
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3926
    gen_op_POWER_abs();
3927
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3928
    if (unlikely(Rc(ctx->opcode) != 0))
3929
        gen_set_Rc0(ctx);
3930
}
3931

    
3932
/* abso - abso. */
3933
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3934
{
3935
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3936
    gen_op_POWER_abso();
3937
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3938
    if (unlikely(Rc(ctx->opcode) != 0))
3939
        gen_set_Rc0(ctx);
3940
}
3941

    
3942
/* clcs */
3943
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3944
{
3945
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3946
    gen_op_POWER_clcs();
3947
    /* Rc=1 sets CR0 to an undefined state */
3948
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3949
}
3950

    
3951
/* div - div. */
3952
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3953
{
3954
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3955
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3956
    gen_op_POWER_div();
3957
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3958
    if (unlikely(Rc(ctx->opcode) != 0))
3959
        gen_set_Rc0(ctx);
3960
}
3961

    
3962
/* divo - divo. */
3963
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3964
{
3965
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3966
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3967
    gen_op_POWER_divo();
3968
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3969
    if (unlikely(Rc(ctx->opcode) != 0))
3970
        gen_set_Rc0(ctx);
3971
}
3972

    
3973
/* divs - divs. */
3974
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3975
{
3976
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3977
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3978
    gen_op_POWER_divs();
3979
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3980
    if (unlikely(Rc(ctx->opcode) != 0))
3981
        gen_set_Rc0(ctx);
3982
}
3983

    
3984
/* divso - divso. */
3985
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3986
{
3987
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3988
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
3989
    gen_op_POWER_divso();
3990
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
3991
    if (unlikely(Rc(ctx->opcode) != 0))
3992
        gen_set_Rc0(ctx);
3993
}
3994

    
3995
/* doz - doz. */
3996
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3997
{
3998
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
3999
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4000
    gen_op_POWER_doz();
4001
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4002
    if (unlikely(Rc(ctx->opcode) != 0))
4003
        gen_set_Rc0(ctx);
4004
}
4005

    
4006
/* dozo - dozo. */
4007
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
4008
{
4009
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4010
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4011
    gen_op_POWER_dozo();
4012
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4013
    if (unlikely(Rc(ctx->opcode) != 0))
4014
        gen_set_Rc0(ctx);
4015
}
4016

    
4017
/* dozi */
4018
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4019
{
4020
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4021
    tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode));
4022
    gen_op_POWER_doz();
4023
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4024
}
4025

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

    
4047
/* lscbx - lscbx. */
4048
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
4049
{
4050
    int ra = rA(ctx->opcode);
4051
    int rb = rB(ctx->opcode);
4052

    
4053
    gen_addr_reg_index(ctx);
4054
    if (ra == 0) {
4055
        ra = rb;
4056
    }
4057
    /* NIP cannot be restored if the memory exception comes from an helper */
4058
    gen_update_nip(ctx, ctx->nip - 4);
4059
    gen_op_load_xer_bc();
4060
    gen_op_load_xer_cmp();
4061
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
4062
    gen_op_store_xer_bc();
4063
    if (unlikely(Rc(ctx->opcode) != 0))
4064
        gen_set_Rc0(ctx);
4065
}
4066

    
4067
/* maskg - maskg. */
4068
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
4069
{
4070
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4071
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4072
    gen_op_POWER_maskg();
4073
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4074
    if (unlikely(Rc(ctx->opcode) != 0))
4075
        gen_set_Rc0(ctx);
4076
}
4077

    
4078
/* maskir - maskir. */
4079
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4080
{
4081
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4082
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
4083
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4084
    gen_op_POWER_maskir();
4085
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4086
    if (unlikely(Rc(ctx->opcode) != 0))
4087
        gen_set_Rc0(ctx);
4088
}
4089

    
4090
/* mul - mul. */
4091
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4092
{
4093
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4094
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4095
    gen_op_POWER_mul();
4096
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4097
    if (unlikely(Rc(ctx->opcode) != 0))
4098
        gen_set_Rc0(ctx);
4099
}
4100

    
4101
/* mulo - mulo. */
4102
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4103
{
4104
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4105
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4106
    gen_op_POWER_mulo();
4107
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4108
    if (unlikely(Rc(ctx->opcode) != 0))
4109
        gen_set_Rc0(ctx);
4110
}
4111

    
4112
/* nabs - nabs. */
4113
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4114
{
4115
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4116
    gen_op_POWER_nabs();
4117
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4118
    if (unlikely(Rc(ctx->opcode) != 0))
4119
        gen_set_Rc0(ctx);
4120
}
4121

    
4122
/* nabso - nabso. */
4123
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4124
{
4125
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4126
    gen_op_POWER_nabso();
4127
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4128
    if (unlikely(Rc(ctx->opcode) != 0))
4129
        gen_set_Rc0(ctx);
4130
}
4131

    
4132
/* rlmi - rlmi. */
4133
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4134
{
4135
    uint32_t mb, me;
4136

    
4137
    mb = MB(ctx->opcode);
4138
    me = ME(ctx->opcode);
4139
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4140
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4141
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4142
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4143
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4144
    if (unlikely(Rc(ctx->opcode) != 0))
4145
        gen_set_Rc0(ctx);
4146
}
4147

    
4148
/* rrib - rrib. */
4149
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4150
{
4151
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4152
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]);
4153
    tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]);
4154
    gen_op_POWER_rrib();
4155
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4156
    if (unlikely(Rc(ctx->opcode) != 0))
4157
        gen_set_Rc0(ctx);
4158
}
4159

    
4160
/* sle - sle. */
4161
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4162
{
4163
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4164
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4165
    gen_op_POWER_sle();
4166
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4167
    if (unlikely(Rc(ctx->opcode) != 0))
4168
        gen_set_Rc0(ctx);
4169
}
4170

    
4171
/* sleq - sleq. */
4172
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4173
{
4174
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4175
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4176
    gen_op_POWER_sleq();
4177
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4178
    if (unlikely(Rc(ctx->opcode) != 0))
4179
        gen_set_Rc0(ctx);
4180
}
4181

    
4182
/* sliq - sliq. */
4183
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4184
{
4185
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4186
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4187
    gen_op_POWER_sle();
4188
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4189
    if (unlikely(Rc(ctx->opcode) != 0))
4190
        gen_set_Rc0(ctx);
4191
}
4192

    
4193
/* slliq - slliq. */
4194
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4195
{
4196
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4197
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4198
    gen_op_POWER_sleq();
4199
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4200
    if (unlikely(Rc(ctx->opcode) != 0))
4201
        gen_set_Rc0(ctx);
4202
}
4203

    
4204
/* sllq - sllq. */
4205
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4206
{
4207
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4208
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4209
    gen_op_POWER_sllq();
4210
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4211
    if (unlikely(Rc(ctx->opcode) != 0))
4212
        gen_set_Rc0(ctx);
4213
}
4214

    
4215
/* slq - slq. */
4216
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4217
{
4218
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4219
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4220
    gen_op_POWER_slq();
4221
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4222
    if (unlikely(Rc(ctx->opcode) != 0))
4223
        gen_set_Rc0(ctx);
4224
}
4225

    
4226
/* sraiq - sraiq. */
4227
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4228
{
4229
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4230
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4231
    gen_op_POWER_sraq();
4232
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4233
    if (unlikely(Rc(ctx->opcode) != 0))
4234
        gen_set_Rc0(ctx);
4235
}
4236

    
4237
/* sraq - sraq. */
4238
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4239
{
4240
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4241
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4242
    gen_op_POWER_sraq();
4243
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4244
    if (unlikely(Rc(ctx->opcode) != 0))
4245
        gen_set_Rc0(ctx);
4246
}
4247

    
4248
/* sre - sre. */
4249
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4250
{
4251
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4252
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4253
    gen_op_POWER_sre();
4254
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4255
    if (unlikely(Rc(ctx->opcode) != 0))
4256
        gen_set_Rc0(ctx);
4257
}
4258

    
4259
/* srea - srea. */
4260
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4261
{
4262
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4263
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4264
    gen_op_POWER_srea();
4265
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4266
    if (unlikely(Rc(ctx->opcode) != 0))
4267
        gen_set_Rc0(ctx);
4268
}
4269

    
4270
/* sreq */
4271
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4272
{
4273
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4274
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4275
    gen_op_POWER_sreq();
4276
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4277
    if (unlikely(Rc(ctx->opcode) != 0))
4278
        gen_set_Rc0(ctx);
4279
}
4280

    
4281
/* sriq */
4282
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4283
{
4284
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4285
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4286
    gen_op_POWER_srq();
4287
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4288
    if (unlikely(Rc(ctx->opcode) != 0))
4289
        gen_set_Rc0(ctx);
4290
}
4291

    
4292
/* srliq */
4293
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4294
{
4295
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4296
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4297
    tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode));
4298
    gen_op_POWER_srlq();
4299
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4300
    if (unlikely(Rc(ctx->opcode) != 0))
4301
        gen_set_Rc0(ctx);
4302
}
4303

    
4304
/* srlq */
4305
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4306
{
4307
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4308
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4309
    gen_op_POWER_srlq();
4310
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4311
    if (unlikely(Rc(ctx->opcode) != 0))
4312
        gen_set_Rc0(ctx);
4313
}
4314

    
4315
/* srq */
4316
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4317
{
4318
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
4319
    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
4320
    gen_op_POWER_srq();
4321
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
4322
    if (unlikely(Rc(ctx->opcode) != 0))
4323
        gen_set_Rc0(ctx);
4324
}
4325

    
4326
/* PowerPC 602 specific instructions */
4327
/* dsa  */
4328
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4329
{
4330
    /* XXX: TODO */
4331
    GEN_EXCP_INVAL(ctx);
4332
}
4333

    
4334
/* esa */
4335
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4336
{
4337
    /* XXX: TODO */
4338
    GEN_EXCP_INVAL(ctx);
4339
}
4340

    
4341
/* mfrom */
4342
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4343
{
4344
#if defined(CONFIG_USER_ONLY)
4345
    GEN_EXCP_PRIVOPC(ctx);
4346
#else
4347
    if (unlikely(!ctx->supervisor)) {
4348
        GEN_EXCP_PRIVOPC(ctx);
4349
        return;
4350
    }
4351
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
4352
    gen_op_602_mfrom();
4353
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4354
#endif
4355
}
4356

    
4357
/* 602 - 603 - G2 TLB management */
4358
/* tlbld */
4359
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
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
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4369
    gen_op_6xx_tlbld();
4370
#endif
4371
}
4372

    
4373
/* tlbli */
4374
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4375
{
4376
#if defined(CONFIG_USER_ONLY)
4377
    GEN_EXCP_PRIVOPC(ctx);
4378
#else
4379
    if (unlikely(!ctx->supervisor)) {
4380
        GEN_EXCP_PRIVOPC(ctx);
4381
        return;
4382
    }
4383
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4384
    gen_op_6xx_tlbli();
4385
#endif
4386
}
4387

    
4388
/* 74xx TLB management */
4389
/* tlbld */
4390
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4391
{
4392
#if defined(CONFIG_USER_ONLY)
4393
    GEN_EXCP_PRIVOPC(ctx);
4394
#else
4395
    if (unlikely(!ctx->supervisor)) {
4396
        GEN_EXCP_PRIVOPC(ctx);
4397
        return;
4398
    }
4399
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4400
    gen_op_74xx_tlbld();
4401
#endif
4402
}
4403

    
4404
/* tlbli */
4405
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4406
{
4407
#if defined(CONFIG_USER_ONLY)
4408
    GEN_EXCP_PRIVOPC(ctx);
4409
#else
4410
    if (unlikely(!ctx->supervisor)) {
4411
        GEN_EXCP_PRIVOPC(ctx);
4412
        return;
4413
    }
4414
    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rB(ctx->opcode)]);
4415
    gen_op_74xx_tlbli();
4416
#endif
4417
}
4418

    
4419
/* POWER instructions not in PowerPC 601 */
4420
/* clf */
4421
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4422
{
4423
    /* Cache line flush: implemented as no-op */
4424
}
4425

    
4426
/* cli */
4427
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4428
{
4429
    /* Cache line invalidate: privileged and treated as no-op */
4430
#if defined(CONFIG_USER_ONLY)
4431
    GEN_EXCP_PRIVOPC(ctx);
4432
#else
4433
    if (unlikely(!ctx->supervisor)) {
4434
        GEN_EXCP_PRIVOPC(ctx);
4435
        return;
4436
    }
4437
#endif
4438
}
4439

    
4440
/* dclst */
4441
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4442
{
4443
    /* Data cache line store: treated as no-op */
4444
}
4445

    
4446
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4447
{
4448
#if defined(CONFIG_USER_ONLY)
4449
    GEN_EXCP_PRIVOPC(ctx);
4450
#else
4451
    if (unlikely(!ctx->supervisor)) {
4452
        GEN_EXCP_PRIVOPC(ctx);
4453
        return;
4454
    }
4455
    int ra = rA(ctx->opcode);
4456
    int rd = rD(ctx->opcode);
4457

    
4458
    gen_addr_reg_index(ctx);
4459
    gen_op_POWER_mfsri();
4460
    tcg_gen_mov_tl(cpu_gpr[rd], cpu_T[0]);
4461
    if (ra != 0 && ra != rd)
4462
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[1]);
4463
#endif
4464
}
4465

    
4466
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4467
{
4468
#if defined(CONFIG_USER_ONLY)
4469
    GEN_EXCP_PRIVOPC(ctx);
4470
#else
4471
    if (unlikely(!ctx->supervisor)) {
4472
        GEN_EXCP_PRIVOPC(ctx);
4473
        return;
4474
    }
4475
    gen_addr_reg_index(ctx);
4476
    gen_op_POWER_rac();
4477
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
4478
#endif
4479
}
4480

    
4481
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4482
{
4483
#if defined(CONFIG_USER_ONLY)
4484
    GEN_EXCP_PRIVOPC(ctx);
4485
#else
4486
    if (unlikely(!ctx->supervisor)) {
4487
        GEN_EXCP_PRIVOPC(ctx);
4488
        return;
4489
    }
4490
    gen_op_POWER_rfsvc();
4491
    GEN_SYNC(ctx);
4492
#endif
4493
}
4494

    
4495
/* svc is not implemented for now */
4496

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

    
4525
/* lfq */
4526
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4527
{
4528
    /* NIP cannot be restored if the memory exception comes from an helper */
4529
    gen_update_nip(ctx, ctx->nip - 4);
4530
    gen_addr_imm_index(ctx, 0);
4531
    op_POWER2_lfq();
4532
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4533
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4534
}
4535

    
4536
/* lfqu */
4537
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4538
{
4539
    int ra = rA(ctx->opcode);
4540

    
4541
    /* NIP cannot be restored if the memory exception comes from an helper */
4542
    gen_update_nip(ctx, ctx->nip - 4);
4543
    gen_addr_imm_index(ctx, 0);
4544
    op_POWER2_lfq();
4545
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4546
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4547
    if (ra != 0)
4548
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4549
}
4550

    
4551
/* lfqux */
4552
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4553
{
4554
    int ra = rA(ctx->opcode);
4555

    
4556
    /* NIP cannot be restored if the memory exception comes from an helper */
4557
    gen_update_nip(ctx, ctx->nip - 4);
4558
    gen_addr_reg_index(ctx);
4559
    op_POWER2_lfq();
4560
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4561
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4562
    if (ra != 0)
4563
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4564
}
4565

    
4566
/* lfqx */
4567
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4568
{
4569
    /* NIP cannot be restored if the memory exception comes from an helper */
4570
    gen_update_nip(ctx, ctx->nip - 4);
4571
    gen_addr_reg_index(ctx);
4572
    op_POWER2_lfq();
4573
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
4574
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
4575
}
4576

    
4577
/* stfq */
4578
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4579
{
4580
    /* NIP cannot be restored if the memory exception comes from an helper */
4581
    gen_update_nip(ctx, ctx->nip - 4);
4582
    gen_addr_imm_index(ctx, 0);
4583
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4584
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4585
    op_POWER2_stfq();
4586
}
4587

    
4588
/* stfqu */
4589
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4590
{
4591
    int ra = rA(ctx->opcode);
4592

    
4593
    /* NIP cannot be restored if the memory exception comes from an helper */
4594
    gen_update_nip(ctx, ctx->nip - 4);
4595
    gen_addr_imm_index(ctx, 0);
4596
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4597
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4598
    op_POWER2_stfq();
4599
    if (ra != 0)
4600
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4601
}
4602

    
4603
/* stfqux */
4604
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4605
{
4606
    int ra = rA(ctx->opcode);
4607

    
4608
    /* NIP cannot be restored if the memory exception comes from an helper */
4609
    gen_update_nip(ctx, ctx->nip - 4);
4610
    gen_addr_reg_index(ctx);
4611
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4612
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4613
    op_POWER2_stfq();
4614
    if (ra != 0)
4615
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
4616
}
4617

    
4618
/* stfqx */
4619
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4620
{
4621
    /* NIP cannot be restored if the memory exception comes from an helper */
4622
    gen_update_nip(ctx, ctx->nip - 4);
4623
    gen_addr_reg_index(ctx);
4624
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
4625
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
4626
    op_POWER2_stfq();
4627
}
4628

    
4629
/* BookE specific instructions */
4630
/* XXX: not implemented on 440 ? */
4631
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
4632
{
4633
    /* XXX: TODO */
4634
    GEN_EXCP_INVAL(ctx);
4635
}
4636

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

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

    
4740
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4741
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4742
{                                                                             \
4743
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4744
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4745
}
4746

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