Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 57fec1fe

History | View | Annotate | Download (219.4 kB)

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

    
26
#include "cpu.h"
27
#include "exec-all.h"
28
#include "disas.h"
29
#include "tcg-op.h"
30

    
31
/* Include definitions for instructions classes and implementations flags */
32
//#define DO_SINGLE_STEP
33
//#define PPC_DEBUG_DISAS
34
//#define DEBUG_MEMORY_ACCESSES
35
//#define DO_PPC_STATISTICS
36
//#define OPTIMIZE_FPRF_UPDATE
37

    
38
/*****************************************************************************/
39
/* Code translation helpers                                                  */
40

    
41
#if defined(OPTIMIZE_FPRF_UPDATE)
42
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
43
static uint16_t **gen_fprf_ptr;
44
#endif
45

    
46
static always_inline void gen_set_T0 (target_ulong val)
47
{
48
#if defined(TARGET_PPC64)
49
    if (val >> 32)
50
        gen_op_set_T0_64(val >> 32, val);
51
    else
52
#endif
53
        gen_op_set_T0(val);
54
}
55

    
56
static always_inline void gen_set_T1 (target_ulong val)
57
{
58
#if defined(TARGET_PPC64)
59
    if (val >> 32)
60
        gen_op_set_T1_64(val >> 32, val);
61
    else
62
#endif
63
        gen_op_set_T1(val);
64
}
65

    
66
#define GEN8(func, NAME)                                                      \
67
static GenOpFunc *NAME ## _table [8] = {                                      \
68
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
69
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
70
};                                                                            \
71
static always_inline void func (int n)                                        \
72
{                                                                             \
73
    NAME ## _table[n]();                                                      \
74
}
75

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

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

    
104
/* Condition register moves */
105
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
106
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
107
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
108
#if 0 // Unused
109
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
110
#endif
111

    
112
/* General purpose registers moves */
113
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
114
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
115
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
116

    
117
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
118
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
119
#if 0 // unused
120
GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
121
#endif
122

    
123
/* floating point registers moves */
124
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
125
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
126
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
127
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
128
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
129
#if 0 // unused
130
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
131
#endif
132

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

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

    
171
static always_inline void gen_set_Rc0 (DisasContext *ctx)
172
{
173
#if defined(TARGET_PPC64)
174
    if (ctx->sf_mode)
175
        gen_op_cmpi_64(0);
176
    else
177
#endif
178
        gen_op_cmpi(0);
179
    gen_op_set_Rc0();
180
}
181

    
182
static always_inline void gen_reset_fpstatus (void)
183
{
184
#ifdef CONFIG_SOFTFLOAT
185
    gen_op_reset_fpstatus();
186
#endif
187
}
188

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

    
209
static always_inline void gen_optimize_fprf (void)
210
{
211
#if defined(OPTIMIZE_FPRF_UPDATE)
212
    uint16_t **ptr;
213

    
214
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
215
        *ptr = INDEX_op_nop1;
216
    gen_fprf_ptr = gen_fprf_buf;
217
#endif
218
}
219

    
220
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
221
{
222
#if defined(TARGET_PPC64)
223
    if (ctx->sf_mode)
224
        gen_op_update_nip_64(nip >> 32, nip);
225
    else
226
#endif
227
        gen_op_update_nip(nip);
228
}
229

    
230
#define GEN_EXCP(ctx, excp, error)                                            \
231
do {                                                                          \
232
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
233
        gen_update_nip(ctx, (ctx)->nip);                                      \
234
    }                                                                         \
235
    gen_op_raise_exception_err((excp), (error));                              \
236
    ctx->exception = (excp);                                                  \
237
} while (0)
238

    
239
#define GEN_EXCP_INVAL(ctx)                                                   \
240
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
241
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
242

    
243
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
244
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
245
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
246

    
247
#define GEN_EXCP_PRIVREG(ctx)                                                 \
248
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
249
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
250

    
251
#define GEN_EXCP_NO_FP(ctx)                                                   \
252
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
253

    
254
#define GEN_EXCP_NO_AP(ctx)                                                   \
255
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
256

    
257
#define GEN_EXCP_NO_VR(ctx)                                                   \
258
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
259

    
260
/* Stop translation */
261
static always_inline void GEN_STOP (DisasContext *ctx)
262
{
263
    gen_update_nip(ctx, ctx->nip);
264
    ctx->exception = POWERPC_EXCP_STOP;
265
}
266

    
267
/* No need to update nip here, as execution flow will change */
268
static always_inline void GEN_SYNC (DisasContext *ctx)
269
{
270
    ctx->exception = POWERPC_EXCP_SYNC;
271
}
272

    
273
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
274
static void gen_##name (DisasContext *ctx);                                   \
275
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
276
static void gen_##name (DisasContext *ctx)
277

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

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

    
294
/*****************************************************************************/
295
/***                           Instruction decoding                        ***/
296
#define EXTRACT_HELPER(name, shift, nb)                                       \
297
static always_inline uint32_t name (uint32_t opcode)                          \
298
{                                                                             \
299
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
300
}
301

    
302
#define EXTRACT_SHELPER(name, shift, nb)                                      \
303
static always_inline int32_t name (uint32_t opcode)                           \
304
{                                                                             \
305
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
306
}
307

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

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

    
357
EXTRACT_HELPER(CRM, 12, 8);
358
EXTRACT_HELPER(FM, 17, 8);
359
EXTRACT_HELPER(SR, 16, 4);
360
EXTRACT_HELPER(FPIMM, 20, 4);
361

    
362
/***                            Jump target decoding                       ***/
363
/* Displacement */
364
EXTRACT_SHELPER(d, 0, 16);
365
/* Immediate address */
366
static always_inline target_ulong LI (uint32_t opcode)
367
{
368
    return (opcode >> 0) & 0x03FFFFFC;
369
}
370

    
371
static always_inline uint32_t BD (uint32_t opcode)
372
{
373
    return (opcode >> 0) & 0xFFFC;
374
}
375

    
376
EXTRACT_HELPER(BO, 21, 5);
377
EXTRACT_HELPER(BI, 16, 5);
378
/* Absolute/relative address */
379
EXTRACT_HELPER(AA, 1, 1);
380
/* Link */
381
EXTRACT_HELPER(LK, 0, 1);
382

    
383
/* Create a mask between <start> and <end> bits */
384
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
385
{
386
    target_ulong ret;
387

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

    
408
    return ret;
409
}
410

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

    
447
    /* Fixed-point unit extensions                                           */
448
    /*   PowerPC 602 specific                                                */
449
    PPC_602_SPEC       = 0x0000000000000400ULL,
450
    /*   isel instruction                                                    */
451
    PPC_ISEL           = 0x0000000000000800ULL,
452
    /*   popcntb instruction                                                 */
453
    PPC_POPCNTB        = 0x0000000000001000ULL,
454
    /*   string load / store                                                 */
455
    PPC_STRING         = 0x0000000000002000ULL,
456

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

    
469
    /* Vector/SIMD extensions                                                */
470
    /*   Altivec support                                                     */
471
    PPC_ALTIVEC        = 0x0000000001000000ULL,
472
    /*   PowerPC 2.03 SPE extension                                          */
473
    PPC_SPE            = 0x0000000002000000ULL,
474
    /*   PowerPC 2.03 SPE floating-point extension                           */
475
    PPC_SPEFPU         = 0x0000000004000000ULL,
476

    
477
    /* Optional memory control instructions                                  */
478
    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
479
    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
480
    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
481
    /*   sync instruction                                                    */
482
    PPC_MEM_SYNC       = 0x0000000080000000ULL,
483
    /*   eieio instruction                                                   */
484
    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
485

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

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

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

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

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

    
620
#define GEN_OPCODE_MARK(name)                                                 \
621
OPCODES_SECTION opcode_t opc_##name = {                                       \
622
    .opc1 = 0xFF,                                                             \
623
    .opc2 = 0xFF,                                                             \
624
    .opc3 = 0xFF,                                                             \
625
    .pad  = { 0, },                                                           \
626
    .handler = {                                                              \
627
        .inval   = 0x00000000,                                                \
628
        .type = 0x00,                                                         \
629
        .handler = NULL,                                                      \
630
    },                                                                        \
631
    .oname = stringify(name),                                                 \
632
}
633

    
634
/* Start opcode list */
635
GEN_OPCODE_MARK(start);
636

    
637
/* Invalid instruction */
638
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
639
{
640
    GEN_EXCP_INVAL(ctx);
641
}
642

    
643
static opc_handler_t invalid_handler = {
644
    .inval   = 0xFFFFFFFF,
645
    .type    = PPC_NONE,
646
    .handler = gen_invalid,
647
};
648

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

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

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

    
691
/* Two operands arithmetic functions */
692
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
693
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
694
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
695

    
696
/* Two operands arithmetic functions with no overflow allowed */
697
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
698
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
699

    
700
/* One operand arithmetic functions */
701
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
702
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
703
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
704

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

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

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

    
759
/* Two operands arithmetic functions */
760
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
761
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
762
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
763

    
764
/* Two operands arithmetic functions with no overflow allowed */
765
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
766
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
767

    
768
/* One operand arithmetic functions */
769
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
770
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
771
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
772
#else
773
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
774
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
775
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
776
#endif
777

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

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

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

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

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

    
1054
#if defined(TARGET_PPC64)
1055
/* mulhd  mulhd.                   */
1056
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
1057
/* mulhdu mulhdu.                  */
1058
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
1059
/* mulld  mulld.  mulldo  mulldo.  */
1060
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
1061
/* divd   divd.   divdo   divdo.   */
1062
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
1063
/* divdu  divdu.  divduo  divduo.  */
1064
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
1065
#endif
1066

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

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

    
1120
/* isel (PowerPC 2.03 specification) */
1121
GEN_HANDLER(isel, 0x1F, 0x0F, 0x00, 0x00000001, PPC_ISEL)
1122
{
1123
    uint32_t bi = rC(ctx->opcode);
1124
    uint32_t mask;
1125

    
1126
    if (rA(ctx->opcode) == 0) {
1127
        gen_set_T0(0);
1128
    } else {
1129
        gen_op_load_gpr_T1(rA(ctx->opcode));
1130
    }
1131
    gen_op_load_gpr_T2(rB(ctx->opcode));
1132
    mask = 1 << (3 - (bi & 0x03));
1133
    gen_op_load_crf_T0(bi >> 2);
1134
    gen_op_test_true(mask);
1135
    gen_op_isel();
1136
    gen_op_store_T0_gpr(rD(ctx->opcode));
1137
}
1138

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

    
1153
#define GEN_LOGICAL1(name, opc, type)                                         \
1154
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1155
{                                                                             \
1156
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1157
    gen_op_##name();                                                          \
1158
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1159
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1160
        gen_set_Rc0(ctx);                                                     \
1161
}
1162

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

    
1184
/* cntlzw */
1185
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1186
/* eqv & eqv. */
1187
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1188
/* extsb & extsb. */
1189
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1190
/* extsh & extsh. */
1191
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1192
/* nand & nand. */
1193
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1194
/* nor & nor. */
1195
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1196

    
1197
/* or & or. */
1198
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1199
{
1200
    int rs, ra, rb;
1201

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

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

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

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

    
1318
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1319
        /* NOP */
1320
        return;
1321
    }
1322
    gen_op_load_gpr_T0(rS(ctx->opcode));
1323
    if (likely(uimm != 0))
1324
        gen_op_xori(uimm);
1325
    gen_op_store_T0_gpr(rA(ctx->opcode));
1326
}
1327

    
1328
/* xoris */
1329
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1330
{
1331
    target_ulong uimm = UIMM(ctx->opcode);
1332

    
1333
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1334
        /* NOP */
1335
        return;
1336
    }
1337
    gen_op_load_gpr_T0(rS(ctx->opcode));
1338
    if (likely(uimm != 0))
1339
        gen_op_xori(uimm << 16);
1340
    gen_op_store_T0_gpr(rA(ctx->opcode));
1341
}
1342

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

    
1356
#if defined(TARGET_PPC64)
1357
/* extsw & extsw. */
1358
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1359
/* cntlzd */
1360
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1361
#endif
1362

    
1363
/***                             Integer rotate                            ***/
1364
/* rlwimi & rlwimi. */
1365
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1366
{
1367
    target_ulong mask;
1368
    uint32_t mb, me, sh;
1369

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

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

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

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

    
1494
static always_inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1495
{
1496
    if (mask >> 32)
1497
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1498
    else
1499
        gen_op_andi_T0(mask);
1500
}
1501

    
1502
static always_inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1503
{
1504
    if (mask >> 32)
1505
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1506
    else
1507
        gen_op_andi_T1(mask);
1508
}
1509

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

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

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

    
1564
    sh = SH(ctx->opcode) | (shn << 5);
1565
    mb = MB(ctx->opcode) | (mbn << 5);
1566
    gen_rldinm(ctx, mb, 63 - sh, sh);
1567
}
1568
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1569

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

    
1584
/* rldcl - rldcl. */
1585
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1586
{
1587
    uint32_t mb;
1588

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

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

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

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

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

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

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

    
1719
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1720
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1721
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1722

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

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

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

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

    
1793
/* fadd - fadds */
1794
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1795
/* fdiv - fdivs */
1796
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1797
/* fmul - fmuls */
1798
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
1799

    
1800
/* fre */
1801
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1802

    
1803
/* fres */
1804
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1805

    
1806
/* frsqrte */
1807
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
1808

    
1809
/* frsqrtes */
1810
static always_inline void gen_op_frsqrtes (void)
1811
{
1812
    gen_op_frsqrte();
1813
    gen_op_frsp();
1814
}
1815
GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1816

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

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

    
1850
/***                     Floating-Point multiply-and-add                   ***/
1851
/* fmadd - fmadds */
1852
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1853
/* fmsub - fmsubs */
1854
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1855
/* fnmadd - fnmadds */
1856
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1857
/* fnmsub - fnmsubs */
1858
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1859

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

    
1876
/* frin */
1877
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
1878
/* friz */
1879
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
1880
/* frip */
1881
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
1882
/* frim */
1883
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1884

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

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

    
1916
/***                         Floating-point move                           ***/
1917
/* fabs */
1918
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
1919
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1920

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

    
1934
/* fnabs */
1935
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
1936
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1937
/* fneg */
1938
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
1939
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1940

    
1941
/***                  Floating-Point status & ctrl register                ***/
1942
/* mcrfs */
1943
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1944
{
1945
    int bfa;
1946

    
1947
    if (unlikely(!ctx->fpu_enabled)) {
1948
        GEN_EXCP_NO_FP(ctx);
1949
        return;
1950
    }
1951
    gen_optimize_fprf();
1952
    bfa = 4 * (7 - crfS(ctx->opcode));
1953
    gen_op_load_fpscr_T0(bfa);
1954
    gen_op_store_T0_crf(crfD(ctx->opcode));
1955
    gen_op_fpscr_resetbit(~(0xF << bfa));
1956
}
1957

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

    
1972
/* mtfsb0 */
1973
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1974
{
1975
    uint8_t crb;
1976

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

    
1992
/* mtfsb1 */
1993
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1994
{
1995
    uint8_t crb;
1996

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

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

    
2034
/* mtfsfi */
2035
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2036
{
2037
    int bf, sh;
2038

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

    
2057
/***                           Addressing modes                            ***/
2058
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2059
static always_inline void gen_addr_imm_index (DisasContext *ctx,
2060
                                              target_long maskl)
2061
{
2062
    target_long simm = SIMM(ctx->opcode);
2063

    
2064
    simm &= ~maskl;
2065
    if (rA(ctx->opcode) == 0) {
2066
        gen_set_T0(simm);
2067
    } else {
2068
        gen_op_load_gpr_T0(rA(ctx->opcode));
2069
        if (likely(simm != 0))
2070
            gen_op_addi(simm);
2071
    }
2072
#ifdef DEBUG_MEMORY_ACCESSES
2073
    gen_op_print_mem_EA();
2074
#endif
2075
}
2076

    
2077
static always_inline void gen_addr_reg_index (DisasContext *ctx)
2078
{
2079
    if (rA(ctx->opcode) == 0) {
2080
        gen_op_load_gpr_T0(rB(ctx->opcode));
2081
    } else {
2082
        gen_op_load_gpr_T0(rA(ctx->opcode));
2083
        gen_op_load_gpr_T1(rB(ctx->opcode));
2084
        gen_op_add();
2085
    }
2086
#ifdef DEBUG_MEMORY_ACCESSES
2087
    gen_op_print_mem_EA();
2088
#endif
2089
}
2090

    
2091
static always_inline void gen_addr_register (DisasContext *ctx)
2092
{
2093
    if (rA(ctx->opcode) == 0) {
2094
        gen_op_reset_T0();
2095
    } else {
2096
        gen_op_load_gpr_T0(rA(ctx->opcode));
2097
    }
2098
#ifdef DEBUG_MEMORY_ACCESSES
2099
    gen_op_print_mem_EA();
2100
#endif
2101
}
2102

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

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

    
2162
#define GEN_LD(width, opc, type)                                              \
2163
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2164
{                                                                             \
2165
    gen_addr_imm_index(ctx, 0);                                               \
2166
    op_ldst(l##width);                                                        \
2167
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2168
}
2169

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

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

    
2201
#define GEN_LDX(width, opc2, opc3, type)                                      \
2202
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2203
{                                                                             \
2204
    gen_addr_reg_index(ctx);                                                  \
2205
    op_ldst(l##width);                                                        \
2206
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2207
}
2208

    
2209
#define GEN_LDS(width, op, type)                                              \
2210
OP_LD_TABLE(width);                                                           \
2211
GEN_LD(width, op | 0x20, type);                                               \
2212
GEN_LDU(width, op | 0x21, type);                                              \
2213
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2214
GEN_LDX(width, 0x17, op | 0x00, type)
2215

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

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

    
2290
/***                              Integer store                            ***/
2291
#define GEN_ST(width, opc, type)                                              \
2292
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2293
{                                                                             \
2294
    gen_addr_imm_index(ctx, 0);                                               \
2295
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2296
    op_ldst(st##width);                                                       \
2297
}
2298

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

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

    
2328
#define GEN_STX(width, opc2, opc3, type)                                      \
2329
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2330
{                                                                             \
2331
    gen_addr_reg_index(ctx);                                                  \
2332
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2333
    op_ldst(st##width);                                                       \
2334
}
2335

    
2336
#define GEN_STS(width, op, type)                                              \
2337
OP_ST_TABLE(width);                                                           \
2338
GEN_ST(width, op | 0x20, type);                                               \
2339
GEN_STU(width, op | 0x21, type);                                              \
2340
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2341
GEN_STX(width, 0x17, op | 0x00, type)
2342

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

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

    
2413
/***                    Integer load and store multiple                    ***/
2414
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2415
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
2416
    GEN_MEM_FUNCS(lmw),
2417
};
2418
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
2419
    GEN_MEM_FUNCS(stmw),
2420
};
2421

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

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

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

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

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

    
2508
/* lswx */
2509
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
2510
{
2511
    int ra = rA(ctx->opcode);
2512
    int rb = rB(ctx->opcode);
2513

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

    
2524
/* stswi */
2525
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
2526
{
2527
    int nb = NB(ctx->opcode);
2528

    
2529
    /* NIP cannot be restored if the memory exception comes from an helper */
2530
    gen_update_nip(ctx, ctx->nip - 4);
2531
    gen_addr_register(ctx);
2532
    if (nb == 0)
2533
        nb = 32;
2534
    gen_op_set_T1(nb);
2535
    op_ldsts(stsw, rS(ctx->opcode));
2536
}
2537

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

    
2548
/***                        Memory synchronisation                         ***/
2549
/* eieio */
2550
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2551
{
2552
}
2553

    
2554
/* isync */
2555
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2556
{
2557
    GEN_STOP(ctx);
2558
}
2559

    
2560
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2561
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2562
static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
2563
    GEN_MEM_FUNCS(lwarx),
2564
};
2565
static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
2566
    GEN_MEM_FUNCS(stwcx),
2567
};
2568

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

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

    
2589
#if defined(TARGET_PPC64)
2590
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2591
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2592
static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
2593
    GEN_MEM_FUNCS(ldarx),
2594
};
2595
static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
2596
    GEN_MEM_FUNCS(stdcx),
2597
};
2598

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

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

    
2620
/* sync */
2621
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
2622
{
2623
}
2624

    
2625
/* wait */
2626
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2627
{
2628
    /* Stop translation, as the CPU is supposed to sleep from now */
2629
    gen_op_wait();
2630
    GEN_EXCP(ctx, EXCP_HLT, 1);
2631
}
2632

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

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

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

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

    
2692
#define GEN_LDFS(width, op, type)                                             \
2693
OP_LD_TABLE(width);                                                           \
2694
GEN_LDF(width, op | 0x20, type);                                              \
2695
GEN_LDUF(width, op | 0x21, type);                                             \
2696
GEN_LDUXF(width, op | 0x01, type);                                            \
2697
GEN_LDXF(width, 0x17, op | 0x00, type)
2698

    
2699
/* lfd lfdu lfdux lfdx */
2700
GEN_LDFS(fd, 0x12, PPC_FLOAT);
2701
/* lfs lfsu lfsux lfsx */
2702
GEN_LDFS(fs, 0x10, PPC_FLOAT);
2703

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

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

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

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

    
2763
#define GEN_STFS(width, op, type)                                             \
2764
OP_ST_TABLE(width);                                                           \
2765
GEN_STF(width, op | 0x20, type);                                              \
2766
GEN_STUF(width, op | 0x21, type);                                             \
2767
GEN_STUXF(width, op | 0x01, type);                                            \
2768
GEN_STXF(width, 0x17, op | 0x00, type)
2769

    
2770
/* stfd stfdu stfdux stfdx */
2771
GEN_STFS(fd, 0x16, PPC_FLOAT);
2772
/* stfs stfsu stfsux stfsx */
2773
GEN_STFS(fs, 0x14, PPC_FLOAT);
2774

    
2775
/* Optional: */
2776
/* stfiwx */
2777
OP_ST_TABLE(fiw);
2778
GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2779

    
2780
/***                                Branch                                 ***/
2781
static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2782
                                       target_ulong dest)
2783
{
2784
    TranslationBlock *tb;
2785
    tb = ctx->tb;
2786
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2787
        !ctx->singlestep_enabled) {
2788
        tcg_gen_goto_tb(n);
2789
        gen_set_T1(dest);
2790
#if defined(TARGET_PPC64)
2791
        if (ctx->sf_mode)
2792
            gen_op_b_T1_64();
2793
        else
2794
#endif
2795
            gen_op_b_T1();
2796
        tcg_gen_exit_tb((long)tb + n);
2797
    } else {
2798
        gen_set_T1(dest);
2799
#if defined(TARGET_PPC64)
2800
        if (ctx->sf_mode)
2801
            gen_op_b_T1_64();
2802
        else
2803
#endif
2804
            gen_op_b_T1();
2805
        if (ctx->singlestep_enabled)
2806
            gen_op_debug();
2807
        tcg_gen_exit_tb(0);
2808
    }
2809
}
2810

    
2811
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2812
{
2813
#if defined(TARGET_PPC64)
2814
    if (ctx->sf_mode != 0 && (nip >> 32))
2815
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2816
    else
2817
#endif
2818
        gen_op_setlr(ctx->nip);
2819
}
2820

    
2821
/* b ba bl bla */
2822
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2823
{
2824
    target_ulong li, target;
2825

    
2826
    /* sign extend LI */
2827
#if defined(TARGET_PPC64)
2828
    if (ctx->sf_mode)
2829
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2830
    else
2831
#endif
2832
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2833
    if (likely(AA(ctx->opcode) == 0))
2834
        target = ctx->nip + li - 4;
2835
    else
2836
        target = li;
2837
#if defined(TARGET_PPC64)
2838
    if (!ctx->sf_mode)
2839
        target = (uint32_t)target;
2840
#endif
2841
    if (LK(ctx->opcode))
2842
        gen_setlr(ctx, ctx->nip);
2843
    gen_goto_tb(ctx, 0, target);
2844
    ctx->exception = POWERPC_EXCP_BRANCH;
2845
}
2846

    
2847
#define BCOND_IM  0
2848
#define BCOND_LR  1
2849
#define BCOND_CTR 2
2850

    
2851
static always_inline void gen_bcond (DisasContext *ctx, int type)
2852
{
2853
    target_ulong target = 0;
2854
    target_ulong li;
2855
    uint32_t bo = BO(ctx->opcode);
2856
    uint32_t bi = BI(ctx->opcode);
2857
    uint32_t mask;
2858

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

    
2995
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2996
{
2997
    gen_bcond(ctx, BCOND_IM);
2998
}
2999

    
3000
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3001
{
3002
    gen_bcond(ctx, BCOND_CTR);
3003
}
3004

    
3005
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3006
{
3007
    gen_bcond(ctx, BCOND_LR);
3008
}
3009

    
3010
/***                      Condition register logical                       ***/
3011
#define GEN_CRLOGIC(op, opc)                                                  \
3012
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
3013
{                                                                             \
3014
    uint8_t bitmask;                                                          \
3015
    int sh;                                                                   \
3016
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
3017
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3018
    if (sh > 0)                                                               \
3019
        gen_op_srli_T0(sh);                                                   \
3020
    else if (sh < 0)                                                          \
3021
        gen_op_sli_T0(-sh);                                                   \
3022
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
3023
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3024
    if (sh > 0)                                                               \
3025
        gen_op_srli_T1(sh);                                                   \
3026
    else if (sh < 0)                                                          \
3027
        gen_op_sli_T1(-sh);                                                   \
3028
    gen_op_##op();                                                            \
3029
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3030
    gen_op_andi_T0(bitmask);                                                  \
3031
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
3032
    gen_op_andi_T1(~bitmask);                                                 \
3033
    gen_op_or();                                                              \
3034
    gen_op_store_T0_crf(crbD(ctx->opcode) >> 2);                              \
3035
}
3036

    
3037
/* crand */
3038
GEN_CRLOGIC(and, 0x08);
3039
/* crandc */
3040
GEN_CRLOGIC(andc, 0x04);
3041
/* creqv */
3042
GEN_CRLOGIC(eqv, 0x09);
3043
/* crnand */
3044
GEN_CRLOGIC(nand, 0x07);
3045
/* crnor */
3046
GEN_CRLOGIC(nor, 0x01);
3047
/* cror */
3048
GEN_CRLOGIC(or, 0x0E);
3049
/* crorc */
3050
GEN_CRLOGIC(orc, 0x0D);
3051
/* crxor */
3052
GEN_CRLOGIC(xor, 0x06);
3053
/* mcrf */
3054
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3055
{
3056
    gen_op_load_crf_T0(crfS(ctx->opcode));
3057
    gen_op_store_T0_crf(crfD(ctx->opcode));
3058
}
3059

    
3060
/***                           System linkage                              ***/
3061
/* rfi (supervisor only) */
3062
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3063
{
3064
#if defined(CONFIG_USER_ONLY)
3065
    GEN_EXCP_PRIVOPC(ctx);
3066
#else
3067
    /* Restore CPU state */
3068
    if (unlikely(!ctx->supervisor)) {
3069
        GEN_EXCP_PRIVOPC(ctx);
3070
        return;
3071
    }
3072
    gen_op_rfi();
3073
    GEN_SYNC(ctx);
3074
#endif
3075
}
3076

    
3077
#if defined(TARGET_PPC64)
3078
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3079
{
3080
#if defined(CONFIG_USER_ONLY)
3081
    GEN_EXCP_PRIVOPC(ctx);
3082
#else
3083
    /* Restore CPU state */
3084
    if (unlikely(!ctx->supervisor)) {
3085
        GEN_EXCP_PRIVOPC(ctx);
3086
        return;
3087
    }
3088
    gen_op_rfid();
3089
    GEN_SYNC(ctx);
3090
#endif
3091
}
3092

    
3093
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3094
{
3095
#if defined(CONFIG_USER_ONLY)
3096
    GEN_EXCP_PRIVOPC(ctx);
3097
#else
3098
    /* Restore CPU state */
3099
    if (unlikely(ctx->supervisor <= 1)) {
3100
        GEN_EXCP_PRIVOPC(ctx);
3101
        return;
3102
    }
3103
    gen_op_hrfid();
3104
    GEN_SYNC(ctx);
3105
#endif
3106
}
3107
#endif
3108

    
3109
/* sc */
3110
#if defined(CONFIG_USER_ONLY)
3111
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3112
#else
3113
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3114
#endif
3115
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3116
{
3117
    uint32_t lev;
3118

    
3119
    lev = (ctx->opcode >> 5) & 0x7F;
3120
    GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
3121
}
3122

    
3123
/***                                Trap                                   ***/
3124
/* tw */
3125
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3126
{
3127
    gen_op_load_gpr_T0(rA(ctx->opcode));
3128
    gen_op_load_gpr_T1(rB(ctx->opcode));
3129
    /* Update the nip since this might generate a trap exception */
3130
    gen_update_nip(ctx, ctx->nip);
3131
    gen_op_tw(TO(ctx->opcode));
3132
}
3133

    
3134
/* twi */
3135
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3136
{
3137
    gen_op_load_gpr_T0(rA(ctx->opcode));
3138
    gen_set_T1(SIMM(ctx->opcode));
3139
    /* Update the nip since this might generate a trap exception */
3140
    gen_update_nip(ctx, ctx->nip);
3141
    gen_op_tw(TO(ctx->opcode));
3142
}
3143

    
3144
#if defined(TARGET_PPC64)
3145
/* td */
3146
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3147
{
3148
    gen_op_load_gpr_T0(rA(ctx->opcode));
3149
    gen_op_load_gpr_T1(rB(ctx->opcode));
3150
    /* Update the nip since this might generate a trap exception */
3151
    gen_update_nip(ctx, ctx->nip);
3152
    gen_op_td(TO(ctx->opcode));
3153
}
3154

    
3155
/* tdi */
3156
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3157
{
3158
    gen_op_load_gpr_T0(rA(ctx->opcode));
3159
    gen_set_T1(SIMM(ctx->opcode));
3160
    /* Update the nip since this might generate a trap exception */
3161
    gen_update_nip(ctx, ctx->nip);
3162
    gen_op_td(TO(ctx->opcode));
3163
}
3164
#endif
3165

    
3166
/***                          Processor control                            ***/
3167
/* mcrxr */
3168
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3169
{
3170
    gen_op_load_xer_cr();
3171
    gen_op_store_T0_crf(crfD(ctx->opcode));
3172
    gen_op_clear_xer_ov();
3173
    gen_op_clear_xer_ca();
3174
}
3175

    
3176
/* mfcr */
3177
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3178
{
3179
    uint32_t crm, crn;
3180

    
3181
    if (likely(ctx->opcode & 0x00100000)) {
3182
        crm = CRM(ctx->opcode);
3183
        if (likely((crm ^ (crm - 1)) == 0)) {
3184
            crn = ffs(crm);
3185
            gen_op_load_cro(7 - crn);
3186
        }
3187
    } else {
3188
        gen_op_load_cr();
3189
    }
3190
    gen_op_store_T0_gpr(rD(ctx->opcode));
3191
}
3192

    
3193
/* mfmsr */
3194
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3195
{
3196
#if defined(CONFIG_USER_ONLY)
3197
    GEN_EXCP_PRIVREG(ctx);
3198
#else
3199
    if (unlikely(!ctx->supervisor)) {
3200
        GEN_EXCP_PRIVREG(ctx);
3201
        return;
3202
    }
3203
    gen_op_load_msr();
3204
    gen_op_store_T0_gpr(rD(ctx->opcode));
3205
#endif
3206
}
3207

    
3208
#if 1
3209
#define SPR_NOACCESS ((void *)(-1UL))
3210
#else
3211
static void spr_noaccess (void *opaque, int sprn)
3212
{
3213
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3214
    printf("ERROR: try to access SPR %d !\n", sprn);
3215
}
3216
#define SPR_NOACCESS (&spr_noaccess)
3217
#endif
3218

    
3219
/* mfspr */
3220
static always_inline void gen_op_mfspr (DisasContext *ctx)
3221
{
3222
    void (*read_cb)(void *opaque, int sprn);
3223
    uint32_t sprn = SPR(ctx->opcode);
3224

    
3225
#if !defined(CONFIG_USER_ONLY)
3226
    if (ctx->supervisor == 2)
3227
        read_cb = ctx->spr_cb[sprn].hea_read;
3228
    else if (ctx->supervisor)
3229
        read_cb = ctx->spr_cb[sprn].oea_read;
3230
    else
3231
#endif
3232
        read_cb = ctx->spr_cb[sprn].uea_read;
3233
    if (likely(read_cb != NULL)) {
3234
        if (likely(read_cb != SPR_NOACCESS)) {
3235
            (*read_cb)(ctx, sprn);
3236
            gen_op_store_T0_gpr(rD(ctx->opcode));
3237
        } else {
3238
            /* Privilege exception */
3239
            /* This is a hack to avoid warnings when running Linux:
3240
             * this OS breaks the PowerPC virtualisation model,
3241
             * allowing userland application to read the PVR
3242
             */
3243
            if (sprn != SPR_PVR) {
3244
                if (loglevel != 0) {
3245
                    fprintf(logfile, "Trying to read privileged spr %d %03x at "
3246
                            ADDRX "\n", sprn, sprn, ctx->nip);
3247
                }
3248
                printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
3249
                       sprn, sprn, ctx->nip);
3250
            }
3251
            GEN_EXCP_PRIVREG(ctx);
3252
        }
3253
    } else {
3254
        /* Not defined */
3255
        if (loglevel != 0) {
3256
            fprintf(logfile, "Trying to read invalid spr %d %03x at "
3257
                    ADDRX "\n", sprn, sprn, ctx->nip);
3258
        }
3259
        printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
3260
               sprn, sprn, ctx->nip);
3261
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3262
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3263
    }
3264
}
3265

    
3266
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3267
{
3268
    gen_op_mfspr(ctx);
3269
}
3270

    
3271
/* mftb */
3272
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3273
{
3274
    gen_op_mfspr(ctx);
3275
}
3276

    
3277
/* mtcrf */
3278
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3279
{
3280
    uint32_t crm, crn;
3281

    
3282
    gen_op_load_gpr_T0(rS(ctx->opcode));
3283
    crm = CRM(ctx->opcode);
3284
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3285
        crn = ffs(crm);
3286
        gen_op_srli_T0(crn * 4);
3287
        gen_op_andi_T0(0xF);
3288
        gen_op_store_cro(7 - crn);
3289
    } else {
3290
        gen_op_store_cr(crm);
3291
    }
3292
}
3293

    
3294
/* mtmsr */
3295
#if defined(TARGET_PPC64)
3296
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3297
{
3298
#if defined(CONFIG_USER_ONLY)
3299
    GEN_EXCP_PRIVREG(ctx);
3300
#else
3301
    if (unlikely(!ctx->supervisor)) {
3302
        GEN_EXCP_PRIVREG(ctx);
3303
        return;
3304
    }
3305
    gen_op_load_gpr_T0(rS(ctx->opcode));
3306
    if (ctx->opcode & 0x00010000) {
3307
        /* Special form that does not need any synchronisation */
3308
        gen_op_update_riee();
3309
    } else {
3310
        /* XXX: we need to update nip before the store
3311
         *      if we enter power saving mode, we will exit the loop
3312
         *      directly from ppc_store_msr
3313
         */
3314
        gen_update_nip(ctx, ctx->nip);
3315
        gen_op_store_msr();
3316
        /* Must stop the translation as machine state (may have) changed */
3317
        /* Note that mtmsr is not always defined as context-synchronizing */
3318
        ctx->exception = POWERPC_EXCP_STOP;
3319
    }
3320
#endif
3321
}
3322
#endif
3323

    
3324
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3325
{
3326
#if defined(CONFIG_USER_ONLY)
3327
    GEN_EXCP_PRIVREG(ctx);
3328
#else
3329
    if (unlikely(!ctx->supervisor)) {
3330
        GEN_EXCP_PRIVREG(ctx);
3331
        return;
3332
    }
3333
    gen_op_load_gpr_T0(rS(ctx->opcode));
3334
    if (ctx->opcode & 0x00010000) {
3335
        /* Special form that does not need any synchronisation */
3336
        gen_op_update_riee();
3337
    } else {
3338
        /* XXX: we need to update nip before the store
3339
         *      if we enter power saving mode, we will exit the loop
3340
         *      directly from ppc_store_msr
3341
         */
3342
        gen_update_nip(ctx, ctx->nip);
3343
#if defined(TARGET_PPC64)
3344
        if (!ctx->sf_mode)
3345
            gen_op_store_msr_32();
3346
        else
3347
#endif
3348
            gen_op_store_msr();
3349
        /* Must stop the translation as machine state (may have) changed */
3350
        /* Note that mtmsrd is not always defined as context-synchronizing */
3351
        ctx->exception = POWERPC_EXCP_STOP;
3352
    }
3353
#endif
3354
}
3355

    
3356
/* mtspr */
3357
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3358
{
3359
    void (*write_cb)(void *opaque, int sprn);
3360
    uint32_t sprn = SPR(ctx->opcode);
3361

    
3362
#if !defined(CONFIG_USER_ONLY)
3363
    if (ctx->supervisor == 2)
3364
        write_cb = ctx->spr_cb[sprn].hea_write;
3365
    else if (ctx->supervisor)
3366
        write_cb = ctx->spr_cb[sprn].oea_write;
3367
    else
3368
#endif
3369
        write_cb = ctx->spr_cb[sprn].uea_write;
3370
    if (likely(write_cb != NULL)) {
3371
        if (likely(write_cb != SPR_NOACCESS)) {
3372
            gen_op_load_gpr_T0(rS(ctx->opcode));
3373
            (*write_cb)(ctx, sprn);
3374
        } else {
3375
            /* Privilege exception */
3376
            if (loglevel != 0) {
3377
                fprintf(logfile, "Trying to write privileged spr %d %03x at "
3378
                        ADDRX "\n", sprn, sprn, ctx->nip);
3379
            }
3380
            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
3381
                   sprn, sprn, ctx->nip);
3382
            GEN_EXCP_PRIVREG(ctx);
3383
        }
3384
    } else {
3385
        /* Not defined */
3386
        if (loglevel != 0) {
3387
            fprintf(logfile, "Trying to write invalid spr %d %03x at "
3388
                    ADDRX "\n", sprn, sprn, ctx->nip);
3389
        }
3390
        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
3391
               sprn, sprn, ctx->nip);
3392
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3393
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3394
    }
3395
}
3396

    
3397
/***                         Cache management                              ***/
3398
/* dcbf */
3399
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3400
{
3401
    /* XXX: specification says this is treated as a load by the MMU */
3402
    gen_addr_reg_index(ctx);
3403
    op_ldst(lbz);
3404
}
3405

    
3406
/* dcbi (Supervisor only) */
3407
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3408
{
3409
#if defined(CONFIG_USER_ONLY)
3410
    GEN_EXCP_PRIVOPC(ctx);
3411
#else
3412
    if (unlikely(!ctx->supervisor)) {
3413
        GEN_EXCP_PRIVOPC(ctx);
3414
        return;
3415
    }
3416
    gen_addr_reg_index(ctx);
3417
    /* XXX: specification says this should be treated as a store by the MMU */
3418
    op_ldst(lbz);
3419
    op_ldst(stb);
3420
#endif
3421
}
3422

    
3423
/* dcdst */
3424
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3425
{
3426
    /* XXX: specification say this is treated as a load by the MMU */
3427
    gen_addr_reg_index(ctx);
3428
    op_ldst(lbz);
3429
}
3430

    
3431
/* dcbt */
3432
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3433
{
3434
    /* interpreted as no-op */
3435
    /* XXX: specification say this is treated as a load by the MMU
3436
     *      but does not generate any exception
3437
     */
3438
}
3439

    
3440
/* dcbtst */
3441
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3442
{
3443
    /* interpreted as no-op */
3444
    /* XXX: specification say this is treated as a load by the MMU
3445
     *      but does not generate any exception
3446
     */
3447
}
3448

    
3449
/* dcbz */
3450
#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
3451
static GenOpFunc *gen_op_dcbz[4][NB_MEM_FUNCS] = {
3452
    /* 32 bytes cache line size */
3453
    {
3454
#define gen_op_dcbz_l32_le_raw        gen_op_dcbz_l32_raw
3455
#define gen_op_dcbz_l32_le_user       gen_op_dcbz_l32_user
3456
#define gen_op_dcbz_l32_le_kernel     gen_op_dcbz_l32_kernel
3457
#define gen_op_dcbz_l32_le_hypv       gen_op_dcbz_l32_hypv
3458
#define gen_op_dcbz_l32_le_64_raw     gen_op_dcbz_l32_64_raw
3459
#define gen_op_dcbz_l32_le_64_user    gen_op_dcbz_l32_64_user
3460
#define gen_op_dcbz_l32_le_64_kernel  gen_op_dcbz_l32_64_kernel
3461
#define gen_op_dcbz_l32_le_64_hypv    gen_op_dcbz_l32_64_hypv
3462
        GEN_MEM_FUNCS(dcbz_l32),
3463
    },
3464
    /* 64 bytes cache line size */
3465
    {
3466
#define gen_op_dcbz_l64_le_raw        gen_op_dcbz_l64_raw
3467
#define gen_op_dcbz_l64_le_user       gen_op_dcbz_l64_user
3468
#define gen_op_dcbz_l64_le_kernel     gen_op_dcbz_l64_kernel
3469
#define gen_op_dcbz_l64_le_hypv       gen_op_dcbz_l64_hypv
3470
#define gen_op_dcbz_l64_le_64_raw     gen_op_dcbz_l64_64_raw
3471
#define gen_op_dcbz_l64_le_64_user    gen_op_dcbz_l64_64_user
3472
#define gen_op_dcbz_l64_le_64_kernel  gen_op_dcbz_l64_64_kernel
3473
#define gen_op_dcbz_l64_le_64_hypv    gen_op_dcbz_l64_64_hypv
3474
        GEN_MEM_FUNCS(dcbz_l64),
3475
    },
3476
    /* 128 bytes cache line size */
3477
    {
3478
#define gen_op_dcbz_l128_le_raw       gen_op_dcbz_l128_raw
3479
#define gen_op_dcbz_l128_le_user      gen_op_dcbz_l128_user
3480
#define gen_op_dcbz_l128_le_kernel    gen_op_dcbz_l128_kernel
3481
#define gen_op_dcbz_l128_le_hypv      gen_op_dcbz_l128_hypv
3482
#define gen_op_dcbz_l128_le_64_raw    gen_op_dcbz_l128_64_raw
3483
#define gen_op_dcbz_l128_le_64_user   gen_op_dcbz_l128_64_user
3484
#define gen_op_dcbz_l128_le_64_kernel gen_op_dcbz_l128_64_kernel
3485
#define gen_op_dcbz_l128_le_64_hypv   gen_op_dcbz_l128_64_hypv
3486
        GEN_MEM_FUNCS(dcbz_l128),
3487
    },
3488
    /* tunable cache line size */
3489
    {
3490
#define gen_op_dcbz_le_raw            gen_op_dcbz_raw
3491
#define gen_op_dcbz_le_user           gen_op_dcbz_user
3492
#define gen_op_dcbz_le_kernel         gen_op_dcbz_kernel
3493
#define gen_op_dcbz_le_hypv           gen_op_dcbz_hypv
3494
#define gen_op_dcbz_le_64_raw         gen_op_dcbz_64_raw
3495
#define gen_op_dcbz_le_64_user        gen_op_dcbz_64_user
3496
#define gen_op_dcbz_le_64_kernel      gen_op_dcbz_64_kernel
3497
#define gen_op_dcbz_le_64_hypv        gen_op_dcbz_64_hypv
3498
        GEN_MEM_FUNCS(dcbz),
3499
    },
3500
};
3501

    
3502
static always_inline void handler_dcbz (DisasContext *ctx,
3503
                                        int dcache_line_size)
3504
{
3505
    int n;
3506

    
3507
    switch (dcache_line_size) {
3508
    case 32:
3509
        n = 0;
3510
        break;
3511
    case 64:
3512
        n = 1;
3513
        break;
3514
    case 128:
3515
        n = 2;
3516
        break;
3517
    default:
3518
        n = 3;
3519
        break;
3520
    }
3521
    op_dcbz(n);
3522
}
3523

    
3524
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
3525
{
3526
    gen_addr_reg_index(ctx);
3527
    handler_dcbz(ctx, ctx->dcache_line_size);
3528
    gen_op_check_reservation();
3529
}
3530

    
3531
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
3532
{
3533
    gen_addr_reg_index(ctx);
3534
    if (ctx->opcode & 0x00200000)
3535
        handler_dcbz(ctx, ctx->dcache_line_size);
3536
    else
3537
        handler_dcbz(ctx, -1);
3538
    gen_op_check_reservation();
3539
}
3540

    
3541
/* icbi */
3542
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3543
#define gen_op_icbi_le_raw       gen_op_icbi_raw
3544
#define gen_op_icbi_le_user      gen_op_icbi_user
3545
#define gen_op_icbi_le_kernel    gen_op_icbi_kernel
3546
#define gen_op_icbi_le_hypv      gen_op_icbi_hypv
3547
#define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
3548
#define gen_op_icbi_le_64_user   gen_op_icbi_64_user
3549
#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
3550
#define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
3551
static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
3552
    GEN_MEM_FUNCS(icbi),
3553
};
3554

    
3555
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
3556
{
3557
    /* NIP cannot be restored if the memory exception comes from an helper */
3558
    gen_update_nip(ctx, ctx->nip - 4);
3559
    gen_addr_reg_index(ctx);
3560
    op_icbi();
3561
}
3562

    
3563
/* Optional: */
3564
/* dcba */
3565
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3566
{
3567
    /* interpreted as no-op */
3568
    /* XXX: specification say this is treated as a store by the MMU
3569
     *      but does not generate any exception
3570
     */
3571
}
3572

    
3573
/***                    Segment register manipulation                      ***/
3574
/* Supervisor only: */
3575
/* mfsr */
3576
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3577
{
3578
#if defined(CONFIG_USER_ONLY)
3579
    GEN_EXCP_PRIVREG(ctx);
3580
#else
3581
    if (unlikely(!ctx->supervisor)) {
3582
        GEN_EXCP_PRIVREG(ctx);
3583
        return;
3584
    }
3585
    gen_op_set_T1(SR(ctx->opcode));
3586
    gen_op_load_sr();
3587
    gen_op_store_T0_gpr(rD(ctx->opcode));
3588
#endif
3589
}
3590

    
3591
/* mfsrin */
3592
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3593
{
3594
#if defined(CONFIG_USER_ONLY)
3595
    GEN_EXCP_PRIVREG(ctx);
3596
#else
3597
    if (unlikely(!ctx->supervisor)) {
3598
        GEN_EXCP_PRIVREG(ctx);
3599
        return;
3600
    }
3601
    gen_op_load_gpr_T1(rB(ctx->opcode));
3602
    gen_op_srli_T1(28);
3603
    gen_op_load_sr();
3604
    gen_op_store_T0_gpr(rD(ctx->opcode));
3605
#endif
3606
}
3607

    
3608
/* mtsr */
3609
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3610
{
3611
#if defined(CONFIG_USER_ONLY)
3612
    GEN_EXCP_PRIVREG(ctx);
3613
#else
3614
    if (unlikely(!ctx->supervisor)) {
3615
        GEN_EXCP_PRIVREG(ctx);
3616
        return;
3617
    }
3618
    gen_op_load_gpr_T0(rS(ctx->opcode));
3619
    gen_op_set_T1(SR(ctx->opcode));
3620
    gen_op_store_sr();
3621
#endif
3622
}
3623

    
3624
/* mtsrin */
3625
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3626
{
3627
#if defined(CONFIG_USER_ONLY)
3628
    GEN_EXCP_PRIVREG(ctx);
3629
#else
3630
    if (unlikely(!ctx->supervisor)) {
3631
        GEN_EXCP_PRIVREG(ctx);
3632
        return;
3633
    }
3634
    gen_op_load_gpr_T0(rS(ctx->opcode));
3635
    gen_op_load_gpr_T1(rB(ctx->opcode));
3636
    gen_op_srli_T1(28);
3637
    gen_op_store_sr();
3638
#endif
3639
}
3640

    
3641
#if defined(TARGET_PPC64)
3642
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
3643
/* mfsr */
3644
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
3645
{
3646
#if defined(CONFIG_USER_ONLY)
3647
    GEN_EXCP_PRIVREG(ctx);
3648
#else
3649
    if (unlikely(!ctx->supervisor)) {
3650
        GEN_EXCP_PRIVREG(ctx);
3651
        return;
3652
    }
3653
    gen_op_set_T1(SR(ctx->opcode));
3654
    gen_op_load_slb();
3655
    gen_op_store_T0_gpr(rD(ctx->opcode));
3656
#endif
3657
}
3658

    
3659
/* mfsrin */
3660
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
3661
             PPC_SEGMENT_64B)
3662
{
3663
#if defined(CONFIG_USER_ONLY)
3664
    GEN_EXCP_PRIVREG(ctx);
3665
#else
3666
    if (unlikely(!ctx->supervisor)) {
3667
        GEN_EXCP_PRIVREG(ctx);
3668
        return;
3669
    }
3670
    gen_op_load_gpr_T1(rB(ctx->opcode));
3671
    gen_op_srli_T1(28);
3672
    gen_op_load_slb();
3673
    gen_op_store_T0_gpr(rD(ctx->opcode));
3674
#endif
3675
}
3676

    
3677
/* mtsr */
3678
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
3679
{
3680
#if defined(CONFIG_USER_ONLY)
3681
    GEN_EXCP_PRIVREG(ctx);
3682
#else
3683
    if (unlikely(!ctx->supervisor)) {
3684
        GEN_EXCP_PRIVREG(ctx);
3685
        return;
3686
    }
3687
    gen_op_load_gpr_T0(rS(ctx->opcode));
3688
    gen_op_set_T1(SR(ctx->opcode));
3689
    gen_op_store_slb();
3690
#endif
3691
}
3692

    
3693
/* mtsrin */
3694
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
3695
             PPC_SEGMENT_64B)
3696
{
3697
#if defined(CONFIG_USER_ONLY)
3698
    GEN_EXCP_PRIVREG(ctx);
3699
#else
3700
    if (unlikely(!ctx->supervisor)) {
3701
        GEN_EXCP_PRIVREG(ctx);
3702
        return;
3703
    }
3704
    gen_op_load_gpr_T0(rS(ctx->opcode));
3705
    gen_op_load_gpr_T1(rB(ctx->opcode));
3706
    gen_op_srli_T1(28);
3707
    gen_op_store_slb();
3708
#endif
3709
}
3710
#endif /* defined(TARGET_PPC64) */
3711

    
3712
/***                      Lookaside buffer management                      ***/
3713
/* Optional & supervisor only: */
3714
/* tlbia */
3715
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3716
{
3717
#if defined(CONFIG_USER_ONLY)
3718
    GEN_EXCP_PRIVOPC(ctx);
3719
#else
3720
    if (unlikely(!ctx->supervisor)) {
3721
        GEN_EXCP_PRIVOPC(ctx);
3722
        return;
3723
    }
3724
    gen_op_tlbia();
3725
#endif
3726
}
3727

    
3728
/* tlbie */
3729
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3730
{
3731
#if defined(CONFIG_USER_ONLY)
3732
    GEN_EXCP_PRIVOPC(ctx);
3733
#else
3734
    if (unlikely(!ctx->supervisor)) {
3735
        GEN_EXCP_PRIVOPC(ctx);
3736
        return;
3737
    }
3738
    gen_op_load_gpr_T0(rB(ctx->opcode));
3739
#if defined(TARGET_PPC64)
3740
    if (ctx->sf_mode)
3741
        gen_op_tlbie_64();
3742
    else
3743
#endif
3744
        gen_op_tlbie();
3745
#endif
3746
}
3747

    
3748
/* tlbsync */
3749
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3750
{
3751
#if defined(CONFIG_USER_ONLY)
3752
    GEN_EXCP_PRIVOPC(ctx);
3753
#else
3754
    if (unlikely(!ctx->supervisor)) {
3755
        GEN_EXCP_PRIVOPC(ctx);
3756
        return;
3757
    }
3758
    /* This has no effect: it should ensure that all previous
3759
     * tlbie have completed
3760
     */
3761
    GEN_STOP(ctx);
3762
#endif
3763
}
3764

    
3765
#if defined(TARGET_PPC64)
3766
/* slbia */
3767
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
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
    gen_op_slbia();
3777
#endif
3778
}
3779

    
3780
/* slbie */
3781
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3782
{
3783
#if defined(CONFIG_USER_ONLY)
3784
    GEN_EXCP_PRIVOPC(ctx);
3785
#else
3786
    if (unlikely(!ctx->supervisor)) {
3787
        GEN_EXCP_PRIVOPC(ctx);
3788
        return;
3789
    }
3790
    gen_op_load_gpr_T0(rB(ctx->opcode));
3791
    gen_op_slbie();
3792
#endif
3793
}
3794
#endif
3795

    
3796
/***                              External control                         ***/
3797
/* Optional: */
3798
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3799
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3800
static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
3801
    GEN_MEM_FUNCS(eciwx),
3802
};
3803
static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
3804
    GEN_MEM_FUNCS(ecowx),
3805
};
3806

    
3807
/* eciwx */
3808
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3809
{
3810
    /* Should check EAR[E] & alignment ! */
3811
    gen_addr_reg_index(ctx);
3812
    op_eciwx();
3813
    gen_op_store_T0_gpr(rD(ctx->opcode));
3814
}
3815

    
3816
/* ecowx */
3817
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3818
{
3819
    /* Should check EAR[E] & alignment ! */
3820
    gen_addr_reg_index(ctx);
3821
    gen_op_load_gpr_T1(rS(ctx->opcode));
3822
    op_ecowx();
3823
}
3824

    
3825
/* PowerPC 601 specific instructions */
3826
/* abs - abs. */
3827
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3828
{
3829
    gen_op_load_gpr_T0(rA(ctx->opcode));
3830
    gen_op_POWER_abs();
3831
    gen_op_store_T0_gpr(rD(ctx->opcode));
3832
    if (unlikely(Rc(ctx->opcode) != 0))
3833
        gen_set_Rc0(ctx);
3834
}
3835

    
3836
/* abso - abso. */
3837
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3838
{
3839
    gen_op_load_gpr_T0(rA(ctx->opcode));
3840
    gen_op_POWER_abso();
3841
    gen_op_store_T0_gpr(rD(ctx->opcode));
3842
    if (unlikely(Rc(ctx->opcode) != 0))
3843
        gen_set_Rc0(ctx);
3844
}
3845

    
3846
/* clcs */
3847
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3848
{
3849
    gen_op_load_gpr_T0(rA(ctx->opcode));
3850
    gen_op_POWER_clcs();
3851
    /* Rc=1 sets CR0 to an undefined state */
3852
    gen_op_store_T0_gpr(rD(ctx->opcode));
3853
}
3854

    
3855
/* div - div. */
3856
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3857
{
3858
    gen_op_load_gpr_T0(rA(ctx->opcode));
3859
    gen_op_load_gpr_T1(rB(ctx->opcode));
3860
    gen_op_POWER_div();
3861
    gen_op_store_T0_gpr(rD(ctx->opcode));
3862
    if (unlikely(Rc(ctx->opcode) != 0))
3863
        gen_set_Rc0(ctx);
3864
}
3865

    
3866
/* divo - divo. */
3867
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3868
{
3869
    gen_op_load_gpr_T0(rA(ctx->opcode));
3870
    gen_op_load_gpr_T1(rB(ctx->opcode));
3871
    gen_op_POWER_divo();
3872
    gen_op_store_T0_gpr(rD(ctx->opcode));
3873
    if (unlikely(Rc(ctx->opcode) != 0))
3874
        gen_set_Rc0(ctx);
3875
}
3876

    
3877
/* divs - divs. */
3878
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3879
{
3880
    gen_op_load_gpr_T0(rA(ctx->opcode));
3881
    gen_op_load_gpr_T1(rB(ctx->opcode));
3882
    gen_op_POWER_divs();
3883
    gen_op_store_T0_gpr(rD(ctx->opcode));
3884
    if (unlikely(Rc(ctx->opcode) != 0))
3885
        gen_set_Rc0(ctx);
3886
}
3887

    
3888
/* divso - divso. */
3889
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3890
{
3891
    gen_op_load_gpr_T0(rA(ctx->opcode));
3892
    gen_op_load_gpr_T1(rB(ctx->opcode));
3893
    gen_op_POWER_divso();
3894
    gen_op_store_T0_gpr(rD(ctx->opcode));
3895
    if (unlikely(Rc(ctx->opcode) != 0))
3896
        gen_set_Rc0(ctx);
3897
}
3898

    
3899
/* doz - doz. */
3900
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3901
{
3902
    gen_op_load_gpr_T0(rA(ctx->opcode));
3903
    gen_op_load_gpr_T1(rB(ctx->opcode));
3904
    gen_op_POWER_doz();
3905
    gen_op_store_T0_gpr(rD(ctx->opcode));
3906
    if (unlikely(Rc(ctx->opcode) != 0))
3907
        gen_set_Rc0(ctx);
3908
}
3909

    
3910
/* dozo - dozo. */
3911
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3912
{
3913
    gen_op_load_gpr_T0(rA(ctx->opcode));
3914
    gen_op_load_gpr_T1(rB(ctx->opcode));
3915
    gen_op_POWER_dozo();
3916
    gen_op_store_T0_gpr(rD(ctx->opcode));
3917
    if (unlikely(Rc(ctx->opcode) != 0))
3918
        gen_set_Rc0(ctx);
3919
}
3920

    
3921
/* dozi */
3922
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3923
{
3924
    gen_op_load_gpr_T0(rA(ctx->opcode));
3925
    gen_op_set_T1(SIMM(ctx->opcode));
3926
    gen_op_POWER_doz();
3927
    gen_op_store_T0_gpr(rD(ctx->opcode));
3928
}
3929

    
3930
/* As lscbx load from memory byte after byte, it's always endian safe.
3931
 * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones
3932
 */
3933
#define op_POWER_lscbx(start, ra, rb)                                         \
3934
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3935
#define gen_op_POWER_lscbx_64_raw       gen_op_POWER_lscbx_raw
3936
#define gen_op_POWER_lscbx_64_user      gen_op_POWER_lscbx_user
3937
#define gen_op_POWER_lscbx_64_kernel    gen_op_POWER_lscbx_kernel
3938
#define gen_op_POWER_lscbx_64_hypv      gen_op_POWER_lscbx_hypv
3939
#define gen_op_POWER_lscbx_le_raw       gen_op_POWER_lscbx_raw
3940
#define gen_op_POWER_lscbx_le_user      gen_op_POWER_lscbx_user
3941
#define gen_op_POWER_lscbx_le_kernel    gen_op_POWER_lscbx_kernel
3942
#define gen_op_POWER_lscbx_le_hypv      gen_op_POWER_lscbx_hypv
3943
#define gen_op_POWER_lscbx_le_64_raw    gen_op_POWER_lscbx_raw
3944
#define gen_op_POWER_lscbx_le_64_user   gen_op_POWER_lscbx_user
3945
#define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel
3946
#define gen_op_POWER_lscbx_le_64_hypv   gen_op_POWER_lscbx_hypv
3947
static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = {
3948
    GEN_MEM_FUNCS(POWER_lscbx),
3949
};
3950

    
3951
/* lscbx - lscbx. */
3952
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3953
{
3954
    int ra = rA(ctx->opcode);
3955
    int rb = rB(ctx->opcode);
3956

    
3957
    gen_addr_reg_index(ctx);
3958
    if (ra == 0) {
3959
        ra = rb;
3960
    }
3961
    /* NIP cannot be restored if the memory exception comes from an helper */
3962
    gen_update_nip(ctx, ctx->nip - 4);
3963
    gen_op_load_xer_bc();
3964
    gen_op_load_xer_cmp();
3965
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3966
    gen_op_store_xer_bc();
3967
    if (unlikely(Rc(ctx->opcode) != 0))
3968
        gen_set_Rc0(ctx);
3969
}
3970

    
3971
/* maskg - maskg. */
3972
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3973
{
3974
    gen_op_load_gpr_T0(rS(ctx->opcode));
3975
    gen_op_load_gpr_T1(rB(ctx->opcode));
3976
    gen_op_POWER_maskg();
3977
    gen_op_store_T0_gpr(rA(ctx->opcode));
3978
    if (unlikely(Rc(ctx->opcode) != 0))
3979
        gen_set_Rc0(ctx);
3980
}
3981

    
3982
/* maskir - maskir. */
3983
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3984
{
3985
    gen_op_load_gpr_T0(rA(ctx->opcode));
3986
    gen_op_load_gpr_T1(rS(ctx->opcode));
3987
    gen_op_load_gpr_T2(rB(ctx->opcode));
3988
    gen_op_POWER_maskir();
3989
    gen_op_store_T0_gpr(rA(ctx->opcode));
3990
    if (unlikely(Rc(ctx->opcode) != 0))
3991
        gen_set_Rc0(ctx);
3992
}
3993

    
3994
/* mul - mul. */
3995
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
3996
{
3997
    gen_op_load_gpr_T0(rA(ctx->opcode));
3998
    gen_op_load_gpr_T1(rB(ctx->opcode));
3999
    gen_op_POWER_mul();
4000
    gen_op_store_T0_gpr(rD(ctx->opcode));
4001
    if (unlikely(Rc(ctx->opcode) != 0))
4002
        gen_set_Rc0(ctx);
4003
}
4004

    
4005
/* mulo - mulo. */
4006
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4007
{
4008
    gen_op_load_gpr_T0(rA(ctx->opcode));
4009
    gen_op_load_gpr_T1(rB(ctx->opcode));
4010
    gen_op_POWER_mulo();
4011
    gen_op_store_T0_gpr(rD(ctx->opcode));
4012
    if (unlikely(Rc(ctx->opcode) != 0))
4013
        gen_set_Rc0(ctx);
4014
}
4015

    
4016
/* nabs - nabs. */
4017
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4018
{
4019
    gen_op_load_gpr_T0(rA(ctx->opcode));
4020
    gen_op_POWER_nabs();
4021
    gen_op_store_T0_gpr(rD(ctx->opcode));
4022
    if (unlikely(Rc(ctx->opcode) != 0))
4023
        gen_set_Rc0(ctx);
4024
}
4025

    
4026
/* nabso - nabso. */
4027
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4028
{
4029
    gen_op_load_gpr_T0(rA(ctx->opcode));
4030
    gen_op_POWER_nabso();
4031
    gen_op_store_T0_gpr(rD(ctx->opcode));
4032
    if (unlikely(Rc(ctx->opcode) != 0))
4033
        gen_set_Rc0(ctx);
4034
}
4035

    
4036
/* rlmi - rlmi. */
4037
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4038
{
4039
    uint32_t mb, me;
4040

    
4041
    mb = MB(ctx->opcode);
4042
    me = ME(ctx->opcode);
4043
    gen_op_load_gpr_T0(rS(ctx->opcode));
4044
    gen_op_load_gpr_T1(rA(ctx->opcode));
4045
    gen_op_load_gpr_T2(rB(ctx->opcode));
4046
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4047
    gen_op_store_T0_gpr(rA(ctx->opcode));
4048
    if (unlikely(Rc(ctx->opcode) != 0))
4049
        gen_set_Rc0(ctx);
4050
}
4051

    
4052
/* rrib - rrib. */
4053
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4054
{
4055
    gen_op_load_gpr_T0(rS(ctx->opcode));
4056
    gen_op_load_gpr_T1(rA(ctx->opcode));
4057
    gen_op_load_gpr_T2(rB(ctx->opcode));
4058
    gen_op_POWER_rrib();
4059
    gen_op_store_T0_gpr(rA(ctx->opcode));
4060
    if (unlikely(Rc(ctx->opcode) != 0))
4061
        gen_set_Rc0(ctx);
4062
}
4063

    
4064
/* sle - sle. */
4065
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4066
{
4067
    gen_op_load_gpr_T0(rS(ctx->opcode));
4068
    gen_op_load_gpr_T1(rB(ctx->opcode));
4069
    gen_op_POWER_sle();
4070
    gen_op_store_T0_gpr(rA(ctx->opcode));
4071
    if (unlikely(Rc(ctx->opcode) != 0))
4072
        gen_set_Rc0(ctx);
4073
}
4074

    
4075
/* sleq - sleq. */
4076
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4077
{
4078
    gen_op_load_gpr_T0(rS(ctx->opcode));
4079
    gen_op_load_gpr_T1(rB(ctx->opcode));
4080
    gen_op_POWER_sleq();
4081
    gen_op_store_T0_gpr(rA(ctx->opcode));
4082
    if (unlikely(Rc(ctx->opcode) != 0))
4083
        gen_set_Rc0(ctx);
4084
}
4085

    
4086
/* sliq - sliq. */
4087
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4088
{
4089
    gen_op_load_gpr_T0(rS(ctx->opcode));
4090
    gen_op_set_T1(SH(ctx->opcode));
4091
    gen_op_POWER_sle();
4092
    gen_op_store_T0_gpr(rA(ctx->opcode));
4093
    if (unlikely(Rc(ctx->opcode) != 0))
4094
        gen_set_Rc0(ctx);
4095
}
4096

    
4097
/* slliq - slliq. */
4098
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4099
{
4100
    gen_op_load_gpr_T0(rS(ctx->opcode));
4101
    gen_op_set_T1(SH(ctx->opcode));
4102
    gen_op_POWER_sleq();
4103
    gen_op_store_T0_gpr(rA(ctx->opcode));
4104
    if (unlikely(Rc(ctx->opcode) != 0))
4105
        gen_set_Rc0(ctx);
4106
}
4107

    
4108
/* sllq - sllq. */
4109
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4110
{
4111
    gen_op_load_gpr_T0(rS(ctx->opcode));
4112
    gen_op_load_gpr_T1(rB(ctx->opcode));
4113
    gen_op_POWER_sllq();
4114
    gen_op_store_T0_gpr(rA(ctx->opcode));
4115
    if (unlikely(Rc(ctx->opcode) != 0))
4116
        gen_set_Rc0(ctx);
4117
}
4118

    
4119
/* slq - slq. */
4120
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4121
{
4122
    gen_op_load_gpr_T0(rS(ctx->opcode));
4123
    gen_op_load_gpr_T1(rB(ctx->opcode));
4124
    gen_op_POWER_slq();
4125
    gen_op_store_T0_gpr(rA(ctx->opcode));
4126
    if (unlikely(Rc(ctx->opcode) != 0))
4127
        gen_set_Rc0(ctx);
4128
}
4129

    
4130
/* sraiq - sraiq. */
4131
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4132
{
4133
    gen_op_load_gpr_T0(rS(ctx->opcode));
4134
    gen_op_set_T1(SH(ctx->opcode));
4135
    gen_op_POWER_sraq();
4136
    gen_op_store_T0_gpr(rA(ctx->opcode));
4137
    if (unlikely(Rc(ctx->opcode) != 0))
4138
        gen_set_Rc0(ctx);
4139
}
4140

    
4141
/* sraq - sraq. */
4142
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4143
{
4144
    gen_op_load_gpr_T0(rS(ctx->opcode));
4145
    gen_op_load_gpr_T1(rB(ctx->opcode));
4146
    gen_op_POWER_sraq();
4147
    gen_op_store_T0_gpr(rA(ctx->opcode));
4148
    if (unlikely(Rc(ctx->opcode) != 0))
4149
        gen_set_Rc0(ctx);
4150
}
4151

    
4152
/* sre - sre. */
4153
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4154
{
4155
    gen_op_load_gpr_T0(rS(ctx->opcode));
4156
    gen_op_load_gpr_T1(rB(ctx->opcode));
4157
    gen_op_POWER_sre();
4158
    gen_op_store_T0_gpr(rA(ctx->opcode));
4159
    if (unlikely(Rc(ctx->opcode) != 0))
4160
        gen_set_Rc0(ctx);
4161
}
4162

    
4163
/* srea - srea. */
4164
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4165
{
4166
    gen_op_load_gpr_T0(rS(ctx->opcode));
4167
    gen_op_load_gpr_T1(rB(ctx->opcode));
4168
    gen_op_POWER_srea();
4169
    gen_op_store_T0_gpr(rA(ctx->opcode));
4170
    if (unlikely(Rc(ctx->opcode) != 0))
4171
        gen_set_Rc0(ctx);
4172
}
4173

    
4174
/* sreq */
4175
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4176
{
4177
    gen_op_load_gpr_T0(rS(ctx->opcode));
4178
    gen_op_load_gpr_T1(rB(ctx->opcode));
4179
    gen_op_POWER_sreq();
4180
    gen_op_store_T0_gpr(rA(ctx->opcode));
4181
    if (unlikely(Rc(ctx->opcode) != 0))
4182
        gen_set_Rc0(ctx);
4183
}
4184

    
4185
/* sriq */
4186
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4187
{
4188
    gen_op_load_gpr_T0(rS(ctx->opcode));
4189
    gen_op_set_T1(SH(ctx->opcode));
4190
    gen_op_POWER_srq();
4191
    gen_op_store_T0_gpr(rA(ctx->opcode));
4192
    if (unlikely(Rc(ctx->opcode) != 0))
4193
        gen_set_Rc0(ctx);
4194
}
4195

    
4196
/* srliq */
4197
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4198
{
4199
    gen_op_load_gpr_T0(rS(ctx->opcode));
4200
    gen_op_load_gpr_T1(rB(ctx->opcode));
4201
    gen_op_set_T1(SH(ctx->opcode));
4202
    gen_op_POWER_srlq();
4203
    gen_op_store_T0_gpr(rA(ctx->opcode));
4204
    if (unlikely(Rc(ctx->opcode) != 0))
4205
        gen_set_Rc0(ctx);
4206
}
4207

    
4208
/* srlq */
4209
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4210
{
4211
    gen_op_load_gpr_T0(rS(ctx->opcode));
4212
    gen_op_load_gpr_T1(rB(ctx->opcode));
4213
    gen_op_POWER_srlq();
4214
    gen_op_store_T0_gpr(rA(ctx->opcode));
4215
    if (unlikely(Rc(ctx->opcode) != 0))
4216
        gen_set_Rc0(ctx);
4217
}
4218

    
4219
/* srq */
4220
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4221
{
4222
    gen_op_load_gpr_T0(rS(ctx->opcode));
4223
    gen_op_load_gpr_T1(rB(ctx->opcode));
4224
    gen_op_POWER_srq();
4225
    gen_op_store_T0_gpr(rA(ctx->opcode));
4226
    if (unlikely(Rc(ctx->opcode) != 0))
4227
        gen_set_Rc0(ctx);
4228
}
4229

    
4230
/* PowerPC 602 specific instructions */
4231
/* dsa  */
4232
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4233
{
4234
    /* XXX: TODO */
4235
    GEN_EXCP_INVAL(ctx);
4236
}
4237

    
4238
/* esa */
4239
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4240
{
4241
    /* XXX: TODO */
4242
    GEN_EXCP_INVAL(ctx);
4243
}
4244

    
4245
/* mfrom */
4246
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4247
{
4248
#if defined(CONFIG_USER_ONLY)
4249
    GEN_EXCP_PRIVOPC(ctx);
4250
#else
4251
    if (unlikely(!ctx->supervisor)) {
4252
        GEN_EXCP_PRIVOPC(ctx);
4253
        return;
4254
    }
4255
    gen_op_load_gpr_T0(rA(ctx->opcode));
4256
    gen_op_602_mfrom();
4257
    gen_op_store_T0_gpr(rD(ctx->opcode));
4258
#endif
4259
}
4260

    
4261
/* 602 - 603 - G2 TLB management */
4262
/* tlbld */
4263
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4264
{
4265
#if defined(CONFIG_USER_ONLY)
4266
    GEN_EXCP_PRIVOPC(ctx);
4267
#else
4268
    if (unlikely(!ctx->supervisor)) {
4269
        GEN_EXCP_PRIVOPC(ctx);
4270
        return;
4271
    }
4272
    gen_op_load_gpr_T0(rB(ctx->opcode));
4273
    gen_op_6xx_tlbld();
4274
#endif
4275
}
4276

    
4277
/* tlbli */
4278
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4279
{
4280
#if defined(CONFIG_USER_ONLY)
4281
    GEN_EXCP_PRIVOPC(ctx);
4282
#else
4283
    if (unlikely(!ctx->supervisor)) {
4284
        GEN_EXCP_PRIVOPC(ctx);
4285
        return;
4286
    }
4287
    gen_op_load_gpr_T0(rB(ctx->opcode));
4288
    gen_op_6xx_tlbli();
4289
#endif
4290
}
4291

    
4292
/* 74xx TLB management */
4293
/* tlbld */
4294
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4295
{
4296
#if defined(CONFIG_USER_ONLY)
4297
    GEN_EXCP_PRIVOPC(ctx);
4298
#else
4299
    if (unlikely(!ctx->supervisor)) {
4300
        GEN_EXCP_PRIVOPC(ctx);
4301
        return;
4302
    }
4303
    gen_op_load_gpr_T0(rB(ctx->opcode));
4304
    gen_op_74xx_tlbld();
4305
#endif
4306
}
4307

    
4308
/* tlbli */
4309
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4310
{
4311
#if defined(CONFIG_USER_ONLY)
4312
    GEN_EXCP_PRIVOPC(ctx);
4313
#else
4314
    if (unlikely(!ctx->supervisor)) {
4315
        GEN_EXCP_PRIVOPC(ctx);
4316
        return;
4317
    }
4318
    gen_op_load_gpr_T0(rB(ctx->opcode));
4319
    gen_op_74xx_tlbli();
4320
#endif
4321
}
4322

    
4323
/* POWER instructions not in PowerPC 601 */
4324
/* clf */
4325
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4326
{
4327
    /* Cache line flush: implemented as no-op */
4328
}
4329

    
4330
/* cli */
4331
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4332
{
4333
    /* Cache line invalidate: privileged and treated as no-op */
4334
#if defined(CONFIG_USER_ONLY)
4335
    GEN_EXCP_PRIVOPC(ctx);
4336
#else
4337
    if (unlikely(!ctx->supervisor)) {
4338
        GEN_EXCP_PRIVOPC(ctx);
4339
        return;
4340
    }
4341
#endif
4342
}
4343

    
4344
/* dclst */
4345
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4346
{
4347
    /* Data cache line store: treated as no-op */
4348
}
4349

    
4350
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4351
{
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
    int ra = rA(ctx->opcode);
4360
    int rd = rD(ctx->opcode);
4361

    
4362
    gen_addr_reg_index(ctx);
4363
    gen_op_POWER_mfsri();
4364
    gen_op_store_T0_gpr(rd);
4365
    if (ra != 0 && ra != rd)
4366
        gen_op_store_T1_gpr(ra);
4367
#endif
4368
}
4369

    
4370
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4371
{
4372
#if defined(CONFIG_USER_ONLY)
4373
    GEN_EXCP_PRIVOPC(ctx);
4374
#else
4375
    if (unlikely(!ctx->supervisor)) {
4376
        GEN_EXCP_PRIVOPC(ctx);
4377
        return;
4378
    }
4379
    gen_addr_reg_index(ctx);
4380
    gen_op_POWER_rac();
4381
    gen_op_store_T0_gpr(rD(ctx->opcode));
4382
#endif
4383
}
4384

    
4385
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4386
{
4387
#if defined(CONFIG_USER_ONLY)
4388
    GEN_EXCP_PRIVOPC(ctx);
4389
#else
4390
    if (unlikely(!ctx->supervisor)) {
4391
        GEN_EXCP_PRIVOPC(ctx);
4392
        return;
4393
    }
4394
    gen_op_POWER_rfsvc();
4395
    GEN_SYNC(ctx);
4396
#endif
4397
}
4398

    
4399
/* svc is not implemented for now */
4400

    
4401
/* POWER2 specific instructions */
4402
/* Quad manipulation (load/store two floats at a time) */
4403
/* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
4404
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4405
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4406
#define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
4407
#define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
4408
#define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
4409
#define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
4410
#define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
4411
#define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
4412
#define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
4413
#define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
4414
#define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
4415
#define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
4416
#define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
4417
#define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
4418
#define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
4419
#define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
4420
#define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
4421
#define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
4422
static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
4423
    GEN_MEM_FUNCS(POWER2_lfq),
4424
};
4425
static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
4426
    GEN_MEM_FUNCS(POWER2_stfq),
4427
};
4428

    
4429
/* lfq */
4430
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4431
{
4432
    /* NIP cannot be restored if the memory exception comes from an helper */
4433
    gen_update_nip(ctx, ctx->nip - 4);
4434
    gen_addr_imm_index(ctx, 0);
4435
    op_POWER2_lfq();
4436
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4437
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4438
}
4439

    
4440
/* lfqu */
4441
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4442
{
4443
    int ra = rA(ctx->opcode);
4444

    
4445
    /* NIP cannot be restored if the memory exception comes from an helper */
4446
    gen_update_nip(ctx, ctx->nip - 4);
4447
    gen_addr_imm_index(ctx, 0);
4448
    op_POWER2_lfq();
4449
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4450
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4451
    if (ra != 0)
4452
        gen_op_store_T0_gpr(ra);
4453
}
4454

    
4455
/* lfqux */
4456
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4457
{
4458
    int ra = rA(ctx->opcode);
4459

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

    
4470
/* lfqx */
4471
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4472
{
4473
    /* NIP cannot be restored if the memory exception comes from an helper */
4474
    gen_update_nip(ctx, ctx->nip - 4);
4475
    gen_addr_reg_index(ctx);
4476
    op_POWER2_lfq();
4477
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4478
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4479
}
4480

    
4481
/* stfq */
4482
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4483
{
4484
    /* NIP cannot be restored if the memory exception comes from an helper */
4485
    gen_update_nip(ctx, ctx->nip - 4);
4486
    gen_addr_imm_index(ctx, 0);
4487
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4488
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4489
    op_POWER2_stfq();
4490
}
4491

    
4492
/* stfqu */
4493
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4494
{
4495
    int ra = rA(ctx->opcode);
4496

    
4497
    /* NIP cannot be restored if the memory exception comes from an helper */
4498
    gen_update_nip(ctx, ctx->nip - 4);
4499
    gen_addr_imm_index(ctx, 0);
4500
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4501
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4502
    op_POWER2_stfq();
4503
    if (ra != 0)
4504
        gen_op_store_T0_gpr(ra);
4505
}
4506

    
4507
/* stfqux */
4508
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4509
{
4510
    int ra = rA(ctx->opcode);
4511

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

    
4522
/* stfqx */
4523
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4524
{
4525
    /* NIP cannot be restored if the memory exception comes from an helper */
4526
    gen_update_nip(ctx, ctx->nip - 4);
4527
    gen_addr_reg_index(ctx);
4528
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4529
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4530
    op_POWER2_stfq();
4531
}
4532

    
4533
/* BookE specific instructions */
4534
/* XXX: not implemented on 440 ? */
4535
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
4536
{
4537
    /* XXX: TODO */
4538
    GEN_EXCP_INVAL(ctx);
4539
}
4540

    
4541
/* XXX: not implemented on 440 ? */
4542
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
4543
{
4544
#if defined(CONFIG_USER_ONLY)
4545
    GEN_EXCP_PRIVOPC(ctx);
4546
#else
4547
    if (unlikely(!ctx->supervisor)) {
4548
        GEN_EXCP_PRIVOPC(ctx);
4549
        return;
4550
    }
4551
    gen_addr_reg_index(ctx);
4552
    /* Use the same micro-ops as for tlbie */
4553
#if defined(TARGET_PPC64)
4554
    if (ctx->sf_mode)
4555
        gen_op_tlbie_64();
4556
    else
4557
#endif
4558
        gen_op_tlbie();
4559
#endif
4560
}
4561

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

    
4644
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4645
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4646
{                                                                             \
4647
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4648
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4649
}
4650

    
4651
/* macchw    - macchw.    */
4652
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4653
/* macchwo   - macchwo.   */
4654
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4655
/* macchws   - macchws.   */
4656
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4657
/* macchwso  - macchwso.  */
4658
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4659
/* macchwsu  - macchwsu.  */
4660
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4661
/* macchwsuo - macchwsuo. */
4662
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4663
/* macchwu   - macchwu.   */
4664
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4665
/* macchwuo  - macchwuo.  */
4666
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4667
/* machhw    - machhw.    */
4668
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4669
/* machhwo   - machhwo.   */
4670
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4671
/* machhws   - machhws.   */
4672
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4673
/* machhwso  - machhwso.  */
4674
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4675
/* machhwsu  - machhwsu.  */
4676
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4677
/* machhwsuo - machhwsuo. */
4678
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4679
/* machhwu   - machhwu.   */
4680
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4681
/* machhwuo  - machhwuo.  */
4682
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4683
/* maclhw    - maclhw.    */
4684
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4685
/* maclhwo   - maclhwo.   */
4686
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4687
/* maclhws   - maclhws.   */
4688
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4689
/* maclhwso  - maclhwso.  */
4690
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4691
/* maclhwu   - maclhwu.   */
4692
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4693
/* maclhwuo  - maclhwuo.  */
4694
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4695
/* maclhwsu  - maclhwsu.  */
4696
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4697
/* maclhwsuo - maclhwsuo. */
4698
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4699
/* nmacchw   - nmacchw.   */
4700
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4701
/* nmacchwo  - nmacchwo.  */
4702
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4703
/* nmacchws  - nmacchws.  */
4704
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4705
/* nmacchwso - nmacchwso. */
4706
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4707
/* nmachhw   - nmachhw.   */
4708
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4709
/* nmachhwo  - nmachhwo.  */
4710
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4711
/* nmachhws  - nmachhws.  */
4712
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4713
/* nmachhwso - nmachhwso. */
4714
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4715
/* nmaclhw   - nmaclhw.   */
4716
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4717
/* nmaclhwo  - nmaclhwo.  */
4718
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4719
/* nmaclhws  - nmaclhws.  */
4720
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4721
/* nmaclhwso - nmaclhwso. */
4722
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4723

    
4724
/* mulchw  - mulchw.  */
4725
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4726
/* mulchwu - mulchwu. */
4727
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4728
/* mulhhw  - mulhhw.  */
4729
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4730
/* mulhhwu - mulhhwu. */
4731
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4732
/* mullhw  - mullhw.  */
4733
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4734
/* mullhwu - mullhwu. */
4735
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4736

    
4737
/* mfdcr */
4738
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
4739
{
4740
#if defined(CONFIG_USER_ONLY)
4741
    GEN_EXCP_PRIVREG(ctx);
4742
#else
4743
    uint32_t dcrn = SPR(ctx->opcode);
4744

    
4745
    if (unlikely(!ctx->supervisor)) {
4746
        GEN_EXCP_PRIVREG(ctx);
4747
        return;
4748
    }
4749
    gen_op_set_T0(dcrn);
4750
    gen_op_load_dcr();
4751
    gen_op_store_T0_gpr(rD(ctx->opcode));
4752
#endif
4753
}
4754

    
4755
/* mtdcr */
4756
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 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_gpr_T1(rS(ctx->opcode));
4769
    gen_op_store_dcr();
4770
#endif
4771
}
4772

    
4773
/* mfdcrx */
4774
/* XXX: not implemented on 440 ? */
4775
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
4776
{
4777
#if defined(CONFIG_USER_ONLY)
4778
    GEN_EXCP_PRIVREG(ctx);
4779
#else
4780
    if (unlikely(!ctx->supervisor)) {
4781
        GEN_EXCP_PRIVREG(ctx);
4782
        return;
4783
    }
4784
    gen_op_load_gpr_T0(rA(ctx->opcode));
4785
    gen_op_load_dcr();
4786
    gen_op_store_T0_gpr(rD(ctx->opcode));
4787
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4788
#endif
4789
}
4790

    
4791
/* mtdcrx */
4792
/* XXX: not implemented on 440 ? */
4793
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 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_gpr_T1(rS(ctx->opcode));
4804
    gen_op_store_dcr();
4805
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4806
#endif
4807
}
4808

    
4809
/* mfdcrux (PPC 460) : user-mode access to DCR */
4810
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4811
{
4812
    gen_op_load_gpr_T0(rA(ctx->opcode));
4813
    gen_op_load_dcr();
4814
    gen_op_store_T0_gpr(rD(ctx->opcode));
4815
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4816
}
4817

    
4818
/* mtdcrux (PPC 460) : user-mode access to DCR */
4819
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4820
{
4821
    gen_op_load_gpr_T0(rA(ctx->opcode));
4822
    gen_op_load_gpr_T1(rS(ctx->opcode));
4823
    gen_op_store_dcr();
4824
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4825
}
4826

    
4827
/* dccci */
4828
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4829
{
4830
#if defined(CONFIG_USER_ONLY)
4831
    GEN_EXCP_PRIVOPC(ctx);
4832
#else
4833
    if (unlikely(!ctx->supervisor)) {
4834
        GEN_EXCP_PRIVOPC(ctx);
4835
        return;
4836
    }
4837
    /* interpreted as no-op */
4838
#endif
4839
}
4840

    
4841
/* dcread */
4842
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4843
{
4844
#if defined(CONFIG_USER_ONLY)
4845
    GEN_EXCP_PRIVOPC(ctx);
4846
#else
4847
    if (unlikely(!ctx->supervisor)) {
4848
        GEN_EXCP_PRIVOPC(ctx);
4849
        return;
4850
    }
4851
    gen_addr_reg_index(ctx);
4852
    op_ldst(lwz);
4853
    gen_op_store_T0_gpr(rD(ctx->opcode));
4854
#endif
4855
}
4856

    
4857
/* icbt */
4858
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4859
{
4860
    /* interpreted as no-op */
4861
    /* XXX: specification say this is treated as a load by the MMU
4862
     *      but does not generate any exception
4863
     */
4864
}
4865

    
4866
/* iccci */
4867
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4868
{
4869
#if defined(CONFIG_USER_ONLY)
4870
    GEN_EXCP_PRIVOPC(ctx);
4871
#else
4872
    if (unlikely(!ctx->supervisor)) {
4873
        GEN_EXCP_PRIVOPC(ctx);
4874
        return;
4875
    }
4876
    /* interpreted as no-op */
4877
#endif
4878
}
4879

    
4880
/* icread */
4881
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4882
{
4883
#if defined(CONFIG_USER_ONLY)
4884
    GEN_EXCP_PRIVOPC(ctx);
4885
#else
4886
    if (unlikely(!ctx->supervisor)) {
4887
        GEN_EXCP_PRIVOPC(ctx);
4888
        return;
4889
    }
4890
    /* interpreted as no-op */
4891
#endif
4892
}
4893

    
4894
/* rfci (supervisor only) */
4895
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4896
{
4897
#if defined(CONFIG_USER_ONLY)
4898
    GEN_EXCP_PRIVOPC(ctx);
4899
#else
4900
    if (unlikely(!ctx->supervisor)) {
4901
        GEN_EXCP_PRIVOPC(ctx);
4902
        return;
4903
    }
4904
    /* Restore CPU state */
4905
    gen_op_40x_rfci();
4906
    GEN_SYNC(ctx);
4907
#endif
4908
}
4909

    
4910
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4911
{
4912
#if defined(CONFIG_USER_ONLY)
4913
    GEN_EXCP_PRIVOPC(ctx);
4914
#else
4915
    if (unlikely(!ctx->supervisor)) {
4916
        GEN_EXCP_PRIVOPC(ctx);
4917
        return;
4918
    }
4919
    /* Restore CPU state */
4920
    gen_op_rfci();
4921
    GEN_SYNC(ctx);
4922
#endif
4923
}
4924

    
4925
/* BookE specific */
4926
/* XXX: not implemented on 440 ? */
4927
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
4928
{
4929
#if defined(CONFIG_USER_ONLY)
4930
    GEN_EXCP_PRIVOPC(ctx);
4931
#else
4932
    if (unlikely(!ctx->supervisor)) {
4933
        GEN_EXCP_PRIVOPC(ctx);
4934
        return;
4935
    }
4936
    /* Restore CPU state */
4937
    gen_op_rfdi();
4938
    GEN_SYNC(ctx);
4939
#endif
4940
}
4941

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

    
4958
/* TLB management - PowerPC 405 implementation */
4959
/* tlbre */
4960
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4961
{
4962
#if defined(CONFIG_USER_ONLY)
4963
    GEN_EXCP_PRIVOPC(ctx);
4964
#else
4965
    if (unlikely(!ctx->supervisor)) {
4966
        GEN_EXCP_PRIVOPC(ctx);
4967
        return;
4968
    }
4969
    switch (rB(ctx->opcode)) {
4970
    case 0:
4971
        gen_op_load_gpr_T0(rA(ctx->opcode));
4972
        gen_op_4xx_tlbre_hi();
4973
        gen_op_store_T0_gpr(rD(ctx->opcode));
4974
        break;
4975
    case 1:
4976
        gen_op_load_gpr_T0(rA(ctx->opcode));
4977
        gen_op_4xx_tlbre_lo();
4978
        gen_op_store_T0_gpr(rD(ctx->opcode));
4979
        break;
4980
    default:
4981
        GEN_EXCP_INVAL(ctx);
4982
        break;
4983
    }
4984
#endif
4985
}
4986

    
4987
/* tlbsx - tlbsx. */
4988
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
4989
{
4990
#if defined(CONFIG_USER_ONLY)
4991
    GEN_EXCP_PRIVOPC(ctx);
4992
#else
4993
    if (unlikely(!ctx->supervisor)) {
4994
        GEN_EXCP_PRIVOPC(ctx);
4995
        return;
4996
    }
4997
    gen_addr_reg_index(ctx);
4998
    gen_op_4xx_tlbsx();
4999
    if (Rc(ctx->opcode))
5000
        gen_op_4xx_tlbsx_check();
5001
    gen_op_store_T0_gpr(rD(ctx->opcode));
5002
#endif
5003
}
5004

    
5005
/* tlbwe */
5006
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, 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
    switch (rB(ctx->opcode)) {
5016
    case 0:
5017
        gen_op_load_gpr_T0(rA(ctx->opcode));
5018
        gen_op_load_gpr_T1(rS(ctx->opcode));
5019
        gen_op_4xx_tlbwe_hi();
5020
        break;
5021
    case 1:
5022
        gen_op_load_gpr_T0(rA(ctx->opcode));
5023
        gen_op_load_gpr_T1(rS(ctx->opcode));
5024
        gen_op_4xx_tlbwe_lo();
5025
        break;
5026
    default:
5027
        GEN_EXCP_INVAL(ctx);
5028
        break;
5029
    }
5030
#endif
5031
}
5032

    
5033
/* TLB management - PowerPC 440 implementation */
5034
/* tlbre */
5035
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5036
{
5037
#if defined(CONFIG_USER_ONLY)
5038
    GEN_EXCP_PRIVOPC(ctx);
5039
#else
5040
    if (unlikely(!ctx->supervisor)) {
5041
        GEN_EXCP_PRIVOPC(ctx);
5042
        return;
5043
    }
5044
    switch (rB(ctx->opcode)) {
5045
    case 0:
5046
    case 1:
5047
    case 2:
5048
        gen_op_load_gpr_T0(rA(ctx->opcode));
5049
        gen_op_440_tlbre(rB(ctx->opcode));
5050
        gen_op_store_T0_gpr(rD(ctx->opcode));
5051
        break;
5052
    default:
5053
        GEN_EXCP_INVAL(ctx);
5054
        break;
5055
    }
5056
#endif
5057
}
5058

    
5059
/* tlbsx - tlbsx. */
5060
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5061
{
5062
#if defined(CONFIG_USER_ONLY)
5063
    GEN_EXCP_PRIVOPC(ctx);
5064
#else
5065
    if (unlikely(!ctx->supervisor)) {
5066
        GEN_EXCP_PRIVOPC(ctx);
5067
        return;
5068
    }
5069
    gen_addr_reg_index(ctx);
5070
    gen_op_440_tlbsx();
5071
    if (Rc(ctx->opcode))
5072
        gen_op_4xx_tlbsx_check();
5073
    gen_op_store_T0_gpr(rD(ctx->opcode));
5074
#endif
5075
}
5076

    
5077
/* tlbwe */
5078
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, 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
    switch (rB(ctx->opcode)) {
5088
    case 0:
5089
    case 1:
5090
    case 2:
5091
        gen_op_load_gpr_T0(rA(ctx->opcode));
5092
        gen_op_load_gpr_T1(rS(ctx->opcode));
5093
        gen_op_440_tlbwe(rB(ctx->opcode));
5094
        break;
5095
    default:
5096
        GEN_EXCP_INVAL(ctx);
5097
        break;
5098
    }
5099
#endif
5100
}
5101

    
5102
/* wrtee */
5103
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
5104
{
5105
#if defined(CONFIG_USER_ONLY)
5106
    GEN_EXCP_PRIVOPC(ctx);
5107
#else
5108
    if (unlikely(!ctx->supervisor)) {
5109
        GEN_EXCP_PRIVOPC(ctx);
5110
        return;
5111
    }
5112
    gen_op_load_gpr_T0(rD(ctx->opcode));
5113
    gen_op_wrte();
5114
    /* Stop translation to have a chance to raise an exception
5115
     * if we just set msr_ee to 1
5116
     */
5117
    GEN_STOP(ctx);
5118
#endif
5119
}
5120

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

    
5140
/* PowerPC 440 specific instructions */
5141
/* dlmzb */
5142
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5143
{
5144
    gen_op_load_gpr_T0(rS(ctx->opcode));
5145
    gen_op_load_gpr_T1(rB(ctx->opcode));
5146
    gen_op_440_dlmzb();
5147
    gen_op_store_T0_gpr(rA(ctx->opcode));
5148
    gen_op_store_xer_bc();
5149
    if (Rc(ctx->opcode)) {
5150
        gen_op_440_dlmzb_update_Rc();
5151
        gen_op_store_T0_crf(0);
5152
    }
5153
}
5154

    
5155
/* mbar replaces eieio on 440 */
5156
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5157
{
5158
    /* interpreted as no-op */
5159
}
5160

    
5161
/* msync replaces sync on 440 */
5162
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5163
{
5164
    /* interpreted as no-op */
5165
}
5166

    
5167
/* icbt */
5168
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5169
{
5170
    /* interpreted as no-op */
5171
    /* XXX: specification say this is treated as a load by the MMU
5172
     *      but does not generate any exception
5173
     */
5174
}
5175

    
5176
/***                      Altivec vector extension                         ***/
5177
/* Altivec registers moves */
5178
GEN32(gen_op_load_avr_A0, gen_op_load_avr_A0_avr);
5179
GEN32(gen_op_load_avr_A1, gen_op_load_avr_A1_avr);
5180
GEN32(gen_op_load_avr_A2, gen_op_load_avr_A2_avr);
5181

    
5182
GEN32(gen_op_store_A0_avr, gen_op_store_A0_avr_avr);
5183
GEN32(gen_op_store_A1_avr, gen_op_store_A1_avr_avr);
5184
#if 0 // unused
5185
GEN32(gen_op_store_A2_avr, gen_op_store_A2_avr_avr);
5186
#endif
5187

    
5188
#define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5189
#define OP_VR_LD_TABLE(name)                                                  \
5190
static GenOpFunc *gen_op_vr_l##name[NB_MEM_FUNCS] = {                         \
5191
    GEN_MEM_FUNCS(vr_l##name),                                                \
5192
};
5193
#define OP_VR_ST_TABLE(name)                                                  \
5194
static GenOpFunc *gen_op_vr_st##name[NB_MEM_FUNCS] = {                        \
5195
    GEN_MEM_FUNCS(vr_st##name),                                               \
5196
};
5197

    
5198
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5199
GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
5200
{                                                                             \
5201
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5202
        GEN_EXCP_NO_VR(ctx);                                                  \
5203
        return;                                                               \
5204
    }                                                                         \
5205
    gen_addr_reg_index(ctx);                                                  \
5206
    op_vr_ldst(vr_l##name);                                                   \
5207
    gen_op_store_A0_avr(rD(ctx->opcode));                                     \
5208
}
5209

    
5210
#define GEN_VR_STX(name, opc2, opc3)                                          \
5211
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
5212
{                                                                             \
5213
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5214
        GEN_EXCP_NO_VR(ctx);                                                  \
5215
        return;                                                               \
5216
    }                                                                         \
5217
    gen_addr_reg_index(ctx);                                                  \
5218
    gen_op_load_avr_A0(rS(ctx->opcode));                                      \
5219
    op_vr_ldst(vr_st##name);                                                  \
5220
}
5221

    
5222
OP_VR_LD_TABLE(vx);
5223
GEN_VR_LDX(vx, 0x07, 0x03);
5224
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
5225
#define gen_op_vr_lvxl gen_op_vr_lvx
5226
GEN_VR_LDX(vxl, 0x07, 0x0B);
5227

    
5228
OP_VR_ST_TABLE(vx);
5229
GEN_VR_STX(vx, 0x07, 0x07);
5230
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
5231
#define gen_op_vr_stvxl gen_op_vr_stvx
5232
GEN_VR_STX(vxl, 0x07, 0x0F);
5233

    
5234
/***                           SPE extension                               ***/
5235
/* Register moves */
5236
#if !defined(TARGET_PPC64)
5237

    
5238
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
5239
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
5240
#if 0 // unused
5241
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
5242
#endif
5243

    
5244
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
5245
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
5246
#if 0 // unused
5247
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
5248
#endif
5249

    
5250
#else /* !defined(TARGET_PPC64) */
5251

    
5252
/* No specific load/store functions: GPRs are already 64 bits */
5253
#define gen_op_load_gpr64_T0 gen_op_load_gpr_T0
5254
#define gen_op_load_gpr64_T1 gen_op_load_gpr_T1
5255
#if 0 // unused
5256
#define gen_op_load_gpr64_T2 gen_op_load_gpr_T2
5257
#endif
5258

    
5259
#define gen_op_store_T0_gpr64 gen_op_store_T0_gpr
5260
#define gen_op_store_T1_gpr64 gen_op_store_T1_gpr
5261
#if 0 // unused
5262
#define gen_op_store_T2_gpr64 gen_op_store_T2_gpr
5263
#endif
5264

    
5265
#endif /* !defined(TARGET_PPC64) */
5266

    
5267
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5268
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5269
{                                                                             \
5270
    if (Rc(ctx->opcode))                                                      \
5271
        gen_##name1(ctx);                                                     \
5272
    else                                                                      \
5273
        gen_##name0(ctx);                                                     \
5274
}
5275

    
5276
/* Handler for undefined SPE opcodes */
5277
static always_inline void gen_speundef (DisasContext *ctx)
5278
{
5279
    GEN_EXCP_INVAL(ctx);
5280
}
5281

    
5282
/* SPE load and stores */
5283
static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5284
{
5285
    target_long simm = rB(ctx->opcode);
5286

    
5287
    if (rA(ctx->opcode) == 0) {
5288
        gen_set_T0(simm << sh);
5289
    } else {
5290
        gen_op_load_gpr_T0(rA(ctx->opcode));
5291
        if (likely(simm != 0))
5292
            gen_op_addi(simm << sh);
5293
    }
5294
}
5295

    
5296
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5297
#define OP_SPE_LD_TABLE(name)                                                 \
5298
static GenOpFunc *gen_op_spe_l##name[NB_MEM_FUNCS] = {                        \
5299
    GEN_MEM_FUNCS(spe_l##name),                                               \
5300
};
5301
#define OP_SPE_ST_TABLE(name)                                                 \
5302
static GenOpFunc *gen_op_spe_st##name[NB_MEM_FUNCS] = {                       \
5303
    GEN_MEM_FUNCS(spe_st##name),                                              \
5304
};
5305

    
5306
#define GEN_SPE_LD(name, sh)                                                  \
5307
static always_inline void gen_evl##name (DisasContext *ctx)                   \
5308
{                                                                             \
5309
    if (unlikely(!ctx->spe_enabled)) {                                        \
5310
        GEN_EXCP_NO_AP(ctx);                                                  \
5311
        return;                                                               \
5312
    }                                                                         \
5313
    gen_addr_spe_imm_index(ctx, sh);                                          \
5314
    op_spe_ldst(spe_l##name);                                                 \
5315
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5316
}
5317

    
5318
#define GEN_SPE_LDX(name)                                                     \
5319
static always_inline void gen_evl##name##x (DisasContext *ctx)                \
5320
{                                                                             \
5321
    if (unlikely(!ctx->spe_enabled)) {                                        \
5322
        GEN_EXCP_NO_AP(ctx);                                                  \
5323
        return;                                                               \
5324
    }                                                                         \
5325
    gen_addr_reg_index(ctx);                                                  \
5326
    op_spe_ldst(spe_l##name);                                                 \
5327
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5328
}
5329

    
5330
#define GEN_SPEOP_LD(name, sh)                                                \
5331
OP_SPE_LD_TABLE(name);                                                        \
5332
GEN_SPE_LD(name, sh);                                                         \
5333
GEN_SPE_LDX(name)
5334

    
5335
#define GEN_SPE_ST(name, sh)                                                  \
5336
static always_inline void gen_evst##name (DisasContext *ctx)                  \
5337
{                                                                             \
5338
    if (unlikely(!ctx->spe_enabled)) {                                        \
5339
        GEN_EXCP_NO_AP(ctx);                                                  \
5340
        return;                                                               \
5341
    }                                                                         \
5342
    gen_addr_spe_imm_index(ctx, sh);                                          \
5343
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5344
    op_spe_ldst(spe_st##name);                                                \
5345
}
5346

    
5347
#define GEN_SPE_STX(name)                                                     \
5348
static always_inline void gen_evst##name##x (DisasContext *ctx)               \
5349
{                                                                             \
5350
    if (unlikely(!ctx->spe_enabled)) {                                        \
5351
        GEN_EXCP_NO_AP(ctx);                                                  \
5352
        return;                                                               \
5353
    }                                                                         \
5354
    gen_addr_reg_index(ctx);                                                  \
5355
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5356
    op_spe_ldst(spe_st##name);                                                \
5357
}
5358

    
5359
#define GEN_SPEOP_ST(name, sh)                                                \
5360
OP_SPE_ST_TABLE(name);                                                        \
5361
GEN_SPE_ST(name, sh);                                                         \
5362
GEN_SPE_STX(name)
5363

    
5364
#define GEN_SPEOP_LDST(name, sh)                                              \
5365
GEN_SPEOP_LD(name, sh);                                                       \
5366
GEN_SPEOP_ST(name, sh)
5367

    
5368
/* SPE arithmetic and logic */
5369
#define GEN_SPEOP_ARITH2(name)                                                \
5370
static always_inline void gen_##name (DisasContext *ctx)                      \
5371
{                                                                             \
5372
    if (unlikely(!ctx->spe_enabled)) {                                        \
5373
        GEN_EXCP_NO_AP(ctx);                                                  \
5374
        return;                                                               \
5375
    }                                                                         \
5376
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5377
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5378
    gen_op_##name();                                                          \
5379
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5380
}
5381

    
5382
#define GEN_SPEOP_ARITH1(name)                                                \
5383
static always_inline void gen_##name (DisasContext *ctx)                      \
5384
{                                                                             \
5385
    if (unlikely(!ctx->spe_enabled)) {                                        \
5386
        GEN_EXCP_NO_AP(ctx);                                                  \
5387
        return;                                                               \
5388
    }                                                                         \
5389
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5390
    gen_op_##name();                                                          \
5391
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5392
}
5393

    
5394
#define GEN_SPEOP_COMP(name)                                                  \
5395
static always_inline void gen_##name (DisasContext *ctx)                      \
5396
{                                                                             \
5397
    if (unlikely(!ctx->spe_enabled)) {                                        \
5398
        GEN_EXCP_NO_AP(ctx);                                                  \
5399
        return;                                                               \
5400
    }                                                                         \
5401
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5402
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5403
    gen_op_##name();                                                          \
5404
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5405
}
5406

    
5407
/* Logical */
5408
GEN_SPEOP_ARITH2(evand);
5409
GEN_SPEOP_ARITH2(evandc);
5410
GEN_SPEOP_ARITH2(evxor);
5411
GEN_SPEOP_ARITH2(evor);
5412
GEN_SPEOP_ARITH2(evnor);
5413
GEN_SPEOP_ARITH2(eveqv);
5414
GEN_SPEOP_ARITH2(evorc);
5415
GEN_SPEOP_ARITH2(evnand);
5416
GEN_SPEOP_ARITH2(evsrwu);
5417
GEN_SPEOP_ARITH2(evsrws);
5418
GEN_SPEOP_ARITH2(evslw);
5419
GEN_SPEOP_ARITH2(evrlw);
5420
GEN_SPEOP_ARITH2(evmergehi);
5421
GEN_SPEOP_ARITH2(evmergelo);
5422
GEN_SPEOP_ARITH2(evmergehilo);
5423
GEN_SPEOP_ARITH2(evmergelohi);
5424

    
5425
/* Arithmetic */
5426
GEN_SPEOP_ARITH2(evaddw);
5427
GEN_SPEOP_ARITH2(evsubfw);
5428
GEN_SPEOP_ARITH1(evabs);
5429
GEN_SPEOP_ARITH1(evneg);
5430
GEN_SPEOP_ARITH1(evextsb);
5431
GEN_SPEOP_ARITH1(evextsh);
5432
GEN_SPEOP_ARITH1(evrndw);
5433
GEN_SPEOP_ARITH1(evcntlzw);
5434
GEN_SPEOP_ARITH1(evcntlsw);
5435
static always_inline void gen_brinc (DisasContext *ctx)
5436
{
5437
    /* Note: brinc is usable even if SPE is disabled */
5438
    gen_op_load_gpr_T0(rA(ctx->opcode));
5439
    gen_op_load_gpr_T1(rB(ctx->opcode));
5440
    gen_op_brinc();
5441
    gen_op_store_T0_gpr(rD(ctx->opcode));
5442
}
5443

    
5444
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5445
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5446
{                                                                             \
5447
    if (unlikely(!ctx->spe_enabled)) {                                        \
5448
        GEN_EXCP_NO_AP(ctx);                                                  \
5449
        return;                                                               \
5450
    }                                                                         \
5451
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5452
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5453
    gen_op_##name();                                                          \
5454
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5455
}
5456

    
5457
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5458
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5459
{                                                                             \
5460
    if (unlikely(!ctx->spe_enabled)) {                                        \
5461
        GEN_EXCP_NO_AP(ctx);                                                  \
5462
        return;                                                               \
5463
    }                                                                         \
5464
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5465
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5466
    gen_op_##name();                                                          \
5467
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5468
}
5469

    
5470
GEN_SPEOP_ARITH_IMM2(evaddw);
5471
#define gen_evaddiw gen_evaddwi
5472
GEN_SPEOP_ARITH_IMM2(evsubfw);
5473
#define gen_evsubifw gen_evsubfwi
5474
GEN_SPEOP_LOGIC_IMM2(evslw);
5475
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5476
#define gen_evsrwis gen_evsrwsi
5477
GEN_SPEOP_LOGIC_IMM2(evsrws);
5478
#define gen_evsrwiu gen_evsrwui
5479
GEN_SPEOP_LOGIC_IMM2(evrlw);
5480

    
5481
static always_inline void gen_evsplati (DisasContext *ctx)
5482
{
5483
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5484

    
5485
    gen_op_splatwi_T0_64(imm);
5486
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5487
}
5488

    
5489
static always_inline void gen_evsplatfi (DisasContext *ctx)
5490
{
5491
    uint32_t imm = rA(ctx->opcode) << 27;
5492

    
5493
    gen_op_splatwi_T0_64(imm);
5494
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5495
}
5496

    
5497
/* Comparison */
5498
GEN_SPEOP_COMP(evcmpgtu);
5499
GEN_SPEOP_COMP(evcmpgts);
5500
GEN_SPEOP_COMP(evcmpltu);
5501
GEN_SPEOP_COMP(evcmplts);
5502
GEN_SPEOP_COMP(evcmpeq);
5503

    
5504
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5505
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5506
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5507
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5508
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5509
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5510
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5511
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5512
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5513
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5514
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5515
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5516
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5517
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5518
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5519
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5520
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5521
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5522
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5523
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5524
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5525
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5526
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5527
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5528
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5529

    
5530
static always_inline void gen_evsel (DisasContext *ctx)
5531
{
5532
    if (unlikely(!ctx->spe_enabled)) {
5533
        GEN_EXCP_NO_AP(ctx);
5534
        return;
5535
    }
5536
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5537
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5538
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5539
    gen_op_evsel();
5540
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5541
}
5542

    
5543
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5544
{
5545
    gen_evsel(ctx);
5546
}
5547
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5548
{
5549
    gen_evsel(ctx);
5550
}
5551
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5552
{
5553
    gen_evsel(ctx);
5554
}
5555
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5556
{
5557
    gen_evsel(ctx);
5558
}
5559

    
5560
/* Load and stores */
5561
#if defined(TARGET_PPC64)
5562
/* In that case, we already have 64 bits load & stores
5563
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5564
 */
5565
#define gen_op_spe_ldd_raw           gen_op_ld_raw
5566
#define gen_op_spe_ldd_user          gen_op_ld_user
5567
#define gen_op_spe_ldd_kernel        gen_op_ld_kernel
5568
#define gen_op_spe_ldd_hypv          gen_op_ld_hypv
5569
#define gen_op_spe_ldd_64_raw        gen_op_ld_64_raw
5570
#define gen_op_spe_ldd_64_user       gen_op_ld_64_user
5571
#define gen_op_spe_ldd_64_kernel     gen_op_ld_64_kernel
5572
#define gen_op_spe_ldd_64_hypv       gen_op_ld_64_hypv
5573
#define gen_op_spe_ldd_le_raw        gen_op_ld_le_raw
5574
#define gen_op_spe_ldd_le_user       gen_op_ld_le_user
5575
#define gen_op_spe_ldd_le_kernel     gen_op_ld_le_kernel
5576
#define gen_op_spe_ldd_le_hypv       gen_op_ld_le_hypv
5577
#define gen_op_spe_ldd_le_64_raw     gen_op_ld_le_64_raw
5578
#define gen_op_spe_ldd_le_64_user    gen_op_ld_le_64_user
5579
#define gen_op_spe_ldd_le_64_kernel  gen_op_ld_le_64_kernel
5580
#define gen_op_spe_ldd_le_64_hypv    gen_op_ld_le_64_hypv
5581
#define gen_op_spe_stdd_raw          gen_op_std_raw
5582
#define gen_op_spe_stdd_user         gen_op_std_user
5583
#define gen_op_spe_stdd_kernel       gen_op_std_kernel
5584
#define gen_op_spe_stdd_hypv         gen_op_std_hypv
5585
#define gen_op_spe_stdd_64_raw       gen_op_std_64_raw
5586
#define gen_op_spe_stdd_64_user      gen_op_std_64_user
5587
#define gen_op_spe_stdd_64_kernel    gen_op_std_64_kernel
5588
#define gen_op_spe_stdd_64_hypv      gen_op_std_64_hypv
5589
#define gen_op_spe_stdd_le_raw       gen_op_std_le_raw
5590
#define gen_op_spe_stdd_le_user      gen_op_std_le_user
5591
#define gen_op_spe_stdd_le_kernel    gen_op_std_le_kernel
5592
#define gen_op_spe_stdd_le_hypv      gen_op_std_le_hypv
5593
#define gen_op_spe_stdd_le_64_raw    gen_op_std_le_64_raw
5594
#define gen_op_spe_stdd_le_64_user   gen_op_std_le_64_user
5595
#define gen_op_spe_stdd_le_64_kernel gen_op_std_le_64_kernel
5596
#define gen_op_spe_stdd_le_64_hypv   gen_op_std_le_64_hypv
5597
#endif /* defined(TARGET_PPC64) */
5598
GEN_SPEOP_LDST(dd, 3);
5599
GEN_SPEOP_LDST(dw, 3);
5600
GEN_SPEOP_LDST(dh, 3);
5601
GEN_SPEOP_LDST(whe, 2);
5602
GEN_SPEOP_LD(whou, 2);
5603
GEN_SPEOP_LD(whos, 2);
5604
GEN_SPEOP_ST(who, 2);
5605

    
5606
#if defined(TARGET_PPC64)
5607
/* In that case, spe_stwwo is equivalent to stw */
5608
#define gen_op_spe_stwwo_raw          gen_op_stw_raw
5609
#define gen_op_spe_stwwo_user         gen_op_stw_user
5610
#define gen_op_spe_stwwo_kernel       gen_op_stw_kernel
5611
#define gen_op_spe_stwwo_hypv         gen_op_stw_hypv
5612
#define gen_op_spe_stwwo_le_raw       gen_op_stw_le_raw
5613
#define gen_op_spe_stwwo_le_user      gen_op_stw_le_user
5614
#define gen_op_spe_stwwo_le_kernel    gen_op_stw_le_kernel
5615
#define gen_op_spe_stwwo_le_hypv      gen_op_stw_le_hypv
5616
#define gen_op_spe_stwwo_64_raw       gen_op_stw_64_raw
5617
#define gen_op_spe_stwwo_64_user      gen_op_stw_64_user
5618
#define gen_op_spe_stwwo_64_kernel    gen_op_stw_64_kernel
5619
#define gen_op_spe_stwwo_64_hypv      gen_op_stw_64_hypv
5620
#define gen_op_spe_stwwo_le_64_raw    gen_op_stw_le_64_raw
5621
#define gen_op_spe_stwwo_le_64_user   gen_op_stw_le_64_user
5622
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5623
#define gen_op_spe_stwwo_le_64_hypv   gen_op_stw_le_64_hypv
5624
#endif
5625
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5626
static always_inline void gen_op_spe_stwwe_##suffix (void)                    \
5627
{                                                                             \
5628
    gen_op_srli32_T1_64();                                                    \
5629
    gen_op_spe_stwwo_##suffix();                                              \
5630
}
5631
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5632
static always_inline void gen_op_spe_stwwe_le_##suffix (void)                 \
5633
{                                                                             \
5634
    gen_op_srli32_T1_64();                                                    \
5635
    gen_op_spe_stwwo_le_##suffix();                                           \
5636
}
5637
#if defined(TARGET_PPC64)
5638
#define GEN_OP_SPE_STWWE(suffix)                                              \
5639
_GEN_OP_SPE_STWWE(suffix);                                                    \
5640
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5641
static always_inline void gen_op_spe_stwwe_64_##suffix (void)                 \
5642
{                                                                             \
5643
    gen_op_srli32_T1_64();                                                    \
5644
    gen_op_spe_stwwo_64_##suffix();                                           \
5645
}                                                                             \
5646
static always_inline void gen_op_spe_stwwe_le_64_##suffix (void)              \
5647
{                                                                             \
5648
    gen_op_srli32_T1_64();                                                    \
5649
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5650
}
5651
#else
5652
#define GEN_OP_SPE_STWWE(suffix)                                              \
5653
_GEN_OP_SPE_STWWE(suffix);                                                    \
5654
_GEN_OP_SPE_STWWE_LE(suffix)
5655
#endif
5656
#if defined(CONFIG_USER_ONLY)
5657
GEN_OP_SPE_STWWE(raw);
5658
#else /* defined(CONFIG_USER_ONLY) */
5659
GEN_OP_SPE_STWWE(user);
5660
GEN_OP_SPE_STWWE(kernel);
5661
GEN_OP_SPE_STWWE(hypv);
5662
#endif /* defined(CONFIG_USER_ONLY) */
5663
GEN_SPEOP_ST(wwe, 2);
5664
GEN_SPEOP_ST(wwo, 2);
5665

    
5666
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5667
static always_inline void gen_op_spe_l##name##_##suffix (void)                \
5668
{                                                                             \
5669
    gen_op_##op##_##suffix();                                                 \
5670
    gen_op_splatw_T1_64();                                                    \
5671
}
5672

    
5673
#define GEN_OP_SPE_LHE(suffix)                                                \
5674
static always_inline void gen_op_spe_lhe_##suffix (void)                      \
5675
{                                                                             \
5676
    gen_op_spe_lh_##suffix();                                                 \
5677
    gen_op_sli16_T1_64();                                                     \
5678
}
5679

    
5680
#define GEN_OP_SPE_LHX(suffix)                                                \
5681
static always_inline void gen_op_spe_lhx_##suffix (void)                      \
5682
{                                                                             \
5683
    gen_op_spe_lh_##suffix();                                                 \
5684
    gen_op_extsh_T1_64();                                                     \
5685
}
5686

    
5687
#if defined(CONFIG_USER_ONLY)
5688
GEN_OP_SPE_LHE(raw);
5689
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5690
GEN_OP_SPE_LHE(le_raw);
5691
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5692
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5693
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5694
GEN_OP_SPE_LHX(raw);
5695
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5696
GEN_OP_SPE_LHX(le_raw);
5697
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5698
#if defined(TARGET_PPC64)
5699
GEN_OP_SPE_LHE(64_raw);
5700
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5701
GEN_OP_SPE_LHE(le_64_raw);
5702
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5703
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5704
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5705
GEN_OP_SPE_LHX(64_raw);
5706
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5707
GEN_OP_SPE_LHX(le_64_raw);
5708
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5709
#endif
5710
#else
5711
GEN_OP_SPE_LHE(user);
5712
GEN_OP_SPE_LHE(kernel);
5713
GEN_OP_SPE_LHE(hypv);
5714
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5715
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5716
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv);
5717
GEN_OP_SPE_LHE(le_user);
5718
GEN_OP_SPE_LHE(le_kernel);
5719
GEN_OP_SPE_LHE(le_hypv);
5720
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5721
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5722
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv);
5723
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5724
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5725
GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv);
5726
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5727
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5728
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv);
5729
GEN_OP_SPE_LHX(user);
5730
GEN_OP_SPE_LHX(kernel);
5731
GEN_OP_SPE_LHX(hypv);
5732
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5733
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5734
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv);
5735
GEN_OP_SPE_LHX(le_user);
5736
GEN_OP_SPE_LHX(le_kernel);
5737
GEN_OP_SPE_LHX(le_hypv);
5738
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5739
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5740
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv);
5741
#if defined(TARGET_PPC64)
5742
GEN_OP_SPE_LHE(64_user);
5743
GEN_OP_SPE_LHE(64_kernel);
5744
GEN_OP_SPE_LHE(64_hypv);
5745
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5746
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5747
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv);
5748
GEN_OP_SPE_LHE(le_64_user);
5749
GEN_OP_SPE_LHE(le_64_kernel);
5750
GEN_OP_SPE_LHE(le_64_hypv);
5751
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5752
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5753
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv);
5754
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5755
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5756
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv);
5757
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5758
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5759
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv);
5760
GEN_OP_SPE_LHX(64_user);
5761
GEN_OP_SPE_LHX(64_kernel);
5762
GEN_OP_SPE_LHX(64_hypv);
5763
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5764
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5765
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv);
5766
GEN_OP_SPE_LHX(le_64_user);
5767
GEN_OP_SPE_LHX(le_64_kernel);
5768
GEN_OP_SPE_LHX(le_64_hypv);
5769
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5770
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5771
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv);
5772
#endif
5773
#endif
5774
GEN_SPEOP_LD(hhesplat, 1);
5775
GEN_SPEOP_LD(hhousplat, 1);
5776
GEN_SPEOP_LD(hhossplat, 1);
5777
GEN_SPEOP_LD(wwsplat, 2);
5778
GEN_SPEOP_LD(whsplat, 2);
5779

    
5780
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5781
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5782
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5783
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5784
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5785
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5786
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5787
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5788
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5789
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5790
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5791
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5792
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5793
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5794
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5795
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5796
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5797
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5798

    
5799
/* Multiply and add - TODO */
5800
#if 0
5801
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5802
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5803
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5804
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5805
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5806
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5807
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5808
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5809
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5810
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5811
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5812
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5813

5814
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5815
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5816
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5817
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5818
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5819
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5820
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5821
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5822
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5823
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5824
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5825
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5826
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5827
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5828

5829
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5830
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5831
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5832
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5833
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5834
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5835

5836
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5837
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5838
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5839
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5840
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5841
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5842
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5843
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5844
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5845
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5846
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5847
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5848

5849
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5850
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5851
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5852
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5853
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5854

5855
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5856
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5857
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5858
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5859
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5860
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5861
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5862
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5863
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5864
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5865
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5866
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5867

5868
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5869
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5870
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5871
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5872
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5873
#endif
5874

    
5875
/***                      SPE floating-point extension                     ***/
5876
#define GEN_SPEFPUOP_CONV(name)                                               \
5877
static always_inline void gen_##name (DisasContext *ctx)                      \
5878
{                                                                             \
5879
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5880
    gen_op_##name();                                                          \
5881
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5882
}
5883

    
5884
/* Single precision floating-point vectors operations */
5885
/* Arithmetic */
5886
GEN_SPEOP_ARITH2(evfsadd);
5887
GEN_SPEOP_ARITH2(evfssub);
5888
GEN_SPEOP_ARITH2(evfsmul);
5889
GEN_SPEOP_ARITH2(evfsdiv);
5890
GEN_SPEOP_ARITH1(evfsabs);
5891
GEN_SPEOP_ARITH1(evfsnabs);
5892
GEN_SPEOP_ARITH1(evfsneg);
5893
/* Conversion */
5894
GEN_SPEFPUOP_CONV(evfscfui);
5895
GEN_SPEFPUOP_CONV(evfscfsi);
5896
GEN_SPEFPUOP_CONV(evfscfuf);
5897
GEN_SPEFPUOP_CONV(evfscfsf);
5898
GEN_SPEFPUOP_CONV(evfsctui);
5899
GEN_SPEFPUOP_CONV(evfsctsi);
5900
GEN_SPEFPUOP_CONV(evfsctuf);
5901
GEN_SPEFPUOP_CONV(evfsctsf);
5902
GEN_SPEFPUOP_CONV(evfsctuiz);
5903
GEN_SPEFPUOP_CONV(evfsctsiz);
5904
/* Comparison */
5905
GEN_SPEOP_COMP(evfscmpgt);
5906
GEN_SPEOP_COMP(evfscmplt);
5907
GEN_SPEOP_COMP(evfscmpeq);
5908
GEN_SPEOP_COMP(evfststgt);
5909
GEN_SPEOP_COMP(evfststlt);
5910
GEN_SPEOP_COMP(evfststeq);
5911

    
5912
/* Opcodes definitions */
5913
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5914
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5915
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5916
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5917
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5918
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5919
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5920
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5921
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5922
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5923
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5924
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5925
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5926
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5927

    
5928
/* Single precision floating-point operations */
5929
/* Arithmetic */
5930
GEN_SPEOP_ARITH2(efsadd);
5931
GEN_SPEOP_ARITH2(efssub);
5932
GEN_SPEOP_ARITH2(efsmul);
5933
GEN_SPEOP_ARITH2(efsdiv);
5934
GEN_SPEOP_ARITH1(efsabs);
5935
GEN_SPEOP_ARITH1(efsnabs);
5936
GEN_SPEOP_ARITH1(efsneg);
5937
/* Conversion */
5938
GEN_SPEFPUOP_CONV(efscfui);
5939
GEN_SPEFPUOP_CONV(efscfsi);
5940
GEN_SPEFPUOP_CONV(efscfuf);
5941
GEN_SPEFPUOP_CONV(efscfsf);
5942
GEN_SPEFPUOP_CONV(efsctui);
5943
GEN_SPEFPUOP_CONV(efsctsi);
5944
GEN_SPEFPUOP_CONV(efsctuf);
5945
GEN_SPEFPUOP_CONV(efsctsf);
5946
GEN_SPEFPUOP_CONV(efsctuiz);
5947
GEN_SPEFPUOP_CONV(efsctsiz);
5948
GEN_SPEFPUOP_CONV(efscfd);
5949
/* Comparison */
5950
GEN_SPEOP_COMP(efscmpgt);
5951
GEN_SPEOP_COMP(efscmplt);
5952
GEN_SPEOP_COMP(efscmpeq);
5953
GEN_SPEOP_COMP(efststgt);
5954
GEN_SPEOP_COMP(efststlt);
5955
GEN_SPEOP_COMP(efststeq);
5956

    
5957
/* Opcodes definitions */
5958
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
5959
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5960
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5961
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5962
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5963
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5964
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5965
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5966
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5967
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5968
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5969
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5970
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5971

    
5972
/* Double precision floating-point operations */
5973
/* Arithmetic */
5974
GEN_SPEOP_ARITH2(efdadd);
5975
GEN_SPEOP_ARITH2(efdsub);
5976
GEN_SPEOP_ARITH2(efdmul);
5977
GEN_SPEOP_ARITH2(efddiv);
5978
GEN_SPEOP_ARITH1(efdabs);
5979
GEN_SPEOP_ARITH1(efdnabs);
5980
GEN_SPEOP_ARITH1(efdneg);
5981
/* Conversion */
5982

    
5983
GEN_SPEFPUOP_CONV(efdcfui);
5984
GEN_SPEFPUOP_CONV(efdcfsi);
5985
GEN_SPEFPUOP_CONV(efdcfuf);
5986
GEN_SPEFPUOP_CONV(efdcfsf);
5987
GEN_SPEFPUOP_CONV(efdctui);
5988
GEN_SPEFPUOP_CONV(efdctsi);
5989
GEN_SPEFPUOP_CONV(efdctuf);
5990
GEN_SPEFPUOP_CONV(efdctsf);
5991
GEN_SPEFPUOP_CONV(efdctuiz);
5992
GEN_SPEFPUOP_CONV(efdctsiz);
5993
GEN_SPEFPUOP_CONV(efdcfs);
5994
GEN_SPEFPUOP_CONV(efdcfuid);
5995
GEN_SPEFPUOP_CONV(efdcfsid);
5996
GEN_SPEFPUOP_CONV(efdctuidz);
5997
GEN_SPEFPUOP_CONV(efdctsidz);
5998
/* Comparison */
5999
GEN_SPEOP_COMP(efdcmpgt);
6000
GEN_SPEOP_COMP(efdcmplt);
6001
GEN_SPEOP_COMP(efdcmpeq);
6002
GEN_SPEOP_COMP(efdtstgt);
6003
GEN_SPEOP_COMP(efdtstlt);
6004
GEN_SPEOP_COMP(efdtsteq);
6005

    
6006
/* Opcodes definitions */
6007
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
6008
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
6009
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
6010
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
6011
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
6012
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
6013
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
6014
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
6015
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
6016
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
6017
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
6018
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
6019
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
6020
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
6021
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
6022
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6023

    
6024
/* End opcode list */
6025
GEN_OPCODE_MARK(end);
6026

    
6027
#include "translate_init.c"
6028
#include "helper_regs.h"
6029

    
6030
/*****************************************************************************/
6031
/* Misc PowerPC helpers */
6032
void cpu_dump_state (CPUState *env, FILE *f,
6033
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6034
                     int flags)
6035
{
6036
#define RGPL  4
6037
#define RFPL  4
6038

    
6039
    int i;
6040

    
6041
    cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
6042
                env->nip, env->lr, env->ctr, hreg_load_xer(env));
6043
    cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
6044
                env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
6045
#if !defined(NO_TIMER_DUMP)
6046
    cpu_fprintf(f, "TB %08x %08x "
6047
#if !defined(CONFIG_USER_ONLY)
6048
                "DECR %08x"
6049
#endif
6050
                "\n",
6051
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6052
#if !defined(CONFIG_USER_ONLY)
6053
                , cpu_ppc_load_decr(env)
6054
#endif
6055
                );
6056
#endif
6057
    for (i = 0; i < 32; i++) {
6058
        if ((i & (RGPL - 1)) == 0)
6059
            cpu_fprintf(f, "GPR%02d", i);
6060
        cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
6061
        if ((i & (RGPL - 1)) == (RGPL - 1))
6062
            cpu_fprintf(f, "\n");
6063
    }
6064
    cpu_fprintf(f, "CR ");
6065
    for (i = 0; i < 8; i++)
6066
        cpu_fprintf(f, "%01x", env->crf[i]);
6067
    cpu_fprintf(f, "  [");
6068
    for (i = 0; i < 8; i++) {
6069
        char a = '-';
6070
        if (env->crf[i] & 0x08)
6071
            a = 'L';
6072
        else if (env->crf[i] & 0x04)
6073
            a = 'G';
6074
        else if (env->crf[i] & 0x02)
6075
            a = 'E';
6076
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6077
    }
6078
    cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
6079
    for (i = 0; i < 32; i++) {
6080
        if ((i & (RFPL - 1)) == 0)
6081
            cpu_fprintf(f, "FPR%02d", i);
6082
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6083
        if ((i & (RFPL - 1)) == (RFPL - 1))
6084
            cpu_fprintf(f, "\n");
6085
    }
6086
#if !defined(CONFIG_USER_ONLY)
6087
    cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
6088
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6089
#endif
6090

    
6091
#undef RGPL
6092
#undef RFPL
6093
}
6094

    
6095
void cpu_dump_statistics (CPUState *env, FILE*f,
6096
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6097
                          int flags)
6098
{
6099
#if defined(DO_PPC_STATISTICS)
6100
    opc_handler_t **t1, **t2, **t3, *handler;
6101
    int op1, op2, op3;
6102

    
6103
    t1 = env->opcodes;
6104
    for (op1 = 0; op1 < 64; op1++) {
6105
        handler = t1[op1];
6106
        if (is_indirect_opcode(handler)) {
6107
            t2 = ind_table(handler);
6108
            for (op2 = 0; op2 < 32; op2++) {
6109
                handler = t2[op2];
6110
                if (is_indirect_opcode(handler)) {
6111
                    t3 = ind_table(handler);
6112
                    for (op3 = 0; op3 < 32; op3++) {
6113
                        handler = t3[op3];
6114
                        if (handler->count == 0)
6115
                            continue;
6116
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6117
                                    "%016llx %lld\n",
6118
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6119
                                    handler->oname,
6120
                                    handler->count, handler->count);
6121
                    }
6122
                } else {
6123
                    if (handler->count == 0)
6124
                        continue;
6125
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6126
                                "%016llx %lld\n",
6127
                                op1, op2, op1, op2, handler->oname,
6128
                                handler->count, handler->count);
6129
                }
6130
            }
6131
        } else {
6132
            if (handler->count == 0)
6133
                continue;
6134
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6135
                        op1, op1, handler->oname,
6136
                        handler->count, handler->count);
6137
        }
6138
    }
6139
#endif
6140
}
6141

    
6142
/*****************************************************************************/
6143
static always_inline int gen_intermediate_code_internal (CPUState *env,
6144
                                                         TranslationBlock *tb,
6145
                                                         int search_pc)
6146
{
6147
    DisasContext ctx, *ctxp = &ctx;
6148
    opc_handler_t **table, *handler;
6149
    target_ulong pc_start;
6150
    uint16_t *gen_opc_end;
6151
    int supervisor, little_endian;
6152
    int single_step, branch_step;
6153
    int j, lj = -1;
6154

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

    
6338
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6339
{
6340
    return gen_intermediate_code_internal(env, tb, 0);
6341
}
6342

    
6343
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6344
{
6345
    return gen_intermediate_code_internal(env, tb, 1);
6346
}