Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 8cbcb4fa

History | View | Annotate | Download (220.9 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 "tcg-op.h"
30
#include "qemu-common.h"
31

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

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

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

    
46
#if defined(OPTIMIZE_FPRF_UPDATE)
47
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
48
static uint16_t **gen_fprf_ptr;
49
#endif
50

    
51
static always_inline void gen_set_T0 (target_ulong val)
52
{
53
#if defined(TARGET_PPC64)
54
    if (val >> 32)
55
        gen_op_set_T0_64(val >> 32, val);
56
    else
57
#endif
58
        gen_op_set_T0(val);
59
}
60

    
61
static always_inline void gen_set_T1 (target_ulong val)
62
{
63
#if defined(TARGET_PPC64)
64
    if (val >> 32)
65
        gen_op_set_T1_64(val >> 32, val);
66
    else
67
#endif
68
        gen_op_set_T1(val);
69
}
70

    
71
#define GEN8(func, NAME)                                                      \
72
static GenOpFunc *NAME ## _table [8] = {                                      \
73
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
74
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
75
};                                                                            \
76
static always_inline void func (int n)                                        \
77
{                                                                             \
78
    NAME ## _table[n]();                                                      \
79
}
80

    
81
#define GEN16(func, NAME)                                                     \
82
static GenOpFunc *NAME ## _table [16] = {                                     \
83
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
84
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
85
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
86
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
87
};                                                                            \
88
static always_inline void func (int n)                                        \
89
{                                                                             \
90
    NAME ## _table[n]();                                                      \
91
}
92

    
93
#define GEN32(func, NAME)                                                     \
94
static GenOpFunc *NAME ## _table [32] = {                                     \
95
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
96
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
97
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
98
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
99
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
100
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
101
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
102
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
103
};                                                                            \
104
static always_inline void func (int n)                                        \
105
{                                                                             \
106
    NAME ## _table[n]();                                                      \
107
}
108

    
109
/* Condition register moves */
110
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
111
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
112
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
113
#if 0 // Unused
114
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
115
#endif
116

    
117
/* General purpose registers moves */
118
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
119
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
120
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
121

    
122
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
123
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
124
#if 0 // unused
125
GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
126
#endif
127

    
128
/* floating point registers moves */
129
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
130
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
131
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
132
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
133
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
134
#if 0 // unused
135
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
136
#endif
137

    
138
/* internal defines */
139
typedef struct DisasContext {
140
    struct TranslationBlock *tb;
141
    target_ulong nip;
142
    uint32_t opcode;
143
    uint32_t exception;
144
    /* Routine used to access memory */
145
    int mem_idx;
146
    /* Translation flags */
147
#if !defined(CONFIG_USER_ONLY)
148
    int supervisor;
149
#endif
150
#if defined(TARGET_PPC64)
151
    int sf_mode;
152
#endif
153
    int fpu_enabled;
154
    int altivec_enabled;
155
    int spe_enabled;
156
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
157
    int singlestep_enabled;
158
    int dcache_line_size;
159
} DisasContext;
160

    
161
struct opc_handler_t {
162
    /* invalid bits */
163
    uint32_t inval;
164
    /* instruction type */
165
    uint64_t type;
166
    /* handler */
167
    void (*handler)(DisasContext *ctx);
168
#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
169
    const unsigned char *oname;
170
#endif
171
#if defined(DO_PPC_STATISTICS)
172
    uint64_t count;
173
#endif
174
};
175

    
176
static always_inline void gen_set_Rc0 (DisasContext *ctx)
177
{
178
#if defined(TARGET_PPC64)
179
    if (ctx->sf_mode)
180
        gen_op_cmpi_64(0);
181
    else
182
#endif
183
        gen_op_cmpi(0);
184
    gen_op_set_Rc0();
185
}
186

    
187
static always_inline void gen_reset_fpstatus (void)
188
{
189
#ifdef CONFIG_SOFTFLOAT
190
    gen_op_reset_fpstatus();
191
#endif
192
}
193

    
194
static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
195
{
196
    if (set_fprf != 0) {
197
        /* This case might be optimized later */
198
#if defined(OPTIMIZE_FPRF_UPDATE)
199
        *gen_fprf_ptr++ = gen_opc_ptr;
200
#endif
201
        gen_op_compute_fprf(1);
202
        if (unlikely(set_rc))
203
            gen_op_store_T0_crf(1);
204
        gen_op_float_check_status();
205
    } else if (unlikely(set_rc)) {
206
        /* We always need to compute fpcc */
207
        gen_op_compute_fprf(0);
208
        gen_op_store_T0_crf(1);
209
        if (set_fprf)
210
            gen_op_float_check_status();
211
    }
212
}
213

    
214
static always_inline void gen_optimize_fprf (void)
215
{
216
#if defined(OPTIMIZE_FPRF_UPDATE)
217
    uint16_t **ptr;
218

    
219
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
220
        *ptr = INDEX_op_nop1;
221
    gen_fprf_ptr = gen_fprf_buf;
222
#endif
223
}
224

    
225
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
226
{
227
#if defined(TARGET_PPC64)
228
    if (ctx->sf_mode)
229
        gen_op_update_nip_64(nip >> 32, nip);
230
    else
231
#endif
232
        gen_op_update_nip(nip);
233
}
234

    
235
#define GEN_EXCP(ctx, excp, error)                                            \
236
do {                                                                          \
237
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
238
        gen_update_nip(ctx, (ctx)->nip);                                      \
239
    }                                                                         \
240
    gen_op_raise_exception_err((excp), (error));                              \
241
    ctx->exception = (excp);                                                  \
242
} while (0)
243

    
244
#define GEN_EXCP_INVAL(ctx)                                                   \
245
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
246
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
247

    
248
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
249
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
250
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
251

    
252
#define GEN_EXCP_PRIVREG(ctx)                                                 \
253
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
254
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
255

    
256
#define GEN_EXCP_NO_FP(ctx)                                                   \
257
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
258

    
259
#define GEN_EXCP_NO_AP(ctx)                                                   \
260
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
261

    
262
#define GEN_EXCP_NO_VR(ctx)                                                   \
263
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
264

    
265
/* Stop translation */
266
static always_inline void GEN_STOP (DisasContext *ctx)
267
{
268
    gen_update_nip(ctx, ctx->nip);
269
    ctx->exception = POWERPC_EXCP_STOP;
270
}
271

    
272
/* No need to update nip here, as execution flow will change */
273
static always_inline void GEN_SYNC (DisasContext *ctx)
274
{
275
    ctx->exception = POWERPC_EXCP_SYNC;
276
}
277

    
278
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
279
static void gen_##name (DisasContext *ctx);                                   \
280
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
281
static void gen_##name (DisasContext *ctx)
282

    
283
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
284
static void gen_##name (DisasContext *ctx);                                   \
285
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
286
static void gen_##name (DisasContext *ctx)
287

    
288
typedef struct opcode_t {
289
    unsigned char opc1, opc2, opc3;
290
#if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
291
    unsigned char pad[5];
292
#else
293
    unsigned char pad[1];
294
#endif
295
    opc_handler_t handler;
296
    const unsigned char *oname;
297
} opcode_t;
298

    
299
/*****************************************************************************/
300
/***                           Instruction decoding                        ***/
301
#define EXTRACT_HELPER(name, shift, nb)                                       \
302
static always_inline uint32_t name (uint32_t opcode)                          \
303
{                                                                             \
304
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
305
}
306

    
307
#define EXTRACT_SHELPER(name, shift, nb)                                      \
308
static always_inline int32_t name (uint32_t opcode)                           \
309
{                                                                             \
310
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
311
}
312

    
313
/* Opcode part 1 */
314
EXTRACT_HELPER(opc1, 26, 6);
315
/* Opcode part 2 */
316
EXTRACT_HELPER(opc2, 1, 5);
317
/* Opcode part 3 */
318
EXTRACT_HELPER(opc3, 6, 5);
319
/* Update Cr0 flags */
320
EXTRACT_HELPER(Rc, 0, 1);
321
/* Destination */
322
EXTRACT_HELPER(rD, 21, 5);
323
/* Source */
324
EXTRACT_HELPER(rS, 21, 5);
325
/* First operand */
326
EXTRACT_HELPER(rA, 16, 5);
327
/* Second operand */
328
EXTRACT_HELPER(rB, 11, 5);
329
/* Third operand */
330
EXTRACT_HELPER(rC, 6, 5);
331
/***                               Get CRn                                 ***/
332
EXTRACT_HELPER(crfD, 23, 3);
333
EXTRACT_HELPER(crfS, 18, 3);
334
EXTRACT_HELPER(crbD, 21, 5);
335
EXTRACT_HELPER(crbA, 16, 5);
336
EXTRACT_HELPER(crbB, 11, 5);
337
/* SPR / TBL */
338
EXTRACT_HELPER(_SPR, 11, 10);
339
static always_inline uint32_t SPR (uint32_t opcode)
340
{
341
    uint32_t sprn = _SPR(opcode);
342

    
343
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
344
}
345
/***                              Get constants                            ***/
346
EXTRACT_HELPER(IMM, 12, 8);
347
/* 16 bits signed immediate value */
348
EXTRACT_SHELPER(SIMM, 0, 16);
349
/* 16 bits unsigned immediate value */
350
EXTRACT_HELPER(UIMM, 0, 16);
351
/* Bit count */
352
EXTRACT_HELPER(NB, 11, 5);
353
/* Shift count */
354
EXTRACT_HELPER(SH, 11, 5);
355
/* Mask start */
356
EXTRACT_HELPER(MB, 6, 5);
357
/* Mask end */
358
EXTRACT_HELPER(ME, 1, 5);
359
/* Trap operand */
360
EXTRACT_HELPER(TO, 21, 5);
361

    
362
EXTRACT_HELPER(CRM, 12, 8);
363
EXTRACT_HELPER(FM, 17, 8);
364
EXTRACT_HELPER(SR, 16, 4);
365
EXTRACT_HELPER(FPIMM, 20, 4);
366

    
367
/***                            Jump target decoding                       ***/
368
/* Displacement */
369
EXTRACT_SHELPER(d, 0, 16);
370
/* Immediate address */
371
static always_inline target_ulong LI (uint32_t opcode)
372
{
373
    return (opcode >> 0) & 0x03FFFFFC;
374
}
375

    
376
static always_inline uint32_t BD (uint32_t opcode)
377
{
378
    return (opcode >> 0) & 0xFFFC;
379
}
380

    
381
EXTRACT_HELPER(BO, 21, 5);
382
EXTRACT_HELPER(BI, 16, 5);
383
/* Absolute/relative address */
384
EXTRACT_HELPER(AA, 1, 1);
385
/* Link */
386
EXTRACT_HELPER(LK, 0, 1);
387

    
388
/* Create a mask between <start> and <end> bits */
389
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
390
{
391
    target_ulong ret;
392

    
393
#if defined(TARGET_PPC64)
394
    if (likely(start == 0)) {
395
        ret = UINT64_MAX << (63 - end);
396
    } else if (likely(end == 63)) {
397
        ret = UINT64_MAX >> start;
398
    }
399
#else
400
    if (likely(start == 0)) {
401
        ret = UINT32_MAX << (31  - end);
402
    } else if (likely(end == 31)) {
403
        ret = UINT32_MAX >> start;
404
    }
405
#endif
406
    else {
407
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
408
            (((target_ulong)(-1ULL) >> (end)) >> 1);
409
        if (unlikely(start > end))
410
            return ~ret;
411
    }
412

    
413
    return ret;
414
}
415

    
416
/*****************************************************************************/
417
/* PowerPC Instructions types definitions                                    */
418
enum {
419
    PPC_NONE           = 0x0000000000000000ULL,
420
    /* PowerPC base instructions set                                         */
421
    PPC_INSNS_BASE     = 0x0000000000000001ULL,
422
    /*   integer operations instructions                                     */
423
#define PPC_INTEGER PPC_INSNS_BASE
424
    /*   flow control instructions                                           */
425
#define PPC_FLOW    PPC_INSNS_BASE
426
    /*   virtual memory instructions                                         */
427
#define PPC_MEM     PPC_INSNS_BASE
428
    /*   ld/st with reservation instructions                                 */
429
#define PPC_RES     PPC_INSNS_BASE
430
    /*   spr/msr access instructions                                         */
431
#define PPC_MISC    PPC_INSNS_BASE
432
    /* Deprecated instruction sets                                           */
433
    /*   Original POWER instruction set                                      */
434
    PPC_POWER          = 0x0000000000000002ULL,
435
    /*   POWER2 instruction set extension                                    */
436
    PPC_POWER2         = 0x0000000000000004ULL,
437
    /*   Power RTC support                                                   */
438
    PPC_POWER_RTC      = 0x0000000000000008ULL,
439
    /*   Power-to-PowerPC bridge (601)                                       */
440
    PPC_POWER_BR       = 0x0000000000000010ULL,
441
    /* 64 bits PowerPC instruction set                                       */
442
    PPC_64B            = 0x0000000000000020ULL,
443
    /*   New 64 bits extensions (PowerPC 2.0x)                               */
444
    PPC_64BX           = 0x0000000000000040ULL,
445
    /*   64 bits hypervisor extensions                                       */
446
    PPC_64H            = 0x0000000000000080ULL,
447
    /*   New wait instruction (PowerPC 2.0x)                                 */
448
    PPC_WAIT           = 0x0000000000000100ULL,
449
    /*   Time base mftb instruction                                          */
450
    PPC_MFTB           = 0x0000000000000200ULL,
451

    
452
    /* Fixed-point unit extensions                                           */
453
    /*   PowerPC 602 specific                                                */
454
    PPC_602_SPEC       = 0x0000000000000400ULL,
455
    /*   isel instruction                                                    */
456
    PPC_ISEL           = 0x0000000000000800ULL,
457
    /*   popcntb instruction                                                 */
458
    PPC_POPCNTB        = 0x0000000000001000ULL,
459
    /*   string load / store                                                 */
460
    PPC_STRING         = 0x0000000000002000ULL,
461

    
462
    /* Floating-point unit extensions                                        */
463
    /*   Optional floating point instructions                                */
464
    PPC_FLOAT          = 0x0000000000010000ULL,
465
    /* New floating-point extensions (PowerPC 2.0x)                          */
466
    PPC_FLOAT_EXT      = 0x0000000000020000ULL,
467
    PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
468
    PPC_FLOAT_FRES     = 0x0000000000080000ULL,
469
    PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
470
    PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
471
    PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
472
    PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
473

    
474
    /* Vector/SIMD extensions                                                */
475
    /*   Altivec support                                                     */
476
    PPC_ALTIVEC        = 0x0000000001000000ULL,
477
    /*   PowerPC 2.03 SPE extension                                          */
478
    PPC_SPE            = 0x0000000002000000ULL,
479
    /*   PowerPC 2.03 SPE floating-point extension                           */
480
    PPC_SPEFPU         = 0x0000000004000000ULL,
481

    
482
    /* Optional memory control instructions                                  */
483
    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
484
    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
485
    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
486
    /*   sync instruction                                                    */
487
    PPC_MEM_SYNC       = 0x0000000080000000ULL,
488
    /*   eieio instruction                                                   */
489
    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
490

    
491
    /* Cache control instructions                                            */
492
    PPC_CACHE          = 0x0000000200000000ULL,
493
    /*   icbi instruction                                                    */
494
    PPC_CACHE_ICBI     = 0x0000000400000000ULL,
495
    /*   dcbz instruction with fixed cache line size                         */
496
    PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
497
    /*   dcbz instruction with tunable cache line size                       */
498
    PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
499
    /*   dcba instruction                                                    */
500
    PPC_CACHE_DCBA     = 0x0000002000000000ULL,
501
    /*   Freescale cache locking instructions                                */
502
    PPC_CACHE_LOCK     = 0x0000004000000000ULL,
503

    
504
    /* MMU related extensions                                                */
505
    /*   external control instructions                                       */
506
    PPC_EXTERN         = 0x0000010000000000ULL,
507
    /*   segment register access instructions                                */
508
    PPC_SEGMENT        = 0x0000020000000000ULL,
509
    /*   PowerPC 6xx TLB management instructions                             */
510
    PPC_6xx_TLB        = 0x0000040000000000ULL,
511
    /* PowerPC 74xx TLB management instructions                              */
512
    PPC_74xx_TLB       = 0x0000080000000000ULL,
513
    /*   PowerPC 40x TLB management instructions                             */
514
    PPC_40x_TLB        = 0x0000100000000000ULL,
515
    /*   segment register access instructions for PowerPC 64 "bridge"        */
516
    PPC_SEGMENT_64B    = 0x0000200000000000ULL,
517
    /*   SLB management                                                      */
518
    PPC_SLBI           = 0x0000400000000000ULL,
519

    
520
    /* Embedded PowerPC dedicated instructions                               */
521
    PPC_WRTEE          = 0x0001000000000000ULL,
522
    /* PowerPC 40x exception model                                           */
523
    PPC_40x_EXCP       = 0x0002000000000000ULL,
524
    /* PowerPC 405 Mac instructions                                          */
525
    PPC_405_MAC        = 0x0004000000000000ULL,
526
    /* PowerPC 440 specific instructions                                     */
527
    PPC_440_SPEC       = 0x0008000000000000ULL,
528
    /* BookE (embedded) PowerPC specification                                */
529
    PPC_BOOKE          = 0x0010000000000000ULL,
530
    /* mfapidi instruction                                                   */
531
    PPC_MFAPIDI        = 0x0020000000000000ULL,
532
    /* tlbiva instruction                                                    */
533
    PPC_TLBIVA         = 0x0040000000000000ULL,
534
    /* tlbivax instruction                                                   */
535
    PPC_TLBIVAX        = 0x0080000000000000ULL,
536
    /* PowerPC 4xx dedicated instructions                                    */
537
    PPC_4xx_COMMON     = 0x0100000000000000ULL,
538
    /* PowerPC 40x ibct instructions                                         */
539
    PPC_40x_ICBT       = 0x0200000000000000ULL,
540
    /* rfmci is not implemented in all BookE PowerPC                         */
541
    PPC_RFMCI          = 0x0400000000000000ULL,
542
    /* rfdi instruction                                                      */
543
    PPC_RFDI           = 0x0800000000000000ULL,
544
    /* DCR accesses                                                          */
545
    PPC_DCR            = 0x1000000000000000ULL,
546
    /* DCR extended accesse                                                  */
547
    PPC_DCRX           = 0x2000000000000000ULL,
548
    /* user-mode DCR access, implemented in PowerPC 460                      */
549
    PPC_DCRUX          = 0x4000000000000000ULL,
550
};
551

    
552
/*****************************************************************************/
553
/* PowerPC instructions table                                                */
554
#if HOST_LONG_BITS == 64
555
#define OPC_ALIGN 8
556
#else
557
#define OPC_ALIGN 4
558
#endif
559
#if defined(__APPLE__)
560
#define OPCODES_SECTION                                                       \
561
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
562
#else
563
#define OPCODES_SECTION                                                       \
564
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
565
#endif
566

    
567
#if defined(DO_PPC_STATISTICS)
568
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
569
OPCODES_SECTION opcode_t opc_##name = {                                       \
570
    .opc1 = op1,                                                              \
571
    .opc2 = op2,                                                              \
572
    .opc3 = op3,                                                              \
573
    .pad  = { 0, },                                                           \
574
    .handler = {                                                              \
575
        .inval   = invl,                                                      \
576
        .type = _typ,                                                         \
577
        .handler = &gen_##name,                                               \
578
        .oname = stringify(name),                                             \
579
    },                                                                        \
580
    .oname = stringify(name),                                                 \
581
}
582
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
583
OPCODES_SECTION opcode_t opc_##name = {                                       \
584
    .opc1 = op1,                                                              \
585
    .opc2 = op2,                                                              \
586
    .opc3 = op3,                                                              \
587
    .pad  = { 0, },                                                           \
588
    .handler = {                                                              \
589
        .inval   = invl,                                                      \
590
        .type = _typ,                                                         \
591
        .handler = &gen_##name,                                               \
592
        .oname = onam,                                                        \
593
    },                                                                        \
594
    .oname = onam,                                                            \
595
}
596
#else
597
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
598
OPCODES_SECTION opcode_t opc_##name = {                                       \
599
    .opc1 = op1,                                                              \
600
    .opc2 = op2,                                                              \
601
    .opc3 = op3,                                                              \
602
    .pad  = { 0, },                                                           \
603
    .handler = {                                                              \
604
        .inval   = invl,                                                      \
605
        .type = _typ,                                                         \
606
        .handler = &gen_##name,                                               \
607
    },                                                                        \
608
    .oname = stringify(name),                                                 \
609
}
610
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
611
OPCODES_SECTION opcode_t opc_##name = {                                       \
612
    .opc1 = op1,                                                              \
613
    .opc2 = op2,                                                              \
614
    .opc3 = op3,                                                              \
615
    .pad  = { 0, },                                                           \
616
    .handler = {                                                              \
617
        .inval   = invl,                                                      \
618
        .type = _typ,                                                         \
619
        .handler = &gen_##name,                                               \
620
    },                                                                        \
621
    .oname = onam,                                                            \
622
}
623
#endif
624

    
625
#define GEN_OPCODE_MARK(name)                                                 \
626
OPCODES_SECTION opcode_t opc_##name = {                                       \
627
    .opc1 = 0xFF,                                                             \
628
    .opc2 = 0xFF,                                                             \
629
    .opc3 = 0xFF,                                                             \
630
    .pad  = { 0, },                                                           \
631
    .handler = {                                                              \
632
        .inval   = 0x00000000,                                                \
633
        .type = 0x00,                                                         \
634
        .handler = NULL,                                                      \
635
    },                                                                        \
636
    .oname = stringify(name),                                                 \
637
}
638

    
639
/* Start opcode list */
640
GEN_OPCODE_MARK(start);
641

    
642
/* Invalid instruction */
643
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
644
{
645
    GEN_EXCP_INVAL(ctx);
646
}
647

    
648
static opc_handler_t invalid_handler = {
649
    .inval   = 0xFFFFFFFF,
650
    .type    = PPC_NONE,
651
    .handler = gen_invalid,
652
};
653

    
654
/***                           Integer arithmetic                          ***/
655
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
656
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
657
{                                                                             \
658
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
659
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
660
    gen_op_##name();                                                          \
661
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
662
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
663
        gen_set_Rc0(ctx);                                                     \
664
}
665

    
666
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
667
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
668
{                                                                             \
669
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
670
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
671
    gen_op_##name();                                                          \
672
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
673
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
674
        gen_set_Rc0(ctx);                                                     \
675
}
676

    
677
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
678
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
679
{                                                                             \
680
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
681
    gen_op_##name();                                                          \
682
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
683
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
684
        gen_set_Rc0(ctx);                                                     \
685
}
686
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
687
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
688
{                                                                             \
689
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
690
    gen_op_##name();                                                          \
691
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
692
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
693
        gen_set_Rc0(ctx);                                                     \
694
}
695

    
696
/* Two operands arithmetic functions */
697
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
698
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
699
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
700

    
701
/* Two operands arithmetic functions with no overflow allowed */
702
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
703
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
704

    
705
/* One operand arithmetic functions */
706
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
707
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
708
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
709

    
710
#if defined(TARGET_PPC64)
711
#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
712
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
713
{                                                                             \
714
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
715
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
716
    if (ctx->sf_mode)                                                         \
717
        gen_op_##name##_64();                                                 \
718
    else                                                                      \
719
        gen_op_##name();                                                      \
720
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
721
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
722
        gen_set_Rc0(ctx);                                                     \
723
}
724

    
725
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
726
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
727
{                                                                             \
728
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
729
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
730
    if (ctx->sf_mode)                                                         \
731
        gen_op_##name##_64();                                                 \
732
    else                                                                      \
733
        gen_op_##name();                                                      \
734
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
735
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
736
        gen_set_Rc0(ctx);                                                     \
737
}
738

    
739
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
740
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
741
{                                                                             \
742
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
743
    if (ctx->sf_mode)                                                         \
744
        gen_op_##name##_64();                                                 \
745
    else                                                                      \
746
        gen_op_##name();                                                      \
747
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
748
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
749
        gen_set_Rc0(ctx);                                                     \
750
}
751
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
752
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
753
{                                                                             \
754
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
755
    if (ctx->sf_mode)                                                         \
756
        gen_op_##name##_64();                                                 \
757
    else                                                                      \
758
        gen_op_##name();                                                      \
759
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
760
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
761
        gen_set_Rc0(ctx);                                                     \
762
}
763

    
764
/* Two operands arithmetic functions */
765
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
766
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
767
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
768

    
769
/* Two operands arithmetic functions with no overflow allowed */
770
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
771
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
772

    
773
/* One operand arithmetic functions */
774
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
775
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
776
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
777
#else
778
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
779
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
780
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
781
#endif
782

    
783
/* add    add.    addo    addo.    */
784
static always_inline void gen_op_addo (void)
785
{
786
    gen_op_move_T2_T0();
787
    gen_op_add();
788
    gen_op_check_addo();
789
}
790
#if defined(TARGET_PPC64)
791
#define gen_op_add_64 gen_op_add
792
static always_inline void gen_op_addo_64 (void)
793
{
794
    gen_op_move_T2_T0();
795
    gen_op_add();
796
    gen_op_check_addo_64();
797
}
798
#endif
799
GEN_INT_ARITH2_64 (add,    0x1F, 0x0A, 0x08, PPC_INTEGER);
800
/* addc   addc.   addco   addco.   */
801
static always_inline void gen_op_addc (void)
802
{
803
    gen_op_move_T2_T0();
804
    gen_op_add();
805
    gen_op_check_addc();
806
}
807
static always_inline void gen_op_addco (void)
808
{
809
    gen_op_move_T2_T0();
810
    gen_op_add();
811
    gen_op_check_addc();
812
    gen_op_check_addo();
813
}
814
#if defined(TARGET_PPC64)
815
static always_inline void gen_op_addc_64 (void)
816
{
817
    gen_op_move_T2_T0();
818
    gen_op_add();
819
    gen_op_check_addc_64();
820
}
821
static always_inline void gen_op_addco_64 (void)
822
{
823
    gen_op_move_T2_T0();
824
    gen_op_add();
825
    gen_op_check_addc_64();
826
    gen_op_check_addo_64();
827
}
828
#endif
829
GEN_INT_ARITH2_64 (addc,   0x1F, 0x0A, 0x00, PPC_INTEGER);
830
/* adde   adde.   addeo   addeo.   */
831
static always_inline void gen_op_addeo (void)
832
{
833
    gen_op_move_T2_T0();
834
    gen_op_adde();
835
    gen_op_check_addo();
836
}
837
#if defined(TARGET_PPC64)
838
static always_inline void gen_op_addeo_64 (void)
839
{
840
    gen_op_move_T2_T0();
841
    gen_op_adde_64();
842
    gen_op_check_addo_64();
843
}
844
#endif
845
GEN_INT_ARITH2_64 (adde,   0x1F, 0x0A, 0x04, PPC_INTEGER);
846
/* addme  addme.  addmeo  addmeo.  */
847
static always_inline void gen_op_addme (void)
848
{
849
    gen_op_move_T1_T0();
850
    gen_op_add_me();
851
}
852
#if defined(TARGET_PPC64)
853
static always_inline void gen_op_addme_64 (void)
854
{
855
    gen_op_move_T1_T0();
856
    gen_op_add_me_64();
857
}
858
#endif
859
GEN_INT_ARITH1_64 (addme,  0x1F, 0x0A, 0x07, PPC_INTEGER);
860
/* addze  addze.  addzeo  addzeo.  */
861
static always_inline void gen_op_addze (void)
862
{
863
    gen_op_move_T2_T0();
864
    gen_op_add_ze();
865
    gen_op_check_addc();
866
}
867
static always_inline void gen_op_addzeo (void)
868
{
869
    gen_op_move_T2_T0();
870
    gen_op_add_ze();
871
    gen_op_check_addc();
872
    gen_op_check_addo();
873
}
874
#if defined(TARGET_PPC64)
875
static always_inline void gen_op_addze_64 (void)
876
{
877
    gen_op_move_T2_T0();
878
    gen_op_add_ze();
879
    gen_op_check_addc_64();
880
}
881
static always_inline void gen_op_addzeo_64 (void)
882
{
883
    gen_op_move_T2_T0();
884
    gen_op_add_ze();
885
    gen_op_check_addc_64();
886
    gen_op_check_addo_64();
887
}
888
#endif
889
GEN_INT_ARITH1_64 (addze,  0x1F, 0x0A, 0x06, PPC_INTEGER);
890
/* divw   divw.   divwo   divwo.   */
891
GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F, PPC_INTEGER);
892
/* divwu  divwu.  divwuo  divwuo.  */
893
GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E, PPC_INTEGER);
894
/* mulhw  mulhw.                   */
895
GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02, PPC_INTEGER);
896
/* mulhwu mulhwu.                  */
897
GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);
898
/* mullw  mullw.  mullwo  mullwo.  */
899
GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07, PPC_INTEGER);
900
/* neg    neg.    nego    nego.    */
901
GEN_INT_ARITH1_64 (neg,    0x1F, 0x08, 0x03, PPC_INTEGER);
902
/* subf   subf.   subfo   subfo.   */
903
static always_inline void gen_op_subfo (void)
904
{
905
    gen_op_moven_T2_T0();
906
    gen_op_subf();
907
    gen_op_check_addo();
908
}
909
#if defined(TARGET_PPC64)
910
#define gen_op_subf_64 gen_op_subf
911
static always_inline void gen_op_subfo_64 (void)
912
{
913
    gen_op_moven_T2_T0();
914
    gen_op_subf();
915
    gen_op_check_addo_64();
916
}
917
#endif
918
GEN_INT_ARITH2_64 (subf,   0x1F, 0x08, 0x01, PPC_INTEGER);
919
/* subfc  subfc.  subfco  subfco.  */
920
static always_inline void gen_op_subfc (void)
921
{
922
    gen_op_subf();
923
    gen_op_check_subfc();
924
}
925
static always_inline void gen_op_subfco (void)
926
{
927
    gen_op_moven_T2_T0();
928
    gen_op_subf();
929
    gen_op_check_subfc();
930
    gen_op_check_addo();
931
}
932
#if defined(TARGET_PPC64)
933
static always_inline void gen_op_subfc_64 (void)
934
{
935
    gen_op_subf();
936
    gen_op_check_subfc_64();
937
}
938
static always_inline void gen_op_subfco_64 (void)
939
{
940
    gen_op_moven_T2_T0();
941
    gen_op_subf();
942
    gen_op_check_subfc_64();
943
    gen_op_check_addo_64();
944
}
945
#endif
946
GEN_INT_ARITH2_64 (subfc,  0x1F, 0x08, 0x00, PPC_INTEGER);
947
/* subfe  subfe.  subfeo  subfeo.  */
948
static always_inline void gen_op_subfeo (void)
949
{
950
    gen_op_moven_T2_T0();
951
    gen_op_subfe();
952
    gen_op_check_addo();
953
}
954
#if defined(TARGET_PPC64)
955
#define gen_op_subfe_64 gen_op_subfe
956
static always_inline void gen_op_subfeo_64 (void)
957
{
958
    gen_op_moven_T2_T0();
959
    gen_op_subfe_64();
960
    gen_op_check_addo_64();
961
}
962
#endif
963
GEN_INT_ARITH2_64 (subfe,  0x1F, 0x08, 0x04, PPC_INTEGER);
964
/* subfme subfme. subfmeo subfmeo. */
965
GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);
966
/* subfze subfze. subfzeo subfzeo. */
967
GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);
968
/* addi */
969
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
970
{
971
    target_long simm = SIMM(ctx->opcode);
972

    
973
    if (rA(ctx->opcode) == 0) {
974
        /* li case */
975
        gen_set_T0(simm);
976
    } else {
977
        gen_op_load_gpr_T0(rA(ctx->opcode));
978
        if (likely(simm != 0))
979
            gen_op_addi(simm);
980
    }
981
    gen_op_store_T0_gpr(rD(ctx->opcode));
982
}
983
/* addic */
984
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
985
{
986
    target_long simm = SIMM(ctx->opcode);
987

    
988
    gen_op_load_gpr_T0(rA(ctx->opcode));
989
    if (likely(simm != 0)) {
990
        gen_op_move_T2_T0();
991
        gen_op_addi(simm);
992
#if defined(TARGET_PPC64)
993
        if (ctx->sf_mode)
994
            gen_op_check_addc_64();
995
        else
996
#endif
997
            gen_op_check_addc();
998
    } else {
999
        gen_op_clear_xer_ca();
1000
    }
1001
    gen_op_store_T0_gpr(rD(ctx->opcode));
1002
}
1003
/* addic. */
1004
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1005
{
1006
    target_long simm = SIMM(ctx->opcode);
1007

    
1008
    gen_op_load_gpr_T0(rA(ctx->opcode));
1009
    if (likely(simm != 0)) {
1010
        gen_op_move_T2_T0();
1011
        gen_op_addi(simm);
1012
#if defined(TARGET_PPC64)
1013
        if (ctx->sf_mode)
1014
            gen_op_check_addc_64();
1015
        else
1016
#endif
1017
            gen_op_check_addc();
1018
    } else {
1019
        gen_op_clear_xer_ca();
1020
    }
1021
    gen_op_store_T0_gpr(rD(ctx->opcode));
1022
    gen_set_Rc0(ctx);
1023
}
1024
/* addis */
1025
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1026
{
1027
    target_long simm = SIMM(ctx->opcode);
1028

    
1029
    if (rA(ctx->opcode) == 0) {
1030
        /* lis case */
1031
        gen_set_T0(simm << 16);
1032
    } else {
1033
        gen_op_load_gpr_T0(rA(ctx->opcode));
1034
        if (likely(simm != 0))
1035
            gen_op_addi(simm << 16);
1036
    }
1037
    gen_op_store_T0_gpr(rD(ctx->opcode));
1038
}
1039
/* mulli */
1040
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1041
{
1042
    gen_op_load_gpr_T0(rA(ctx->opcode));
1043
    gen_op_mulli(SIMM(ctx->opcode));
1044
    gen_op_store_T0_gpr(rD(ctx->opcode));
1045
}
1046
/* subfic */
1047
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1048
{
1049
    gen_op_load_gpr_T0(rA(ctx->opcode));
1050
#if defined(TARGET_PPC64)
1051
    if (ctx->sf_mode)
1052
        gen_op_subfic_64(SIMM(ctx->opcode));
1053
    else
1054
#endif
1055
        gen_op_subfic(SIMM(ctx->opcode));
1056
    gen_op_store_T0_gpr(rD(ctx->opcode));
1057
}
1058

    
1059
#if defined(TARGET_PPC64)
1060
/* mulhd  mulhd.                   */
1061
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
1062
/* mulhdu mulhdu.                  */
1063
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
1064
/* mulld  mulld.  mulldo  mulldo.  */
1065
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
1066
/* divd   divd.   divdo   divdo.   */
1067
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
1068
/* divdu  divdu.  divduo  divduo.  */
1069
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
1070
#endif
1071

    
1072
/***                           Integer comparison                          ***/
1073
#if defined(TARGET_PPC64)
1074
#define GEN_CMP(name, opc, type)                                              \
1075
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1076
{                                                                             \
1077
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1078
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1079
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))                           \
1080
        gen_op_##name##_64();                                                 \
1081
    else                                                                      \
1082
        gen_op_##name();                                                      \
1083
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
1084
}
1085
#else
1086
#define GEN_CMP(name, opc, type)                                              \
1087
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1088
{                                                                             \
1089
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1090
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1091
    gen_op_##name();                                                          \
1092
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
1093
}
1094
#endif
1095

    
1096
/* cmp */
1097
GEN_CMP(cmp, 0x00, PPC_INTEGER);
1098
/* cmpi */
1099
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1100
{
1101
    gen_op_load_gpr_T0(rA(ctx->opcode));
1102
#if defined(TARGET_PPC64)
1103
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1104
        gen_op_cmpi_64(SIMM(ctx->opcode));
1105
    else
1106
#endif
1107
        gen_op_cmpi(SIMM(ctx->opcode));
1108
    gen_op_store_T0_crf(crfD(ctx->opcode));
1109
}
1110
/* cmpl */
1111
GEN_CMP(cmpl, 0x01, PPC_INTEGER);
1112
/* cmpli */
1113
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1114
{
1115
    gen_op_load_gpr_T0(rA(ctx->opcode));
1116
#if defined(TARGET_PPC64)
1117
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1118
        gen_op_cmpli_64(UIMM(ctx->opcode));
1119
    else
1120
#endif
1121
        gen_op_cmpli(UIMM(ctx->opcode));
1122
    gen_op_store_T0_crf(crfD(ctx->opcode));
1123
}
1124

    
1125
/* isel (PowerPC 2.03 specification) */
1126
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
1127
{
1128
    uint32_t bi = rC(ctx->opcode);
1129
    uint32_t mask;
1130

    
1131
    if (rA(ctx->opcode) == 0) {
1132
        gen_set_T0(0);
1133
    } else {
1134
        gen_op_load_gpr_T1(rA(ctx->opcode));
1135
    }
1136
    gen_op_load_gpr_T2(rB(ctx->opcode));
1137
    mask = 1 << (3 - (bi & 0x03));
1138
    gen_op_load_crf_T0(bi >> 2);
1139
    gen_op_test_true(mask);
1140
    gen_op_isel();
1141
    gen_op_store_T0_gpr(rD(ctx->opcode));
1142
}
1143

    
1144
/***                            Integer logical                            ***/
1145
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1146
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1147
{                                                                             \
1148
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1149
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1150
    gen_op_##name();                                                          \
1151
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1152
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1153
        gen_set_Rc0(ctx);                                                     \
1154
}
1155
#define GEN_LOGICAL2(name, opc, type)                                         \
1156
__GEN_LOGICAL2(name, 0x1C, opc, type)
1157

    
1158
#define GEN_LOGICAL1(name, opc, type)                                         \
1159
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1160
{                                                                             \
1161
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1162
    gen_op_##name();                                                          \
1163
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1164
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1165
        gen_set_Rc0(ctx);                                                     \
1166
}
1167

    
1168
/* and & and. */
1169
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1170
/* andc & andc. */
1171
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1172
/* andi. */
1173
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1174
{
1175
    gen_op_load_gpr_T0(rS(ctx->opcode));
1176
    gen_op_andi_T0(UIMM(ctx->opcode));
1177
    gen_op_store_T0_gpr(rA(ctx->opcode));
1178
    gen_set_Rc0(ctx);
1179
}
1180
/* andis. */
1181
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1182
{
1183
    gen_op_load_gpr_T0(rS(ctx->opcode));
1184
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
1185
    gen_op_store_T0_gpr(rA(ctx->opcode));
1186
    gen_set_Rc0(ctx);
1187
}
1188

    
1189
/* cntlzw */
1190
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1191
/* eqv & eqv. */
1192
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1193
/* extsb & extsb. */
1194
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1195
/* extsh & extsh. */
1196
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1197
/* nand & nand. */
1198
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1199
/* nor & nor. */
1200
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1201

    
1202
/* or & or. */
1203
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1204
{
1205
    int rs, ra, rb;
1206

    
1207
    rs = rS(ctx->opcode);
1208
    ra = rA(ctx->opcode);
1209
    rb = rB(ctx->opcode);
1210
    /* Optimisation for mr. ri case */
1211
    if (rs != ra || rs != rb) {
1212
        gen_op_load_gpr_T0(rs);
1213
        if (rs != rb) {
1214
            gen_op_load_gpr_T1(rb);
1215
            gen_op_or();
1216
        }
1217
        gen_op_store_T0_gpr(ra);
1218
        if (unlikely(Rc(ctx->opcode) != 0))
1219
            gen_set_Rc0(ctx);
1220
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1221
        gen_op_load_gpr_T0(rs);
1222
        gen_set_Rc0(ctx);
1223
#if defined(TARGET_PPC64)
1224
    } else {
1225
        switch (rs) {
1226
        case 1:
1227
            /* Set process priority to low */
1228
            gen_op_store_pri(2);
1229
            break;
1230
        case 6:
1231
            /* Set process priority to medium-low */
1232
            gen_op_store_pri(3);
1233
            break;
1234
        case 2:
1235
            /* Set process priority to normal */
1236
            gen_op_store_pri(4);
1237
            break;
1238
#if !defined(CONFIG_USER_ONLY)
1239
        case 31:
1240
            if (ctx->supervisor > 0) {
1241
                /* Set process priority to very low */
1242
                gen_op_store_pri(1);
1243
            }
1244
            break;
1245
        case 5:
1246
            if (ctx->supervisor > 0) {
1247
                /* Set process priority to medium-hight */
1248
                gen_op_store_pri(5);
1249
            }
1250
            break;
1251
        case 3:
1252
            if (ctx->supervisor > 0) {
1253
                /* Set process priority to high */
1254
                gen_op_store_pri(6);
1255
            }
1256
            break;
1257
        case 7:
1258
            if (ctx->supervisor > 1) {
1259
                /* Set process priority to very high */
1260
                gen_op_store_pri(7);
1261
            }
1262
            break;
1263
#endif
1264
        default:
1265
            /* nop */
1266
            break;
1267
        }
1268
#endif
1269
    }
1270
}
1271

    
1272
/* orc & orc. */
1273
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1274
/* xor & xor. */
1275
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1276
{
1277
    gen_op_load_gpr_T0(rS(ctx->opcode));
1278
    /* Optimisation for "set to zero" case */
1279
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1280
        gen_op_load_gpr_T1(rB(ctx->opcode));
1281
        gen_op_xor();
1282
    } else {
1283
        gen_op_reset_T0();
1284
    }
1285
    gen_op_store_T0_gpr(rA(ctx->opcode));
1286
    if (unlikely(Rc(ctx->opcode) != 0))
1287
        gen_set_Rc0(ctx);
1288
}
1289
/* ori */
1290
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1291
{
1292
    target_ulong uimm = UIMM(ctx->opcode);
1293

    
1294
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1295
        /* NOP */
1296
        /* XXX: should handle special NOPs for POWER series */
1297
        return;
1298
    }
1299
    gen_op_load_gpr_T0(rS(ctx->opcode));
1300
    if (likely(uimm != 0))
1301
        gen_op_ori(uimm);
1302
    gen_op_store_T0_gpr(rA(ctx->opcode));
1303
}
1304
/* oris */
1305
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1306
{
1307
    target_ulong uimm = UIMM(ctx->opcode);
1308

    
1309
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1310
        /* NOP */
1311
        return;
1312
    }
1313
    gen_op_load_gpr_T0(rS(ctx->opcode));
1314
    if (likely(uimm != 0))
1315
        gen_op_ori(uimm << 16);
1316
    gen_op_store_T0_gpr(rA(ctx->opcode));
1317
}
1318
/* xori */
1319
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1320
{
1321
    target_ulong uimm = UIMM(ctx->opcode);
1322

    
1323
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1324
        /* NOP */
1325
        return;
1326
    }
1327
    gen_op_load_gpr_T0(rS(ctx->opcode));
1328
    if (likely(uimm != 0))
1329
        gen_op_xori(uimm);
1330
    gen_op_store_T0_gpr(rA(ctx->opcode));
1331
}
1332

    
1333
/* xoris */
1334
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1335
{
1336
    target_ulong uimm = UIMM(ctx->opcode);
1337

    
1338
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1339
        /* NOP */
1340
        return;
1341
    }
1342
    gen_op_load_gpr_T0(rS(ctx->opcode));
1343
    if (likely(uimm != 0))
1344
        gen_op_xori(uimm << 16);
1345
    gen_op_store_T0_gpr(rA(ctx->opcode));
1346
}
1347

    
1348
/* popcntb : PowerPC 2.03 specification */
1349
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
1350
{
1351
    gen_op_load_gpr_T0(rS(ctx->opcode));
1352
#if defined(TARGET_PPC64)
1353
    if (ctx->sf_mode)
1354
        gen_op_popcntb_64();
1355
    else
1356
#endif
1357
        gen_op_popcntb();
1358
    gen_op_store_T0_gpr(rA(ctx->opcode));
1359
}
1360

    
1361
#if defined(TARGET_PPC64)
1362
/* extsw & extsw. */
1363
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1364
/* cntlzd */
1365
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1366
#endif
1367

    
1368
/***                             Integer rotate                            ***/
1369
/* rlwimi & rlwimi. */
1370
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1371
{
1372
    target_ulong mask;
1373
    uint32_t mb, me, sh;
1374

    
1375
    mb = MB(ctx->opcode);
1376
    me = ME(ctx->opcode);
1377
    sh = SH(ctx->opcode);
1378
    if (likely(sh == 0)) {
1379
        if (likely(mb == 0 && me == 31)) {
1380
            gen_op_load_gpr_T0(rS(ctx->opcode));
1381
            goto do_store;
1382
        } else if (likely(mb == 31 && me == 0)) {
1383
            gen_op_load_gpr_T0(rA(ctx->opcode));
1384
            goto do_store;
1385
        }
1386
        gen_op_load_gpr_T0(rS(ctx->opcode));
1387
        gen_op_load_gpr_T1(rA(ctx->opcode));
1388
        goto do_mask;
1389
    }
1390
    gen_op_load_gpr_T0(rS(ctx->opcode));
1391
    gen_op_load_gpr_T1(rA(ctx->opcode));
1392
    gen_op_rotli32_T0(SH(ctx->opcode));
1393
 do_mask:
1394
#if defined(TARGET_PPC64)
1395
    mb += 32;
1396
    me += 32;
1397
#endif
1398
    mask = MASK(mb, me);
1399
    gen_op_andi_T0(mask);
1400
    gen_op_andi_T1(~mask);
1401
    gen_op_or();
1402
 do_store:
1403
    gen_op_store_T0_gpr(rA(ctx->opcode));
1404
    if (unlikely(Rc(ctx->opcode) != 0))
1405
        gen_set_Rc0(ctx);
1406
}
1407
/* rlwinm & rlwinm. */
1408
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1409
{
1410
    uint32_t mb, me, sh;
1411

    
1412
    sh = SH(ctx->opcode);
1413
    mb = MB(ctx->opcode);
1414
    me = ME(ctx->opcode);
1415
    gen_op_load_gpr_T0(rS(ctx->opcode));
1416
    if (likely(sh == 0)) {
1417
        goto do_mask;
1418
    }
1419
    if (likely(mb == 0)) {
1420
        if (likely(me == 31)) {
1421
            gen_op_rotli32_T0(sh);
1422
            goto do_store;
1423
        } else if (likely(me == (31 - sh))) {
1424
            gen_op_sli_T0(sh);
1425
            goto do_store;
1426
        }
1427
    } else if (likely(me == 31)) {
1428
        if (likely(sh == (32 - mb))) {
1429
            gen_op_srli_T0(mb);
1430
            goto do_store;
1431
        }
1432
    }
1433
    gen_op_rotli32_T0(sh);
1434
 do_mask:
1435
#if defined(TARGET_PPC64)
1436
    mb += 32;
1437
    me += 32;
1438
#endif
1439
    gen_op_andi_T0(MASK(mb, me));
1440
 do_store:
1441
    gen_op_store_T0_gpr(rA(ctx->opcode));
1442
    if (unlikely(Rc(ctx->opcode) != 0))
1443
        gen_set_Rc0(ctx);
1444
}
1445
/* rlwnm & rlwnm. */
1446
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1447
{
1448
    uint32_t mb, me;
1449

    
1450
    mb = MB(ctx->opcode);
1451
    me = ME(ctx->opcode);
1452
    gen_op_load_gpr_T0(rS(ctx->opcode));
1453
    gen_op_load_gpr_T1(rB(ctx->opcode));
1454
    gen_op_rotl32_T0_T1();
1455
    if (unlikely(mb != 0 || me != 31)) {
1456
#if defined(TARGET_PPC64)
1457
        mb += 32;
1458
        me += 32;
1459
#endif
1460
        gen_op_andi_T0(MASK(mb, me));
1461
    }
1462
    gen_op_store_T0_gpr(rA(ctx->opcode));
1463
    if (unlikely(Rc(ctx->opcode) != 0))
1464
        gen_set_Rc0(ctx);
1465
}
1466

    
1467
#if defined(TARGET_PPC64)
1468
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1469
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1470
{                                                                             \
1471
    gen_##name(ctx, 0);                                                       \
1472
}                                                                             \
1473
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1474
             PPC_64B)                                                         \
1475
{                                                                             \
1476
    gen_##name(ctx, 1);                                                       \
1477
}
1478
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1479
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1480
{                                                                             \
1481
    gen_##name(ctx, 0, 0);                                                    \
1482
}                                                                             \
1483
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
1484
             PPC_64B)                                                         \
1485
{                                                                             \
1486
    gen_##name(ctx, 0, 1);                                                    \
1487
}                                                                             \
1488
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1489
             PPC_64B)                                                         \
1490
{                                                                             \
1491
    gen_##name(ctx, 1, 0);                                                    \
1492
}                                                                             \
1493
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
1494
             PPC_64B)                                                         \
1495
{                                                                             \
1496
    gen_##name(ctx, 1, 1);                                                    \
1497
}
1498

    
1499
static always_inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1500
{
1501
    if (mask >> 32)
1502
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1503
    else
1504
        gen_op_andi_T0(mask);
1505
}
1506

    
1507
static always_inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1508
{
1509
    if (mask >> 32)
1510
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1511
    else
1512
        gen_op_andi_T1(mask);
1513
}
1514

    
1515
static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
1516
                                      uint32_t me, uint32_t sh)
1517
{
1518
    gen_op_load_gpr_T0(rS(ctx->opcode));
1519
    if (likely(sh == 0)) {
1520
        goto do_mask;
1521
    }
1522
    if (likely(mb == 0)) {
1523
        if (likely(me == 63)) {
1524
            gen_op_rotli64_T0(sh);
1525
            goto do_store;
1526
        } else if (likely(me == (63 - sh))) {
1527
            gen_op_sli_T0(sh);
1528
            goto do_store;
1529
        }
1530
    } else if (likely(me == 63)) {
1531
        if (likely(sh == (64 - mb))) {
1532
            gen_op_srli_T0_64(mb);
1533
            goto do_store;
1534
        }
1535
    }
1536
    gen_op_rotli64_T0(sh);
1537
 do_mask:
1538
    gen_andi_T0_64(ctx, MASK(mb, me));
1539
 do_store:
1540
    gen_op_store_T0_gpr(rA(ctx->opcode));
1541
    if (unlikely(Rc(ctx->opcode) != 0))
1542
        gen_set_Rc0(ctx);
1543
}
1544
/* rldicl - rldicl. */
1545
static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1546
{
1547
    uint32_t sh, mb;
1548

    
1549
    sh = SH(ctx->opcode) | (shn << 5);
1550
    mb = MB(ctx->opcode) | (mbn << 5);
1551
    gen_rldinm(ctx, mb, 63, sh);
1552
}
1553
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1554
/* rldicr - rldicr. */
1555
static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1556
{
1557
    uint32_t sh, me;
1558

    
1559
    sh = SH(ctx->opcode) | (shn << 5);
1560
    me = MB(ctx->opcode) | (men << 5);
1561
    gen_rldinm(ctx, 0, me, sh);
1562
}
1563
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1564
/* rldic - rldic. */
1565
static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1566
{
1567
    uint32_t sh, mb;
1568

    
1569
    sh = SH(ctx->opcode) | (shn << 5);
1570
    mb = MB(ctx->opcode) | (mbn << 5);
1571
    gen_rldinm(ctx, mb, 63 - sh, sh);
1572
}
1573
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1574

    
1575
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1576
                                     uint32_t me)
1577
{
1578
    gen_op_load_gpr_T0(rS(ctx->opcode));
1579
    gen_op_load_gpr_T1(rB(ctx->opcode));
1580
    gen_op_rotl64_T0_T1();
1581
    if (unlikely(mb != 0 || me != 63)) {
1582
        gen_andi_T0_64(ctx, MASK(mb, me));
1583
    }
1584
    gen_op_store_T0_gpr(rA(ctx->opcode));
1585
    if (unlikely(Rc(ctx->opcode) != 0))
1586
        gen_set_Rc0(ctx);
1587
}
1588

    
1589
/* rldcl - rldcl. */
1590
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1591
{
1592
    uint32_t mb;
1593

    
1594
    mb = MB(ctx->opcode) | (mbn << 5);
1595
    gen_rldnm(ctx, mb, 63);
1596
}
1597
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1598
/* rldcr - rldcr. */
1599
static always_inline void gen_rldcr (DisasContext *ctx, int men)
1600
{
1601
    uint32_t me;
1602

    
1603
    me = MB(ctx->opcode) | (men << 5);
1604
    gen_rldnm(ctx, 0, me);
1605
}
1606
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1607
/* rldimi - rldimi. */
1608
static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1609
{
1610
    uint64_t mask;
1611
    uint32_t sh, mb, me;
1612

    
1613
    sh = SH(ctx->opcode) | (shn << 5);
1614
    mb = MB(ctx->opcode) | (mbn << 5);
1615
    me = 63 - sh;
1616
    if (likely(sh == 0)) {
1617
        if (likely(mb == 0)) {
1618
            gen_op_load_gpr_T0(rS(ctx->opcode));
1619
            goto do_store;
1620
        }
1621
        gen_op_load_gpr_T0(rS(ctx->opcode));
1622
        gen_op_load_gpr_T1(rA(ctx->opcode));
1623
        goto do_mask;
1624
    }
1625
    gen_op_load_gpr_T0(rS(ctx->opcode));
1626
    gen_op_load_gpr_T1(rA(ctx->opcode));
1627
    gen_op_rotli64_T0(sh);
1628
 do_mask:
1629
    mask = MASK(mb, me);
1630
    gen_andi_T0_64(ctx, mask);
1631
    gen_andi_T1_64(ctx, ~mask);
1632
    gen_op_or();
1633
 do_store:
1634
    gen_op_store_T0_gpr(rA(ctx->opcode));
1635
    if (unlikely(Rc(ctx->opcode) != 0))
1636
        gen_set_Rc0(ctx);
1637
}
1638
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1639
#endif
1640

    
1641
/***                             Integer shift                             ***/
1642
/* slw & slw. */
1643
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1644
/* sraw & sraw. */
1645
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1646
/* srawi & srawi. */
1647
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1648
{
1649
    int mb, me;
1650
    gen_op_load_gpr_T0(rS(ctx->opcode));
1651
    if (SH(ctx->opcode) != 0) {
1652
        gen_op_move_T1_T0();
1653
        mb = 32 - SH(ctx->opcode);
1654
        me = 31;
1655
#if defined(TARGET_PPC64)
1656
        mb += 32;
1657
        me += 32;
1658
#endif
1659
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1660
    }
1661
    gen_op_store_T0_gpr(rA(ctx->opcode));
1662
    if (unlikely(Rc(ctx->opcode) != 0))
1663
        gen_set_Rc0(ctx);
1664
}
1665
/* srw & srw. */
1666
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1667

    
1668
#if defined(TARGET_PPC64)
1669
/* sld & sld. */
1670
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1671
/* srad & srad. */
1672
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1673
/* sradi & sradi. */
1674
static always_inline void gen_sradi (DisasContext *ctx, int n)
1675
{
1676
    uint64_t mask;
1677
    int sh, mb, me;
1678

    
1679
    gen_op_load_gpr_T0(rS(ctx->opcode));
1680
    sh = SH(ctx->opcode) + (n << 5);
1681
    if (sh != 0) {
1682
        gen_op_move_T1_T0();
1683
        mb = 64 - SH(ctx->opcode);
1684
        me = 63;
1685
        mask = MASK(mb, me);
1686
        gen_op_sradi(sh, mask >> 32, mask);
1687
    }
1688
    gen_op_store_T0_gpr(rA(ctx->opcode));
1689
    if (unlikely(Rc(ctx->opcode) != 0))
1690
        gen_set_Rc0(ctx);
1691
}
1692
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1693
{
1694
    gen_sradi(ctx, 0);
1695
}
1696
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1697
{
1698
    gen_sradi(ctx, 1);
1699
}
1700
/* srd & srd. */
1701
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1702
#endif
1703

    
1704
/***                       Floating-Point arithmetic                       ***/
1705
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1706
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1707
{                                                                             \
1708
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1709
        GEN_EXCP_NO_FP(ctx);                                                  \
1710
        return;                                                               \
1711
    }                                                                         \
1712
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1713
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1714
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1715
    gen_reset_fpstatus();                                                     \
1716
    gen_op_f##op();                                                           \
1717
    if (isfloat) {                                                            \
1718
        gen_op_frsp();                                                        \
1719
    }                                                                         \
1720
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1721
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1722
}
1723

    
1724
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1725
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1726
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1727

    
1728
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1729
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1730
{                                                                             \
1731
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1732
        GEN_EXCP_NO_FP(ctx);                                                  \
1733
        return;                                                               \
1734
    }                                                                         \
1735
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1736
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1737
    gen_reset_fpstatus();                                                     \
1738
    gen_op_f##op();                                                           \
1739
    if (isfloat) {                                                            \
1740
        gen_op_frsp();                                                        \
1741
    }                                                                         \
1742
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1743
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1744
}
1745
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
1746
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1747
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1748

    
1749
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1750
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1751
{                                                                             \
1752
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1753
        GEN_EXCP_NO_FP(ctx);                                                  \
1754
        return;                                                               \
1755
    }                                                                         \
1756
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1757
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1758
    gen_reset_fpstatus();                                                     \
1759
    gen_op_f##op();                                                           \
1760
    if (isfloat) {                                                            \
1761
        gen_op_frsp();                                                        \
1762
    }                                                                         \
1763
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1764
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1765
}
1766
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
1767
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1768
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1769

    
1770
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
1771
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1772
{                                                                             \
1773
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1774
        GEN_EXCP_NO_FP(ctx);                                                  \
1775
        return;                                                               \
1776
    }                                                                         \
1777
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1778
    gen_reset_fpstatus();                                                     \
1779
    gen_op_f##name();                                                         \
1780
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1781
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1782
}
1783

    
1784
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1785
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1786
{                                                                             \
1787
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1788
        GEN_EXCP_NO_FP(ctx);                                                  \
1789
        return;                                                               \
1790
    }                                                                         \
1791
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1792
    gen_reset_fpstatus();                                                     \
1793
    gen_op_f##name();                                                         \
1794
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1795
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1796
}
1797

    
1798
/* fadd - fadds */
1799
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1800
/* fdiv - fdivs */
1801
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1802
/* fmul - fmuls */
1803
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
1804

    
1805
/* fre */
1806
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1807

    
1808
/* fres */
1809
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1810

    
1811
/* frsqrte */
1812
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
1813

    
1814
/* frsqrtes */
1815
static always_inline void gen_op_frsqrtes (void)
1816
{
1817
    gen_op_frsqrte();
1818
    gen_op_frsp();
1819
}
1820
GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1821

    
1822
/* fsel */
1823
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1824
/* fsub - fsubs */
1825
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1826
/* Optional: */
1827
/* fsqrt */
1828
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1829
{
1830
    if (unlikely(!ctx->fpu_enabled)) {
1831
        GEN_EXCP_NO_FP(ctx);
1832
        return;
1833
    }
1834
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1835
    gen_reset_fpstatus();
1836
    gen_op_fsqrt();
1837
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1838
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1839
}
1840

    
1841
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1842
{
1843
    if (unlikely(!ctx->fpu_enabled)) {
1844
        GEN_EXCP_NO_FP(ctx);
1845
        return;
1846
    }
1847
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1848
    gen_reset_fpstatus();
1849
    gen_op_fsqrt();
1850
    gen_op_frsp();
1851
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1852
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1853
}
1854

    
1855
/***                     Floating-Point multiply-and-add                   ***/
1856
/* fmadd - fmadds */
1857
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1858
/* fmsub - fmsubs */
1859
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1860
/* fnmadd - fnmadds */
1861
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1862
/* fnmsub - fnmsubs */
1863
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1864

    
1865
/***                     Floating-Point round & convert                    ***/
1866
/* fctiw */
1867
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1868
/* fctiwz */
1869
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1870
/* frsp */
1871
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
1872
#if defined(TARGET_PPC64)
1873
/* fcfid */
1874
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
1875
/* fctid */
1876
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
1877
/* fctidz */
1878
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
1879
#endif
1880

    
1881
/* frin */
1882
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
1883
/* friz */
1884
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
1885
/* frip */
1886
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
1887
/* frim */
1888
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1889

    
1890
/***                         Floating-Point compare                        ***/
1891
/* fcmpo */
1892
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1893
{
1894
    if (unlikely(!ctx->fpu_enabled)) {
1895
        GEN_EXCP_NO_FP(ctx);
1896
        return;
1897
    }
1898
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1899
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1900
    gen_reset_fpstatus();
1901
    gen_op_fcmpo();
1902
    gen_op_store_T0_crf(crfD(ctx->opcode));
1903
    gen_op_float_check_status();
1904
}
1905

    
1906
/* fcmpu */
1907
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1908
{
1909
    if (unlikely(!ctx->fpu_enabled)) {
1910
        GEN_EXCP_NO_FP(ctx);
1911
        return;
1912
    }
1913
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1914
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1915
    gen_reset_fpstatus();
1916
    gen_op_fcmpu();
1917
    gen_op_store_T0_crf(crfD(ctx->opcode));
1918
    gen_op_float_check_status();
1919
}
1920

    
1921
/***                         Floating-point move                           ***/
1922
/* fabs */
1923
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
1924
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1925

    
1926
/* fmr  - fmr. */
1927
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1928
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1929
{
1930
    if (unlikely(!ctx->fpu_enabled)) {
1931
        GEN_EXCP_NO_FP(ctx);
1932
        return;
1933
    }
1934
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1935
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1936
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1937
}
1938

    
1939
/* fnabs */
1940
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
1941
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1942
/* fneg */
1943
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
1944
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1945

    
1946
/***                  Floating-Point status & ctrl register                ***/
1947
/* mcrfs */
1948
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1949
{
1950
    int bfa;
1951

    
1952
    if (unlikely(!ctx->fpu_enabled)) {
1953
        GEN_EXCP_NO_FP(ctx);
1954
        return;
1955
    }
1956
    gen_optimize_fprf();
1957
    bfa = 4 * (7 - crfS(ctx->opcode));
1958
    gen_op_load_fpscr_T0(bfa);
1959
    gen_op_store_T0_crf(crfD(ctx->opcode));
1960
    gen_op_fpscr_resetbit(~(0xF << bfa));
1961
}
1962

    
1963
/* mffs */
1964
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1965
{
1966
    if (unlikely(!ctx->fpu_enabled)) {
1967
        GEN_EXCP_NO_FP(ctx);
1968
        return;
1969
    }
1970
    gen_optimize_fprf();
1971
    gen_reset_fpstatus();
1972
    gen_op_load_fpscr_FT0();
1973
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1974
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1975
}
1976

    
1977
/* mtfsb0 */
1978
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1979
{
1980
    uint8_t crb;
1981

    
1982
    if (unlikely(!ctx->fpu_enabled)) {
1983
        GEN_EXCP_NO_FP(ctx);
1984
        return;
1985
    }
1986
    crb = 32 - (crbD(ctx->opcode) >> 2);
1987
    gen_optimize_fprf();
1988
    gen_reset_fpstatus();
1989
    if (likely(crb != 30 && crb != 29))
1990
        gen_op_fpscr_resetbit(~(1 << crb));
1991
    if (unlikely(Rc(ctx->opcode) != 0)) {
1992
        gen_op_load_fpcc();
1993
        gen_op_set_Rc0();
1994
    }
1995
}
1996

    
1997
/* mtfsb1 */
1998
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1999
{
2000
    uint8_t crb;
2001

    
2002
    if (unlikely(!ctx->fpu_enabled)) {
2003
        GEN_EXCP_NO_FP(ctx);
2004
        return;
2005
    }
2006
    crb = 32 - (crbD(ctx->opcode) >> 2);
2007
    gen_optimize_fprf();
2008
    gen_reset_fpstatus();
2009
    /* XXX: we pretend we can only do IEEE floating-point computations */
2010
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
2011
        gen_op_fpscr_setbit(crb);
2012
    if (unlikely(Rc(ctx->opcode) != 0)) {
2013
        gen_op_load_fpcc();
2014
        gen_op_set_Rc0();
2015
    }
2016
    /* We can raise a differed exception */
2017
    gen_op_float_check_status();
2018
}
2019

    
2020
/* mtfsf */
2021
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2022
{
2023
    if (unlikely(!ctx->fpu_enabled)) {
2024
        GEN_EXCP_NO_FP(ctx);
2025
        return;
2026
    }
2027
    gen_optimize_fprf();
2028
    gen_op_load_fpr_FT0(rB(ctx->opcode));
2029
    gen_reset_fpstatus();
2030
    gen_op_store_fpscr(FM(ctx->opcode));
2031
    if (unlikely(Rc(ctx->opcode) != 0)) {
2032
        gen_op_load_fpcc();
2033
        gen_op_set_Rc0();
2034
    }
2035
    /* We can raise a differed exception */
2036
    gen_op_float_check_status();
2037
}
2038

    
2039
/* mtfsfi */
2040
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2041
{
2042
    int bf, sh;
2043

    
2044
    if (unlikely(!ctx->fpu_enabled)) {
2045
        GEN_EXCP_NO_FP(ctx);
2046
        return;
2047
    }
2048
    bf = crbD(ctx->opcode) >> 2;
2049
    sh = 7 - bf;
2050
    gen_optimize_fprf();
2051
    gen_op_set_FT0(FPIMM(ctx->opcode) << (4 * sh));
2052
    gen_reset_fpstatus();
2053
    gen_op_store_fpscr(1 << sh);
2054
    if (unlikely(Rc(ctx->opcode) != 0)) {
2055
        gen_op_load_fpcc();
2056
        gen_op_set_Rc0();
2057
    }
2058
    /* We can raise a differed exception */
2059
    gen_op_float_check_status();
2060
}
2061

    
2062
/***                           Addressing modes                            ***/
2063
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2064
static always_inline void gen_addr_imm_index (DisasContext *ctx,
2065
                                              target_long maskl)
2066
{
2067
    target_long simm = SIMM(ctx->opcode);
2068

    
2069
    simm &= ~maskl;
2070
    if (rA(ctx->opcode) == 0) {
2071
        gen_set_T0(simm);
2072
    } else {
2073
        gen_op_load_gpr_T0(rA(ctx->opcode));
2074
        if (likely(simm != 0))
2075
            gen_op_addi(simm);
2076
    }
2077
#ifdef DEBUG_MEMORY_ACCESSES
2078
    gen_op_print_mem_EA();
2079
#endif
2080
}
2081

    
2082
static always_inline void gen_addr_reg_index (DisasContext *ctx)
2083
{
2084
    if (rA(ctx->opcode) == 0) {
2085
        gen_op_load_gpr_T0(rB(ctx->opcode));
2086
    } else {
2087
        gen_op_load_gpr_T0(rA(ctx->opcode));
2088
        gen_op_load_gpr_T1(rB(ctx->opcode));
2089
        gen_op_add();
2090
    }
2091
#ifdef DEBUG_MEMORY_ACCESSES
2092
    gen_op_print_mem_EA();
2093
#endif
2094
}
2095

    
2096
static always_inline void gen_addr_register (DisasContext *ctx)
2097
{
2098
    if (rA(ctx->opcode) == 0) {
2099
        gen_op_reset_T0();
2100
    } else {
2101
        gen_op_load_gpr_T0(rA(ctx->opcode));
2102
    }
2103
#ifdef DEBUG_MEMORY_ACCESSES
2104
    gen_op_print_mem_EA();
2105
#endif
2106
}
2107

    
2108
#if defined(TARGET_PPC64)
2109
#define _GEN_MEM_FUNCS(name, mode)                                            \
2110
    &gen_op_##name##_##mode,                                                  \
2111
    &gen_op_##name##_le_##mode,                                               \
2112
    &gen_op_##name##_64_##mode,                                               \
2113
    &gen_op_##name##_le_64_##mode
2114
#else
2115
#define _GEN_MEM_FUNCS(name, mode)                                            \
2116
    &gen_op_##name##_##mode,                                                  \
2117
    &gen_op_##name##_le_##mode
2118
#endif
2119
#if defined(CONFIG_USER_ONLY)
2120
#if defined(TARGET_PPC64)
2121
#define NB_MEM_FUNCS 4
2122
#else
2123
#define NB_MEM_FUNCS 2
2124
#endif
2125
#define GEN_MEM_FUNCS(name)                                                   \
2126
    _GEN_MEM_FUNCS(name, raw)
2127
#else
2128
#if defined(TARGET_PPC64)
2129
#define NB_MEM_FUNCS 12
2130
#else
2131
#define NB_MEM_FUNCS 6
2132
#endif
2133
#define GEN_MEM_FUNCS(name)                                                   \
2134
    _GEN_MEM_FUNCS(name, user),                                               \
2135
    _GEN_MEM_FUNCS(name, kernel),                                             \
2136
    _GEN_MEM_FUNCS(name, hypv)
2137
#endif
2138

    
2139
/***                             Integer load                              ***/
2140
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
2141
/* Byte access routine are endian safe */
2142
#define gen_op_lbz_le_raw       gen_op_lbz_raw
2143
#define gen_op_lbz_le_user      gen_op_lbz_user
2144
#define gen_op_lbz_le_kernel    gen_op_lbz_kernel
2145
#define gen_op_lbz_le_hypv      gen_op_lbz_hypv
2146
#define gen_op_lbz_le_64_raw    gen_op_lbz_64_raw
2147
#define gen_op_lbz_le_64_user   gen_op_lbz_64_user
2148
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
2149
#define gen_op_lbz_le_64_hypv   gen_op_lbz_64_hypv
2150
#define gen_op_stb_le_raw       gen_op_stb_raw
2151
#define gen_op_stb_le_user      gen_op_stb_user
2152
#define gen_op_stb_le_kernel    gen_op_stb_kernel
2153
#define gen_op_stb_le_hypv      gen_op_stb_hypv
2154
#define gen_op_stb_le_64_raw    gen_op_stb_64_raw
2155
#define gen_op_stb_le_64_user   gen_op_stb_64_user
2156
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
2157
#define gen_op_stb_le_64_hypv   gen_op_stb_64_hypv
2158
#define OP_LD_TABLE(width)                                                    \
2159
static GenOpFunc *gen_op_l##width[NB_MEM_FUNCS] = {                           \
2160
    GEN_MEM_FUNCS(l##width),                                                  \
2161
};
2162
#define OP_ST_TABLE(width)                                                    \
2163
static GenOpFunc *gen_op_st##width[NB_MEM_FUNCS] = {                          \
2164
    GEN_MEM_FUNCS(st##width),                                                 \
2165
};
2166

    
2167
#define GEN_LD(width, opc, type)                                              \
2168
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2169
{                                                                             \
2170
    gen_addr_imm_index(ctx, 0);                                               \
2171
    op_ldst(l##width);                                                        \
2172
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2173
}
2174

    
2175
#define GEN_LDU(width, opc, type)                                             \
2176
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2177
{                                                                             \
2178
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2179
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2180
        GEN_EXCP_INVAL(ctx);                                                  \
2181
        return;                                                               \
2182
    }                                                                         \
2183
    if (type == PPC_64B)                                                      \
2184
        gen_addr_imm_index(ctx, 0x03);                                        \
2185
    else                                                                      \
2186
        gen_addr_imm_index(ctx, 0);                                           \
2187
    op_ldst(l##width);                                                        \
2188
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2189
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2190
}
2191

    
2192
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2193
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2194
{                                                                             \
2195
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2196
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2197
        GEN_EXCP_INVAL(ctx);                                                  \
2198
        return;                                                               \
2199
    }                                                                         \
2200
    gen_addr_reg_index(ctx);                                                  \
2201
    op_ldst(l##width);                                                        \
2202
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2203
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2204
}
2205

    
2206
#define GEN_LDX(width, opc2, opc3, type)                                      \
2207
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2208
{                                                                             \
2209
    gen_addr_reg_index(ctx);                                                  \
2210
    op_ldst(l##width);                                                        \
2211
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2212
}
2213

    
2214
#define GEN_LDS(width, op, type)                                              \
2215
OP_LD_TABLE(width);                                                           \
2216
GEN_LD(width, op | 0x20, type);                                               \
2217
GEN_LDU(width, op | 0x21, type);                                              \
2218
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2219
GEN_LDX(width, 0x17, op | 0x00, type)
2220

    
2221
/* lbz lbzu lbzux lbzx */
2222
GEN_LDS(bz, 0x02, PPC_INTEGER);
2223
/* lha lhau lhaux lhax */
2224
GEN_LDS(ha, 0x0A, PPC_INTEGER);
2225
/* lhz lhzu lhzux lhzx */
2226
GEN_LDS(hz, 0x08, PPC_INTEGER);
2227
/* lwz lwzu lwzux lwzx */
2228
GEN_LDS(wz, 0x00, PPC_INTEGER);
2229
#if defined(TARGET_PPC64)
2230
OP_LD_TABLE(wa);
2231
OP_LD_TABLE(d);
2232
/* lwaux */
2233
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
2234
/* lwax */
2235
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
2236
/* ldux */
2237
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
2238
/* ldx */
2239
GEN_LDX(d, 0x15, 0x00, PPC_64B);
2240
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2241
{
2242
    if (Rc(ctx->opcode)) {
2243
        if (unlikely(rA(ctx->opcode) == 0 ||
2244
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2245
            GEN_EXCP_INVAL(ctx);
2246
            return;
2247
        }
2248
    }
2249
    gen_addr_imm_index(ctx, 0x03);
2250
    if (ctx->opcode & 0x02) {
2251
        /* lwa (lwau is undefined) */
2252
        op_ldst(lwa);
2253
    } else {
2254
        /* ld - ldu */
2255
        op_ldst(ld);
2256
    }
2257
    gen_op_store_T1_gpr(rD(ctx->opcode));
2258
    if (Rc(ctx->opcode))
2259
        gen_op_store_T0_gpr(rA(ctx->opcode));
2260
}
2261
/* lq */
2262
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2263
{
2264
#if defined(CONFIG_USER_ONLY)
2265
    GEN_EXCP_PRIVOPC(ctx);
2266
#else
2267
    int ra, rd;
2268

    
2269
    /* Restore CPU state */
2270
    if (unlikely(ctx->supervisor == 0)) {
2271
        GEN_EXCP_PRIVOPC(ctx);
2272
        return;
2273
    }
2274
    ra = rA(ctx->opcode);
2275
    rd = rD(ctx->opcode);
2276
    if (unlikely((rd & 1) || rd == ra)) {
2277
        GEN_EXCP_INVAL(ctx);
2278
        return;
2279
    }
2280
    if (unlikely(ctx->mem_idx & 1)) {
2281
        /* Little-endian mode is not handled */
2282
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2283
        return;
2284
    }
2285
    gen_addr_imm_index(ctx, 0x0F);
2286
    op_ldst(ld);
2287
    gen_op_store_T1_gpr(rd);
2288
    gen_op_addi(8);
2289
    op_ldst(ld);
2290
    gen_op_store_T1_gpr(rd + 1);
2291
#endif
2292
}
2293
#endif
2294

    
2295
/***                              Integer store                            ***/
2296
#define GEN_ST(width, opc, type)                                              \
2297
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2298
{                                                                             \
2299
    gen_addr_imm_index(ctx, 0);                                               \
2300
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2301
    op_ldst(st##width);                                                       \
2302
}
2303

    
2304
#define GEN_STU(width, opc, type)                                             \
2305
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2306
{                                                                             \
2307
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2308
        GEN_EXCP_INVAL(ctx);                                                  \
2309
        return;                                                               \
2310
    }                                                                         \
2311
    if (type == PPC_64B)                                                      \
2312
        gen_addr_imm_index(ctx, 0x03);                                        \
2313
    else                                                                      \
2314
        gen_addr_imm_index(ctx, 0);                                           \
2315
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2316
    op_ldst(st##width);                                                       \
2317
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2318
}
2319

    
2320
#define GEN_STUX(width, opc2, opc3, type)                                     \
2321
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2322
{                                                                             \
2323
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2324
        GEN_EXCP_INVAL(ctx);                                                  \
2325
        return;                                                               \
2326
    }                                                                         \
2327
    gen_addr_reg_index(ctx);                                                  \
2328
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2329
    op_ldst(st##width);                                                       \
2330
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2331
}
2332

    
2333
#define GEN_STX(width, opc2, opc3, type)                                      \
2334
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2335
{                                                                             \
2336
    gen_addr_reg_index(ctx);                                                  \
2337
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2338
    op_ldst(st##width);                                                       \
2339
}
2340

    
2341
#define GEN_STS(width, op, type)                                              \
2342
OP_ST_TABLE(width);                                                           \
2343
GEN_ST(width, op | 0x20, type);                                               \
2344
GEN_STU(width, op | 0x21, type);                                              \
2345
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2346
GEN_STX(width, 0x17, op | 0x00, type)
2347

    
2348
/* stb stbu stbux stbx */
2349
GEN_STS(b, 0x06, PPC_INTEGER);
2350
/* sth sthu sthux sthx */
2351
GEN_STS(h, 0x0C, PPC_INTEGER);
2352
/* stw stwu stwux stwx */
2353
GEN_STS(w, 0x04, PPC_INTEGER);
2354
#if defined(TARGET_PPC64)
2355
OP_ST_TABLE(d);
2356
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2357
GEN_STX(d, 0x15, 0x04, PPC_64B);
2358
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2359
{
2360
    int rs;
2361

    
2362
    rs = rS(ctx->opcode);
2363
    if ((ctx->opcode & 0x3) == 0x2) {
2364
#if defined(CONFIG_USER_ONLY)
2365
        GEN_EXCP_PRIVOPC(ctx);
2366
#else
2367
        /* stq */
2368
        if (unlikely(ctx->supervisor == 0)) {
2369
            GEN_EXCP_PRIVOPC(ctx);
2370
            return;
2371
        }
2372
        if (unlikely(rs & 1)) {
2373
            GEN_EXCP_INVAL(ctx);
2374
            return;
2375
        }
2376
        if (unlikely(ctx->mem_idx & 1)) {
2377
            /* Little-endian mode is not handled */
2378
            GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2379
            return;
2380
        }
2381
        gen_addr_imm_index(ctx, 0x03);
2382
        gen_op_load_gpr_T1(rs);
2383
        op_ldst(std);
2384
        gen_op_addi(8);
2385
        gen_op_load_gpr_T1(rs + 1);
2386
        op_ldst(std);
2387
#endif
2388
    } else {
2389
        /* std / stdu */
2390
        if (Rc(ctx->opcode)) {
2391
            if (unlikely(rA(ctx->opcode) == 0)) {
2392
                GEN_EXCP_INVAL(ctx);
2393
                return;
2394
            }
2395
        }
2396
        gen_addr_imm_index(ctx, 0x03);
2397
        gen_op_load_gpr_T1(rs);
2398
        op_ldst(std);
2399
        if (Rc(ctx->opcode))
2400
            gen_op_store_T0_gpr(rA(ctx->opcode));
2401
    }
2402
}
2403
#endif
2404
/***                Integer load and store with byte reverse               ***/
2405
/* lhbrx */
2406
OP_LD_TABLE(hbr);
2407
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2408
/* lwbrx */
2409
OP_LD_TABLE(wbr);
2410
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2411
/* sthbrx */
2412
OP_ST_TABLE(hbr);
2413
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2414
/* stwbrx */
2415
OP_ST_TABLE(wbr);
2416
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2417

    
2418
/***                    Integer load and store multiple                    ***/
2419
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2420
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
2421
    GEN_MEM_FUNCS(lmw),
2422
};
2423
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
2424
    GEN_MEM_FUNCS(stmw),
2425
};
2426

    
2427
/* lmw */
2428
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2429
{
2430
    /* NIP cannot be restored if the memory exception comes from an helper */
2431
    gen_update_nip(ctx, ctx->nip - 4);
2432
    gen_addr_imm_index(ctx, 0);
2433
    op_ldstm(lmw, rD(ctx->opcode));
2434
}
2435

    
2436
/* stmw */
2437
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2438
{
2439
    /* NIP cannot be restored if the memory exception comes from an helper */
2440
    gen_update_nip(ctx, ctx->nip - 4);
2441
    gen_addr_imm_index(ctx, 0);
2442
    op_ldstm(stmw, rS(ctx->opcode));
2443
}
2444

    
2445
/***                    Integer load and store strings                     ***/
2446
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2447
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2448
/* string load & stores are by definition endian-safe */
2449
#define gen_op_lswi_le_raw       gen_op_lswi_raw
2450
#define gen_op_lswi_le_user      gen_op_lswi_user
2451
#define gen_op_lswi_le_kernel    gen_op_lswi_kernel
2452
#define gen_op_lswi_le_hypv      gen_op_lswi_hypv
2453
#define gen_op_lswi_le_64_raw    gen_op_lswi_raw
2454
#define gen_op_lswi_le_64_user   gen_op_lswi_user
2455
#define gen_op_lswi_le_64_kernel gen_op_lswi_kernel
2456
#define gen_op_lswi_le_64_hypv   gen_op_lswi_hypv
2457
static GenOpFunc1 *gen_op_lswi[NB_MEM_FUNCS] = {
2458
    GEN_MEM_FUNCS(lswi),
2459
};
2460
#define gen_op_lswx_le_raw       gen_op_lswx_raw
2461
#define gen_op_lswx_le_user      gen_op_lswx_user
2462
#define gen_op_lswx_le_kernel    gen_op_lswx_kernel
2463
#define gen_op_lswx_le_hypv      gen_op_lswx_hypv
2464
#define gen_op_lswx_le_64_raw    gen_op_lswx_raw
2465
#define gen_op_lswx_le_64_user   gen_op_lswx_user
2466
#define gen_op_lswx_le_64_kernel gen_op_lswx_kernel
2467
#define gen_op_lswx_le_64_hypv   gen_op_lswx_hypv
2468
static GenOpFunc3 *gen_op_lswx[NB_MEM_FUNCS] = {
2469
    GEN_MEM_FUNCS(lswx),
2470
};
2471
#define gen_op_stsw_le_raw       gen_op_stsw_raw
2472
#define gen_op_stsw_le_user      gen_op_stsw_user
2473
#define gen_op_stsw_le_kernel    gen_op_stsw_kernel
2474
#define gen_op_stsw_le_hypv      gen_op_stsw_hypv
2475
#define gen_op_stsw_le_64_raw    gen_op_stsw_raw
2476
#define gen_op_stsw_le_64_user   gen_op_stsw_user
2477
#define gen_op_stsw_le_64_kernel gen_op_stsw_kernel
2478
#define gen_op_stsw_le_64_hypv   gen_op_stsw_hypv
2479
static GenOpFunc1 *gen_op_stsw[NB_MEM_FUNCS] = {
2480
    GEN_MEM_FUNCS(stsw),
2481
};
2482

    
2483
/* lswi */
2484
/* PowerPC32 specification says we must generate an exception if
2485
 * rA is in the range of registers to be loaded.
2486
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2487
 * For now, I'll follow the spec...
2488
 */
2489
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
2490
{
2491
    int nb = NB(ctx->opcode);
2492
    int start = rD(ctx->opcode);
2493
    int ra = rA(ctx->opcode);
2494
    int nr;
2495

    
2496
    if (nb == 0)
2497
        nb = 32;
2498
    nr = nb / 4;
2499
    if (unlikely(((start + nr) > 32  &&
2500
                  start <= ra && (start + nr - 32) > ra) ||
2501
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2502
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
2503
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
2504
        return;
2505
    }
2506
    /* NIP cannot be restored if the memory exception comes from an helper */
2507
    gen_update_nip(ctx, ctx->nip - 4);
2508
    gen_addr_register(ctx);
2509
    gen_op_set_T1(nb);
2510
    op_ldsts(lswi, start);
2511
}
2512

    
2513
/* lswx */
2514
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
2515
{
2516
    int ra = rA(ctx->opcode);
2517
    int rb = rB(ctx->opcode);
2518

    
2519
    /* NIP cannot be restored if the memory exception comes from an helper */
2520
    gen_update_nip(ctx, ctx->nip - 4);
2521
    gen_addr_reg_index(ctx);
2522
    if (ra == 0) {
2523
        ra = rb;
2524
    }
2525
    gen_op_load_xer_bc();
2526
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2527
}
2528

    
2529
/* stswi */
2530
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
2531
{
2532
    int nb = NB(ctx->opcode);
2533

    
2534
    /* NIP cannot be restored if the memory exception comes from an helper */
2535
    gen_update_nip(ctx, ctx->nip - 4);
2536
    gen_addr_register(ctx);
2537
    if (nb == 0)
2538
        nb = 32;
2539
    gen_op_set_T1(nb);
2540
    op_ldsts(stsw, rS(ctx->opcode));
2541
}
2542

    
2543
/* stswx */
2544
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
2545
{
2546
    /* NIP cannot be restored if the memory exception comes from an helper */
2547
    gen_update_nip(ctx, ctx->nip - 4);
2548
    gen_addr_reg_index(ctx);
2549
    gen_op_load_xer_bc();
2550
    op_ldsts(stsw, rS(ctx->opcode));
2551
}
2552

    
2553
/***                        Memory synchronisation                         ***/
2554
/* eieio */
2555
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2556
{
2557
}
2558

    
2559
/* isync */
2560
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2561
{
2562
    GEN_STOP(ctx);
2563
}
2564

    
2565
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2566
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2567
static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
2568
    GEN_MEM_FUNCS(lwarx),
2569
};
2570
static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
2571
    GEN_MEM_FUNCS(stwcx),
2572
};
2573

    
2574
/* lwarx */
2575
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2576
{
2577
    /* NIP cannot be restored if the memory exception comes from an helper */
2578
    gen_update_nip(ctx, ctx->nip - 4);
2579
    gen_addr_reg_index(ctx);
2580
    op_lwarx();
2581
    gen_op_store_T1_gpr(rD(ctx->opcode));
2582
}
2583

    
2584
/* stwcx. */
2585
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2586
{
2587
    /* NIP cannot be restored if the memory exception comes from an helper */
2588
    gen_update_nip(ctx, ctx->nip - 4);
2589
    gen_addr_reg_index(ctx);
2590
    gen_op_load_gpr_T1(rS(ctx->opcode));
2591
    op_stwcx();
2592
}
2593

    
2594
#if defined(TARGET_PPC64)
2595
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2596
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2597
static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
2598
    GEN_MEM_FUNCS(ldarx),
2599
};
2600
static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
2601
    GEN_MEM_FUNCS(stdcx),
2602
};
2603

    
2604
/* ldarx */
2605
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2606
{
2607
    /* NIP cannot be restored if the memory exception comes from an helper */
2608
    gen_update_nip(ctx, ctx->nip - 4);
2609
    gen_addr_reg_index(ctx);
2610
    op_ldarx();
2611
    gen_op_store_T1_gpr(rD(ctx->opcode));
2612
}
2613

    
2614
/* stdcx. */
2615
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2616
{
2617
    /* NIP cannot be restored if the memory exception comes from an helper */
2618
    gen_update_nip(ctx, ctx->nip - 4);
2619
    gen_addr_reg_index(ctx);
2620
    gen_op_load_gpr_T1(rS(ctx->opcode));
2621
    op_stdcx();
2622
}
2623
#endif /* defined(TARGET_PPC64) */
2624

    
2625
/* sync */
2626
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
2627
{
2628
}
2629

    
2630
/* wait */
2631
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2632
{
2633
    /* Stop translation, as the CPU is supposed to sleep from now */
2634
    gen_op_wait();
2635
    GEN_EXCP(ctx, EXCP_HLT, 1);
2636
}
2637

    
2638
/***                         Floating-point load                           ***/
2639
#define GEN_LDF(width, opc, type)                                             \
2640
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2641
{                                                                             \
2642
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2643
        GEN_EXCP_NO_FP(ctx);                                                  \
2644
        return;                                                               \
2645
    }                                                                         \
2646
    gen_addr_imm_index(ctx, 0);                                               \
2647
    op_ldst(l##width);                                                        \
2648
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2649
}
2650

    
2651
#define GEN_LDUF(width, opc, type)                                            \
2652
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2653
{                                                                             \
2654
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2655
        GEN_EXCP_NO_FP(ctx);                                                  \
2656
        return;                                                               \
2657
    }                                                                         \
2658
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2659
        GEN_EXCP_INVAL(ctx);                                                  \
2660
        return;                                                               \
2661
    }                                                                         \
2662
    gen_addr_imm_index(ctx, 0);                                               \
2663
    op_ldst(l##width);                                                        \
2664
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2665
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2666
}
2667

    
2668
#define GEN_LDUXF(width, opc, type)                                           \
2669
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
2670
{                                                                             \
2671
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2672
        GEN_EXCP_NO_FP(ctx);                                                  \
2673
        return;                                                               \
2674
    }                                                                         \
2675
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2676
        GEN_EXCP_INVAL(ctx);                                                  \
2677
        return;                                                               \
2678
    }                                                                         \
2679
    gen_addr_reg_index(ctx);                                                  \
2680
    op_ldst(l##width);                                                        \
2681
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2682
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2683
}
2684

    
2685
#define GEN_LDXF(width, opc2, opc3, type)                                     \
2686
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2687
{                                                                             \
2688
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2689
        GEN_EXCP_NO_FP(ctx);                                                  \
2690
        return;                                                               \
2691
    }                                                                         \
2692
    gen_addr_reg_index(ctx);                                                  \
2693
    op_ldst(l##width);                                                        \
2694
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2695
}
2696

    
2697
#define GEN_LDFS(width, op, type)                                             \
2698
OP_LD_TABLE(width);                                                           \
2699
GEN_LDF(width, op | 0x20, type);                                              \
2700
GEN_LDUF(width, op | 0x21, type);                                             \
2701
GEN_LDUXF(width, op | 0x01, type);                                            \
2702
GEN_LDXF(width, 0x17, op | 0x00, type)
2703

    
2704
/* lfd lfdu lfdux lfdx */
2705
GEN_LDFS(fd, 0x12, PPC_FLOAT);
2706
/* lfs lfsu lfsux lfsx */
2707
GEN_LDFS(fs, 0x10, PPC_FLOAT);
2708

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

    
2722
#define GEN_STUF(width, opc, type)                                            \
2723
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2724
{                                                                             \
2725
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2726
        GEN_EXCP_NO_FP(ctx);                                                  \
2727
        return;                                                               \
2728
    }                                                                         \
2729
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2730
        GEN_EXCP_INVAL(ctx);                                                  \
2731
        return;                                                               \
2732
    }                                                                         \
2733
    gen_addr_imm_index(ctx, 0);                                               \
2734
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2735
    op_ldst(st##width);                                                       \
2736
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2737
}
2738

    
2739
#define GEN_STUXF(width, opc, type)                                           \
2740
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
2741
{                                                                             \
2742
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2743
        GEN_EXCP_NO_FP(ctx);                                                  \
2744
        return;                                                               \
2745
    }                                                                         \
2746
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2747
        GEN_EXCP_INVAL(ctx);                                                  \
2748
        return;                                                               \
2749
    }                                                                         \
2750
    gen_addr_reg_index(ctx);                                                  \
2751
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2752
    op_ldst(st##width);                                                       \
2753
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2754
}
2755

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

    
2768
#define GEN_STFS(width, op, type)                                             \
2769
OP_ST_TABLE(width);                                                           \
2770
GEN_STF(width, op | 0x20, type);                                              \
2771
GEN_STUF(width, op | 0x21, type);                                             \
2772
GEN_STUXF(width, op | 0x01, type);                                            \
2773
GEN_STXF(width, 0x17, op | 0x00, type)
2774

    
2775
/* stfd stfdu stfdux stfdx */
2776
GEN_STFS(fd, 0x16, PPC_FLOAT);
2777
/* stfs stfsu stfsux stfsx */
2778
GEN_STFS(fs, 0x14, PPC_FLOAT);
2779

    
2780
/* Optional: */
2781
/* stfiwx */
2782
OP_ST_TABLE(fiw);
2783
GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2784

    
2785
/***                                Branch                                 ***/
2786
static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2787
                                       target_ulong dest)
2788
{
2789
    TranslationBlock *tb;
2790
    tb = ctx->tb;
2791
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2792
        likely(!ctx->singlestep_enabled)) {
2793
        tcg_gen_goto_tb(n);
2794
        gen_set_T1(dest);
2795
#if defined(TARGET_PPC64)
2796
        if (ctx->sf_mode)
2797
            gen_op_b_T1_64();
2798
        else
2799
#endif
2800
            gen_op_b_T1();
2801
        tcg_gen_exit_tb((long)tb + n);
2802
    } else {
2803
        gen_set_T1(dest);
2804
#if defined(TARGET_PPC64)
2805
        if (ctx->sf_mode)
2806
            gen_op_b_T1_64();
2807
        else
2808
#endif
2809
            gen_op_b_T1();
2810
        if (unlikely(ctx->singlestep_enabled)) {
2811
            if ((ctx->singlestep_enabled &
2812
                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
2813
                ctx->exception == POWERPC_EXCP_BRANCH) {
2814
                target_ulong tmp = ctx->nip;
2815
                ctx->nip = dest;
2816
                GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
2817
                ctx->nip = tmp;
2818
            }
2819
            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
2820
                gen_update_nip(ctx, dest);
2821
                gen_op_debug();
2822
            }
2823
        }
2824
        tcg_gen_exit_tb(0);
2825
    }
2826
}
2827

    
2828
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2829
{
2830
#if defined(TARGET_PPC64)
2831
    if (ctx->sf_mode != 0 && (nip >> 32))
2832
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2833
    else
2834
#endif
2835
        gen_op_setlr(ctx->nip);
2836
}
2837

    
2838
/* b ba bl bla */
2839
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2840
{
2841
    target_ulong li, target;
2842

    
2843
    ctx->exception = POWERPC_EXCP_BRANCH;
2844
    /* sign extend LI */
2845
#if defined(TARGET_PPC64)
2846
    if (ctx->sf_mode)
2847
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2848
    else
2849
#endif
2850
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2851
    if (likely(AA(ctx->opcode) == 0))
2852
        target = ctx->nip + li - 4;
2853
    else
2854
        target = li;
2855
#if defined(TARGET_PPC64)
2856
    if (!ctx->sf_mode)
2857
        target = (uint32_t)target;
2858
#endif
2859
    if (LK(ctx->opcode))
2860
        gen_setlr(ctx, ctx->nip);
2861
    gen_goto_tb(ctx, 0, target);
2862
}
2863

    
2864
#define BCOND_IM  0
2865
#define BCOND_LR  1
2866
#define BCOND_CTR 2
2867

    
2868
static always_inline void gen_bcond (DisasContext *ctx, int type)
2869
{
2870
    target_ulong target = 0;
2871
    target_ulong li;
2872
    uint32_t bo = BO(ctx->opcode);
2873
    uint32_t bi = BI(ctx->opcode);
2874
    uint32_t mask;
2875

    
2876
    ctx->exception = POWERPC_EXCP_BRANCH;
2877
    if ((bo & 0x4) == 0)
2878
        gen_op_dec_ctr();
2879
    switch(type) {
2880
    case BCOND_IM:
2881
        li = (target_long)((int16_t)(BD(ctx->opcode)));
2882
        if (likely(AA(ctx->opcode) == 0)) {
2883
            target = ctx->nip + li - 4;
2884
        } else {
2885
            target = li;
2886
        }
2887
#if defined(TARGET_PPC64)
2888
        if (!ctx->sf_mode)
2889
            target = (uint32_t)target;
2890
#endif
2891
        break;
2892
    case BCOND_CTR:
2893
        gen_op_movl_T1_ctr();
2894
        break;
2895
    default:
2896
    case BCOND_LR:
2897
        gen_op_movl_T1_lr();
2898
        break;
2899
    }
2900
    if (LK(ctx->opcode))
2901
        gen_setlr(ctx, ctx->nip);
2902
    if (bo & 0x10) {
2903
        /* No CR condition */
2904
        switch (bo & 0x6) {
2905
        case 0:
2906
#if defined(TARGET_PPC64)
2907
            if (ctx->sf_mode)
2908
                gen_op_test_ctr_64();
2909
            else
2910
#endif
2911
                gen_op_test_ctr();
2912
            break;
2913
        case 2:
2914
#if defined(TARGET_PPC64)
2915
            if (ctx->sf_mode)
2916
                gen_op_test_ctrz_64();
2917
            else
2918
#endif
2919
                gen_op_test_ctrz();
2920
            break;
2921
        default:
2922
        case 4:
2923
        case 6:
2924
            if (type == BCOND_IM) {
2925
                gen_goto_tb(ctx, 0, target);
2926
                return;
2927
            } else {
2928
#if defined(TARGET_PPC64)
2929
                if (ctx->sf_mode)
2930
                    gen_op_b_T1_64();
2931
                else
2932
#endif
2933
                    gen_op_b_T1();
2934
                goto no_test;
2935
            }
2936
            break;
2937
        }
2938
    } else {
2939
        mask = 1 << (3 - (bi & 0x03));
2940
        gen_op_load_crf_T0(bi >> 2);
2941
        if (bo & 0x8) {
2942
            switch (bo & 0x6) {
2943
            case 0:
2944
#if defined(TARGET_PPC64)
2945
                if (ctx->sf_mode)
2946
                    gen_op_test_ctr_true_64(mask);
2947
                else
2948
#endif
2949
                    gen_op_test_ctr_true(mask);
2950
                break;
2951
            case 2:
2952
#if defined(TARGET_PPC64)
2953
                if (ctx->sf_mode)
2954
                    gen_op_test_ctrz_true_64(mask);
2955
                else
2956
#endif
2957
                    gen_op_test_ctrz_true(mask);
2958
                break;
2959
            default:
2960
            case 4:
2961
            case 6:
2962
                gen_op_test_true(mask);
2963
                break;
2964
            }
2965
        } else {
2966
            switch (bo & 0x6) {
2967
            case 0:
2968
#if defined(TARGET_PPC64)
2969
                if (ctx->sf_mode)
2970
                    gen_op_test_ctr_false_64(mask);
2971
                else
2972
#endif
2973
                    gen_op_test_ctr_false(mask);
2974
                break;
2975
            case 2:
2976
#if defined(TARGET_PPC64)
2977
                if (ctx->sf_mode)
2978
                    gen_op_test_ctrz_false_64(mask);
2979
                else
2980
#endif
2981
                    gen_op_test_ctrz_false(mask);
2982
                break;
2983
            default:
2984
            case 4:
2985
            case 6:
2986
                gen_op_test_false(mask);
2987
                break;
2988
            }
2989
        }
2990
    }
2991
    if (type == BCOND_IM) {
2992
        int l1 = gen_new_label();
2993
        gen_op_jz_T0(l1);
2994
        gen_goto_tb(ctx, 0, target);
2995
        gen_set_label(l1);
2996
        gen_goto_tb(ctx, 1, ctx->nip);
2997
    } else {
2998
#if defined(TARGET_PPC64)
2999
        if (ctx->sf_mode)
3000
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
3001
        else
3002
#endif
3003
            gen_op_btest_T1(ctx->nip);
3004
    no_test:
3005
        if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3006
            gen_update_nip(ctx, ctx->nip);
3007
            gen_op_debug();
3008
        }
3009
        tcg_gen_exit_tb(0);
3010
    }
3011
}
3012

    
3013
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3014
{
3015
    gen_bcond(ctx, BCOND_IM);
3016
}
3017

    
3018
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3019
{
3020
    gen_bcond(ctx, BCOND_CTR);
3021
}
3022

    
3023
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3024
{
3025
    gen_bcond(ctx, BCOND_LR);
3026
}
3027

    
3028
/***                      Condition register logical                       ***/
3029
#define GEN_CRLOGIC(op, opc)                                                  \
3030
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
3031
{                                                                             \
3032
    uint8_t bitmask;                                                          \
3033
    int sh;                                                                   \
3034
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
3035
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3036
    if (sh > 0)                                                               \
3037
        gen_op_srli_T0(sh);                                                   \
3038
    else if (sh < 0)                                                          \
3039
        gen_op_sli_T0(-sh);                                                   \
3040
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
3041
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3042
    if (sh > 0)                                                               \
3043
        gen_op_srli_T1(sh);                                                   \
3044
    else if (sh < 0)                                                          \
3045
        gen_op_sli_T1(-sh);                                                   \
3046
    gen_op_##op();                                                            \
3047
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3048
    gen_op_andi_T0(bitmask);                                                  \
3049
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
3050
    gen_op_andi_T1(~bitmask);                                                 \
3051
    gen_op_or();                                                              \
3052
    gen_op_store_T0_crf(crbD(ctx->opcode) >> 2);                              \
3053
}
3054

    
3055
/* crand */
3056
GEN_CRLOGIC(and, 0x08);
3057
/* crandc */
3058
GEN_CRLOGIC(andc, 0x04);
3059
/* creqv */
3060
GEN_CRLOGIC(eqv, 0x09);
3061
/* crnand */
3062
GEN_CRLOGIC(nand, 0x07);
3063
/* crnor */
3064
GEN_CRLOGIC(nor, 0x01);
3065
/* cror */
3066
GEN_CRLOGIC(or, 0x0E);
3067
/* crorc */
3068
GEN_CRLOGIC(orc, 0x0D);
3069
/* crxor */
3070
GEN_CRLOGIC(xor, 0x06);
3071
/* mcrf */
3072
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3073
{
3074
    gen_op_load_crf_T0(crfS(ctx->opcode));
3075
    gen_op_store_T0_crf(crfD(ctx->opcode));
3076
}
3077

    
3078
/***                           System linkage                              ***/
3079
/* rfi (supervisor only) */
3080
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3081
{
3082
#if defined(CONFIG_USER_ONLY)
3083
    GEN_EXCP_PRIVOPC(ctx);
3084
#else
3085
    /* Restore CPU state */
3086
    if (unlikely(!ctx->supervisor)) {
3087
        GEN_EXCP_PRIVOPC(ctx);
3088
        return;
3089
    }
3090
    gen_op_rfi();
3091
    GEN_SYNC(ctx);
3092
#endif
3093
}
3094

    
3095
#if defined(TARGET_PPC64)
3096
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3097
{
3098
#if defined(CONFIG_USER_ONLY)
3099
    GEN_EXCP_PRIVOPC(ctx);
3100
#else
3101
    /* Restore CPU state */
3102
    if (unlikely(!ctx->supervisor)) {
3103
        GEN_EXCP_PRIVOPC(ctx);
3104
        return;
3105
    }
3106
    gen_op_rfid();
3107
    GEN_SYNC(ctx);
3108
#endif
3109
}
3110

    
3111
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3112
{
3113
#if defined(CONFIG_USER_ONLY)
3114
    GEN_EXCP_PRIVOPC(ctx);
3115
#else
3116
    /* Restore CPU state */
3117
    if (unlikely(ctx->supervisor <= 1)) {
3118
        GEN_EXCP_PRIVOPC(ctx);
3119
        return;
3120
    }
3121
    gen_op_hrfid();
3122
    GEN_SYNC(ctx);
3123
#endif
3124
}
3125
#endif
3126

    
3127
/* sc */
3128
#if defined(CONFIG_USER_ONLY)
3129
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3130
#else
3131
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3132
#endif
3133
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3134
{
3135
    uint32_t lev;
3136

    
3137
    lev = (ctx->opcode >> 5) & 0x7F;
3138
    GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
3139
}
3140

    
3141
/***                                Trap                                   ***/
3142
/* tw */
3143
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3144
{
3145
    gen_op_load_gpr_T0(rA(ctx->opcode));
3146
    gen_op_load_gpr_T1(rB(ctx->opcode));
3147
    /* Update the nip since this might generate a trap exception */
3148
    gen_update_nip(ctx, ctx->nip);
3149
    gen_op_tw(TO(ctx->opcode));
3150
}
3151

    
3152
/* twi */
3153
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3154
{
3155
    gen_op_load_gpr_T0(rA(ctx->opcode));
3156
    gen_set_T1(SIMM(ctx->opcode));
3157
    /* Update the nip since this might generate a trap exception */
3158
    gen_update_nip(ctx, ctx->nip);
3159
    gen_op_tw(TO(ctx->opcode));
3160
}
3161

    
3162
#if defined(TARGET_PPC64)
3163
/* td */
3164
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3165
{
3166
    gen_op_load_gpr_T0(rA(ctx->opcode));
3167
    gen_op_load_gpr_T1(rB(ctx->opcode));
3168
    /* Update the nip since this might generate a trap exception */
3169
    gen_update_nip(ctx, ctx->nip);
3170
    gen_op_td(TO(ctx->opcode));
3171
}
3172

    
3173
/* tdi */
3174
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3175
{
3176
    gen_op_load_gpr_T0(rA(ctx->opcode));
3177
    gen_set_T1(SIMM(ctx->opcode));
3178
    /* Update the nip since this might generate a trap exception */
3179
    gen_update_nip(ctx, ctx->nip);
3180
    gen_op_td(TO(ctx->opcode));
3181
}
3182
#endif
3183

    
3184
/***                          Processor control                            ***/
3185
/* mcrxr */
3186
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3187
{
3188
    gen_op_load_xer_cr();
3189
    gen_op_store_T0_crf(crfD(ctx->opcode));
3190
    gen_op_clear_xer_ov();
3191
    gen_op_clear_xer_ca();
3192
}
3193

    
3194
/* mfcr */
3195
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3196
{
3197
    uint32_t crm, crn;
3198

    
3199
    if (likely(ctx->opcode & 0x00100000)) {
3200
        crm = CRM(ctx->opcode);
3201
        if (likely((crm ^ (crm - 1)) == 0)) {
3202
            crn = ffs(crm);
3203
            gen_op_load_cro(7 - crn);
3204
        }
3205
    } else {
3206
        gen_op_load_cr();
3207
    }
3208
    gen_op_store_T0_gpr(rD(ctx->opcode));
3209
}
3210

    
3211
/* mfmsr */
3212
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3213
{
3214
#if defined(CONFIG_USER_ONLY)
3215
    GEN_EXCP_PRIVREG(ctx);
3216
#else
3217
    if (unlikely(!ctx->supervisor)) {
3218
        GEN_EXCP_PRIVREG(ctx);
3219
        return;
3220
    }
3221
    gen_op_load_msr();
3222
    gen_op_store_T0_gpr(rD(ctx->opcode));
3223
#endif
3224
}
3225

    
3226
#if 1
3227
#define SPR_NOACCESS ((void *)(-1UL))
3228
#else
3229
static void spr_noaccess (void *opaque, int sprn)
3230
{
3231
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3232
    printf("ERROR: try to access SPR %d !\n", sprn);
3233
}
3234
#define SPR_NOACCESS (&spr_noaccess)
3235
#endif
3236

    
3237
/* mfspr */
3238
static always_inline void gen_op_mfspr (DisasContext *ctx)
3239
{
3240
    void (*read_cb)(void *opaque, int sprn);
3241
    uint32_t sprn = SPR(ctx->opcode);
3242

    
3243
#if !defined(CONFIG_USER_ONLY)
3244
    if (ctx->supervisor == 2)
3245
        read_cb = ctx->spr_cb[sprn].hea_read;
3246
    else if (ctx->supervisor)
3247
        read_cb = ctx->spr_cb[sprn].oea_read;
3248
    else
3249
#endif
3250
        read_cb = ctx->spr_cb[sprn].uea_read;
3251
    if (likely(read_cb != NULL)) {
3252
        if (likely(read_cb != SPR_NOACCESS)) {
3253
            (*read_cb)(ctx, sprn);
3254
            gen_op_store_T0_gpr(rD(ctx->opcode));
3255
        } else {
3256
            /* Privilege exception */
3257
            /* This is a hack to avoid warnings when running Linux:
3258
             * this OS breaks the PowerPC virtualisation model,
3259
             * allowing userland application to read the PVR
3260
             */
3261
            if (sprn != SPR_PVR) {
3262
                if (loglevel != 0) {
3263
                    fprintf(logfile, "Trying to read privileged spr %d %03x at "
3264
                            ADDRX "\n", sprn, sprn, ctx->nip);
3265
                }
3266
                printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
3267
                       sprn, sprn, ctx->nip);
3268
            }
3269
            GEN_EXCP_PRIVREG(ctx);
3270
        }
3271
    } else {
3272
        /* Not defined */
3273
        if (loglevel != 0) {
3274
            fprintf(logfile, "Trying to read invalid spr %d %03x at "
3275
                    ADDRX "\n", sprn, sprn, ctx->nip);
3276
        }
3277
        printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
3278
               sprn, sprn, ctx->nip);
3279
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3280
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3281
    }
3282
}
3283

    
3284
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3285
{
3286
    gen_op_mfspr(ctx);
3287
}
3288

    
3289
/* mftb */
3290
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3291
{
3292
    gen_op_mfspr(ctx);
3293
}
3294

    
3295
/* mtcrf */
3296
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3297
{
3298
    uint32_t crm, crn;
3299

    
3300
    gen_op_load_gpr_T0(rS(ctx->opcode));
3301
    crm = CRM(ctx->opcode);
3302
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3303
        crn = ffs(crm);
3304
        gen_op_srli_T0(crn * 4);
3305
        gen_op_andi_T0(0xF);
3306
        gen_op_store_cro(7 - crn);
3307
    } else {
3308
        gen_op_store_cr(crm);
3309
    }
3310
}
3311

    
3312
/* mtmsr */
3313
#if defined(TARGET_PPC64)
3314
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3315
{
3316
#if defined(CONFIG_USER_ONLY)
3317
    GEN_EXCP_PRIVREG(ctx);
3318
#else
3319
    if (unlikely(!ctx->supervisor)) {
3320
        GEN_EXCP_PRIVREG(ctx);
3321
        return;
3322
    }
3323
    gen_op_load_gpr_T0(rS(ctx->opcode));
3324
    if (ctx->opcode & 0x00010000) {
3325
        /* Special form that does not need any synchronisation */
3326
        gen_op_update_riee();
3327
    } else {
3328
        /* XXX: we need to update nip before the store
3329
         *      if we enter power saving mode, we will exit the loop
3330
         *      directly from ppc_store_msr
3331
         */
3332
        gen_update_nip(ctx, ctx->nip);
3333
        gen_op_store_msr();
3334
        /* Must stop the translation as machine state (may have) changed */
3335
        /* Note that mtmsr is not always defined as context-synchronizing */
3336
        ctx->exception = POWERPC_EXCP_STOP;
3337
    }
3338
#endif
3339
}
3340
#endif
3341

    
3342
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3343
{
3344
#if defined(CONFIG_USER_ONLY)
3345
    GEN_EXCP_PRIVREG(ctx);
3346
#else
3347
    if (unlikely(!ctx->supervisor)) {
3348
        GEN_EXCP_PRIVREG(ctx);
3349
        return;
3350
    }
3351
    gen_op_load_gpr_T0(rS(ctx->opcode));
3352
    if (ctx->opcode & 0x00010000) {
3353
        /* Special form that does not need any synchronisation */
3354
        gen_op_update_riee();
3355
    } else {
3356
        /* XXX: we need to update nip before the store
3357
         *      if we enter power saving mode, we will exit the loop
3358
         *      directly from ppc_store_msr
3359
         */
3360
        gen_update_nip(ctx, ctx->nip);
3361
#if defined(TARGET_PPC64)
3362
        if (!ctx->sf_mode)
3363
            gen_op_store_msr_32();
3364
        else
3365
#endif
3366
            gen_op_store_msr();
3367
        /* Must stop the translation as machine state (may have) changed */
3368
        /* Note that mtmsrd is not always defined as context-synchronizing */
3369
        ctx->exception = POWERPC_EXCP_STOP;
3370
    }
3371
#endif
3372
}
3373

    
3374
/* mtspr */
3375
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3376
{
3377
    void (*write_cb)(void *opaque, int sprn);
3378
    uint32_t sprn = SPR(ctx->opcode);
3379

    
3380
#if !defined(CONFIG_USER_ONLY)
3381
    if (ctx->supervisor == 2)
3382
        write_cb = ctx->spr_cb[sprn].hea_write;
3383
    else if (ctx->supervisor)
3384
        write_cb = ctx->spr_cb[sprn].oea_write;
3385
    else
3386
#endif
3387
        write_cb = ctx->spr_cb[sprn].uea_write;
3388
    if (likely(write_cb != NULL)) {
3389
        if (likely(write_cb != SPR_NOACCESS)) {
3390
            gen_op_load_gpr_T0(rS(ctx->opcode));
3391
            (*write_cb)(ctx, sprn);
3392
        } else {
3393
            /* Privilege exception */
3394
            if (loglevel != 0) {
3395
                fprintf(logfile, "Trying to write privileged spr %d %03x at "
3396
                        ADDRX "\n", sprn, sprn, ctx->nip);
3397
            }
3398
            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
3399
                   sprn, sprn, ctx->nip);
3400
            GEN_EXCP_PRIVREG(ctx);
3401
        }
3402
    } else {
3403
        /* Not defined */
3404
        if (loglevel != 0) {
3405
            fprintf(logfile, "Trying to write invalid spr %d %03x at "
3406
                    ADDRX "\n", sprn, sprn, ctx->nip);
3407
        }
3408
        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
3409
               sprn, sprn, ctx->nip);
3410
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3411
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3412
    }
3413
}
3414

    
3415
/***                         Cache management                              ***/
3416
/* dcbf */
3417
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3418
{
3419
    /* XXX: specification says this is treated as a load by the MMU */
3420
    gen_addr_reg_index(ctx);
3421
    op_ldst(lbz);
3422
}
3423

    
3424
/* dcbi (Supervisor only) */
3425
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3426
{
3427
#if defined(CONFIG_USER_ONLY)
3428
    GEN_EXCP_PRIVOPC(ctx);
3429
#else
3430
    if (unlikely(!ctx->supervisor)) {
3431
        GEN_EXCP_PRIVOPC(ctx);
3432
        return;
3433
    }
3434
    gen_addr_reg_index(ctx);
3435
    /* XXX: specification says this should be treated as a store by the MMU */
3436
    op_ldst(lbz);
3437
    op_ldst(stb);
3438
#endif
3439
}
3440

    
3441
/* dcdst */
3442
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3443
{
3444
    /* XXX: specification say this is treated as a load by the MMU */
3445
    gen_addr_reg_index(ctx);
3446
    op_ldst(lbz);
3447
}
3448

    
3449
/* dcbt */
3450
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3451
{
3452
    /* interpreted as no-op */
3453
    /* XXX: specification say this is treated as a load by the MMU
3454
     *      but does not generate any exception
3455
     */
3456
}
3457

    
3458
/* dcbtst */
3459
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3460
{
3461
    /* interpreted as no-op */
3462
    /* XXX: specification say this is treated as a load by the MMU
3463
     *      but does not generate any exception
3464
     */
3465
}
3466

    
3467
/* dcbz */
3468
#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
3469
static GenOpFunc *gen_op_dcbz[4][NB_MEM_FUNCS] = {
3470
    /* 32 bytes cache line size */
3471
    {
3472
#define gen_op_dcbz_l32_le_raw        gen_op_dcbz_l32_raw
3473
#define gen_op_dcbz_l32_le_user       gen_op_dcbz_l32_user
3474
#define gen_op_dcbz_l32_le_kernel     gen_op_dcbz_l32_kernel
3475
#define gen_op_dcbz_l32_le_hypv       gen_op_dcbz_l32_hypv
3476
#define gen_op_dcbz_l32_le_64_raw     gen_op_dcbz_l32_64_raw
3477
#define gen_op_dcbz_l32_le_64_user    gen_op_dcbz_l32_64_user
3478
#define gen_op_dcbz_l32_le_64_kernel  gen_op_dcbz_l32_64_kernel
3479
#define gen_op_dcbz_l32_le_64_hypv    gen_op_dcbz_l32_64_hypv
3480
        GEN_MEM_FUNCS(dcbz_l32),
3481
    },
3482
    /* 64 bytes cache line size */
3483
    {
3484
#define gen_op_dcbz_l64_le_raw        gen_op_dcbz_l64_raw
3485
#define gen_op_dcbz_l64_le_user       gen_op_dcbz_l64_user
3486
#define gen_op_dcbz_l64_le_kernel     gen_op_dcbz_l64_kernel
3487
#define gen_op_dcbz_l64_le_hypv       gen_op_dcbz_l64_hypv
3488
#define gen_op_dcbz_l64_le_64_raw     gen_op_dcbz_l64_64_raw
3489
#define gen_op_dcbz_l64_le_64_user    gen_op_dcbz_l64_64_user
3490
#define gen_op_dcbz_l64_le_64_kernel  gen_op_dcbz_l64_64_kernel
3491
#define gen_op_dcbz_l64_le_64_hypv    gen_op_dcbz_l64_64_hypv
3492
        GEN_MEM_FUNCS(dcbz_l64),
3493
    },
3494
    /* 128 bytes cache line size */
3495
    {
3496
#define gen_op_dcbz_l128_le_raw       gen_op_dcbz_l128_raw
3497
#define gen_op_dcbz_l128_le_user      gen_op_dcbz_l128_user
3498
#define gen_op_dcbz_l128_le_kernel    gen_op_dcbz_l128_kernel
3499
#define gen_op_dcbz_l128_le_hypv      gen_op_dcbz_l128_hypv
3500
#define gen_op_dcbz_l128_le_64_raw    gen_op_dcbz_l128_64_raw
3501
#define gen_op_dcbz_l128_le_64_user   gen_op_dcbz_l128_64_user
3502
#define gen_op_dcbz_l128_le_64_kernel gen_op_dcbz_l128_64_kernel
3503
#define gen_op_dcbz_l128_le_64_hypv   gen_op_dcbz_l128_64_hypv
3504
        GEN_MEM_FUNCS(dcbz_l128),
3505
    },
3506
    /* tunable cache line size */
3507
    {
3508
#define gen_op_dcbz_le_raw            gen_op_dcbz_raw
3509
#define gen_op_dcbz_le_user           gen_op_dcbz_user
3510
#define gen_op_dcbz_le_kernel         gen_op_dcbz_kernel
3511
#define gen_op_dcbz_le_hypv           gen_op_dcbz_hypv
3512
#define gen_op_dcbz_le_64_raw         gen_op_dcbz_64_raw
3513
#define gen_op_dcbz_le_64_user        gen_op_dcbz_64_user
3514
#define gen_op_dcbz_le_64_kernel      gen_op_dcbz_64_kernel
3515
#define gen_op_dcbz_le_64_hypv        gen_op_dcbz_64_hypv
3516
        GEN_MEM_FUNCS(dcbz),
3517
    },
3518
};
3519

    
3520
static always_inline void handler_dcbz (DisasContext *ctx,
3521
                                        int dcache_line_size)
3522
{
3523
    int n;
3524

    
3525
    switch (dcache_line_size) {
3526
    case 32:
3527
        n = 0;
3528
        break;
3529
    case 64:
3530
        n = 1;
3531
        break;
3532
    case 128:
3533
        n = 2;
3534
        break;
3535
    default:
3536
        n = 3;
3537
        break;
3538
    }
3539
    op_dcbz(n);
3540
}
3541

    
3542
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
3543
{
3544
    gen_addr_reg_index(ctx);
3545
    handler_dcbz(ctx, ctx->dcache_line_size);
3546
    gen_op_check_reservation();
3547
}
3548

    
3549
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
3550
{
3551
    gen_addr_reg_index(ctx);
3552
    if (ctx->opcode & 0x00200000)
3553
        handler_dcbz(ctx, ctx->dcache_line_size);
3554
    else
3555
        handler_dcbz(ctx, -1);
3556
    gen_op_check_reservation();
3557
}
3558

    
3559
/* icbi */
3560
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3561
#define gen_op_icbi_le_raw       gen_op_icbi_raw
3562
#define gen_op_icbi_le_user      gen_op_icbi_user
3563
#define gen_op_icbi_le_kernel    gen_op_icbi_kernel
3564
#define gen_op_icbi_le_hypv      gen_op_icbi_hypv
3565
#define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
3566
#define gen_op_icbi_le_64_user   gen_op_icbi_64_user
3567
#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
3568
#define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
3569
static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
3570
    GEN_MEM_FUNCS(icbi),
3571
};
3572

    
3573
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
3574
{
3575
    /* NIP cannot be restored if the memory exception comes from an helper */
3576
    gen_update_nip(ctx, ctx->nip - 4);
3577
    gen_addr_reg_index(ctx);
3578
    op_icbi();
3579
}
3580

    
3581
/* Optional: */
3582
/* dcba */
3583
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3584
{
3585
    /* interpreted as no-op */
3586
    /* XXX: specification say this is treated as a store by the MMU
3587
     *      but does not generate any exception
3588
     */
3589
}
3590

    
3591
/***                    Segment register manipulation                      ***/
3592
/* Supervisor only: */
3593
/* mfsr */
3594
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3595
{
3596
#if defined(CONFIG_USER_ONLY)
3597
    GEN_EXCP_PRIVREG(ctx);
3598
#else
3599
    if (unlikely(!ctx->supervisor)) {
3600
        GEN_EXCP_PRIVREG(ctx);
3601
        return;
3602
    }
3603
    gen_op_set_T1(SR(ctx->opcode));
3604
    gen_op_load_sr();
3605
    gen_op_store_T0_gpr(rD(ctx->opcode));
3606
#endif
3607
}
3608

    
3609
/* mfsrin */
3610
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3611
{
3612
#if defined(CONFIG_USER_ONLY)
3613
    GEN_EXCP_PRIVREG(ctx);
3614
#else
3615
    if (unlikely(!ctx->supervisor)) {
3616
        GEN_EXCP_PRIVREG(ctx);
3617
        return;
3618
    }
3619
    gen_op_load_gpr_T1(rB(ctx->opcode));
3620
    gen_op_srli_T1(28);
3621
    gen_op_load_sr();
3622
    gen_op_store_T0_gpr(rD(ctx->opcode));
3623
#endif
3624
}
3625

    
3626
/* mtsr */
3627
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3628
{
3629
#if defined(CONFIG_USER_ONLY)
3630
    GEN_EXCP_PRIVREG(ctx);
3631
#else
3632
    if (unlikely(!ctx->supervisor)) {
3633
        GEN_EXCP_PRIVREG(ctx);
3634
        return;
3635
    }
3636
    gen_op_load_gpr_T0(rS(ctx->opcode));
3637
    gen_op_set_T1(SR(ctx->opcode));
3638
    gen_op_store_sr();
3639
#endif
3640
}
3641

    
3642
/* mtsrin */
3643
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3644
{
3645
#if defined(CONFIG_USER_ONLY)
3646
    GEN_EXCP_PRIVREG(ctx);
3647
#else
3648
    if (unlikely(!ctx->supervisor)) {
3649
        GEN_EXCP_PRIVREG(ctx);
3650
        return;
3651
    }
3652
    gen_op_load_gpr_T0(rS(ctx->opcode));
3653
    gen_op_load_gpr_T1(rB(ctx->opcode));
3654
    gen_op_srli_T1(28);
3655
    gen_op_store_sr();
3656
#endif
3657
}
3658

    
3659
#if defined(TARGET_PPC64)
3660
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
3661
/* mfsr */
3662
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
3663
{
3664
#if defined(CONFIG_USER_ONLY)
3665
    GEN_EXCP_PRIVREG(ctx);
3666
#else
3667
    if (unlikely(!ctx->supervisor)) {
3668
        GEN_EXCP_PRIVREG(ctx);
3669
        return;
3670
    }
3671
    gen_op_set_T1(SR(ctx->opcode));
3672
    gen_op_load_slb();
3673
    gen_op_store_T0_gpr(rD(ctx->opcode));
3674
#endif
3675
}
3676

    
3677
/* mfsrin */
3678
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
3679
             PPC_SEGMENT_64B)
3680
{
3681
#if defined(CONFIG_USER_ONLY)
3682
    GEN_EXCP_PRIVREG(ctx);
3683
#else
3684
    if (unlikely(!ctx->supervisor)) {
3685
        GEN_EXCP_PRIVREG(ctx);
3686
        return;
3687
    }
3688
    gen_op_load_gpr_T1(rB(ctx->opcode));
3689
    gen_op_srli_T1(28);
3690
    gen_op_load_slb();
3691
    gen_op_store_T0_gpr(rD(ctx->opcode));
3692
#endif
3693
}
3694

    
3695
/* mtsr */
3696
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
3697
{
3698
#if defined(CONFIG_USER_ONLY)
3699
    GEN_EXCP_PRIVREG(ctx);
3700
#else
3701
    if (unlikely(!ctx->supervisor)) {
3702
        GEN_EXCP_PRIVREG(ctx);
3703
        return;
3704
    }
3705
    gen_op_load_gpr_T0(rS(ctx->opcode));
3706
    gen_op_set_T1(SR(ctx->opcode));
3707
    gen_op_store_slb();
3708
#endif
3709
}
3710

    
3711
/* mtsrin */
3712
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
3713
             PPC_SEGMENT_64B)
3714
{
3715
#if defined(CONFIG_USER_ONLY)
3716
    GEN_EXCP_PRIVREG(ctx);
3717
#else
3718
    if (unlikely(!ctx->supervisor)) {
3719
        GEN_EXCP_PRIVREG(ctx);
3720
        return;
3721
    }
3722
    gen_op_load_gpr_T0(rS(ctx->opcode));
3723
    gen_op_load_gpr_T1(rB(ctx->opcode));
3724
    gen_op_srli_T1(28);
3725
    gen_op_store_slb();
3726
#endif
3727
}
3728
#endif /* defined(TARGET_PPC64) */
3729

    
3730
/***                      Lookaside buffer management                      ***/
3731
/* Optional & supervisor only: */
3732
/* tlbia */
3733
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3734
{
3735
#if defined(CONFIG_USER_ONLY)
3736
    GEN_EXCP_PRIVOPC(ctx);
3737
#else
3738
    if (unlikely(!ctx->supervisor)) {
3739
        GEN_EXCP_PRIVOPC(ctx);
3740
        return;
3741
    }
3742
    gen_op_tlbia();
3743
#endif
3744
}
3745

    
3746
/* tlbie */
3747
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3748
{
3749
#if defined(CONFIG_USER_ONLY)
3750
    GEN_EXCP_PRIVOPC(ctx);
3751
#else
3752
    if (unlikely(!ctx->supervisor)) {
3753
        GEN_EXCP_PRIVOPC(ctx);
3754
        return;
3755
    }
3756
    gen_op_load_gpr_T0(rB(ctx->opcode));
3757
#if defined(TARGET_PPC64)
3758
    if (ctx->sf_mode)
3759
        gen_op_tlbie_64();
3760
    else
3761
#endif
3762
        gen_op_tlbie();
3763
#endif
3764
}
3765

    
3766
/* tlbsync */
3767
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3768
{
3769
#if defined(CONFIG_USER_ONLY)
3770
    GEN_EXCP_PRIVOPC(ctx);
3771
#else
3772
    if (unlikely(!ctx->supervisor)) {
3773
        GEN_EXCP_PRIVOPC(ctx);
3774
        return;
3775
    }
3776
    /* This has no effect: it should ensure that all previous
3777
     * tlbie have completed
3778
     */
3779
    GEN_STOP(ctx);
3780
#endif
3781
}
3782

    
3783
#if defined(TARGET_PPC64)
3784
/* slbia */
3785
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3786
{
3787
#if defined(CONFIG_USER_ONLY)
3788
    GEN_EXCP_PRIVOPC(ctx);
3789
#else
3790
    if (unlikely(!ctx->supervisor)) {
3791
        GEN_EXCP_PRIVOPC(ctx);
3792
        return;
3793
    }
3794
    gen_op_slbia();
3795
#endif
3796
}
3797

    
3798
/* slbie */
3799
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3800
{
3801
#if defined(CONFIG_USER_ONLY)
3802
    GEN_EXCP_PRIVOPC(ctx);
3803
#else
3804
    if (unlikely(!ctx->supervisor)) {
3805
        GEN_EXCP_PRIVOPC(ctx);
3806
        return;
3807
    }
3808
    gen_op_load_gpr_T0(rB(ctx->opcode));
3809
    gen_op_slbie();
3810
#endif
3811
}
3812
#endif
3813

    
3814
/***                              External control                         ***/
3815
/* Optional: */
3816
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3817
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3818
static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
3819
    GEN_MEM_FUNCS(eciwx),
3820
};
3821
static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
3822
    GEN_MEM_FUNCS(ecowx),
3823
};
3824

    
3825
/* eciwx */
3826
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3827
{
3828
    /* Should check EAR[E] & alignment ! */
3829
    gen_addr_reg_index(ctx);
3830
    op_eciwx();
3831
    gen_op_store_T0_gpr(rD(ctx->opcode));
3832
}
3833

    
3834
/* ecowx */
3835
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3836
{
3837
    /* Should check EAR[E] & alignment ! */
3838
    gen_addr_reg_index(ctx);
3839
    gen_op_load_gpr_T1(rS(ctx->opcode));
3840
    op_ecowx();
3841
}
3842

    
3843
/* PowerPC 601 specific instructions */
3844
/* abs - abs. */
3845
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3846
{
3847
    gen_op_load_gpr_T0(rA(ctx->opcode));
3848
    gen_op_POWER_abs();
3849
    gen_op_store_T0_gpr(rD(ctx->opcode));
3850
    if (unlikely(Rc(ctx->opcode) != 0))
3851
        gen_set_Rc0(ctx);
3852
}
3853

    
3854
/* abso - abso. */
3855
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3856
{
3857
    gen_op_load_gpr_T0(rA(ctx->opcode));
3858
    gen_op_POWER_abso();
3859
    gen_op_store_T0_gpr(rD(ctx->opcode));
3860
    if (unlikely(Rc(ctx->opcode) != 0))
3861
        gen_set_Rc0(ctx);
3862
}
3863

    
3864
/* clcs */
3865
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3866
{
3867
    gen_op_load_gpr_T0(rA(ctx->opcode));
3868
    gen_op_POWER_clcs();
3869
    /* Rc=1 sets CR0 to an undefined state */
3870
    gen_op_store_T0_gpr(rD(ctx->opcode));
3871
}
3872

    
3873
/* div - div. */
3874
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3875
{
3876
    gen_op_load_gpr_T0(rA(ctx->opcode));
3877
    gen_op_load_gpr_T1(rB(ctx->opcode));
3878
    gen_op_POWER_div();
3879
    gen_op_store_T0_gpr(rD(ctx->opcode));
3880
    if (unlikely(Rc(ctx->opcode) != 0))
3881
        gen_set_Rc0(ctx);
3882
}
3883

    
3884
/* divo - divo. */
3885
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3886
{
3887
    gen_op_load_gpr_T0(rA(ctx->opcode));
3888
    gen_op_load_gpr_T1(rB(ctx->opcode));
3889
    gen_op_POWER_divo();
3890
    gen_op_store_T0_gpr(rD(ctx->opcode));
3891
    if (unlikely(Rc(ctx->opcode) != 0))
3892
        gen_set_Rc0(ctx);
3893
}
3894

    
3895
/* divs - divs. */
3896
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3897
{
3898
    gen_op_load_gpr_T0(rA(ctx->opcode));
3899
    gen_op_load_gpr_T1(rB(ctx->opcode));
3900
    gen_op_POWER_divs();
3901
    gen_op_store_T0_gpr(rD(ctx->opcode));
3902
    if (unlikely(Rc(ctx->opcode) != 0))
3903
        gen_set_Rc0(ctx);
3904
}
3905

    
3906
/* divso - divso. */
3907
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3908
{
3909
    gen_op_load_gpr_T0(rA(ctx->opcode));
3910
    gen_op_load_gpr_T1(rB(ctx->opcode));
3911
    gen_op_POWER_divso();
3912
    gen_op_store_T0_gpr(rD(ctx->opcode));
3913
    if (unlikely(Rc(ctx->opcode) != 0))
3914
        gen_set_Rc0(ctx);
3915
}
3916

    
3917
/* doz - doz. */
3918
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3919
{
3920
    gen_op_load_gpr_T0(rA(ctx->opcode));
3921
    gen_op_load_gpr_T1(rB(ctx->opcode));
3922
    gen_op_POWER_doz();
3923
    gen_op_store_T0_gpr(rD(ctx->opcode));
3924
    if (unlikely(Rc(ctx->opcode) != 0))
3925
        gen_set_Rc0(ctx);
3926
}
3927

    
3928
/* dozo - dozo. */
3929
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3930
{
3931
    gen_op_load_gpr_T0(rA(ctx->opcode));
3932
    gen_op_load_gpr_T1(rB(ctx->opcode));
3933
    gen_op_POWER_dozo();
3934
    gen_op_store_T0_gpr(rD(ctx->opcode));
3935
    if (unlikely(Rc(ctx->opcode) != 0))
3936
        gen_set_Rc0(ctx);
3937
}
3938

    
3939
/* dozi */
3940
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3941
{
3942
    gen_op_load_gpr_T0(rA(ctx->opcode));
3943
    gen_op_set_T1(SIMM(ctx->opcode));
3944
    gen_op_POWER_doz();
3945
    gen_op_store_T0_gpr(rD(ctx->opcode));
3946
}
3947

    
3948
/* As lscbx load from memory byte after byte, it's always endian safe.
3949
 * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones
3950
 */
3951
#define op_POWER_lscbx(start, ra, rb)                                         \
3952
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3953
#define gen_op_POWER_lscbx_64_raw       gen_op_POWER_lscbx_raw
3954
#define gen_op_POWER_lscbx_64_user      gen_op_POWER_lscbx_user
3955
#define gen_op_POWER_lscbx_64_kernel    gen_op_POWER_lscbx_kernel
3956
#define gen_op_POWER_lscbx_64_hypv      gen_op_POWER_lscbx_hypv
3957
#define gen_op_POWER_lscbx_le_raw       gen_op_POWER_lscbx_raw
3958
#define gen_op_POWER_lscbx_le_user      gen_op_POWER_lscbx_user
3959
#define gen_op_POWER_lscbx_le_kernel    gen_op_POWER_lscbx_kernel
3960
#define gen_op_POWER_lscbx_le_hypv      gen_op_POWER_lscbx_hypv
3961
#define gen_op_POWER_lscbx_le_64_raw    gen_op_POWER_lscbx_raw
3962
#define gen_op_POWER_lscbx_le_64_user   gen_op_POWER_lscbx_user
3963
#define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel
3964
#define gen_op_POWER_lscbx_le_64_hypv   gen_op_POWER_lscbx_hypv
3965
static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = {
3966
    GEN_MEM_FUNCS(POWER_lscbx),
3967
};
3968

    
3969
/* lscbx - lscbx. */
3970
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3971
{
3972
    int ra = rA(ctx->opcode);
3973
    int rb = rB(ctx->opcode);
3974

    
3975
    gen_addr_reg_index(ctx);
3976
    if (ra == 0) {
3977
        ra = rb;
3978
    }
3979
    /* NIP cannot be restored if the memory exception comes from an helper */
3980
    gen_update_nip(ctx, ctx->nip - 4);
3981
    gen_op_load_xer_bc();
3982
    gen_op_load_xer_cmp();
3983
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3984
    gen_op_store_xer_bc();
3985
    if (unlikely(Rc(ctx->opcode) != 0))
3986
        gen_set_Rc0(ctx);
3987
}
3988

    
3989
/* maskg - maskg. */
3990
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3991
{
3992
    gen_op_load_gpr_T0(rS(ctx->opcode));
3993
    gen_op_load_gpr_T1(rB(ctx->opcode));
3994
    gen_op_POWER_maskg();
3995
    gen_op_store_T0_gpr(rA(ctx->opcode));
3996
    if (unlikely(Rc(ctx->opcode) != 0))
3997
        gen_set_Rc0(ctx);
3998
}
3999

    
4000
/* maskir - maskir. */
4001
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4002
{
4003
    gen_op_load_gpr_T0(rA(ctx->opcode));
4004
    gen_op_load_gpr_T1(rS(ctx->opcode));
4005
    gen_op_load_gpr_T2(rB(ctx->opcode));
4006
    gen_op_POWER_maskir();
4007
    gen_op_store_T0_gpr(rA(ctx->opcode));
4008
    if (unlikely(Rc(ctx->opcode) != 0))
4009
        gen_set_Rc0(ctx);
4010
}
4011

    
4012
/* mul - mul. */
4013
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4014
{
4015
    gen_op_load_gpr_T0(rA(ctx->opcode));
4016
    gen_op_load_gpr_T1(rB(ctx->opcode));
4017
    gen_op_POWER_mul();
4018
    gen_op_store_T0_gpr(rD(ctx->opcode));
4019
    if (unlikely(Rc(ctx->opcode) != 0))
4020
        gen_set_Rc0(ctx);
4021
}
4022

    
4023
/* mulo - mulo. */
4024
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4025
{
4026
    gen_op_load_gpr_T0(rA(ctx->opcode));
4027
    gen_op_load_gpr_T1(rB(ctx->opcode));
4028
    gen_op_POWER_mulo();
4029
    gen_op_store_T0_gpr(rD(ctx->opcode));
4030
    if (unlikely(Rc(ctx->opcode) != 0))
4031
        gen_set_Rc0(ctx);
4032
}
4033

    
4034
/* nabs - nabs. */
4035
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4036
{
4037
    gen_op_load_gpr_T0(rA(ctx->opcode));
4038
    gen_op_POWER_nabs();
4039
    gen_op_store_T0_gpr(rD(ctx->opcode));
4040
    if (unlikely(Rc(ctx->opcode) != 0))
4041
        gen_set_Rc0(ctx);
4042
}
4043

    
4044
/* nabso - nabso. */
4045
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4046
{
4047
    gen_op_load_gpr_T0(rA(ctx->opcode));
4048
    gen_op_POWER_nabso();
4049
    gen_op_store_T0_gpr(rD(ctx->opcode));
4050
    if (unlikely(Rc(ctx->opcode) != 0))
4051
        gen_set_Rc0(ctx);
4052
}
4053

    
4054
/* rlmi - rlmi. */
4055
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4056
{
4057
    uint32_t mb, me;
4058

    
4059
    mb = MB(ctx->opcode);
4060
    me = ME(ctx->opcode);
4061
    gen_op_load_gpr_T0(rS(ctx->opcode));
4062
    gen_op_load_gpr_T1(rA(ctx->opcode));
4063
    gen_op_load_gpr_T2(rB(ctx->opcode));
4064
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4065
    gen_op_store_T0_gpr(rA(ctx->opcode));
4066
    if (unlikely(Rc(ctx->opcode) != 0))
4067
        gen_set_Rc0(ctx);
4068
}
4069

    
4070
/* rrib - rrib. */
4071
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4072
{
4073
    gen_op_load_gpr_T0(rS(ctx->opcode));
4074
    gen_op_load_gpr_T1(rA(ctx->opcode));
4075
    gen_op_load_gpr_T2(rB(ctx->opcode));
4076
    gen_op_POWER_rrib();
4077
    gen_op_store_T0_gpr(rA(ctx->opcode));
4078
    if (unlikely(Rc(ctx->opcode) != 0))
4079
        gen_set_Rc0(ctx);
4080
}
4081

    
4082
/* sle - sle. */
4083
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4084
{
4085
    gen_op_load_gpr_T0(rS(ctx->opcode));
4086
    gen_op_load_gpr_T1(rB(ctx->opcode));
4087
    gen_op_POWER_sle();
4088
    gen_op_store_T0_gpr(rA(ctx->opcode));
4089
    if (unlikely(Rc(ctx->opcode) != 0))
4090
        gen_set_Rc0(ctx);
4091
}
4092

    
4093
/* sleq - sleq. */
4094
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4095
{
4096
    gen_op_load_gpr_T0(rS(ctx->opcode));
4097
    gen_op_load_gpr_T1(rB(ctx->opcode));
4098
    gen_op_POWER_sleq();
4099
    gen_op_store_T0_gpr(rA(ctx->opcode));
4100
    if (unlikely(Rc(ctx->opcode) != 0))
4101
        gen_set_Rc0(ctx);
4102
}
4103

    
4104
/* sliq - sliq. */
4105
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4106
{
4107
    gen_op_load_gpr_T0(rS(ctx->opcode));
4108
    gen_op_set_T1(SH(ctx->opcode));
4109
    gen_op_POWER_sle();
4110
    gen_op_store_T0_gpr(rA(ctx->opcode));
4111
    if (unlikely(Rc(ctx->opcode) != 0))
4112
        gen_set_Rc0(ctx);
4113
}
4114

    
4115
/* slliq - slliq. */
4116
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4117
{
4118
    gen_op_load_gpr_T0(rS(ctx->opcode));
4119
    gen_op_set_T1(SH(ctx->opcode));
4120
    gen_op_POWER_sleq();
4121
    gen_op_store_T0_gpr(rA(ctx->opcode));
4122
    if (unlikely(Rc(ctx->opcode) != 0))
4123
        gen_set_Rc0(ctx);
4124
}
4125

    
4126
/* sllq - sllq. */
4127
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4128
{
4129
    gen_op_load_gpr_T0(rS(ctx->opcode));
4130
    gen_op_load_gpr_T1(rB(ctx->opcode));
4131
    gen_op_POWER_sllq();
4132
    gen_op_store_T0_gpr(rA(ctx->opcode));
4133
    if (unlikely(Rc(ctx->opcode) != 0))
4134
        gen_set_Rc0(ctx);
4135
}
4136

    
4137
/* slq - slq. */
4138
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4139
{
4140
    gen_op_load_gpr_T0(rS(ctx->opcode));
4141
    gen_op_load_gpr_T1(rB(ctx->opcode));
4142
    gen_op_POWER_slq();
4143
    gen_op_store_T0_gpr(rA(ctx->opcode));
4144
    if (unlikely(Rc(ctx->opcode) != 0))
4145
        gen_set_Rc0(ctx);
4146
}
4147

    
4148
/* sraiq - sraiq. */
4149
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4150
{
4151
    gen_op_load_gpr_T0(rS(ctx->opcode));
4152
    gen_op_set_T1(SH(ctx->opcode));
4153
    gen_op_POWER_sraq();
4154
    gen_op_store_T0_gpr(rA(ctx->opcode));
4155
    if (unlikely(Rc(ctx->opcode) != 0))
4156
        gen_set_Rc0(ctx);
4157
}
4158

    
4159
/* sraq - sraq. */
4160
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4161
{
4162
    gen_op_load_gpr_T0(rS(ctx->opcode));
4163
    gen_op_load_gpr_T1(rB(ctx->opcode));
4164
    gen_op_POWER_sraq();
4165
    gen_op_store_T0_gpr(rA(ctx->opcode));
4166
    if (unlikely(Rc(ctx->opcode) != 0))
4167
        gen_set_Rc0(ctx);
4168
}
4169

    
4170
/* sre - sre. */
4171
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4172
{
4173
    gen_op_load_gpr_T0(rS(ctx->opcode));
4174
    gen_op_load_gpr_T1(rB(ctx->opcode));
4175
    gen_op_POWER_sre();
4176
    gen_op_store_T0_gpr(rA(ctx->opcode));
4177
    if (unlikely(Rc(ctx->opcode) != 0))
4178
        gen_set_Rc0(ctx);
4179
}
4180

    
4181
/* srea - srea. */
4182
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4183
{
4184
    gen_op_load_gpr_T0(rS(ctx->opcode));
4185
    gen_op_load_gpr_T1(rB(ctx->opcode));
4186
    gen_op_POWER_srea();
4187
    gen_op_store_T0_gpr(rA(ctx->opcode));
4188
    if (unlikely(Rc(ctx->opcode) != 0))
4189
        gen_set_Rc0(ctx);
4190
}
4191

    
4192
/* sreq */
4193
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4194
{
4195
    gen_op_load_gpr_T0(rS(ctx->opcode));
4196
    gen_op_load_gpr_T1(rB(ctx->opcode));
4197
    gen_op_POWER_sreq();
4198
    gen_op_store_T0_gpr(rA(ctx->opcode));
4199
    if (unlikely(Rc(ctx->opcode) != 0))
4200
        gen_set_Rc0(ctx);
4201
}
4202

    
4203
/* sriq */
4204
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4205
{
4206
    gen_op_load_gpr_T0(rS(ctx->opcode));
4207
    gen_op_set_T1(SH(ctx->opcode));
4208
    gen_op_POWER_srq();
4209
    gen_op_store_T0_gpr(rA(ctx->opcode));
4210
    if (unlikely(Rc(ctx->opcode) != 0))
4211
        gen_set_Rc0(ctx);
4212
}
4213

    
4214
/* srliq */
4215
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4216
{
4217
    gen_op_load_gpr_T0(rS(ctx->opcode));
4218
    gen_op_load_gpr_T1(rB(ctx->opcode));
4219
    gen_op_set_T1(SH(ctx->opcode));
4220
    gen_op_POWER_srlq();
4221
    gen_op_store_T0_gpr(rA(ctx->opcode));
4222
    if (unlikely(Rc(ctx->opcode) != 0))
4223
        gen_set_Rc0(ctx);
4224
}
4225

    
4226
/* srlq */
4227
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4228
{
4229
    gen_op_load_gpr_T0(rS(ctx->opcode));
4230
    gen_op_load_gpr_T1(rB(ctx->opcode));
4231
    gen_op_POWER_srlq();
4232
    gen_op_store_T0_gpr(rA(ctx->opcode));
4233
    if (unlikely(Rc(ctx->opcode) != 0))
4234
        gen_set_Rc0(ctx);
4235
}
4236

    
4237
/* srq */
4238
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4239
{
4240
    gen_op_load_gpr_T0(rS(ctx->opcode));
4241
    gen_op_load_gpr_T1(rB(ctx->opcode));
4242
    gen_op_POWER_srq();
4243
    gen_op_store_T0_gpr(rA(ctx->opcode));
4244
    if (unlikely(Rc(ctx->opcode) != 0))
4245
        gen_set_Rc0(ctx);
4246
}
4247

    
4248
/* PowerPC 602 specific instructions */
4249
/* dsa  */
4250
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4251
{
4252
    /* XXX: TODO */
4253
    GEN_EXCP_INVAL(ctx);
4254
}
4255

    
4256
/* esa */
4257
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4258
{
4259
    /* XXX: TODO */
4260
    GEN_EXCP_INVAL(ctx);
4261
}
4262

    
4263
/* mfrom */
4264
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4265
{
4266
#if defined(CONFIG_USER_ONLY)
4267
    GEN_EXCP_PRIVOPC(ctx);
4268
#else
4269
    if (unlikely(!ctx->supervisor)) {
4270
        GEN_EXCP_PRIVOPC(ctx);
4271
        return;
4272
    }
4273
    gen_op_load_gpr_T0(rA(ctx->opcode));
4274
    gen_op_602_mfrom();
4275
    gen_op_store_T0_gpr(rD(ctx->opcode));
4276
#endif
4277
}
4278

    
4279
/* 602 - 603 - G2 TLB management */
4280
/* tlbld */
4281
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4282
{
4283
#if defined(CONFIG_USER_ONLY)
4284
    GEN_EXCP_PRIVOPC(ctx);
4285
#else
4286
    if (unlikely(!ctx->supervisor)) {
4287
        GEN_EXCP_PRIVOPC(ctx);
4288
        return;
4289
    }
4290
    gen_op_load_gpr_T0(rB(ctx->opcode));
4291
    gen_op_6xx_tlbld();
4292
#endif
4293
}
4294

    
4295
/* tlbli */
4296
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4297
{
4298
#if defined(CONFIG_USER_ONLY)
4299
    GEN_EXCP_PRIVOPC(ctx);
4300
#else
4301
    if (unlikely(!ctx->supervisor)) {
4302
        GEN_EXCP_PRIVOPC(ctx);
4303
        return;
4304
    }
4305
    gen_op_load_gpr_T0(rB(ctx->opcode));
4306
    gen_op_6xx_tlbli();
4307
#endif
4308
}
4309

    
4310
/* 74xx TLB management */
4311
/* tlbld */
4312
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4313
{
4314
#if defined(CONFIG_USER_ONLY)
4315
    GEN_EXCP_PRIVOPC(ctx);
4316
#else
4317
    if (unlikely(!ctx->supervisor)) {
4318
        GEN_EXCP_PRIVOPC(ctx);
4319
        return;
4320
    }
4321
    gen_op_load_gpr_T0(rB(ctx->opcode));
4322
    gen_op_74xx_tlbld();
4323
#endif
4324
}
4325

    
4326
/* tlbli */
4327
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4328
{
4329
#if defined(CONFIG_USER_ONLY)
4330
    GEN_EXCP_PRIVOPC(ctx);
4331
#else
4332
    if (unlikely(!ctx->supervisor)) {
4333
        GEN_EXCP_PRIVOPC(ctx);
4334
        return;
4335
    }
4336
    gen_op_load_gpr_T0(rB(ctx->opcode));
4337
    gen_op_74xx_tlbli();
4338
#endif
4339
}
4340

    
4341
/* POWER instructions not in PowerPC 601 */
4342
/* clf */
4343
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4344
{
4345
    /* Cache line flush: implemented as no-op */
4346
}
4347

    
4348
/* cli */
4349
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4350
{
4351
    /* Cache line invalidate: privileged and treated as no-op */
4352
#if defined(CONFIG_USER_ONLY)
4353
    GEN_EXCP_PRIVOPC(ctx);
4354
#else
4355
    if (unlikely(!ctx->supervisor)) {
4356
        GEN_EXCP_PRIVOPC(ctx);
4357
        return;
4358
    }
4359
#endif
4360
}
4361

    
4362
/* dclst */
4363
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4364
{
4365
    /* Data cache line store: treated as no-op */
4366
}
4367

    
4368
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4369
{
4370
#if defined(CONFIG_USER_ONLY)
4371
    GEN_EXCP_PRIVOPC(ctx);
4372
#else
4373
    if (unlikely(!ctx->supervisor)) {
4374
        GEN_EXCP_PRIVOPC(ctx);
4375
        return;
4376
    }
4377
    int ra = rA(ctx->opcode);
4378
    int rd = rD(ctx->opcode);
4379

    
4380
    gen_addr_reg_index(ctx);
4381
    gen_op_POWER_mfsri();
4382
    gen_op_store_T0_gpr(rd);
4383
    if (ra != 0 && ra != rd)
4384
        gen_op_store_T1_gpr(ra);
4385
#endif
4386
}
4387

    
4388
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4389
{
4390
#if defined(CONFIG_USER_ONLY)
4391
    GEN_EXCP_PRIVOPC(ctx);
4392
#else
4393
    if (unlikely(!ctx->supervisor)) {
4394
        GEN_EXCP_PRIVOPC(ctx);
4395
        return;
4396
    }
4397
    gen_addr_reg_index(ctx);
4398
    gen_op_POWER_rac();
4399
    gen_op_store_T0_gpr(rD(ctx->opcode));
4400
#endif
4401
}
4402

    
4403
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4404
{
4405
#if defined(CONFIG_USER_ONLY)
4406
    GEN_EXCP_PRIVOPC(ctx);
4407
#else
4408
    if (unlikely(!ctx->supervisor)) {
4409
        GEN_EXCP_PRIVOPC(ctx);
4410
        return;
4411
    }
4412
    gen_op_POWER_rfsvc();
4413
    GEN_SYNC(ctx);
4414
#endif
4415
}
4416

    
4417
/* svc is not implemented for now */
4418

    
4419
/* POWER2 specific instructions */
4420
/* Quad manipulation (load/store two floats at a time) */
4421
/* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
4422
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4423
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4424
#define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
4425
#define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
4426
#define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
4427
#define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
4428
#define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
4429
#define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
4430
#define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
4431
#define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
4432
#define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
4433
#define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
4434
#define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
4435
#define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
4436
#define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
4437
#define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
4438
#define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
4439
#define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
4440
static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
4441
    GEN_MEM_FUNCS(POWER2_lfq),
4442
};
4443
static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
4444
    GEN_MEM_FUNCS(POWER2_stfq),
4445
};
4446

    
4447
/* lfq */
4448
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4449
{
4450
    /* NIP cannot be restored if the memory exception comes from an helper */
4451
    gen_update_nip(ctx, ctx->nip - 4);
4452
    gen_addr_imm_index(ctx, 0);
4453
    op_POWER2_lfq();
4454
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4455
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4456
}
4457

    
4458
/* lfqu */
4459
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4460
{
4461
    int ra = rA(ctx->opcode);
4462

    
4463
    /* NIP cannot be restored if the memory exception comes from an helper */
4464
    gen_update_nip(ctx, ctx->nip - 4);
4465
    gen_addr_imm_index(ctx, 0);
4466
    op_POWER2_lfq();
4467
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4468
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4469
    if (ra != 0)
4470
        gen_op_store_T0_gpr(ra);
4471
}
4472

    
4473
/* lfqux */
4474
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4475
{
4476
    int ra = rA(ctx->opcode);
4477

    
4478
    /* NIP cannot be restored if the memory exception comes from an helper */
4479
    gen_update_nip(ctx, ctx->nip - 4);
4480
    gen_addr_reg_index(ctx);
4481
    op_POWER2_lfq();
4482
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4483
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4484
    if (ra != 0)
4485
        gen_op_store_T0_gpr(ra);
4486
}
4487

    
4488
/* lfqx */
4489
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4490
{
4491
    /* NIP cannot be restored if the memory exception comes from an helper */
4492
    gen_update_nip(ctx, ctx->nip - 4);
4493
    gen_addr_reg_index(ctx);
4494
    op_POWER2_lfq();
4495
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4496
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4497
}
4498

    
4499
/* stfq */
4500
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4501
{
4502
    /* NIP cannot be restored if the memory exception comes from an helper */
4503
    gen_update_nip(ctx, ctx->nip - 4);
4504
    gen_addr_imm_index(ctx, 0);
4505
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4506
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4507
    op_POWER2_stfq();
4508
}
4509

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

    
4515
    /* NIP cannot be restored if the memory exception comes from an helper */
4516
    gen_update_nip(ctx, ctx->nip - 4);
4517
    gen_addr_imm_index(ctx, 0);
4518
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4519
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4520
    op_POWER2_stfq();
4521
    if (ra != 0)
4522
        gen_op_store_T0_gpr(ra);
4523
}
4524

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

    
4530
    /* NIP cannot be restored if the memory exception comes from an helper */
4531
    gen_update_nip(ctx, ctx->nip - 4);
4532
    gen_addr_reg_index(ctx);
4533
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4534
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4535
    op_POWER2_stfq();
4536
    if (ra != 0)
4537
        gen_op_store_T0_gpr(ra);
4538
}
4539

    
4540
/* stfqx */
4541
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4542
{
4543
    /* NIP cannot be restored if the memory exception comes from an helper */
4544
    gen_update_nip(ctx, ctx->nip - 4);
4545
    gen_addr_reg_index(ctx);
4546
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4547
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4548
    op_POWER2_stfq();
4549
}
4550

    
4551
/* BookE specific instructions */
4552
/* XXX: not implemented on 440 ? */
4553
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
4554
{
4555
    /* XXX: TODO */
4556
    GEN_EXCP_INVAL(ctx);
4557
}
4558

    
4559
/* XXX: not implemented on 440 ? */
4560
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
4561
{
4562
#if defined(CONFIG_USER_ONLY)
4563
    GEN_EXCP_PRIVOPC(ctx);
4564
#else
4565
    if (unlikely(!ctx->supervisor)) {
4566
        GEN_EXCP_PRIVOPC(ctx);
4567
        return;
4568
    }
4569
    gen_addr_reg_index(ctx);
4570
    /* Use the same micro-ops as for tlbie */
4571
#if defined(TARGET_PPC64)
4572
    if (ctx->sf_mode)
4573
        gen_op_tlbie_64();
4574
    else
4575
#endif
4576
        gen_op_tlbie();
4577
#endif
4578
}
4579

    
4580
/* All 405 MAC instructions are translated here */
4581
static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
4582
                                                int opc2, int opc3,
4583
                                                int ra, int rb, int rt, int Rc)
4584
{
4585
    gen_op_load_gpr_T0(ra);
4586
    gen_op_load_gpr_T1(rb);
4587
    switch (opc3 & 0x0D) {
4588
    case 0x05:
4589
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4590
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4591
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4592
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4593
        /* mulchw - mulchw. */
4594
        gen_op_405_mulchw();
4595
        break;
4596
    case 0x04:
4597
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4598
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4599
        /* mulchwu - mulchwu. */
4600
        gen_op_405_mulchwu();
4601
        break;
4602
    case 0x01:
4603
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4604
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4605
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4606
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4607
        /* mulhhw - mulhhw. */
4608
        gen_op_405_mulhhw();
4609
        break;
4610
    case 0x00:
4611
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4612
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4613
        /* mulhhwu - mulhhwu. */
4614
        gen_op_405_mulhhwu();
4615
        break;
4616
    case 0x0D:
4617
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4618
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4619
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4620
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4621
        /* mullhw - mullhw. */
4622
        gen_op_405_mullhw();
4623
        break;
4624
    case 0x0C:
4625
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4626
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4627
        /* mullhwu - mullhwu. */
4628
        gen_op_405_mullhwu();
4629
        break;
4630
    }
4631
    if (opc2 & 0x02) {
4632
        /* nmultiply-and-accumulate (0x0E) */
4633
        gen_op_neg();
4634
    }
4635
    if (opc2 & 0x04) {
4636
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4637
        gen_op_load_gpr_T2(rt);
4638
        gen_op_move_T1_T0();
4639
        gen_op_405_add_T0_T2();
4640
    }
4641
    if (opc3 & 0x10) {
4642
        /* Check overflow */
4643
        if (opc3 & 0x01)
4644
            gen_op_check_addo();
4645
        else
4646
            gen_op_405_check_ovu();
4647
    }
4648
    if (opc3 & 0x02) {
4649
        /* Saturate */
4650
        if (opc3 & 0x01)
4651
            gen_op_405_check_sat();
4652
        else
4653
            gen_op_405_check_satu();
4654
    }
4655
    gen_op_store_T0_gpr(rt);
4656
    if (unlikely(Rc) != 0) {
4657
        /* Update Rc0 */
4658
        gen_set_Rc0(ctx);
4659
    }
4660
}
4661

    
4662
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4663
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4664
{                                                                             \
4665
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4666
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4667
}
4668

    
4669
/* macchw    - macchw.    */
4670
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4671
/* macchwo   - macchwo.   */
4672
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4673
/* macchws   - macchws.   */
4674
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4675
/* macchwso  - macchwso.  */
4676
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4677
/* macchwsu  - macchwsu.  */
4678
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4679
/* macchwsuo - macchwsuo. */
4680
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4681
/* macchwu   - macchwu.   */
4682
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4683
/* macchwuo  - macchwuo.  */
4684
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4685
/* machhw    - machhw.    */
4686
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4687
/* machhwo   - machhwo.   */
4688
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4689
/* machhws   - machhws.   */
4690
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4691
/* machhwso  - machhwso.  */
4692
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4693
/* machhwsu  - machhwsu.  */
4694
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4695
/* machhwsuo - machhwsuo. */
4696
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4697
/* machhwu   - machhwu.   */
4698
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4699
/* machhwuo  - machhwuo.  */
4700
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4701
/* maclhw    - maclhw.    */
4702
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4703
/* maclhwo   - maclhwo.   */
4704
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4705
/* maclhws   - maclhws.   */
4706
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4707
/* maclhwso  - maclhwso.  */
4708
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4709
/* maclhwu   - maclhwu.   */
4710
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4711
/* maclhwuo  - maclhwuo.  */
4712
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4713
/* maclhwsu  - maclhwsu.  */
4714
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4715
/* maclhwsuo - maclhwsuo. */
4716
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4717
/* nmacchw   - nmacchw.   */
4718
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4719
/* nmacchwo  - nmacchwo.  */
4720
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4721
/* nmacchws  - nmacchws.  */
4722
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4723
/* nmacchwso - nmacchwso. */
4724
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4725
/* nmachhw   - nmachhw.   */
4726
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4727
/* nmachhwo  - nmachhwo.  */
4728
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4729
/* nmachhws  - nmachhws.  */
4730
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4731
/* nmachhwso - nmachhwso. */
4732
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4733
/* nmaclhw   - nmaclhw.   */
4734
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4735
/* nmaclhwo  - nmaclhwo.  */
4736
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4737
/* nmaclhws  - nmaclhws.  */
4738
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4739
/* nmaclhwso - nmaclhwso. */
4740
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4741

    
4742
/* mulchw  - mulchw.  */
4743
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4744
/* mulchwu - mulchwu. */
4745
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4746
/* mulhhw  - mulhhw.  */
4747
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4748
/* mulhhwu - mulhhwu. */
4749
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4750
/* mullhw  - mullhw.  */
4751
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4752
/* mullhwu - mullhwu. */
4753
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4754

    
4755
/* mfdcr */
4756
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
4757
{
4758
#if defined(CONFIG_USER_ONLY)
4759
    GEN_EXCP_PRIVREG(ctx);
4760
#else
4761
    uint32_t dcrn = SPR(ctx->opcode);
4762

    
4763
    if (unlikely(!ctx->supervisor)) {
4764
        GEN_EXCP_PRIVREG(ctx);
4765
        return;
4766
    }
4767
    gen_op_set_T0(dcrn);
4768
    gen_op_load_dcr();
4769
    gen_op_store_T0_gpr(rD(ctx->opcode));
4770
#endif
4771
}
4772

    
4773
/* mtdcr */
4774
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
4775
{
4776
#if defined(CONFIG_USER_ONLY)
4777
    GEN_EXCP_PRIVREG(ctx);
4778
#else
4779
    uint32_t dcrn = SPR(ctx->opcode);
4780

    
4781
    if (unlikely(!ctx->supervisor)) {
4782
        GEN_EXCP_PRIVREG(ctx);
4783
        return;
4784
    }
4785
    gen_op_set_T0(dcrn);
4786
    gen_op_load_gpr_T1(rS(ctx->opcode));
4787
    gen_op_store_dcr();
4788
#endif
4789
}
4790

    
4791
/* mfdcrx */
4792
/* XXX: not implemented on 440 ? */
4793
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
4794
{
4795
#if defined(CONFIG_USER_ONLY)
4796
    GEN_EXCP_PRIVREG(ctx);
4797
#else
4798
    if (unlikely(!ctx->supervisor)) {
4799
        GEN_EXCP_PRIVREG(ctx);
4800
        return;
4801
    }
4802
    gen_op_load_gpr_T0(rA(ctx->opcode));
4803
    gen_op_load_dcr();
4804
    gen_op_store_T0_gpr(rD(ctx->opcode));
4805
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4806
#endif
4807
}
4808

    
4809
/* mtdcrx */
4810
/* XXX: not implemented on 440 ? */
4811
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
4812
{
4813
#if defined(CONFIG_USER_ONLY)
4814
    GEN_EXCP_PRIVREG(ctx);
4815
#else
4816
    if (unlikely(!ctx->supervisor)) {
4817
        GEN_EXCP_PRIVREG(ctx);
4818
        return;
4819
    }
4820
    gen_op_load_gpr_T0(rA(ctx->opcode));
4821
    gen_op_load_gpr_T1(rS(ctx->opcode));
4822
    gen_op_store_dcr();
4823
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4824
#endif
4825
}
4826

    
4827
/* mfdcrux (PPC 460) : user-mode access to DCR */
4828
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4829
{
4830
    gen_op_load_gpr_T0(rA(ctx->opcode));
4831
    gen_op_load_dcr();
4832
    gen_op_store_T0_gpr(rD(ctx->opcode));
4833
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4834
}
4835

    
4836
/* mtdcrux (PPC 460) : user-mode access to DCR */
4837
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4838
{
4839
    gen_op_load_gpr_T0(rA(ctx->opcode));
4840
    gen_op_load_gpr_T1(rS(ctx->opcode));
4841
    gen_op_store_dcr();
4842
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4843
}
4844

    
4845
/* dccci */
4846
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4847
{
4848
#if defined(CONFIG_USER_ONLY)
4849
    GEN_EXCP_PRIVOPC(ctx);
4850
#else
4851
    if (unlikely(!ctx->supervisor)) {
4852
        GEN_EXCP_PRIVOPC(ctx);
4853
        return;
4854
    }
4855
    /* interpreted as no-op */
4856
#endif
4857
}
4858

    
4859
/* dcread */
4860
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4861
{
4862
#if defined(CONFIG_USER_ONLY)
4863
    GEN_EXCP_PRIVOPC(ctx);
4864
#else
4865
    if (unlikely(!ctx->supervisor)) {
4866
        GEN_EXCP_PRIVOPC(ctx);
4867
        return;
4868
    }
4869
    gen_addr_reg_index(ctx);
4870
    op_ldst(lwz);
4871
    gen_op_store_T0_gpr(rD(ctx->opcode));
4872
#endif
4873
}
4874

    
4875
/* icbt */
4876
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4877
{
4878
    /* interpreted as no-op */
4879
    /* XXX: specification say this is treated as a load by the MMU
4880
     *      but does not generate any exception
4881
     */
4882
}
4883

    
4884
/* iccci */
4885
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4886
{
4887
#if defined(CONFIG_USER_ONLY)
4888
    GEN_EXCP_PRIVOPC(ctx);
4889
#else
4890
    if (unlikely(!ctx->supervisor)) {
4891
        GEN_EXCP_PRIVOPC(ctx);
4892
        return;
4893
    }
4894
    /* interpreted as no-op */
4895
#endif
4896
}
4897

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

    
4912
/* rfci (supervisor only) */
4913
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4914
{
4915
#if defined(CONFIG_USER_ONLY)
4916
    GEN_EXCP_PRIVOPC(ctx);
4917
#else
4918
    if (unlikely(!ctx->supervisor)) {
4919
        GEN_EXCP_PRIVOPC(ctx);
4920
        return;
4921
    }
4922
    /* Restore CPU state */
4923
    gen_op_40x_rfci();
4924
    GEN_SYNC(ctx);
4925
#endif
4926
}
4927

    
4928
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4929
{
4930
#if defined(CONFIG_USER_ONLY)
4931
    GEN_EXCP_PRIVOPC(ctx);
4932
#else
4933
    if (unlikely(!ctx->supervisor)) {
4934
        GEN_EXCP_PRIVOPC(ctx);
4935
        return;
4936
    }
4937
    /* Restore CPU state */
4938
    gen_op_rfci();
4939
    GEN_SYNC(ctx);
4940
#endif
4941
}
4942

    
4943
/* BookE specific */
4944
/* XXX: not implemented on 440 ? */
4945
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
4946
{
4947
#if defined(CONFIG_USER_ONLY)
4948
    GEN_EXCP_PRIVOPC(ctx);
4949
#else
4950
    if (unlikely(!ctx->supervisor)) {
4951
        GEN_EXCP_PRIVOPC(ctx);
4952
        return;
4953
    }
4954
    /* Restore CPU state */
4955
    gen_op_rfdi();
4956
    GEN_SYNC(ctx);
4957
#endif
4958
}
4959

    
4960
/* XXX: not implemented on 440 ? */
4961
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
4962
{
4963
#if defined(CONFIG_USER_ONLY)
4964
    GEN_EXCP_PRIVOPC(ctx);
4965
#else
4966
    if (unlikely(!ctx->supervisor)) {
4967
        GEN_EXCP_PRIVOPC(ctx);
4968
        return;
4969
    }
4970
    /* Restore CPU state */
4971
    gen_op_rfmci();
4972
    GEN_SYNC(ctx);
4973
#endif
4974
}
4975

    
4976
/* TLB management - PowerPC 405 implementation */
4977
/* tlbre */
4978
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4979
{
4980
#if defined(CONFIG_USER_ONLY)
4981
    GEN_EXCP_PRIVOPC(ctx);
4982
#else
4983
    if (unlikely(!ctx->supervisor)) {
4984
        GEN_EXCP_PRIVOPC(ctx);
4985
        return;
4986
    }
4987
    switch (rB(ctx->opcode)) {
4988
    case 0:
4989
        gen_op_load_gpr_T0(rA(ctx->opcode));
4990
        gen_op_4xx_tlbre_hi();
4991
        gen_op_store_T0_gpr(rD(ctx->opcode));
4992
        break;
4993
    case 1:
4994
        gen_op_load_gpr_T0(rA(ctx->opcode));
4995
        gen_op_4xx_tlbre_lo();
4996
        gen_op_store_T0_gpr(rD(ctx->opcode));
4997
        break;
4998
    default:
4999
        GEN_EXCP_INVAL(ctx);
5000
        break;
5001
    }
5002
#endif
5003
}
5004

    
5005
/* tlbsx - tlbsx. */
5006
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5007
{
5008
#if defined(CONFIG_USER_ONLY)
5009
    GEN_EXCP_PRIVOPC(ctx);
5010
#else
5011
    if (unlikely(!ctx->supervisor)) {
5012
        GEN_EXCP_PRIVOPC(ctx);
5013
        return;
5014
    }
5015
    gen_addr_reg_index(ctx);
5016
    gen_op_4xx_tlbsx();
5017
    if (Rc(ctx->opcode))
5018
        gen_op_4xx_tlbsx_check();
5019
    gen_op_store_T0_gpr(rD(ctx->opcode));
5020
#endif
5021
}
5022

    
5023
/* tlbwe */
5024
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5025
{
5026
#if defined(CONFIG_USER_ONLY)
5027
    GEN_EXCP_PRIVOPC(ctx);
5028
#else
5029
    if (unlikely(!ctx->supervisor)) {
5030
        GEN_EXCP_PRIVOPC(ctx);
5031
        return;
5032
    }
5033
    switch (rB(ctx->opcode)) {
5034
    case 0:
5035
        gen_op_load_gpr_T0(rA(ctx->opcode));
5036
        gen_op_load_gpr_T1(rS(ctx->opcode));
5037
        gen_op_4xx_tlbwe_hi();
5038
        break;
5039
    case 1:
5040
        gen_op_load_gpr_T0(rA(ctx->opcode));
5041
        gen_op_load_gpr_T1(rS(ctx->opcode));
5042
        gen_op_4xx_tlbwe_lo();
5043
        break;
5044
    default:
5045
        GEN_EXCP_INVAL(ctx);
5046
        break;
5047
    }
5048
#endif
5049
}
5050

    
5051
/* TLB management - PowerPC 440 implementation */
5052
/* tlbre */
5053
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5054
{
5055
#if defined(CONFIG_USER_ONLY)
5056
    GEN_EXCP_PRIVOPC(ctx);
5057
#else
5058
    if (unlikely(!ctx->supervisor)) {
5059
        GEN_EXCP_PRIVOPC(ctx);
5060
        return;
5061
    }
5062
    switch (rB(ctx->opcode)) {
5063
    case 0:
5064
    case 1:
5065
    case 2:
5066
        gen_op_load_gpr_T0(rA(ctx->opcode));
5067
        gen_op_440_tlbre(rB(ctx->opcode));
5068
        gen_op_store_T0_gpr(rD(ctx->opcode));
5069
        break;
5070
    default:
5071
        GEN_EXCP_INVAL(ctx);
5072
        break;
5073
    }
5074
#endif
5075
}
5076

    
5077
/* tlbsx - tlbsx. */
5078
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5079
{
5080
#if defined(CONFIG_USER_ONLY)
5081
    GEN_EXCP_PRIVOPC(ctx);
5082
#else
5083
    if (unlikely(!ctx->supervisor)) {
5084
        GEN_EXCP_PRIVOPC(ctx);
5085
        return;
5086
    }
5087
    gen_addr_reg_index(ctx);
5088
    gen_op_440_tlbsx();
5089
    if (Rc(ctx->opcode))
5090
        gen_op_4xx_tlbsx_check();
5091
    gen_op_store_T0_gpr(rD(ctx->opcode));
5092
#endif
5093
}
5094

    
5095
/* tlbwe */
5096
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5097
{
5098
#if defined(CONFIG_USER_ONLY)
5099
    GEN_EXCP_PRIVOPC(ctx);
5100
#else
5101
    if (unlikely(!ctx->supervisor)) {
5102
        GEN_EXCP_PRIVOPC(ctx);
5103
        return;
5104
    }
5105
    switch (rB(ctx->opcode)) {
5106
    case 0:
5107
    case 1:
5108
    case 2:
5109
        gen_op_load_gpr_T0(rA(ctx->opcode));
5110
        gen_op_load_gpr_T1(rS(ctx->opcode));
5111
        gen_op_440_tlbwe(rB(ctx->opcode));
5112
        break;
5113
    default:
5114
        GEN_EXCP_INVAL(ctx);
5115
        break;
5116
    }
5117
#endif
5118
}
5119

    
5120
/* wrtee */
5121
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
5122
{
5123
#if defined(CONFIG_USER_ONLY)
5124
    GEN_EXCP_PRIVOPC(ctx);
5125
#else
5126
    if (unlikely(!ctx->supervisor)) {
5127
        GEN_EXCP_PRIVOPC(ctx);
5128
        return;
5129
    }
5130
    gen_op_load_gpr_T0(rD(ctx->opcode));
5131
    gen_op_wrte();
5132
    /* Stop translation to have a chance to raise an exception
5133
     * if we just set msr_ee to 1
5134
     */
5135
    GEN_STOP(ctx);
5136
#endif
5137
}
5138

    
5139
/* wrteei */
5140
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
5141
{
5142
#if defined(CONFIG_USER_ONLY)
5143
    GEN_EXCP_PRIVOPC(ctx);
5144
#else
5145
    if (unlikely(!ctx->supervisor)) {
5146
        GEN_EXCP_PRIVOPC(ctx);
5147
        return;
5148
    }
5149
    gen_op_set_T0(ctx->opcode & 0x00010000);
5150
    gen_op_wrte();
5151
    /* Stop translation to have a chance to raise an exception
5152
     * if we just set msr_ee to 1
5153
     */
5154
    GEN_STOP(ctx);
5155
#endif
5156
}
5157

    
5158
/* PowerPC 440 specific instructions */
5159
/* dlmzb */
5160
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5161
{
5162
    gen_op_load_gpr_T0(rS(ctx->opcode));
5163
    gen_op_load_gpr_T1(rB(ctx->opcode));
5164
    gen_op_440_dlmzb();
5165
    gen_op_store_T0_gpr(rA(ctx->opcode));
5166
    gen_op_store_xer_bc();
5167
    if (Rc(ctx->opcode)) {
5168
        gen_op_440_dlmzb_update_Rc();
5169
        gen_op_store_T0_crf(0);
5170
    }
5171
}
5172

    
5173
/* mbar replaces eieio on 440 */
5174
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5175
{
5176
    /* interpreted as no-op */
5177
}
5178

    
5179
/* msync replaces sync on 440 */
5180
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5181
{
5182
    /* interpreted as no-op */
5183
}
5184

    
5185
/* icbt */
5186
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5187
{
5188
    /* interpreted as no-op */
5189
    /* XXX: specification say this is treated as a load by the MMU
5190
     *      but does not generate any exception
5191
     */
5192
}
5193

    
5194
/***                      Altivec vector extension                         ***/
5195
/* Altivec registers moves */
5196
GEN32(gen_op_load_avr_A0, gen_op_load_avr_A0_avr);
5197
GEN32(gen_op_load_avr_A1, gen_op_load_avr_A1_avr);
5198
GEN32(gen_op_load_avr_A2, gen_op_load_avr_A2_avr);
5199

    
5200
GEN32(gen_op_store_A0_avr, gen_op_store_A0_avr_avr);
5201
GEN32(gen_op_store_A1_avr, gen_op_store_A1_avr_avr);
5202
#if 0 // unused
5203
GEN32(gen_op_store_A2_avr, gen_op_store_A2_avr_avr);
5204
#endif
5205

    
5206
#define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5207
#define OP_VR_LD_TABLE(name)                                                  \
5208
static GenOpFunc *gen_op_vr_l##name[NB_MEM_FUNCS] = {                         \
5209
    GEN_MEM_FUNCS(vr_l##name),                                                \
5210
};
5211
#define OP_VR_ST_TABLE(name)                                                  \
5212
static GenOpFunc *gen_op_vr_st##name[NB_MEM_FUNCS] = {                        \
5213
    GEN_MEM_FUNCS(vr_st##name),                                               \
5214
};
5215

    
5216
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5217
GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
5218
{                                                                             \
5219
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5220
        GEN_EXCP_NO_VR(ctx);                                                  \
5221
        return;                                                               \
5222
    }                                                                         \
5223
    gen_addr_reg_index(ctx);                                                  \
5224
    op_vr_ldst(vr_l##name);                                                   \
5225
    gen_op_store_A0_avr(rD(ctx->opcode));                                     \
5226
}
5227

    
5228
#define GEN_VR_STX(name, opc2, opc3)                                          \
5229
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
5230
{                                                                             \
5231
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5232
        GEN_EXCP_NO_VR(ctx);                                                  \
5233
        return;                                                               \
5234
    }                                                                         \
5235
    gen_addr_reg_index(ctx);                                                  \
5236
    gen_op_load_avr_A0(rS(ctx->opcode));                                      \
5237
    op_vr_ldst(vr_st##name);                                                  \
5238
}
5239

    
5240
OP_VR_LD_TABLE(vx);
5241
GEN_VR_LDX(vx, 0x07, 0x03);
5242
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
5243
#define gen_op_vr_lvxl gen_op_vr_lvx
5244
GEN_VR_LDX(vxl, 0x07, 0x0B);
5245

    
5246
OP_VR_ST_TABLE(vx);
5247
GEN_VR_STX(vx, 0x07, 0x07);
5248
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
5249
#define gen_op_vr_stvxl gen_op_vr_stvx
5250
GEN_VR_STX(vxl, 0x07, 0x0F);
5251

    
5252
/***                           SPE extension                               ***/
5253
/* Register moves */
5254
#if !defined(TARGET_PPC64)
5255

    
5256
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
5257
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
5258
#if 0 // unused
5259
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
5260
#endif
5261

    
5262
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
5263
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
5264
#if 0 // unused
5265
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
5266
#endif
5267

    
5268
#else /* !defined(TARGET_PPC64) */
5269

    
5270
/* No specific load/store functions: GPRs are already 64 bits */
5271
#define gen_op_load_gpr64_T0 gen_op_load_gpr_T0
5272
#define gen_op_load_gpr64_T1 gen_op_load_gpr_T1
5273
#if 0 // unused
5274
#define gen_op_load_gpr64_T2 gen_op_load_gpr_T2
5275
#endif
5276

    
5277
#define gen_op_store_T0_gpr64 gen_op_store_T0_gpr
5278
#define gen_op_store_T1_gpr64 gen_op_store_T1_gpr
5279
#if 0 // unused
5280
#define gen_op_store_T2_gpr64 gen_op_store_T2_gpr
5281
#endif
5282

    
5283
#endif /* !defined(TARGET_PPC64) */
5284

    
5285
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5286
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5287
{                                                                             \
5288
    if (Rc(ctx->opcode))                                                      \
5289
        gen_##name1(ctx);                                                     \
5290
    else                                                                      \
5291
        gen_##name0(ctx);                                                     \
5292
}
5293

    
5294
/* Handler for undefined SPE opcodes */
5295
static always_inline void gen_speundef (DisasContext *ctx)
5296
{
5297
    GEN_EXCP_INVAL(ctx);
5298
}
5299

    
5300
/* SPE load and stores */
5301
static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5302
{
5303
    target_long simm = rB(ctx->opcode);
5304

    
5305
    if (rA(ctx->opcode) == 0) {
5306
        gen_set_T0(simm << sh);
5307
    } else {
5308
        gen_op_load_gpr_T0(rA(ctx->opcode));
5309
        if (likely(simm != 0))
5310
            gen_op_addi(simm << sh);
5311
    }
5312
}
5313

    
5314
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5315
#define OP_SPE_LD_TABLE(name)                                                 \
5316
static GenOpFunc *gen_op_spe_l##name[NB_MEM_FUNCS] = {                        \
5317
    GEN_MEM_FUNCS(spe_l##name),                                               \
5318
};
5319
#define OP_SPE_ST_TABLE(name)                                                 \
5320
static GenOpFunc *gen_op_spe_st##name[NB_MEM_FUNCS] = {                       \
5321
    GEN_MEM_FUNCS(spe_st##name),                                              \
5322
};
5323

    
5324
#define GEN_SPE_LD(name, sh)                                                  \
5325
static always_inline void gen_evl##name (DisasContext *ctx)                   \
5326
{                                                                             \
5327
    if (unlikely(!ctx->spe_enabled)) {                                        \
5328
        GEN_EXCP_NO_AP(ctx);                                                  \
5329
        return;                                                               \
5330
    }                                                                         \
5331
    gen_addr_spe_imm_index(ctx, sh);                                          \
5332
    op_spe_ldst(spe_l##name);                                                 \
5333
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5334
}
5335

    
5336
#define GEN_SPE_LDX(name)                                                     \
5337
static always_inline void gen_evl##name##x (DisasContext *ctx)                \
5338
{                                                                             \
5339
    if (unlikely(!ctx->spe_enabled)) {                                        \
5340
        GEN_EXCP_NO_AP(ctx);                                                  \
5341
        return;                                                               \
5342
    }                                                                         \
5343
    gen_addr_reg_index(ctx);                                                  \
5344
    op_spe_ldst(spe_l##name);                                                 \
5345
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5346
}
5347

    
5348
#define GEN_SPEOP_LD(name, sh)                                                \
5349
OP_SPE_LD_TABLE(name);                                                        \
5350
GEN_SPE_LD(name, sh);                                                         \
5351
GEN_SPE_LDX(name)
5352

    
5353
#define GEN_SPE_ST(name, sh)                                                  \
5354
static always_inline void gen_evst##name (DisasContext *ctx)                  \
5355
{                                                                             \
5356
    if (unlikely(!ctx->spe_enabled)) {                                        \
5357
        GEN_EXCP_NO_AP(ctx);                                                  \
5358
        return;                                                               \
5359
    }                                                                         \
5360
    gen_addr_spe_imm_index(ctx, sh);                                          \
5361
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5362
    op_spe_ldst(spe_st##name);                                                \
5363
}
5364

    
5365
#define GEN_SPE_STX(name)                                                     \
5366
static always_inline void gen_evst##name##x (DisasContext *ctx)               \
5367
{                                                                             \
5368
    if (unlikely(!ctx->spe_enabled)) {                                        \
5369
        GEN_EXCP_NO_AP(ctx);                                                  \
5370
        return;                                                               \
5371
    }                                                                         \
5372
    gen_addr_reg_index(ctx);                                                  \
5373
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5374
    op_spe_ldst(spe_st##name);                                                \
5375
}
5376

    
5377
#define GEN_SPEOP_ST(name, sh)                                                \
5378
OP_SPE_ST_TABLE(name);                                                        \
5379
GEN_SPE_ST(name, sh);                                                         \
5380
GEN_SPE_STX(name)
5381

    
5382
#define GEN_SPEOP_LDST(name, sh)                                              \
5383
GEN_SPEOP_LD(name, sh);                                                       \
5384
GEN_SPEOP_ST(name, sh)
5385

    
5386
/* SPE arithmetic and logic */
5387
#define GEN_SPEOP_ARITH2(name)                                                \
5388
static always_inline void gen_##name (DisasContext *ctx)                      \
5389
{                                                                             \
5390
    if (unlikely(!ctx->spe_enabled)) {                                        \
5391
        GEN_EXCP_NO_AP(ctx);                                                  \
5392
        return;                                                               \
5393
    }                                                                         \
5394
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5395
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5396
    gen_op_##name();                                                          \
5397
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5398
}
5399

    
5400
#define GEN_SPEOP_ARITH1(name)                                                \
5401
static always_inline void gen_##name (DisasContext *ctx)                      \
5402
{                                                                             \
5403
    if (unlikely(!ctx->spe_enabled)) {                                        \
5404
        GEN_EXCP_NO_AP(ctx);                                                  \
5405
        return;                                                               \
5406
    }                                                                         \
5407
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5408
    gen_op_##name();                                                          \
5409
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5410
}
5411

    
5412
#define GEN_SPEOP_COMP(name)                                                  \
5413
static always_inline void gen_##name (DisasContext *ctx)                      \
5414
{                                                                             \
5415
    if (unlikely(!ctx->spe_enabled)) {                                        \
5416
        GEN_EXCP_NO_AP(ctx);                                                  \
5417
        return;                                                               \
5418
    }                                                                         \
5419
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5420
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5421
    gen_op_##name();                                                          \
5422
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5423
}
5424

    
5425
/* Logical */
5426
GEN_SPEOP_ARITH2(evand);
5427
GEN_SPEOP_ARITH2(evandc);
5428
GEN_SPEOP_ARITH2(evxor);
5429
GEN_SPEOP_ARITH2(evor);
5430
GEN_SPEOP_ARITH2(evnor);
5431
GEN_SPEOP_ARITH2(eveqv);
5432
GEN_SPEOP_ARITH2(evorc);
5433
GEN_SPEOP_ARITH2(evnand);
5434
GEN_SPEOP_ARITH2(evsrwu);
5435
GEN_SPEOP_ARITH2(evsrws);
5436
GEN_SPEOP_ARITH2(evslw);
5437
GEN_SPEOP_ARITH2(evrlw);
5438
GEN_SPEOP_ARITH2(evmergehi);
5439
GEN_SPEOP_ARITH2(evmergelo);
5440
GEN_SPEOP_ARITH2(evmergehilo);
5441
GEN_SPEOP_ARITH2(evmergelohi);
5442

    
5443
/* Arithmetic */
5444
GEN_SPEOP_ARITH2(evaddw);
5445
GEN_SPEOP_ARITH2(evsubfw);
5446
GEN_SPEOP_ARITH1(evabs);
5447
GEN_SPEOP_ARITH1(evneg);
5448
GEN_SPEOP_ARITH1(evextsb);
5449
GEN_SPEOP_ARITH1(evextsh);
5450
GEN_SPEOP_ARITH1(evrndw);
5451
GEN_SPEOP_ARITH1(evcntlzw);
5452
GEN_SPEOP_ARITH1(evcntlsw);
5453
static always_inline void gen_brinc (DisasContext *ctx)
5454
{
5455
    /* Note: brinc is usable even if SPE is disabled */
5456
    gen_op_load_gpr_T0(rA(ctx->opcode));
5457
    gen_op_load_gpr_T1(rB(ctx->opcode));
5458
    gen_op_brinc();
5459
    gen_op_store_T0_gpr(rD(ctx->opcode));
5460
}
5461

    
5462
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5463
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5464
{                                                                             \
5465
    if (unlikely(!ctx->spe_enabled)) {                                        \
5466
        GEN_EXCP_NO_AP(ctx);                                                  \
5467
        return;                                                               \
5468
    }                                                                         \
5469
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5470
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5471
    gen_op_##name();                                                          \
5472
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5473
}
5474

    
5475
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5476
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5477
{                                                                             \
5478
    if (unlikely(!ctx->spe_enabled)) {                                        \
5479
        GEN_EXCP_NO_AP(ctx);                                                  \
5480
        return;                                                               \
5481
    }                                                                         \
5482
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5483
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5484
    gen_op_##name();                                                          \
5485
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5486
}
5487

    
5488
GEN_SPEOP_ARITH_IMM2(evaddw);
5489
#define gen_evaddiw gen_evaddwi
5490
GEN_SPEOP_ARITH_IMM2(evsubfw);
5491
#define gen_evsubifw gen_evsubfwi
5492
GEN_SPEOP_LOGIC_IMM2(evslw);
5493
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5494
#define gen_evsrwis gen_evsrwsi
5495
GEN_SPEOP_LOGIC_IMM2(evsrws);
5496
#define gen_evsrwiu gen_evsrwui
5497
GEN_SPEOP_LOGIC_IMM2(evrlw);
5498

    
5499
static always_inline void gen_evsplati (DisasContext *ctx)
5500
{
5501
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5502

    
5503
    gen_op_splatwi_T0_64(imm);
5504
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5505
}
5506

    
5507
static always_inline void gen_evsplatfi (DisasContext *ctx)
5508
{
5509
    uint32_t imm = rA(ctx->opcode) << 27;
5510

    
5511
    gen_op_splatwi_T0_64(imm);
5512
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5513
}
5514

    
5515
/* Comparison */
5516
GEN_SPEOP_COMP(evcmpgtu);
5517
GEN_SPEOP_COMP(evcmpgts);
5518
GEN_SPEOP_COMP(evcmpltu);
5519
GEN_SPEOP_COMP(evcmplts);
5520
GEN_SPEOP_COMP(evcmpeq);
5521

    
5522
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5523
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5524
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5525
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5526
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5527
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5528
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5529
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5530
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5531
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5532
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5533
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5534
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5535
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5536
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5537
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5538
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5539
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5540
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5541
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5542
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5543
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5544
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5545
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5546
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5547

    
5548
static always_inline void gen_evsel (DisasContext *ctx)
5549
{
5550
    if (unlikely(!ctx->spe_enabled)) {
5551
        GEN_EXCP_NO_AP(ctx);
5552
        return;
5553
    }
5554
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5555
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5556
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5557
    gen_op_evsel();
5558
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5559
}
5560

    
5561
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5562
{
5563
    gen_evsel(ctx);
5564
}
5565
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5566
{
5567
    gen_evsel(ctx);
5568
}
5569
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5570
{
5571
    gen_evsel(ctx);
5572
}
5573
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5574
{
5575
    gen_evsel(ctx);
5576
}
5577

    
5578
/* Load and stores */
5579
#if defined(TARGET_PPC64)
5580
/* In that case, we already have 64 bits load & stores
5581
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5582
 */
5583
#define gen_op_spe_ldd_raw           gen_op_ld_raw
5584
#define gen_op_spe_ldd_user          gen_op_ld_user
5585
#define gen_op_spe_ldd_kernel        gen_op_ld_kernel
5586
#define gen_op_spe_ldd_hypv          gen_op_ld_hypv
5587
#define gen_op_spe_ldd_64_raw        gen_op_ld_64_raw
5588
#define gen_op_spe_ldd_64_user       gen_op_ld_64_user
5589
#define gen_op_spe_ldd_64_kernel     gen_op_ld_64_kernel
5590
#define gen_op_spe_ldd_64_hypv       gen_op_ld_64_hypv
5591
#define gen_op_spe_ldd_le_raw        gen_op_ld_le_raw
5592
#define gen_op_spe_ldd_le_user       gen_op_ld_le_user
5593
#define gen_op_spe_ldd_le_kernel     gen_op_ld_le_kernel
5594
#define gen_op_spe_ldd_le_hypv       gen_op_ld_le_hypv
5595
#define gen_op_spe_ldd_le_64_raw     gen_op_ld_le_64_raw
5596
#define gen_op_spe_ldd_le_64_user    gen_op_ld_le_64_user
5597
#define gen_op_spe_ldd_le_64_kernel  gen_op_ld_le_64_kernel
5598
#define gen_op_spe_ldd_le_64_hypv    gen_op_ld_le_64_hypv
5599
#define gen_op_spe_stdd_raw          gen_op_std_raw
5600
#define gen_op_spe_stdd_user         gen_op_std_user
5601
#define gen_op_spe_stdd_kernel       gen_op_std_kernel
5602
#define gen_op_spe_stdd_hypv         gen_op_std_hypv
5603
#define gen_op_spe_stdd_64_raw       gen_op_std_64_raw
5604
#define gen_op_spe_stdd_64_user      gen_op_std_64_user
5605
#define gen_op_spe_stdd_64_kernel    gen_op_std_64_kernel
5606
#define gen_op_spe_stdd_64_hypv      gen_op_std_64_hypv
5607
#define gen_op_spe_stdd_le_raw       gen_op_std_le_raw
5608
#define gen_op_spe_stdd_le_user      gen_op_std_le_user
5609
#define gen_op_spe_stdd_le_kernel    gen_op_std_le_kernel
5610
#define gen_op_spe_stdd_le_hypv      gen_op_std_le_hypv
5611
#define gen_op_spe_stdd_le_64_raw    gen_op_std_le_64_raw
5612
#define gen_op_spe_stdd_le_64_user   gen_op_std_le_64_user
5613
#define gen_op_spe_stdd_le_64_kernel gen_op_std_le_64_kernel
5614
#define gen_op_spe_stdd_le_64_hypv   gen_op_std_le_64_hypv
5615
#endif /* defined(TARGET_PPC64) */
5616
GEN_SPEOP_LDST(dd, 3);
5617
GEN_SPEOP_LDST(dw, 3);
5618
GEN_SPEOP_LDST(dh, 3);
5619
GEN_SPEOP_LDST(whe, 2);
5620
GEN_SPEOP_LD(whou, 2);
5621
GEN_SPEOP_LD(whos, 2);
5622
GEN_SPEOP_ST(who, 2);
5623

    
5624
#if defined(TARGET_PPC64)
5625
/* In that case, spe_stwwo is equivalent to stw */
5626
#define gen_op_spe_stwwo_raw          gen_op_stw_raw
5627
#define gen_op_spe_stwwo_user         gen_op_stw_user
5628
#define gen_op_spe_stwwo_kernel       gen_op_stw_kernel
5629
#define gen_op_spe_stwwo_hypv         gen_op_stw_hypv
5630
#define gen_op_spe_stwwo_le_raw       gen_op_stw_le_raw
5631
#define gen_op_spe_stwwo_le_user      gen_op_stw_le_user
5632
#define gen_op_spe_stwwo_le_kernel    gen_op_stw_le_kernel
5633
#define gen_op_spe_stwwo_le_hypv      gen_op_stw_le_hypv
5634
#define gen_op_spe_stwwo_64_raw       gen_op_stw_64_raw
5635
#define gen_op_spe_stwwo_64_user      gen_op_stw_64_user
5636
#define gen_op_spe_stwwo_64_kernel    gen_op_stw_64_kernel
5637
#define gen_op_spe_stwwo_64_hypv      gen_op_stw_64_hypv
5638
#define gen_op_spe_stwwo_le_64_raw    gen_op_stw_le_64_raw
5639
#define gen_op_spe_stwwo_le_64_user   gen_op_stw_le_64_user
5640
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5641
#define gen_op_spe_stwwo_le_64_hypv   gen_op_stw_le_64_hypv
5642
#endif
5643
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5644
static always_inline void gen_op_spe_stwwe_##suffix (void)                    \
5645
{                                                                             \
5646
    gen_op_srli32_T1_64();                                                    \
5647
    gen_op_spe_stwwo_##suffix();                                              \
5648
}
5649
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5650
static always_inline void gen_op_spe_stwwe_le_##suffix (void)                 \
5651
{                                                                             \
5652
    gen_op_srli32_T1_64();                                                    \
5653
    gen_op_spe_stwwo_le_##suffix();                                           \
5654
}
5655
#if defined(TARGET_PPC64)
5656
#define GEN_OP_SPE_STWWE(suffix)                                              \
5657
_GEN_OP_SPE_STWWE(suffix);                                                    \
5658
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5659
static always_inline void gen_op_spe_stwwe_64_##suffix (void)                 \
5660
{                                                                             \
5661
    gen_op_srli32_T1_64();                                                    \
5662
    gen_op_spe_stwwo_64_##suffix();                                           \
5663
}                                                                             \
5664
static always_inline void gen_op_spe_stwwe_le_64_##suffix (void)              \
5665
{                                                                             \
5666
    gen_op_srli32_T1_64();                                                    \
5667
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5668
}
5669
#else
5670
#define GEN_OP_SPE_STWWE(suffix)                                              \
5671
_GEN_OP_SPE_STWWE(suffix);                                                    \
5672
_GEN_OP_SPE_STWWE_LE(suffix)
5673
#endif
5674
#if defined(CONFIG_USER_ONLY)
5675
GEN_OP_SPE_STWWE(raw);
5676
#else /* defined(CONFIG_USER_ONLY) */
5677
GEN_OP_SPE_STWWE(user);
5678
GEN_OP_SPE_STWWE(kernel);
5679
GEN_OP_SPE_STWWE(hypv);
5680
#endif /* defined(CONFIG_USER_ONLY) */
5681
GEN_SPEOP_ST(wwe, 2);
5682
GEN_SPEOP_ST(wwo, 2);
5683

    
5684
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5685
static always_inline void gen_op_spe_l##name##_##suffix (void)                \
5686
{                                                                             \
5687
    gen_op_##op##_##suffix();                                                 \
5688
    gen_op_splatw_T1_64();                                                    \
5689
}
5690

    
5691
#define GEN_OP_SPE_LHE(suffix)                                                \
5692
static always_inline void gen_op_spe_lhe_##suffix (void)                      \
5693
{                                                                             \
5694
    gen_op_spe_lh_##suffix();                                                 \
5695
    gen_op_sli16_T1_64();                                                     \
5696
}
5697

    
5698
#define GEN_OP_SPE_LHX(suffix)                                                \
5699
static always_inline void gen_op_spe_lhx_##suffix (void)                      \
5700
{                                                                             \
5701
    gen_op_spe_lh_##suffix();                                                 \
5702
    gen_op_extsh_T1_64();                                                     \
5703
}
5704

    
5705
#if defined(CONFIG_USER_ONLY)
5706
GEN_OP_SPE_LHE(raw);
5707
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5708
GEN_OP_SPE_LHE(le_raw);
5709
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5710
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5711
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5712
GEN_OP_SPE_LHX(raw);
5713
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5714
GEN_OP_SPE_LHX(le_raw);
5715
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5716
#if defined(TARGET_PPC64)
5717
GEN_OP_SPE_LHE(64_raw);
5718
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5719
GEN_OP_SPE_LHE(le_64_raw);
5720
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5721
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5722
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5723
GEN_OP_SPE_LHX(64_raw);
5724
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5725
GEN_OP_SPE_LHX(le_64_raw);
5726
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5727
#endif
5728
#else
5729
GEN_OP_SPE_LHE(user);
5730
GEN_OP_SPE_LHE(kernel);
5731
GEN_OP_SPE_LHE(hypv);
5732
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5733
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5734
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv);
5735
GEN_OP_SPE_LHE(le_user);
5736
GEN_OP_SPE_LHE(le_kernel);
5737
GEN_OP_SPE_LHE(le_hypv);
5738
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5739
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5740
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv);
5741
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5742
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5743
GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv);
5744
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5745
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5746
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv);
5747
GEN_OP_SPE_LHX(user);
5748
GEN_OP_SPE_LHX(kernel);
5749
GEN_OP_SPE_LHX(hypv);
5750
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5751
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5752
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv);
5753
GEN_OP_SPE_LHX(le_user);
5754
GEN_OP_SPE_LHX(le_kernel);
5755
GEN_OP_SPE_LHX(le_hypv);
5756
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5757
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5758
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv);
5759
#if defined(TARGET_PPC64)
5760
GEN_OP_SPE_LHE(64_user);
5761
GEN_OP_SPE_LHE(64_kernel);
5762
GEN_OP_SPE_LHE(64_hypv);
5763
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5764
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5765
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv);
5766
GEN_OP_SPE_LHE(le_64_user);
5767
GEN_OP_SPE_LHE(le_64_kernel);
5768
GEN_OP_SPE_LHE(le_64_hypv);
5769
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5770
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5771
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv);
5772
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5773
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5774
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv);
5775
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5776
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5777
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv);
5778
GEN_OP_SPE_LHX(64_user);
5779
GEN_OP_SPE_LHX(64_kernel);
5780
GEN_OP_SPE_LHX(64_hypv);
5781
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5782
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5783
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv);
5784
GEN_OP_SPE_LHX(le_64_user);
5785
GEN_OP_SPE_LHX(le_64_kernel);
5786
GEN_OP_SPE_LHX(le_64_hypv);
5787
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5788
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5789
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv);
5790
#endif
5791
#endif
5792
GEN_SPEOP_LD(hhesplat, 1);
5793
GEN_SPEOP_LD(hhousplat, 1);
5794
GEN_SPEOP_LD(hhossplat, 1);
5795
GEN_SPEOP_LD(wwsplat, 2);
5796
GEN_SPEOP_LD(whsplat, 2);
5797

    
5798
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5799
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5800
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5801
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5802
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5803
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5804
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5805
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5806
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5807
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5808
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5809
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5810
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5811
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5812
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5813
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5814
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5815
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5816

    
5817
/* Multiply and add - TODO */
5818
#if 0
5819
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5820
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5821
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5822
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5823
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5824
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5825
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5826
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5827
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5828
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5829
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5830
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5831

5832
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5833
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5834
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5835
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5836
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5837
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5838
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5839
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5840
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5841
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5842
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5843
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5844
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5845
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5846

5847
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5848
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5849
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5850
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5851
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5852
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5853

5854
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5855
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5856
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5857
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5858
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5859
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5860
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5861
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5862
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5863
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5864
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5865
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5866

5867
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5868
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5869
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5870
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5871
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5872

5873
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5874
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5875
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5876
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5877
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5878
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5879
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5880
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5881
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5882
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5883
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5884
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5885

5886
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5887
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5888
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5889
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5890
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5891
#endif
5892

    
5893
/***                      SPE floating-point extension                     ***/
5894
#define GEN_SPEFPUOP_CONV(name)                                               \
5895
static always_inline void gen_##name (DisasContext *ctx)                      \
5896
{                                                                             \
5897
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5898
    gen_op_##name();                                                          \
5899
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5900
}
5901

    
5902
/* Single precision floating-point vectors operations */
5903
/* Arithmetic */
5904
GEN_SPEOP_ARITH2(evfsadd);
5905
GEN_SPEOP_ARITH2(evfssub);
5906
GEN_SPEOP_ARITH2(evfsmul);
5907
GEN_SPEOP_ARITH2(evfsdiv);
5908
GEN_SPEOP_ARITH1(evfsabs);
5909
GEN_SPEOP_ARITH1(evfsnabs);
5910
GEN_SPEOP_ARITH1(evfsneg);
5911
/* Conversion */
5912
GEN_SPEFPUOP_CONV(evfscfui);
5913
GEN_SPEFPUOP_CONV(evfscfsi);
5914
GEN_SPEFPUOP_CONV(evfscfuf);
5915
GEN_SPEFPUOP_CONV(evfscfsf);
5916
GEN_SPEFPUOP_CONV(evfsctui);
5917
GEN_SPEFPUOP_CONV(evfsctsi);
5918
GEN_SPEFPUOP_CONV(evfsctuf);
5919
GEN_SPEFPUOP_CONV(evfsctsf);
5920
GEN_SPEFPUOP_CONV(evfsctuiz);
5921
GEN_SPEFPUOP_CONV(evfsctsiz);
5922
/* Comparison */
5923
GEN_SPEOP_COMP(evfscmpgt);
5924
GEN_SPEOP_COMP(evfscmplt);
5925
GEN_SPEOP_COMP(evfscmpeq);
5926
GEN_SPEOP_COMP(evfststgt);
5927
GEN_SPEOP_COMP(evfststlt);
5928
GEN_SPEOP_COMP(evfststeq);
5929

    
5930
/* Opcodes definitions */
5931
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5932
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5933
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5934
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5935
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5936
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5937
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5938
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5939
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5940
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5941
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5942
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5943
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5944
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5945

    
5946
/* Single precision floating-point operations */
5947
/* Arithmetic */
5948
GEN_SPEOP_ARITH2(efsadd);
5949
GEN_SPEOP_ARITH2(efssub);
5950
GEN_SPEOP_ARITH2(efsmul);
5951
GEN_SPEOP_ARITH2(efsdiv);
5952
GEN_SPEOP_ARITH1(efsabs);
5953
GEN_SPEOP_ARITH1(efsnabs);
5954
GEN_SPEOP_ARITH1(efsneg);
5955
/* Conversion */
5956
GEN_SPEFPUOP_CONV(efscfui);
5957
GEN_SPEFPUOP_CONV(efscfsi);
5958
GEN_SPEFPUOP_CONV(efscfuf);
5959
GEN_SPEFPUOP_CONV(efscfsf);
5960
GEN_SPEFPUOP_CONV(efsctui);
5961
GEN_SPEFPUOP_CONV(efsctsi);
5962
GEN_SPEFPUOP_CONV(efsctuf);
5963
GEN_SPEFPUOP_CONV(efsctsf);
5964
GEN_SPEFPUOP_CONV(efsctuiz);
5965
GEN_SPEFPUOP_CONV(efsctsiz);
5966
GEN_SPEFPUOP_CONV(efscfd);
5967
/* Comparison */
5968
GEN_SPEOP_COMP(efscmpgt);
5969
GEN_SPEOP_COMP(efscmplt);
5970
GEN_SPEOP_COMP(efscmpeq);
5971
GEN_SPEOP_COMP(efststgt);
5972
GEN_SPEOP_COMP(efststlt);
5973
GEN_SPEOP_COMP(efststeq);
5974

    
5975
/* Opcodes definitions */
5976
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
5977
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5978
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5979
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5980
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5981
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5982
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5983
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5984
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5985
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5986
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5987
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5988
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5989

    
5990
/* Double precision floating-point operations */
5991
/* Arithmetic */
5992
GEN_SPEOP_ARITH2(efdadd);
5993
GEN_SPEOP_ARITH2(efdsub);
5994
GEN_SPEOP_ARITH2(efdmul);
5995
GEN_SPEOP_ARITH2(efddiv);
5996
GEN_SPEOP_ARITH1(efdabs);
5997
GEN_SPEOP_ARITH1(efdnabs);
5998
GEN_SPEOP_ARITH1(efdneg);
5999
/* Conversion */
6000

    
6001
GEN_SPEFPUOP_CONV(efdcfui);
6002
GEN_SPEFPUOP_CONV(efdcfsi);
6003
GEN_SPEFPUOP_CONV(efdcfuf);
6004
GEN_SPEFPUOP_CONV(efdcfsf);
6005
GEN_SPEFPUOP_CONV(efdctui);
6006
GEN_SPEFPUOP_CONV(efdctsi);
6007
GEN_SPEFPUOP_CONV(efdctuf);
6008
GEN_SPEFPUOP_CONV(efdctsf);
6009
GEN_SPEFPUOP_CONV(efdctuiz);
6010
GEN_SPEFPUOP_CONV(efdctsiz);
6011
GEN_SPEFPUOP_CONV(efdcfs);
6012
GEN_SPEFPUOP_CONV(efdcfuid);
6013
GEN_SPEFPUOP_CONV(efdcfsid);
6014
GEN_SPEFPUOP_CONV(efdctuidz);
6015
GEN_SPEFPUOP_CONV(efdctsidz);
6016
/* Comparison */
6017
GEN_SPEOP_COMP(efdcmpgt);
6018
GEN_SPEOP_COMP(efdcmplt);
6019
GEN_SPEOP_COMP(efdcmpeq);
6020
GEN_SPEOP_COMP(efdtstgt);
6021
GEN_SPEOP_COMP(efdtstlt);
6022
GEN_SPEOP_COMP(efdtsteq);
6023

    
6024
/* Opcodes definitions */
6025
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
6026
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
6027
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
6028
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
6029
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
6030
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
6031
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
6032
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
6033
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
6034
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
6035
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
6036
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
6037
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
6038
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
6039
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
6040
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6041

    
6042
/* End opcode list */
6043
GEN_OPCODE_MARK(end);
6044

    
6045
#include "translate_init.c"
6046
#include "helper_regs.h"
6047

    
6048
/*****************************************************************************/
6049
/* Misc PowerPC helpers */
6050
void cpu_dump_state (CPUState *env, FILE *f,
6051
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6052
                     int flags)
6053
{
6054
#define RGPL  4
6055
#define RFPL  4
6056

    
6057
    int i;
6058

    
6059
    cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
6060
                env->nip, env->lr, env->ctr, hreg_load_xer(env));
6061
    cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
6062
                env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
6063
#if !defined(NO_TIMER_DUMP)
6064
    cpu_fprintf(f, "TB %08x %08x "
6065
#if !defined(CONFIG_USER_ONLY)
6066
                "DECR %08x"
6067
#endif
6068
                "\n",
6069
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6070
#if !defined(CONFIG_USER_ONLY)
6071
                , cpu_ppc_load_decr(env)
6072
#endif
6073
                );
6074
#endif
6075
    for (i = 0; i < 32; i++) {
6076
        if ((i & (RGPL - 1)) == 0)
6077
            cpu_fprintf(f, "GPR%02d", i);
6078
        cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
6079
        if ((i & (RGPL - 1)) == (RGPL - 1))
6080
            cpu_fprintf(f, "\n");
6081
    }
6082
    cpu_fprintf(f, "CR ");
6083
    for (i = 0; i < 8; i++)
6084
        cpu_fprintf(f, "%01x", env->crf[i]);
6085
    cpu_fprintf(f, "  [");
6086
    for (i = 0; i < 8; i++) {
6087
        char a = '-';
6088
        if (env->crf[i] & 0x08)
6089
            a = 'L';
6090
        else if (env->crf[i] & 0x04)
6091
            a = 'G';
6092
        else if (env->crf[i] & 0x02)
6093
            a = 'E';
6094
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6095
    }
6096
    cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
6097
    for (i = 0; i < 32; i++) {
6098
        if ((i & (RFPL - 1)) == 0)
6099
            cpu_fprintf(f, "FPR%02d", i);
6100
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6101
        if ((i & (RFPL - 1)) == (RFPL - 1))
6102
            cpu_fprintf(f, "\n");
6103
    }
6104
#if !defined(CONFIG_USER_ONLY)
6105
    cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
6106
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6107
#endif
6108

    
6109
#undef RGPL
6110
#undef RFPL
6111
}
6112

    
6113
void cpu_dump_statistics (CPUState *env, FILE*f,
6114
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6115
                          int flags)
6116
{
6117
#if defined(DO_PPC_STATISTICS)
6118
    opc_handler_t **t1, **t2, **t3, *handler;
6119
    int op1, op2, op3;
6120

    
6121
    t1 = env->opcodes;
6122
    for (op1 = 0; op1 < 64; op1++) {
6123
        handler = t1[op1];
6124
        if (is_indirect_opcode(handler)) {
6125
            t2 = ind_table(handler);
6126
            for (op2 = 0; op2 < 32; op2++) {
6127
                handler = t2[op2];
6128
                if (is_indirect_opcode(handler)) {
6129
                    t3 = ind_table(handler);
6130
                    for (op3 = 0; op3 < 32; op3++) {
6131
                        handler = t3[op3];
6132
                        if (handler->count == 0)
6133
                            continue;
6134
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6135
                                    "%016llx %lld\n",
6136
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6137
                                    handler->oname,
6138
                                    handler->count, handler->count);
6139
                    }
6140
                } else {
6141
                    if (handler->count == 0)
6142
                        continue;
6143
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6144
                                "%016llx %lld\n",
6145
                                op1, op2, op1, op2, handler->oname,
6146
                                handler->count, handler->count);
6147
                }
6148
            }
6149
        } else {
6150
            if (handler->count == 0)
6151
                continue;
6152
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6153
                        op1, op1, handler->oname,
6154
                        handler->count, handler->count);
6155
        }
6156
    }
6157
#endif
6158
}
6159

    
6160
/*****************************************************************************/
6161
static always_inline int gen_intermediate_code_internal (CPUState *env,
6162
                                                         TranslationBlock *tb,
6163
                                                         int search_pc)
6164
{
6165
    DisasContext ctx, *ctxp = &ctx;
6166
    opc_handler_t **table, *handler;
6167
    target_ulong pc_start;
6168
    uint16_t *gen_opc_end;
6169
    int supervisor, little_endian;
6170
    int j, lj = -1;
6171

    
6172
    pc_start = tb->pc;
6173
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6174
#if defined(OPTIMIZE_FPRF_UPDATE)
6175
    gen_fprf_ptr = gen_fprf_buf;
6176
#endif
6177
    ctx.nip = pc_start;
6178
    ctx.tb = tb;
6179
    ctx.exception = POWERPC_EXCP_NONE;
6180
    ctx.spr_cb = env->spr_cb;
6181
    supervisor = env->mmu_idx;
6182
#if !defined(CONFIG_USER_ONLY)
6183
    ctx.supervisor = supervisor;
6184
#endif
6185
    little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
6186
#if defined(TARGET_PPC64)
6187
    ctx.sf_mode = msr_sf;
6188
    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
6189
#else
6190
    ctx.mem_idx = (supervisor << 1) | little_endian;
6191
#endif
6192
    ctx.dcache_line_size = env->dcache_line_size;
6193
    ctx.fpu_enabled = msr_fp;
6194
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
6195
        ctx.spe_enabled = msr_spe;
6196
    else
6197
        ctx.spe_enabled = 0;
6198
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
6199
        ctx.altivec_enabled = msr_vr;
6200
    else
6201
        ctx.altivec_enabled = 0;
6202
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6203
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
6204
    else
6205
        ctx.singlestep_enabled = 0;
6206
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
6207
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
6208
    if (unlikely(env->singlestep_enabled))
6209
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
6210
#if defined (DO_SINGLE_STEP) && 0
6211
    /* Single step trace mode */
6212
    msr_se = 1;
6213
#endif
6214
    /* Set env in case of segfault during code fetch */
6215
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
6216
        if (unlikely(env->nb_breakpoints > 0)) {
6217
            for (j = 0; j < env->nb_breakpoints; j++) {
6218
                if (env->breakpoints[j] == ctx.nip) {
6219
                    gen_update_nip(&ctx, ctx.nip);
6220
                    gen_op_debug();
6221
                    break;
6222
                }
6223
            }
6224
        }
6225
        if (unlikely(search_pc)) {
6226
            j = gen_opc_ptr - gen_opc_buf;
6227
            if (lj < j) {
6228
                lj++;
6229
                while (lj < j)
6230
                    gen_opc_instr_start[lj++] = 0;
6231
                gen_opc_pc[lj] = ctx.nip;
6232
                gen_opc_instr_start[lj] = 1;
6233
            }
6234
        }
6235
#if defined PPC_DEBUG_DISAS
6236
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6237
            fprintf(logfile, "----------------\n");
6238
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6239
                    ctx.nip, supervisor, (int)msr_ir);
6240
        }
6241
#endif
6242
        if (unlikely(little_endian)) {
6243
            ctx.opcode = bswap32(ldl_code(ctx.nip));
6244
        } else {
6245
            ctx.opcode = ldl_code(ctx.nip);
6246
        }
6247
#if defined PPC_DEBUG_DISAS
6248
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6249
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6250
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6251
                    opc3(ctx.opcode), little_endian ? "little" : "big");
6252
        }
6253
#endif
6254
        ctx.nip += 4;
6255
        table = env->opcodes;
6256
        handler = table[opc1(ctx.opcode)];
6257
        if (is_indirect_opcode(handler)) {
6258
            table = ind_table(handler);
6259
            handler = table[opc2(ctx.opcode)];
6260
            if (is_indirect_opcode(handler)) {
6261
                table = ind_table(handler);
6262
                handler = table[opc3(ctx.opcode)];
6263
            }
6264
        }
6265
        /* Is opcode *REALLY* valid ? */
6266
        if (unlikely(handler->handler == &gen_invalid)) {
6267
            if (loglevel != 0) {
6268
                fprintf(logfile, "invalid/unsupported opcode: "
6269
                        "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6270
                        opc1(ctx.opcode), opc2(ctx.opcode),
6271
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6272
            } else {
6273
                printf("invalid/unsupported opcode: "
6274
                       "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6275
                       opc1(ctx.opcode), opc2(ctx.opcode),
6276
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6277
            }
6278
        } else {
6279
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6280
                if (loglevel != 0) {
6281
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6282
                            "%02x - %02x - %02x (%08x) " ADDRX "\n",
6283
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6284
                            opc2(ctx.opcode), opc3(ctx.opcode),
6285
                            ctx.opcode, ctx.nip - 4);
6286
                } else {
6287
                    printf("invalid bits: %08x for opcode: "
6288
                           "%02x - %02x - %02x (%08x) " ADDRX "\n",
6289
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6290
                           opc2(ctx.opcode), opc3(ctx.opcode),
6291
                           ctx.opcode, ctx.nip - 4);
6292
                }
6293
                GEN_EXCP_INVAL(ctxp);
6294
                break;
6295
            }
6296
        }
6297
        (*(handler->handler))(&ctx);
6298
#if defined(DO_PPC_STATISTICS)
6299
        handler->count++;
6300
#endif
6301
        /* Check trace mode exceptions */
6302
        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
6303
                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
6304
                     ctx.exception != POWERPC_SYSCALL &&
6305
                     ctx.exception != POWERPC_EXCP_TRAP &&
6306
                     ctx.exception != POWERPC_EXCP_BRANCH)) {
6307
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6308
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6309
                            (env->singlestep_enabled))) {
6310
            /* if we reach a page boundary or are single stepping, stop
6311
             * generation
6312
             */
6313
            break;
6314
        }
6315
#if defined (DO_SINGLE_STEP)
6316
        break;
6317
#endif
6318
    }
6319
    if (ctx.exception == POWERPC_EXCP_NONE) {
6320
        gen_goto_tb(&ctx, 0, ctx.nip);
6321
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6322
        if (unlikely(env->singlestep_enabled)) {
6323
            gen_update_nip(&ctx, ctx.nip);
6324
            gen_op_debug();
6325
        }
6326
        /* Generate the return instruction */
6327
        tcg_gen_exit_tb(0);
6328
    }
6329
    *gen_opc_ptr = INDEX_op_end;
6330
    if (unlikely(search_pc)) {
6331
        j = gen_opc_ptr - gen_opc_buf;
6332
        lj++;
6333
        while (lj <= j)
6334
            gen_opc_instr_start[lj++] = 0;
6335
    } else {
6336
        tb->size = ctx.nip - pc_start;
6337
    }
6338
#if defined(DEBUG_DISAS)
6339
    if (loglevel & CPU_LOG_TB_CPU) {
6340
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6341
        cpu_dump_state(env, logfile, fprintf, 0);
6342
    }
6343
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6344
        int flags;
6345
        flags = env->bfd_mach;
6346
        flags |= little_endian << 16;
6347
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6348
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6349
        fprintf(logfile, "\n");
6350
    }
6351
#endif
6352
    return 0;
6353
}
6354

    
6355
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6356
{
6357
    return gen_intermediate_code_internal(env, tb, 0);
6358
}
6359

    
6360
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6361
{
6362
    return gen_intermediate_code_internal(env, tb, 1);
6363
}
6364

    
6365
void gen_pc_load(CPUState *env, TranslationBlock *tb,
6366
                unsigned long searched_pc, int pc_pos, void *puc)
6367
{
6368
    int type, c;
6369
    /* for PPC, we need to look at the micro operation to get the
6370
     * access type */
6371
    env->nip = gen_opc_pc[pc_pos];
6372
    c = gen_opc_buf[pc_pos];
6373
    switch(c) {
6374
#if defined(CONFIG_USER_ONLY)
6375
#define CASE3(op)\
6376
    case INDEX_op_ ## op ## _raw
6377
#else
6378
#define CASE3(op)\
6379
    case INDEX_op_ ## op ## _user:\
6380
    case INDEX_op_ ## op ## _kernel:\
6381
    case INDEX_op_ ## op ## _hypv
6382
#endif
6383

    
6384
    CASE3(stfd):
6385
    CASE3(stfs):
6386
    CASE3(lfd):
6387
    CASE3(lfs):
6388
        type = ACCESS_FLOAT;
6389
        break;
6390
    CASE3(lwarx):
6391
        type = ACCESS_RES;
6392
        break;
6393
    CASE3(stwcx):
6394
        type = ACCESS_RES;
6395
        break;
6396
    CASE3(eciwx):
6397
    CASE3(ecowx):
6398
        type = ACCESS_EXT;
6399
        break;
6400
    default:
6401
        type = ACCESS_INT;
6402
        break;
6403
    }
6404
    env->access_type = type;
6405
}