Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 7dbe11ac

History | View | Annotate | Download (212.3 kB)

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

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

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

    
36
/*****************************************************************************/
37
/* Code translation helpers                                                  */
38
#if defined(USE_DIRECT_JUMP)
39
#define TBPARAM(x)
40
#else
41
#define TBPARAM(x) (long)(x)
42
#endif
43

    
44
enum {
45
#define DEF(s, n, copy_size) INDEX_op_ ## s,
46
#include "opc.h"
47
#undef DEF
48
    NB_OPS,
49
};
50

    
51
static uint16_t *gen_opc_ptr;
52
static uint32_t *gen_opparam_ptr;
53

    
54
#include "gen-op.h"
55

    
56
static inline void gen_set_T0 (target_ulong val)
57
{
58
#if defined(TARGET_PPC64)
59
    if (val >> 32)
60
        gen_op_set_T0_64(val >> 32, val);
61
    else
62
#endif
63
        gen_op_set_T0(val);
64
}
65

    
66
static inline void gen_set_T1 (target_ulong val)
67
{
68
#if defined(TARGET_PPC64)
69
    if (val >> 32)
70
        gen_op_set_T1_64(val >> 32, val);
71
    else
72
#endif
73
        gen_op_set_T1(val);
74
}
75

    
76
#define GEN8(func, NAME)                                                      \
77
static GenOpFunc *NAME ## _table [8] = {                                      \
78
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
79
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
80
};                                                                            \
81
static inline void func(int n)                                                \
82
{                                                                             \
83
    NAME ## _table[n]();                                                      \
84
}
85

    
86
#define GEN16(func, NAME)                                                     \
87
static GenOpFunc *NAME ## _table [16] = {                                     \
88
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
89
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
90
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
91
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
92
};                                                                            \
93
static inline void func(int n)                                                \
94
{                                                                             \
95
    NAME ## _table[n]();                                                      \
96
}
97

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

    
114
/* Condition register moves */
115
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
116
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
117
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
118
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
119

    
120
/* Floating point condition and status register moves */
121
GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
122
GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
123
GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
124
static inline void gen_op_store_T0_fpscri (int n, uint8_t param)
125
{
126
    gen_op_set_T0(param);
127
    gen_op_store_T0_fpscr(n);
128
}
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
#if defined(TARGET_PPCEMB)
168
    int spe_enabled;
169
#endif
170
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
171
    int singlestep_enabled;
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 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 inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
201
{
202
#if defined(TARGET_PPC64)
203
    if (ctx->sf_mode)
204
        gen_op_update_nip_64(nip >> 32, nip);
205
    else
206
#endif
207
        gen_op_update_nip(nip);
208
}
209

    
210
#define GEN_EXCP(ctx, excp, error)                                            \
211
do {                                                                          \
212
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
213
        gen_update_nip(ctx, (ctx)->nip);                                      \
214
    }                                                                         \
215
    gen_op_raise_exception_err((excp), (error));                              \
216
    ctx->exception = (excp);                                                  \
217
} while (0)
218

    
219
#define GEN_EXCP_INVAL(ctx)                                                   \
220
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
221
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
222

    
223
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
224
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
225
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
226

    
227
#define GEN_EXCP_PRIVREG(ctx)                                                 \
228
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
229
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
230

    
231
#define GEN_EXCP_NO_FP(ctx)                                                   \
232
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
233

    
234
#define GEN_EXCP_NO_AP(ctx)                                                   \
235
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
236

    
237
/* Stop translation */
238
static inline void GEN_STOP (DisasContext *ctx)
239
{
240
    gen_update_nip(ctx, ctx->nip);
241
    ctx->exception = POWERPC_EXCP_STOP;
242
}
243

    
244
/* No need to update nip here, as execution flow will change */
245
static inline void GEN_SYNC (DisasContext *ctx)
246
{
247
    ctx->exception = POWERPC_EXCP_SYNC;
248
}
249

    
250
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
251
static void gen_##name (DisasContext *ctx);                                   \
252
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
253
static void gen_##name (DisasContext *ctx)
254

    
255
typedef struct opcode_t {
256
    unsigned char opc1, opc2, opc3;
257
#if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
258
    unsigned char pad[5];
259
#else
260
    unsigned char pad[1];
261
#endif
262
    opc_handler_t handler;
263
    const unsigned char *oname;
264
} opcode_t;
265

    
266
/*****************************************************************************/
267
/***                           Instruction decoding                        ***/
268
#define EXTRACT_HELPER(name, shift, nb)                                       \
269
static inline uint32_t name (uint32_t opcode)                                 \
270
{                                                                             \
271
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
272
}
273

    
274
#define EXTRACT_SHELPER(name, shift, nb)                                      \
275
static inline int32_t name (uint32_t opcode)                                  \
276
{                                                                             \
277
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
278
}
279

    
280
/* Opcode part 1 */
281
EXTRACT_HELPER(opc1, 26, 6);
282
/* Opcode part 2 */
283
EXTRACT_HELPER(opc2, 1, 5);
284
/* Opcode part 3 */
285
EXTRACT_HELPER(opc3, 6, 5);
286
/* Update Cr0 flags */
287
EXTRACT_HELPER(Rc, 0, 1);
288
/* Destination */
289
EXTRACT_HELPER(rD, 21, 5);
290
/* Source */
291
EXTRACT_HELPER(rS, 21, 5);
292
/* First operand */
293
EXTRACT_HELPER(rA, 16, 5);
294
/* Second operand */
295
EXTRACT_HELPER(rB, 11, 5);
296
/* Third operand */
297
EXTRACT_HELPER(rC, 6, 5);
298
/***                               Get CRn                                 ***/
299
EXTRACT_HELPER(crfD, 23, 3);
300
EXTRACT_HELPER(crfS, 18, 3);
301
EXTRACT_HELPER(crbD, 21, 5);
302
EXTRACT_HELPER(crbA, 16, 5);
303
EXTRACT_HELPER(crbB, 11, 5);
304
/* SPR / TBL */
305
EXTRACT_HELPER(_SPR, 11, 10);
306
static inline uint32_t SPR (uint32_t opcode)
307
{
308
    uint32_t sprn = _SPR(opcode);
309

    
310
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
311
}
312
/***                              Get constants                            ***/
313
EXTRACT_HELPER(IMM, 12, 8);
314
/* 16 bits signed immediate value */
315
EXTRACT_SHELPER(SIMM, 0, 16);
316
/* 16 bits unsigned immediate value */
317
EXTRACT_HELPER(UIMM, 0, 16);
318
/* Bit count */
319
EXTRACT_HELPER(NB, 11, 5);
320
/* Shift count */
321
EXTRACT_HELPER(SH, 11, 5);
322
/* Mask start */
323
EXTRACT_HELPER(MB, 6, 5);
324
/* Mask end */
325
EXTRACT_HELPER(ME, 1, 5);
326
/* Trap operand */
327
EXTRACT_HELPER(TO, 21, 5);
328

    
329
EXTRACT_HELPER(CRM, 12, 8);
330
EXTRACT_HELPER(FM, 17, 8);
331
EXTRACT_HELPER(SR, 16, 4);
332
EXTRACT_HELPER(FPIMM, 20, 4);
333

    
334
/***                            Jump target decoding                       ***/
335
/* Displacement */
336
EXTRACT_SHELPER(d, 0, 16);
337
/* Immediate address */
338
static inline target_ulong LI (uint32_t opcode)
339
{
340
    return (opcode >> 0) & 0x03FFFFFC;
341
}
342

    
343
static inline uint32_t BD (uint32_t opcode)
344
{
345
    return (opcode >> 0) & 0xFFFC;
346
}
347

    
348
EXTRACT_HELPER(BO, 21, 5);
349
EXTRACT_HELPER(BI, 16, 5);
350
/* Absolute/relative address */
351
EXTRACT_HELPER(AA, 1, 1);
352
/* Link */
353
EXTRACT_HELPER(LK, 0, 1);
354

    
355
/* Create a mask between <start> and <end> bits */
356
static inline target_ulong MASK (uint32_t start, uint32_t end)
357
{
358
    target_ulong ret;
359

    
360
#if defined(TARGET_PPC64)
361
    if (likely(start == 0)) {
362
        ret = (uint64_t)(-1ULL) << (63 - end);
363
    } else if (likely(end == 63)) {
364
        ret = (uint64_t)(-1ULL) >> start;
365
    }
366
#else
367
    if (likely(start == 0)) {
368
        ret = (uint32_t)(-1ULL) << (31  - end);
369
    } else if (likely(end == 31)) {
370
        ret = (uint32_t)(-1ULL) >> start;
371
    }
372
#endif
373
    else {
374
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
375
            (((target_ulong)(-1ULL) >> (end)) >> 1);
376
        if (unlikely(start > end))
377
            return ~ret;
378
    }
379

    
380
    return ret;
381
}
382

    
383
/*****************************************************************************/
384
/* PowerPC Instructions types definitions                                    */
385
enum {
386
    PPC_NONE          = 0x0000000000000000ULL,
387
    /* integer operations instructions                  */
388
    /* flow control instructions                        */
389
    /* virtual memory instructions                      */
390
    /* ld/st with reservation instructions              */
391
    /* cache control instructions                       */
392
    /* spr/msr access instructions                      */
393
    PPC_INSNS_BASE    = 0x0000000000000001ULL,
394
#define PPC_INTEGER PPC_INSNS_BASE
395
#define PPC_FLOW    PPC_INSNS_BASE
396
#define PPC_MEM     PPC_INSNS_BASE
397
#define PPC_RES     PPC_INSNS_BASE
398
#define PPC_CACHE   PPC_INSNS_BASE
399
#define PPC_MISC    PPC_INSNS_BASE
400
    /* Optional floating point instructions             */
401
    PPC_FLOAT         = 0x0000000000000002ULL,
402
    PPC_FLOAT_FSQRT   = 0x0000000000000004ULL,
403
    PPC_FLOAT_FRES    = 0x0000000000000008ULL,
404
    PPC_FLOAT_FRSQRTE = 0x0000000000000010ULL,
405
    PPC_FLOAT_FSEL    = 0x0000000000000020ULL,
406
    PPC_FLOAT_STFIWX  = 0x0000000000000040ULL,
407
    /* external control instructions                    */
408
    PPC_EXTERN        = 0x0000000000000080ULL,
409
    /* segment register access instructions             */
410
    PPC_SEGMENT       = 0x0000000000000100ULL,
411
    /* Optional cache control instruction               */
412
    PPC_CACHE_DCBA    = 0x0000000000000200ULL,
413
    /* Optional memory control instructions             */
414
    PPC_MEM_TLBIA     = 0x0000000000000400ULL,
415
    PPC_MEM_TLBIE     = 0x0000000000000800ULL,
416
    PPC_MEM_TLBSYNC   = 0x0000000000001000ULL,
417
    /* eieio & sync                                     */
418
    PPC_MEM_SYNC      = 0x0000000000002000ULL,
419
    /* PowerPC 6xx TLB management instructions          */
420
    PPC_6xx_TLB       = 0x0000000000004000ULL,
421
    /* Altivec support                                  */
422
    PPC_ALTIVEC       = 0x0000000000008000ULL,
423
    /* Time base mftb instruction                       */
424
    PPC_MFTB          = 0x0000000000010000ULL,
425
    /* Embedded PowerPC dedicated instructions          */
426
    PPC_EMB_COMMON    = 0x0000000000020000ULL,
427
    /* PowerPC 40x exception model                      */
428
    PPC_40x_EXCP      = 0x0000000000040000ULL,
429
    /* PowerPC 40x TLB management instructions          */
430
    PPC_40x_TLB       = 0x0000000000080000ULL,
431
    /* PowerPC 405 Mac instructions                     */
432
    PPC_405_MAC       = 0x0000000000100000ULL,
433
    /* PowerPC 440 specific instructions                */
434
    PPC_440_SPEC      = 0x0000000000200000ULL,
435
    /* Power-to-PowerPC bridge (601)                    */
436
    PPC_POWER_BR      = 0x0000000000400000ULL,
437
    /* PowerPC 602 specific */
438
    PPC_602_SPEC      = 0x0000000000800000ULL,
439
    /* Deprecated instructions                          */
440
    /* Original POWER instruction set                   */
441
    PPC_POWER         = 0x0000000001000000ULL,
442
    /* POWER2 instruction set extension                 */
443
    PPC_POWER2        = 0x0000000002000000ULL,
444
    /* Power RTC support */
445
    PPC_POWER_RTC     = 0x0000000004000000ULL,
446
    /* 64 bits PowerPC instructions                     */
447
    /* 64 bits PowerPC instruction set                  */
448
    PPC_64B           = 0x0000000008000000ULL,
449
    /* 64 bits hypervisor extensions                    */
450
    PPC_64H           = 0x0000000010000000ULL,
451
    /* 64 bits PowerPC "bridge" features                */
452
    PPC_64_BRIDGE     = 0x0000000020000000ULL,
453
    /* BookE (embedded) PowerPC specification           */
454
    PPC_BOOKE         = 0x0000000040000000ULL,
455
    /* eieio                                            */
456
    PPC_MEM_EIEIO     = 0x0000000080000000ULL,
457
    /* e500 vector instructions                         */
458
    PPC_E500_VECTOR   = 0x0000000100000000ULL,
459
    /* PowerPC 4xx dedicated instructions               */
460
    PPC_4xx_COMMON    = 0x0000000200000000ULL,
461
    /* PowerPC 2.03 specification extensions            */
462
    PPC_203           = 0x0000000400000000ULL,
463
    /* PowerPC 2.03 SPE extension                       */
464
    PPC_SPE           = 0x0000000800000000ULL,
465
    /* PowerPC 2.03 SPE floating-point extension        */
466
    PPC_SPEFPU        = 0x0000001000000000ULL,
467
    /* SLB management                                   */
468
    PPC_SLBI          = 0x0000002000000000ULL,
469
    /* PowerPC 40x ibct instructions                    */
470
    PPC_40x_ICBT      = 0x0000004000000000ULL,
471
    /* PowerPC 74xx TLB management instructions         */
472
    PPC_74xx_TLB      = 0x0000008000000000ULL,
473
    /* More BookE (embedded) instructions...            */
474
    PPC_BOOKE_EXT     = 0x0000010000000000ULL,
475
    /* rfmci is not implemented in all BookE PowerPC    */
476
    PPC_RFMCI         = 0x0000020000000000ULL,
477
    /* user-mode DCR access, implemented in PowerPC 460 */
478
    PPC_DCRUX         = 0x0000040000000000ULL,
479
    /* New floating-point extensions (PowerPC 2.0x)     */
480
    PPC_FLOAT_EXT     = 0x0000080000000000ULL,
481
    /* New wait instruction (PowerPC 2.0x)              */
482
    PPC_WAIT          = 0x0000100000000000ULL,
483
    /* New 64 bits extensions (PowerPC 2.0x)            */
484
    PPC_64BX          = 0x0000200000000000ULL,
485
};
486

    
487
/*****************************************************************************/
488
/* PowerPC instructions table                                                */
489
#if HOST_LONG_BITS == 64
490
#define OPC_ALIGN 8
491
#else
492
#define OPC_ALIGN 4
493
#endif
494
#if defined(__APPLE__)
495
#define OPCODES_SECTION                                                       \
496
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
497
#else
498
#define OPCODES_SECTION                                                       \
499
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
500
#endif
501

    
502
#if defined(DO_PPC_STATISTICS)
503
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
504
OPCODES_SECTION opcode_t opc_##name = {                                       \
505
    .opc1 = op1,                                                              \
506
    .opc2 = op2,                                                              \
507
    .opc3 = op3,                                                              \
508
    .pad  = { 0, },                                                           \
509
    .handler = {                                                              \
510
        .inval   = invl,                                                      \
511
        .type = _typ,                                                         \
512
        .handler = &gen_##name,                                               \
513
        .oname = stringify(name),                                             \
514
    },                                                                        \
515
    .oname = stringify(name),                                                 \
516
}
517
#else
518
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
519
OPCODES_SECTION opcode_t opc_##name = {                                       \
520
    .opc1 = op1,                                                              \
521
    .opc2 = op2,                                                              \
522
    .opc3 = op3,                                                              \
523
    .pad  = { 0, },                                                           \
524
    .handler = {                                                              \
525
        .inval   = invl,                                                      \
526
        .type = _typ,                                                         \
527
        .handler = &gen_##name,                                               \
528
    },                                                                        \
529
    .oname = stringify(name),                                                 \
530
}
531
#endif
532

    
533
#define GEN_OPCODE_MARK(name)                                                 \
534
OPCODES_SECTION opcode_t opc_##name = {                                       \
535
    .opc1 = 0xFF,                                                             \
536
    .opc2 = 0xFF,                                                             \
537
    .opc3 = 0xFF,                                                             \
538
    .pad  = { 0, },                                                           \
539
    .handler = {                                                              \
540
        .inval   = 0x00000000,                                                \
541
        .type = 0x00,                                                         \
542
        .handler = NULL,                                                      \
543
    },                                                                        \
544
    .oname = stringify(name),                                                 \
545
}
546

    
547
/* Start opcode list */
548
GEN_OPCODE_MARK(start);
549

    
550
/* Invalid instruction */
551
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
552
{
553
    GEN_EXCP_INVAL(ctx);
554
}
555

    
556
static opc_handler_t invalid_handler = {
557
    .inval   = 0xFFFFFFFF,
558
    .type    = PPC_NONE,
559
    .handler = gen_invalid,
560
};
561

    
562
/***                           Integer arithmetic                          ***/
563
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
564
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
565
{                                                                             \
566
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
567
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
568
    gen_op_##name();                                                          \
569
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
570
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
571
        gen_set_Rc0(ctx);                                                     \
572
}
573

    
574
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
575
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
576
{                                                                             \
577
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
578
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
579
    gen_op_##name();                                                          \
580
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
581
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
582
        gen_set_Rc0(ctx);                                                     \
583
}
584

    
585
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
586
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
587
{                                                                             \
588
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
589
    gen_op_##name();                                                          \
590
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
591
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
592
        gen_set_Rc0(ctx);                                                     \
593
}
594
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
595
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
596
{                                                                             \
597
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
598
    gen_op_##name();                                                          \
599
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
600
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
601
        gen_set_Rc0(ctx);                                                     \
602
}
603

    
604
/* Two operands arithmetic functions */
605
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
606
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
607
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
608

    
609
/* Two operands arithmetic functions with no overflow allowed */
610
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
611
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
612

    
613
/* One operand arithmetic functions */
614
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
615
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
616
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
617

    
618
#if defined(TARGET_PPC64)
619
#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
620
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
621
{                                                                             \
622
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
623
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
624
    if (ctx->sf_mode)                                                         \
625
        gen_op_##name##_64();                                                 \
626
    else                                                                      \
627
        gen_op_##name();                                                      \
628
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
629
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
630
        gen_set_Rc0(ctx);                                                     \
631
}
632

    
633
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
634
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
635
{                                                                             \
636
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
637
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
638
    if (ctx->sf_mode)                                                         \
639
        gen_op_##name##_64();                                                 \
640
    else                                                                      \
641
        gen_op_##name();                                                      \
642
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
643
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
644
        gen_set_Rc0(ctx);                                                     \
645
}
646

    
647
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
648
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
649
{                                                                             \
650
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
651
    if (ctx->sf_mode)                                                         \
652
        gen_op_##name##_64();                                                 \
653
    else                                                                      \
654
        gen_op_##name();                                                      \
655
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
656
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
657
        gen_set_Rc0(ctx);                                                     \
658
}
659
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
660
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
661
{                                                                             \
662
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
663
    if (ctx->sf_mode)                                                         \
664
        gen_op_##name##_64();                                                 \
665
    else                                                                      \
666
        gen_op_##name();                                                      \
667
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
668
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
669
        gen_set_Rc0(ctx);                                                     \
670
}
671

    
672
/* Two operands arithmetic functions */
673
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
674
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
675
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
676

    
677
/* Two operands arithmetic functions with no overflow allowed */
678
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
679
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
680

    
681
/* One operand arithmetic functions */
682
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
683
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
684
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
685
#else
686
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
687
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
688
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
689
#endif
690

    
691
/* add    add.    addo    addo.    */
692
static inline void gen_op_addo (void)
693
{
694
    gen_op_move_T2_T0();
695
    gen_op_add();
696
    gen_op_check_addo();
697
}
698
#if defined(TARGET_PPC64)
699
#define gen_op_add_64 gen_op_add
700
static inline void gen_op_addo_64 (void)
701
{
702
    gen_op_move_T2_T0();
703
    gen_op_add();
704
    gen_op_check_addo_64();
705
}
706
#endif
707
GEN_INT_ARITH2_64 (add,    0x1F, 0x0A, 0x08, PPC_INTEGER);
708
/* addc   addc.   addco   addco.   */
709
static inline void gen_op_addc (void)
710
{
711
    gen_op_move_T2_T0();
712
    gen_op_add();
713
    gen_op_check_addc();
714
}
715
static inline void gen_op_addco (void)
716
{
717
    gen_op_move_T2_T0();
718
    gen_op_add();
719
    gen_op_check_addc();
720
    gen_op_check_addo();
721
}
722
#if defined(TARGET_PPC64)
723
static inline void gen_op_addc_64 (void)
724
{
725
    gen_op_move_T2_T0();
726
    gen_op_add();
727
    gen_op_check_addc_64();
728
}
729
static inline void gen_op_addco_64 (void)
730
{
731
    gen_op_move_T2_T0();
732
    gen_op_add();
733
    gen_op_check_addc_64();
734
    gen_op_check_addo_64();
735
}
736
#endif
737
GEN_INT_ARITH2_64 (addc,   0x1F, 0x0A, 0x00, PPC_INTEGER);
738
/* adde   adde.   addeo   addeo.   */
739
static inline void gen_op_addeo (void)
740
{
741
    gen_op_move_T2_T0();
742
    gen_op_adde();
743
    gen_op_check_addo();
744
}
745
#if defined(TARGET_PPC64)
746
static inline void gen_op_addeo_64 (void)
747
{
748
    gen_op_move_T2_T0();
749
    gen_op_adde_64();
750
    gen_op_check_addo_64();
751
}
752
#endif
753
GEN_INT_ARITH2_64 (adde,   0x1F, 0x0A, 0x04, PPC_INTEGER);
754
/* addme  addme.  addmeo  addmeo.  */
755
static inline void gen_op_addme (void)
756
{
757
    gen_op_move_T1_T0();
758
    gen_op_add_me();
759
}
760
#if defined(TARGET_PPC64)
761
static inline void gen_op_addme_64 (void)
762
{
763
    gen_op_move_T1_T0();
764
    gen_op_add_me_64();
765
}
766
#endif
767
GEN_INT_ARITH1_64 (addme,  0x1F, 0x0A, 0x07, PPC_INTEGER);
768
/* addze  addze.  addzeo  addzeo.  */
769
static inline void gen_op_addze (void)
770
{
771
    gen_op_move_T2_T0();
772
    gen_op_add_ze();
773
    gen_op_check_addc();
774
}
775
static inline void gen_op_addzeo (void)
776
{
777
    gen_op_move_T2_T0();
778
    gen_op_add_ze();
779
    gen_op_check_addc();
780
    gen_op_check_addo();
781
}
782
#if defined(TARGET_PPC64)
783
static inline void gen_op_addze_64 (void)
784
{
785
    gen_op_move_T2_T0();
786
    gen_op_add_ze();
787
    gen_op_check_addc_64();
788
}
789
static inline void gen_op_addzeo_64 (void)
790
{
791
    gen_op_move_T2_T0();
792
    gen_op_add_ze();
793
    gen_op_check_addc_64();
794
    gen_op_check_addo_64();
795
}
796
#endif
797
GEN_INT_ARITH1_64 (addze,  0x1F, 0x0A, 0x06, PPC_INTEGER);
798
/* divw   divw.   divwo   divwo.   */
799
GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F, PPC_INTEGER);
800
/* divwu  divwu.  divwuo  divwuo.  */
801
GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E, PPC_INTEGER);
802
/* mulhw  mulhw.                   */
803
GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02, PPC_INTEGER);
804
/* mulhwu mulhwu.                  */
805
GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);
806
/* mullw  mullw.  mullwo  mullwo.  */
807
GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07, PPC_INTEGER);
808
/* neg    neg.    nego    nego.    */
809
GEN_INT_ARITH1_64 (neg,    0x1F, 0x08, 0x03, PPC_INTEGER);
810
/* subf   subf.   subfo   subfo.   */
811
static inline void gen_op_subfo (void)
812
{
813
    gen_op_move_T2_T0();
814
    gen_op_subf();
815
    gen_op_check_subfo();
816
}
817
#if defined(TARGET_PPC64)
818
#define gen_op_subf_64 gen_op_subf
819
static inline void gen_op_subfo_64 (void)
820
{
821
    gen_op_move_T2_T0();
822
    gen_op_subf();
823
    gen_op_check_subfo_64();
824
}
825
#endif
826
GEN_INT_ARITH2_64 (subf,   0x1F, 0x08, 0x01, PPC_INTEGER);
827
/* subfc  subfc.  subfco  subfco.  */
828
static inline void gen_op_subfc (void)
829
{
830
    gen_op_subf();
831
    gen_op_check_subfc();
832
}
833
static inline void gen_op_subfco (void)
834
{
835
    gen_op_move_T2_T0();
836
    gen_op_subf();
837
    gen_op_check_subfc();
838
    gen_op_check_subfo();
839
}
840
#if defined(TARGET_PPC64)
841
static inline void gen_op_subfc_64 (void)
842
{
843
    gen_op_subf();
844
    gen_op_check_subfc_64();
845
}
846
static inline void gen_op_subfco_64 (void)
847
{
848
    gen_op_move_T2_T0();
849
    gen_op_subf();
850
    gen_op_check_subfc_64();
851
    gen_op_check_subfo_64();
852
}
853
#endif
854
GEN_INT_ARITH2_64 (subfc,  0x1F, 0x08, 0x00, PPC_INTEGER);
855
/* subfe  subfe.  subfeo  subfeo.  */
856
static inline void gen_op_subfeo (void)
857
{
858
    gen_op_move_T2_T0();
859
    gen_op_subfe();
860
    gen_op_check_subfo();
861
}
862
#if defined(TARGET_PPC64)
863
#define gen_op_subfe_64 gen_op_subfe
864
static inline void gen_op_subfeo_64 (void)
865
{
866
    gen_op_move_T2_T0();
867
    gen_op_subfe_64();
868
    gen_op_check_subfo_64();
869
}
870
#endif
871
GEN_INT_ARITH2_64 (subfe,  0x1F, 0x08, 0x04, PPC_INTEGER);
872
/* subfme subfme. subfmeo subfmeo. */
873
GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);
874
/* subfze subfze. subfzeo subfzeo. */
875
GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);
876
/* addi */
877
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
878
{
879
    target_long simm = SIMM(ctx->opcode);
880

    
881
    if (rA(ctx->opcode) == 0) {
882
        /* li case */
883
        gen_set_T0(simm);
884
    } else {
885
        gen_op_load_gpr_T0(rA(ctx->opcode));
886
        if (likely(simm != 0))
887
            gen_op_addi(simm);
888
    }
889
    gen_op_store_T0_gpr(rD(ctx->opcode));
890
}
891
/* addic */
892
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
893
{
894
    target_long simm = SIMM(ctx->opcode);
895

    
896
    gen_op_load_gpr_T0(rA(ctx->opcode));
897
    if (likely(simm != 0)) {
898
        gen_op_move_T2_T0();
899
        gen_op_addi(simm);
900
#if defined(TARGET_PPC64)
901
        if (ctx->sf_mode)
902
            gen_op_check_addc_64();
903
        else
904
#endif
905
            gen_op_check_addc();
906
    } else {
907
        gen_op_clear_xer_ca();
908
    }
909
    gen_op_store_T0_gpr(rD(ctx->opcode));
910
}
911
/* addic. */
912
GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
913
{
914
    target_long simm = SIMM(ctx->opcode);
915

    
916
    gen_op_load_gpr_T0(rA(ctx->opcode));
917
    if (likely(simm != 0)) {
918
        gen_op_move_T2_T0();
919
        gen_op_addi(simm);
920
#if defined(TARGET_PPC64)
921
        if (ctx->sf_mode)
922
            gen_op_check_addc_64();
923
        else
924
#endif
925
            gen_op_check_addc();
926
    } else {
927
        gen_op_clear_xer_ca();
928
    }
929
    gen_op_store_T0_gpr(rD(ctx->opcode));
930
    gen_set_Rc0(ctx);
931
}
932
/* addis */
933
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
934
{
935
    target_long simm = SIMM(ctx->opcode);
936

    
937
    if (rA(ctx->opcode) == 0) {
938
        /* lis case */
939
        gen_set_T0(simm << 16);
940
    } else {
941
        gen_op_load_gpr_T0(rA(ctx->opcode));
942
        if (likely(simm != 0))
943
            gen_op_addi(simm << 16);
944
    }
945
    gen_op_store_T0_gpr(rD(ctx->opcode));
946
}
947
/* mulli */
948
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
949
{
950
    gen_op_load_gpr_T0(rA(ctx->opcode));
951
    gen_op_mulli(SIMM(ctx->opcode));
952
    gen_op_store_T0_gpr(rD(ctx->opcode));
953
}
954
/* subfic */
955
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
956
{
957
    gen_op_load_gpr_T0(rA(ctx->opcode));
958
#if defined(TARGET_PPC64)
959
    if (ctx->sf_mode)
960
        gen_op_subfic_64(SIMM(ctx->opcode));
961
    else
962
#endif
963
        gen_op_subfic(SIMM(ctx->opcode));
964
    gen_op_store_T0_gpr(rD(ctx->opcode));
965
}
966

    
967
#if defined(TARGET_PPC64)
968
/* mulhd  mulhd.                   */
969
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
970
/* mulhdu mulhdu.                  */
971
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
972
/* mulld  mulld.  mulldo  mulldo.  */
973
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
974
/* divd   divd.   divdo   divdo.   */
975
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
976
/* divdu  divdu.  divduo  divduo.  */
977
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
978
#endif
979

    
980
/***                           Integer comparison                          ***/
981
#if defined(TARGET_PPC64)
982
#define GEN_CMP(name, opc, type)                                              \
983
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
984
{                                                                             \
985
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
986
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
987
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))                           \
988
        gen_op_##name##_64();                                                 \
989
    else                                                                      \
990
        gen_op_##name();                                                      \
991
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
992
}
993
#else
994
#define GEN_CMP(name, opc, type)                                              \
995
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
996
{                                                                             \
997
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
998
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
999
    gen_op_##name();                                                          \
1000
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
1001
}
1002
#endif
1003

    
1004
/* cmp */
1005
GEN_CMP(cmp, 0x00, PPC_INTEGER);
1006
/* cmpi */
1007
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1008
{
1009
    gen_op_load_gpr_T0(rA(ctx->opcode));
1010
#if defined(TARGET_PPC64)
1011
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1012
        gen_op_cmpi_64(SIMM(ctx->opcode));
1013
    else
1014
#endif
1015
        gen_op_cmpi(SIMM(ctx->opcode));
1016
    gen_op_store_T0_crf(crfD(ctx->opcode));
1017
}
1018
/* cmpl */
1019
GEN_CMP(cmpl, 0x01, PPC_INTEGER);
1020
/* cmpli */
1021
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1022
{
1023
    gen_op_load_gpr_T0(rA(ctx->opcode));
1024
#if defined(TARGET_PPC64)
1025
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1026
        gen_op_cmpli_64(UIMM(ctx->opcode));
1027
    else
1028
#endif
1029
        gen_op_cmpli(UIMM(ctx->opcode));
1030
    gen_op_store_T0_crf(crfD(ctx->opcode));
1031
}
1032

    
1033
/* isel (PowerPC 2.03 specification) */
1034
GEN_HANDLER(isel, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203)
1035
{
1036
    uint32_t bi = rC(ctx->opcode);
1037
    uint32_t mask;
1038

    
1039
    if (rA(ctx->opcode) == 0) {
1040
        gen_set_T0(0);
1041
    } else {
1042
        gen_op_load_gpr_T1(rA(ctx->opcode));
1043
    }
1044
    gen_op_load_gpr_T2(rB(ctx->opcode));
1045
    mask = 1 << (3 - (bi & 0x03));
1046
    gen_op_load_crf_T0(bi >> 2);
1047
    gen_op_test_true(mask);
1048
    gen_op_isel();
1049
    gen_op_store_T0_gpr(rD(ctx->opcode));
1050
}
1051

    
1052
/***                            Integer logical                            ***/
1053
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1054
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1055
{                                                                             \
1056
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1057
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1058
    gen_op_##name();                                                          \
1059
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1060
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1061
        gen_set_Rc0(ctx);                                                     \
1062
}
1063
#define GEN_LOGICAL2(name, opc, type)                                         \
1064
__GEN_LOGICAL2(name, 0x1C, opc, type)
1065

    
1066
#define GEN_LOGICAL1(name, opc, type)                                         \
1067
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1068
{                                                                             \
1069
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1070
    gen_op_##name();                                                          \
1071
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1072
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1073
        gen_set_Rc0(ctx);                                                     \
1074
}
1075

    
1076
/* and & and. */
1077
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1078
/* andc & andc. */
1079
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1080
/* andi. */
1081
GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1082
{
1083
    gen_op_load_gpr_T0(rS(ctx->opcode));
1084
    gen_op_andi_T0(UIMM(ctx->opcode));
1085
    gen_op_store_T0_gpr(rA(ctx->opcode));
1086
    gen_set_Rc0(ctx);
1087
}
1088
/* andis. */
1089
GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1090
{
1091
    gen_op_load_gpr_T0(rS(ctx->opcode));
1092
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
1093
    gen_op_store_T0_gpr(rA(ctx->opcode));
1094
    gen_set_Rc0(ctx);
1095
}
1096

    
1097
/* cntlzw */
1098
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1099
/* eqv & eqv. */
1100
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1101
/* extsb & extsb. */
1102
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1103
/* extsh & extsh. */
1104
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1105
/* nand & nand. */
1106
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1107
/* nor & nor. */
1108
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1109

    
1110
/* or & or. */
1111
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1112
{
1113
    int rs, ra, rb;
1114

    
1115
    rs = rS(ctx->opcode);
1116
    ra = rA(ctx->opcode);
1117
    rb = rB(ctx->opcode);
1118
    /* Optimisation for mr. ri case */
1119
    if (rs != ra || rs != rb) {
1120
        gen_op_load_gpr_T0(rs);
1121
        if (rs != rb) {
1122
            gen_op_load_gpr_T1(rb);
1123
            gen_op_or();
1124
        }
1125
        gen_op_store_T0_gpr(ra);
1126
        if (unlikely(Rc(ctx->opcode) != 0))
1127
            gen_set_Rc0(ctx);
1128
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1129
        gen_op_load_gpr_T0(rs);
1130
        gen_set_Rc0(ctx);
1131
#if defined(TARGET_PPC64)
1132
    } else {
1133
        switch (rs) {
1134
        case 1:
1135
            /* Set process priority to low */
1136
            gen_op_store_pri(2);
1137
            break;
1138
        case 6:
1139
            /* Set process priority to medium-low */
1140
            gen_op_store_pri(3);
1141
            break;
1142
        case 2:
1143
            /* Set process priority to normal */
1144
            gen_op_store_pri(4);
1145
            break;
1146
#if !defined(CONFIG_USER_ONLY)
1147
        case 31:
1148
            if (ctx->supervisor > 0) {
1149
                /* Set process priority to very low */
1150
                gen_op_store_pri(1);
1151
            }
1152
            break;
1153
        case 5:
1154
            if (ctx->supervisor > 0) {
1155
                /* Set process priority to medium-hight */
1156
                gen_op_store_pri(5);
1157
            }
1158
            break;
1159
        case 3:
1160
            if (ctx->supervisor > 0) {
1161
                /* Set process priority to high */
1162
                gen_op_store_pri(6);
1163
            }
1164
            break;
1165
#if defined(TARGET_PPC64H)
1166
        case 7:
1167
            if (ctx->supervisor > 1) {
1168
                /* Set process priority to very high */
1169
                gen_op_store_pri(7);
1170
            }
1171
            break;
1172
#endif
1173
#endif
1174
        default:
1175
            /* nop */
1176
            break;
1177
        }
1178
#endif
1179
    }
1180
}
1181

    
1182
/* orc & orc. */
1183
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1184
/* xor & xor. */
1185
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1186
{
1187
    gen_op_load_gpr_T0(rS(ctx->opcode));
1188
    /* Optimisation for "set to zero" case */
1189
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1190
        gen_op_load_gpr_T1(rB(ctx->opcode));
1191
        gen_op_xor();
1192
    } else {
1193
        gen_op_reset_T0();
1194
    }
1195
    gen_op_store_T0_gpr(rA(ctx->opcode));
1196
    if (unlikely(Rc(ctx->opcode) != 0))
1197
        gen_set_Rc0(ctx);
1198
}
1199
/* ori */
1200
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1201
{
1202
    target_ulong uimm = UIMM(ctx->opcode);
1203

    
1204
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1205
        /* NOP */
1206
        /* XXX: should handle special NOPs for POWER series */
1207
        return;
1208
    }
1209
    gen_op_load_gpr_T0(rS(ctx->opcode));
1210
    if (likely(uimm != 0))
1211
        gen_op_ori(uimm);
1212
    gen_op_store_T0_gpr(rA(ctx->opcode));
1213
}
1214
/* oris */
1215
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1216
{
1217
    target_ulong uimm = UIMM(ctx->opcode);
1218

    
1219
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1220
        /* NOP */
1221
        return;
1222
    }
1223
    gen_op_load_gpr_T0(rS(ctx->opcode));
1224
    if (likely(uimm != 0))
1225
        gen_op_ori(uimm << 16);
1226
    gen_op_store_T0_gpr(rA(ctx->opcode));
1227
}
1228
/* xori */
1229
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1230
{
1231
    target_ulong uimm = UIMM(ctx->opcode);
1232

    
1233
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1234
        /* NOP */
1235
        return;
1236
    }
1237
    gen_op_load_gpr_T0(rS(ctx->opcode));
1238
    if (likely(uimm != 0))
1239
        gen_op_xori(uimm);
1240
    gen_op_store_T0_gpr(rA(ctx->opcode));
1241
}
1242

    
1243
/* xoris */
1244
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1245
{
1246
    target_ulong uimm = UIMM(ctx->opcode);
1247

    
1248
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1249
        /* NOP */
1250
        return;
1251
    }
1252
    gen_op_load_gpr_T0(rS(ctx->opcode));
1253
    if (likely(uimm != 0))
1254
        gen_op_xori(uimm << 16);
1255
    gen_op_store_T0_gpr(rA(ctx->opcode));
1256
}
1257

    
1258
/* popcntb : PowerPC 2.03 specification */
1259
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_203)
1260
{
1261
    gen_op_load_gpr_T0(rS(ctx->opcode));
1262
#if defined(TARGET_PPC64)
1263
    if (ctx->sf_mode)
1264
        gen_op_popcntb_64();
1265
    else
1266
#endif
1267
        gen_op_popcntb();
1268
    gen_op_store_T0_gpr(rA(ctx->opcode));
1269
}
1270

    
1271
#if defined(TARGET_PPC64)
1272
/* extsw & extsw. */
1273
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1274
/* cntlzd */
1275
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1276
#endif
1277

    
1278
/***                             Integer rotate                            ***/
1279
/* rlwimi & rlwimi. */
1280
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1281
{
1282
    target_ulong mask;
1283
    uint32_t mb, me, sh;
1284

    
1285
    mb = MB(ctx->opcode);
1286
    me = ME(ctx->opcode);
1287
    sh = SH(ctx->opcode);
1288
    if (likely(sh == 0)) {
1289
        if (likely(mb == 0 && me == 31)) {
1290
            gen_op_load_gpr_T0(rS(ctx->opcode));
1291
            goto do_store;
1292
        } else if (likely(mb == 31 && me == 0)) {
1293
            gen_op_load_gpr_T0(rA(ctx->opcode));
1294
            goto do_store;
1295
        }
1296
        gen_op_load_gpr_T0(rS(ctx->opcode));
1297
        gen_op_load_gpr_T1(rA(ctx->opcode));
1298
        goto do_mask;
1299
    }
1300
    gen_op_load_gpr_T0(rS(ctx->opcode));
1301
    gen_op_load_gpr_T1(rA(ctx->opcode));
1302
    gen_op_rotli32_T0(SH(ctx->opcode));
1303
 do_mask:
1304
#if defined(TARGET_PPC64)
1305
    mb += 32;
1306
    me += 32;
1307
#endif
1308
    mask = MASK(mb, me);
1309
    gen_op_andi_T0(mask);
1310
    gen_op_andi_T1(~mask);
1311
    gen_op_or();
1312
 do_store:
1313
    gen_op_store_T0_gpr(rA(ctx->opcode));
1314
    if (unlikely(Rc(ctx->opcode) != 0))
1315
        gen_set_Rc0(ctx);
1316
}
1317
/* rlwinm & rlwinm. */
1318
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1319
{
1320
    uint32_t mb, me, sh;
1321

    
1322
    sh = SH(ctx->opcode);
1323
    mb = MB(ctx->opcode);
1324
    me = ME(ctx->opcode);
1325
    gen_op_load_gpr_T0(rS(ctx->opcode));
1326
    if (likely(sh == 0)) {
1327
        goto do_mask;
1328
    }
1329
    if (likely(mb == 0)) {
1330
        if (likely(me == 31)) {
1331
            gen_op_rotli32_T0(sh);
1332
            goto do_store;
1333
        } else if (likely(me == (31 - sh))) {
1334
            gen_op_sli_T0(sh);
1335
            goto do_store;
1336
        }
1337
    } else if (likely(me == 31)) {
1338
        if (likely(sh == (32 - mb))) {
1339
            gen_op_srli_T0(mb);
1340
            goto do_store;
1341
        }
1342
    }
1343
    gen_op_rotli32_T0(sh);
1344
 do_mask:
1345
#if defined(TARGET_PPC64)
1346
    mb += 32;
1347
    me += 32;
1348
#endif
1349
    gen_op_andi_T0(MASK(mb, me));
1350
 do_store:
1351
    gen_op_store_T0_gpr(rA(ctx->opcode));
1352
    if (unlikely(Rc(ctx->opcode) != 0))
1353
        gen_set_Rc0(ctx);
1354
}
1355
/* rlwnm & rlwnm. */
1356
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1357
{
1358
    uint32_t mb, me;
1359

    
1360
    mb = MB(ctx->opcode);
1361
    me = ME(ctx->opcode);
1362
    gen_op_load_gpr_T0(rS(ctx->opcode));
1363
    gen_op_load_gpr_T1(rB(ctx->opcode));
1364
    gen_op_rotl32_T0_T1();
1365
    if (unlikely(mb != 0 || me != 31)) {
1366
#if defined(TARGET_PPC64)
1367
        mb += 32;
1368
        me += 32;
1369
#endif
1370
        gen_op_andi_T0(MASK(mb, me));
1371
    }
1372
    gen_op_store_T0_gpr(rA(ctx->opcode));
1373
    if (unlikely(Rc(ctx->opcode) != 0))
1374
        gen_set_Rc0(ctx);
1375
}
1376

    
1377
#if defined(TARGET_PPC64)
1378
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1379
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1380
{                                                                             \
1381
    gen_##name(ctx, 0);                                                       \
1382
}                                                                             \
1383
GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1384
{                                                                             \
1385
    gen_##name(ctx, 1);                                                       \
1386
}
1387
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1388
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1389
{                                                                             \
1390
    gen_##name(ctx, 0, 0);                                                    \
1391
}                                                                             \
1392
GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B)            \
1393
{                                                                             \
1394
    gen_##name(ctx, 0, 1);                                                    \
1395
}                                                                             \
1396
GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1397
{                                                                             \
1398
    gen_##name(ctx, 1, 0);                                                    \
1399
}                                                                             \
1400
GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B)            \
1401
{                                                                             \
1402
    gen_##name(ctx, 1, 1);                                                    \
1403
}
1404

    
1405
static inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1406
{
1407
    if (mask >> 32)
1408
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1409
    else
1410
        gen_op_andi_T0(mask);
1411
}
1412

    
1413
static inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1414
{
1415
    if (mask >> 32)
1416
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1417
    else
1418
        gen_op_andi_T1(mask);
1419
}
1420

    
1421
static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me,
1422
                               uint32_t sh)
1423
{
1424
    gen_op_load_gpr_T0(rS(ctx->opcode));
1425
    if (likely(sh == 0)) {
1426
        goto do_mask;
1427
    }
1428
    if (likely(mb == 0)) {
1429
        if (likely(me == 63)) {
1430
            gen_op_rotli64_T0(sh);
1431
            goto do_store;
1432
        } else if (likely(me == (63 - sh))) {
1433
            gen_op_sli_T0(sh);
1434
            goto do_store;
1435
        }
1436
    } else if (likely(me == 63)) {
1437
        if (likely(sh == (64 - mb))) {
1438
            gen_op_srli_T0_64(mb);
1439
            goto do_store;
1440
        }
1441
    }
1442
    gen_op_rotli64_T0(sh);
1443
 do_mask:
1444
    gen_andi_T0_64(ctx, MASK(mb, me));
1445
 do_store:
1446
    gen_op_store_T0_gpr(rA(ctx->opcode));
1447
    if (unlikely(Rc(ctx->opcode) != 0))
1448
        gen_set_Rc0(ctx);
1449
}
1450
/* rldicl - rldicl. */
1451
static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1452
{
1453
    uint32_t sh, mb;
1454

    
1455
    sh = SH(ctx->opcode) | (shn << 5);
1456
    mb = MB(ctx->opcode) | (mbn << 5);
1457
    gen_rldinm(ctx, mb, 63, sh);
1458
}
1459
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1460
/* rldicr - rldicr. */
1461
static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1462
{
1463
    uint32_t sh, me;
1464

    
1465
    sh = SH(ctx->opcode) | (shn << 5);
1466
    me = MB(ctx->opcode) | (men << 5);
1467
    gen_rldinm(ctx, 0, me, sh);
1468
}
1469
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1470
/* rldic - rldic. */
1471
static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1472
{
1473
    uint32_t sh, mb;
1474

    
1475
    sh = SH(ctx->opcode) | (shn << 5);
1476
    mb = MB(ctx->opcode) | (mbn << 5);
1477
    gen_rldinm(ctx, mb, 63 - sh, sh);
1478
}
1479
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1480

    
1481
static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me)
1482
{
1483
    gen_op_load_gpr_T0(rS(ctx->opcode));
1484
    gen_op_load_gpr_T1(rB(ctx->opcode));
1485
    gen_op_rotl64_T0_T1();
1486
    if (unlikely(mb != 0 || me != 63)) {
1487
        gen_andi_T0_64(ctx, MASK(mb, me));
1488
    }
1489
    gen_op_store_T0_gpr(rA(ctx->opcode));
1490
    if (unlikely(Rc(ctx->opcode) != 0))
1491
        gen_set_Rc0(ctx);
1492
}
1493

    
1494
/* rldcl - rldcl. */
1495
static inline void gen_rldcl (DisasContext *ctx, int mbn)
1496
{
1497
    uint32_t mb;
1498

    
1499
    mb = MB(ctx->opcode) | (mbn << 5);
1500
    gen_rldnm(ctx, mb, 63);
1501
}
1502
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1503
/* rldcr - rldcr. */
1504
static inline void gen_rldcr (DisasContext *ctx, int men)
1505
{
1506
    uint32_t me;
1507

    
1508
    me = MB(ctx->opcode) | (men << 5);
1509
    gen_rldnm(ctx, 0, me);
1510
}
1511
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1512
/* rldimi - rldimi. */
1513
static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1514
{
1515
    uint64_t mask;
1516
    uint32_t sh, mb;
1517

    
1518
    sh = SH(ctx->opcode) | (shn << 5);
1519
    mb = MB(ctx->opcode) | (mbn << 5);
1520
    if (likely(sh == 0)) {
1521
        if (likely(mb == 0)) {
1522
            gen_op_load_gpr_T0(rS(ctx->opcode));
1523
            goto do_store;
1524
        } else if (likely(mb == 63)) {
1525
            gen_op_load_gpr_T0(rA(ctx->opcode));
1526
            goto do_store;
1527
        }
1528
        gen_op_load_gpr_T0(rS(ctx->opcode));
1529
        gen_op_load_gpr_T1(rA(ctx->opcode));
1530
        goto do_mask;
1531
    }
1532
    gen_op_load_gpr_T0(rS(ctx->opcode));
1533
    gen_op_load_gpr_T1(rA(ctx->opcode));
1534
    gen_op_rotli64_T0(sh);
1535
 do_mask:
1536
    mask = MASK(mb, 63 - sh);
1537
    gen_andi_T0_64(ctx, mask);
1538
    gen_andi_T1_64(ctx, ~mask);
1539
    gen_op_or();
1540
 do_store:
1541
    gen_op_store_T0_gpr(rA(ctx->opcode));
1542
    if (unlikely(Rc(ctx->opcode) != 0))
1543
        gen_set_Rc0(ctx);
1544
}
1545
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1546
#endif
1547

    
1548
/***                             Integer shift                             ***/
1549
/* slw & slw. */
1550
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1551
/* sraw & sraw. */
1552
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1553
/* srawi & srawi. */
1554
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1555
{
1556
    int mb, me;
1557
    gen_op_load_gpr_T0(rS(ctx->opcode));
1558
    if (SH(ctx->opcode) != 0) {
1559
        gen_op_move_T1_T0();
1560
        mb = 32 - SH(ctx->opcode);
1561
        me = 31;
1562
#if defined(TARGET_PPC64)
1563
        mb += 32;
1564
        me += 32;
1565
#endif
1566
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1567
    }
1568
    gen_op_store_T0_gpr(rA(ctx->opcode));
1569
    if (unlikely(Rc(ctx->opcode) != 0))
1570
        gen_set_Rc0(ctx);
1571
}
1572
/* srw & srw. */
1573
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1574

    
1575
#if defined(TARGET_PPC64)
1576
/* sld & sld. */
1577
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1578
/* srad & srad. */
1579
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1580
/* sradi & sradi. */
1581
static inline void gen_sradi (DisasContext *ctx, int n)
1582
{
1583
    uint64_t mask;
1584
    int sh, mb, me;
1585

    
1586
    gen_op_load_gpr_T0(rS(ctx->opcode));
1587
    sh = SH(ctx->opcode) + (n << 5);
1588
    if (sh != 0) {
1589
        gen_op_move_T1_T0();
1590
        mb = 64 - SH(ctx->opcode);
1591
        me = 63;
1592
        mask = MASK(mb, me);
1593
        gen_op_sradi(sh, mask >> 32, mask);
1594
    }
1595
    gen_op_store_T0_gpr(rA(ctx->opcode));
1596
    if (unlikely(Rc(ctx->opcode) != 0))
1597
        gen_set_Rc0(ctx);
1598
}
1599
GEN_HANDLER(sradi0, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1600
{
1601
    gen_sradi(ctx, 0);
1602
}
1603
GEN_HANDLER(sradi1, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1604
{
1605
    gen_sradi(ctx, 1);
1606
}
1607
/* srd & srd. */
1608
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1609
#endif
1610

    
1611
/***                       Floating-Point arithmetic                       ***/
1612
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, type)                     \
1613
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1614
{                                                                             \
1615
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1616
        GEN_EXCP_NO_FP(ctx);                                                  \
1617
        return;                                                               \
1618
    }                                                                         \
1619
    gen_op_reset_scrfx();                                                     \
1620
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1621
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1622
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1623
    gen_op_f##op();                                                           \
1624
    if (isfloat) {                                                            \
1625
        gen_op_frsp();                                                        \
1626
    }                                                                         \
1627
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1628
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1629
        gen_op_set_Rc1();                                                     \
1630
}
1631

    
1632
#define GEN_FLOAT_ACB(name, op2, type)                                        \
1633
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, type);                               \
1634
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type);
1635

    
1636
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
1637
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1638
{                                                                             \
1639
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1640
        GEN_EXCP_NO_FP(ctx);                                                  \
1641
        return;                                                               \
1642
    }                                                                         \
1643
    gen_op_reset_scrfx();                                                     \
1644
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1645
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1646
    gen_op_f##op();                                                           \
1647
    if (isfloat) {                                                            \
1648
        gen_op_frsp();                                                        \
1649
    }                                                                         \
1650
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1651
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1652
        gen_op_set_Rc1();                                                     \
1653
}
1654
#define GEN_FLOAT_AB(name, op2, inval)                                        \
1655
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
1656
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1657

    
1658
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
1659
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1660
{                                                                             \
1661
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1662
        GEN_EXCP_NO_FP(ctx);                                                  \
1663
        return;                                                               \
1664
    }                                                                         \
1665
    gen_op_reset_scrfx();                                                     \
1666
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1667
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1668
    gen_op_f##op();                                                           \
1669
    if (isfloat) {                                                            \
1670
        gen_op_frsp();                                                        \
1671
    }                                                                         \
1672
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1673
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1674
        gen_op_set_Rc1();                                                     \
1675
}
1676
#define GEN_FLOAT_AC(name, op2, inval)                                        \
1677
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
1678
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1679

    
1680
#define GEN_FLOAT_B(name, op2, op3, type)                                     \
1681
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1682
{                                                                             \
1683
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1684
        GEN_EXCP_NO_FP(ctx);                                                  \
1685
        return;                                                               \
1686
    }                                                                         \
1687
    gen_op_reset_scrfx();                                                     \
1688
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1689
    gen_op_f##name();                                                         \
1690
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1691
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1692
        gen_op_set_Rc1();                                                     \
1693
}
1694

    
1695
#define GEN_FLOAT_BS(name, op1, op2, type)                                    \
1696
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1697
{                                                                             \
1698
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1699
        GEN_EXCP_NO_FP(ctx);                                                  \
1700
        return;                                                               \
1701
    }                                                                         \
1702
    gen_op_reset_scrfx();                                                     \
1703
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1704
    gen_op_f##name();                                                         \
1705
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1706
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1707
        gen_op_set_Rc1();                                                     \
1708
}
1709

    
1710
/* fadd - fadds */
1711
GEN_FLOAT_AB(add, 0x15, 0x000007C0);
1712
/* fdiv - fdivs */
1713
GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1714
/* fmul - fmuls */
1715
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1716

    
1717
/* fre */
1718
GEN_FLOAT_BS(re, 0x3F, 0x18, PPC_FLOAT_EXT);
1719

    
1720
/* fres */
1721
GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
1722

    
1723
/* frsqrte */
1724
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, PPC_FLOAT_FRSQRTE);
1725

    
1726
/* fsel */
1727
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, PPC_FLOAT_FSEL);
1728
/* fsub - fsubs */
1729
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1730
/* Optional: */
1731
/* fsqrt */
1732
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1733
{
1734
    if (unlikely(!ctx->fpu_enabled)) {
1735
        GEN_EXCP_NO_FP(ctx);
1736
        return;
1737
    }
1738
    gen_op_reset_scrfx();
1739
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1740
    gen_op_fsqrt();
1741
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1742
    if (unlikely(Rc(ctx->opcode) != 0))
1743
        gen_op_set_Rc1();
1744
}
1745

    
1746
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1747
{
1748
    if (unlikely(!ctx->fpu_enabled)) {
1749
        GEN_EXCP_NO_FP(ctx);
1750
        return;
1751
    }
1752
    gen_op_reset_scrfx();
1753
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1754
    gen_op_fsqrt();
1755
    gen_op_frsp();
1756
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1757
    if (unlikely(Rc(ctx->opcode) != 0))
1758
        gen_op_set_Rc1();
1759
}
1760

    
1761
/***                     Floating-Point multiply-and-add                   ***/
1762
/* fmadd - fmadds */
1763
GEN_FLOAT_ACB(madd, 0x1D, PPC_FLOAT);
1764
/* fmsub - fmsubs */
1765
GEN_FLOAT_ACB(msub, 0x1C, PPC_FLOAT);
1766
/* fnmadd - fnmadds */
1767
GEN_FLOAT_ACB(nmadd, 0x1F, PPC_FLOAT);
1768
/* fnmsub - fnmsubs */
1769
GEN_FLOAT_ACB(nmsub, 0x1E, PPC_FLOAT);
1770

    
1771
/***                     Floating-Point round & convert                    ***/
1772
/* fctiw */
1773
GEN_FLOAT_B(ctiw, 0x0E, 0x00, PPC_FLOAT);
1774
/* fctiwz */
1775
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, PPC_FLOAT);
1776
/* frsp */
1777
GEN_FLOAT_B(rsp, 0x0C, 0x00, PPC_FLOAT);
1778
#if defined(TARGET_PPC64)
1779
/* fcfid */
1780
GEN_FLOAT_B(cfid, 0x0E, 0x1A, PPC_64B);
1781
/* fctid */
1782
GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
1783
/* fctidz */
1784
GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
1785
#endif
1786

    
1787
/* frin */
1788
GEN_FLOAT_B(rin, 0x08, 0x0C, PPC_FLOAT_EXT);
1789
/* friz */
1790
GEN_FLOAT_B(riz, 0x08, 0x0D, PPC_FLOAT_EXT);
1791
/* frip */
1792
GEN_FLOAT_B(rip, 0x08, 0x0E, PPC_FLOAT_EXT);
1793
/* frim */
1794
GEN_FLOAT_B(rim, 0x08, 0x0F, PPC_FLOAT_EXT);
1795

    
1796
/***                         Floating-Point compare                        ***/
1797
/* fcmpo */
1798
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1799
{
1800
    if (unlikely(!ctx->fpu_enabled)) {
1801
        GEN_EXCP_NO_FP(ctx);
1802
        return;
1803
    }
1804
    gen_op_reset_scrfx();
1805
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1806
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1807
    gen_op_fcmpo();
1808
    gen_op_store_T0_crf(crfD(ctx->opcode));
1809
}
1810

    
1811
/* fcmpu */
1812
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1813
{
1814
    if (unlikely(!ctx->fpu_enabled)) {
1815
        GEN_EXCP_NO_FP(ctx);
1816
        return;
1817
    }
1818
    gen_op_reset_scrfx();
1819
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1820
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1821
    gen_op_fcmpu();
1822
    gen_op_store_T0_crf(crfD(ctx->opcode));
1823
}
1824

    
1825
/***                         Floating-point move                           ***/
1826
/* fabs */
1827
GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT);
1828

    
1829
/* fmr  - fmr. */
1830
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1831
{
1832
    if (unlikely(!ctx->fpu_enabled)) {
1833
        GEN_EXCP_NO_FP(ctx);
1834
        return;
1835
    }
1836
    gen_op_reset_scrfx();
1837
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1838
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1839
    if (unlikely(Rc(ctx->opcode) != 0))
1840
        gen_op_set_Rc1();
1841
}
1842

    
1843
/* fnabs */
1844
GEN_FLOAT_B(nabs, 0x08, 0x04, PPC_FLOAT);
1845
/* fneg */
1846
GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT);
1847

    
1848
/***                  Floating-Point status & ctrl register                ***/
1849
/* mcrfs */
1850
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1851
{
1852
    if (unlikely(!ctx->fpu_enabled)) {
1853
        GEN_EXCP_NO_FP(ctx);
1854
        return;
1855
    }
1856
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
1857
    gen_op_store_T0_crf(crfD(ctx->opcode));
1858
    gen_op_clear_fpscr(crfS(ctx->opcode));
1859
}
1860

    
1861
/* mffs */
1862
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1863
{
1864
    if (unlikely(!ctx->fpu_enabled)) {
1865
        GEN_EXCP_NO_FP(ctx);
1866
        return;
1867
    }
1868
    gen_op_load_fpscr();
1869
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1870
    if (unlikely(Rc(ctx->opcode) != 0))
1871
        gen_op_set_Rc1();
1872
}
1873

    
1874
/* mtfsb0 */
1875
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1876
{
1877
    uint8_t crb;
1878

    
1879
    if (unlikely(!ctx->fpu_enabled)) {
1880
        GEN_EXCP_NO_FP(ctx);
1881
        return;
1882
    }
1883
    crb = crbD(ctx->opcode) >> 2;
1884
    gen_op_load_fpscr_T0(crb);
1885
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1886
    gen_op_store_T0_fpscr(crb);
1887
    if (unlikely(Rc(ctx->opcode) != 0))
1888
        gen_op_set_Rc1();
1889
}
1890

    
1891
/* mtfsb1 */
1892
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1893
{
1894
    uint8_t crb;
1895

    
1896
    if (unlikely(!ctx->fpu_enabled)) {
1897
        GEN_EXCP_NO_FP(ctx);
1898
        return;
1899
    }
1900
    crb = crbD(ctx->opcode) >> 2;
1901
    gen_op_load_fpscr_T0(crb);
1902
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1903
    gen_op_store_T0_fpscr(crb);
1904
    if (unlikely(Rc(ctx->opcode) != 0))
1905
        gen_op_set_Rc1();
1906
}
1907

    
1908
/* mtfsf */
1909
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1910
{
1911
    if (unlikely(!ctx->fpu_enabled)) {
1912
        GEN_EXCP_NO_FP(ctx);
1913
        return;
1914
    }
1915
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1916
    gen_op_store_fpscr(FM(ctx->opcode));
1917
    if (unlikely(Rc(ctx->opcode) != 0))
1918
        gen_op_set_Rc1();
1919
}
1920

    
1921
/* mtfsfi */
1922
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1923
{
1924
    if (unlikely(!ctx->fpu_enabled)) {
1925
        GEN_EXCP_NO_FP(ctx);
1926
        return;
1927
    }
1928
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1929
    if (unlikely(Rc(ctx->opcode) != 0))
1930
        gen_op_set_Rc1();
1931
}
1932

    
1933
/***                           Addressing modes                            ***/
1934
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1935
static inline void gen_addr_imm_index (DisasContext *ctx, target_long maskl)
1936
{
1937
    target_long simm = SIMM(ctx->opcode);
1938

    
1939
    simm &= ~maskl;
1940
    if (rA(ctx->opcode) == 0) {
1941
        gen_set_T0(simm);
1942
    } else {
1943
        gen_op_load_gpr_T0(rA(ctx->opcode));
1944
        if (likely(simm != 0))
1945
            gen_op_addi(simm);
1946
    }
1947
#ifdef DEBUG_MEMORY_ACCESSES
1948
    gen_op_print_mem_EA();
1949
#endif
1950
}
1951

    
1952
static inline void gen_addr_reg_index (DisasContext *ctx)
1953
{
1954
    if (rA(ctx->opcode) == 0) {
1955
        gen_op_load_gpr_T0(rB(ctx->opcode));
1956
    } else {
1957
        gen_op_load_gpr_T0(rA(ctx->opcode));
1958
        gen_op_load_gpr_T1(rB(ctx->opcode));
1959
        gen_op_add();
1960
    }
1961
#ifdef DEBUG_MEMORY_ACCESSES
1962
    gen_op_print_mem_EA();
1963
#endif
1964
}
1965

    
1966
static inline void gen_addr_register (DisasContext *ctx)
1967
{
1968
    if (rA(ctx->opcode) == 0) {
1969
        gen_op_reset_T0();
1970
    } else {
1971
        gen_op_load_gpr_T0(rA(ctx->opcode));
1972
    }
1973
#ifdef DEBUG_MEMORY_ACCESSES
1974
    gen_op_print_mem_EA();
1975
#endif
1976
}
1977

    
1978
/***                             Integer load                              ***/
1979
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1980
#if defined(CONFIG_USER_ONLY)
1981
#if defined(TARGET_PPC64)
1982
#define OP_LD_TABLE(width)                                                    \
1983
static GenOpFunc *gen_op_l##width[] = {                                       \
1984
    &gen_op_l##width##_raw,                                                   \
1985
    &gen_op_l##width##_le_raw,                                                \
1986
    &gen_op_l##width##_64_raw,                                                \
1987
    &gen_op_l##width##_le_64_raw,                                             \
1988
};
1989
#define OP_ST_TABLE(width)                                                    \
1990
static GenOpFunc *gen_op_st##width[] = {                                      \
1991
    &gen_op_st##width##_raw,                                                  \
1992
    &gen_op_st##width##_le_raw,                                               \
1993
    &gen_op_st##width##_64_raw,                                               \
1994
    &gen_op_st##width##_le_64_raw,                                            \
1995
};
1996
/* Byte access routine are endian safe */
1997
#define gen_op_stb_le_64_raw gen_op_stb_64_raw
1998
#define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1999
#else
2000
#define OP_LD_TABLE(width)                                                    \
2001
static GenOpFunc *gen_op_l##width[] = {                                       \
2002
    &gen_op_l##width##_raw,                                                   \
2003
    &gen_op_l##width##_le_raw,                                                \
2004
};
2005
#define OP_ST_TABLE(width)                                                    \
2006
static GenOpFunc *gen_op_st##width[] = {                                      \
2007
    &gen_op_st##width##_raw,                                                  \
2008
    &gen_op_st##width##_le_raw,                                               \
2009
};
2010
#endif
2011
/* Byte access routine are endian safe */
2012
#define gen_op_stb_le_raw gen_op_stb_raw
2013
#define gen_op_lbz_le_raw gen_op_lbz_raw
2014
#else
2015
#if defined(TARGET_PPC64)
2016
#define OP_LD_TABLE(width)                                                    \
2017
static GenOpFunc *gen_op_l##width[] = {                                       \
2018
    &gen_op_l##width##_user,                                                  \
2019
    &gen_op_l##width##_le_user,                                               \
2020
    &gen_op_l##width##_kernel,                                                \
2021
    &gen_op_l##width##_le_kernel,                                             \
2022
    &gen_op_l##width##_64_user,                                               \
2023
    &gen_op_l##width##_le_64_user,                                            \
2024
    &gen_op_l##width##_64_kernel,                                             \
2025
    &gen_op_l##width##_le_64_kernel,                                          \
2026
};
2027
#define OP_ST_TABLE(width)                                                    \
2028
static GenOpFunc *gen_op_st##width[] = {                                      \
2029
    &gen_op_st##width##_user,                                                 \
2030
    &gen_op_st##width##_le_user,                                              \
2031
    &gen_op_st##width##_kernel,                                               \
2032
    &gen_op_st##width##_le_kernel,                                            \
2033
    &gen_op_st##width##_64_user,                                              \
2034
    &gen_op_st##width##_le_64_user,                                           \
2035
    &gen_op_st##width##_64_kernel,                                            \
2036
    &gen_op_st##width##_le_64_kernel,                                         \
2037
};
2038
/* Byte access routine are endian safe */
2039
#define gen_op_stb_le_64_user gen_op_stb_64_user
2040
#define gen_op_lbz_le_64_user gen_op_lbz_64_user
2041
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
2042
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
2043
#else
2044
#define OP_LD_TABLE(width)                                                    \
2045
static GenOpFunc *gen_op_l##width[] = {                                       \
2046
    &gen_op_l##width##_user,                                                  \
2047
    &gen_op_l##width##_le_user,                                               \
2048
    &gen_op_l##width##_kernel,                                                \
2049
    &gen_op_l##width##_le_kernel,                                             \
2050
};
2051
#define OP_ST_TABLE(width)                                                    \
2052
static GenOpFunc *gen_op_st##width[] = {                                      \
2053
    &gen_op_st##width##_user,                                                 \
2054
    &gen_op_st##width##_le_user,                                              \
2055
    &gen_op_st##width##_kernel,                                               \
2056
    &gen_op_st##width##_le_kernel,                                            \
2057
};
2058
#endif
2059
/* Byte access routine are endian safe */
2060
#define gen_op_stb_le_user gen_op_stb_user
2061
#define gen_op_lbz_le_user gen_op_lbz_user
2062
#define gen_op_stb_le_kernel gen_op_stb_kernel
2063
#define gen_op_lbz_le_kernel gen_op_lbz_kernel
2064
#endif
2065

    
2066
#define GEN_LD(width, opc, type)                                              \
2067
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2068
{                                                                             \
2069
    gen_addr_imm_index(ctx, 0);                                               \
2070
    op_ldst(l##width);                                                        \
2071
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2072
}
2073

    
2074
#define GEN_LDU(width, opc, type)                                             \
2075
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2076
{                                                                             \
2077
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2078
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2079
        GEN_EXCP_INVAL(ctx);                                                  \
2080
        return;                                                               \
2081
    }                                                                         \
2082
    if (type == PPC_64B)                                                      \
2083
        gen_addr_imm_index(ctx, 0x03);                                        \
2084
    else                                                                      \
2085
        gen_addr_imm_index(ctx, 0);                                           \
2086
    op_ldst(l##width);                                                        \
2087
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2088
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2089
}
2090

    
2091
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2092
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2093
{                                                                             \
2094
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2095
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2096
        GEN_EXCP_INVAL(ctx);                                                  \
2097
        return;                                                               \
2098
    }                                                                         \
2099
    gen_addr_reg_index(ctx);                                                  \
2100
    op_ldst(l##width);                                                        \
2101
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2102
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2103
}
2104

    
2105
#define GEN_LDX(width, opc2, opc3, type)                                      \
2106
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2107
{                                                                             \
2108
    gen_addr_reg_index(ctx);                                                  \
2109
    op_ldst(l##width);                                                        \
2110
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2111
}
2112

    
2113
#define GEN_LDS(width, op, type)                                              \
2114
OP_LD_TABLE(width);                                                           \
2115
GEN_LD(width, op | 0x20, type);                                               \
2116
GEN_LDU(width, op | 0x21, type);                                              \
2117
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2118
GEN_LDX(width, 0x17, op | 0x00, type)
2119

    
2120
/* lbz lbzu lbzux lbzx */
2121
GEN_LDS(bz, 0x02, PPC_INTEGER);
2122
/* lha lhau lhaux lhax */
2123
GEN_LDS(ha, 0x0A, PPC_INTEGER);
2124
/* lhz lhzu lhzux lhzx */
2125
GEN_LDS(hz, 0x08, PPC_INTEGER);
2126
/* lwz lwzu lwzux lwzx */
2127
GEN_LDS(wz, 0x00, PPC_INTEGER);
2128
#if defined(TARGET_PPC64)
2129
OP_LD_TABLE(wa);
2130
OP_LD_TABLE(d);
2131
/* lwaux */
2132
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
2133
/* lwax */
2134
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
2135
/* ldux */
2136
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
2137
/* ldx */
2138
GEN_LDX(d, 0x15, 0x00, PPC_64B);
2139
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2140
{
2141
    if (Rc(ctx->opcode)) {
2142
        if (unlikely(rA(ctx->opcode) == 0 ||
2143
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2144
            GEN_EXCP_INVAL(ctx);
2145
            return;
2146
        }
2147
    }
2148
    gen_addr_imm_index(ctx, 0x03);
2149
    if (ctx->opcode & 0x02) {
2150
        /* lwa (lwau is undefined) */
2151
        op_ldst(lwa);
2152
    } else {
2153
        /* ld - ldu */
2154
        op_ldst(ld);
2155
    }
2156
    gen_op_store_T1_gpr(rD(ctx->opcode));
2157
    if (Rc(ctx->opcode))
2158
        gen_op_store_T0_gpr(rA(ctx->opcode));
2159
}
2160
/* lq */
2161
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2162
{
2163
#if defined(CONFIG_USER_ONLY)
2164
    GEN_EXCP_PRIVOPC(ctx);
2165
#else
2166
    int ra, rd;
2167

    
2168
    /* Restore CPU state */
2169
    if (unlikely(ctx->supervisor == 0)) {
2170
        GEN_EXCP_PRIVOPC(ctx);
2171
        return;
2172
    }
2173
    ra = rA(ctx->opcode);
2174
    rd = rD(ctx->opcode);
2175
    if (unlikely((rd & 1) || rd == ra)) {
2176
        GEN_EXCP_INVAL(ctx);
2177
        return;
2178
    }
2179
    if (unlikely(ctx->mem_idx & 1)) {
2180
        /* Little-endian mode is not handled */
2181
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2182
        return;
2183
    }
2184
    gen_addr_imm_index(ctx, 0x0F);
2185
    op_ldst(ld);
2186
    gen_op_store_T1_gpr(rd);
2187
    gen_op_addi(8);
2188
    op_ldst(ld);
2189
    gen_op_store_T1_gpr(rd + 1);
2190
#endif
2191
}
2192
#endif
2193

    
2194
/***                              Integer store                            ***/
2195
#define GEN_ST(width, opc, type)                                              \
2196
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2197
{                                                                             \
2198
    gen_addr_imm_index(ctx, 0);                                               \
2199
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2200
    op_ldst(st##width);                                                       \
2201
}
2202

    
2203
#define GEN_STU(width, opc, type)                                             \
2204
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2205
{                                                                             \
2206
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2207
        GEN_EXCP_INVAL(ctx);                                                  \
2208
        return;                                                               \
2209
    }                                                                         \
2210
    if (type == PPC_64B)                                                      \
2211
        gen_addr_imm_index(ctx, 0x03);                                        \
2212
    else                                                                      \
2213
        gen_addr_imm_index(ctx, 0);                                           \
2214
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2215
    op_ldst(st##width);                                                       \
2216
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2217
}
2218

    
2219
#define GEN_STUX(width, opc2, opc3, type)                                     \
2220
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2221
{                                                                             \
2222
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2223
        GEN_EXCP_INVAL(ctx);                                                  \
2224
        return;                                                               \
2225
    }                                                                         \
2226
    gen_addr_reg_index(ctx);                                                  \
2227
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2228
    op_ldst(st##width);                                                       \
2229
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2230
}
2231

    
2232
#define GEN_STX(width, opc2, opc3, type)                                      \
2233
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2234
{                                                                             \
2235
    gen_addr_reg_index(ctx);                                                  \
2236
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2237
    op_ldst(st##width);                                                       \
2238
}
2239

    
2240
#define GEN_STS(width, op, type)                                              \
2241
OP_ST_TABLE(width);                                                           \
2242
GEN_ST(width, op | 0x20, type);                                               \
2243
GEN_STU(width, op | 0x21, type);                                              \
2244
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2245
GEN_STX(width, 0x17, op | 0x00, type)
2246

    
2247
/* stb stbu stbux stbx */
2248
GEN_STS(b, 0x06, PPC_INTEGER);
2249
/* sth sthu sthux sthx */
2250
GEN_STS(h, 0x0C, PPC_INTEGER);
2251
/* stw stwu stwux stwx */
2252
GEN_STS(w, 0x04, PPC_INTEGER);
2253
#if defined(TARGET_PPC64)
2254
OP_ST_TABLE(d);
2255
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2256
GEN_STX(d, 0x15, 0x04, PPC_64B);
2257
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2258
{
2259
    int rs;
2260

    
2261
    rs = rS(ctx->opcode);
2262
    if ((ctx->opcode & 0x3) == 0x2) {
2263
#if defined(CONFIG_USER_ONLY)
2264
        GEN_EXCP_PRIVOPC(ctx);
2265
#else
2266
        /* stq */
2267
        if (unlikely(ctx->supervisor == 0)) {
2268
            GEN_EXCP_PRIVOPC(ctx);
2269
            return;
2270
        }
2271
        if (unlikely(rs & 1)) {
2272
            GEN_EXCP_INVAL(ctx);
2273
            return;
2274
        }
2275
        if (unlikely(ctx->mem_idx & 1)) {
2276
            /* Little-endian mode is not handled */
2277
            GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2278
            return;
2279
        }
2280
        gen_addr_imm_index(ctx, 0x03);
2281
        gen_op_load_gpr_T1(rs);
2282
        op_ldst(std);
2283
        gen_op_addi(8);
2284
        gen_op_load_gpr_T1(rs + 1);
2285
        op_ldst(std);
2286
#endif
2287
    } else {
2288
        /* std / stdu */
2289
        if (Rc(ctx->opcode)) {
2290
            if (unlikely(rA(ctx->opcode) == 0)) {
2291
                GEN_EXCP_INVAL(ctx);
2292
                return;
2293
            }
2294
        }
2295
        gen_addr_imm_index(ctx, 0x03);
2296
        gen_op_load_gpr_T1(rs);
2297
        op_ldst(std);
2298
        if (Rc(ctx->opcode))
2299
            gen_op_store_T0_gpr(rA(ctx->opcode));
2300
    }
2301
}
2302
#endif
2303
/***                Integer load and store with byte reverse               ***/
2304
/* lhbrx */
2305
OP_LD_TABLE(hbr);
2306
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2307
/* lwbrx */
2308
OP_LD_TABLE(wbr);
2309
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2310
/* sthbrx */
2311
OP_ST_TABLE(hbr);
2312
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2313
/* stwbrx */
2314
OP_ST_TABLE(wbr);
2315
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2316

    
2317
/***                    Integer load and store multiple                    ***/
2318
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2319
#if defined(TARGET_PPC64)
2320
#if defined(CONFIG_USER_ONLY)
2321
static GenOpFunc1 *gen_op_lmw[] = {
2322
    &gen_op_lmw_raw,
2323
    &gen_op_lmw_le_raw,
2324
    &gen_op_lmw_64_raw,
2325
    &gen_op_lmw_le_64_raw,
2326
};
2327
static GenOpFunc1 *gen_op_stmw[] = {
2328
    &gen_op_stmw_64_raw,
2329
    &gen_op_stmw_le_64_raw,
2330
};
2331
#else
2332
static GenOpFunc1 *gen_op_lmw[] = {
2333
    &gen_op_lmw_user,
2334
    &gen_op_lmw_le_user,
2335
    &gen_op_lmw_kernel,
2336
    &gen_op_lmw_le_kernel,
2337
    &gen_op_lmw_64_user,
2338
    &gen_op_lmw_le_64_user,
2339
    &gen_op_lmw_64_kernel,
2340
    &gen_op_lmw_le_64_kernel,
2341
};
2342
static GenOpFunc1 *gen_op_stmw[] = {
2343
    &gen_op_stmw_user,
2344
    &gen_op_stmw_le_user,
2345
    &gen_op_stmw_kernel,
2346
    &gen_op_stmw_le_kernel,
2347
    &gen_op_stmw_64_user,
2348
    &gen_op_stmw_le_64_user,
2349
    &gen_op_stmw_64_kernel,
2350
    &gen_op_stmw_le_64_kernel,
2351
};
2352
#endif
2353
#else
2354
#if defined(CONFIG_USER_ONLY)
2355
static GenOpFunc1 *gen_op_lmw[] = {
2356
    &gen_op_lmw_raw,
2357
    &gen_op_lmw_le_raw,
2358
};
2359
static GenOpFunc1 *gen_op_stmw[] = {
2360
    &gen_op_stmw_raw,
2361
    &gen_op_stmw_le_raw,
2362
};
2363
#else
2364
static GenOpFunc1 *gen_op_lmw[] = {
2365
    &gen_op_lmw_user,
2366
    &gen_op_lmw_le_user,
2367
    &gen_op_lmw_kernel,
2368
    &gen_op_lmw_le_kernel,
2369
};
2370
static GenOpFunc1 *gen_op_stmw[] = {
2371
    &gen_op_stmw_user,
2372
    &gen_op_stmw_le_user,
2373
    &gen_op_stmw_kernel,
2374
    &gen_op_stmw_le_kernel,
2375
};
2376
#endif
2377
#endif
2378

    
2379
/* lmw */
2380
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2381
{
2382
    /* NIP cannot be restored if the memory exception comes from an helper */
2383
    gen_update_nip(ctx, ctx->nip - 4);
2384
    gen_addr_imm_index(ctx, 0);
2385
    op_ldstm(lmw, rD(ctx->opcode));
2386
}
2387

    
2388
/* stmw */
2389
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2390
{
2391
    /* NIP cannot be restored if the memory exception comes from an helper */
2392
    gen_update_nip(ctx, ctx->nip - 4);
2393
    gen_addr_imm_index(ctx, 0);
2394
    op_ldstm(stmw, rS(ctx->opcode));
2395
}
2396

    
2397
/***                    Integer load and store strings                     ***/
2398
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2399
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2400
#if defined(TARGET_PPC64)
2401
#if defined(CONFIG_USER_ONLY)
2402
static GenOpFunc1 *gen_op_lswi[] = {
2403
    &gen_op_lswi_raw,
2404
    &gen_op_lswi_le_raw,
2405
    &gen_op_lswi_64_raw,
2406
    &gen_op_lswi_le_64_raw,
2407
};
2408
static GenOpFunc3 *gen_op_lswx[] = {
2409
    &gen_op_lswx_raw,
2410
    &gen_op_lswx_le_raw,
2411
    &gen_op_lswx_64_raw,
2412
    &gen_op_lswx_le_64_raw,
2413
};
2414
static GenOpFunc1 *gen_op_stsw[] = {
2415
    &gen_op_stsw_raw,
2416
    &gen_op_stsw_le_raw,
2417
    &gen_op_stsw_64_raw,
2418
    &gen_op_stsw_le_64_raw,
2419
};
2420
#else
2421
static GenOpFunc1 *gen_op_lswi[] = {
2422
    &gen_op_lswi_user,
2423
    &gen_op_lswi_le_user,
2424
    &gen_op_lswi_kernel,
2425
    &gen_op_lswi_le_kernel,
2426
    &gen_op_lswi_64_user,
2427
    &gen_op_lswi_le_64_user,
2428
    &gen_op_lswi_64_kernel,
2429
    &gen_op_lswi_le_64_kernel,
2430
};
2431
static GenOpFunc3 *gen_op_lswx[] = {
2432
    &gen_op_lswx_user,
2433
    &gen_op_lswx_le_user,
2434
    &gen_op_lswx_kernel,
2435
    &gen_op_lswx_le_kernel,
2436
    &gen_op_lswx_64_user,
2437
    &gen_op_lswx_le_64_user,
2438
    &gen_op_lswx_64_kernel,
2439
    &gen_op_lswx_le_64_kernel,
2440
};
2441
static GenOpFunc1 *gen_op_stsw[] = {
2442
    &gen_op_stsw_user,
2443
    &gen_op_stsw_le_user,
2444
    &gen_op_stsw_kernel,
2445
    &gen_op_stsw_le_kernel,
2446
    &gen_op_stsw_64_user,
2447
    &gen_op_stsw_le_64_user,
2448
    &gen_op_stsw_64_kernel,
2449
    &gen_op_stsw_le_64_kernel,
2450
};
2451
#endif
2452
#else
2453
#if defined(CONFIG_USER_ONLY)
2454
static GenOpFunc1 *gen_op_lswi[] = {
2455
    &gen_op_lswi_raw,
2456
    &gen_op_lswi_le_raw,
2457
};
2458
static GenOpFunc3 *gen_op_lswx[] = {
2459
    &gen_op_lswx_raw,
2460
    &gen_op_lswx_le_raw,
2461
};
2462
static GenOpFunc1 *gen_op_stsw[] = {
2463
    &gen_op_stsw_raw,
2464
    &gen_op_stsw_le_raw,
2465
};
2466
#else
2467
static GenOpFunc1 *gen_op_lswi[] = {
2468
    &gen_op_lswi_user,
2469
    &gen_op_lswi_le_user,
2470
    &gen_op_lswi_kernel,
2471
    &gen_op_lswi_le_kernel,
2472
};
2473
static GenOpFunc3 *gen_op_lswx[] = {
2474
    &gen_op_lswx_user,
2475
    &gen_op_lswx_le_user,
2476
    &gen_op_lswx_kernel,
2477
    &gen_op_lswx_le_kernel,
2478
};
2479
static GenOpFunc1 *gen_op_stsw[] = {
2480
    &gen_op_stsw_user,
2481
    &gen_op_stsw_le_user,
2482
    &gen_op_stsw_kernel,
2483
    &gen_op_stsw_le_kernel,
2484
};
2485
#endif
2486
#endif
2487

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

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

    
2518
/* lswx */
2519
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
2520
{
2521
    int ra = rA(ctx->opcode);
2522
    int rb = rB(ctx->opcode);
2523

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

    
2534
/* stswi */
2535
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
2536
{
2537
    int nb = NB(ctx->opcode);
2538

    
2539
    /* NIP cannot be restored if the memory exception comes from an helper */
2540
    gen_update_nip(ctx, ctx->nip - 4);
2541
    gen_addr_register(ctx);
2542
    if (nb == 0)
2543
        nb = 32;
2544
    gen_op_set_T1(nb);
2545
    op_ldsts(stsw, rS(ctx->opcode));
2546
}
2547

    
2548
/* stswx */
2549
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
2550
{
2551
    /* NIP cannot be restored if the memory exception comes from an helper */
2552
    gen_update_nip(ctx, ctx->nip - 4);
2553
    gen_addr_reg_index(ctx);
2554
    gen_op_load_xer_bc();
2555
    op_ldsts(stsw, rS(ctx->opcode));
2556
}
2557

    
2558
/***                        Memory synchronisation                         ***/
2559
/* eieio */
2560
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2561
{
2562
}
2563

    
2564
/* isync */
2565
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2566
{
2567
    GEN_STOP(ctx);
2568
}
2569

    
2570
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2571
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2572
#if defined(TARGET_PPC64)
2573
#if defined(CONFIG_USER_ONLY)
2574
static GenOpFunc *gen_op_lwarx[] = {
2575
    &gen_op_lwarx_raw,
2576
    &gen_op_lwarx_le_raw,
2577
    &gen_op_lwarx_64_raw,
2578
    &gen_op_lwarx_le_64_raw,
2579
};
2580
static GenOpFunc *gen_op_stwcx[] = {
2581
    &gen_op_stwcx_raw,
2582
    &gen_op_stwcx_le_raw,
2583
    &gen_op_stwcx_64_raw,
2584
    &gen_op_stwcx_le_64_raw,
2585
};
2586
#else
2587
static GenOpFunc *gen_op_lwarx[] = {
2588
    &gen_op_lwarx_user,
2589
    &gen_op_lwarx_le_user,
2590
    &gen_op_lwarx_kernel,
2591
    &gen_op_lwarx_le_kernel,
2592
    &gen_op_lwarx_64_user,
2593
    &gen_op_lwarx_le_64_user,
2594
    &gen_op_lwarx_64_kernel,
2595
    &gen_op_lwarx_le_64_kernel,
2596
};
2597
static GenOpFunc *gen_op_stwcx[] = {
2598
    &gen_op_stwcx_user,
2599
    &gen_op_stwcx_le_user,
2600
    &gen_op_stwcx_kernel,
2601
    &gen_op_stwcx_le_kernel,
2602
    &gen_op_stwcx_64_user,
2603
    &gen_op_stwcx_le_64_user,
2604
    &gen_op_stwcx_64_kernel,
2605
    &gen_op_stwcx_le_64_kernel,
2606
};
2607
#endif
2608
#else
2609
#if defined(CONFIG_USER_ONLY)
2610
static GenOpFunc *gen_op_lwarx[] = {
2611
    &gen_op_lwarx_raw,
2612
    &gen_op_lwarx_le_raw,
2613
};
2614
static GenOpFunc *gen_op_stwcx[] = {
2615
    &gen_op_stwcx_raw,
2616
    &gen_op_stwcx_le_raw,
2617
};
2618
#else
2619
static GenOpFunc *gen_op_lwarx[] = {
2620
    &gen_op_lwarx_user,
2621
    &gen_op_lwarx_le_user,
2622
    &gen_op_lwarx_kernel,
2623
    &gen_op_lwarx_le_kernel,
2624
};
2625
static GenOpFunc *gen_op_stwcx[] = {
2626
    &gen_op_stwcx_user,
2627
    &gen_op_stwcx_le_user,
2628
    &gen_op_stwcx_kernel,
2629
    &gen_op_stwcx_le_kernel,
2630
};
2631
#endif
2632
#endif
2633

    
2634
/* lwarx */
2635
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2636
{
2637
    gen_addr_reg_index(ctx);
2638
    op_lwarx();
2639
    gen_op_store_T1_gpr(rD(ctx->opcode));
2640
}
2641

    
2642
/* stwcx. */
2643
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2644
{
2645
    gen_addr_reg_index(ctx);
2646
    gen_op_load_gpr_T1(rS(ctx->opcode));
2647
    op_stwcx();
2648
}
2649

    
2650
#if defined(TARGET_PPC64)
2651
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2652
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2653
#if defined(CONFIG_USER_ONLY)
2654
static GenOpFunc *gen_op_ldarx[] = {
2655
    &gen_op_ldarx_raw,
2656
    &gen_op_ldarx_le_raw,
2657
    &gen_op_ldarx_64_raw,
2658
    &gen_op_ldarx_le_64_raw,
2659
};
2660
static GenOpFunc *gen_op_stdcx[] = {
2661
    &gen_op_stdcx_raw,
2662
    &gen_op_stdcx_le_raw,
2663
    &gen_op_stdcx_64_raw,
2664
    &gen_op_stdcx_le_64_raw,
2665
};
2666
#else
2667
static GenOpFunc *gen_op_ldarx[] = {
2668
    &gen_op_ldarx_user,
2669
    &gen_op_ldarx_le_user,
2670
    &gen_op_ldarx_kernel,
2671
    &gen_op_ldarx_le_kernel,
2672
    &gen_op_ldarx_64_user,
2673
    &gen_op_ldarx_le_64_user,
2674
    &gen_op_ldarx_64_kernel,
2675
    &gen_op_ldarx_le_64_kernel,
2676
};
2677
static GenOpFunc *gen_op_stdcx[] = {
2678
    &gen_op_stdcx_user,
2679
    &gen_op_stdcx_le_user,
2680
    &gen_op_stdcx_kernel,
2681
    &gen_op_stdcx_le_kernel,
2682
    &gen_op_stdcx_64_user,
2683
    &gen_op_stdcx_le_64_user,
2684
    &gen_op_stdcx_64_kernel,
2685
    &gen_op_stdcx_le_64_kernel,
2686
};
2687
#endif
2688

    
2689
/* ldarx */
2690
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2691
{
2692
    gen_addr_reg_index(ctx);
2693
    op_ldarx();
2694
    gen_op_store_T1_gpr(rD(ctx->opcode));
2695
}
2696

    
2697
/* stdcx. */
2698
GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2699
{
2700
    gen_addr_reg_index(ctx);
2701
    gen_op_load_gpr_T1(rS(ctx->opcode));
2702
    op_stdcx();
2703
}
2704
#endif /* defined(TARGET_PPC64) */
2705

    
2706
/* sync */
2707
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
2708
{
2709
}
2710

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

    
2719
/***                         Floating-point load                           ***/
2720
#define GEN_LDF(width, opc, type)                                             \
2721
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2722
{                                                                             \
2723
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2724
        GEN_EXCP_NO_FP(ctx);                                                  \
2725
        return;                                                               \
2726
    }                                                                         \
2727
    gen_addr_imm_index(ctx, 0);                                               \
2728
    op_ldst(l##width);                                                        \
2729
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2730
}
2731

    
2732
#define GEN_LDUF(width, opc, type)                                            \
2733
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2734
{                                                                             \
2735
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2736
        GEN_EXCP_NO_FP(ctx);                                                  \
2737
        return;                                                               \
2738
    }                                                                         \
2739
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2740
        GEN_EXCP_INVAL(ctx);                                                  \
2741
        return;                                                               \
2742
    }                                                                         \
2743
    gen_addr_imm_index(ctx, 0);                                               \
2744
    op_ldst(l##width);                                                        \
2745
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2746
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2747
}
2748

    
2749
#define GEN_LDUXF(width, opc, type)                                           \
2750
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
2751
{                                                                             \
2752
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2753
        GEN_EXCP_NO_FP(ctx);                                                  \
2754
        return;                                                               \
2755
    }                                                                         \
2756
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2757
        GEN_EXCP_INVAL(ctx);                                                  \
2758
        return;                                                               \
2759
    }                                                                         \
2760
    gen_addr_reg_index(ctx);                                                  \
2761
    op_ldst(l##width);                                                        \
2762
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2763
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2764
}
2765

    
2766
#define GEN_LDXF(width, opc2, opc3, type)                                     \
2767
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2768
{                                                                             \
2769
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2770
        GEN_EXCP_NO_FP(ctx);                                                  \
2771
        return;                                                               \
2772
    }                                                                         \
2773
    gen_addr_reg_index(ctx);                                                  \
2774
    op_ldst(l##width);                                                        \
2775
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2776
}
2777

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

    
2785
/* lfd lfdu lfdux lfdx */
2786
GEN_LDFS(fd, 0x12, PPC_FLOAT);
2787
/* lfs lfsu lfsux lfsx */
2788
GEN_LDFS(fs, 0x10, PPC_FLOAT);
2789

    
2790
/***                         Floating-point store                          ***/
2791
#define GEN_STF(width, opc, type)                                             \
2792
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2793
{                                                                             \
2794
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2795
        GEN_EXCP_NO_FP(ctx);                                                  \
2796
        return;                                                               \
2797
    }                                                                         \
2798
    gen_addr_imm_index(ctx, 0);                                               \
2799
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2800
    op_ldst(st##width);                                                       \
2801
}
2802

    
2803
#define GEN_STUF(width, opc, type)                                            \
2804
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2805
{                                                                             \
2806
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2807
        GEN_EXCP_NO_FP(ctx);                                                  \
2808
        return;                                                               \
2809
    }                                                                         \
2810
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2811
        GEN_EXCP_INVAL(ctx);                                                  \
2812
        return;                                                               \
2813
    }                                                                         \
2814
    gen_addr_imm_index(ctx, 0);                                               \
2815
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2816
    op_ldst(st##width);                                                       \
2817
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2818
}
2819

    
2820
#define GEN_STUXF(width, opc, type)                                           \
2821
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
2822
{                                                                             \
2823
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2824
        GEN_EXCP_NO_FP(ctx);                                                  \
2825
        return;                                                               \
2826
    }                                                                         \
2827
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2828
        GEN_EXCP_INVAL(ctx);                                                  \
2829
        return;                                                               \
2830
    }                                                                         \
2831
    gen_addr_reg_index(ctx);                                                  \
2832
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2833
    op_ldst(st##width);                                                       \
2834
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2835
}
2836

    
2837
#define GEN_STXF(width, opc2, opc3, type)                                     \
2838
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2839
{                                                                             \
2840
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2841
        GEN_EXCP_NO_FP(ctx);                                                  \
2842
        return;                                                               \
2843
    }                                                                         \
2844
    gen_addr_reg_index(ctx);                                                  \
2845
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2846
    op_ldst(st##width);                                                       \
2847
}
2848

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

    
2856
/* stfd stfdu stfdux stfdx */
2857
GEN_STFS(fd, 0x16, PPC_FLOAT);
2858
/* stfs stfsu stfsux stfsx */
2859
GEN_STFS(fs, 0x14, PPC_FLOAT);
2860

    
2861
/* Optional: */
2862
/* stfiwx */
2863
OP_ST_TABLE(fiwx);
2864
GEN_STXF(fiwx, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2865

    
2866
/***                                Branch                                 ***/
2867
static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
2868
{
2869
    TranslationBlock *tb;
2870
    tb = ctx->tb;
2871
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2872
        if (n == 0)
2873
            gen_op_goto_tb0(TBPARAM(tb));
2874
        else
2875
            gen_op_goto_tb1(TBPARAM(tb));
2876
        gen_set_T1(dest);
2877
#if defined(TARGET_PPC64)
2878
        if (ctx->sf_mode)
2879
            gen_op_b_T1_64();
2880
        else
2881
#endif
2882
            gen_op_b_T1();
2883
        gen_op_set_T0((long)tb + n);
2884
        if (ctx->singlestep_enabled)
2885
            gen_op_debug();
2886
        gen_op_exit_tb();
2887
    } else {
2888
        gen_set_T1(dest);
2889
#if defined(TARGET_PPC64)
2890
        if (ctx->sf_mode)
2891
            gen_op_b_T1_64();
2892
        else
2893
#endif
2894
            gen_op_b_T1();
2895
        gen_op_reset_T0();
2896
        if (ctx->singlestep_enabled)
2897
            gen_op_debug();
2898
        gen_op_exit_tb();
2899
    }
2900
}
2901

    
2902
static inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2903
{
2904
#if defined(TARGET_PPC64)
2905
    if (ctx->sf_mode != 0 && (nip >> 32))
2906
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2907
    else
2908
#endif
2909
        gen_op_setlr(ctx->nip);
2910
}
2911

    
2912
/* b ba bl bla */
2913
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2914
{
2915
    target_ulong li, target;
2916

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

    
2938
#define BCOND_IM  0
2939
#define BCOND_LR  1
2940
#define BCOND_CTR 2
2941

    
2942
static inline void gen_bcond (DisasContext *ctx, int type)
2943
{
2944
    target_ulong target = 0;
2945
    target_ulong li;
2946
    uint32_t bo = BO(ctx->opcode);
2947
    uint32_t bi = BI(ctx->opcode);
2948
    uint32_t mask;
2949

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

    
3088
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3089
{
3090
    gen_bcond(ctx, BCOND_IM);
3091
}
3092

    
3093
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3094
{
3095
    gen_bcond(ctx, BCOND_CTR);
3096
}
3097

    
3098
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3099
{
3100
    gen_bcond(ctx, BCOND_LR);
3101
}
3102

    
3103
/***                      Condition register logical                       ***/
3104
#define GEN_CRLOGIC(op, opc)                                                  \
3105
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
3106
{                                                                             \
3107
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
3108
    gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
3109
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
3110
    gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
3111
    gen_op_##op();                                                            \
3112
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
3113
    gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
3114
                     3 - (crbD(ctx->opcode) & 0x03));                         \
3115
    gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
3116
}
3117

    
3118
/* crand */
3119
GEN_CRLOGIC(and, 0x08);
3120
/* crandc */
3121
GEN_CRLOGIC(andc, 0x04);
3122
/* creqv */
3123
GEN_CRLOGIC(eqv, 0x09);
3124
/* crnand */
3125
GEN_CRLOGIC(nand, 0x07);
3126
/* crnor */
3127
GEN_CRLOGIC(nor, 0x01);
3128
/* cror */
3129
GEN_CRLOGIC(or, 0x0E);
3130
/* crorc */
3131
GEN_CRLOGIC(orc, 0x0D);
3132
/* crxor */
3133
GEN_CRLOGIC(xor, 0x06);
3134
/* mcrf */
3135
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3136
{
3137
    gen_op_load_crf_T0(crfS(ctx->opcode));
3138
    gen_op_store_T0_crf(crfD(ctx->opcode));
3139
}
3140

    
3141
/***                           System linkage                              ***/
3142
/* rfi (supervisor only) */
3143
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3144
{
3145
#if defined(CONFIG_USER_ONLY)
3146
    GEN_EXCP_PRIVOPC(ctx);
3147
#else
3148
    /* Restore CPU state */
3149
    if (unlikely(!ctx->supervisor)) {
3150
        GEN_EXCP_PRIVOPC(ctx);
3151
        return;
3152
    }
3153
    gen_op_rfi();
3154
    GEN_SYNC(ctx);
3155
#endif
3156
}
3157

    
3158
#if defined(TARGET_PPC64)
3159
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3160
{
3161
#if defined(CONFIG_USER_ONLY)
3162
    GEN_EXCP_PRIVOPC(ctx);
3163
#else
3164
    /* Restore CPU state */
3165
    if (unlikely(!ctx->supervisor)) {
3166
        GEN_EXCP_PRIVOPC(ctx);
3167
        return;
3168
    }
3169
    gen_op_rfid();
3170
    GEN_SYNC(ctx);
3171
#endif
3172
}
3173
#endif
3174

    
3175
#if defined(TARGET_PPC64H)
3176
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64B)
3177
{
3178
#if defined(CONFIG_USER_ONLY)
3179
    GEN_EXCP_PRIVOPC(ctx);
3180
#else
3181
    /* Restore CPU state */
3182
    if (unlikely(ctx->supervisor <= 1)) {
3183
        GEN_EXCP_PRIVOPC(ctx);
3184
        return;
3185
    }
3186
    gen_op_hrfid();
3187
    GEN_SYNC(ctx);
3188
#endif
3189
}
3190
#endif
3191

    
3192
/* sc */
3193
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3194
{
3195
    uint32_t lev;
3196

    
3197
    lev = (ctx->opcode >> 5) & 0x7F;
3198
#if defined(CONFIG_USER_ONLY)
3199
    GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
3200
#else
3201
    GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL, lev);
3202
#endif
3203
}
3204

    
3205
/***                                Trap                                   ***/
3206
/* tw */
3207
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3208
{
3209
    gen_op_load_gpr_T0(rA(ctx->opcode));
3210
    gen_op_load_gpr_T1(rB(ctx->opcode));
3211
    /* Update the nip since this might generate a trap exception */
3212
    gen_update_nip(ctx, ctx->nip);
3213
    gen_op_tw(TO(ctx->opcode));
3214
}
3215

    
3216
/* twi */
3217
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3218
{
3219
    gen_op_load_gpr_T0(rA(ctx->opcode));
3220
    gen_set_T1(SIMM(ctx->opcode));
3221
    /* Update the nip since this might generate a trap exception */
3222
    gen_update_nip(ctx, ctx->nip);
3223
    gen_op_tw(TO(ctx->opcode));
3224
}
3225

    
3226
#if defined(TARGET_PPC64)
3227
/* td */
3228
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3229
{
3230
    gen_op_load_gpr_T0(rA(ctx->opcode));
3231
    gen_op_load_gpr_T1(rB(ctx->opcode));
3232
    /* Update the nip since this might generate a trap exception */
3233
    gen_update_nip(ctx, ctx->nip);
3234
    gen_op_td(TO(ctx->opcode));
3235
}
3236

    
3237
/* tdi */
3238
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3239
{
3240
    gen_op_load_gpr_T0(rA(ctx->opcode));
3241
    gen_set_T1(SIMM(ctx->opcode));
3242
    /* Update the nip since this might generate a trap exception */
3243
    gen_update_nip(ctx, ctx->nip);
3244
    gen_op_td(TO(ctx->opcode));
3245
}
3246
#endif
3247

    
3248
/***                          Processor control                            ***/
3249
/* mcrxr */
3250
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3251
{
3252
    gen_op_load_xer_cr();
3253
    gen_op_store_T0_crf(crfD(ctx->opcode));
3254
    gen_op_clear_xer_ov();
3255
    gen_op_clear_xer_ca();
3256
}
3257

    
3258
/* mfcr */
3259
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3260
{
3261
    uint32_t crm, crn;
3262

    
3263
    if (likely(ctx->opcode & 0x00100000)) {
3264
        crm = CRM(ctx->opcode);
3265
        if (likely((crm ^ (crm - 1)) == 0)) {
3266
            crn = ffs(crm);
3267
            gen_op_load_cro(7 - crn);
3268
        }
3269
    } else {
3270
        gen_op_load_cr();
3271
    }
3272
    gen_op_store_T0_gpr(rD(ctx->opcode));
3273
}
3274

    
3275
/* mfmsr */
3276
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3277
{
3278
#if defined(CONFIG_USER_ONLY)
3279
    GEN_EXCP_PRIVREG(ctx);
3280
#else
3281
    if (unlikely(!ctx->supervisor)) {
3282
        GEN_EXCP_PRIVREG(ctx);
3283
        return;
3284
    }
3285
    gen_op_load_msr();
3286
    gen_op_store_T0_gpr(rD(ctx->opcode));
3287
#endif
3288
}
3289

    
3290
#if 0
3291
#define SPR_NOACCESS ((void *)(-1))
3292
#else
3293
static void spr_noaccess (void *opaque, int sprn)
3294
{
3295
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3296
    printf("ERROR: try to access SPR %d !\n", sprn);
3297
}
3298
#define SPR_NOACCESS (&spr_noaccess)
3299
#endif
3300

    
3301
/* mfspr */
3302
static inline void gen_op_mfspr (DisasContext *ctx)
3303
{
3304
    void (*read_cb)(void *opaque, int sprn);
3305
    uint32_t sprn = SPR(ctx->opcode);
3306

    
3307
#if !defined(CONFIG_USER_ONLY)
3308
#if defined(TARGET_PPC64H)
3309
    if (ctx->supervisor == 2)
3310
        read_cb = ctx->spr_cb[sprn].hea_read;
3311
    else
3312
#endif
3313
    if (ctx->supervisor)
3314
        read_cb = ctx->spr_cb[sprn].oea_read;
3315
    else
3316
#endif
3317
        read_cb = ctx->spr_cb[sprn].uea_read;
3318
    if (likely(read_cb != NULL)) {
3319
        if (likely(read_cb != SPR_NOACCESS)) {
3320
            (*read_cb)(ctx, sprn);
3321
            gen_op_store_T0_gpr(rD(ctx->opcode));
3322
        } else {
3323
            /* Privilege exception */
3324
            if (loglevel != 0) {
3325
                fprintf(logfile, "Trying to read privileged spr %d %03x\n",
3326
                        sprn, sprn);
3327
            }
3328
            printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
3329
            GEN_EXCP_PRIVREG(ctx);
3330
        }
3331
    } else {
3332
        /* Not defined */
3333
        if (loglevel != 0) {
3334
            fprintf(logfile, "Trying to read invalid spr %d %03x\n",
3335
                    sprn, sprn);
3336
        }
3337
        printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
3338
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3339
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3340
    }
3341
}
3342

    
3343
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3344
{
3345
    gen_op_mfspr(ctx);
3346
}
3347

    
3348
/* mftb */
3349
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3350
{
3351
    gen_op_mfspr(ctx);
3352
}
3353

    
3354
/* mtcrf */
3355
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3356
{
3357
    uint32_t crm, crn;
3358

    
3359
    gen_op_load_gpr_T0(rS(ctx->opcode));
3360
    crm = CRM(ctx->opcode);
3361
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3362
        crn = ffs(crm);
3363
        gen_op_srli_T0(crn * 4);
3364
        gen_op_andi_T0(0xF);
3365
        gen_op_store_cro(7 - crn);
3366
    } else {
3367
        gen_op_store_cr(crm);
3368
    }
3369
}
3370

    
3371
/* mtmsr */
3372
#if defined(TARGET_PPC64)
3373
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3374
{
3375
#if defined(CONFIG_USER_ONLY)
3376
    GEN_EXCP_PRIVREG(ctx);
3377
#else
3378
    if (unlikely(!ctx->supervisor)) {
3379
        GEN_EXCP_PRIVREG(ctx);
3380
        return;
3381
    }
3382
    gen_op_load_gpr_T0(rS(ctx->opcode));
3383
    if (ctx->opcode & 0x00010000) {
3384
        /* Special form that does not need any synchronisation */
3385
        gen_op_update_riee();
3386
    } else {
3387
        /* XXX: we need to update nip before the store
3388
         *      if we enter power saving mode, we will exit the loop
3389
         *      directly from ppc_store_msr
3390
         */
3391
        gen_update_nip(ctx, ctx->nip);
3392
        gen_op_store_msr();
3393
        /* Must stop the translation as machine state (may have) changed */
3394
        /* Note that mtmsr is not always defined as context-synchronizing */
3395
        ctx->exception = POWERPC_EXCP_STOP;
3396
    }
3397
#endif
3398
}
3399
#endif
3400

    
3401
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3402
{
3403
#if defined(CONFIG_USER_ONLY)
3404
    GEN_EXCP_PRIVREG(ctx);
3405
#else
3406
    if (unlikely(!ctx->supervisor)) {
3407
        GEN_EXCP_PRIVREG(ctx);
3408
        return;
3409
    }
3410
    gen_op_load_gpr_T0(rS(ctx->opcode));
3411
    if (ctx->opcode & 0x00010000) {
3412
        /* Special form that does not need any synchronisation */
3413
        gen_op_update_riee();
3414
    } else {
3415
        /* XXX: we need to update nip before the store
3416
         *      if we enter power saving mode, we will exit the loop
3417
         *      directly from ppc_store_msr
3418
         */
3419
        gen_update_nip(ctx, ctx->nip);
3420
#if defined(TARGET_PPC64)
3421
        if (!ctx->sf_mode)
3422
            gen_op_store_msr_32();
3423
        else
3424
#endif
3425
            gen_op_store_msr();
3426
        /* Must stop the translation as machine state (may have) changed */
3427
        /* Note that mtmsrd is not always defined as context-synchronizing */
3428
        ctx->exception = POWERPC_EXCP_STOP;
3429
    }
3430
#endif
3431
}
3432

    
3433
/* mtspr */
3434
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3435
{
3436
    void (*write_cb)(void *opaque, int sprn);
3437
    uint32_t sprn = SPR(ctx->opcode);
3438

    
3439
#if !defined(CONFIG_USER_ONLY)
3440
#if defined(TARGET_PPC64H)
3441
    if (ctx->supervisor == 2)
3442
        write_cb = ctx->spr_cb[sprn].hea_write;
3443
    else
3444
#endif
3445
    if (ctx->supervisor)
3446
        write_cb = ctx->spr_cb[sprn].oea_write;
3447
    else
3448
#endif
3449
        write_cb = ctx->spr_cb[sprn].uea_write;
3450
    if (likely(write_cb != NULL)) {
3451
        if (likely(write_cb != SPR_NOACCESS)) {
3452
            gen_op_load_gpr_T0(rS(ctx->opcode));
3453
            (*write_cb)(ctx, sprn);
3454
        } else {
3455
            /* Privilege exception */
3456
            if (loglevel != 0) {
3457
                fprintf(logfile, "Trying to write privileged spr %d %03x\n",
3458
                        sprn, sprn);
3459
            }
3460
            printf("Trying to write privileged spr %d %03x\n", sprn, sprn);
3461
            GEN_EXCP_PRIVREG(ctx);
3462
        }
3463
    } else {
3464
        /* Not defined */
3465
        if (loglevel != 0) {
3466
            fprintf(logfile, "Trying to write invalid spr %d %03x\n",
3467
                    sprn, sprn);
3468
        }
3469
        printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
3470
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3471
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3472
    }
3473
}
3474

    
3475
/***                         Cache management                              ***/
3476
/* For now, all those will be implemented as nop:
3477
 * this is valid, regarding the PowerPC specs...
3478
 * We just have to flush tb while invalidating instruction cache lines...
3479
 */
3480
/* dcbf */
3481
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3482
{
3483
    gen_addr_reg_index(ctx);
3484
    op_ldst(lbz);
3485
}
3486

    
3487
/* dcbi (Supervisor only) */
3488
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3489
{
3490
#if defined(CONFIG_USER_ONLY)
3491
    GEN_EXCP_PRIVOPC(ctx);
3492
#else
3493
    if (unlikely(!ctx->supervisor)) {
3494
        GEN_EXCP_PRIVOPC(ctx);
3495
        return;
3496
    }
3497
    gen_addr_reg_index(ctx);
3498
    /* XXX: specification says this should be treated as a store by the MMU */
3499
    //op_ldst(lbz);
3500
    op_ldst(stb);
3501
#endif
3502
}
3503

    
3504
/* dcdst */
3505
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3506
{
3507
    /* XXX: specification say this is treated as a load by the MMU */
3508
    gen_addr_reg_index(ctx);
3509
    op_ldst(lbz);
3510
}
3511

    
3512
/* dcbt */
3513
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3514
{
3515
    /* interpreted as no-op */
3516
    /* XXX: specification say this is treated as a load by the MMU
3517
     *      but does not generate any exception
3518
     */
3519
}
3520

    
3521
/* dcbtst */
3522
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3523
{
3524
    /* interpreted as no-op */
3525
    /* XXX: specification say this is treated as a load by the MMU
3526
     *      but does not generate any exception
3527
     */
3528
}
3529

    
3530
/* dcbz */
3531
#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3532
#if defined(TARGET_PPC64)
3533
#if defined(CONFIG_USER_ONLY)
3534
static GenOpFunc *gen_op_dcbz[] = {
3535
    &gen_op_dcbz_raw,
3536
    &gen_op_dcbz_raw,
3537
    &gen_op_dcbz_64_raw,
3538
    &gen_op_dcbz_64_raw,
3539
};
3540
#else
3541
static GenOpFunc *gen_op_dcbz[] = {
3542
    &gen_op_dcbz_user,
3543
    &gen_op_dcbz_user,
3544
    &gen_op_dcbz_kernel,
3545
    &gen_op_dcbz_kernel,
3546
    &gen_op_dcbz_64_user,
3547
    &gen_op_dcbz_64_user,
3548
    &gen_op_dcbz_64_kernel,
3549
    &gen_op_dcbz_64_kernel,
3550
};
3551
#endif
3552
#else
3553
#if defined(CONFIG_USER_ONLY)
3554
static GenOpFunc *gen_op_dcbz[] = {
3555
    &gen_op_dcbz_raw,
3556
    &gen_op_dcbz_raw,
3557
};
3558
#else
3559
static GenOpFunc *gen_op_dcbz[] = {
3560
    &gen_op_dcbz_user,
3561
    &gen_op_dcbz_user,
3562
    &gen_op_dcbz_kernel,
3563
    &gen_op_dcbz_kernel,
3564
};
3565
#endif
3566
#endif
3567

    
3568
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3569
{
3570
    gen_addr_reg_index(ctx);
3571
    op_dcbz();
3572
    gen_op_check_reservation();
3573
}
3574

    
3575
/* icbi */
3576
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3577
#if defined(TARGET_PPC64)
3578
#if defined(CONFIG_USER_ONLY)
3579
static GenOpFunc *gen_op_icbi[] = {
3580
    &gen_op_icbi_raw,
3581
    &gen_op_icbi_raw,
3582
    &gen_op_icbi_64_raw,
3583
    &gen_op_icbi_64_raw,
3584
};
3585
#else
3586
static GenOpFunc *gen_op_icbi[] = {
3587
    &gen_op_icbi_user,
3588
    &gen_op_icbi_user,
3589
    &gen_op_icbi_kernel,
3590
    &gen_op_icbi_kernel,
3591
    &gen_op_icbi_64_user,
3592
    &gen_op_icbi_64_user,
3593
    &gen_op_icbi_64_kernel,
3594
    &gen_op_icbi_64_kernel,
3595
};
3596
#endif
3597
#else
3598
#if defined(CONFIG_USER_ONLY)
3599
static GenOpFunc *gen_op_icbi[] = {
3600
    &gen_op_icbi_raw,
3601
    &gen_op_icbi_raw,
3602
};
3603
#else
3604
static GenOpFunc *gen_op_icbi[] = {
3605
    &gen_op_icbi_user,
3606
    &gen_op_icbi_user,
3607
    &gen_op_icbi_kernel,
3608
    &gen_op_icbi_kernel,
3609
};
3610
#endif
3611
#endif
3612

    
3613
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3614
{
3615
    gen_addr_reg_index(ctx);
3616
    op_icbi();
3617
}
3618

    
3619
/* Optional: */
3620
/* dcba */
3621
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3622
{
3623
    /* interpreted as no-op */
3624
    /* XXX: specification say this is treated as a store by the MMU
3625
     *      but does not generate any exception
3626
     */
3627
}
3628

    
3629
/***                    Segment register manipulation                      ***/
3630
/* Supervisor only: */
3631
/* mfsr */
3632
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3633
{
3634
#if defined(CONFIG_USER_ONLY)
3635
    GEN_EXCP_PRIVREG(ctx);
3636
#else
3637
    if (unlikely(!ctx->supervisor)) {
3638
        GEN_EXCP_PRIVREG(ctx);
3639
        return;
3640
    }
3641
    gen_op_set_T1(SR(ctx->opcode));
3642
    gen_op_load_sr();
3643
    gen_op_store_T0_gpr(rD(ctx->opcode));
3644
#endif
3645
}
3646

    
3647
/* mfsrin */
3648
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3649
{
3650
#if defined(CONFIG_USER_ONLY)
3651
    GEN_EXCP_PRIVREG(ctx);
3652
#else
3653
    if (unlikely(!ctx->supervisor)) {
3654
        GEN_EXCP_PRIVREG(ctx);
3655
        return;
3656
    }
3657
    gen_op_load_gpr_T1(rB(ctx->opcode));
3658
    gen_op_srli_T1(28);
3659
    gen_op_load_sr();
3660
    gen_op_store_T0_gpr(rD(ctx->opcode));
3661
#endif
3662
}
3663

    
3664
/* mtsr */
3665
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3666
{
3667
#if defined(CONFIG_USER_ONLY)
3668
    GEN_EXCP_PRIVREG(ctx);
3669
#else
3670
    if (unlikely(!ctx->supervisor)) {
3671
        GEN_EXCP_PRIVREG(ctx);
3672
        return;
3673
    }
3674
    gen_op_load_gpr_T0(rS(ctx->opcode));
3675
    gen_op_set_T1(SR(ctx->opcode));
3676
    gen_op_store_sr();
3677
#endif
3678
}
3679

    
3680
/* mtsrin */
3681
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3682
{
3683
#if defined(CONFIG_USER_ONLY)
3684
    GEN_EXCP_PRIVREG(ctx);
3685
#else
3686
    if (unlikely(!ctx->supervisor)) {
3687
        GEN_EXCP_PRIVREG(ctx);
3688
        return;
3689
    }
3690
    gen_op_load_gpr_T0(rS(ctx->opcode));
3691
    gen_op_load_gpr_T1(rB(ctx->opcode));
3692
    gen_op_srli_T1(28);
3693
    gen_op_store_sr();
3694
#endif
3695
}
3696

    
3697
/***                      Lookaside buffer management                      ***/
3698
/* Optional & supervisor only: */
3699
/* tlbia */
3700
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3701
{
3702
#if defined(CONFIG_USER_ONLY)
3703
    GEN_EXCP_PRIVOPC(ctx);
3704
#else
3705
    if (unlikely(!ctx->supervisor)) {
3706
        if (loglevel != 0)
3707
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3708
        GEN_EXCP_PRIVOPC(ctx);
3709
        return;
3710
    }
3711
    gen_op_tlbia();
3712
#endif
3713
}
3714

    
3715
/* tlbie */
3716
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3717
{
3718
#if defined(CONFIG_USER_ONLY)
3719
    GEN_EXCP_PRIVOPC(ctx);
3720
#else
3721
    if (unlikely(!ctx->supervisor)) {
3722
        GEN_EXCP_PRIVOPC(ctx);
3723
        return;
3724
    }
3725
    gen_op_load_gpr_T0(rB(ctx->opcode));
3726
#if defined(TARGET_PPC64)
3727
    if (ctx->sf_mode)
3728
        gen_op_tlbie_64();
3729
    else
3730
#endif
3731
        gen_op_tlbie();
3732
#endif
3733
}
3734

    
3735
/* tlbsync */
3736
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3737
{
3738
#if defined(CONFIG_USER_ONLY)
3739
    GEN_EXCP_PRIVOPC(ctx);
3740
#else
3741
    if (unlikely(!ctx->supervisor)) {
3742
        GEN_EXCP_PRIVOPC(ctx);
3743
        return;
3744
    }
3745
    /* This has no effect: it should ensure that all previous
3746
     * tlbie have completed
3747
     */
3748
    GEN_STOP(ctx);
3749
#endif
3750
}
3751

    
3752
#if defined(TARGET_PPC64)
3753
/* slbia */
3754
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3755
{
3756
#if defined(CONFIG_USER_ONLY)
3757
    GEN_EXCP_PRIVOPC(ctx);
3758
#else
3759
    if (unlikely(!ctx->supervisor)) {
3760
        if (loglevel != 0)
3761
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3762
        GEN_EXCP_PRIVOPC(ctx);
3763
        return;
3764
    }
3765
    gen_op_slbia();
3766
#endif
3767
}
3768

    
3769
/* slbie */
3770
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3771
{
3772
#if defined(CONFIG_USER_ONLY)
3773
    GEN_EXCP_PRIVOPC(ctx);
3774
#else
3775
    if (unlikely(!ctx->supervisor)) {
3776
        GEN_EXCP_PRIVOPC(ctx);
3777
        return;
3778
    }
3779
    gen_op_load_gpr_T0(rB(ctx->opcode));
3780
    gen_op_slbie();
3781
#endif
3782
}
3783
#endif
3784

    
3785
/***                              External control                         ***/
3786
/* Optional: */
3787
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3788
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3789
#if defined(TARGET_PPC64)
3790
#if defined(CONFIG_USER_ONLY)
3791
static GenOpFunc *gen_op_eciwx[] = {
3792
    &gen_op_eciwx_raw,
3793
    &gen_op_eciwx_le_raw,
3794
    &gen_op_eciwx_64_raw,
3795
    &gen_op_eciwx_le_64_raw,
3796
};
3797
static GenOpFunc *gen_op_ecowx[] = {
3798
    &gen_op_ecowx_raw,
3799
    &gen_op_ecowx_le_raw,
3800
    &gen_op_ecowx_64_raw,
3801
    &gen_op_ecowx_le_64_raw,
3802
};
3803
#else
3804
static GenOpFunc *gen_op_eciwx[] = {
3805
    &gen_op_eciwx_user,
3806
    &gen_op_eciwx_le_user,
3807
    &gen_op_eciwx_kernel,
3808
    &gen_op_eciwx_le_kernel,
3809
    &gen_op_eciwx_64_user,
3810
    &gen_op_eciwx_le_64_user,
3811
    &gen_op_eciwx_64_kernel,
3812
    &gen_op_eciwx_le_64_kernel,
3813
};
3814
static GenOpFunc *gen_op_ecowx[] = {
3815
    &gen_op_ecowx_user,
3816
    &gen_op_ecowx_le_user,
3817
    &gen_op_ecowx_kernel,
3818
    &gen_op_ecowx_le_kernel,
3819
    &gen_op_ecowx_64_user,
3820
    &gen_op_ecowx_le_64_user,
3821
    &gen_op_ecowx_64_kernel,
3822
    &gen_op_ecowx_le_64_kernel,
3823
};
3824
#endif
3825
#else
3826
#if defined(CONFIG_USER_ONLY)
3827
static GenOpFunc *gen_op_eciwx[] = {
3828
    &gen_op_eciwx_raw,
3829
    &gen_op_eciwx_le_raw,
3830
};
3831
static GenOpFunc *gen_op_ecowx[] = {
3832
    &gen_op_ecowx_raw,
3833
    &gen_op_ecowx_le_raw,
3834
};
3835
#else
3836
static GenOpFunc *gen_op_eciwx[] = {
3837
    &gen_op_eciwx_user,
3838
    &gen_op_eciwx_le_user,
3839
    &gen_op_eciwx_kernel,
3840
    &gen_op_eciwx_le_kernel,
3841
};
3842
static GenOpFunc *gen_op_ecowx[] = {
3843
    &gen_op_ecowx_user,
3844
    &gen_op_ecowx_le_user,
3845
    &gen_op_ecowx_kernel,
3846
    &gen_op_ecowx_le_kernel,
3847
};
3848
#endif
3849
#endif
3850

    
3851
/* eciwx */
3852
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3853
{
3854
    /* Should check EAR[E] & alignment ! */
3855
    gen_addr_reg_index(ctx);
3856
    op_eciwx();
3857
    gen_op_store_T0_gpr(rD(ctx->opcode));
3858
}
3859

    
3860
/* ecowx */
3861
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3862
{
3863
    /* Should check EAR[E] & alignment ! */
3864
    gen_addr_reg_index(ctx);
3865
    gen_op_load_gpr_T1(rS(ctx->opcode));
3866
    op_ecowx();
3867
}
3868

    
3869
/* PowerPC 601 specific instructions */
3870
/* abs - abs. */
3871
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3872
{
3873
    gen_op_load_gpr_T0(rA(ctx->opcode));
3874
    gen_op_POWER_abs();
3875
    gen_op_store_T0_gpr(rD(ctx->opcode));
3876
    if (unlikely(Rc(ctx->opcode) != 0))
3877
        gen_set_Rc0(ctx);
3878
}
3879

    
3880
/* abso - abso. */
3881
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3882
{
3883
    gen_op_load_gpr_T0(rA(ctx->opcode));
3884
    gen_op_POWER_abso();
3885
    gen_op_store_T0_gpr(rD(ctx->opcode));
3886
    if (unlikely(Rc(ctx->opcode) != 0))
3887
        gen_set_Rc0(ctx);
3888
}
3889

    
3890
/* clcs */
3891
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3892
{
3893
    gen_op_load_gpr_T0(rA(ctx->opcode));
3894
    gen_op_POWER_clcs();
3895
    gen_op_store_T0_gpr(rD(ctx->opcode));
3896
}
3897

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

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

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

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

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

    
3953
/* dozo - dozo. */
3954
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3955
{
3956
    gen_op_load_gpr_T0(rA(ctx->opcode));
3957
    gen_op_load_gpr_T1(rB(ctx->opcode));
3958
    gen_op_POWER_dozo();
3959
    gen_op_store_T0_gpr(rD(ctx->opcode));
3960
    if (unlikely(Rc(ctx->opcode) != 0))
3961
        gen_set_Rc0(ctx);
3962
}
3963

    
3964
/* dozi */
3965
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3966
{
3967
    gen_op_load_gpr_T0(rA(ctx->opcode));
3968
    gen_op_set_T1(SIMM(ctx->opcode));
3969
    gen_op_POWER_doz();
3970
    gen_op_store_T0_gpr(rD(ctx->opcode));
3971
}
3972

    
3973
/* As lscbx load from memory byte after byte, it's always endian safe */
3974
#define op_POWER_lscbx(start, ra, rb) \
3975
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3976
#if defined(CONFIG_USER_ONLY)
3977
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3978
    &gen_op_POWER_lscbx_raw,
3979
    &gen_op_POWER_lscbx_raw,
3980
};
3981
#else
3982
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3983
    &gen_op_POWER_lscbx_user,
3984
    &gen_op_POWER_lscbx_user,
3985
    &gen_op_POWER_lscbx_kernel,
3986
    &gen_op_POWER_lscbx_kernel,
3987
};
3988
#endif
3989

    
3990
/* lscbx - lscbx. */
3991
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3992
{
3993
    int ra = rA(ctx->opcode);
3994
    int rb = rB(ctx->opcode);
3995

    
3996
    gen_addr_reg_index(ctx);
3997
    if (ra == 0) {
3998
        ra = rb;
3999
    }
4000
    /* NIP cannot be restored if the memory exception comes from an helper */
4001
    gen_update_nip(ctx, ctx->nip - 4);
4002
    gen_op_load_xer_bc();
4003
    gen_op_load_xer_cmp();
4004
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
4005
    gen_op_store_xer_bc();
4006
    if (unlikely(Rc(ctx->opcode) != 0))
4007
        gen_set_Rc0(ctx);
4008
}
4009

    
4010
/* maskg - maskg. */
4011
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
4012
{
4013
    gen_op_load_gpr_T0(rS(ctx->opcode));
4014
    gen_op_load_gpr_T1(rB(ctx->opcode));
4015
    gen_op_POWER_maskg();
4016
    gen_op_store_T0_gpr(rA(ctx->opcode));
4017
    if (unlikely(Rc(ctx->opcode) != 0))
4018
        gen_set_Rc0(ctx);
4019
}
4020

    
4021
/* maskir - maskir. */
4022
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4023
{
4024
    gen_op_load_gpr_T0(rA(ctx->opcode));
4025
    gen_op_load_gpr_T1(rS(ctx->opcode));
4026
    gen_op_load_gpr_T2(rB(ctx->opcode));
4027
    gen_op_POWER_maskir();
4028
    gen_op_store_T0_gpr(rA(ctx->opcode));
4029
    if (unlikely(Rc(ctx->opcode) != 0))
4030
        gen_set_Rc0(ctx);
4031
}
4032

    
4033
/* mul - mul. */
4034
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4035
{
4036
    gen_op_load_gpr_T0(rA(ctx->opcode));
4037
    gen_op_load_gpr_T1(rB(ctx->opcode));
4038
    gen_op_POWER_mul();
4039
    gen_op_store_T0_gpr(rD(ctx->opcode));
4040
    if (unlikely(Rc(ctx->opcode) != 0))
4041
        gen_set_Rc0(ctx);
4042
}
4043

    
4044
/* mulo - mulo. */
4045
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4046
{
4047
    gen_op_load_gpr_T0(rA(ctx->opcode));
4048
    gen_op_load_gpr_T1(rB(ctx->opcode));
4049
    gen_op_POWER_mulo();
4050
    gen_op_store_T0_gpr(rD(ctx->opcode));
4051
    if (unlikely(Rc(ctx->opcode) != 0))
4052
        gen_set_Rc0(ctx);
4053
}
4054

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

    
4065
/* nabso - nabso. */
4066
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4067
{
4068
    gen_op_load_gpr_T0(rA(ctx->opcode));
4069
    gen_op_POWER_nabso();
4070
    gen_op_store_T0_gpr(rD(ctx->opcode));
4071
    if (unlikely(Rc(ctx->opcode) != 0))
4072
        gen_set_Rc0(ctx);
4073
}
4074

    
4075
/* rlmi - rlmi. */
4076
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4077
{
4078
    uint32_t mb, me;
4079

    
4080
    mb = MB(ctx->opcode);
4081
    me = ME(ctx->opcode);
4082
    gen_op_load_gpr_T0(rS(ctx->opcode));
4083
    gen_op_load_gpr_T1(rA(ctx->opcode));
4084
    gen_op_load_gpr_T2(rB(ctx->opcode));
4085
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4086
    gen_op_store_T0_gpr(rA(ctx->opcode));
4087
    if (unlikely(Rc(ctx->opcode) != 0))
4088
        gen_set_Rc0(ctx);
4089
}
4090

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

    
4103
/* sle - sle. */
4104
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4105
{
4106
    gen_op_load_gpr_T0(rS(ctx->opcode));
4107
    gen_op_load_gpr_T1(rB(ctx->opcode));
4108
    gen_op_POWER_sle();
4109
    gen_op_store_T0_gpr(rA(ctx->opcode));
4110
    if (unlikely(Rc(ctx->opcode) != 0))
4111
        gen_set_Rc0(ctx);
4112
}
4113

    
4114
/* sleq - sleq. */
4115
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4116
{
4117
    gen_op_load_gpr_T0(rS(ctx->opcode));
4118
    gen_op_load_gpr_T1(rB(ctx->opcode));
4119
    gen_op_POWER_sleq();
4120
    gen_op_store_T0_gpr(rA(ctx->opcode));
4121
    if (unlikely(Rc(ctx->opcode) != 0))
4122
        gen_set_Rc0(ctx);
4123
}
4124

    
4125
/* sliq - sliq. */
4126
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4127
{
4128
    gen_op_load_gpr_T0(rS(ctx->opcode));
4129
    gen_op_set_T1(SH(ctx->opcode));
4130
    gen_op_POWER_sle();
4131
    gen_op_store_T0_gpr(rA(ctx->opcode));
4132
    if (unlikely(Rc(ctx->opcode) != 0))
4133
        gen_set_Rc0(ctx);
4134
}
4135

    
4136
/* slliq - slliq. */
4137
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4138
{
4139
    gen_op_load_gpr_T0(rS(ctx->opcode));
4140
    gen_op_set_T1(SH(ctx->opcode));
4141
    gen_op_POWER_sleq();
4142
    gen_op_store_T0_gpr(rA(ctx->opcode));
4143
    if (unlikely(Rc(ctx->opcode) != 0))
4144
        gen_set_Rc0(ctx);
4145
}
4146

    
4147
/* sllq - sllq. */
4148
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4149
{
4150
    gen_op_load_gpr_T0(rS(ctx->opcode));
4151
    gen_op_load_gpr_T1(rB(ctx->opcode));
4152
    gen_op_POWER_sllq();
4153
    gen_op_store_T0_gpr(rA(ctx->opcode));
4154
    if (unlikely(Rc(ctx->opcode) != 0))
4155
        gen_set_Rc0(ctx);
4156
}
4157

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

    
4169
/* sraiq - sraiq. */
4170
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4171
{
4172
    gen_op_load_gpr_T0(rS(ctx->opcode));
4173
    gen_op_set_T1(SH(ctx->opcode));
4174
    gen_op_POWER_sraq();
4175
    gen_op_store_T0_gpr(rA(ctx->opcode));
4176
    if (unlikely(Rc(ctx->opcode) != 0))
4177
        gen_set_Rc0(ctx);
4178
}
4179

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

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

    
4202
/* srea - srea. */
4203
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4204
{
4205
    gen_op_load_gpr_T0(rS(ctx->opcode));
4206
    gen_op_load_gpr_T1(rB(ctx->opcode));
4207
    gen_op_POWER_srea();
4208
    gen_op_store_T0_gpr(rA(ctx->opcode));
4209
    if (unlikely(Rc(ctx->opcode) != 0))
4210
        gen_set_Rc0(ctx);
4211
}
4212

    
4213
/* sreq */
4214
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4215
{
4216
    gen_op_load_gpr_T0(rS(ctx->opcode));
4217
    gen_op_load_gpr_T1(rB(ctx->opcode));
4218
    gen_op_POWER_sreq();
4219
    gen_op_store_T0_gpr(rA(ctx->opcode));
4220
    if (unlikely(Rc(ctx->opcode) != 0))
4221
        gen_set_Rc0(ctx);
4222
}
4223

    
4224
/* sriq */
4225
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4226
{
4227
    gen_op_load_gpr_T0(rS(ctx->opcode));
4228
    gen_op_set_T1(SH(ctx->opcode));
4229
    gen_op_POWER_srq();
4230
    gen_op_store_T0_gpr(rA(ctx->opcode));
4231
    if (unlikely(Rc(ctx->opcode) != 0))
4232
        gen_set_Rc0(ctx);
4233
}
4234

    
4235
/* srliq */
4236
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4237
{
4238
    gen_op_load_gpr_T0(rS(ctx->opcode));
4239
    gen_op_load_gpr_T1(rB(ctx->opcode));
4240
    gen_op_set_T1(SH(ctx->opcode));
4241
    gen_op_POWER_srlq();
4242
    gen_op_store_T0_gpr(rA(ctx->opcode));
4243
    if (unlikely(Rc(ctx->opcode) != 0))
4244
        gen_set_Rc0(ctx);
4245
}
4246

    
4247
/* srlq */
4248
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4249
{
4250
    gen_op_load_gpr_T0(rS(ctx->opcode));
4251
    gen_op_load_gpr_T1(rB(ctx->opcode));
4252
    gen_op_POWER_srlq();
4253
    gen_op_store_T0_gpr(rA(ctx->opcode));
4254
    if (unlikely(Rc(ctx->opcode) != 0))
4255
        gen_set_Rc0(ctx);
4256
}
4257

    
4258
/* srq */
4259
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4260
{
4261
    gen_op_load_gpr_T0(rS(ctx->opcode));
4262
    gen_op_load_gpr_T1(rB(ctx->opcode));
4263
    gen_op_POWER_srq();
4264
    gen_op_store_T0_gpr(rA(ctx->opcode));
4265
    if (unlikely(Rc(ctx->opcode) != 0))
4266
        gen_set_Rc0(ctx);
4267
}
4268

    
4269
/* PowerPC 602 specific instructions */
4270
/* dsa  */
4271
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4272
{
4273
    /* XXX: TODO */
4274
    GEN_EXCP_INVAL(ctx);
4275
}
4276

    
4277
/* esa */
4278
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4279
{
4280
    /* XXX: TODO */
4281
    GEN_EXCP_INVAL(ctx);
4282
}
4283

    
4284
/* mfrom */
4285
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4286
{
4287
#if defined(CONFIG_USER_ONLY)
4288
    GEN_EXCP_PRIVOPC(ctx);
4289
#else
4290
    if (unlikely(!ctx->supervisor)) {
4291
        GEN_EXCP_PRIVOPC(ctx);
4292
        return;
4293
    }
4294
    gen_op_load_gpr_T0(rA(ctx->opcode));
4295
    gen_op_602_mfrom();
4296
    gen_op_store_T0_gpr(rD(ctx->opcode));
4297
#endif
4298
}
4299

    
4300
/* 602 - 603 - G2 TLB management */
4301
/* tlbld */
4302
GEN_HANDLER(tlbld_6xx, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4303
{
4304
#if defined(CONFIG_USER_ONLY)
4305
    GEN_EXCP_PRIVOPC(ctx);
4306
#else
4307
    if (unlikely(!ctx->supervisor)) {
4308
        GEN_EXCP_PRIVOPC(ctx);
4309
        return;
4310
    }
4311
    gen_op_load_gpr_T0(rB(ctx->opcode));
4312
    gen_op_6xx_tlbld();
4313
#endif
4314
}
4315

    
4316
/* tlbli */
4317
GEN_HANDLER(tlbli_6xx, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4318
{
4319
#if defined(CONFIG_USER_ONLY)
4320
    GEN_EXCP_PRIVOPC(ctx);
4321
#else
4322
    if (unlikely(!ctx->supervisor)) {
4323
        GEN_EXCP_PRIVOPC(ctx);
4324
        return;
4325
    }
4326
    gen_op_load_gpr_T0(rB(ctx->opcode));
4327
    gen_op_6xx_tlbli();
4328
#endif
4329
}
4330

    
4331
/* 74xx TLB management */
4332
/* tlbld */
4333
GEN_HANDLER(tlbld_74xx, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4334
{
4335
#if defined(CONFIG_USER_ONLY)
4336
    GEN_EXCP_PRIVOPC(ctx);
4337
#else
4338
    if (unlikely(!ctx->supervisor)) {
4339
        GEN_EXCP_PRIVOPC(ctx);
4340
        return;
4341
    }
4342
    gen_op_load_gpr_T0(rB(ctx->opcode));
4343
    gen_op_74xx_tlbld();
4344
#endif
4345
}
4346

    
4347
/* tlbli */
4348
GEN_HANDLER(tlbli_74xx, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4349
{
4350
#if defined(CONFIG_USER_ONLY)
4351
    GEN_EXCP_PRIVOPC(ctx);
4352
#else
4353
    if (unlikely(!ctx->supervisor)) {
4354
        GEN_EXCP_PRIVOPC(ctx);
4355
        return;
4356
    }
4357
    gen_op_load_gpr_T0(rB(ctx->opcode));
4358
    gen_op_74xx_tlbli();
4359
#endif
4360
}
4361

    
4362
/* POWER instructions not in PowerPC 601 */
4363
/* clf */
4364
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4365
{
4366
    /* Cache line flush: implemented as no-op */
4367
}
4368

    
4369
/* cli */
4370
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4371
{
4372
    /* Cache line invalidate: privileged and treated as no-op */
4373
#if defined(CONFIG_USER_ONLY)
4374
    GEN_EXCP_PRIVOPC(ctx);
4375
#else
4376
    if (unlikely(!ctx->supervisor)) {
4377
        GEN_EXCP_PRIVOPC(ctx);
4378
        return;
4379
    }
4380
#endif
4381
}
4382

    
4383
/* dclst */
4384
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4385
{
4386
    /* Data cache line store: treated as no-op */
4387
}
4388

    
4389
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4390
{
4391
#if defined(CONFIG_USER_ONLY)
4392
    GEN_EXCP_PRIVOPC(ctx);
4393
#else
4394
    if (unlikely(!ctx->supervisor)) {
4395
        GEN_EXCP_PRIVOPC(ctx);
4396
        return;
4397
    }
4398
    int ra = rA(ctx->opcode);
4399
    int rd = rD(ctx->opcode);
4400

    
4401
    gen_addr_reg_index(ctx);
4402
    gen_op_POWER_mfsri();
4403
    gen_op_store_T0_gpr(rd);
4404
    if (ra != 0 && ra != rd)
4405
        gen_op_store_T1_gpr(ra);
4406
#endif
4407
}
4408

    
4409
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4410
{
4411
#if defined(CONFIG_USER_ONLY)
4412
    GEN_EXCP_PRIVOPC(ctx);
4413
#else
4414
    if (unlikely(!ctx->supervisor)) {
4415
        GEN_EXCP_PRIVOPC(ctx);
4416
        return;
4417
    }
4418
    gen_addr_reg_index(ctx);
4419
    gen_op_POWER_rac();
4420
    gen_op_store_T0_gpr(rD(ctx->opcode));
4421
#endif
4422
}
4423

    
4424
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4425
{
4426
#if defined(CONFIG_USER_ONLY)
4427
    GEN_EXCP_PRIVOPC(ctx);
4428
#else
4429
    if (unlikely(!ctx->supervisor)) {
4430
        GEN_EXCP_PRIVOPC(ctx);
4431
        return;
4432
    }
4433
    gen_op_POWER_rfsvc();
4434
    GEN_SYNC(ctx);
4435
#endif
4436
}
4437

    
4438
/* svc is not implemented for now */
4439

    
4440
/* POWER2 specific instructions */
4441
/* Quad manipulation (load/store two floats at a time) */
4442
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4443
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4444
#if defined(CONFIG_USER_ONLY)
4445
static GenOpFunc *gen_op_POWER2_lfq[] = {
4446
    &gen_op_POWER2_lfq_le_raw,
4447
    &gen_op_POWER2_lfq_raw,
4448
};
4449
static GenOpFunc *gen_op_POWER2_stfq[] = {
4450
    &gen_op_POWER2_stfq_le_raw,
4451
    &gen_op_POWER2_stfq_raw,
4452
};
4453
#else
4454
static GenOpFunc *gen_op_POWER2_lfq[] = {
4455
    &gen_op_POWER2_lfq_le_user,
4456
    &gen_op_POWER2_lfq_user,
4457
    &gen_op_POWER2_lfq_le_kernel,
4458
    &gen_op_POWER2_lfq_kernel,
4459
};
4460
static GenOpFunc *gen_op_POWER2_stfq[] = {
4461
    &gen_op_POWER2_stfq_le_user,
4462
    &gen_op_POWER2_stfq_user,
4463
    &gen_op_POWER2_stfq_le_kernel,
4464
    &gen_op_POWER2_stfq_kernel,
4465
};
4466
#endif
4467

    
4468
/* lfq */
4469
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4470
{
4471
    /* NIP cannot be restored if the memory exception comes from an helper */
4472
    gen_update_nip(ctx, ctx->nip - 4);
4473
    gen_addr_imm_index(ctx, 0);
4474
    op_POWER2_lfq();
4475
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4476
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4477
}
4478

    
4479
/* lfqu */
4480
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4481
{
4482
    int ra = rA(ctx->opcode);
4483

    
4484
    /* NIP cannot be restored if the memory exception comes from an helper */
4485
    gen_update_nip(ctx, ctx->nip - 4);
4486
    gen_addr_imm_index(ctx, 0);
4487
    op_POWER2_lfq();
4488
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4489
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4490
    if (ra != 0)
4491
        gen_op_store_T0_gpr(ra);
4492
}
4493

    
4494
/* lfqux */
4495
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4496
{
4497
    int ra = rA(ctx->opcode);
4498

    
4499
    /* NIP cannot be restored if the memory exception comes from an helper */
4500
    gen_update_nip(ctx, ctx->nip - 4);
4501
    gen_addr_reg_index(ctx);
4502
    op_POWER2_lfq();
4503
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4504
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4505
    if (ra != 0)
4506
        gen_op_store_T0_gpr(ra);
4507
}
4508

    
4509
/* lfqx */
4510
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4511
{
4512
    /* NIP cannot be restored if the memory exception comes from an helper */
4513
    gen_update_nip(ctx, ctx->nip - 4);
4514
    gen_addr_reg_index(ctx);
4515
    op_POWER2_lfq();
4516
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4517
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4518
}
4519

    
4520
/* stfq */
4521
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4522
{
4523
    /* NIP cannot be restored if the memory exception comes from an helper */
4524
    gen_update_nip(ctx, ctx->nip - 4);
4525
    gen_addr_imm_index(ctx, 0);
4526
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4527
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4528
    op_POWER2_stfq();
4529
}
4530

    
4531
/* stfqu */
4532
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4533
{
4534
    int ra = rA(ctx->opcode);
4535

    
4536
    /* NIP cannot be restored if the memory exception comes from an helper */
4537
    gen_update_nip(ctx, ctx->nip - 4);
4538
    gen_addr_imm_index(ctx, 0);
4539
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4540
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4541
    op_POWER2_stfq();
4542
    if (ra != 0)
4543
        gen_op_store_T0_gpr(ra);
4544
}
4545

    
4546
/* stfqux */
4547
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4548
{
4549
    int ra = rA(ctx->opcode);
4550

    
4551
    /* NIP cannot be restored if the memory exception comes from an helper */
4552
    gen_update_nip(ctx, ctx->nip - 4);
4553
    gen_addr_reg_index(ctx);
4554
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4555
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4556
    op_POWER2_stfq();
4557
    if (ra != 0)
4558
        gen_op_store_T0_gpr(ra);
4559
}
4560

    
4561
/* stfqx */
4562
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4563
{
4564
    /* NIP cannot be restored if the memory exception comes from an helper */
4565
    gen_update_nip(ctx, ctx->nip - 4);
4566
    gen_addr_reg_index(ctx);
4567
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4568
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4569
    op_POWER2_stfq();
4570
}
4571

    
4572
/* BookE specific instructions */
4573
/* XXX: not implemented on 440 ? */
4574
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT)
4575
{
4576
    /* XXX: TODO */
4577
    GEN_EXCP_INVAL(ctx);
4578
}
4579

    
4580
/* XXX: not implemented on 440 ? */
4581
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
4582
{
4583
#if defined(CONFIG_USER_ONLY)
4584
    GEN_EXCP_PRIVOPC(ctx);
4585
#else
4586
    if (unlikely(!ctx->supervisor)) {
4587
        GEN_EXCP_PRIVOPC(ctx);
4588
        return;
4589
    }
4590
    gen_addr_reg_index(ctx);
4591
    /* Use the same micro-ops as for tlbie */
4592
#if defined(TARGET_PPC64)
4593
    if (ctx->sf_mode)
4594
        gen_op_tlbie_64();
4595
    else
4596
#endif
4597
        gen_op_tlbie();
4598
#endif
4599
}
4600

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

    
4682
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4683
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4684
{                                                                             \
4685
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4686
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4687
}
4688

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

    
4762
/* mulchw  - mulchw.  */
4763
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4764
/* mulchwu - mulchwu. */
4765
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4766
/* mulhhw  - mulhhw.  */
4767
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4768
/* mulhhwu - mulhhwu. */
4769
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4770
/* mullhw  - mullhw.  */
4771
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4772
/* mullhwu - mullhwu. */
4773
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4774

    
4775
/* mfdcr */
4776
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4777
{
4778
#if defined(CONFIG_USER_ONLY)
4779
    GEN_EXCP_PRIVREG(ctx);
4780
#else
4781
    uint32_t dcrn = SPR(ctx->opcode);
4782

    
4783
    if (unlikely(!ctx->supervisor)) {
4784
        GEN_EXCP_PRIVREG(ctx);
4785
        return;
4786
    }
4787
    gen_op_set_T0(dcrn);
4788
    gen_op_load_dcr();
4789
    gen_op_store_T0_gpr(rD(ctx->opcode));
4790
#endif
4791
}
4792

    
4793
/* mtdcr */
4794
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4795
{
4796
#if defined(CONFIG_USER_ONLY)
4797
    GEN_EXCP_PRIVREG(ctx);
4798
#else
4799
    uint32_t dcrn = SPR(ctx->opcode);
4800

    
4801
    if (unlikely(!ctx->supervisor)) {
4802
        GEN_EXCP_PRIVREG(ctx);
4803
        return;
4804
    }
4805
    gen_op_set_T0(dcrn);
4806
    gen_op_load_gpr_T1(rS(ctx->opcode));
4807
    gen_op_store_dcr();
4808
#endif
4809
}
4810

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

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

    
4847
/* mfdcrux (PPC 460) : user-mode access to DCR */
4848
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4849
{
4850
    gen_op_load_gpr_T0(rA(ctx->opcode));
4851
    gen_op_load_dcr();
4852
    gen_op_store_T0_gpr(rD(ctx->opcode));
4853
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4854
}
4855

    
4856
/* mtdcrux (PPC 460) : user-mode access to DCR */
4857
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4858
{
4859
    gen_op_load_gpr_T0(rA(ctx->opcode));
4860
    gen_op_load_gpr_T1(rS(ctx->opcode));
4861
    gen_op_store_dcr();
4862
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4863
}
4864

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

    
4879
/* dcread */
4880
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4881
{
4882
#if defined(CONFIG_USER_ONLY)
4883
    GEN_EXCP_PRIVOPC(ctx);
4884
#else
4885
    if (unlikely(!ctx->supervisor)) {
4886
        GEN_EXCP_PRIVOPC(ctx);
4887
        return;
4888
    }
4889
    gen_addr_reg_index(ctx);
4890
    op_ldst(lwz);
4891
    gen_op_store_T0_gpr(rD(ctx->opcode));
4892
#endif
4893
}
4894

    
4895
/* icbt */
4896
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4897
{
4898
    /* interpreted as no-op */
4899
    /* XXX: specification say this is treated as a load by the MMU
4900
     *      but does not generate any exception
4901
     */
4902
}
4903

    
4904
/* iccci */
4905
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4906
{
4907
#if defined(CONFIG_USER_ONLY)
4908
    GEN_EXCP_PRIVOPC(ctx);
4909
#else
4910
    if (unlikely(!ctx->supervisor)) {
4911
        GEN_EXCP_PRIVOPC(ctx);
4912
        return;
4913
    }
4914
    /* interpreted as no-op */
4915
#endif
4916
}
4917

    
4918
/* icread */
4919
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4920
{
4921
#if defined(CONFIG_USER_ONLY)
4922
    GEN_EXCP_PRIVOPC(ctx);
4923
#else
4924
    if (unlikely(!ctx->supervisor)) {
4925
        GEN_EXCP_PRIVOPC(ctx);
4926
        return;
4927
    }
4928
    /* interpreted as no-op */
4929
#endif
4930
}
4931

    
4932
/* rfci (supervisor only) */
4933
GEN_HANDLER(rfci_40x, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4934
{
4935
#if defined(CONFIG_USER_ONLY)
4936
    GEN_EXCP_PRIVOPC(ctx);
4937
#else
4938
    if (unlikely(!ctx->supervisor)) {
4939
        GEN_EXCP_PRIVOPC(ctx);
4940
        return;
4941
    }
4942
    /* Restore CPU state */
4943
    gen_op_40x_rfci();
4944
    GEN_SYNC(ctx);
4945
#endif
4946
}
4947

    
4948
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4949
{
4950
#if defined(CONFIG_USER_ONLY)
4951
    GEN_EXCP_PRIVOPC(ctx);
4952
#else
4953
    if (unlikely(!ctx->supervisor)) {
4954
        GEN_EXCP_PRIVOPC(ctx);
4955
        return;
4956
    }
4957
    /* Restore CPU state */
4958
    gen_op_rfci();
4959
    GEN_SYNC(ctx);
4960
#endif
4961
}
4962

    
4963
/* BookE specific */
4964
/* XXX: not implemented on 440 ? */
4965
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
4966
{
4967
#if defined(CONFIG_USER_ONLY)
4968
    GEN_EXCP_PRIVOPC(ctx);
4969
#else
4970
    if (unlikely(!ctx->supervisor)) {
4971
        GEN_EXCP_PRIVOPC(ctx);
4972
        return;
4973
    }
4974
    /* Restore CPU state */
4975
    gen_op_rfdi();
4976
    GEN_SYNC(ctx);
4977
#endif
4978
}
4979

    
4980
/* XXX: not implemented on 440 ? */
4981
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
4982
{
4983
#if defined(CONFIG_USER_ONLY)
4984
    GEN_EXCP_PRIVOPC(ctx);
4985
#else
4986
    if (unlikely(!ctx->supervisor)) {
4987
        GEN_EXCP_PRIVOPC(ctx);
4988
        return;
4989
    }
4990
    /* Restore CPU state */
4991
    gen_op_rfmci();
4992
    GEN_SYNC(ctx);
4993
#endif
4994
}
4995

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

    
5025
/* tlbsx - tlbsx. */
5026
GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5027
{
5028
#if defined(CONFIG_USER_ONLY)
5029
    GEN_EXCP_PRIVOPC(ctx);
5030
#else
5031
    if (unlikely(!ctx->supervisor)) {
5032
        GEN_EXCP_PRIVOPC(ctx);
5033
        return;
5034
    }
5035
    gen_addr_reg_index(ctx);
5036
    gen_op_4xx_tlbsx();
5037
    if (Rc(ctx->opcode))
5038
        gen_op_4xx_tlbsx_check();
5039
    gen_op_store_T0_gpr(rD(ctx->opcode));
5040
#endif
5041
}
5042

    
5043
/* tlbwe */
5044
GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5045
{
5046
#if defined(CONFIG_USER_ONLY)
5047
    GEN_EXCP_PRIVOPC(ctx);
5048
#else
5049
    if (unlikely(!ctx->supervisor)) {
5050
        GEN_EXCP_PRIVOPC(ctx);
5051
        return;
5052
    }
5053
    switch (rB(ctx->opcode)) {
5054
    case 0:
5055
        gen_op_load_gpr_T0(rA(ctx->opcode));
5056
        gen_op_load_gpr_T1(rS(ctx->opcode));
5057
        gen_op_4xx_tlbwe_hi();
5058
        break;
5059
    case 1:
5060
        gen_op_load_gpr_T0(rA(ctx->opcode));
5061
        gen_op_load_gpr_T1(rS(ctx->opcode));
5062
        gen_op_4xx_tlbwe_lo();
5063
        break;
5064
    default:
5065
        GEN_EXCP_INVAL(ctx);
5066
        break;
5067
    }
5068
#endif
5069
}
5070

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

    
5097
/* tlbsx - tlbsx. */
5098
GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5099
{
5100
#if defined(CONFIG_USER_ONLY)
5101
    GEN_EXCP_PRIVOPC(ctx);
5102
#else
5103
    if (unlikely(!ctx->supervisor)) {
5104
        GEN_EXCP_PRIVOPC(ctx);
5105
        return;
5106
    }
5107
    gen_addr_reg_index(ctx);
5108
    gen_op_440_tlbsx();
5109
    if (Rc(ctx->opcode))
5110
        gen_op_4xx_tlbsx_check();
5111
    gen_op_store_T0_gpr(rD(ctx->opcode));
5112
#endif
5113
}
5114

    
5115
/* tlbwe */
5116
GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5117
{
5118
#if defined(CONFIG_USER_ONLY)
5119
    GEN_EXCP_PRIVOPC(ctx);
5120
#else
5121
    if (unlikely(!ctx->supervisor)) {
5122
        GEN_EXCP_PRIVOPC(ctx);
5123
        return;
5124
    }
5125
    switch (rB(ctx->opcode)) {
5126
    case 0:
5127
    case 1:
5128
    case 2:
5129
        gen_op_load_gpr_T0(rA(ctx->opcode));
5130
        gen_op_load_gpr_T1(rS(ctx->opcode));
5131
        gen_op_440_tlbwe(rB(ctx->opcode));
5132
        break;
5133
    default:
5134
        GEN_EXCP_INVAL(ctx);
5135
        break;
5136
    }
5137
#endif
5138
}
5139

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

    
5159
/* wrteei */
5160
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
5161
{
5162
#if defined(CONFIG_USER_ONLY)
5163
    GEN_EXCP_PRIVOPC(ctx);
5164
#else
5165
    if (unlikely(!ctx->supervisor)) {
5166
        GEN_EXCP_PRIVOPC(ctx);
5167
        return;
5168
    }
5169
    gen_op_set_T0(ctx->opcode & 0x00010000);
5170
    gen_op_wrte();
5171
    /* Stop translation to have a chance to raise an exception
5172
     * if we just set msr_ee to 1
5173
     */
5174
    GEN_STOP(ctx);
5175
#endif
5176
}
5177

    
5178
/* PowerPC 440 specific instructions */
5179
/* dlmzb */
5180
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5181
{
5182
    gen_op_load_gpr_T0(rS(ctx->opcode));
5183
    gen_op_load_gpr_T1(rB(ctx->opcode));
5184
    gen_op_440_dlmzb();
5185
    gen_op_store_T0_gpr(rA(ctx->opcode));
5186
    gen_op_store_xer_bc();
5187
    if (Rc(ctx->opcode)) {
5188
        gen_op_440_dlmzb_update_Rc();
5189
        gen_op_store_T0_crf(0);
5190
    }
5191
}
5192

    
5193
/* mbar replaces eieio on 440 */
5194
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5195
{
5196
    /* interpreted as no-op */
5197
}
5198

    
5199
/* msync replaces sync on 440 */
5200
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5201
{
5202
    /* interpreted as no-op */
5203
}
5204

    
5205
/* icbt */
5206
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5207
{
5208
    /* interpreted as no-op */
5209
    /* XXX: specification say this is treated as a load by the MMU
5210
     *      but does not generate any exception
5211
     */
5212
}
5213

    
5214
#if defined(TARGET_PPCEMB)
5215
/***                           SPE extension                               ***/
5216

    
5217
/* Register moves */
5218
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
5219
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
5220
#if 0 // unused
5221
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
5222
#endif
5223

    
5224
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
5225
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
5226
#if 0 // unused
5227
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
5228
#endif
5229

    
5230
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5231
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5232
{                                                                             \
5233
    if (Rc(ctx->opcode))                                                      \
5234
        gen_##name1(ctx);                                                     \
5235
    else                                                                      \
5236
        gen_##name0(ctx);                                                     \
5237
}
5238

    
5239
/* Handler for undefined SPE opcodes */
5240
static inline void gen_speundef (DisasContext *ctx)
5241
{
5242
    GEN_EXCP_INVAL(ctx);
5243
}
5244

    
5245
/* SPE load and stores */
5246
static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5247
{
5248
    target_long simm = rB(ctx->opcode);
5249

    
5250
    if (rA(ctx->opcode) == 0) {
5251
        gen_set_T0(simm << sh);
5252
    } else {
5253
        gen_op_load_gpr_T0(rA(ctx->opcode));
5254
        if (likely(simm != 0))
5255
            gen_op_addi(simm << sh);
5256
    }
5257
}
5258

    
5259
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5260
#if defined(CONFIG_USER_ONLY)
5261
#if defined(TARGET_PPC64)
5262
#define OP_SPE_LD_TABLE(name)                                                 \
5263
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5264
    &gen_op_spe_l##name##_raw,                                                \
5265
    &gen_op_spe_l##name##_le_raw,                                             \
5266
    &gen_op_spe_l##name##_64_raw,                                             \
5267
    &gen_op_spe_l##name##_le_64_raw,                                          \
5268
};
5269
#define OP_SPE_ST_TABLE(name)                                                 \
5270
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5271
    &gen_op_spe_st##name##_raw,                                               \
5272
    &gen_op_spe_st##name##_le_raw,                                            \
5273
    &gen_op_spe_st##name##_64_raw,                                            \
5274
    &gen_op_spe_st##name##_le_64_raw,                                         \
5275
};
5276
#else /* defined(TARGET_PPC64) */
5277
#define OP_SPE_LD_TABLE(name)                                                 \
5278
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5279
    &gen_op_spe_l##name##_raw,                                                \
5280
    &gen_op_spe_l##name##_le_raw,                                             \
5281
};
5282
#define OP_SPE_ST_TABLE(name)                                                 \
5283
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5284
    &gen_op_spe_st##name##_raw,                                               \
5285
    &gen_op_spe_st##name##_le_raw,                                            \
5286
};
5287
#endif /* defined(TARGET_PPC64) */
5288
#else /* defined(CONFIG_USER_ONLY) */
5289
#if defined(TARGET_PPC64)
5290
#define OP_SPE_LD_TABLE(name)                                                 \
5291
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5292
    &gen_op_spe_l##name##_user,                                               \
5293
    &gen_op_spe_l##name##_le_user,                                            \
5294
    &gen_op_spe_l##name##_kernel,                                             \
5295
    &gen_op_spe_l##name##_le_kernel,                                          \
5296
    &gen_op_spe_l##name##_64_user,                                            \
5297
    &gen_op_spe_l##name##_le_64_user,                                         \
5298
    &gen_op_spe_l##name##_64_kernel,                                          \
5299
    &gen_op_spe_l##name##_le_64_kernel,                                       \
5300
};
5301
#define OP_SPE_ST_TABLE(name)                                                 \
5302
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5303
    &gen_op_spe_st##name##_user,                                              \
5304
    &gen_op_spe_st##name##_le_user,                                           \
5305
    &gen_op_spe_st##name##_kernel,                                            \
5306
    &gen_op_spe_st##name##_le_kernel,                                         \
5307
    &gen_op_spe_st##name##_64_user,                                           \
5308
    &gen_op_spe_st##name##_le_64_user,                                        \
5309
    &gen_op_spe_st##name##_64_kernel,                                         \
5310
    &gen_op_spe_st##name##_le_64_kernel,                                      \
5311
};
5312
#else /* defined(TARGET_PPC64) */
5313
#define OP_SPE_LD_TABLE(name)                                                 \
5314
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5315
    &gen_op_spe_l##name##_user,                                               \
5316
    &gen_op_spe_l##name##_le_user,                                            \
5317
    &gen_op_spe_l##name##_kernel,                                             \
5318
    &gen_op_spe_l##name##_le_kernel,                                          \
5319
};
5320
#define OP_SPE_ST_TABLE(name)                                                 \
5321
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5322
    &gen_op_spe_st##name##_user,                                              \
5323
    &gen_op_spe_st##name##_le_user,                                           \
5324
    &gen_op_spe_st##name##_kernel,                                            \
5325
    &gen_op_spe_st##name##_le_kernel,                                         \
5326
};
5327
#endif /* defined(TARGET_PPC64) */
5328
#endif /* defined(CONFIG_USER_ONLY) */
5329

    
5330
#define GEN_SPE_LD(name, sh)                                                  \
5331
static inline void gen_evl##name (DisasContext *ctx)                          \
5332
{                                                                             \
5333
    if (unlikely(!ctx->spe_enabled)) {                                        \
5334
        GEN_EXCP_NO_AP(ctx);                                                  \
5335
        return;                                                               \
5336
    }                                                                         \
5337
    gen_addr_spe_imm_index(ctx, sh);                                          \
5338
    op_spe_ldst(spe_l##name);                                                 \
5339
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5340
}
5341

    
5342
#define GEN_SPE_LDX(name)                                                     \
5343
static inline void gen_evl##name##x (DisasContext *ctx)                       \
5344
{                                                                             \
5345
    if (unlikely(!ctx->spe_enabled)) {                                        \
5346
        GEN_EXCP_NO_AP(ctx);                                                  \
5347
        return;                                                               \
5348
    }                                                                         \
5349
    gen_addr_reg_index(ctx);                                                  \
5350
    op_spe_ldst(spe_l##name);                                                 \
5351
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5352
}
5353

    
5354
#define GEN_SPEOP_LD(name, sh)                                                \
5355
OP_SPE_LD_TABLE(name);                                                        \
5356
GEN_SPE_LD(name, sh);                                                         \
5357
GEN_SPE_LDX(name)
5358

    
5359
#define GEN_SPE_ST(name, sh)                                                  \
5360
static inline void gen_evst##name (DisasContext *ctx)                         \
5361
{                                                                             \
5362
    if (unlikely(!ctx->spe_enabled)) {                                        \
5363
        GEN_EXCP_NO_AP(ctx);                                                  \
5364
        return;                                                               \
5365
    }                                                                         \
5366
    gen_addr_spe_imm_index(ctx, sh);                                          \
5367
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5368
    op_spe_ldst(spe_st##name);                                                \
5369
}
5370

    
5371
#define GEN_SPE_STX(name)                                                     \
5372
static inline void gen_evst##name##x (DisasContext *ctx)                      \
5373
{                                                                             \
5374
    if (unlikely(!ctx->spe_enabled)) {                                        \
5375
        GEN_EXCP_NO_AP(ctx);                                                  \
5376
        return;                                                               \
5377
    }                                                                         \
5378
    gen_addr_reg_index(ctx);                                                  \
5379
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5380
    op_spe_ldst(spe_st##name);                                                \
5381
}
5382

    
5383
#define GEN_SPEOP_ST(name, sh)                                                \
5384
OP_SPE_ST_TABLE(name);                                                        \
5385
GEN_SPE_ST(name, sh);                                                         \
5386
GEN_SPE_STX(name)
5387

    
5388
#define GEN_SPEOP_LDST(name, sh)                                              \
5389
GEN_SPEOP_LD(name, sh);                                                       \
5390
GEN_SPEOP_ST(name, sh)
5391

    
5392
/* SPE arithmetic and logic */
5393
#define GEN_SPEOP_ARITH2(name)                                                \
5394
static inline void gen_##name (DisasContext *ctx)                             \
5395
{                                                                             \
5396
    if (unlikely(!ctx->spe_enabled)) {                                        \
5397
        GEN_EXCP_NO_AP(ctx);                                                  \
5398
        return;                                                               \
5399
    }                                                                         \
5400
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5401
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5402
    gen_op_##name();                                                          \
5403
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5404
}
5405

    
5406
#define GEN_SPEOP_ARITH1(name)                                                \
5407
static inline void gen_##name (DisasContext *ctx)                             \
5408
{                                                                             \
5409
    if (unlikely(!ctx->spe_enabled)) {                                        \
5410
        GEN_EXCP_NO_AP(ctx);                                                  \
5411
        return;                                                               \
5412
    }                                                                         \
5413
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5414
    gen_op_##name();                                                          \
5415
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5416
}
5417

    
5418
#define GEN_SPEOP_COMP(name)                                                  \
5419
static inline void gen_##name (DisasContext *ctx)                             \
5420
{                                                                             \
5421
    if (unlikely(!ctx->spe_enabled)) {                                        \
5422
        GEN_EXCP_NO_AP(ctx);                                                  \
5423
        return;                                                               \
5424
    }                                                                         \
5425
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5426
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5427
    gen_op_##name();                                                          \
5428
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5429
}
5430

    
5431
/* Logical */
5432
GEN_SPEOP_ARITH2(evand);
5433
GEN_SPEOP_ARITH2(evandc);
5434
GEN_SPEOP_ARITH2(evxor);
5435
GEN_SPEOP_ARITH2(evor);
5436
GEN_SPEOP_ARITH2(evnor);
5437
GEN_SPEOP_ARITH2(eveqv);
5438
GEN_SPEOP_ARITH2(evorc);
5439
GEN_SPEOP_ARITH2(evnand);
5440
GEN_SPEOP_ARITH2(evsrwu);
5441
GEN_SPEOP_ARITH2(evsrws);
5442
GEN_SPEOP_ARITH2(evslw);
5443
GEN_SPEOP_ARITH2(evrlw);
5444
GEN_SPEOP_ARITH2(evmergehi);
5445
GEN_SPEOP_ARITH2(evmergelo);
5446
GEN_SPEOP_ARITH2(evmergehilo);
5447
GEN_SPEOP_ARITH2(evmergelohi);
5448

    
5449
/* Arithmetic */
5450
GEN_SPEOP_ARITH2(evaddw);
5451
GEN_SPEOP_ARITH2(evsubfw);
5452
GEN_SPEOP_ARITH1(evabs);
5453
GEN_SPEOP_ARITH1(evneg);
5454
GEN_SPEOP_ARITH1(evextsb);
5455
GEN_SPEOP_ARITH1(evextsh);
5456
GEN_SPEOP_ARITH1(evrndw);
5457
GEN_SPEOP_ARITH1(evcntlzw);
5458
GEN_SPEOP_ARITH1(evcntlsw);
5459
static inline void gen_brinc (DisasContext *ctx)
5460
{
5461
    /* Note: brinc is usable even if SPE is disabled */
5462
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5463
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5464
    gen_op_brinc();
5465
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5466
}
5467

    
5468
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5469
static inline void gen_##name##i (DisasContext *ctx)                          \
5470
{                                                                             \
5471
    if (unlikely(!ctx->spe_enabled)) {                                        \
5472
        GEN_EXCP_NO_AP(ctx);                                                  \
5473
        return;                                                               \
5474
    }                                                                         \
5475
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5476
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5477
    gen_op_##name();                                                          \
5478
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5479
}
5480

    
5481
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5482
static inline void gen_##name##i (DisasContext *ctx)                          \
5483
{                                                                             \
5484
    if (unlikely(!ctx->spe_enabled)) {                                        \
5485
        GEN_EXCP_NO_AP(ctx);                                                  \
5486
        return;                                                               \
5487
    }                                                                         \
5488
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5489
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5490
    gen_op_##name();                                                          \
5491
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5492
}
5493

    
5494
GEN_SPEOP_ARITH_IMM2(evaddw);
5495
#define gen_evaddiw gen_evaddwi
5496
GEN_SPEOP_ARITH_IMM2(evsubfw);
5497
#define gen_evsubifw gen_evsubfwi
5498
GEN_SPEOP_LOGIC_IMM2(evslw);
5499
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5500
#define gen_evsrwis gen_evsrwsi
5501
GEN_SPEOP_LOGIC_IMM2(evsrws);
5502
#define gen_evsrwiu gen_evsrwui
5503
GEN_SPEOP_LOGIC_IMM2(evrlw);
5504

    
5505
static inline void gen_evsplati (DisasContext *ctx)
5506
{
5507
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5508

    
5509
    gen_op_splatwi_T0_64(imm);
5510
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5511
}
5512

    
5513
static inline void gen_evsplatfi (DisasContext *ctx)
5514
{
5515
    uint32_t imm = rA(ctx->opcode) << 27;
5516

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

    
5521
/* Comparison */
5522
GEN_SPEOP_COMP(evcmpgtu);
5523
GEN_SPEOP_COMP(evcmpgts);
5524
GEN_SPEOP_COMP(evcmpltu);
5525
GEN_SPEOP_COMP(evcmplts);
5526
GEN_SPEOP_COMP(evcmpeq);
5527

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

    
5554
static inline void gen_evsel (DisasContext *ctx)
5555
{
5556
    if (unlikely(!ctx->spe_enabled)) {
5557
        GEN_EXCP_NO_AP(ctx);
5558
        return;
5559
    }
5560
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5561
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5562
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5563
    gen_op_evsel();
5564
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5565
}
5566

    
5567
GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5568
{
5569
    gen_evsel(ctx);
5570
}
5571
GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5572
{
5573
    gen_evsel(ctx);
5574
}
5575
GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5576
{
5577
    gen_evsel(ctx);
5578
}
5579
GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5580
{
5581
    gen_evsel(ctx);
5582
}
5583

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6022
/* End opcode list */
6023
GEN_OPCODE_MARK(end);
6024

    
6025
#include "translate_init.c"
6026

    
6027
/*****************************************************************************/
6028
/* Misc PowerPC helpers */
6029
static inline uint32_t load_xer (CPUState *env)
6030
{
6031
    return (xer_so << XER_SO) |
6032
        (xer_ov << XER_OV) |
6033
        (xer_ca << XER_CA) |
6034
        (xer_bc << XER_BC) |
6035
        (xer_cmp << XER_CMP);
6036
}
6037

    
6038
void cpu_dump_state (CPUState *env, FILE *f,
6039
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6040
                     int flags)
6041
{
6042
#if defined(TARGET_PPC64) || 1
6043
#define FILL ""
6044
#define RGPL  4
6045
#define RFPL  4
6046
#else
6047
#define FILL "        "
6048
#define RGPL  8
6049
#define RFPL  4
6050
#endif
6051

    
6052
    int i;
6053

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

    
6105
#undef RGPL
6106
#undef RFPL
6107
#undef FILL
6108
}
6109

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

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

    
6157
/*****************************************************************************/
6158
static inline int gen_intermediate_code_internal (CPUState *env,
6159
                                                  TranslationBlock *tb,
6160
                                                  int search_pc)
6161
{
6162
    DisasContext ctx, *ctxp = &ctx;
6163
    opc_handler_t **table, *handler;
6164
    target_ulong pc_start;
6165
    uint16_t *gen_opc_end;
6166
    int j, lj = -1;
6167

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

    
6364
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6365
{
6366
    return gen_intermediate_code_internal(env, tb, 0);
6367
}
6368

    
6369
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6370
{
6371
    return gen_intermediate_code_internal(env, tb, 1);
6372
}