Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 9ceb2a77

History | View | Annotate | Download (221.7 kB)

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

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

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

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

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

    
46
static TCGv cpu_env;
47

    
48
#include "gen-icount.h"
49

    
50
void ppc_translate_init(void)
51
{
52
    static int done_init = 0;
53
    if (done_init)
54
        return;
55
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
56
    done_init = 1;
57
}
58

    
59
#if defined(OPTIMIZE_FPRF_UPDATE)
60
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
61
static uint16_t **gen_fprf_ptr;
62
#endif
63

    
64
static always_inline void gen_set_T0 (target_ulong val)
65
{
66
#if defined(TARGET_PPC64)
67
    if (val >> 32)
68
        gen_op_set_T0_64(val >> 32, val);
69
    else
70
#endif
71
        gen_op_set_T0(val);
72
}
73

    
74
static always_inline void gen_set_T1 (target_ulong val)
75
{
76
#if defined(TARGET_PPC64)
77
    if (val >> 32)
78
        gen_op_set_T1_64(val >> 32, val);
79
    else
80
#endif
81
        gen_op_set_T1(val);
82
}
83

    
84
#define GEN8(func, NAME)                                                      \
85
static GenOpFunc *NAME ## _table [8] = {                                      \
86
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
87
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
88
};                                                                            \
89
static always_inline void func (int n)                                        \
90
{                                                                             \
91
    NAME ## _table[n]();                                                      \
92
}
93

    
94
#define GEN16(func, NAME)                                                     \
95
static GenOpFunc *NAME ## _table [16] = {                                     \
96
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
97
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
98
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
99
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
100
};                                                                            \
101
static always_inline void func (int n)                                        \
102
{                                                                             \
103
    NAME ## _table[n]();                                                      \
104
}
105

    
106
#define GEN32(func, NAME)                                                     \
107
static GenOpFunc *NAME ## _table [32] = {                                     \
108
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
109
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
110
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
111
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
112
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
113
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
114
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
115
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
116
};                                                                            \
117
static always_inline void func (int n)                                        \
118
{                                                                             \
119
    NAME ## _table[n]();                                                      \
120
}
121

    
122
/* Condition register moves */
123
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
124
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
125
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
126
#if 0 // Unused
127
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
128
#endif
129

    
130
/* General purpose registers moves */
131
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
132
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
133
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
134

    
135
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
136
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
137
#if 0 // unused
138
GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
139
#endif
140

    
141
/* floating point registers moves */
142
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
143
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
144
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
145
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
146
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
147
#if 0 // unused
148
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
149
#endif
150

    
151
/* internal defines */
152
typedef struct DisasContext {
153
    struct TranslationBlock *tb;
154
    target_ulong nip;
155
    uint32_t opcode;
156
    uint32_t exception;
157
    /* Routine used to access memory */
158
    int mem_idx;
159
    /* Translation flags */
160
#if !defined(CONFIG_USER_ONLY)
161
    int supervisor;
162
#endif
163
#if defined(TARGET_PPC64)
164
    int sf_mode;
165
#endif
166
    int fpu_enabled;
167
    int altivec_enabled;
168
    int spe_enabled;
169
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
170
    int singlestep_enabled;
171
    int dcache_line_size;
172
} DisasContext;
173

    
174
struct opc_handler_t {
175
    /* invalid bits */
176
    uint32_t inval;
177
    /* instruction type */
178
    uint64_t type;
179
    /* handler */
180
    void (*handler)(DisasContext *ctx);
181
#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
182
    const unsigned char *oname;
183
#endif
184
#if defined(DO_PPC_STATISTICS)
185
    uint64_t count;
186
#endif
187
};
188

    
189
static always_inline void gen_set_Rc0 (DisasContext *ctx)
190
{
191
#if defined(TARGET_PPC64)
192
    if (ctx->sf_mode)
193
        gen_op_cmpi_64(0);
194
    else
195
#endif
196
        gen_op_cmpi(0);
197
    gen_op_set_Rc0();
198
}
199

    
200
static always_inline void gen_reset_fpstatus (void)
201
{
202
#ifdef CONFIG_SOFTFLOAT
203
    gen_op_reset_fpstatus();
204
#endif
205
}
206

    
207
static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
208
{
209
    if (set_fprf != 0) {
210
        /* This case might be optimized later */
211
#if defined(OPTIMIZE_FPRF_UPDATE)
212
        *gen_fprf_ptr++ = gen_opc_ptr;
213
#endif
214
        gen_op_compute_fprf(1);
215
        if (unlikely(set_rc))
216
            gen_op_store_T0_crf(1);
217
        gen_op_float_check_status();
218
    } else if (unlikely(set_rc)) {
219
        /* We always need to compute fpcc */
220
        gen_op_compute_fprf(0);
221
        gen_op_store_T0_crf(1);
222
        if (set_fprf)
223
            gen_op_float_check_status();
224
    }
225
}
226

    
227
static always_inline void gen_optimize_fprf (void)
228
{
229
#if defined(OPTIMIZE_FPRF_UPDATE)
230
    uint16_t **ptr;
231

    
232
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
233
        *ptr = INDEX_op_nop1;
234
    gen_fprf_ptr = gen_fprf_buf;
235
#endif
236
}
237

    
238
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
239
{
240
#if defined(TARGET_PPC64)
241
    if (ctx->sf_mode)
242
        gen_op_update_nip_64(nip >> 32, nip);
243
    else
244
#endif
245
        gen_op_update_nip(nip);
246
}
247

    
248
#define GEN_EXCP(ctx, excp, error)                                            \
249
do {                                                                          \
250
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
251
        gen_update_nip(ctx, (ctx)->nip);                                      \
252
    }                                                                         \
253
    gen_op_raise_exception_err((excp), (error));                              \
254
    ctx->exception = (excp);                                                  \
255
} while (0)
256

    
257
#define GEN_EXCP_INVAL(ctx)                                                   \
258
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
259
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
260

    
261
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
262
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
263
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
264

    
265
#define GEN_EXCP_PRIVREG(ctx)                                                 \
266
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
267
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
268

    
269
#define GEN_EXCP_NO_FP(ctx)                                                   \
270
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
271

    
272
#define GEN_EXCP_NO_AP(ctx)                                                   \
273
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
274

    
275
#define GEN_EXCP_NO_VR(ctx)                                                   \
276
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
277

    
278
/* Stop translation */
279
static always_inline void GEN_STOP (DisasContext *ctx)
280
{
281
    gen_update_nip(ctx, ctx->nip);
282
    ctx->exception = POWERPC_EXCP_STOP;
283
}
284

    
285
/* No need to update nip here, as execution flow will change */
286
static always_inline void GEN_SYNC (DisasContext *ctx)
287
{
288
    ctx->exception = POWERPC_EXCP_SYNC;
289
}
290

    
291
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
292
static void gen_##name (DisasContext *ctx);                                   \
293
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
294
static void gen_##name (DisasContext *ctx)
295

    
296
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
297
static void gen_##name (DisasContext *ctx);                                   \
298
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
299
static void gen_##name (DisasContext *ctx)
300

    
301
typedef struct opcode_t {
302
    unsigned char opc1, opc2, opc3;
303
#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
304
    unsigned char pad[5];
305
#else
306
    unsigned char pad[1];
307
#endif
308
    opc_handler_t handler;
309
    const unsigned char *oname;
310
} opcode_t;
311

    
312
/*****************************************************************************/
313
/***                           Instruction decoding                        ***/
314
#define EXTRACT_HELPER(name, shift, nb)                                       \
315
static always_inline uint32_t name (uint32_t opcode)                          \
316
{                                                                             \
317
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
318
}
319

    
320
#define EXTRACT_SHELPER(name, shift, nb)                                      \
321
static always_inline int32_t name (uint32_t opcode)                           \
322
{                                                                             \
323
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
324
}
325

    
326
/* Opcode part 1 */
327
EXTRACT_HELPER(opc1, 26, 6);
328
/* Opcode part 2 */
329
EXTRACT_HELPER(opc2, 1, 5);
330
/* Opcode part 3 */
331
EXTRACT_HELPER(opc3, 6, 5);
332
/* Update Cr0 flags */
333
EXTRACT_HELPER(Rc, 0, 1);
334
/* Destination */
335
EXTRACT_HELPER(rD, 21, 5);
336
/* Source */
337
EXTRACT_HELPER(rS, 21, 5);
338
/* First operand */
339
EXTRACT_HELPER(rA, 16, 5);
340
/* Second operand */
341
EXTRACT_HELPER(rB, 11, 5);
342
/* Third operand */
343
EXTRACT_HELPER(rC, 6, 5);
344
/***                               Get CRn                                 ***/
345
EXTRACT_HELPER(crfD, 23, 3);
346
EXTRACT_HELPER(crfS, 18, 3);
347
EXTRACT_HELPER(crbD, 21, 5);
348
EXTRACT_HELPER(crbA, 16, 5);
349
EXTRACT_HELPER(crbB, 11, 5);
350
/* SPR / TBL */
351
EXTRACT_HELPER(_SPR, 11, 10);
352
static always_inline uint32_t SPR (uint32_t opcode)
353
{
354
    uint32_t sprn = _SPR(opcode);
355

    
356
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
357
}
358
/***                              Get constants                            ***/
359
EXTRACT_HELPER(IMM, 12, 8);
360
/* 16 bits signed immediate value */
361
EXTRACT_SHELPER(SIMM, 0, 16);
362
/* 16 bits unsigned immediate value */
363
EXTRACT_HELPER(UIMM, 0, 16);
364
/* Bit count */
365
EXTRACT_HELPER(NB, 11, 5);
366
/* Shift count */
367
EXTRACT_HELPER(SH, 11, 5);
368
/* Mask start */
369
EXTRACT_HELPER(MB, 6, 5);
370
/* Mask end */
371
EXTRACT_HELPER(ME, 1, 5);
372
/* Trap operand */
373
EXTRACT_HELPER(TO, 21, 5);
374

    
375
EXTRACT_HELPER(CRM, 12, 8);
376
EXTRACT_HELPER(FM, 17, 8);
377
EXTRACT_HELPER(SR, 16, 4);
378
EXTRACT_HELPER(FPIMM, 12, 4);
379

    
380
/***                            Jump target decoding                       ***/
381
/* Displacement */
382
EXTRACT_SHELPER(d, 0, 16);
383
/* Immediate address */
384
static always_inline target_ulong LI (uint32_t opcode)
385
{
386
    return (opcode >> 0) & 0x03FFFFFC;
387
}
388

    
389
static always_inline uint32_t BD (uint32_t opcode)
390
{
391
    return (opcode >> 0) & 0xFFFC;
392
}
393

    
394
EXTRACT_HELPER(BO, 21, 5);
395
EXTRACT_HELPER(BI, 16, 5);
396
/* Absolute/relative address */
397
EXTRACT_HELPER(AA, 1, 1);
398
/* Link */
399
EXTRACT_HELPER(LK, 0, 1);
400

    
401
/* Create a mask between <start> and <end> bits */
402
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
403
{
404
    target_ulong ret;
405

    
406
#if defined(TARGET_PPC64)
407
    if (likely(start == 0)) {
408
        ret = UINT64_MAX << (63 - end);
409
    } else if (likely(end == 63)) {
410
        ret = UINT64_MAX >> start;
411
    }
412
#else
413
    if (likely(start == 0)) {
414
        ret = UINT32_MAX << (31  - end);
415
    } else if (likely(end == 31)) {
416
        ret = UINT32_MAX >> start;
417
    }
418
#endif
419
    else {
420
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
421
            (((target_ulong)(-1ULL) >> (end)) >> 1);
422
        if (unlikely(start > end))
423
            return ~ret;
424
    }
425

    
426
    return ret;
427
}
428

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

    
465
    /* Fixed-point unit extensions                                           */
466
    /*   PowerPC 602 specific                                                */
467
    PPC_602_SPEC       = 0x0000000000000400ULL,
468
    /*   isel instruction                                                    */
469
    PPC_ISEL           = 0x0000000000000800ULL,
470
    /*   popcntb instruction                                                 */
471
    PPC_POPCNTB        = 0x0000000000001000ULL,
472
    /*   string load / store                                                 */
473
    PPC_STRING         = 0x0000000000002000ULL,
474

    
475
    /* Floating-point unit extensions                                        */
476
    /*   Optional floating point instructions                                */
477
    PPC_FLOAT          = 0x0000000000010000ULL,
478
    /* New floating-point extensions (PowerPC 2.0x)                          */
479
    PPC_FLOAT_EXT      = 0x0000000000020000ULL,
480
    PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
481
    PPC_FLOAT_FRES     = 0x0000000000080000ULL,
482
    PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
483
    PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
484
    PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
485
    PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
486

    
487
    /* Vector/SIMD extensions                                                */
488
    /*   Altivec support                                                     */
489
    PPC_ALTIVEC        = 0x0000000001000000ULL,
490
    /*   PowerPC 2.03 SPE extension                                          */
491
    PPC_SPE            = 0x0000000002000000ULL,
492
    /*   PowerPC 2.03 SPE floating-point extension                           */
493
    PPC_SPEFPU         = 0x0000000004000000ULL,
494

    
495
    /* Optional memory control instructions                                  */
496
    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
497
    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
498
    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
499
    /*   sync instruction                                                    */
500
    PPC_MEM_SYNC       = 0x0000000080000000ULL,
501
    /*   eieio instruction                                                   */
502
    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
503

    
504
    /* Cache control instructions                                            */
505
    PPC_CACHE          = 0x0000000200000000ULL,
506
    /*   icbi instruction                                                    */
507
    PPC_CACHE_ICBI     = 0x0000000400000000ULL,
508
    /*   dcbz instruction with fixed cache line size                         */
509
    PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
510
    /*   dcbz instruction with tunable cache line size                       */
511
    PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
512
    /*   dcba instruction                                                    */
513
    PPC_CACHE_DCBA     = 0x0000002000000000ULL,
514
    /*   Freescale cache locking instructions                                */
515
    PPC_CACHE_LOCK     = 0x0000004000000000ULL,
516

    
517
    /* MMU related extensions                                                */
518
    /*   external control instructions                                       */
519
    PPC_EXTERN         = 0x0000010000000000ULL,
520
    /*   segment register access instructions                                */
521
    PPC_SEGMENT        = 0x0000020000000000ULL,
522
    /*   PowerPC 6xx TLB management instructions                             */
523
    PPC_6xx_TLB        = 0x0000040000000000ULL,
524
    /* PowerPC 74xx TLB management instructions                              */
525
    PPC_74xx_TLB       = 0x0000080000000000ULL,
526
    /*   PowerPC 40x TLB management instructions                             */
527
    PPC_40x_TLB        = 0x0000100000000000ULL,
528
    /*   segment register access instructions for PowerPC 64 "bridge"        */
529
    PPC_SEGMENT_64B    = 0x0000200000000000ULL,
530
    /*   SLB management                                                      */
531
    PPC_SLBI           = 0x0000400000000000ULL,
532

    
533
    /* Embedded PowerPC dedicated instructions                               */
534
    PPC_WRTEE          = 0x0001000000000000ULL,
535
    /* PowerPC 40x exception model                                           */
536
    PPC_40x_EXCP       = 0x0002000000000000ULL,
537
    /* PowerPC 405 Mac instructions                                          */
538
    PPC_405_MAC        = 0x0004000000000000ULL,
539
    /* PowerPC 440 specific instructions                                     */
540
    PPC_440_SPEC       = 0x0008000000000000ULL,
541
    /* BookE (embedded) PowerPC specification                                */
542
    PPC_BOOKE          = 0x0010000000000000ULL,
543
    /* mfapidi instruction                                                   */
544
    PPC_MFAPIDI        = 0x0020000000000000ULL,
545
    /* tlbiva instruction                                                    */
546
    PPC_TLBIVA         = 0x0040000000000000ULL,
547
    /* tlbivax instruction                                                   */
548
    PPC_TLBIVAX        = 0x0080000000000000ULL,
549
    /* PowerPC 4xx dedicated instructions                                    */
550
    PPC_4xx_COMMON     = 0x0100000000000000ULL,
551
    /* PowerPC 40x ibct instructions                                         */
552
    PPC_40x_ICBT       = 0x0200000000000000ULL,
553
    /* rfmci is not implemented in all BookE PowerPC                         */
554
    PPC_RFMCI          = 0x0400000000000000ULL,
555
    /* rfdi instruction                                                      */
556
    PPC_RFDI           = 0x0800000000000000ULL,
557
    /* DCR accesses                                                          */
558
    PPC_DCR            = 0x1000000000000000ULL,
559
    /* DCR extended accesse                                                  */
560
    PPC_DCRX           = 0x2000000000000000ULL,
561
    /* user-mode DCR access, implemented in PowerPC 460                      */
562
    PPC_DCRUX          = 0x4000000000000000ULL,
563
};
564

    
565
/*****************************************************************************/
566
/* PowerPC instructions table                                                */
567
#if HOST_LONG_BITS == 64
568
#define OPC_ALIGN 8
569
#else
570
#define OPC_ALIGN 4
571
#endif
572
#if defined(__APPLE__)
573
#define OPCODES_SECTION                                                       \
574
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
575
#else
576
#define OPCODES_SECTION                                                       \
577
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
578
#endif
579

    
580
#if defined(DO_PPC_STATISTICS)
581
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
582
OPCODES_SECTION opcode_t opc_##name = {                                       \
583
    .opc1 = op1,                                                              \
584
    .opc2 = op2,                                                              \
585
    .opc3 = op3,                                                              \
586
    .pad  = { 0, },                                                           \
587
    .handler = {                                                              \
588
        .inval   = invl,                                                      \
589
        .type = _typ,                                                         \
590
        .handler = &gen_##name,                                               \
591
        .oname = stringify(name),                                             \
592
    },                                                                        \
593
    .oname = stringify(name),                                                 \
594
}
595
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
596
OPCODES_SECTION opcode_t opc_##name = {                                       \
597
    .opc1 = op1,                                                              \
598
    .opc2 = op2,                                                              \
599
    .opc3 = op3,                                                              \
600
    .pad  = { 0, },                                                           \
601
    .handler = {                                                              \
602
        .inval   = invl,                                                      \
603
        .type = _typ,                                                         \
604
        .handler = &gen_##name,                                               \
605
        .oname = onam,                                                        \
606
    },                                                                        \
607
    .oname = onam,                                                            \
608
}
609
#else
610
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
611
OPCODES_SECTION opcode_t opc_##name = {                                       \
612
    .opc1 = op1,                                                              \
613
    .opc2 = op2,                                                              \
614
    .opc3 = op3,                                                              \
615
    .pad  = { 0, },                                                           \
616
    .handler = {                                                              \
617
        .inval   = invl,                                                      \
618
        .type = _typ,                                                         \
619
        .handler = &gen_##name,                                               \
620
    },                                                                        \
621
    .oname = stringify(name),                                                 \
622
}
623
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
624
OPCODES_SECTION opcode_t opc_##name = {                                       \
625
    .opc1 = op1,                                                              \
626
    .opc2 = op2,                                                              \
627
    .opc3 = op3,                                                              \
628
    .pad  = { 0, },                                                           \
629
    .handler = {                                                              \
630
        .inval   = invl,                                                      \
631
        .type = _typ,                                                         \
632
        .handler = &gen_##name,                                               \
633
    },                                                                        \
634
    .oname = onam,                                                            \
635
}
636
#endif
637

    
638
#define GEN_OPCODE_MARK(name)                                                 \
639
OPCODES_SECTION opcode_t opc_##name = {                                       \
640
    .opc1 = 0xFF,                                                             \
641
    .opc2 = 0xFF,                                                             \
642
    .opc3 = 0xFF,                                                             \
643
    .pad  = { 0, },                                                           \
644
    .handler = {                                                              \
645
        .inval   = 0x00000000,                                                \
646
        .type = 0x00,                                                         \
647
        .handler = NULL,                                                      \
648
    },                                                                        \
649
    .oname = stringify(name),                                                 \
650
}
651

    
652
/* Start opcode list */
653
GEN_OPCODE_MARK(start);
654

    
655
/* Invalid instruction */
656
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
657
{
658
    GEN_EXCP_INVAL(ctx);
659
}
660

    
661
static opc_handler_t invalid_handler = {
662
    .inval   = 0xFFFFFFFF,
663
    .type    = PPC_NONE,
664
    .handler = gen_invalid,
665
};
666

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

    
679
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
680
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
681
{                                                                             \
682
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
683
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
684
    gen_op_##name();                                                          \
685
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
686
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
687
        gen_set_Rc0(ctx);                                                     \
688
}
689

    
690
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
691
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
692
{                                                                             \
693
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
694
    gen_op_##name();                                                          \
695
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
696
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
697
        gen_set_Rc0(ctx);                                                     \
698
}
699
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
700
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
701
{                                                                             \
702
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
703
    gen_op_##name();                                                          \
704
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
705
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
706
        gen_set_Rc0(ctx);                                                     \
707
}
708

    
709
/* Two operands arithmetic functions */
710
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
711
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
712
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
713

    
714
/* Two operands arithmetic functions with no overflow allowed */
715
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
716
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
717

    
718
/* One operand arithmetic functions */
719
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
720
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
721
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
722

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

    
738
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
739
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
740
{                                                                             \
741
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
742
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
743
    if (ctx->sf_mode)                                                         \
744
        gen_op_##name##_64();                                                 \
745
    else                                                                      \
746
        gen_op_##name();                                                      \
747
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
748
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
749
        gen_set_Rc0(ctx);                                                     \
750
}
751

    
752
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
753
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
754
{                                                                             \
755
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
756
    if (ctx->sf_mode)                                                         \
757
        gen_op_##name##_64();                                                 \
758
    else                                                                      \
759
        gen_op_##name();                                                      \
760
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
761
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
762
        gen_set_Rc0(ctx);                                                     \
763
}
764
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
765
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
766
{                                                                             \
767
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
768
    if (ctx->sf_mode)                                                         \
769
        gen_op_##name##_64();                                                 \
770
    else                                                                      \
771
        gen_op_##name();                                                      \
772
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
773
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
774
        gen_set_Rc0(ctx);                                                     \
775
}
776

    
777
/* Two operands arithmetic functions */
778
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
779
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
780
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
781

    
782
/* Two operands arithmetic functions with no overflow allowed */
783
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
784
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
785

    
786
/* One operand arithmetic functions */
787
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
788
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
789
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
790
#else
791
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
792
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
793
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
794
#endif
795

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

    
986
    if (rA(ctx->opcode) == 0) {
987
        /* li case */
988
        gen_set_T0(simm);
989
    } else {
990
        gen_op_load_gpr_T0(rA(ctx->opcode));
991
        if (likely(simm != 0))
992
            gen_op_addi(simm);
993
    }
994
    gen_op_store_T0_gpr(rD(ctx->opcode));
995
}
996
/* addic */
997
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
998
{
999
    target_long simm = SIMM(ctx->opcode);
1000

    
1001
    gen_op_load_gpr_T0(rA(ctx->opcode));
1002
    if (likely(simm != 0)) {
1003
        gen_op_move_T2_T0();
1004
        gen_op_addi(simm);
1005
#if defined(TARGET_PPC64)
1006
        if (ctx->sf_mode)
1007
            gen_op_check_addc_64();
1008
        else
1009
#endif
1010
            gen_op_check_addc();
1011
    } else {
1012
        gen_op_clear_xer_ca();
1013
    }
1014
    gen_op_store_T0_gpr(rD(ctx->opcode));
1015
}
1016
/* addic. */
1017
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1018
{
1019
    target_long simm = SIMM(ctx->opcode);
1020

    
1021
    gen_op_load_gpr_T0(rA(ctx->opcode));
1022
    if (likely(simm != 0)) {
1023
        gen_op_move_T2_T0();
1024
        gen_op_addi(simm);
1025
#if defined(TARGET_PPC64)
1026
        if (ctx->sf_mode)
1027
            gen_op_check_addc_64();
1028
        else
1029
#endif
1030
            gen_op_check_addc();
1031
    } else {
1032
        gen_op_clear_xer_ca();
1033
    }
1034
    gen_op_store_T0_gpr(rD(ctx->opcode));
1035
    gen_set_Rc0(ctx);
1036
}
1037
/* addis */
1038
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1039
{
1040
    target_long simm = SIMM(ctx->opcode);
1041

    
1042
    if (rA(ctx->opcode) == 0) {
1043
        /* lis case */
1044
        gen_set_T0(simm << 16);
1045
    } else {
1046
        gen_op_load_gpr_T0(rA(ctx->opcode));
1047
        if (likely(simm != 0))
1048
            gen_op_addi(simm << 16);
1049
    }
1050
    gen_op_store_T0_gpr(rD(ctx->opcode));
1051
}
1052
/* mulli */
1053
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1054
{
1055
    gen_op_load_gpr_T0(rA(ctx->opcode));
1056
    gen_op_mulli(SIMM(ctx->opcode));
1057
    gen_op_store_T0_gpr(rD(ctx->opcode));
1058
}
1059
/* subfic */
1060
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1061
{
1062
    gen_op_load_gpr_T0(rA(ctx->opcode));
1063
#if defined(TARGET_PPC64)
1064
    if (ctx->sf_mode)
1065
        gen_op_subfic_64(SIMM(ctx->opcode));
1066
    else
1067
#endif
1068
        gen_op_subfic(SIMM(ctx->opcode));
1069
    gen_op_store_T0_gpr(rD(ctx->opcode));
1070
}
1071

    
1072
#if defined(TARGET_PPC64)
1073
/* mulhd  mulhd.                   */
1074
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
1075
/* mulhdu mulhdu.                  */
1076
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
1077
/* mulld  mulld.  mulldo  mulldo.  */
1078
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
1079
/* divd   divd.   divdo   divdo.   */
1080
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
1081
/* divdu  divdu.  divduo  divduo.  */
1082
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
1083
#endif
1084

    
1085
/***                           Integer comparison                          ***/
1086
#if defined(TARGET_PPC64)
1087
#define GEN_CMP(name, opc, type)                                              \
1088
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1089
{                                                                             \
1090
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1091
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1092
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))                           \
1093
        gen_op_##name##_64();                                                 \
1094
    else                                                                      \
1095
        gen_op_##name();                                                      \
1096
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
1097
}
1098
#else
1099
#define GEN_CMP(name, opc, type)                                              \
1100
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1101
{                                                                             \
1102
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1103
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1104
    gen_op_##name();                                                          \
1105
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
1106
}
1107
#endif
1108

    
1109
/* cmp */
1110
GEN_CMP(cmp, 0x00, PPC_INTEGER);
1111
/* cmpi */
1112
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1113
{
1114
    gen_op_load_gpr_T0(rA(ctx->opcode));
1115
#if defined(TARGET_PPC64)
1116
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1117
        gen_op_cmpi_64(SIMM(ctx->opcode));
1118
    else
1119
#endif
1120
        gen_op_cmpi(SIMM(ctx->opcode));
1121
    gen_op_store_T0_crf(crfD(ctx->opcode));
1122
}
1123
/* cmpl */
1124
GEN_CMP(cmpl, 0x01, PPC_INTEGER);
1125
/* cmpli */
1126
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1127
{
1128
    gen_op_load_gpr_T0(rA(ctx->opcode));
1129
#if defined(TARGET_PPC64)
1130
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1131
        gen_op_cmpli_64(UIMM(ctx->opcode));
1132
    else
1133
#endif
1134
        gen_op_cmpli(UIMM(ctx->opcode));
1135
    gen_op_store_T0_crf(crfD(ctx->opcode));
1136
}
1137

    
1138
/* isel (PowerPC 2.03 specification) */
1139
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
1140
{
1141
    uint32_t bi = rC(ctx->opcode);
1142
    uint32_t mask;
1143

    
1144
    if (rA(ctx->opcode) == 0) {
1145
        gen_set_T0(0);
1146
    } else {
1147
        gen_op_load_gpr_T1(rA(ctx->opcode));
1148
    }
1149
    gen_op_load_gpr_T2(rB(ctx->opcode));
1150
    mask = 1 << (3 - (bi & 0x03));
1151
    gen_op_load_crf_T0(bi >> 2);
1152
    gen_op_test_true(mask);
1153
    gen_op_isel();
1154
    gen_op_store_T0_gpr(rD(ctx->opcode));
1155
}
1156

    
1157
/***                            Integer logical                            ***/
1158
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1159
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1160
{                                                                             \
1161
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1162
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1163
    gen_op_##name();                                                          \
1164
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1165
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1166
        gen_set_Rc0(ctx);                                                     \
1167
}
1168
#define GEN_LOGICAL2(name, opc, type)                                         \
1169
__GEN_LOGICAL2(name, 0x1C, opc, type)
1170

    
1171
#define GEN_LOGICAL1(name, opc, type)                                         \
1172
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1173
{                                                                             \
1174
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1175
    gen_op_##name();                                                          \
1176
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1177
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1178
        gen_set_Rc0(ctx);                                                     \
1179
}
1180

    
1181
/* and & and. */
1182
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1183
/* andc & andc. */
1184
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1185
/* andi. */
1186
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1187
{
1188
    gen_op_load_gpr_T0(rS(ctx->opcode));
1189
    gen_op_andi_T0(UIMM(ctx->opcode));
1190
    gen_op_store_T0_gpr(rA(ctx->opcode));
1191
    gen_set_Rc0(ctx);
1192
}
1193
/* andis. */
1194
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1195
{
1196
    gen_op_load_gpr_T0(rS(ctx->opcode));
1197
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
1198
    gen_op_store_T0_gpr(rA(ctx->opcode));
1199
    gen_set_Rc0(ctx);
1200
}
1201

    
1202
/* cntlzw */
1203
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1204
/* eqv & eqv. */
1205
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1206
/* extsb & extsb. */
1207
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1208
/* extsh & extsh. */
1209
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1210
/* nand & nand. */
1211
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1212
/* nor & nor. */
1213
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1214

    
1215
/* or & or. */
1216
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1217
{
1218
    int rs, ra, rb;
1219

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

    
1285
/* orc & orc. */
1286
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1287
/* xor & xor. */
1288
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1289
{
1290
    gen_op_load_gpr_T0(rS(ctx->opcode));
1291
    /* Optimisation for "set to zero" case */
1292
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1293
        gen_op_load_gpr_T1(rB(ctx->opcode));
1294
        gen_op_xor();
1295
    } else {
1296
        gen_op_reset_T0();
1297
    }
1298
    gen_op_store_T0_gpr(rA(ctx->opcode));
1299
    if (unlikely(Rc(ctx->opcode) != 0))
1300
        gen_set_Rc0(ctx);
1301
}
1302
/* ori */
1303
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1304
{
1305
    target_ulong uimm = UIMM(ctx->opcode);
1306

    
1307
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1308
        /* NOP */
1309
        /* XXX: should handle special NOPs for POWER series */
1310
        return;
1311
    }
1312
    gen_op_load_gpr_T0(rS(ctx->opcode));
1313
    if (likely(uimm != 0))
1314
        gen_op_ori(uimm);
1315
    gen_op_store_T0_gpr(rA(ctx->opcode));
1316
}
1317
/* oris */
1318
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1319
{
1320
    target_ulong uimm = UIMM(ctx->opcode);
1321

    
1322
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1323
        /* NOP */
1324
        return;
1325
    }
1326
    gen_op_load_gpr_T0(rS(ctx->opcode));
1327
    if (likely(uimm != 0))
1328
        gen_op_ori(uimm << 16);
1329
    gen_op_store_T0_gpr(rA(ctx->opcode));
1330
}
1331
/* xori */
1332
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1333
{
1334
    target_ulong uimm = UIMM(ctx->opcode);
1335

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

    
1346
/* xoris */
1347
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1348
{
1349
    target_ulong uimm = UIMM(ctx->opcode);
1350

    
1351
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1352
        /* NOP */
1353
        return;
1354
    }
1355
    gen_op_load_gpr_T0(rS(ctx->opcode));
1356
    if (likely(uimm != 0))
1357
        gen_op_xori(uimm << 16);
1358
    gen_op_store_T0_gpr(rA(ctx->opcode));
1359
}
1360

    
1361
/* popcntb : PowerPC 2.03 specification */
1362
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
1363
{
1364
    gen_op_load_gpr_T0(rS(ctx->opcode));
1365
#if defined(TARGET_PPC64)
1366
    if (ctx->sf_mode)
1367
        gen_op_popcntb_64();
1368
    else
1369
#endif
1370
        gen_op_popcntb();
1371
    gen_op_store_T0_gpr(rA(ctx->opcode));
1372
}
1373

    
1374
#if defined(TARGET_PPC64)
1375
/* extsw & extsw. */
1376
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1377
/* cntlzd */
1378
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1379
#endif
1380

    
1381
/***                             Integer rotate                            ***/
1382
/* rlwimi & rlwimi. */
1383
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1384
{
1385
    target_ulong mask;
1386
    uint32_t mb, me, sh;
1387

    
1388
    mb = MB(ctx->opcode);
1389
    me = ME(ctx->opcode);
1390
    sh = SH(ctx->opcode);
1391
    if (likely(sh == 0)) {
1392
        if (likely(mb == 0 && me == 31)) {
1393
            gen_op_load_gpr_T0(rS(ctx->opcode));
1394
            goto do_store;
1395
        } else if (likely(mb == 31 && me == 0)) {
1396
            gen_op_load_gpr_T0(rA(ctx->opcode));
1397
            goto do_store;
1398
        }
1399
        gen_op_load_gpr_T0(rS(ctx->opcode));
1400
        gen_op_load_gpr_T1(rA(ctx->opcode));
1401
        goto do_mask;
1402
    }
1403
    gen_op_load_gpr_T0(rS(ctx->opcode));
1404
    gen_op_load_gpr_T1(rA(ctx->opcode));
1405
    gen_op_rotli32_T0(SH(ctx->opcode));
1406
 do_mask:
1407
#if defined(TARGET_PPC64)
1408
    mb += 32;
1409
    me += 32;
1410
#endif
1411
    mask = MASK(mb, me);
1412
    gen_op_andi_T0(mask);
1413
    gen_op_andi_T1(~mask);
1414
    gen_op_or();
1415
 do_store:
1416
    gen_op_store_T0_gpr(rA(ctx->opcode));
1417
    if (unlikely(Rc(ctx->opcode) != 0))
1418
        gen_set_Rc0(ctx);
1419
}
1420
/* rlwinm & rlwinm. */
1421
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1422
{
1423
    uint32_t mb, me, sh;
1424

    
1425
    sh = SH(ctx->opcode);
1426
    mb = MB(ctx->opcode);
1427
    me = ME(ctx->opcode);
1428
    gen_op_load_gpr_T0(rS(ctx->opcode));
1429
    if (likely(sh == 0)) {
1430
        goto do_mask;
1431
    }
1432
    if (likely(mb == 0)) {
1433
        if (likely(me == 31)) {
1434
            gen_op_rotli32_T0(sh);
1435
            goto do_store;
1436
        } else if (likely(me == (31 - sh))) {
1437
            gen_op_sli_T0(sh);
1438
            goto do_store;
1439
        }
1440
    } else if (likely(me == 31)) {
1441
        if (likely(sh == (32 - mb))) {
1442
            gen_op_srli_T0(mb);
1443
            goto do_store;
1444
        }
1445
    }
1446
    gen_op_rotli32_T0(sh);
1447
 do_mask:
1448
#if defined(TARGET_PPC64)
1449
    mb += 32;
1450
    me += 32;
1451
#endif
1452
    gen_op_andi_T0(MASK(mb, me));
1453
 do_store:
1454
    gen_op_store_T0_gpr(rA(ctx->opcode));
1455
    if (unlikely(Rc(ctx->opcode) != 0))
1456
        gen_set_Rc0(ctx);
1457
}
1458
/* rlwnm & rlwnm. */
1459
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1460
{
1461
    uint32_t mb, me;
1462

    
1463
    mb = MB(ctx->opcode);
1464
    me = ME(ctx->opcode);
1465
    gen_op_load_gpr_T0(rS(ctx->opcode));
1466
    gen_op_load_gpr_T1(rB(ctx->opcode));
1467
    gen_op_rotl32_T0_T1();
1468
    if (unlikely(mb != 0 || me != 31)) {
1469
#if defined(TARGET_PPC64)
1470
        mb += 32;
1471
        me += 32;
1472
#endif
1473
        gen_op_andi_T0(MASK(mb, me));
1474
    }
1475
    gen_op_store_T0_gpr(rA(ctx->opcode));
1476
    if (unlikely(Rc(ctx->opcode) != 0))
1477
        gen_set_Rc0(ctx);
1478
}
1479

    
1480
#if defined(TARGET_PPC64)
1481
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1482
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1483
{                                                                             \
1484
    gen_##name(ctx, 0);                                                       \
1485
}                                                                             \
1486
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1487
             PPC_64B)                                                         \
1488
{                                                                             \
1489
    gen_##name(ctx, 1);                                                       \
1490
}
1491
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1492
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1493
{                                                                             \
1494
    gen_##name(ctx, 0, 0);                                                    \
1495
}                                                                             \
1496
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
1497
             PPC_64B)                                                         \
1498
{                                                                             \
1499
    gen_##name(ctx, 0, 1);                                                    \
1500
}                                                                             \
1501
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1502
             PPC_64B)                                                         \
1503
{                                                                             \
1504
    gen_##name(ctx, 1, 0);                                                    \
1505
}                                                                             \
1506
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
1507
             PPC_64B)                                                         \
1508
{                                                                             \
1509
    gen_##name(ctx, 1, 1);                                                    \
1510
}
1511

    
1512
static always_inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1513
{
1514
    if (mask >> 32)
1515
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1516
    else
1517
        gen_op_andi_T0(mask);
1518
}
1519

    
1520
static always_inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1521
{
1522
    if (mask >> 32)
1523
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1524
    else
1525
        gen_op_andi_T1(mask);
1526
}
1527

    
1528
static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
1529
                                      uint32_t me, uint32_t sh)
1530
{
1531
    gen_op_load_gpr_T0(rS(ctx->opcode));
1532
    if (likely(sh == 0)) {
1533
        goto do_mask;
1534
    }
1535
    if (likely(mb == 0)) {
1536
        if (likely(me == 63)) {
1537
            gen_op_rotli64_T0(sh);
1538
            goto do_store;
1539
        } else if (likely(me == (63 - sh))) {
1540
            gen_op_sli_T0(sh);
1541
            goto do_store;
1542
        }
1543
    } else if (likely(me == 63)) {
1544
        if (likely(sh == (64 - mb))) {
1545
            gen_op_srli_T0_64(mb);
1546
            goto do_store;
1547
        }
1548
    }
1549
    gen_op_rotli64_T0(sh);
1550
 do_mask:
1551
    gen_andi_T0_64(ctx, MASK(mb, me));
1552
 do_store:
1553
    gen_op_store_T0_gpr(rA(ctx->opcode));
1554
    if (unlikely(Rc(ctx->opcode) != 0))
1555
        gen_set_Rc0(ctx);
1556
}
1557
/* rldicl - rldicl. */
1558
static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1559
{
1560
    uint32_t sh, mb;
1561

    
1562
    sh = SH(ctx->opcode) | (shn << 5);
1563
    mb = MB(ctx->opcode) | (mbn << 5);
1564
    gen_rldinm(ctx, mb, 63, sh);
1565
}
1566
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1567
/* rldicr - rldicr. */
1568
static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1569
{
1570
    uint32_t sh, me;
1571

    
1572
    sh = SH(ctx->opcode) | (shn << 5);
1573
    me = MB(ctx->opcode) | (men << 5);
1574
    gen_rldinm(ctx, 0, me, sh);
1575
}
1576
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1577
/* rldic - rldic. */
1578
static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1579
{
1580
    uint32_t sh, mb;
1581

    
1582
    sh = SH(ctx->opcode) | (shn << 5);
1583
    mb = MB(ctx->opcode) | (mbn << 5);
1584
    gen_rldinm(ctx, mb, 63 - sh, sh);
1585
}
1586
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1587

    
1588
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1589
                                     uint32_t me)
1590
{
1591
    gen_op_load_gpr_T0(rS(ctx->opcode));
1592
    gen_op_load_gpr_T1(rB(ctx->opcode));
1593
    gen_op_rotl64_T0_T1();
1594
    if (unlikely(mb != 0 || me != 63)) {
1595
        gen_andi_T0_64(ctx, MASK(mb, me));
1596
    }
1597
    gen_op_store_T0_gpr(rA(ctx->opcode));
1598
    if (unlikely(Rc(ctx->opcode) != 0))
1599
        gen_set_Rc0(ctx);
1600
}
1601

    
1602
/* rldcl - rldcl. */
1603
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1604
{
1605
    uint32_t mb;
1606

    
1607
    mb = MB(ctx->opcode) | (mbn << 5);
1608
    gen_rldnm(ctx, mb, 63);
1609
}
1610
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1611
/* rldcr - rldcr. */
1612
static always_inline void gen_rldcr (DisasContext *ctx, int men)
1613
{
1614
    uint32_t me;
1615

    
1616
    me = MB(ctx->opcode) | (men << 5);
1617
    gen_rldnm(ctx, 0, me);
1618
}
1619
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1620
/* rldimi - rldimi. */
1621
static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1622
{
1623
    uint64_t mask;
1624
    uint32_t sh, mb, me;
1625

    
1626
    sh = SH(ctx->opcode) | (shn << 5);
1627
    mb = MB(ctx->opcode) | (mbn << 5);
1628
    me = 63 - sh;
1629
    if (likely(sh == 0)) {
1630
        if (likely(mb == 0)) {
1631
            gen_op_load_gpr_T0(rS(ctx->opcode));
1632
            goto do_store;
1633
        }
1634
        gen_op_load_gpr_T0(rS(ctx->opcode));
1635
        gen_op_load_gpr_T1(rA(ctx->opcode));
1636
        goto do_mask;
1637
    }
1638
    gen_op_load_gpr_T0(rS(ctx->opcode));
1639
    gen_op_load_gpr_T1(rA(ctx->opcode));
1640
    gen_op_rotli64_T0(sh);
1641
 do_mask:
1642
    mask = MASK(mb, me);
1643
    gen_andi_T0_64(ctx, mask);
1644
    gen_andi_T1_64(ctx, ~mask);
1645
    gen_op_or();
1646
 do_store:
1647
    gen_op_store_T0_gpr(rA(ctx->opcode));
1648
    if (unlikely(Rc(ctx->opcode) != 0))
1649
        gen_set_Rc0(ctx);
1650
}
1651
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1652
#endif
1653

    
1654
/***                             Integer shift                             ***/
1655
/* slw & slw. */
1656
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1657
/* sraw & sraw. */
1658
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1659
/* srawi & srawi. */
1660
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1661
{
1662
    int mb, me;
1663
    gen_op_load_gpr_T0(rS(ctx->opcode));
1664
    if (SH(ctx->opcode) != 0) {
1665
        gen_op_move_T1_T0();
1666
        mb = 32 - SH(ctx->opcode);
1667
        me = 31;
1668
#if defined(TARGET_PPC64)
1669
        mb += 32;
1670
        me += 32;
1671
#endif
1672
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1673
    }
1674
    gen_op_store_T0_gpr(rA(ctx->opcode));
1675
    if (unlikely(Rc(ctx->opcode) != 0))
1676
        gen_set_Rc0(ctx);
1677
}
1678
/* srw & srw. */
1679
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1680

    
1681
#if defined(TARGET_PPC64)
1682
/* sld & sld. */
1683
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1684
/* srad & srad. */
1685
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1686
/* sradi & sradi. */
1687
static always_inline void gen_sradi (DisasContext *ctx, int n)
1688
{
1689
    uint64_t mask;
1690
    int sh, mb, me;
1691

    
1692
    gen_op_load_gpr_T0(rS(ctx->opcode));
1693
    sh = SH(ctx->opcode) + (n << 5);
1694
    if (sh != 0) {
1695
        gen_op_move_T1_T0();
1696
        mb = 64 - SH(ctx->opcode);
1697
        me = 63;
1698
        mask = MASK(mb, me);
1699
        gen_op_sradi(sh, mask >> 32, mask);
1700
    }
1701
    gen_op_store_T0_gpr(rA(ctx->opcode));
1702
    if (unlikely(Rc(ctx->opcode) != 0))
1703
        gen_set_Rc0(ctx);
1704
}
1705
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1706
{
1707
    gen_sradi(ctx, 0);
1708
}
1709
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1710
{
1711
    gen_sradi(ctx, 1);
1712
}
1713
/* srd & srd. */
1714
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1715
#endif
1716

    
1717
/***                       Floating-Point arithmetic                       ***/
1718
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1719
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1720
{                                                                             \
1721
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1722
        GEN_EXCP_NO_FP(ctx);                                                  \
1723
        return;                                                               \
1724
    }                                                                         \
1725
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1726
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1727
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1728
    gen_reset_fpstatus();                                                     \
1729
    gen_op_f##op();                                                           \
1730
    if (isfloat) {                                                            \
1731
        gen_op_frsp();                                                        \
1732
    }                                                                         \
1733
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1734
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1735
}
1736

    
1737
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1738
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1739
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1740

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

    
1762
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1763
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1764
{                                                                             \
1765
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1766
        GEN_EXCP_NO_FP(ctx);                                                  \
1767
        return;                                                               \
1768
    }                                                                         \
1769
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1770
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1771
    gen_reset_fpstatus();                                                     \
1772
    gen_op_f##op();                                                           \
1773
    if (isfloat) {                                                            \
1774
        gen_op_frsp();                                                        \
1775
    }                                                                         \
1776
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1777
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1778
}
1779
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
1780
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1781
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1782

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

    
1797
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1798
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1799
{                                                                             \
1800
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1801
        GEN_EXCP_NO_FP(ctx);                                                  \
1802
        return;                                                               \
1803
    }                                                                         \
1804
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1805
    gen_reset_fpstatus();                                                     \
1806
    gen_op_f##name();                                                         \
1807
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1808
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1809
}
1810

    
1811
/* fadd - fadds */
1812
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1813
/* fdiv - fdivs */
1814
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1815
/* fmul - fmuls */
1816
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
1817

    
1818
/* fre */
1819
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1820

    
1821
/* fres */
1822
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1823

    
1824
/* frsqrte */
1825
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
1826

    
1827
/* frsqrtes */
1828
static always_inline void gen_op_frsqrtes (void)
1829
{
1830
    gen_op_frsqrte();
1831
    gen_op_frsp();
1832
}
1833
GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1834

    
1835
/* fsel */
1836
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1837
/* fsub - fsubs */
1838
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1839
/* Optional: */
1840
/* fsqrt */
1841
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1842
{
1843
    if (unlikely(!ctx->fpu_enabled)) {
1844
        GEN_EXCP_NO_FP(ctx);
1845
        return;
1846
    }
1847
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1848
    gen_reset_fpstatus();
1849
    gen_op_fsqrt();
1850
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1851
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1852
}
1853

    
1854
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1855
{
1856
    if (unlikely(!ctx->fpu_enabled)) {
1857
        GEN_EXCP_NO_FP(ctx);
1858
        return;
1859
    }
1860
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1861
    gen_reset_fpstatus();
1862
    gen_op_fsqrt();
1863
    gen_op_frsp();
1864
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1865
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1866
}
1867

    
1868
/***                     Floating-Point multiply-and-add                   ***/
1869
/* fmadd - fmadds */
1870
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1871
/* fmsub - fmsubs */
1872
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1873
/* fnmadd - fnmadds */
1874
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1875
/* fnmsub - fnmsubs */
1876
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1877

    
1878
/***                     Floating-Point round & convert                    ***/
1879
/* fctiw */
1880
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1881
/* fctiwz */
1882
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1883
/* frsp */
1884
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
1885
#if defined(TARGET_PPC64)
1886
/* fcfid */
1887
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
1888
/* fctid */
1889
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
1890
/* fctidz */
1891
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
1892
#endif
1893

    
1894
/* frin */
1895
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
1896
/* friz */
1897
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
1898
/* frip */
1899
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
1900
/* frim */
1901
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1902

    
1903
/***                         Floating-Point compare                        ***/
1904
/* fcmpo */
1905
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1906
{
1907
    if (unlikely(!ctx->fpu_enabled)) {
1908
        GEN_EXCP_NO_FP(ctx);
1909
        return;
1910
    }
1911
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1912
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1913
    gen_reset_fpstatus();
1914
    gen_op_fcmpo();
1915
    gen_op_store_T0_crf(crfD(ctx->opcode));
1916
    gen_op_float_check_status();
1917
}
1918

    
1919
/* fcmpu */
1920
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1921
{
1922
    if (unlikely(!ctx->fpu_enabled)) {
1923
        GEN_EXCP_NO_FP(ctx);
1924
        return;
1925
    }
1926
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1927
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1928
    gen_reset_fpstatus();
1929
    gen_op_fcmpu();
1930
    gen_op_store_T0_crf(crfD(ctx->opcode));
1931
    gen_op_float_check_status();
1932
}
1933

    
1934
/***                         Floating-point move                           ***/
1935
/* fabs */
1936
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
1937
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1938

    
1939
/* fmr  - fmr. */
1940
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1941
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1942
{
1943
    if (unlikely(!ctx->fpu_enabled)) {
1944
        GEN_EXCP_NO_FP(ctx);
1945
        return;
1946
    }
1947
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1948
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1949
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1950
}
1951

    
1952
/* fnabs */
1953
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
1954
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1955
/* fneg */
1956
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
1957
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1958

    
1959
/***                  Floating-Point status & ctrl register                ***/
1960
/* mcrfs */
1961
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1962
{
1963
    int bfa;
1964

    
1965
    if (unlikely(!ctx->fpu_enabled)) {
1966
        GEN_EXCP_NO_FP(ctx);
1967
        return;
1968
    }
1969
    gen_optimize_fprf();
1970
    bfa = 4 * (7 - crfS(ctx->opcode));
1971
    gen_op_load_fpscr_T0(bfa);
1972
    gen_op_store_T0_crf(crfD(ctx->opcode));
1973
    gen_op_fpscr_resetbit(~(0xF << bfa));
1974
}
1975

    
1976
/* mffs */
1977
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1978
{
1979
    if (unlikely(!ctx->fpu_enabled)) {
1980
        GEN_EXCP_NO_FP(ctx);
1981
        return;
1982
    }
1983
    gen_optimize_fprf();
1984
    gen_reset_fpstatus();
1985
    gen_op_load_fpscr_FT0();
1986
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1987
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1988
}
1989

    
1990
/* mtfsb0 */
1991
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1992
{
1993
    uint8_t crb;
1994

    
1995
    if (unlikely(!ctx->fpu_enabled)) {
1996
        GEN_EXCP_NO_FP(ctx);
1997
        return;
1998
    }
1999
    crb = 32 - (crbD(ctx->opcode) >> 2);
2000
    gen_optimize_fprf();
2001
    gen_reset_fpstatus();
2002
    if (likely(crb != 30 && crb != 29))
2003
        gen_op_fpscr_resetbit(~(1 << crb));
2004
    if (unlikely(Rc(ctx->opcode) != 0)) {
2005
        gen_op_load_fpcc();
2006
        gen_op_set_Rc0();
2007
    }
2008
}
2009

    
2010
/* mtfsb1 */
2011
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2012
{
2013
    uint8_t crb;
2014

    
2015
    if (unlikely(!ctx->fpu_enabled)) {
2016
        GEN_EXCP_NO_FP(ctx);
2017
        return;
2018
    }
2019
    crb = 32 - (crbD(ctx->opcode) >> 2);
2020
    gen_optimize_fprf();
2021
    gen_reset_fpstatus();
2022
    /* XXX: we pretend we can only do IEEE floating-point computations */
2023
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
2024
        gen_op_fpscr_setbit(crb);
2025
    if (unlikely(Rc(ctx->opcode) != 0)) {
2026
        gen_op_load_fpcc();
2027
        gen_op_set_Rc0();
2028
    }
2029
    /* We can raise a differed exception */
2030
    gen_op_float_check_status();
2031
}
2032

    
2033
/* mtfsf */
2034
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2035
{
2036
    if (unlikely(!ctx->fpu_enabled)) {
2037
        GEN_EXCP_NO_FP(ctx);
2038
        return;
2039
    }
2040
    gen_optimize_fprf();
2041
    gen_op_load_fpr_FT0(rB(ctx->opcode));
2042
    gen_reset_fpstatus();
2043
    gen_op_store_fpscr(FM(ctx->opcode));
2044
    if (unlikely(Rc(ctx->opcode) != 0)) {
2045
        gen_op_load_fpcc();
2046
        gen_op_set_Rc0();
2047
    }
2048
    /* We can raise a differed exception */
2049
    gen_op_float_check_status();
2050
}
2051

    
2052
/* mtfsfi */
2053
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2054
{
2055
    int bf, sh;
2056

    
2057
    if (unlikely(!ctx->fpu_enabled)) {
2058
        GEN_EXCP_NO_FP(ctx);
2059
        return;
2060
    }
2061
    bf = crbD(ctx->opcode) >> 2;
2062
    sh = 7 - bf;
2063
    gen_optimize_fprf();
2064
    gen_op_set_FT0(FPIMM(ctx->opcode) << (4 * sh));
2065
    gen_reset_fpstatus();
2066
    gen_op_store_fpscr(1 << sh);
2067
    if (unlikely(Rc(ctx->opcode) != 0)) {
2068
        gen_op_load_fpcc();
2069
        gen_op_set_Rc0();
2070
    }
2071
    /* We can raise a differed exception */
2072
    gen_op_float_check_status();
2073
}
2074

    
2075
/***                           Addressing modes                            ***/
2076
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2077
static always_inline void gen_addr_imm_index (DisasContext *ctx,
2078
                                              target_long maskl)
2079
{
2080
    target_long simm = SIMM(ctx->opcode);
2081

    
2082
    simm &= ~maskl;
2083
    if (rA(ctx->opcode) == 0) {
2084
        gen_set_T0(simm);
2085
    } else {
2086
        gen_op_load_gpr_T0(rA(ctx->opcode));
2087
        if (likely(simm != 0))
2088
            gen_op_addi(simm);
2089
    }
2090
#ifdef DEBUG_MEMORY_ACCESSES
2091
    gen_op_print_mem_EA();
2092
#endif
2093
}
2094

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

    
2109
static always_inline void gen_addr_register (DisasContext *ctx)
2110
{
2111
    if (rA(ctx->opcode) == 0) {
2112
        gen_op_reset_T0();
2113
    } else {
2114
        gen_op_load_gpr_T0(rA(ctx->opcode));
2115
    }
2116
#ifdef DEBUG_MEMORY_ACCESSES
2117
    gen_op_print_mem_EA();
2118
#endif
2119
}
2120

    
2121
#if defined(TARGET_PPC64)
2122
#define _GEN_MEM_FUNCS(name, mode)                                            \
2123
    &gen_op_##name##_##mode,                                                  \
2124
    &gen_op_##name##_le_##mode,                                               \
2125
    &gen_op_##name##_64_##mode,                                               \
2126
    &gen_op_##name##_le_64_##mode
2127
#else
2128
#define _GEN_MEM_FUNCS(name, mode)                                            \
2129
    &gen_op_##name##_##mode,                                                  \
2130
    &gen_op_##name##_le_##mode
2131
#endif
2132
#if defined(CONFIG_USER_ONLY)
2133
#if defined(TARGET_PPC64)
2134
#define NB_MEM_FUNCS 4
2135
#else
2136
#define NB_MEM_FUNCS 2
2137
#endif
2138
#define GEN_MEM_FUNCS(name)                                                   \
2139
    _GEN_MEM_FUNCS(name, raw)
2140
#else
2141
#if defined(TARGET_PPC64)
2142
#define NB_MEM_FUNCS 12
2143
#else
2144
#define NB_MEM_FUNCS 6
2145
#endif
2146
#define GEN_MEM_FUNCS(name)                                                   \
2147
    _GEN_MEM_FUNCS(name, user),                                               \
2148
    _GEN_MEM_FUNCS(name, kernel),                                             \
2149
    _GEN_MEM_FUNCS(name, hypv)
2150
#endif
2151

    
2152
/***                             Integer load                              ***/
2153
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
2154
/* Byte access routine are endian safe */
2155
#define gen_op_lbz_le_raw       gen_op_lbz_raw
2156
#define gen_op_lbz_le_user      gen_op_lbz_user
2157
#define gen_op_lbz_le_kernel    gen_op_lbz_kernel
2158
#define gen_op_lbz_le_hypv      gen_op_lbz_hypv
2159
#define gen_op_lbz_le_64_raw    gen_op_lbz_64_raw
2160
#define gen_op_lbz_le_64_user   gen_op_lbz_64_user
2161
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
2162
#define gen_op_lbz_le_64_hypv   gen_op_lbz_64_hypv
2163
#define gen_op_stb_le_raw       gen_op_stb_raw
2164
#define gen_op_stb_le_user      gen_op_stb_user
2165
#define gen_op_stb_le_kernel    gen_op_stb_kernel
2166
#define gen_op_stb_le_hypv      gen_op_stb_hypv
2167
#define gen_op_stb_le_64_raw    gen_op_stb_64_raw
2168
#define gen_op_stb_le_64_user   gen_op_stb_64_user
2169
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
2170
#define gen_op_stb_le_64_hypv   gen_op_stb_64_hypv
2171
#define OP_LD_TABLE(width)                                                    \
2172
static GenOpFunc *gen_op_l##width[NB_MEM_FUNCS] = {                           \
2173
    GEN_MEM_FUNCS(l##width),                                                  \
2174
};
2175
#define OP_ST_TABLE(width)                                                    \
2176
static GenOpFunc *gen_op_st##width[NB_MEM_FUNCS] = {                          \
2177
    GEN_MEM_FUNCS(st##width),                                                 \
2178
};
2179

    
2180
#define GEN_LD(width, opc, type)                                              \
2181
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2182
{                                                                             \
2183
    gen_addr_imm_index(ctx, 0);                                               \
2184
    op_ldst(l##width);                                                        \
2185
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2186
}
2187

    
2188
#define GEN_LDU(width, opc, type)                                             \
2189
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2190
{                                                                             \
2191
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2192
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2193
        GEN_EXCP_INVAL(ctx);                                                  \
2194
        return;                                                               \
2195
    }                                                                         \
2196
    if (type == PPC_64B)                                                      \
2197
        gen_addr_imm_index(ctx, 0x03);                                        \
2198
    else                                                                      \
2199
        gen_addr_imm_index(ctx, 0);                                           \
2200
    op_ldst(l##width);                                                        \
2201
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2202
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2203
}
2204

    
2205
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2206
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2207
{                                                                             \
2208
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2209
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2210
        GEN_EXCP_INVAL(ctx);                                                  \
2211
        return;                                                               \
2212
    }                                                                         \
2213
    gen_addr_reg_index(ctx);                                                  \
2214
    op_ldst(l##width);                                                        \
2215
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2216
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2217
}
2218

    
2219
#define GEN_LDX(width, opc2, opc3, type)                                      \
2220
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2221
{                                                                             \
2222
    gen_addr_reg_index(ctx);                                                  \
2223
    op_ldst(l##width);                                                        \
2224
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2225
}
2226

    
2227
#define GEN_LDS(width, op, type)                                              \
2228
OP_LD_TABLE(width);                                                           \
2229
GEN_LD(width, op | 0x20, type);                                               \
2230
GEN_LDU(width, op | 0x21, type);                                              \
2231
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2232
GEN_LDX(width, 0x17, op | 0x00, type)
2233

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

    
2282
    /* Restore CPU state */
2283
    if (unlikely(ctx->supervisor == 0)) {
2284
        GEN_EXCP_PRIVOPC(ctx);
2285
        return;
2286
    }
2287
    ra = rA(ctx->opcode);
2288
    rd = rD(ctx->opcode);
2289
    if (unlikely((rd & 1) || rd == ra)) {
2290
        GEN_EXCP_INVAL(ctx);
2291
        return;
2292
    }
2293
    if (unlikely(ctx->mem_idx & 1)) {
2294
        /* Little-endian mode is not handled */
2295
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2296
        return;
2297
    }
2298
    gen_addr_imm_index(ctx, 0x0F);
2299
    op_ldst(ld);
2300
    gen_op_store_T1_gpr(rd);
2301
    gen_op_addi(8);
2302
    op_ldst(ld);
2303
    gen_op_store_T1_gpr(rd + 1);
2304
#endif
2305
}
2306
#endif
2307

    
2308
/***                              Integer store                            ***/
2309
#define GEN_ST(width, opc, type)                                              \
2310
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2311
{                                                                             \
2312
    gen_addr_imm_index(ctx, 0);                                               \
2313
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2314
    op_ldst(st##width);                                                       \
2315
}
2316

    
2317
#define GEN_STU(width, opc, type)                                             \
2318
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2319
{                                                                             \
2320
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2321
        GEN_EXCP_INVAL(ctx);                                                  \
2322
        return;                                                               \
2323
    }                                                                         \
2324
    if (type == PPC_64B)                                                      \
2325
        gen_addr_imm_index(ctx, 0x03);                                        \
2326
    else                                                                      \
2327
        gen_addr_imm_index(ctx, 0);                                           \
2328
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2329
    op_ldst(st##width);                                                       \
2330
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2331
}
2332

    
2333
#define GEN_STUX(width, opc2, opc3, type)                                     \
2334
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2335
{                                                                             \
2336
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2337
        GEN_EXCP_INVAL(ctx);                                                  \
2338
        return;                                                               \
2339
    }                                                                         \
2340
    gen_addr_reg_index(ctx);                                                  \
2341
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2342
    op_ldst(st##width);                                                       \
2343
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2344
}
2345

    
2346
#define GEN_STX(width, opc2, opc3, type)                                      \
2347
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2348
{                                                                             \
2349
    gen_addr_reg_index(ctx);                                                  \
2350
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2351
    op_ldst(st##width);                                                       \
2352
}
2353

    
2354
#define GEN_STS(width, op, type)                                              \
2355
OP_ST_TABLE(width);                                                           \
2356
GEN_ST(width, op | 0x20, type);                                               \
2357
GEN_STU(width, op | 0x21, type);                                              \
2358
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2359
GEN_STX(width, 0x17, op | 0x00, type)
2360

    
2361
/* stb stbu stbux stbx */
2362
GEN_STS(b, 0x06, PPC_INTEGER);
2363
/* sth sthu sthux sthx */
2364
GEN_STS(h, 0x0C, PPC_INTEGER);
2365
/* stw stwu stwux stwx */
2366
GEN_STS(w, 0x04, PPC_INTEGER);
2367
#if defined(TARGET_PPC64)
2368
OP_ST_TABLE(d);
2369
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2370
GEN_STX(d, 0x15, 0x04, PPC_64B);
2371
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2372
{
2373
    int rs;
2374

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

    
2431
/***                    Integer load and store multiple                    ***/
2432
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2433
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
2434
    GEN_MEM_FUNCS(lmw),
2435
};
2436
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
2437
    GEN_MEM_FUNCS(stmw),
2438
};
2439

    
2440
/* lmw */
2441
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2442
{
2443
    /* NIP cannot be restored if the memory exception comes from an helper */
2444
    gen_update_nip(ctx, ctx->nip - 4);
2445
    gen_addr_imm_index(ctx, 0);
2446
    op_ldstm(lmw, rD(ctx->opcode));
2447
}
2448

    
2449
/* stmw */
2450
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2451
{
2452
    /* NIP cannot be restored if the memory exception comes from an helper */
2453
    gen_update_nip(ctx, ctx->nip - 4);
2454
    gen_addr_imm_index(ctx, 0);
2455
    op_ldstm(stmw, rS(ctx->opcode));
2456
}
2457

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

    
2496
/* lswi */
2497
/* PowerPC32 specification says we must generate an exception if
2498
 * rA is in the range of registers to be loaded.
2499
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2500
 * For now, I'll follow the spec...
2501
 */
2502
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
2503
{
2504
    int nb = NB(ctx->opcode);
2505
    int start = rD(ctx->opcode);
2506
    int ra = rA(ctx->opcode);
2507
    int nr;
2508

    
2509
    if (nb == 0)
2510
        nb = 32;
2511
    nr = nb / 4;
2512
    if (unlikely(((start + nr) > 32  &&
2513
                  start <= ra && (start + nr - 32) > ra) ||
2514
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2515
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
2516
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
2517
        return;
2518
    }
2519
    /* NIP cannot be restored if the memory exception comes from an helper */
2520
    gen_update_nip(ctx, ctx->nip - 4);
2521
    gen_addr_register(ctx);
2522
    gen_op_set_T1(nb);
2523
    op_ldsts(lswi, start);
2524
}
2525

    
2526
/* lswx */
2527
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
2528
{
2529
    int ra = rA(ctx->opcode);
2530
    int rb = rB(ctx->opcode);
2531

    
2532
    /* NIP cannot be restored if the memory exception comes from an helper */
2533
    gen_update_nip(ctx, ctx->nip - 4);
2534
    gen_addr_reg_index(ctx);
2535
    if (ra == 0) {
2536
        ra = rb;
2537
    }
2538
    gen_op_load_xer_bc();
2539
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2540
}
2541

    
2542
/* stswi */
2543
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
2544
{
2545
    int nb = NB(ctx->opcode);
2546

    
2547
    /* NIP cannot be restored if the memory exception comes from an helper */
2548
    gen_update_nip(ctx, ctx->nip - 4);
2549
    gen_addr_register(ctx);
2550
    if (nb == 0)
2551
        nb = 32;
2552
    gen_op_set_T1(nb);
2553
    op_ldsts(stsw, rS(ctx->opcode));
2554
}
2555

    
2556
/* stswx */
2557
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
2558
{
2559
    /* NIP cannot be restored if the memory exception comes from an helper */
2560
    gen_update_nip(ctx, ctx->nip - 4);
2561
    gen_addr_reg_index(ctx);
2562
    gen_op_load_xer_bc();
2563
    op_ldsts(stsw, rS(ctx->opcode));
2564
}
2565

    
2566
/***                        Memory synchronisation                         ***/
2567
/* eieio */
2568
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2569
{
2570
}
2571

    
2572
/* isync */
2573
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2574
{
2575
    GEN_STOP(ctx);
2576
}
2577

    
2578
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2579
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2580
static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
2581
    GEN_MEM_FUNCS(lwarx),
2582
};
2583
static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
2584
    GEN_MEM_FUNCS(stwcx),
2585
};
2586

    
2587
/* lwarx */
2588
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2589
{
2590
    /* NIP cannot be restored if the memory exception comes from an helper */
2591
    gen_update_nip(ctx, ctx->nip - 4);
2592
    gen_addr_reg_index(ctx);
2593
    op_lwarx();
2594
    gen_op_store_T1_gpr(rD(ctx->opcode));
2595
}
2596

    
2597
/* stwcx. */
2598
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2599
{
2600
    /* NIP cannot be restored if the memory exception comes from an helper */
2601
    gen_update_nip(ctx, ctx->nip - 4);
2602
    gen_addr_reg_index(ctx);
2603
    gen_op_load_gpr_T1(rS(ctx->opcode));
2604
    op_stwcx();
2605
}
2606

    
2607
#if defined(TARGET_PPC64)
2608
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2609
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2610
static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
2611
    GEN_MEM_FUNCS(ldarx),
2612
};
2613
static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
2614
    GEN_MEM_FUNCS(stdcx),
2615
};
2616

    
2617
/* ldarx */
2618
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2619
{
2620
    /* NIP cannot be restored if the memory exception comes from an helper */
2621
    gen_update_nip(ctx, ctx->nip - 4);
2622
    gen_addr_reg_index(ctx);
2623
    op_ldarx();
2624
    gen_op_store_T1_gpr(rD(ctx->opcode));
2625
}
2626

    
2627
/* stdcx. */
2628
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2629
{
2630
    /* NIP cannot be restored if the memory exception comes from an helper */
2631
    gen_update_nip(ctx, ctx->nip - 4);
2632
    gen_addr_reg_index(ctx);
2633
    gen_op_load_gpr_T1(rS(ctx->opcode));
2634
    op_stdcx();
2635
}
2636
#endif /* defined(TARGET_PPC64) */
2637

    
2638
/* sync */
2639
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
2640
{
2641
}
2642

    
2643
/* wait */
2644
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2645
{
2646
    /* Stop translation, as the CPU is supposed to sleep from now */
2647
    gen_op_wait();
2648
    GEN_EXCP(ctx, EXCP_HLT, 1);
2649
}
2650

    
2651
/***                         Floating-point load                           ***/
2652
#define GEN_LDF(width, opc, type)                                             \
2653
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2654
{                                                                             \
2655
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2656
        GEN_EXCP_NO_FP(ctx);                                                  \
2657
        return;                                                               \
2658
    }                                                                         \
2659
    gen_addr_imm_index(ctx, 0);                                               \
2660
    op_ldst(l##width);                                                        \
2661
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2662
}
2663

    
2664
#define GEN_LDUF(width, opc, type)                                            \
2665
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2666
{                                                                             \
2667
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2668
        GEN_EXCP_NO_FP(ctx);                                                  \
2669
        return;                                                               \
2670
    }                                                                         \
2671
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2672
        GEN_EXCP_INVAL(ctx);                                                  \
2673
        return;                                                               \
2674
    }                                                                         \
2675
    gen_addr_imm_index(ctx, 0);                                               \
2676
    op_ldst(l##width);                                                        \
2677
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2678
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2679
}
2680

    
2681
#define GEN_LDUXF(width, opc, type)                                           \
2682
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
2683
{                                                                             \
2684
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2685
        GEN_EXCP_NO_FP(ctx);                                                  \
2686
        return;                                                               \
2687
    }                                                                         \
2688
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2689
        GEN_EXCP_INVAL(ctx);                                                  \
2690
        return;                                                               \
2691
    }                                                                         \
2692
    gen_addr_reg_index(ctx);                                                  \
2693
    op_ldst(l##width);                                                        \
2694
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2695
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2696
}
2697

    
2698
#define GEN_LDXF(width, opc2, opc3, type)                                     \
2699
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2700
{                                                                             \
2701
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2702
        GEN_EXCP_NO_FP(ctx);                                                  \
2703
        return;                                                               \
2704
    }                                                                         \
2705
    gen_addr_reg_index(ctx);                                                  \
2706
    op_ldst(l##width);                                                        \
2707
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2708
}
2709

    
2710
#define GEN_LDFS(width, op, type)                                             \
2711
OP_LD_TABLE(width);                                                           \
2712
GEN_LDF(width, op | 0x20, type);                                              \
2713
GEN_LDUF(width, op | 0x21, type);                                             \
2714
GEN_LDUXF(width, op | 0x01, type);                                            \
2715
GEN_LDXF(width, 0x17, op | 0x00, type)
2716

    
2717
/* lfd lfdu lfdux lfdx */
2718
GEN_LDFS(fd, 0x12, PPC_FLOAT);
2719
/* lfs lfsu lfsux lfsx */
2720
GEN_LDFS(fs, 0x10, PPC_FLOAT);
2721

    
2722
/***                         Floating-point store                          ***/
2723
#define GEN_STF(width, opc, type)                                             \
2724
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2725
{                                                                             \
2726
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2727
        GEN_EXCP_NO_FP(ctx);                                                  \
2728
        return;                                                               \
2729
    }                                                                         \
2730
    gen_addr_imm_index(ctx, 0);                                               \
2731
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2732
    op_ldst(st##width);                                                       \
2733
}
2734

    
2735
#define GEN_STUF(width, opc, type)                                            \
2736
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2737
{                                                                             \
2738
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2739
        GEN_EXCP_NO_FP(ctx);                                                  \
2740
        return;                                                               \
2741
    }                                                                         \
2742
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2743
        GEN_EXCP_INVAL(ctx);                                                  \
2744
        return;                                                               \
2745
    }                                                                         \
2746
    gen_addr_imm_index(ctx, 0);                                               \
2747
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2748
    op_ldst(st##width);                                                       \
2749
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2750
}
2751

    
2752
#define GEN_STUXF(width, opc, type)                                           \
2753
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
2754
{                                                                             \
2755
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2756
        GEN_EXCP_NO_FP(ctx);                                                  \
2757
        return;                                                               \
2758
    }                                                                         \
2759
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2760
        GEN_EXCP_INVAL(ctx);                                                  \
2761
        return;                                                               \
2762
    }                                                                         \
2763
    gen_addr_reg_index(ctx);                                                  \
2764
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2765
    op_ldst(st##width);                                                       \
2766
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2767
}
2768

    
2769
#define GEN_STXF(width, opc2, opc3, type)                                     \
2770
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2771
{                                                                             \
2772
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2773
        GEN_EXCP_NO_FP(ctx);                                                  \
2774
        return;                                                               \
2775
    }                                                                         \
2776
    gen_addr_reg_index(ctx);                                                  \
2777
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2778
    op_ldst(st##width);                                                       \
2779
}
2780

    
2781
#define GEN_STFS(width, op, type)                                             \
2782
OP_ST_TABLE(width);                                                           \
2783
GEN_STF(width, op | 0x20, type);                                              \
2784
GEN_STUF(width, op | 0x21, type);                                             \
2785
GEN_STUXF(width, op | 0x01, type);                                            \
2786
GEN_STXF(width, 0x17, op | 0x00, type)
2787

    
2788
/* stfd stfdu stfdux stfdx */
2789
GEN_STFS(fd, 0x16, PPC_FLOAT);
2790
/* stfs stfsu stfsux stfsx */
2791
GEN_STFS(fs, 0x14, PPC_FLOAT);
2792

    
2793
/* Optional: */
2794
/* stfiwx */
2795
OP_ST_TABLE(fiw);
2796
GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2797

    
2798
/***                                Branch                                 ***/
2799
static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2800
                                       target_ulong dest)
2801
{
2802
    TranslationBlock *tb;
2803
    tb = ctx->tb;
2804
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2805
        likely(!ctx->singlestep_enabled)) {
2806
        tcg_gen_goto_tb(n);
2807
        gen_set_T1(dest);
2808
#if defined(TARGET_PPC64)
2809
        if (ctx->sf_mode)
2810
            gen_op_b_T1_64();
2811
        else
2812
#endif
2813
            gen_op_b_T1();
2814
        tcg_gen_exit_tb((long)tb + n);
2815
    } else {
2816
        gen_set_T1(dest);
2817
#if defined(TARGET_PPC64)
2818
        if (ctx->sf_mode)
2819
            gen_op_b_T1_64();
2820
        else
2821
#endif
2822
            gen_op_b_T1();
2823
        if (unlikely(ctx->singlestep_enabled)) {
2824
            if ((ctx->singlestep_enabled &
2825
                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
2826
                ctx->exception == POWERPC_EXCP_BRANCH) {
2827
                target_ulong tmp = ctx->nip;
2828
                ctx->nip = dest;
2829
                GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
2830
                ctx->nip = tmp;
2831
            }
2832
            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
2833
                gen_update_nip(ctx, dest);
2834
                gen_op_debug();
2835
            }
2836
        }
2837
        tcg_gen_exit_tb(0);
2838
    }
2839
}
2840

    
2841
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2842
{
2843
#if defined(TARGET_PPC64)
2844
    if (ctx->sf_mode != 0 && (nip >> 32))
2845
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2846
    else
2847
#endif
2848
        gen_op_setlr(ctx->nip);
2849
}
2850

    
2851
/* b ba bl bla */
2852
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2853
{
2854
    target_ulong li, target;
2855

    
2856
    ctx->exception = POWERPC_EXCP_BRANCH;
2857
    /* sign extend LI */
2858
#if defined(TARGET_PPC64)
2859
    if (ctx->sf_mode)
2860
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2861
    else
2862
#endif
2863
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2864
    if (likely(AA(ctx->opcode) == 0))
2865
        target = ctx->nip + li - 4;
2866
    else
2867
        target = li;
2868
#if defined(TARGET_PPC64)
2869
    if (!ctx->sf_mode)
2870
        target = (uint32_t)target;
2871
#endif
2872
    if (LK(ctx->opcode))
2873
        gen_setlr(ctx, ctx->nip);
2874
    gen_goto_tb(ctx, 0, target);
2875
}
2876

    
2877
#define BCOND_IM  0
2878
#define BCOND_LR  1
2879
#define BCOND_CTR 2
2880

    
2881
static always_inline void gen_bcond (DisasContext *ctx, int type)
2882
{
2883
    target_ulong target = 0;
2884
    target_ulong li;
2885
    uint32_t bo = BO(ctx->opcode);
2886
    uint32_t bi = BI(ctx->opcode);
2887
    uint32_t mask;
2888

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

    
3026
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3027
{
3028
    gen_bcond(ctx, BCOND_IM);
3029
}
3030

    
3031
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3032
{
3033
    gen_bcond(ctx, BCOND_CTR);
3034
}
3035

    
3036
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3037
{
3038
    gen_bcond(ctx, BCOND_LR);
3039
}
3040

    
3041
/***                      Condition register logical                       ***/
3042
#define GEN_CRLOGIC(op, opc)                                                  \
3043
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
3044
{                                                                             \
3045
    uint8_t bitmask;                                                          \
3046
    int sh;                                                                   \
3047
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
3048
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3049
    if (sh > 0)                                                               \
3050
        gen_op_srli_T0(sh);                                                   \
3051
    else if (sh < 0)                                                          \
3052
        gen_op_sli_T0(-sh);                                                   \
3053
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
3054
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3055
    if (sh > 0)                                                               \
3056
        gen_op_srli_T1(sh);                                                   \
3057
    else if (sh < 0)                                                          \
3058
        gen_op_sli_T1(-sh);                                                   \
3059
    gen_op_##op();                                                            \
3060
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3061
    gen_op_andi_T0(bitmask);                                                  \
3062
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
3063
    gen_op_andi_T1(~bitmask);                                                 \
3064
    gen_op_or();                                                              \
3065
    gen_op_store_T0_crf(crbD(ctx->opcode) >> 2);                              \
3066
}
3067

    
3068
/* crand */
3069
GEN_CRLOGIC(and, 0x08);
3070
/* crandc */
3071
GEN_CRLOGIC(andc, 0x04);
3072
/* creqv */
3073
GEN_CRLOGIC(eqv, 0x09);
3074
/* crnand */
3075
GEN_CRLOGIC(nand, 0x07);
3076
/* crnor */
3077
GEN_CRLOGIC(nor, 0x01);
3078
/* cror */
3079
GEN_CRLOGIC(or, 0x0E);
3080
/* crorc */
3081
GEN_CRLOGIC(orc, 0x0D);
3082
/* crxor */
3083
GEN_CRLOGIC(xor, 0x06);
3084
/* mcrf */
3085
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3086
{
3087
    gen_op_load_crf_T0(crfS(ctx->opcode));
3088
    gen_op_store_T0_crf(crfD(ctx->opcode));
3089
}
3090

    
3091
/***                           System linkage                              ***/
3092
/* rfi (supervisor only) */
3093
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3094
{
3095
#if defined(CONFIG_USER_ONLY)
3096
    GEN_EXCP_PRIVOPC(ctx);
3097
#else
3098
    /* Restore CPU state */
3099
    if (unlikely(!ctx->supervisor)) {
3100
        GEN_EXCP_PRIVOPC(ctx);
3101
        return;
3102
    }
3103
    gen_op_rfi();
3104
    GEN_SYNC(ctx);
3105
#endif
3106
}
3107

    
3108
#if defined(TARGET_PPC64)
3109
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3110
{
3111
#if defined(CONFIG_USER_ONLY)
3112
    GEN_EXCP_PRIVOPC(ctx);
3113
#else
3114
    /* Restore CPU state */
3115
    if (unlikely(!ctx->supervisor)) {
3116
        GEN_EXCP_PRIVOPC(ctx);
3117
        return;
3118
    }
3119
    gen_op_rfid();
3120
    GEN_SYNC(ctx);
3121
#endif
3122
}
3123

    
3124
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3125
{
3126
#if defined(CONFIG_USER_ONLY)
3127
    GEN_EXCP_PRIVOPC(ctx);
3128
#else
3129
    /* Restore CPU state */
3130
    if (unlikely(ctx->supervisor <= 1)) {
3131
        GEN_EXCP_PRIVOPC(ctx);
3132
        return;
3133
    }
3134
    gen_op_hrfid();
3135
    GEN_SYNC(ctx);
3136
#endif
3137
}
3138
#endif
3139

    
3140
/* sc */
3141
#if defined(CONFIG_USER_ONLY)
3142
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3143
#else
3144
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3145
#endif
3146
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3147
{
3148
    uint32_t lev;
3149

    
3150
    lev = (ctx->opcode >> 5) & 0x7F;
3151
    GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
3152
}
3153

    
3154
/***                                Trap                                   ***/
3155
/* tw */
3156
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3157
{
3158
    gen_op_load_gpr_T0(rA(ctx->opcode));
3159
    gen_op_load_gpr_T1(rB(ctx->opcode));
3160
    /* Update the nip since this might generate a trap exception */
3161
    gen_update_nip(ctx, ctx->nip);
3162
    gen_op_tw(TO(ctx->opcode));
3163
}
3164

    
3165
/* twi */
3166
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3167
{
3168
    gen_op_load_gpr_T0(rA(ctx->opcode));
3169
    gen_set_T1(SIMM(ctx->opcode));
3170
    /* Update the nip since this might generate a trap exception */
3171
    gen_update_nip(ctx, ctx->nip);
3172
    gen_op_tw(TO(ctx->opcode));
3173
}
3174

    
3175
#if defined(TARGET_PPC64)
3176
/* td */
3177
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3178
{
3179
    gen_op_load_gpr_T0(rA(ctx->opcode));
3180
    gen_op_load_gpr_T1(rB(ctx->opcode));
3181
    /* Update the nip since this might generate a trap exception */
3182
    gen_update_nip(ctx, ctx->nip);
3183
    gen_op_td(TO(ctx->opcode));
3184
}
3185

    
3186
/* tdi */
3187
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3188
{
3189
    gen_op_load_gpr_T0(rA(ctx->opcode));
3190
    gen_set_T1(SIMM(ctx->opcode));
3191
    /* Update the nip since this might generate a trap exception */
3192
    gen_update_nip(ctx, ctx->nip);
3193
    gen_op_td(TO(ctx->opcode));
3194
}
3195
#endif
3196

    
3197
/***                          Processor control                            ***/
3198
/* mcrxr */
3199
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3200
{
3201
    gen_op_load_xer_cr();
3202
    gen_op_store_T0_crf(crfD(ctx->opcode));
3203
    gen_op_clear_xer_ov();
3204
    gen_op_clear_xer_ca();
3205
}
3206

    
3207
/* mfcr */
3208
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3209
{
3210
    uint32_t crm, crn;
3211

    
3212
    if (likely(ctx->opcode & 0x00100000)) {
3213
        crm = CRM(ctx->opcode);
3214
        if (likely((crm ^ (crm - 1)) == 0)) {
3215
            crn = ffs(crm);
3216
            gen_op_load_cro(7 - crn);
3217
        }
3218
    } else {
3219
        gen_op_load_cr();
3220
    }
3221
    gen_op_store_T0_gpr(rD(ctx->opcode));
3222
}
3223

    
3224
/* mfmsr */
3225
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3226
{
3227
#if defined(CONFIG_USER_ONLY)
3228
    GEN_EXCP_PRIVREG(ctx);
3229
#else
3230
    if (unlikely(!ctx->supervisor)) {
3231
        GEN_EXCP_PRIVREG(ctx);
3232
        return;
3233
    }
3234
    gen_op_load_msr();
3235
    gen_op_store_T0_gpr(rD(ctx->opcode));
3236
#endif
3237
}
3238

    
3239
#if 1
3240
#define SPR_NOACCESS ((void *)(-1UL))
3241
#else
3242
static void spr_noaccess (void *opaque, int sprn)
3243
{
3244
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3245
    printf("ERROR: try to access SPR %d !\n", sprn);
3246
}
3247
#define SPR_NOACCESS (&spr_noaccess)
3248
#endif
3249

    
3250
/* mfspr */
3251
static always_inline void gen_op_mfspr (DisasContext *ctx)
3252
{
3253
    void (*read_cb)(void *opaque, int sprn);
3254
    uint32_t sprn = SPR(ctx->opcode);
3255

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

    
3297
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3298
{
3299
    gen_op_mfspr(ctx);
3300
}
3301

    
3302
/* mftb */
3303
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3304
{
3305
    gen_op_mfspr(ctx);
3306
}
3307

    
3308
/* mtcrf */
3309
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3310
{
3311
    uint32_t crm, crn;
3312

    
3313
    gen_op_load_gpr_T0(rS(ctx->opcode));
3314
    crm = CRM(ctx->opcode);
3315
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3316
        crn = ffs(crm);
3317
        gen_op_srli_T0(crn * 4);
3318
        gen_op_andi_T0(0xF);
3319
        gen_op_store_cro(7 - crn);
3320
    } else {
3321
        gen_op_store_cr(crm);
3322
    }
3323
}
3324

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

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

    
3387
/* mtspr */
3388
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3389
{
3390
    void (*write_cb)(void *opaque, int sprn);
3391
    uint32_t sprn = SPR(ctx->opcode);
3392

    
3393
#if !defined(CONFIG_USER_ONLY)
3394
    if (ctx->supervisor == 2)
3395
        write_cb = ctx->spr_cb[sprn].hea_write;
3396
    else if (ctx->supervisor)
3397
        write_cb = ctx->spr_cb[sprn].oea_write;
3398
    else
3399
#endif
3400
        write_cb = ctx->spr_cb[sprn].uea_write;
3401
    if (likely(write_cb != NULL)) {
3402
        if (likely(write_cb != SPR_NOACCESS)) {
3403
            gen_op_load_gpr_T0(rS(ctx->opcode));
3404
            (*write_cb)(ctx, sprn);
3405
        } else {
3406
            /* Privilege exception */
3407
            if (loglevel != 0) {
3408
                fprintf(logfile, "Trying to write privileged spr %d %03x at "
3409
                        ADDRX "\n", sprn, sprn, ctx->nip);
3410
            }
3411
            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
3412
                   sprn, sprn, ctx->nip);
3413
            GEN_EXCP_PRIVREG(ctx);
3414
        }
3415
    } else {
3416
        /* Not defined */
3417
        if (loglevel != 0) {
3418
            fprintf(logfile, "Trying to write invalid spr %d %03x at "
3419
                    ADDRX "\n", sprn, sprn, ctx->nip);
3420
        }
3421
        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
3422
               sprn, sprn, ctx->nip);
3423
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3424
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3425
    }
3426
}
3427

    
3428
/***                         Cache management                              ***/
3429
/* dcbf */
3430
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3431
{
3432
    /* XXX: specification says this is treated as a load by the MMU */
3433
    gen_addr_reg_index(ctx);
3434
    op_ldst(lbz);
3435
}
3436

    
3437
/* dcbi (Supervisor only) */
3438
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3439
{
3440
#if defined(CONFIG_USER_ONLY)
3441
    GEN_EXCP_PRIVOPC(ctx);
3442
#else
3443
    if (unlikely(!ctx->supervisor)) {
3444
        GEN_EXCP_PRIVOPC(ctx);
3445
        return;
3446
    }
3447
    gen_addr_reg_index(ctx);
3448
    /* XXX: specification says this should be treated as a store by the MMU */
3449
    op_ldst(lbz);
3450
    op_ldst(stb);
3451
#endif
3452
}
3453

    
3454
/* dcdst */
3455
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3456
{
3457
    /* XXX: specification say this is treated as a load by the MMU */
3458
    gen_addr_reg_index(ctx);
3459
    op_ldst(lbz);
3460
}
3461

    
3462
/* dcbt */
3463
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3464
{
3465
    /* interpreted as no-op */
3466
    /* XXX: specification say this is treated as a load by the MMU
3467
     *      but does not generate any exception
3468
     */
3469
}
3470

    
3471
/* dcbtst */
3472
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3473
{
3474
    /* interpreted as no-op */
3475
    /* XXX: specification say this is treated as a load by the MMU
3476
     *      but does not generate any exception
3477
     */
3478
}
3479

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

    
3533
static always_inline void handler_dcbz (DisasContext *ctx,
3534
                                        int dcache_line_size)
3535
{
3536
    int n;
3537

    
3538
    switch (dcache_line_size) {
3539
    case 32:
3540
        n = 0;
3541
        break;
3542
    case 64:
3543
        n = 1;
3544
        break;
3545
    case 128:
3546
        n = 2;
3547
        break;
3548
    default:
3549
        n = 3;
3550
        break;
3551
    }
3552
    op_dcbz(n);
3553
}
3554

    
3555
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
3556
{
3557
    gen_addr_reg_index(ctx);
3558
    handler_dcbz(ctx, ctx->dcache_line_size);
3559
    gen_op_check_reservation();
3560
}
3561

    
3562
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
3563
{
3564
    gen_addr_reg_index(ctx);
3565
    if (ctx->opcode & 0x00200000)
3566
        handler_dcbz(ctx, ctx->dcache_line_size);
3567
    else
3568
        handler_dcbz(ctx, -1);
3569
    gen_op_check_reservation();
3570
}
3571

    
3572
/* icbi */
3573
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3574
#define gen_op_icbi_le_raw       gen_op_icbi_raw
3575
#define gen_op_icbi_le_user      gen_op_icbi_user
3576
#define gen_op_icbi_le_kernel    gen_op_icbi_kernel
3577
#define gen_op_icbi_le_hypv      gen_op_icbi_hypv
3578
#define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
3579
#define gen_op_icbi_le_64_user   gen_op_icbi_64_user
3580
#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
3581
#define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
3582
static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
3583
    GEN_MEM_FUNCS(icbi),
3584
};
3585

    
3586
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
3587
{
3588
    /* NIP cannot be restored if the memory exception comes from an helper */
3589
    gen_update_nip(ctx, ctx->nip - 4);
3590
    gen_addr_reg_index(ctx);
3591
    op_icbi();
3592
}
3593

    
3594
/* Optional: */
3595
/* dcba */
3596
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3597
{
3598
    /* interpreted as no-op */
3599
    /* XXX: specification say this is treated as a store by the MMU
3600
     *      but does not generate any exception
3601
     */
3602
}
3603

    
3604
/***                    Segment register manipulation                      ***/
3605
/* Supervisor only: */
3606
/* mfsr */
3607
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3608
{
3609
#if defined(CONFIG_USER_ONLY)
3610
    GEN_EXCP_PRIVREG(ctx);
3611
#else
3612
    if (unlikely(!ctx->supervisor)) {
3613
        GEN_EXCP_PRIVREG(ctx);
3614
        return;
3615
    }
3616
    gen_op_set_T1(SR(ctx->opcode));
3617
    gen_op_load_sr();
3618
    gen_op_store_T0_gpr(rD(ctx->opcode));
3619
#endif
3620
}
3621

    
3622
/* mfsrin */
3623
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3624
{
3625
#if defined(CONFIG_USER_ONLY)
3626
    GEN_EXCP_PRIVREG(ctx);
3627
#else
3628
    if (unlikely(!ctx->supervisor)) {
3629
        GEN_EXCP_PRIVREG(ctx);
3630
        return;
3631
    }
3632
    gen_op_load_gpr_T1(rB(ctx->opcode));
3633
    gen_op_srli_T1(28);
3634
    gen_op_load_sr();
3635
    gen_op_store_T0_gpr(rD(ctx->opcode));
3636
#endif
3637
}
3638

    
3639
/* mtsr */
3640
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3641
{
3642
#if defined(CONFIG_USER_ONLY)
3643
    GEN_EXCP_PRIVREG(ctx);
3644
#else
3645
    if (unlikely(!ctx->supervisor)) {
3646
        GEN_EXCP_PRIVREG(ctx);
3647
        return;
3648
    }
3649
    gen_op_load_gpr_T0(rS(ctx->opcode));
3650
    gen_op_set_T1(SR(ctx->opcode));
3651
    gen_op_store_sr();
3652
#endif
3653
}
3654

    
3655
/* mtsrin */
3656
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3657
{
3658
#if defined(CONFIG_USER_ONLY)
3659
    GEN_EXCP_PRIVREG(ctx);
3660
#else
3661
    if (unlikely(!ctx->supervisor)) {
3662
        GEN_EXCP_PRIVREG(ctx);
3663
        return;
3664
    }
3665
    gen_op_load_gpr_T0(rS(ctx->opcode));
3666
    gen_op_load_gpr_T1(rB(ctx->opcode));
3667
    gen_op_srli_T1(28);
3668
    gen_op_store_sr();
3669
#endif
3670
}
3671

    
3672
#if defined(TARGET_PPC64)
3673
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
3674
/* mfsr */
3675
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
3676
{
3677
#if defined(CONFIG_USER_ONLY)
3678
    GEN_EXCP_PRIVREG(ctx);
3679
#else
3680
    if (unlikely(!ctx->supervisor)) {
3681
        GEN_EXCP_PRIVREG(ctx);
3682
        return;
3683
    }
3684
    gen_op_set_T1(SR(ctx->opcode));
3685
    gen_op_load_slb();
3686
    gen_op_store_T0_gpr(rD(ctx->opcode));
3687
#endif
3688
}
3689

    
3690
/* mfsrin */
3691
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
3692
             PPC_SEGMENT_64B)
3693
{
3694
#if defined(CONFIG_USER_ONLY)
3695
    GEN_EXCP_PRIVREG(ctx);
3696
#else
3697
    if (unlikely(!ctx->supervisor)) {
3698
        GEN_EXCP_PRIVREG(ctx);
3699
        return;
3700
    }
3701
    gen_op_load_gpr_T1(rB(ctx->opcode));
3702
    gen_op_srli_T1(28);
3703
    gen_op_load_slb();
3704
    gen_op_store_T0_gpr(rD(ctx->opcode));
3705
#endif
3706
}
3707

    
3708
/* mtsr */
3709
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
3710
{
3711
#if defined(CONFIG_USER_ONLY)
3712
    GEN_EXCP_PRIVREG(ctx);
3713
#else
3714
    if (unlikely(!ctx->supervisor)) {
3715
        GEN_EXCP_PRIVREG(ctx);
3716
        return;
3717
    }
3718
    gen_op_load_gpr_T0(rS(ctx->opcode));
3719
    gen_op_set_T1(SR(ctx->opcode));
3720
    gen_op_store_slb();
3721
#endif
3722
}
3723

    
3724
/* mtsrin */
3725
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
3726
             PPC_SEGMENT_64B)
3727
{
3728
#if defined(CONFIG_USER_ONLY)
3729
    GEN_EXCP_PRIVREG(ctx);
3730
#else
3731
    if (unlikely(!ctx->supervisor)) {
3732
        GEN_EXCP_PRIVREG(ctx);
3733
        return;
3734
    }
3735
    gen_op_load_gpr_T0(rS(ctx->opcode));
3736
    gen_op_load_gpr_T1(rB(ctx->opcode));
3737
    gen_op_srli_T1(28);
3738
    gen_op_store_slb();
3739
#endif
3740
}
3741
#endif /* defined(TARGET_PPC64) */
3742

    
3743
/***                      Lookaside buffer management                      ***/
3744
/* Optional & supervisor only: */
3745
/* tlbia */
3746
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3747
{
3748
#if defined(CONFIG_USER_ONLY)
3749
    GEN_EXCP_PRIVOPC(ctx);
3750
#else
3751
    if (unlikely(!ctx->supervisor)) {
3752
        GEN_EXCP_PRIVOPC(ctx);
3753
        return;
3754
    }
3755
    gen_op_tlbia();
3756
#endif
3757
}
3758

    
3759
/* tlbie */
3760
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3761
{
3762
#if defined(CONFIG_USER_ONLY)
3763
    GEN_EXCP_PRIVOPC(ctx);
3764
#else
3765
    if (unlikely(!ctx->supervisor)) {
3766
        GEN_EXCP_PRIVOPC(ctx);
3767
        return;
3768
    }
3769
    gen_op_load_gpr_T0(rB(ctx->opcode));
3770
#if defined(TARGET_PPC64)
3771
    if (ctx->sf_mode)
3772
        gen_op_tlbie_64();
3773
    else
3774
#endif
3775
        gen_op_tlbie();
3776
#endif
3777
}
3778

    
3779
/* tlbsync */
3780
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3781
{
3782
#if defined(CONFIG_USER_ONLY)
3783
    GEN_EXCP_PRIVOPC(ctx);
3784
#else
3785
    if (unlikely(!ctx->supervisor)) {
3786
        GEN_EXCP_PRIVOPC(ctx);
3787
        return;
3788
    }
3789
    /* This has no effect: it should ensure that all previous
3790
     * tlbie have completed
3791
     */
3792
    GEN_STOP(ctx);
3793
#endif
3794
}
3795

    
3796
#if defined(TARGET_PPC64)
3797
/* slbia */
3798
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3799
{
3800
#if defined(CONFIG_USER_ONLY)
3801
    GEN_EXCP_PRIVOPC(ctx);
3802
#else
3803
    if (unlikely(!ctx->supervisor)) {
3804
        GEN_EXCP_PRIVOPC(ctx);
3805
        return;
3806
    }
3807
    gen_op_slbia();
3808
#endif
3809
}
3810

    
3811
/* slbie */
3812
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3813
{
3814
#if defined(CONFIG_USER_ONLY)
3815
    GEN_EXCP_PRIVOPC(ctx);
3816
#else
3817
    if (unlikely(!ctx->supervisor)) {
3818
        GEN_EXCP_PRIVOPC(ctx);
3819
        return;
3820
    }
3821
    gen_op_load_gpr_T0(rB(ctx->opcode));
3822
    gen_op_slbie();
3823
#endif
3824
}
3825
#endif
3826

    
3827
/***                              External control                         ***/
3828
/* Optional: */
3829
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3830
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3831
static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
3832
    GEN_MEM_FUNCS(eciwx),
3833
};
3834
static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
3835
    GEN_MEM_FUNCS(ecowx),
3836
};
3837

    
3838
/* eciwx */
3839
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3840
{
3841
    /* Should check EAR[E] & alignment ! */
3842
    gen_addr_reg_index(ctx);
3843
    op_eciwx();
3844
    gen_op_store_T0_gpr(rD(ctx->opcode));
3845
}
3846

    
3847
/* ecowx */
3848
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3849
{
3850
    /* Should check EAR[E] & alignment ! */
3851
    gen_addr_reg_index(ctx);
3852
    gen_op_load_gpr_T1(rS(ctx->opcode));
3853
    op_ecowx();
3854
}
3855

    
3856
/* PowerPC 601 specific instructions */
3857
/* abs - abs. */
3858
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3859
{
3860
    gen_op_load_gpr_T0(rA(ctx->opcode));
3861
    gen_op_POWER_abs();
3862
    gen_op_store_T0_gpr(rD(ctx->opcode));
3863
    if (unlikely(Rc(ctx->opcode) != 0))
3864
        gen_set_Rc0(ctx);
3865
}
3866

    
3867
/* abso - abso. */
3868
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3869
{
3870
    gen_op_load_gpr_T0(rA(ctx->opcode));
3871
    gen_op_POWER_abso();
3872
    gen_op_store_T0_gpr(rD(ctx->opcode));
3873
    if (unlikely(Rc(ctx->opcode) != 0))
3874
        gen_set_Rc0(ctx);
3875
}
3876

    
3877
/* clcs */
3878
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3879
{
3880
    gen_op_load_gpr_T0(rA(ctx->opcode));
3881
    gen_op_POWER_clcs();
3882
    /* Rc=1 sets CR0 to an undefined state */
3883
    gen_op_store_T0_gpr(rD(ctx->opcode));
3884
}
3885

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

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

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

    
3919
/* divso - divso. */
3920
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3921
{
3922
    gen_op_load_gpr_T0(rA(ctx->opcode));
3923
    gen_op_load_gpr_T1(rB(ctx->opcode));
3924
    gen_op_POWER_divso();
3925
    gen_op_store_T0_gpr(rD(ctx->opcode));
3926
    if (unlikely(Rc(ctx->opcode) != 0))
3927
        gen_set_Rc0(ctx);
3928
}
3929

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

    
3941
/* dozo - dozo. */
3942
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3943
{
3944
    gen_op_load_gpr_T0(rA(ctx->opcode));
3945
    gen_op_load_gpr_T1(rB(ctx->opcode));
3946
    gen_op_POWER_dozo();
3947
    gen_op_store_T0_gpr(rD(ctx->opcode));
3948
    if (unlikely(Rc(ctx->opcode) != 0))
3949
        gen_set_Rc0(ctx);
3950
}
3951

    
3952
/* dozi */
3953
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3954
{
3955
    gen_op_load_gpr_T0(rA(ctx->opcode));
3956
    gen_op_set_T1(SIMM(ctx->opcode));
3957
    gen_op_POWER_doz();
3958
    gen_op_store_T0_gpr(rD(ctx->opcode));
3959
}
3960

    
3961
/* As lscbx load from memory byte after byte, it's always endian safe.
3962
 * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones
3963
 */
3964
#define op_POWER_lscbx(start, ra, rb)                                         \
3965
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3966
#define gen_op_POWER_lscbx_64_raw       gen_op_POWER_lscbx_raw
3967
#define gen_op_POWER_lscbx_64_user      gen_op_POWER_lscbx_user
3968
#define gen_op_POWER_lscbx_64_kernel    gen_op_POWER_lscbx_kernel
3969
#define gen_op_POWER_lscbx_64_hypv      gen_op_POWER_lscbx_hypv
3970
#define gen_op_POWER_lscbx_le_raw       gen_op_POWER_lscbx_raw
3971
#define gen_op_POWER_lscbx_le_user      gen_op_POWER_lscbx_user
3972
#define gen_op_POWER_lscbx_le_kernel    gen_op_POWER_lscbx_kernel
3973
#define gen_op_POWER_lscbx_le_hypv      gen_op_POWER_lscbx_hypv
3974
#define gen_op_POWER_lscbx_le_64_raw    gen_op_POWER_lscbx_raw
3975
#define gen_op_POWER_lscbx_le_64_user   gen_op_POWER_lscbx_user
3976
#define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel
3977
#define gen_op_POWER_lscbx_le_64_hypv   gen_op_POWER_lscbx_hypv
3978
static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = {
3979
    GEN_MEM_FUNCS(POWER_lscbx),
3980
};
3981

    
3982
/* lscbx - lscbx. */
3983
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3984
{
3985
    int ra = rA(ctx->opcode);
3986
    int rb = rB(ctx->opcode);
3987

    
3988
    gen_addr_reg_index(ctx);
3989
    if (ra == 0) {
3990
        ra = rb;
3991
    }
3992
    /* NIP cannot be restored if the memory exception comes from an helper */
3993
    gen_update_nip(ctx, ctx->nip - 4);
3994
    gen_op_load_xer_bc();
3995
    gen_op_load_xer_cmp();
3996
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3997
    gen_op_store_xer_bc();
3998
    if (unlikely(Rc(ctx->opcode) != 0))
3999
        gen_set_Rc0(ctx);
4000
}
4001

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

    
4013
/* maskir - maskir. */
4014
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4015
{
4016
    gen_op_load_gpr_T0(rA(ctx->opcode));
4017
    gen_op_load_gpr_T1(rS(ctx->opcode));
4018
    gen_op_load_gpr_T2(rB(ctx->opcode));
4019
    gen_op_POWER_maskir();
4020
    gen_op_store_T0_gpr(rA(ctx->opcode));
4021
    if (unlikely(Rc(ctx->opcode) != 0))
4022
        gen_set_Rc0(ctx);
4023
}
4024

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

    
4036
/* mulo - mulo. */
4037
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4038
{
4039
    gen_op_load_gpr_T0(rA(ctx->opcode));
4040
    gen_op_load_gpr_T1(rB(ctx->opcode));
4041
    gen_op_POWER_mulo();
4042
    gen_op_store_T0_gpr(rD(ctx->opcode));
4043
    if (unlikely(Rc(ctx->opcode) != 0))
4044
        gen_set_Rc0(ctx);
4045
}
4046

    
4047
/* nabs - nabs. */
4048
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4049
{
4050
    gen_op_load_gpr_T0(rA(ctx->opcode));
4051
    gen_op_POWER_nabs();
4052
    gen_op_store_T0_gpr(rD(ctx->opcode));
4053
    if (unlikely(Rc(ctx->opcode) != 0))
4054
        gen_set_Rc0(ctx);
4055
}
4056

    
4057
/* nabso - nabso. */
4058
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4059
{
4060
    gen_op_load_gpr_T0(rA(ctx->opcode));
4061
    gen_op_POWER_nabso();
4062
    gen_op_store_T0_gpr(rD(ctx->opcode));
4063
    if (unlikely(Rc(ctx->opcode) != 0))
4064
        gen_set_Rc0(ctx);
4065
}
4066

    
4067
/* rlmi - rlmi. */
4068
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4069
{
4070
    uint32_t mb, me;
4071

    
4072
    mb = MB(ctx->opcode);
4073
    me = ME(ctx->opcode);
4074
    gen_op_load_gpr_T0(rS(ctx->opcode));
4075
    gen_op_load_gpr_T1(rA(ctx->opcode));
4076
    gen_op_load_gpr_T2(rB(ctx->opcode));
4077
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4078
    gen_op_store_T0_gpr(rA(ctx->opcode));
4079
    if (unlikely(Rc(ctx->opcode) != 0))
4080
        gen_set_Rc0(ctx);
4081
}
4082

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

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

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

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

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

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

    
4150
/* slq - slq. */
4151
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4152
{
4153
    gen_op_load_gpr_T0(rS(ctx->opcode));
4154
    gen_op_load_gpr_T1(rB(ctx->opcode));
4155
    gen_op_POWER_slq();
4156
    gen_op_store_T0_gpr(rA(ctx->opcode));
4157
    if (unlikely(Rc(ctx->opcode) != 0))
4158
        gen_set_Rc0(ctx);
4159
}
4160

    
4161
/* sraiq - sraiq. */
4162
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4163
{
4164
    gen_op_load_gpr_T0(rS(ctx->opcode));
4165
    gen_op_set_T1(SH(ctx->opcode));
4166
    gen_op_POWER_sraq();
4167
    gen_op_store_T0_gpr(rA(ctx->opcode));
4168
    if (unlikely(Rc(ctx->opcode) != 0))
4169
        gen_set_Rc0(ctx);
4170
}
4171

    
4172
/* sraq - sraq. */
4173
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4174
{
4175
    gen_op_load_gpr_T0(rS(ctx->opcode));
4176
    gen_op_load_gpr_T1(rB(ctx->opcode));
4177
    gen_op_POWER_sraq();
4178
    gen_op_store_T0_gpr(rA(ctx->opcode));
4179
    if (unlikely(Rc(ctx->opcode) != 0))
4180
        gen_set_Rc0(ctx);
4181
}
4182

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

    
4194
/* srea - srea. */
4195
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4196
{
4197
    gen_op_load_gpr_T0(rS(ctx->opcode));
4198
    gen_op_load_gpr_T1(rB(ctx->opcode));
4199
    gen_op_POWER_srea();
4200
    gen_op_store_T0_gpr(rA(ctx->opcode));
4201
    if (unlikely(Rc(ctx->opcode) != 0))
4202
        gen_set_Rc0(ctx);
4203
}
4204

    
4205
/* sreq */
4206
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4207
{
4208
    gen_op_load_gpr_T0(rS(ctx->opcode));
4209
    gen_op_load_gpr_T1(rB(ctx->opcode));
4210
    gen_op_POWER_sreq();
4211
    gen_op_store_T0_gpr(rA(ctx->opcode));
4212
    if (unlikely(Rc(ctx->opcode) != 0))
4213
        gen_set_Rc0(ctx);
4214
}
4215

    
4216
/* sriq */
4217
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4218
{
4219
    gen_op_load_gpr_T0(rS(ctx->opcode));
4220
    gen_op_set_T1(SH(ctx->opcode));
4221
    gen_op_POWER_srq();
4222
    gen_op_store_T0_gpr(rA(ctx->opcode));
4223
    if (unlikely(Rc(ctx->opcode) != 0))
4224
        gen_set_Rc0(ctx);
4225
}
4226

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

    
4239
/* srlq */
4240
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4241
{
4242
    gen_op_load_gpr_T0(rS(ctx->opcode));
4243
    gen_op_load_gpr_T1(rB(ctx->opcode));
4244
    gen_op_POWER_srlq();
4245
    gen_op_store_T0_gpr(rA(ctx->opcode));
4246
    if (unlikely(Rc(ctx->opcode) != 0))
4247
        gen_set_Rc0(ctx);
4248
}
4249

    
4250
/* srq */
4251
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4252
{
4253
    gen_op_load_gpr_T0(rS(ctx->opcode));
4254
    gen_op_load_gpr_T1(rB(ctx->opcode));
4255
    gen_op_POWER_srq();
4256
    gen_op_store_T0_gpr(rA(ctx->opcode));
4257
    if (unlikely(Rc(ctx->opcode) != 0))
4258
        gen_set_Rc0(ctx);
4259
}
4260

    
4261
/* PowerPC 602 specific instructions */
4262
/* dsa  */
4263
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4264
{
4265
    /* XXX: TODO */
4266
    GEN_EXCP_INVAL(ctx);
4267
}
4268

    
4269
/* esa */
4270
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4271
{
4272
    /* XXX: TODO */
4273
    GEN_EXCP_INVAL(ctx);
4274
}
4275

    
4276
/* mfrom */
4277
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4278
{
4279
#if defined(CONFIG_USER_ONLY)
4280
    GEN_EXCP_PRIVOPC(ctx);
4281
#else
4282
    if (unlikely(!ctx->supervisor)) {
4283
        GEN_EXCP_PRIVOPC(ctx);
4284
        return;
4285
    }
4286
    gen_op_load_gpr_T0(rA(ctx->opcode));
4287
    gen_op_602_mfrom();
4288
    gen_op_store_T0_gpr(rD(ctx->opcode));
4289
#endif
4290
}
4291

    
4292
/* 602 - 603 - G2 TLB management */
4293
/* tlbld */
4294
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_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_6xx_tlbld();
4305
#endif
4306
}
4307

    
4308
/* tlbli */
4309
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_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_6xx_tlbli();
4320
#endif
4321
}
4322

    
4323
/* 74xx TLB management */
4324
/* tlbld */
4325
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4326
{
4327
#if defined(CONFIG_USER_ONLY)
4328
    GEN_EXCP_PRIVOPC(ctx);
4329
#else
4330
    if (unlikely(!ctx->supervisor)) {
4331
        GEN_EXCP_PRIVOPC(ctx);
4332
        return;
4333
    }
4334
    gen_op_load_gpr_T0(rB(ctx->opcode));
4335
    gen_op_74xx_tlbld();
4336
#endif
4337
}
4338

    
4339
/* tlbli */
4340
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4341
{
4342
#if defined(CONFIG_USER_ONLY)
4343
    GEN_EXCP_PRIVOPC(ctx);
4344
#else
4345
    if (unlikely(!ctx->supervisor)) {
4346
        GEN_EXCP_PRIVOPC(ctx);
4347
        return;
4348
    }
4349
    gen_op_load_gpr_T0(rB(ctx->opcode));
4350
    gen_op_74xx_tlbli();
4351
#endif
4352
}
4353

    
4354
/* POWER instructions not in PowerPC 601 */
4355
/* clf */
4356
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4357
{
4358
    /* Cache line flush: implemented as no-op */
4359
}
4360

    
4361
/* cli */
4362
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4363
{
4364
    /* Cache line invalidate: privileged and treated as no-op */
4365
#if defined(CONFIG_USER_ONLY)
4366
    GEN_EXCP_PRIVOPC(ctx);
4367
#else
4368
    if (unlikely(!ctx->supervisor)) {
4369
        GEN_EXCP_PRIVOPC(ctx);
4370
        return;
4371
    }
4372
#endif
4373
}
4374

    
4375
/* dclst */
4376
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4377
{
4378
    /* Data cache line store: treated as no-op */
4379
}
4380

    
4381
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4382
{
4383
#if defined(CONFIG_USER_ONLY)
4384
    GEN_EXCP_PRIVOPC(ctx);
4385
#else
4386
    if (unlikely(!ctx->supervisor)) {
4387
        GEN_EXCP_PRIVOPC(ctx);
4388
        return;
4389
    }
4390
    int ra = rA(ctx->opcode);
4391
    int rd = rD(ctx->opcode);
4392

    
4393
    gen_addr_reg_index(ctx);
4394
    gen_op_POWER_mfsri();
4395
    gen_op_store_T0_gpr(rd);
4396
    if (ra != 0 && ra != rd)
4397
        gen_op_store_T1_gpr(ra);
4398
#endif
4399
}
4400

    
4401
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4402
{
4403
#if defined(CONFIG_USER_ONLY)
4404
    GEN_EXCP_PRIVOPC(ctx);
4405
#else
4406
    if (unlikely(!ctx->supervisor)) {
4407
        GEN_EXCP_PRIVOPC(ctx);
4408
        return;
4409
    }
4410
    gen_addr_reg_index(ctx);
4411
    gen_op_POWER_rac();
4412
    gen_op_store_T0_gpr(rD(ctx->opcode));
4413
#endif
4414
}
4415

    
4416
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4417
{
4418
#if defined(CONFIG_USER_ONLY)
4419
    GEN_EXCP_PRIVOPC(ctx);
4420
#else
4421
    if (unlikely(!ctx->supervisor)) {
4422
        GEN_EXCP_PRIVOPC(ctx);
4423
        return;
4424
    }
4425
    gen_op_POWER_rfsvc();
4426
    GEN_SYNC(ctx);
4427
#endif
4428
}
4429

    
4430
/* svc is not implemented for now */
4431

    
4432
/* POWER2 specific instructions */
4433
/* Quad manipulation (load/store two floats at a time) */
4434
/* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
4435
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4436
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4437
#define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
4438
#define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
4439
#define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
4440
#define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
4441
#define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
4442
#define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
4443
#define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
4444
#define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
4445
#define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
4446
#define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
4447
#define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
4448
#define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
4449
#define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
4450
#define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
4451
#define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
4452
#define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
4453
static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
4454
    GEN_MEM_FUNCS(POWER2_lfq),
4455
};
4456
static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
4457
    GEN_MEM_FUNCS(POWER2_stfq),
4458
};
4459

    
4460
/* lfq */
4461
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4462
{
4463
    /* NIP cannot be restored if the memory exception comes from an helper */
4464
    gen_update_nip(ctx, ctx->nip - 4);
4465
    gen_addr_imm_index(ctx, 0);
4466
    op_POWER2_lfq();
4467
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4468
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4469
}
4470

    
4471
/* lfqu */
4472
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4473
{
4474
    int ra = rA(ctx->opcode);
4475

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

    
4486
/* lfqux */
4487
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4488
{
4489
    int ra = rA(ctx->opcode);
4490

    
4491
    /* NIP cannot be restored if the memory exception comes from an helper */
4492
    gen_update_nip(ctx, ctx->nip - 4);
4493
    gen_addr_reg_index(ctx);
4494
    op_POWER2_lfq();
4495
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4496
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4497
    if (ra != 0)
4498
        gen_op_store_T0_gpr(ra);
4499
}
4500

    
4501
/* lfqx */
4502
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4503
{
4504
    /* NIP cannot be restored if the memory exception comes from an helper */
4505
    gen_update_nip(ctx, ctx->nip - 4);
4506
    gen_addr_reg_index(ctx);
4507
    op_POWER2_lfq();
4508
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4509
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4510
}
4511

    
4512
/* stfq */
4513
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4514
{
4515
    /* NIP cannot be restored if the memory exception comes from an helper */
4516
    gen_update_nip(ctx, ctx->nip - 4);
4517
    gen_addr_imm_index(ctx, 0);
4518
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4519
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4520
    op_POWER2_stfq();
4521
}
4522

    
4523
/* stfqu */
4524
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4525
{
4526
    int ra = rA(ctx->opcode);
4527

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

    
4538
/* stfqux */
4539
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4540
{
4541
    int ra = rA(ctx->opcode);
4542

    
4543
    /* NIP cannot be restored if the memory exception comes from an helper */
4544
    gen_update_nip(ctx, ctx->nip - 4);
4545
    gen_addr_reg_index(ctx);
4546
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4547
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4548
    op_POWER2_stfq();
4549
    if (ra != 0)
4550
        gen_op_store_T0_gpr(ra);
4551
}
4552

    
4553
/* stfqx */
4554
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4555
{
4556
    /* NIP cannot be restored if the memory exception comes from an helper */
4557
    gen_update_nip(ctx, ctx->nip - 4);
4558
    gen_addr_reg_index(ctx);
4559
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4560
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4561
    op_POWER2_stfq();
4562
}
4563

    
4564
/* BookE specific instructions */
4565
/* XXX: not implemented on 440 ? */
4566
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
4567
{
4568
    /* XXX: TODO */
4569
    GEN_EXCP_INVAL(ctx);
4570
}
4571

    
4572
/* XXX: not implemented on 440 ? */
4573
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
4574
{
4575
#if defined(CONFIG_USER_ONLY)
4576
    GEN_EXCP_PRIVOPC(ctx);
4577
#else
4578
    if (unlikely(!ctx->supervisor)) {
4579
        GEN_EXCP_PRIVOPC(ctx);
4580
        return;
4581
    }
4582
    gen_addr_reg_index(ctx);
4583
    /* Use the same micro-ops as for tlbie */
4584
#if defined(TARGET_PPC64)
4585
    if (ctx->sf_mode)
4586
        gen_op_tlbie_64();
4587
    else
4588
#endif
4589
        gen_op_tlbie();
4590
#endif
4591
}
4592

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

    
4675
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4676
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4677
{                                                                             \
4678
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4679
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4680
}
4681

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

    
4755
/* mulchw  - mulchw.  */
4756
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4757
/* mulchwu - mulchwu. */
4758
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4759
/* mulhhw  - mulhhw.  */
4760
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4761
/* mulhhwu - mulhhwu. */
4762
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4763
/* mullhw  - mullhw.  */
4764
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4765
/* mullhwu - mullhwu. */
4766
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4767

    
4768
/* mfdcr */
4769
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
4770
{
4771
#if defined(CONFIG_USER_ONLY)
4772
    GEN_EXCP_PRIVREG(ctx);
4773
#else
4774
    uint32_t dcrn = SPR(ctx->opcode);
4775

    
4776
    if (unlikely(!ctx->supervisor)) {
4777
        GEN_EXCP_PRIVREG(ctx);
4778
        return;
4779
    }
4780
    gen_op_set_T0(dcrn);
4781
    gen_op_load_dcr();
4782
    gen_op_store_T0_gpr(rD(ctx->opcode));
4783
#endif
4784
}
4785

    
4786
/* mtdcr */
4787
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
4788
{
4789
#if defined(CONFIG_USER_ONLY)
4790
    GEN_EXCP_PRIVREG(ctx);
4791
#else
4792
    uint32_t dcrn = SPR(ctx->opcode);
4793

    
4794
    if (unlikely(!ctx->supervisor)) {
4795
        GEN_EXCP_PRIVREG(ctx);
4796
        return;
4797
    }
4798
    gen_op_set_T0(dcrn);
4799
    gen_op_load_gpr_T1(rS(ctx->opcode));
4800
    gen_op_store_dcr();
4801
#endif
4802
}
4803

    
4804
/* mfdcrx */
4805
/* XXX: not implemented on 440 ? */
4806
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
4807
{
4808
#if defined(CONFIG_USER_ONLY)
4809
    GEN_EXCP_PRIVREG(ctx);
4810
#else
4811
    if (unlikely(!ctx->supervisor)) {
4812
        GEN_EXCP_PRIVREG(ctx);
4813
        return;
4814
    }
4815
    gen_op_load_gpr_T0(rA(ctx->opcode));
4816
    gen_op_load_dcr();
4817
    gen_op_store_T0_gpr(rD(ctx->opcode));
4818
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4819
#endif
4820
}
4821

    
4822
/* mtdcrx */
4823
/* XXX: not implemented on 440 ? */
4824
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
4825
{
4826
#if defined(CONFIG_USER_ONLY)
4827
    GEN_EXCP_PRIVREG(ctx);
4828
#else
4829
    if (unlikely(!ctx->supervisor)) {
4830
        GEN_EXCP_PRIVREG(ctx);
4831
        return;
4832
    }
4833
    gen_op_load_gpr_T0(rA(ctx->opcode));
4834
    gen_op_load_gpr_T1(rS(ctx->opcode));
4835
    gen_op_store_dcr();
4836
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4837
#endif
4838
}
4839

    
4840
/* mfdcrux (PPC 460) : user-mode access to DCR */
4841
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4842
{
4843
    gen_op_load_gpr_T0(rA(ctx->opcode));
4844
    gen_op_load_dcr();
4845
    gen_op_store_T0_gpr(rD(ctx->opcode));
4846
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4847
}
4848

    
4849
/* mtdcrux (PPC 460) : user-mode access to DCR */
4850
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4851
{
4852
    gen_op_load_gpr_T0(rA(ctx->opcode));
4853
    gen_op_load_gpr_T1(rS(ctx->opcode));
4854
    gen_op_store_dcr();
4855
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4856
}
4857

    
4858
/* dccci */
4859
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4860
{
4861
#if defined(CONFIG_USER_ONLY)
4862
    GEN_EXCP_PRIVOPC(ctx);
4863
#else
4864
    if (unlikely(!ctx->supervisor)) {
4865
        GEN_EXCP_PRIVOPC(ctx);
4866
        return;
4867
    }
4868
    /* interpreted as no-op */
4869
#endif
4870
}
4871

    
4872
/* dcread */
4873
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4874
{
4875
#if defined(CONFIG_USER_ONLY)
4876
    GEN_EXCP_PRIVOPC(ctx);
4877
#else
4878
    if (unlikely(!ctx->supervisor)) {
4879
        GEN_EXCP_PRIVOPC(ctx);
4880
        return;
4881
    }
4882
    gen_addr_reg_index(ctx);
4883
    op_ldst(lwz);
4884
    gen_op_store_T0_gpr(rD(ctx->opcode));
4885
#endif
4886
}
4887

    
4888
/* icbt */
4889
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4890
{
4891
    /* interpreted as no-op */
4892
    /* XXX: specification say this is treated as a load by the MMU
4893
     *      but does not generate any exception
4894
     */
4895
}
4896

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

    
4911
/* icread */
4912
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4913
{
4914
#if defined(CONFIG_USER_ONLY)
4915
    GEN_EXCP_PRIVOPC(ctx);
4916
#else
4917
    if (unlikely(!ctx->supervisor)) {
4918
        GEN_EXCP_PRIVOPC(ctx);
4919
        return;
4920
    }
4921
    /* interpreted as no-op */
4922
#endif
4923
}
4924

    
4925
/* rfci (supervisor only) */
4926
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4927
{
4928
#if defined(CONFIG_USER_ONLY)
4929
    GEN_EXCP_PRIVOPC(ctx);
4930
#else
4931
    if (unlikely(!ctx->supervisor)) {
4932
        GEN_EXCP_PRIVOPC(ctx);
4933
        return;
4934
    }
4935
    /* Restore CPU state */
4936
    gen_op_40x_rfci();
4937
    GEN_SYNC(ctx);
4938
#endif
4939
}
4940

    
4941
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4942
{
4943
#if defined(CONFIG_USER_ONLY)
4944
    GEN_EXCP_PRIVOPC(ctx);
4945
#else
4946
    if (unlikely(!ctx->supervisor)) {
4947
        GEN_EXCP_PRIVOPC(ctx);
4948
        return;
4949
    }
4950
    /* Restore CPU state */
4951
    gen_op_rfci();
4952
    GEN_SYNC(ctx);
4953
#endif
4954
}
4955

    
4956
/* BookE specific */
4957
/* XXX: not implemented on 440 ? */
4958
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
4959
{
4960
#if defined(CONFIG_USER_ONLY)
4961
    GEN_EXCP_PRIVOPC(ctx);
4962
#else
4963
    if (unlikely(!ctx->supervisor)) {
4964
        GEN_EXCP_PRIVOPC(ctx);
4965
        return;
4966
    }
4967
    /* Restore CPU state */
4968
    gen_op_rfdi();
4969
    GEN_SYNC(ctx);
4970
#endif
4971
}
4972

    
4973
/* XXX: not implemented on 440 ? */
4974
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
4975
{
4976
#if defined(CONFIG_USER_ONLY)
4977
    GEN_EXCP_PRIVOPC(ctx);
4978
#else
4979
    if (unlikely(!ctx->supervisor)) {
4980
        GEN_EXCP_PRIVOPC(ctx);
4981
        return;
4982
    }
4983
    /* Restore CPU state */
4984
    gen_op_rfmci();
4985
    GEN_SYNC(ctx);
4986
#endif
4987
}
4988

    
4989
/* TLB management - PowerPC 405 implementation */
4990
/* tlbre */
4991
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4992
{
4993
#if defined(CONFIG_USER_ONLY)
4994
    GEN_EXCP_PRIVOPC(ctx);
4995
#else
4996
    if (unlikely(!ctx->supervisor)) {
4997
        GEN_EXCP_PRIVOPC(ctx);
4998
        return;
4999
    }
5000
    switch (rB(ctx->opcode)) {
5001
    case 0:
5002
        gen_op_load_gpr_T0(rA(ctx->opcode));
5003
        gen_op_4xx_tlbre_hi();
5004
        gen_op_store_T0_gpr(rD(ctx->opcode));
5005
        break;
5006
    case 1:
5007
        gen_op_load_gpr_T0(rA(ctx->opcode));
5008
        gen_op_4xx_tlbre_lo();
5009
        gen_op_store_T0_gpr(rD(ctx->opcode));
5010
        break;
5011
    default:
5012
        GEN_EXCP_INVAL(ctx);
5013
        break;
5014
    }
5015
#endif
5016
}
5017

    
5018
/* tlbsx - tlbsx. */
5019
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5020
{
5021
#if defined(CONFIG_USER_ONLY)
5022
    GEN_EXCP_PRIVOPC(ctx);
5023
#else
5024
    if (unlikely(!ctx->supervisor)) {
5025
        GEN_EXCP_PRIVOPC(ctx);
5026
        return;
5027
    }
5028
    gen_addr_reg_index(ctx);
5029
    gen_op_4xx_tlbsx();
5030
    if (Rc(ctx->opcode))
5031
        gen_op_4xx_tlbsx_check();
5032
    gen_op_store_T0_gpr(rD(ctx->opcode));
5033
#endif
5034
}
5035

    
5036
/* tlbwe */
5037
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5038
{
5039
#if defined(CONFIG_USER_ONLY)
5040
    GEN_EXCP_PRIVOPC(ctx);
5041
#else
5042
    if (unlikely(!ctx->supervisor)) {
5043
        GEN_EXCP_PRIVOPC(ctx);
5044
        return;
5045
    }
5046
    switch (rB(ctx->opcode)) {
5047
    case 0:
5048
        gen_op_load_gpr_T0(rA(ctx->opcode));
5049
        gen_op_load_gpr_T1(rS(ctx->opcode));
5050
        gen_op_4xx_tlbwe_hi();
5051
        break;
5052
    case 1:
5053
        gen_op_load_gpr_T0(rA(ctx->opcode));
5054
        gen_op_load_gpr_T1(rS(ctx->opcode));
5055
        gen_op_4xx_tlbwe_lo();
5056
        break;
5057
    default:
5058
        GEN_EXCP_INVAL(ctx);
5059
        break;
5060
    }
5061
#endif
5062
}
5063

    
5064
/* TLB management - PowerPC 440 implementation */
5065
/* tlbre */
5066
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5067
{
5068
#if defined(CONFIG_USER_ONLY)
5069
    GEN_EXCP_PRIVOPC(ctx);
5070
#else
5071
    if (unlikely(!ctx->supervisor)) {
5072
        GEN_EXCP_PRIVOPC(ctx);
5073
        return;
5074
    }
5075
    switch (rB(ctx->opcode)) {
5076
    case 0:
5077
    case 1:
5078
    case 2:
5079
        gen_op_load_gpr_T0(rA(ctx->opcode));
5080
        gen_op_440_tlbre(rB(ctx->opcode));
5081
        gen_op_store_T0_gpr(rD(ctx->opcode));
5082
        break;
5083
    default:
5084
        GEN_EXCP_INVAL(ctx);
5085
        break;
5086
    }
5087
#endif
5088
}
5089

    
5090
/* tlbsx - tlbsx. */
5091
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5092
{
5093
#if defined(CONFIG_USER_ONLY)
5094
    GEN_EXCP_PRIVOPC(ctx);
5095
#else
5096
    if (unlikely(!ctx->supervisor)) {
5097
        GEN_EXCP_PRIVOPC(ctx);
5098
        return;
5099
    }
5100
    gen_addr_reg_index(ctx);
5101
    gen_op_440_tlbsx();
5102
    if (Rc(ctx->opcode))
5103
        gen_op_4xx_tlbsx_check();
5104
    gen_op_store_T0_gpr(rD(ctx->opcode));
5105
#endif
5106
}
5107

    
5108
/* tlbwe */
5109
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5110
{
5111
#if defined(CONFIG_USER_ONLY)
5112
    GEN_EXCP_PRIVOPC(ctx);
5113
#else
5114
    if (unlikely(!ctx->supervisor)) {
5115
        GEN_EXCP_PRIVOPC(ctx);
5116
        return;
5117
    }
5118
    switch (rB(ctx->opcode)) {
5119
    case 0:
5120
    case 1:
5121
    case 2:
5122
        gen_op_load_gpr_T0(rA(ctx->opcode));
5123
        gen_op_load_gpr_T1(rS(ctx->opcode));
5124
        gen_op_440_tlbwe(rB(ctx->opcode));
5125
        break;
5126
    default:
5127
        GEN_EXCP_INVAL(ctx);
5128
        break;
5129
    }
5130
#endif
5131
}
5132

    
5133
/* wrtee */
5134
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
5135
{
5136
#if defined(CONFIG_USER_ONLY)
5137
    GEN_EXCP_PRIVOPC(ctx);
5138
#else
5139
    if (unlikely(!ctx->supervisor)) {
5140
        GEN_EXCP_PRIVOPC(ctx);
5141
        return;
5142
    }
5143
    gen_op_load_gpr_T0(rD(ctx->opcode));
5144
    gen_op_wrte();
5145
    /* Stop translation to have a chance to raise an exception
5146
     * if we just set msr_ee to 1
5147
     */
5148
    GEN_STOP(ctx);
5149
#endif
5150
}
5151

    
5152
/* wrteei */
5153
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
5154
{
5155
#if defined(CONFIG_USER_ONLY)
5156
    GEN_EXCP_PRIVOPC(ctx);
5157
#else
5158
    if (unlikely(!ctx->supervisor)) {
5159
        GEN_EXCP_PRIVOPC(ctx);
5160
        return;
5161
    }
5162
    gen_op_set_T0(ctx->opcode & 0x00010000);
5163
    gen_op_wrte();
5164
    /* Stop translation to have a chance to raise an exception
5165
     * if we just set msr_ee to 1
5166
     */
5167
    GEN_STOP(ctx);
5168
#endif
5169
}
5170

    
5171
/* PowerPC 440 specific instructions */
5172
/* dlmzb */
5173
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5174
{
5175
    gen_op_load_gpr_T0(rS(ctx->opcode));
5176
    gen_op_load_gpr_T1(rB(ctx->opcode));
5177
    gen_op_440_dlmzb();
5178
    gen_op_store_T0_gpr(rA(ctx->opcode));
5179
    gen_op_store_xer_bc();
5180
    if (Rc(ctx->opcode)) {
5181
        gen_op_440_dlmzb_update_Rc();
5182
        gen_op_store_T0_crf(0);
5183
    }
5184
}
5185

    
5186
/* mbar replaces eieio on 440 */
5187
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5188
{
5189
    /* interpreted as no-op */
5190
}
5191

    
5192
/* msync replaces sync on 440 */
5193
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5194
{
5195
    /* interpreted as no-op */
5196
}
5197

    
5198
/* icbt */
5199
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5200
{
5201
    /* interpreted as no-op */
5202
    /* XXX: specification say this is treated as a load by the MMU
5203
     *      but does not generate any exception
5204
     */
5205
}
5206

    
5207
/***                      Altivec vector extension                         ***/
5208
/* Altivec registers moves */
5209
GEN32(gen_op_load_avr_A0, gen_op_load_avr_A0_avr);
5210
GEN32(gen_op_load_avr_A1, gen_op_load_avr_A1_avr);
5211
GEN32(gen_op_load_avr_A2, gen_op_load_avr_A2_avr);
5212

    
5213
GEN32(gen_op_store_A0_avr, gen_op_store_A0_avr_avr);
5214
GEN32(gen_op_store_A1_avr, gen_op_store_A1_avr_avr);
5215
#if 0 // unused
5216
GEN32(gen_op_store_A2_avr, gen_op_store_A2_avr_avr);
5217
#endif
5218

    
5219
#define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5220
#define OP_VR_LD_TABLE(name)                                                  \
5221
static GenOpFunc *gen_op_vr_l##name[NB_MEM_FUNCS] = {                         \
5222
    GEN_MEM_FUNCS(vr_l##name),                                                \
5223
};
5224
#define OP_VR_ST_TABLE(name)                                                  \
5225
static GenOpFunc *gen_op_vr_st##name[NB_MEM_FUNCS] = {                        \
5226
    GEN_MEM_FUNCS(vr_st##name),                                               \
5227
};
5228

    
5229
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5230
GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
5231
{                                                                             \
5232
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5233
        GEN_EXCP_NO_VR(ctx);                                                  \
5234
        return;                                                               \
5235
    }                                                                         \
5236
    gen_addr_reg_index(ctx);                                                  \
5237
    op_vr_ldst(vr_l##name);                                                   \
5238
    gen_op_store_A0_avr(rD(ctx->opcode));                                     \
5239
}
5240

    
5241
#define GEN_VR_STX(name, opc2, opc3)                                          \
5242
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
5243
{                                                                             \
5244
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5245
        GEN_EXCP_NO_VR(ctx);                                                  \
5246
        return;                                                               \
5247
    }                                                                         \
5248
    gen_addr_reg_index(ctx);                                                  \
5249
    gen_op_load_avr_A0(rS(ctx->opcode));                                      \
5250
    op_vr_ldst(vr_st##name);                                                  \
5251
}
5252

    
5253
OP_VR_LD_TABLE(vx);
5254
GEN_VR_LDX(vx, 0x07, 0x03);
5255
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
5256
#define gen_op_vr_lvxl gen_op_vr_lvx
5257
GEN_VR_LDX(vxl, 0x07, 0x0B);
5258

    
5259
OP_VR_ST_TABLE(vx);
5260
GEN_VR_STX(vx, 0x07, 0x07);
5261
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
5262
#define gen_op_vr_stvxl gen_op_vr_stvx
5263
GEN_VR_STX(vxl, 0x07, 0x0F);
5264

    
5265
/***                           SPE extension                               ***/
5266
/* Register moves */
5267
#if !defined(TARGET_PPC64)
5268

    
5269
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
5270
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
5271
#if 0 // unused
5272
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
5273
#endif
5274

    
5275
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
5276
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
5277
#if 0 // unused
5278
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
5279
#endif
5280

    
5281
#else /* !defined(TARGET_PPC64) */
5282

    
5283
/* No specific load/store functions: GPRs are already 64 bits */
5284
#define gen_op_load_gpr64_T0 gen_op_load_gpr_T0
5285
#define gen_op_load_gpr64_T1 gen_op_load_gpr_T1
5286
#if 0 // unused
5287
#define gen_op_load_gpr64_T2 gen_op_load_gpr_T2
5288
#endif
5289

    
5290
#define gen_op_store_T0_gpr64 gen_op_store_T0_gpr
5291
#define gen_op_store_T1_gpr64 gen_op_store_T1_gpr
5292
#if 0 // unused
5293
#define gen_op_store_T2_gpr64 gen_op_store_T2_gpr
5294
#endif
5295

    
5296
#endif /* !defined(TARGET_PPC64) */
5297

    
5298
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5299
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5300
{                                                                             \
5301
    if (Rc(ctx->opcode))                                                      \
5302
        gen_##name1(ctx);                                                     \
5303
    else                                                                      \
5304
        gen_##name0(ctx);                                                     \
5305
}
5306

    
5307
/* Handler for undefined SPE opcodes */
5308
static always_inline void gen_speundef (DisasContext *ctx)
5309
{
5310
    GEN_EXCP_INVAL(ctx);
5311
}
5312

    
5313
/* SPE load and stores */
5314
static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5315
{
5316
    target_long simm = rB(ctx->opcode);
5317

    
5318
    if (rA(ctx->opcode) == 0) {
5319
        gen_set_T0(simm << sh);
5320
    } else {
5321
        gen_op_load_gpr_T0(rA(ctx->opcode));
5322
        if (likely(simm != 0))
5323
            gen_op_addi(simm << sh);
5324
    }
5325
}
5326

    
5327
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5328
#define OP_SPE_LD_TABLE(name)                                                 \
5329
static GenOpFunc *gen_op_spe_l##name[NB_MEM_FUNCS] = {                        \
5330
    GEN_MEM_FUNCS(spe_l##name),                                               \
5331
};
5332
#define OP_SPE_ST_TABLE(name)                                                 \
5333
static GenOpFunc *gen_op_spe_st##name[NB_MEM_FUNCS] = {                       \
5334
    GEN_MEM_FUNCS(spe_st##name),                                              \
5335
};
5336

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

    
5349
#define GEN_SPE_LDX(name)                                                     \
5350
static always_inline void gen_evl##name##x (DisasContext *ctx)                \
5351
{                                                                             \
5352
    if (unlikely(!ctx->spe_enabled)) {                                        \
5353
        GEN_EXCP_NO_AP(ctx);                                                  \
5354
        return;                                                               \
5355
    }                                                                         \
5356
    gen_addr_reg_index(ctx);                                                  \
5357
    op_spe_ldst(spe_l##name);                                                 \
5358
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5359
}
5360

    
5361
#define GEN_SPEOP_LD(name, sh)                                                \
5362
OP_SPE_LD_TABLE(name);                                                        \
5363
GEN_SPE_LD(name, sh);                                                         \
5364
GEN_SPE_LDX(name)
5365

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

    
5378
#define GEN_SPE_STX(name)                                                     \
5379
static always_inline void gen_evst##name##x (DisasContext *ctx)               \
5380
{                                                                             \
5381
    if (unlikely(!ctx->spe_enabled)) {                                        \
5382
        GEN_EXCP_NO_AP(ctx);                                                  \
5383
        return;                                                               \
5384
    }                                                                         \
5385
    gen_addr_reg_index(ctx);                                                  \
5386
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5387
    op_spe_ldst(spe_st##name);                                                \
5388
}
5389

    
5390
#define GEN_SPEOP_ST(name, sh)                                                \
5391
OP_SPE_ST_TABLE(name);                                                        \
5392
GEN_SPE_ST(name, sh);                                                         \
5393
GEN_SPE_STX(name)
5394

    
5395
#define GEN_SPEOP_LDST(name, sh)                                              \
5396
GEN_SPEOP_LD(name, sh);                                                       \
5397
GEN_SPEOP_ST(name, sh)
5398

    
5399
/* SPE arithmetic and logic */
5400
#define GEN_SPEOP_ARITH2(name)                                                \
5401
static always_inline void gen_##name (DisasContext *ctx)                      \
5402
{                                                                             \
5403
    if (unlikely(!ctx->spe_enabled)) {                                        \
5404
        GEN_EXCP_NO_AP(ctx);                                                  \
5405
        return;                                                               \
5406
    }                                                                         \
5407
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5408
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5409
    gen_op_##name();                                                          \
5410
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5411
}
5412

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

    
5425
#define GEN_SPEOP_COMP(name)                                                  \
5426
static always_inline void gen_##name (DisasContext *ctx)                      \
5427
{                                                                             \
5428
    if (unlikely(!ctx->spe_enabled)) {                                        \
5429
        GEN_EXCP_NO_AP(ctx);                                                  \
5430
        return;                                                               \
5431
    }                                                                         \
5432
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5433
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5434
    gen_op_##name();                                                          \
5435
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5436
}
5437

    
5438
/* Logical */
5439
GEN_SPEOP_ARITH2(evand);
5440
GEN_SPEOP_ARITH2(evandc);
5441
GEN_SPEOP_ARITH2(evxor);
5442
GEN_SPEOP_ARITH2(evor);
5443
GEN_SPEOP_ARITH2(evnor);
5444
GEN_SPEOP_ARITH2(eveqv);
5445
GEN_SPEOP_ARITH2(evorc);
5446
GEN_SPEOP_ARITH2(evnand);
5447
GEN_SPEOP_ARITH2(evsrwu);
5448
GEN_SPEOP_ARITH2(evsrws);
5449
GEN_SPEOP_ARITH2(evslw);
5450
GEN_SPEOP_ARITH2(evrlw);
5451
GEN_SPEOP_ARITH2(evmergehi);
5452
GEN_SPEOP_ARITH2(evmergelo);
5453
GEN_SPEOP_ARITH2(evmergehilo);
5454
GEN_SPEOP_ARITH2(evmergelohi);
5455

    
5456
/* Arithmetic */
5457
GEN_SPEOP_ARITH2(evaddw);
5458
GEN_SPEOP_ARITH2(evsubfw);
5459
GEN_SPEOP_ARITH1(evabs);
5460
GEN_SPEOP_ARITH1(evneg);
5461
GEN_SPEOP_ARITH1(evextsb);
5462
GEN_SPEOP_ARITH1(evextsh);
5463
GEN_SPEOP_ARITH1(evrndw);
5464
GEN_SPEOP_ARITH1(evcntlzw);
5465
GEN_SPEOP_ARITH1(evcntlsw);
5466
static always_inline void gen_brinc (DisasContext *ctx)
5467
{
5468
    /* Note: brinc is usable even if SPE is disabled */
5469
    gen_op_load_gpr_T0(rA(ctx->opcode));
5470
    gen_op_load_gpr_T1(rB(ctx->opcode));
5471
    gen_op_brinc();
5472
    gen_op_store_T0_gpr(rD(ctx->opcode));
5473
}
5474

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

    
5488
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5489
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5490
{                                                                             \
5491
    if (unlikely(!ctx->spe_enabled)) {                                        \
5492
        GEN_EXCP_NO_AP(ctx);                                                  \
5493
        return;                                                               \
5494
    }                                                                         \
5495
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5496
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5497
    gen_op_##name();                                                          \
5498
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5499
}
5500

    
5501
GEN_SPEOP_ARITH_IMM2(evaddw);
5502
#define gen_evaddiw gen_evaddwi
5503
GEN_SPEOP_ARITH_IMM2(evsubfw);
5504
#define gen_evsubifw gen_evsubfwi
5505
GEN_SPEOP_LOGIC_IMM2(evslw);
5506
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5507
#define gen_evsrwis gen_evsrwsi
5508
GEN_SPEOP_LOGIC_IMM2(evsrws);
5509
#define gen_evsrwiu gen_evsrwui
5510
GEN_SPEOP_LOGIC_IMM2(evrlw);
5511

    
5512
static always_inline void gen_evsplati (DisasContext *ctx)
5513
{
5514
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5515

    
5516
    gen_op_splatwi_T0_64(imm);
5517
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5518
}
5519

    
5520
static always_inline void gen_evsplatfi (DisasContext *ctx)
5521
{
5522
    uint32_t imm = rA(ctx->opcode) << 27;
5523

    
5524
    gen_op_splatwi_T0_64(imm);
5525
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5526
}
5527

    
5528
/* Comparison */
5529
GEN_SPEOP_COMP(evcmpgtu);
5530
GEN_SPEOP_COMP(evcmpgts);
5531
GEN_SPEOP_COMP(evcmpltu);
5532
GEN_SPEOP_COMP(evcmplts);
5533
GEN_SPEOP_COMP(evcmpeq);
5534

    
5535
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5536
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5537
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5538
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5539
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5540
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5541
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5542
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5543
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5544
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5545
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5546
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5547
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5548
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5549
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5550
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5551
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5552
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5553
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5554
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5555
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5556
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5557
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5558
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5559
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5560

    
5561
static always_inline void gen_evsel (DisasContext *ctx)
5562
{
5563
    if (unlikely(!ctx->spe_enabled)) {
5564
        GEN_EXCP_NO_AP(ctx);
5565
        return;
5566
    }
5567
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5568
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5569
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5570
    gen_op_evsel();
5571
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5572
}
5573

    
5574
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5575
{
5576
    gen_evsel(ctx);
5577
}
5578
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5579
{
5580
    gen_evsel(ctx);
5581
}
5582
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5583
{
5584
    gen_evsel(ctx);
5585
}
5586
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5587
{
5588
    gen_evsel(ctx);
5589
}
5590

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

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

    
5697
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5698
static always_inline void gen_op_spe_l##name##_##suffix (void)                \
5699
{                                                                             \
5700
    gen_op_##op##_##suffix();                                                 \
5701
    gen_op_splatw_T1_64();                                                    \
5702
}
5703

    
5704
#define GEN_OP_SPE_LHE(suffix)                                                \
5705
static always_inline void gen_op_spe_lhe_##suffix (void)                      \
5706
{                                                                             \
5707
    gen_op_spe_lh_##suffix();                                                 \
5708
    gen_op_sli16_T1_64();                                                     \
5709
}
5710

    
5711
#define GEN_OP_SPE_LHX(suffix)                                                \
5712
static always_inline void gen_op_spe_lhx_##suffix (void)                      \
5713
{                                                                             \
5714
    gen_op_spe_lh_##suffix();                                                 \
5715
    gen_op_extsh_T1_64();                                                     \
5716
}
5717

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

    
5811
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5812
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5813
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5814
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5815
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5816
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5817
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5818
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5819
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5820
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5821
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5822
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5823
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5824
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5825
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5826
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5827
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5828
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5829

    
5830
/* Multiply and add - TODO */
5831
#if 0
5832
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5833
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5834
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5835
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5836
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5837
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5838
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5839
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5840
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5841
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5842
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5843
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5844

5845
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5846
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5847
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5848
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5849
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5850
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5851
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5852
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5853
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5854
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5855
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5856
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5857
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5858
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5859

5860
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5861
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5862
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5863
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5864
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5865
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5866

5867
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5868
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5869
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5870
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5871
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5872
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5873
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5874
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5875
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5876
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5877
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5878
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5879

5880
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5881
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5882
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5883
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5884
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5885

5886
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5887
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5888
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5889
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5890
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5891
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5892
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5893
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5894
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5895
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5896
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5897
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5898

5899
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5900
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5901
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5902
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5903
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5904
#endif
5905

    
5906
/***                      SPE floating-point extension                     ***/
5907
#define GEN_SPEFPUOP_CONV(name)                                               \
5908
static always_inline void gen_##name (DisasContext *ctx)                      \
5909
{                                                                             \
5910
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5911
    gen_op_##name();                                                          \
5912
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5913
}
5914

    
5915
/* Single precision floating-point vectors operations */
5916
/* Arithmetic */
5917
GEN_SPEOP_ARITH2(evfsadd);
5918
GEN_SPEOP_ARITH2(evfssub);
5919
GEN_SPEOP_ARITH2(evfsmul);
5920
GEN_SPEOP_ARITH2(evfsdiv);
5921
GEN_SPEOP_ARITH1(evfsabs);
5922
GEN_SPEOP_ARITH1(evfsnabs);
5923
GEN_SPEOP_ARITH1(evfsneg);
5924
/* Conversion */
5925
GEN_SPEFPUOP_CONV(evfscfui);
5926
GEN_SPEFPUOP_CONV(evfscfsi);
5927
GEN_SPEFPUOP_CONV(evfscfuf);
5928
GEN_SPEFPUOP_CONV(evfscfsf);
5929
GEN_SPEFPUOP_CONV(evfsctui);
5930
GEN_SPEFPUOP_CONV(evfsctsi);
5931
GEN_SPEFPUOP_CONV(evfsctuf);
5932
GEN_SPEFPUOP_CONV(evfsctsf);
5933
GEN_SPEFPUOP_CONV(evfsctuiz);
5934
GEN_SPEFPUOP_CONV(evfsctsiz);
5935
/* Comparison */
5936
GEN_SPEOP_COMP(evfscmpgt);
5937
GEN_SPEOP_COMP(evfscmplt);
5938
GEN_SPEOP_COMP(evfscmpeq);
5939
GEN_SPEOP_COMP(evfststgt);
5940
GEN_SPEOP_COMP(evfststlt);
5941
GEN_SPEOP_COMP(evfststeq);
5942

    
5943
/* Opcodes definitions */
5944
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5945
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5946
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5947
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5948
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5949
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5950
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5951
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5952
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5953
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5954
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5955
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5956
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5957
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5958

    
5959
/* Single precision floating-point operations */
5960
/* Arithmetic */
5961
GEN_SPEOP_ARITH2(efsadd);
5962
GEN_SPEOP_ARITH2(efssub);
5963
GEN_SPEOP_ARITH2(efsmul);
5964
GEN_SPEOP_ARITH2(efsdiv);
5965
GEN_SPEOP_ARITH1(efsabs);
5966
GEN_SPEOP_ARITH1(efsnabs);
5967
GEN_SPEOP_ARITH1(efsneg);
5968
/* Conversion */
5969
GEN_SPEFPUOP_CONV(efscfui);
5970
GEN_SPEFPUOP_CONV(efscfsi);
5971
GEN_SPEFPUOP_CONV(efscfuf);
5972
GEN_SPEFPUOP_CONV(efscfsf);
5973
GEN_SPEFPUOP_CONV(efsctui);
5974
GEN_SPEFPUOP_CONV(efsctsi);
5975
GEN_SPEFPUOP_CONV(efsctuf);
5976
GEN_SPEFPUOP_CONV(efsctsf);
5977
GEN_SPEFPUOP_CONV(efsctuiz);
5978
GEN_SPEFPUOP_CONV(efsctsiz);
5979
GEN_SPEFPUOP_CONV(efscfd);
5980
/* Comparison */
5981
GEN_SPEOP_COMP(efscmpgt);
5982
GEN_SPEOP_COMP(efscmplt);
5983
GEN_SPEOP_COMP(efscmpeq);
5984
GEN_SPEOP_COMP(efststgt);
5985
GEN_SPEOP_COMP(efststlt);
5986
GEN_SPEOP_COMP(efststeq);
5987

    
5988
/* Opcodes definitions */
5989
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
5990
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5991
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5992
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5993
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5994
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5995
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5996
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5997
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5998
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5999
GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
6000
GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPEFPU); //
6001
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
6002
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
6003

    
6004
/* Double precision floating-point operations */
6005
/* Arithmetic */
6006
GEN_SPEOP_ARITH2(efdadd);
6007
GEN_SPEOP_ARITH2(efdsub);
6008
GEN_SPEOP_ARITH2(efdmul);
6009
GEN_SPEOP_ARITH2(efddiv);
6010
GEN_SPEOP_ARITH1(efdabs);
6011
GEN_SPEOP_ARITH1(efdnabs);
6012
GEN_SPEOP_ARITH1(efdneg);
6013
/* Conversion */
6014

    
6015
GEN_SPEFPUOP_CONV(efdcfui);
6016
GEN_SPEFPUOP_CONV(efdcfsi);
6017
GEN_SPEFPUOP_CONV(efdcfuf);
6018
GEN_SPEFPUOP_CONV(efdcfsf);
6019
GEN_SPEFPUOP_CONV(efdctui);
6020
GEN_SPEFPUOP_CONV(efdctsi);
6021
GEN_SPEFPUOP_CONV(efdctuf);
6022
GEN_SPEFPUOP_CONV(efdctsf);
6023
GEN_SPEFPUOP_CONV(efdctuiz);
6024
GEN_SPEFPUOP_CONV(efdctsiz);
6025
GEN_SPEFPUOP_CONV(efdcfs);
6026
GEN_SPEFPUOP_CONV(efdcfuid);
6027
GEN_SPEFPUOP_CONV(efdcfsid);
6028
GEN_SPEFPUOP_CONV(efdctuidz);
6029
GEN_SPEFPUOP_CONV(efdctsidz);
6030
/* Comparison */
6031
GEN_SPEOP_COMP(efdcmpgt);
6032
GEN_SPEOP_COMP(efdcmplt);
6033
GEN_SPEOP_COMP(efdcmpeq);
6034
GEN_SPEOP_COMP(efdtstgt);
6035
GEN_SPEOP_COMP(efdtstlt);
6036
GEN_SPEOP_COMP(efdtsteq);
6037

    
6038
/* Opcodes definitions */
6039
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
6040
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
6041
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
6042
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
6043
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
6044
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
6045
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
6046
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
6047
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
6048
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
6049
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
6050
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
6051
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
6052
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
6053
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
6054
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6055

    
6056
/* End opcode list */
6057
GEN_OPCODE_MARK(end);
6058

    
6059
#include "translate_init.c"
6060
#include "helper_regs.h"
6061

    
6062
/*****************************************************************************/
6063
/* Misc PowerPC helpers */
6064
void cpu_dump_state (CPUState *env, FILE *f,
6065
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6066
                     int flags)
6067
{
6068
#define RGPL  4
6069
#define RFPL  4
6070

    
6071
    int i;
6072

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

    
6123
#undef RGPL
6124
#undef RFPL
6125
}
6126

    
6127
void cpu_dump_statistics (CPUState *env, FILE*f,
6128
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6129
                          int flags)
6130
{
6131
#if defined(DO_PPC_STATISTICS)
6132
    opc_handler_t **t1, **t2, **t3, *handler;
6133
    int op1, op2, op3;
6134

    
6135
    t1 = env->opcodes;
6136
    for (op1 = 0; op1 < 64; op1++) {
6137
        handler = t1[op1];
6138
        if (is_indirect_opcode(handler)) {
6139
            t2 = ind_table(handler);
6140
            for (op2 = 0; op2 < 32; op2++) {
6141
                handler = t2[op2];
6142
                if (is_indirect_opcode(handler)) {
6143
                    t3 = ind_table(handler);
6144
                    for (op3 = 0; op3 < 32; op3++) {
6145
                        handler = t3[op3];
6146
                        if (handler->count == 0)
6147
                            continue;
6148
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6149
                                    "%016llx %lld\n",
6150
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6151
                                    handler->oname,
6152
                                    handler->count, handler->count);
6153
                    }
6154
                } else {
6155
                    if (handler->count == 0)
6156
                        continue;
6157
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6158
                                "%016llx %lld\n",
6159
                                op1, op2, op1, op2, handler->oname,
6160
                                handler->count, handler->count);
6161
                }
6162
            }
6163
        } else {
6164
            if (handler->count == 0)
6165
                continue;
6166
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6167
                        op1, op1, handler->oname,
6168
                        handler->count, handler->count);
6169
        }
6170
    }
6171
#endif
6172
}
6173

    
6174
/*****************************************************************************/
6175
static always_inline void gen_intermediate_code_internal (CPUState *env,
6176
                                                          TranslationBlock *tb,
6177
                                                          int search_pc)
6178
{
6179
    DisasContext ctx, *ctxp = &ctx;
6180
    opc_handler_t **table, *handler;
6181
    target_ulong pc_start;
6182
    uint16_t *gen_opc_end;
6183
    int supervisor, little_endian;
6184
    int j, lj = -1;
6185
    int num_insns;
6186
    int max_insns;
6187

    
6188
    pc_start = tb->pc;
6189
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6190
#if defined(OPTIMIZE_FPRF_UPDATE)
6191
    gen_fprf_ptr = gen_fprf_buf;
6192
#endif
6193
    ctx.nip = pc_start;
6194
    ctx.tb = tb;
6195
    ctx.exception = POWERPC_EXCP_NONE;
6196
    ctx.spr_cb = env->spr_cb;
6197
    supervisor = env->mmu_idx;
6198
#if !defined(CONFIG_USER_ONLY)
6199
    ctx.supervisor = supervisor;
6200
#endif
6201
    little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
6202
#if defined(TARGET_PPC64)
6203
    ctx.sf_mode = msr_sf;
6204
    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
6205
#else
6206
    ctx.mem_idx = (supervisor << 1) | little_endian;
6207
#endif
6208
    ctx.dcache_line_size = env->dcache_line_size;
6209
    ctx.fpu_enabled = msr_fp;
6210
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
6211
        ctx.spe_enabled = msr_spe;
6212
    else
6213
        ctx.spe_enabled = 0;
6214
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
6215
        ctx.altivec_enabled = msr_vr;
6216
    else
6217
        ctx.altivec_enabled = 0;
6218
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6219
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
6220
    else
6221
        ctx.singlestep_enabled = 0;
6222
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
6223
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
6224
    if (unlikely(env->singlestep_enabled))
6225
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
6226
#if defined (DO_SINGLE_STEP) && 0
6227
    /* Single step trace mode */
6228
    msr_se = 1;
6229
#endif
6230
    num_insns = 0;
6231
    max_insns = tb->cflags & CF_COUNT_MASK;
6232
    if (max_insns == 0)
6233
        max_insns = CF_COUNT_MASK;
6234

    
6235
    gen_icount_start();
6236
    /* Set env in case of segfault during code fetch */
6237
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
6238
        if (unlikely(env->nb_breakpoints > 0)) {
6239
            for (j = 0; j < env->nb_breakpoints; j++) {
6240
                if (env->breakpoints[j] == ctx.nip) {
6241
                    gen_update_nip(&ctx, ctx.nip);
6242
                    gen_op_debug();
6243
                    break;
6244
                }
6245
            }
6246
        }
6247
        if (unlikely(search_pc)) {
6248
            j = gen_opc_ptr - gen_opc_buf;
6249
            if (lj < j) {
6250
                lj++;
6251
                while (lj < j)
6252
                    gen_opc_instr_start[lj++] = 0;
6253
                gen_opc_pc[lj] = ctx.nip;
6254
                gen_opc_instr_start[lj] = 1;
6255
                gen_opc_icount[lj] = num_insns;
6256
            }
6257
        }
6258
#if defined PPC_DEBUG_DISAS
6259
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6260
            fprintf(logfile, "----------------\n");
6261
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6262
                    ctx.nip, supervisor, (int)msr_ir);
6263
        }
6264
#endif
6265
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
6266
            gen_io_start();
6267
        if (unlikely(little_endian)) {
6268
            ctx.opcode = bswap32(ldl_code(ctx.nip));
6269
        } else {
6270
            ctx.opcode = ldl_code(ctx.nip);
6271
        }
6272
#if defined PPC_DEBUG_DISAS
6273
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6274
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6275
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6276
                    opc3(ctx.opcode), little_endian ? "little" : "big");
6277
        }
6278
#endif
6279
        ctx.nip += 4;
6280
        table = env->opcodes;
6281
        num_insns++;
6282
        handler = table[opc1(ctx.opcode)];
6283
        if (is_indirect_opcode(handler)) {
6284
            table = ind_table(handler);
6285
            handler = table[opc2(ctx.opcode)];
6286
            if (is_indirect_opcode(handler)) {
6287
                table = ind_table(handler);
6288
                handler = table[opc3(ctx.opcode)];
6289
            }
6290
        }
6291
        /* Is opcode *REALLY* valid ? */
6292
        if (unlikely(handler->handler == &gen_invalid)) {
6293
            if (loglevel != 0) {
6294
                fprintf(logfile, "invalid/unsupported opcode: "
6295
                        "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6296
                        opc1(ctx.opcode), opc2(ctx.opcode),
6297
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6298
            } else {
6299
                printf("invalid/unsupported opcode: "
6300
                       "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6301
                       opc1(ctx.opcode), opc2(ctx.opcode),
6302
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6303
            }
6304
        } else {
6305
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6306
                if (loglevel != 0) {
6307
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6308
                            "%02x - %02x - %02x (%08x) " ADDRX "\n",
6309
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6310
                            opc2(ctx.opcode), opc3(ctx.opcode),
6311
                            ctx.opcode, ctx.nip - 4);
6312
                } else {
6313
                    printf("invalid bits: %08x for opcode: "
6314
                           "%02x - %02x - %02x (%08x) " ADDRX "\n",
6315
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6316
                           opc2(ctx.opcode), opc3(ctx.opcode),
6317
                           ctx.opcode, ctx.nip - 4);
6318
                }
6319
                GEN_EXCP_INVAL(ctxp);
6320
                break;
6321
            }
6322
        }
6323
        (*(handler->handler))(&ctx);
6324
#if defined(DO_PPC_STATISTICS)
6325
        handler->count++;
6326
#endif
6327
        /* Check trace mode exceptions */
6328
        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
6329
                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
6330
                     ctx.exception != POWERPC_SYSCALL &&
6331
                     ctx.exception != POWERPC_EXCP_TRAP &&
6332
                     ctx.exception != POWERPC_EXCP_BRANCH)) {
6333
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6334
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6335
                            (env->singlestep_enabled) ||
6336
                            num_insns >= max_insns)) {
6337
            /* if we reach a page boundary or are single stepping, stop
6338
             * generation
6339
             */
6340
            break;
6341
        }
6342
#if defined (DO_SINGLE_STEP)
6343
        break;
6344
#endif
6345
    }
6346
    if (tb->cflags & CF_LAST_IO)
6347
        gen_io_end();
6348
    if (ctx.exception == POWERPC_EXCP_NONE) {
6349
        gen_goto_tb(&ctx, 0, ctx.nip);
6350
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6351
        if (unlikely(env->singlestep_enabled)) {
6352
            gen_update_nip(&ctx, ctx.nip);
6353
            gen_op_debug();
6354
        }
6355
        /* Generate the return instruction */
6356
        tcg_gen_exit_tb(0);
6357
    }
6358
    gen_icount_end(tb, num_insns);
6359
    *gen_opc_ptr = INDEX_op_end;
6360
    if (unlikely(search_pc)) {
6361
        j = gen_opc_ptr - gen_opc_buf;
6362
        lj++;
6363
        while (lj <= j)
6364
            gen_opc_instr_start[lj++] = 0;
6365
    } else {
6366
        tb->size = ctx.nip - pc_start;
6367
        tb->icount = num_insns;
6368
    }
6369
#if defined(DEBUG_DISAS)
6370
    if (loglevel & CPU_LOG_TB_CPU) {
6371
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6372
        cpu_dump_state(env, logfile, fprintf, 0);
6373
    }
6374
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6375
        int flags;
6376
        flags = env->bfd_mach;
6377
        flags |= little_endian << 16;
6378
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6379
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6380
        fprintf(logfile, "\n");
6381
    }
6382
#endif
6383
}
6384

    
6385
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6386
{
6387
    gen_intermediate_code_internal(env, tb, 0);
6388
}
6389

    
6390
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6391
{
6392
    gen_intermediate_code_internal(env, tb, 1);
6393
}
6394

    
6395
void gen_pc_load(CPUState *env, TranslationBlock *tb,
6396
                unsigned long searched_pc, int pc_pos, void *puc)
6397
{
6398
    int type, c;
6399
    /* for PPC, we need to look at the micro operation to get the
6400
     * access type */
6401
    env->nip = gen_opc_pc[pc_pos];
6402
    c = gen_opc_buf[pc_pos];
6403
    switch(c) {
6404
#if defined(CONFIG_USER_ONLY)
6405
#define CASE3(op)\
6406
    case INDEX_op_ ## op ## _raw
6407
#else
6408
#define CASE3(op)\
6409
    case INDEX_op_ ## op ## _user:\
6410
    case INDEX_op_ ## op ## _kernel:\
6411
    case INDEX_op_ ## op ## _hypv
6412
#endif
6413

    
6414
    CASE3(stfd):
6415
    CASE3(stfs):
6416
    CASE3(lfd):
6417
    CASE3(lfs):
6418
        type = ACCESS_FLOAT;
6419
        break;
6420
    CASE3(lwarx):
6421
        type = ACCESS_RES;
6422
        break;
6423
    CASE3(stwcx):
6424
        type = ACCESS_RES;
6425
        break;
6426
    CASE3(eciwx):
6427
    CASE3(ecowx):
6428
        type = ACCESS_EXT;
6429
        break;
6430
    default:
6431
        type = ACCESS_INT;
6432
        break;
6433
    }
6434
    env->access_type = type;
6435
}