Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ daf4f96e

History | View | Annotate | Download (211.2 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
            } else {
3000
#if defined(TARGET_PPC64)
3001
                if (ctx->sf_mode)
3002
                    gen_op_b_T1_64();
3003
                else
3004
#endif
3005
                    gen_op_b_T1();
3006
                gen_op_reset_T0();
3007
            }
3008
            goto no_test;
3009
        }
3010
    } else {
3011
        mask = 1 << (3 - (bi & 0x03));
3012
        gen_op_load_crf_T0(bi >> 2);
3013
        if (bo & 0x8) {
3014
            switch (bo & 0x6) {
3015
            case 0:
3016
#if defined(TARGET_PPC64)
3017
                if (ctx->sf_mode)
3018
                    gen_op_test_ctr_true_64(mask);
3019
                else
3020
#endif
3021
                    gen_op_test_ctr_true(mask);
3022
                break;
3023
            case 2:
3024
#if defined(TARGET_PPC64)
3025
                if (ctx->sf_mode)
3026
                    gen_op_test_ctrz_true_64(mask);
3027
                else
3028
#endif
3029
                    gen_op_test_ctrz_true(mask);
3030
                break;
3031
            default:
3032
            case 4:
3033
            case 6:
3034
                gen_op_test_true(mask);
3035
                break;
3036
            }
3037
        } else {
3038
            switch (bo & 0x6) {
3039
            case 0:
3040
#if defined(TARGET_PPC64)
3041
                if (ctx->sf_mode)
3042
                    gen_op_test_ctr_false_64(mask);
3043
                else
3044
#endif
3045
                    gen_op_test_ctr_false(mask);
3046
                break;
3047
            case 2:
3048
#if defined(TARGET_PPC64)
3049
                if (ctx->sf_mode)
3050
                    gen_op_test_ctrz_false_64(mask);
3051
                else
3052
#endif
3053
                    gen_op_test_ctrz_false(mask);
3054
                break;
3055
            default:
3056
            case 4:
3057
            case 6:
3058
                gen_op_test_false(mask);
3059
                break;
3060
            }
3061
        }
3062
    }
3063
    if (type == BCOND_IM) {
3064
        int l1 = gen_new_label();
3065
        gen_op_jz_T0(l1);
3066
        gen_goto_tb(ctx, 0, target);
3067
        gen_set_label(l1);
3068
        gen_goto_tb(ctx, 1, ctx->nip);
3069
    } else {
3070
#if defined(TARGET_PPC64)
3071
        if (ctx->sf_mode)
3072
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
3073
        else
3074
#endif
3075
            gen_op_btest_T1(ctx->nip);
3076
        gen_op_reset_T0();
3077
    no_test:
3078
        if (ctx->singlestep_enabled)
3079
            gen_op_debug();
3080
        gen_op_exit_tb();
3081
    }
3082
    ctx->exception = POWERPC_EXCP_BRANCH;
3083
}
3084

    
3085
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3086
{
3087
    gen_bcond(ctx, BCOND_IM);
3088
}
3089

    
3090
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3091
{
3092
    gen_bcond(ctx, BCOND_CTR);
3093
}
3094

    
3095
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3096
{
3097
    gen_bcond(ctx, BCOND_LR);
3098
}
3099

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

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

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

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

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

    
3189
/* sc */
3190
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3191
{
3192
    uint32_t lev;
3193

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

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

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

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

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

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

    
3255
/* mfcr */
3256
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3257
{
3258
    uint32_t crm, crn;
3259

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

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

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

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

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

    
3340
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3341
{
3342
    gen_op_mfspr(ctx);
3343
}
3344

    
3345
/* mftb */
3346
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3347
{
3348
    gen_op_mfspr(ctx);
3349
}
3350

    
3351
/* mtcrf */
3352
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3353
{
3354
    uint32_t crm, crn;
3355

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

    
3368
/* mtmsr */
3369
#if defined(TARGET_PPC64)
3370
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3371
{
3372
#if defined(CONFIG_USER_ONLY)
3373
    GEN_EXCP_PRIVREG(ctx);
3374
#else
3375
    if (unlikely(!ctx->supervisor)) {
3376
        GEN_EXCP_PRIVREG(ctx);
3377
        return;
3378
    }
3379
    gen_op_load_gpr_T0(rS(ctx->opcode));
3380
    if (ctx->opcode & 0x00010000) {
3381
        /* Special form that does not need any synchronisation */
3382
        gen_op_update_riee();
3383
    } else {
3384
        gen_update_nip(ctx, ctx->nip);
3385
        gen_op_store_msr();
3386
        /* Must stop the translation as machine state (may have) changed */
3387
        /* Note that mtmsr is not always defined as context-synchronizing */
3388
        GEN_STOP(ctx);
3389
    }
3390
#endif
3391
}
3392
#endif
3393

    
3394
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3395
{
3396
#if defined(CONFIG_USER_ONLY)
3397
    GEN_EXCP_PRIVREG(ctx);
3398
#else
3399
    if (unlikely(!ctx->supervisor)) {
3400
        GEN_EXCP_PRIVREG(ctx);
3401
        return;
3402
    }
3403
    gen_op_load_gpr_T0(rS(ctx->opcode));
3404
    if (ctx->opcode & 0x00010000) {
3405
        /* Special form that does not need any synchronisation */
3406
        gen_op_update_riee();
3407
    } else {
3408
        gen_update_nip(ctx, ctx->nip);
3409
#if defined(TARGET_PPC64)
3410
        if (!ctx->sf_mode)
3411
            gen_op_store_msr_32();
3412
        else
3413
#endif
3414
            gen_op_store_msr();
3415
        /* Must stop the translation as machine state (may have) changed */
3416
        /* Note that mtmsrd is not always defined as context-synchronizing */
3417
        GEN_STOP(ctx);
3418
    }
3419
#endif
3420
}
3421

    
3422
/* mtspr */
3423
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3424
{
3425
    void (*write_cb)(void *opaque, int sprn);
3426
    uint32_t sprn = SPR(ctx->opcode);
3427

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

    
3464
/***                         Cache management                              ***/
3465
/* For now, all those will be implemented as nop:
3466
 * this is valid, regarding the PowerPC specs...
3467
 * We just have to flush tb while invalidating instruction cache lines...
3468
 */
3469
/* dcbf */
3470
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3471
{
3472
    gen_addr_reg_index(ctx);
3473
    op_ldst(lbz);
3474
}
3475

    
3476
/* dcbi (Supervisor only) */
3477
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3478
{
3479
#if defined(CONFIG_USER_ONLY)
3480
    GEN_EXCP_PRIVOPC(ctx);
3481
#else
3482
    if (unlikely(!ctx->supervisor)) {
3483
        GEN_EXCP_PRIVOPC(ctx);
3484
        return;
3485
    }
3486
    gen_addr_reg_index(ctx);
3487
    /* XXX: specification says this should be treated as a store by the MMU */
3488
    //op_ldst(lbz);
3489
    op_ldst(stb);
3490
#endif
3491
}
3492

    
3493
/* dcdst */
3494
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3495
{
3496
    /* XXX: specification say this is treated as a load by the MMU */
3497
    gen_addr_reg_index(ctx);
3498
    op_ldst(lbz);
3499
}
3500

    
3501
/* dcbt */
3502
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3503
{
3504
    /* interpreted as no-op */
3505
    /* XXX: specification say this is treated as a load by the MMU
3506
     *      but does not generate any exception
3507
     */
3508
}
3509

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

    
3519
/* dcbz */
3520
#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3521
#if defined(TARGET_PPC64)
3522
#if defined(CONFIG_USER_ONLY)
3523
static GenOpFunc *gen_op_dcbz[] = {
3524
    &gen_op_dcbz_raw,
3525
    &gen_op_dcbz_raw,
3526
    &gen_op_dcbz_64_raw,
3527
    &gen_op_dcbz_64_raw,
3528
};
3529
#else
3530
static GenOpFunc *gen_op_dcbz[] = {
3531
    &gen_op_dcbz_user,
3532
    &gen_op_dcbz_user,
3533
    &gen_op_dcbz_kernel,
3534
    &gen_op_dcbz_kernel,
3535
    &gen_op_dcbz_64_user,
3536
    &gen_op_dcbz_64_user,
3537
    &gen_op_dcbz_64_kernel,
3538
    &gen_op_dcbz_64_kernel,
3539
};
3540
#endif
3541
#else
3542
#if defined(CONFIG_USER_ONLY)
3543
static GenOpFunc *gen_op_dcbz[] = {
3544
    &gen_op_dcbz_raw,
3545
    &gen_op_dcbz_raw,
3546
};
3547
#else
3548
static GenOpFunc *gen_op_dcbz[] = {
3549
    &gen_op_dcbz_user,
3550
    &gen_op_dcbz_user,
3551
    &gen_op_dcbz_kernel,
3552
    &gen_op_dcbz_kernel,
3553
};
3554
#endif
3555
#endif
3556

    
3557
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3558
{
3559
    gen_addr_reg_index(ctx);
3560
    op_dcbz();
3561
    gen_op_check_reservation();
3562
}
3563

    
3564
/* icbi */
3565
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3566
#if defined(TARGET_PPC64)
3567
#if defined(CONFIG_USER_ONLY)
3568
static GenOpFunc *gen_op_icbi[] = {
3569
    &gen_op_icbi_raw,
3570
    &gen_op_icbi_raw,
3571
    &gen_op_icbi_64_raw,
3572
    &gen_op_icbi_64_raw,
3573
};
3574
#else
3575
static GenOpFunc *gen_op_icbi[] = {
3576
    &gen_op_icbi_user,
3577
    &gen_op_icbi_user,
3578
    &gen_op_icbi_kernel,
3579
    &gen_op_icbi_kernel,
3580
    &gen_op_icbi_64_user,
3581
    &gen_op_icbi_64_user,
3582
    &gen_op_icbi_64_kernel,
3583
    &gen_op_icbi_64_kernel,
3584
};
3585
#endif
3586
#else
3587
#if defined(CONFIG_USER_ONLY)
3588
static GenOpFunc *gen_op_icbi[] = {
3589
    &gen_op_icbi_raw,
3590
    &gen_op_icbi_raw,
3591
};
3592
#else
3593
static GenOpFunc *gen_op_icbi[] = {
3594
    &gen_op_icbi_user,
3595
    &gen_op_icbi_user,
3596
    &gen_op_icbi_kernel,
3597
    &gen_op_icbi_kernel,
3598
};
3599
#endif
3600
#endif
3601

    
3602
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3603
{
3604
    gen_addr_reg_index(ctx);
3605
    op_icbi();
3606
}
3607

    
3608
/* Optional: */
3609
/* dcba */
3610
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3611
{
3612
    /* interpreted as no-op */
3613
    /* XXX: specification say this is treated as a store by the MMU
3614
     *      but does not generate any exception
3615
     */
3616
}
3617

    
3618
/***                    Segment register manipulation                      ***/
3619
/* Supervisor only: */
3620
/* mfsr */
3621
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3622
{
3623
#if defined(CONFIG_USER_ONLY)
3624
    GEN_EXCP_PRIVREG(ctx);
3625
#else
3626
    if (unlikely(!ctx->supervisor)) {
3627
        GEN_EXCP_PRIVREG(ctx);
3628
        return;
3629
    }
3630
    gen_op_set_T1(SR(ctx->opcode));
3631
    gen_op_load_sr();
3632
    gen_op_store_T0_gpr(rD(ctx->opcode));
3633
#endif
3634
}
3635

    
3636
/* mfsrin */
3637
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3638
{
3639
#if defined(CONFIG_USER_ONLY)
3640
    GEN_EXCP_PRIVREG(ctx);
3641
#else
3642
    if (unlikely(!ctx->supervisor)) {
3643
        GEN_EXCP_PRIVREG(ctx);
3644
        return;
3645
    }
3646
    gen_op_load_gpr_T1(rB(ctx->opcode));
3647
    gen_op_srli_T1(28);
3648
    gen_op_load_sr();
3649
    gen_op_store_T0_gpr(rD(ctx->opcode));
3650
#endif
3651
}
3652

    
3653
/* mtsr */
3654
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3655
{
3656
#if defined(CONFIG_USER_ONLY)
3657
    GEN_EXCP_PRIVREG(ctx);
3658
#else
3659
    if (unlikely(!ctx->supervisor)) {
3660
        GEN_EXCP_PRIVREG(ctx);
3661
        return;
3662
    }
3663
    gen_op_load_gpr_T0(rS(ctx->opcode));
3664
    gen_op_set_T1(SR(ctx->opcode));
3665
    gen_op_store_sr();
3666
#endif
3667
}
3668

    
3669
/* mtsrin */
3670
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3671
{
3672
#if defined(CONFIG_USER_ONLY)
3673
    GEN_EXCP_PRIVREG(ctx);
3674
#else
3675
    if (unlikely(!ctx->supervisor)) {
3676
        GEN_EXCP_PRIVREG(ctx);
3677
        return;
3678
    }
3679
    gen_op_load_gpr_T0(rS(ctx->opcode));
3680
    gen_op_load_gpr_T1(rB(ctx->opcode));
3681
    gen_op_srli_T1(28);
3682
    gen_op_store_sr();
3683
#endif
3684
}
3685

    
3686
/***                      Lookaside buffer management                      ***/
3687
/* Optional & supervisor only: */
3688
/* tlbia */
3689
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3690
{
3691
#if defined(CONFIG_USER_ONLY)
3692
    GEN_EXCP_PRIVOPC(ctx);
3693
#else
3694
    if (unlikely(!ctx->supervisor)) {
3695
        if (loglevel != 0)
3696
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3697
        GEN_EXCP_PRIVOPC(ctx);
3698
        return;
3699
    }
3700
    gen_op_tlbia();
3701
#endif
3702
}
3703

    
3704
/* tlbie */
3705
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3706
{
3707
#if defined(CONFIG_USER_ONLY)
3708
    GEN_EXCP_PRIVOPC(ctx);
3709
#else
3710
    if (unlikely(!ctx->supervisor)) {
3711
        GEN_EXCP_PRIVOPC(ctx);
3712
        return;
3713
    }
3714
    gen_op_load_gpr_T0(rB(ctx->opcode));
3715
#if defined(TARGET_PPC64)
3716
    if (ctx->sf_mode)
3717
        gen_op_tlbie_64();
3718
    else
3719
#endif
3720
        gen_op_tlbie();
3721
#endif
3722
}
3723

    
3724
/* tlbsync */
3725
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3726
{
3727
#if defined(CONFIG_USER_ONLY)
3728
    GEN_EXCP_PRIVOPC(ctx);
3729
#else
3730
    if (unlikely(!ctx->supervisor)) {
3731
        GEN_EXCP_PRIVOPC(ctx);
3732
        return;
3733
    }
3734
    /* This has no effect: it should ensure that all previous
3735
     * tlbie have completed
3736
     */
3737
    GEN_STOP(ctx);
3738
#endif
3739
}
3740

    
3741
#if defined(TARGET_PPC64)
3742
/* slbia */
3743
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3744
{
3745
#if defined(CONFIG_USER_ONLY)
3746
    GEN_EXCP_PRIVOPC(ctx);
3747
#else
3748
    if (unlikely(!ctx->supervisor)) {
3749
        if (loglevel != 0)
3750
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3751
        GEN_EXCP_PRIVOPC(ctx);
3752
        return;
3753
    }
3754
    gen_op_slbia();
3755
#endif
3756
}
3757

    
3758
/* slbie */
3759
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3760
{
3761
#if defined(CONFIG_USER_ONLY)
3762
    GEN_EXCP_PRIVOPC(ctx);
3763
#else
3764
    if (unlikely(!ctx->supervisor)) {
3765
        GEN_EXCP_PRIVOPC(ctx);
3766
        return;
3767
    }
3768
    gen_op_load_gpr_T0(rB(ctx->opcode));
3769
    gen_op_slbie();
3770
#endif
3771
}
3772
#endif
3773

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

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

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

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

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

    
3879
/* clcs */
3880
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3881
{
3882
    gen_op_load_gpr_T0(rA(ctx->opcode));
3883
    gen_op_POWER_clcs();
3884
    gen_op_store_T0_gpr(rD(ctx->opcode));
3885
}
3886

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

    
3898
/* divo - divo. */
3899
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 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_divo();
3904
    gen_op_store_T0_gpr(rD(ctx->opcode));
3905
    if (unlikely(Rc(ctx->opcode) != 0))
3906
        gen_set_Rc0(ctx);
3907
}
3908

    
3909
/* divs - divs. */
3910
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 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_divs();
3915
    gen_op_store_T0_gpr(rD(ctx->opcode));
3916
    if (unlikely(Rc(ctx->opcode) != 0))
3917
        gen_set_Rc0(ctx);
3918
}
3919

    
3920
/* divso - divso. */
3921
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 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_divso();
3926
    gen_op_store_T0_gpr(rD(ctx->opcode));
3927
    if (unlikely(Rc(ctx->opcode) != 0))
3928
        gen_set_Rc0(ctx);
3929
}
3930

    
3931
/* doz - doz. */
3932
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 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_doz();
3937
    gen_op_store_T0_gpr(rD(ctx->opcode));
3938
    if (unlikely(Rc(ctx->opcode) != 0))
3939
        gen_set_Rc0(ctx);
3940
}
3941

    
3942
/* dozo - dozo. */
3943
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 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_dozo();
3948
    gen_op_store_T0_gpr(rD(ctx->opcode));
3949
    if (unlikely(Rc(ctx->opcode) != 0))
3950
        gen_set_Rc0(ctx);
3951
}
3952

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

    
3962
/* As lscbx load from memory byte after byte, it's always endian safe */
3963
#define op_POWER_lscbx(start, ra, rb) \
3964
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3965
#if defined(CONFIG_USER_ONLY)
3966
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3967
    &gen_op_POWER_lscbx_raw,
3968
    &gen_op_POWER_lscbx_raw,
3969
};
3970
#else
3971
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3972
    &gen_op_POWER_lscbx_user,
3973
    &gen_op_POWER_lscbx_user,
3974
    &gen_op_POWER_lscbx_kernel,
3975
    &gen_op_POWER_lscbx_kernel,
3976
};
3977
#endif
3978

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

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

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

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

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

    
4033
/* mulo - mulo. */
4034
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 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_mulo();
4039
    gen_op_store_T0_gpr(rD(ctx->opcode));
4040
    if (unlikely(Rc(ctx->opcode) != 0))
4041
        gen_set_Rc0(ctx);
4042
}
4043

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

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

    
4064
/* rlmi - rlmi. */
4065
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4066
{
4067
    uint32_t mb, me;
4068

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

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

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

    
4103
/* sleq - sleq. */
4104
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 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_sleq();
4109
    gen_op_store_T0_gpr(rA(ctx->opcode));
4110
    if (unlikely(Rc(ctx->opcode) != 0))
4111
        gen_set_Rc0(ctx);
4112
}
4113

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

    
4125
/* slliq - slliq. */
4126
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 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_sleq();
4131
    gen_op_store_T0_gpr(rA(ctx->opcode));
4132
    if (unlikely(Rc(ctx->opcode) != 0))
4133
        gen_set_Rc0(ctx);
4134
}
4135

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

    
4147
/* slq - slq. */
4148
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 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_slq();
4153
    gen_op_store_T0_gpr(rA(ctx->opcode));
4154
    if (unlikely(Rc(ctx->opcode) != 0))
4155
        gen_set_Rc0(ctx);
4156
}
4157

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

    
4169
/* sraq - sraq. */
4170
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4171
{
4172
    gen_op_load_gpr_T0(rS(ctx->opcode));
4173
    gen_op_load_gpr_T1(rB(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
/* sre - sre. */
4181
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 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_sre();
4186
    gen_op_store_T0_gpr(rA(ctx->opcode));
4187
    if (unlikely(Rc(ctx->opcode) != 0))
4188
        gen_set_Rc0(ctx);
4189
}
4190

    
4191
/* srea - srea. */
4192
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 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_srea();
4197
    gen_op_store_T0_gpr(rA(ctx->opcode));
4198
    if (unlikely(Rc(ctx->opcode) != 0))
4199
        gen_set_Rc0(ctx);
4200
}
4201

    
4202
/* sreq */
4203
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 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_sreq();
4208
    gen_op_store_T0_gpr(rA(ctx->opcode));
4209
    if (unlikely(Rc(ctx->opcode) != 0))
4210
        gen_set_Rc0(ctx);
4211
}
4212

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

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

    
4236
/* srlq */
4237
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4238
{
4239
    gen_op_load_gpr_T0(rS(ctx->opcode));
4240
    gen_op_load_gpr_T1(rB(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
/* srq */
4248
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 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_srq();
4253
    gen_op_store_T0_gpr(rA(ctx->opcode));
4254
    if (unlikely(Rc(ctx->opcode) != 0))
4255
        gen_set_Rc0(ctx);
4256
}
4257

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

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

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

    
4289
/* 602 - 603 - G2 TLB management */
4290
/* tlbld */
4291
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4292
{
4293
#if defined(CONFIG_USER_ONLY)
4294
    GEN_EXCP_PRIVOPC(ctx);
4295
#else
4296
    if (unlikely(!ctx->supervisor)) {
4297
        GEN_EXCP_PRIVOPC(ctx);
4298
        return;
4299
    }
4300
    gen_op_load_gpr_T0(rB(ctx->opcode));
4301
    gen_op_6xx_tlbld();
4302
#endif
4303
}
4304

    
4305
/* tlbli */
4306
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4307
{
4308
#if defined(CONFIG_USER_ONLY)
4309
    GEN_EXCP_PRIVOPC(ctx);
4310
#else
4311
    if (unlikely(!ctx->supervisor)) {
4312
        GEN_EXCP_PRIVOPC(ctx);
4313
        return;
4314
    }
4315
    gen_op_load_gpr_T0(rB(ctx->opcode));
4316
    gen_op_6xx_tlbli();
4317
#endif
4318
}
4319

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

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

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

    
4347
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4348
{
4349
#if defined(CONFIG_USER_ONLY)
4350
    GEN_EXCP_PRIVOPC(ctx);
4351
#else
4352
    if (unlikely(!ctx->supervisor)) {
4353
        GEN_EXCP_PRIVOPC(ctx);
4354
        return;
4355
    }
4356
    int ra = rA(ctx->opcode);
4357
    int rd = rD(ctx->opcode);
4358

    
4359
    gen_addr_reg_index(ctx);
4360
    gen_op_POWER_mfsri();
4361
    gen_op_store_T0_gpr(rd);
4362
    if (ra != 0 && ra != rd)
4363
        gen_op_store_T1_gpr(ra);
4364
#endif
4365
}
4366

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

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

    
4396
/* svc is not implemented for now */
4397

    
4398
/* POWER2 specific instructions */
4399
/* Quad manipulation (load/store two floats at a time) */
4400
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4401
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4402
#if defined(CONFIG_USER_ONLY)
4403
static GenOpFunc *gen_op_POWER2_lfq[] = {
4404
    &gen_op_POWER2_lfq_le_raw,
4405
    &gen_op_POWER2_lfq_raw,
4406
};
4407
static GenOpFunc *gen_op_POWER2_stfq[] = {
4408
    &gen_op_POWER2_stfq_le_raw,
4409
    &gen_op_POWER2_stfq_raw,
4410
};
4411
#else
4412
static GenOpFunc *gen_op_POWER2_lfq[] = {
4413
    &gen_op_POWER2_lfq_le_user,
4414
    &gen_op_POWER2_lfq_user,
4415
    &gen_op_POWER2_lfq_le_kernel,
4416
    &gen_op_POWER2_lfq_kernel,
4417
};
4418
static GenOpFunc *gen_op_POWER2_stfq[] = {
4419
    &gen_op_POWER2_stfq_le_user,
4420
    &gen_op_POWER2_stfq_user,
4421
    &gen_op_POWER2_stfq_le_kernel,
4422
    &gen_op_POWER2_stfq_kernel,
4423
};
4424
#endif
4425

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4640
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4641
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4642
{                                                                             \
4643
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4644
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4645
}
4646

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

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

    
4733
/* mfdcr */
4734
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4735
{
4736
#if defined(CONFIG_USER_ONLY)
4737
    GEN_EXCP_PRIVREG(ctx);
4738
#else
4739
    uint32_t dcrn = SPR(ctx->opcode);
4740

    
4741
    if (unlikely(!ctx->supervisor)) {
4742
        GEN_EXCP_PRIVREG(ctx);
4743
        return;
4744
    }
4745
    gen_op_set_T0(dcrn);
4746
    gen_op_load_dcr();
4747
    gen_op_store_T0_gpr(rD(ctx->opcode));
4748
#endif
4749
}
4750

    
4751
/* mtdcr */
4752
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4753
{
4754
#if defined(CONFIG_USER_ONLY)
4755
    GEN_EXCP_PRIVREG(ctx);
4756
#else
4757
    uint32_t dcrn = SPR(ctx->opcode);
4758

    
4759
    if (unlikely(!ctx->supervisor)) {
4760
        GEN_EXCP_PRIVREG(ctx);
4761
        return;
4762
    }
4763
    gen_op_set_T0(dcrn);
4764
    gen_op_load_gpr_T1(rS(ctx->opcode));
4765
    gen_op_store_dcr();
4766
#endif
4767
}
4768

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

    
4787
/* mtdcrx */
4788
/* XXX: not implemented on 440 ? */
4789
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT)
4790
{
4791
#if defined(CONFIG_USER_ONLY)
4792
    GEN_EXCP_PRIVREG(ctx);
4793
#else
4794
    if (unlikely(!ctx->supervisor)) {
4795
        GEN_EXCP_PRIVREG(ctx);
4796
        return;
4797
    }
4798
    gen_op_load_gpr_T0(rA(ctx->opcode));
4799
    gen_op_load_gpr_T1(rS(ctx->opcode));
4800
    gen_op_store_dcr();
4801
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4802
#endif
4803
}
4804

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

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

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

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

    
4853
/* icbt */
4854
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4855
{
4856
    /* interpreted as no-op */
4857
    /* XXX: specification say this is treated as a load by the MMU
4858
     *      but does not generate any exception
4859
     */
4860
}
4861

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

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

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

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

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

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

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

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

    
5001
/* tlbwe */
5002
GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5003
{
5004
#if defined(CONFIG_USER_ONLY)
5005
    GEN_EXCP_PRIVOPC(ctx);
5006
#else
5007
    if (unlikely(!ctx->supervisor)) {
5008
        GEN_EXCP_PRIVOPC(ctx);
5009
        return;
5010
    }
5011
    switch (rB(ctx->opcode)) {
5012
    case 0:
5013
        gen_op_load_gpr_T0(rA(ctx->opcode));
5014
        gen_op_load_gpr_T1(rS(ctx->opcode));
5015
        gen_op_4xx_tlbwe_hi();
5016
        break;
5017
    case 1:
5018
        gen_op_load_gpr_T0(rA(ctx->opcode));
5019
        gen_op_load_gpr_T1(rS(ctx->opcode));
5020
        gen_op_4xx_tlbwe_lo();
5021
        break;
5022
    default:
5023
        GEN_EXCP_INVAL(ctx);
5024
        break;
5025
    }
5026
#endif
5027
}
5028

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

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

    
5073
/* tlbwe */
5074
GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5075
{
5076
#if defined(CONFIG_USER_ONLY)
5077
    GEN_EXCP_PRIVOPC(ctx);
5078
#else
5079
    if (unlikely(!ctx->supervisor)) {
5080
        GEN_EXCP_PRIVOPC(ctx);
5081
        return;
5082
    }
5083
    switch (rB(ctx->opcode)) {
5084
    case 0:
5085
    case 1:
5086
    case 2:
5087
        gen_op_load_gpr_T0(rA(ctx->opcode));
5088
        gen_op_load_gpr_T1(rS(ctx->opcode));
5089
        gen_op_440_tlbwe(rB(ctx->opcode));
5090
        break;
5091
    default:
5092
        GEN_EXCP_INVAL(ctx);
5093
        break;
5094
    }
5095
#endif
5096
}
5097

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

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

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

    
5151
/* mbar replaces eieio on 440 */
5152
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5153
{
5154
    /* interpreted as no-op */
5155
}
5156

    
5157
/* msync replaces sync on 440 */
5158
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5159
{
5160
    /* interpreted as no-op */
5161
}
5162

    
5163
/* icbt */
5164
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5165
{
5166
    /* interpreted as no-op */
5167
    /* XXX: specification say this is treated as a load by the MMU
5168
     *      but does not generate any exception
5169
     */
5170
}
5171

    
5172
#if defined(TARGET_PPCEMB)
5173
/***                           SPE extension                               ***/
5174

    
5175
/* Register moves */
5176
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
5177
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
5178
#if 0 // unused
5179
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
5180
#endif
5181

    
5182
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
5183
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
5184
#if 0 // unused
5185
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
5186
#endif
5187

    
5188
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5189
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5190
{                                                                             \
5191
    if (Rc(ctx->opcode))                                                      \
5192
        gen_##name1(ctx);                                                     \
5193
    else                                                                      \
5194
        gen_##name0(ctx);                                                     \
5195
}
5196

    
5197
/* Handler for undefined SPE opcodes */
5198
static inline void gen_speundef (DisasContext *ctx)
5199
{
5200
    GEN_EXCP_INVAL(ctx);
5201
}
5202

    
5203
/* SPE load and stores */
5204
static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5205
{
5206
    target_long simm = rB(ctx->opcode);
5207

    
5208
    if (rA(ctx->opcode) == 0) {
5209
        gen_set_T0(simm << sh);
5210
    } else {
5211
        gen_op_load_gpr_T0(rA(ctx->opcode));
5212
        if (likely(simm != 0))
5213
            gen_op_addi(simm << sh);
5214
    }
5215
}
5216

    
5217
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5218
#if defined(CONFIG_USER_ONLY)
5219
#if defined(TARGET_PPC64)
5220
#define OP_SPE_LD_TABLE(name)                                                 \
5221
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5222
    &gen_op_spe_l##name##_raw,                                                \
5223
    &gen_op_spe_l##name##_le_raw,                                             \
5224
    &gen_op_spe_l##name##_64_raw,                                             \
5225
    &gen_op_spe_l##name##_le_64_raw,                                          \
5226
};
5227
#define OP_SPE_ST_TABLE(name)                                                 \
5228
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5229
    &gen_op_spe_st##name##_raw,                                               \
5230
    &gen_op_spe_st##name##_le_raw,                                            \
5231
    &gen_op_spe_st##name##_64_raw,                                            \
5232
    &gen_op_spe_st##name##_le_64_raw,                                         \
5233
};
5234
#else /* defined(TARGET_PPC64) */
5235
#define OP_SPE_LD_TABLE(name)                                                 \
5236
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5237
    &gen_op_spe_l##name##_raw,                                                \
5238
    &gen_op_spe_l##name##_le_raw,                                             \
5239
};
5240
#define OP_SPE_ST_TABLE(name)                                                 \
5241
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5242
    &gen_op_spe_st##name##_raw,                                               \
5243
    &gen_op_spe_st##name##_le_raw,                                            \
5244
};
5245
#endif /* defined(TARGET_PPC64) */
5246
#else /* defined(CONFIG_USER_ONLY) */
5247
#if defined(TARGET_PPC64)
5248
#define OP_SPE_LD_TABLE(name)                                                 \
5249
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5250
    &gen_op_spe_l##name##_user,                                               \
5251
    &gen_op_spe_l##name##_le_user,                                            \
5252
    &gen_op_spe_l##name##_kernel,                                             \
5253
    &gen_op_spe_l##name##_le_kernel,                                          \
5254
    &gen_op_spe_l##name##_64_user,                                            \
5255
    &gen_op_spe_l##name##_le_64_user,                                         \
5256
    &gen_op_spe_l##name##_64_kernel,                                          \
5257
    &gen_op_spe_l##name##_le_64_kernel,                                       \
5258
};
5259
#define OP_SPE_ST_TABLE(name)                                                 \
5260
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5261
    &gen_op_spe_st##name##_user,                                              \
5262
    &gen_op_spe_st##name##_le_user,                                           \
5263
    &gen_op_spe_st##name##_kernel,                                            \
5264
    &gen_op_spe_st##name##_le_kernel,                                         \
5265
    &gen_op_spe_st##name##_64_user,                                           \
5266
    &gen_op_spe_st##name##_le_64_user,                                        \
5267
    &gen_op_spe_st##name##_64_kernel,                                         \
5268
    &gen_op_spe_st##name##_le_64_kernel,                                      \
5269
};
5270
#else /* defined(TARGET_PPC64) */
5271
#define OP_SPE_LD_TABLE(name)                                                 \
5272
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5273
    &gen_op_spe_l##name##_user,                                               \
5274
    &gen_op_spe_l##name##_le_user,                                            \
5275
    &gen_op_spe_l##name##_kernel,                                             \
5276
    &gen_op_spe_l##name##_le_kernel,                                          \
5277
};
5278
#define OP_SPE_ST_TABLE(name)                                                 \
5279
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5280
    &gen_op_spe_st##name##_user,                                              \
5281
    &gen_op_spe_st##name##_le_user,                                           \
5282
    &gen_op_spe_st##name##_kernel,                                            \
5283
    &gen_op_spe_st##name##_le_kernel,                                         \
5284
};
5285
#endif /* defined(TARGET_PPC64) */
5286
#endif /* defined(CONFIG_USER_ONLY) */
5287

    
5288
#define GEN_SPE_LD(name, sh)                                                  \
5289
static inline void gen_evl##name (DisasContext *ctx)                          \
5290
{                                                                             \
5291
    if (unlikely(!ctx->spe_enabled)) {                                        \
5292
        GEN_EXCP_NO_AP(ctx);                                                  \
5293
        return;                                                               \
5294
    }                                                                         \
5295
    gen_addr_spe_imm_index(ctx, sh);                                          \
5296
    op_spe_ldst(spe_l##name);                                                 \
5297
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5298
}
5299

    
5300
#define GEN_SPE_LDX(name)                                                     \
5301
static inline void gen_evl##name##x (DisasContext *ctx)                       \
5302
{                                                                             \
5303
    if (unlikely(!ctx->spe_enabled)) {                                        \
5304
        GEN_EXCP_NO_AP(ctx);                                                  \
5305
        return;                                                               \
5306
    }                                                                         \
5307
    gen_addr_reg_index(ctx);                                                  \
5308
    op_spe_ldst(spe_l##name);                                                 \
5309
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5310
}
5311

    
5312
#define GEN_SPEOP_LD(name, sh)                                                \
5313
OP_SPE_LD_TABLE(name);                                                        \
5314
GEN_SPE_LD(name, sh);                                                         \
5315
GEN_SPE_LDX(name)
5316

    
5317
#define GEN_SPE_ST(name, sh)                                                  \
5318
static inline void gen_evst##name (DisasContext *ctx)                         \
5319
{                                                                             \
5320
    if (unlikely(!ctx->spe_enabled)) {                                        \
5321
        GEN_EXCP_NO_AP(ctx);                                                  \
5322
        return;                                                               \
5323
    }                                                                         \
5324
    gen_addr_spe_imm_index(ctx, sh);                                          \
5325
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5326
    op_spe_ldst(spe_st##name);                                                \
5327
}
5328

    
5329
#define GEN_SPE_STX(name)                                                     \
5330
static inline void gen_evst##name##x (DisasContext *ctx)                      \
5331
{                                                                             \
5332
    if (unlikely(!ctx->spe_enabled)) {                                        \
5333
        GEN_EXCP_NO_AP(ctx);                                                  \
5334
        return;                                                               \
5335
    }                                                                         \
5336
    gen_addr_reg_index(ctx);                                                  \
5337
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5338
    op_spe_ldst(spe_st##name);                                                \
5339
}
5340

    
5341
#define GEN_SPEOP_ST(name, sh)                                                \
5342
OP_SPE_ST_TABLE(name);                                                        \
5343
GEN_SPE_ST(name, sh);                                                         \
5344
GEN_SPE_STX(name)
5345

    
5346
#define GEN_SPEOP_LDST(name, sh)                                              \
5347
GEN_SPEOP_LD(name, sh);                                                       \
5348
GEN_SPEOP_ST(name, sh)
5349

    
5350
/* SPE arithmetic and logic */
5351
#define GEN_SPEOP_ARITH2(name)                                                \
5352
static inline void gen_##name (DisasContext *ctx)                             \
5353
{                                                                             \
5354
    if (unlikely(!ctx->spe_enabled)) {                                        \
5355
        GEN_EXCP_NO_AP(ctx);                                                  \
5356
        return;                                                               \
5357
    }                                                                         \
5358
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5359
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5360
    gen_op_##name();                                                          \
5361
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5362
}
5363

    
5364
#define GEN_SPEOP_ARITH1(name)                                                \
5365
static inline void gen_##name (DisasContext *ctx)                             \
5366
{                                                                             \
5367
    if (unlikely(!ctx->spe_enabled)) {                                        \
5368
        GEN_EXCP_NO_AP(ctx);                                                  \
5369
        return;                                                               \
5370
    }                                                                         \
5371
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5372
    gen_op_##name();                                                          \
5373
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5374
}
5375

    
5376
#define GEN_SPEOP_COMP(name)                                                  \
5377
static inline void gen_##name (DisasContext *ctx)                             \
5378
{                                                                             \
5379
    if (unlikely(!ctx->spe_enabled)) {                                        \
5380
        GEN_EXCP_NO_AP(ctx);                                                  \
5381
        return;                                                               \
5382
    }                                                                         \
5383
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5384
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5385
    gen_op_##name();                                                          \
5386
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5387
}
5388

    
5389
/* Logical */
5390
GEN_SPEOP_ARITH2(evand);
5391
GEN_SPEOP_ARITH2(evandc);
5392
GEN_SPEOP_ARITH2(evxor);
5393
GEN_SPEOP_ARITH2(evor);
5394
GEN_SPEOP_ARITH2(evnor);
5395
GEN_SPEOP_ARITH2(eveqv);
5396
GEN_SPEOP_ARITH2(evorc);
5397
GEN_SPEOP_ARITH2(evnand);
5398
GEN_SPEOP_ARITH2(evsrwu);
5399
GEN_SPEOP_ARITH2(evsrws);
5400
GEN_SPEOP_ARITH2(evslw);
5401
GEN_SPEOP_ARITH2(evrlw);
5402
GEN_SPEOP_ARITH2(evmergehi);
5403
GEN_SPEOP_ARITH2(evmergelo);
5404
GEN_SPEOP_ARITH2(evmergehilo);
5405
GEN_SPEOP_ARITH2(evmergelohi);
5406

    
5407
/* Arithmetic */
5408
GEN_SPEOP_ARITH2(evaddw);
5409
GEN_SPEOP_ARITH2(evsubfw);
5410
GEN_SPEOP_ARITH1(evabs);
5411
GEN_SPEOP_ARITH1(evneg);
5412
GEN_SPEOP_ARITH1(evextsb);
5413
GEN_SPEOP_ARITH1(evextsh);
5414
GEN_SPEOP_ARITH1(evrndw);
5415
GEN_SPEOP_ARITH1(evcntlzw);
5416
GEN_SPEOP_ARITH1(evcntlsw);
5417
static inline void gen_brinc (DisasContext *ctx)
5418
{
5419
    /* Note: brinc is usable even if SPE is disabled */
5420
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5421
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5422
    gen_op_brinc();
5423
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5424
}
5425

    
5426
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5427
static inline void gen_##name##i (DisasContext *ctx)                          \
5428
{                                                                             \
5429
    if (unlikely(!ctx->spe_enabled)) {                                        \
5430
        GEN_EXCP_NO_AP(ctx);                                                  \
5431
        return;                                                               \
5432
    }                                                                         \
5433
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5434
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5435
    gen_op_##name();                                                          \
5436
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5437
}
5438

    
5439
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5440
static inline void gen_##name##i (DisasContext *ctx)                          \
5441
{                                                                             \
5442
    if (unlikely(!ctx->spe_enabled)) {                                        \
5443
        GEN_EXCP_NO_AP(ctx);                                                  \
5444
        return;                                                               \
5445
    }                                                                         \
5446
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5447
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5448
    gen_op_##name();                                                          \
5449
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5450
}
5451

    
5452
GEN_SPEOP_ARITH_IMM2(evaddw);
5453
#define gen_evaddiw gen_evaddwi
5454
GEN_SPEOP_ARITH_IMM2(evsubfw);
5455
#define gen_evsubifw gen_evsubfwi
5456
GEN_SPEOP_LOGIC_IMM2(evslw);
5457
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5458
#define gen_evsrwis gen_evsrwsi
5459
GEN_SPEOP_LOGIC_IMM2(evsrws);
5460
#define gen_evsrwiu gen_evsrwui
5461
GEN_SPEOP_LOGIC_IMM2(evrlw);
5462

    
5463
static inline void gen_evsplati (DisasContext *ctx)
5464
{
5465
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5466

    
5467
    gen_op_splatwi_T0_64(imm);
5468
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5469
}
5470

    
5471
static inline void gen_evsplatfi (DisasContext *ctx)
5472
{
5473
    uint32_t imm = rA(ctx->opcode) << 27;
5474

    
5475
    gen_op_splatwi_T0_64(imm);
5476
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5477
}
5478

    
5479
/* Comparison */
5480
GEN_SPEOP_COMP(evcmpgtu);
5481
GEN_SPEOP_COMP(evcmpgts);
5482
GEN_SPEOP_COMP(evcmpltu);
5483
GEN_SPEOP_COMP(evcmplts);
5484
GEN_SPEOP_COMP(evcmpeq);
5485

    
5486
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5487
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5488
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5489
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5490
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5491
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5492
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5493
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5494
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5495
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5496
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5497
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5498
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5499
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5500
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5501
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5502
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5503
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5504
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5505
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5506
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5507
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5508
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5509
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5510
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5511

    
5512
static inline void gen_evsel (DisasContext *ctx)
5513
{
5514
    if (unlikely(!ctx->spe_enabled)) {
5515
        GEN_EXCP_NO_AP(ctx);
5516
        return;
5517
    }
5518
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5519
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5520
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5521
    gen_op_evsel();
5522
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5523
}
5524

    
5525
GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5526
{
5527
    gen_evsel(ctx);
5528
}
5529
GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5530
{
5531
    gen_evsel(ctx);
5532
}
5533
GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5534
{
5535
    gen_evsel(ctx);
5536
}
5537
GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5538
{
5539
    gen_evsel(ctx);
5540
}
5541

    
5542
/* Load and stores */
5543
#if defined(TARGET_PPC64)
5544
/* In that case, we already have 64 bits load & stores
5545
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5546
 */
5547
#if defined(CONFIG_USER_ONLY)
5548
#define gen_op_spe_ldd_raw gen_op_ld_raw
5549
#define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
5550
#define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
5551
#define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
5552
#define gen_op_spe_stdd_raw gen_op_ld_raw
5553
#define gen_op_spe_stdd_64_raw gen_op_std_64_raw
5554
#define gen_op_spe_stdd_le_raw gen_op_std_le_raw
5555
#define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
5556
#else /* defined(CONFIG_USER_ONLY) */
5557
#define gen_op_spe_ldd_kernel gen_op_ld_kernel
5558
#define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
5559
#define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
5560
#define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
5561
#define gen_op_spe_ldd_user gen_op_ld_user
5562
#define gen_op_spe_ldd_64_user gen_op_ld_64_user
5563
#define gen_op_spe_ldd_le_user gen_op_ld_le_user
5564
#define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
5565
#define gen_op_spe_stdd_kernel gen_op_std_kernel
5566
#define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
5567
#define gen_op_spe_stdd_le_kernel gen_op_std_kernel
5568
#define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
5569
#define gen_op_spe_stdd_user gen_op_std_user
5570
#define gen_op_spe_stdd_64_user gen_op_std_64_user
5571
#define gen_op_spe_stdd_le_user gen_op_std_le_user
5572
#define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
5573
#endif /* defined(CONFIG_USER_ONLY) */
5574
#endif /* defined(TARGET_PPC64) */
5575
GEN_SPEOP_LDST(dd, 3);
5576
GEN_SPEOP_LDST(dw, 3);
5577
GEN_SPEOP_LDST(dh, 3);
5578
GEN_SPEOP_LDST(whe, 2);
5579
GEN_SPEOP_LD(whou, 2);
5580
GEN_SPEOP_LD(whos, 2);
5581
GEN_SPEOP_ST(who, 2);
5582

    
5583
#if defined(TARGET_PPC64)
5584
/* In that case, spe_stwwo is equivalent to stw */
5585
#if defined(CONFIG_USER_ONLY)
5586
#define gen_op_spe_stwwo_raw gen_op_stw_raw
5587
#define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
5588
#define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
5589
#define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
5590
#else
5591
#define gen_op_spe_stwwo_user gen_op_stw_user
5592
#define gen_op_spe_stwwo_le_user gen_op_stw_le_user
5593
#define gen_op_spe_stwwo_64_user gen_op_stw_64_user
5594
#define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
5595
#define gen_op_spe_stwwo_kernel gen_op_stw_kernel
5596
#define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
5597
#define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
5598
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5599
#endif
5600
#endif
5601
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5602
static inline void gen_op_spe_stwwe_##suffix (void)                           \
5603
{                                                                             \
5604
    gen_op_srli32_T1_64();                                                    \
5605
    gen_op_spe_stwwo_##suffix();                                              \
5606
}
5607
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5608
static inline void gen_op_spe_stwwe_le_##suffix (void)                        \
5609
{                                                                             \
5610
    gen_op_srli32_T1_64();                                                    \
5611
    gen_op_spe_stwwo_le_##suffix();                                           \
5612
}
5613
#if defined(TARGET_PPC64)
5614
#define GEN_OP_SPE_STWWE(suffix)                                              \
5615
_GEN_OP_SPE_STWWE(suffix);                                                    \
5616
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5617
static inline void gen_op_spe_stwwe_64_##suffix (void)                        \
5618
{                                                                             \
5619
    gen_op_srli32_T1_64();                                                    \
5620
    gen_op_spe_stwwo_64_##suffix();                                           \
5621
}                                                                             \
5622
static inline void gen_op_spe_stwwe_le_64_##suffix (void)                     \
5623
{                                                                             \
5624
    gen_op_srli32_T1_64();                                                    \
5625
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5626
}
5627
#else
5628
#define GEN_OP_SPE_STWWE(suffix)                                              \
5629
_GEN_OP_SPE_STWWE(suffix);                                                    \
5630
_GEN_OP_SPE_STWWE_LE(suffix)
5631
#endif
5632
#if defined(CONFIG_USER_ONLY)
5633
GEN_OP_SPE_STWWE(raw);
5634
#else /* defined(CONFIG_USER_ONLY) */
5635
GEN_OP_SPE_STWWE(kernel);
5636
GEN_OP_SPE_STWWE(user);
5637
#endif /* defined(CONFIG_USER_ONLY) */
5638
GEN_SPEOP_ST(wwe, 2);
5639
GEN_SPEOP_ST(wwo, 2);
5640

    
5641
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5642
static inline void gen_op_spe_l##name##_##suffix (void)                       \
5643
{                                                                             \
5644
    gen_op_##op##_##suffix();                                                 \
5645
    gen_op_splatw_T1_64();                                                    \
5646
}
5647

    
5648
#define GEN_OP_SPE_LHE(suffix)                                                \
5649
static inline void gen_op_spe_lhe_##suffix (void)                             \
5650
{                                                                             \
5651
    gen_op_spe_lh_##suffix();                                                 \
5652
    gen_op_sli16_T1_64();                                                     \
5653
}
5654

    
5655
#define GEN_OP_SPE_LHX(suffix)                                                \
5656
static inline void gen_op_spe_lhx_##suffix (void)                             \
5657
{                                                                             \
5658
    gen_op_spe_lh_##suffix();                                                 \
5659
    gen_op_extsh_T1_64();                                                     \
5660
}
5661

    
5662
#if defined(CONFIG_USER_ONLY)
5663
GEN_OP_SPE_LHE(raw);
5664
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5665
GEN_OP_SPE_LHE(le_raw);
5666
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5667
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5668
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5669
GEN_OP_SPE_LHX(raw);
5670
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5671
GEN_OP_SPE_LHX(le_raw);
5672
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5673
#if defined(TARGET_PPC64)
5674
GEN_OP_SPE_LHE(64_raw);
5675
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5676
GEN_OP_SPE_LHE(le_64_raw);
5677
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5678
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5679
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5680
GEN_OP_SPE_LHX(64_raw);
5681
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5682
GEN_OP_SPE_LHX(le_64_raw);
5683
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5684
#endif
5685
#else
5686
GEN_OP_SPE_LHE(kernel);
5687
GEN_OP_SPE_LHE(user);
5688
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5689
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5690
GEN_OP_SPE_LHE(le_kernel);
5691
GEN_OP_SPE_LHE(le_user);
5692
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5693
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5694
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5695
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5696
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5697
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5698
GEN_OP_SPE_LHX(kernel);
5699
GEN_OP_SPE_LHX(user);
5700
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5701
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5702
GEN_OP_SPE_LHX(le_kernel);
5703
GEN_OP_SPE_LHX(le_user);
5704
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5705
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5706
#if defined(TARGET_PPC64)
5707
GEN_OP_SPE_LHE(64_kernel);
5708
GEN_OP_SPE_LHE(64_user);
5709
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5710
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5711
GEN_OP_SPE_LHE(le_64_kernel);
5712
GEN_OP_SPE_LHE(le_64_user);
5713
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5714
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5715
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5716
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5717
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5718
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5719
GEN_OP_SPE_LHX(64_kernel);
5720
GEN_OP_SPE_LHX(64_user);
5721
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5722
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5723
GEN_OP_SPE_LHX(le_64_kernel);
5724
GEN_OP_SPE_LHX(le_64_user);
5725
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5726
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5727
#endif
5728
#endif
5729
GEN_SPEOP_LD(hhesplat, 1);
5730
GEN_SPEOP_LD(hhousplat, 1);
5731
GEN_SPEOP_LD(hhossplat, 1);
5732
GEN_SPEOP_LD(wwsplat, 2);
5733
GEN_SPEOP_LD(whsplat, 2);
5734

    
5735
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5736
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5737
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5738
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5739
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5740
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5741
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5742
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5743
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5744
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5745
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5746
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5747
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5748
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5749
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5750
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5751
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5752
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5753

    
5754
/* Multiply and add - TODO */
5755
#if 0
5756
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5757
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5758
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5759
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5760
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5761
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5762
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5763
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5764
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5765
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5766
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5767
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5768

5769
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5770
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5771
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5772
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5773
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5774
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5775
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5776
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5777
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5778
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5779
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5780
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5781
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5782
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5783

5784
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5785
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5786
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5787
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5788
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5789
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5790

5791
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5792
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5793
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5794
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5795
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5796
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5797
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5798
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5799
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5800
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5801
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5802
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5803

5804
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5805
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5806
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5807
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5808
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5809

5810
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5811
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5812
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5813
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5814
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5815
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5816
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5817
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5818
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5819
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5820
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5821
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5822

5823
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5824
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5825
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5826
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5827
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5828
#endif
5829

    
5830
/***                      SPE floating-point extension                     ***/
5831
#define GEN_SPEFPUOP_CONV(name)                                               \
5832
static inline void gen_##name (DisasContext *ctx)                             \
5833
{                                                                             \
5834
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5835
    gen_op_##name();                                                          \
5836
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5837
}
5838

    
5839
/* Single precision floating-point vectors operations */
5840
/* Arithmetic */
5841
GEN_SPEOP_ARITH2(evfsadd);
5842
GEN_SPEOP_ARITH2(evfssub);
5843
GEN_SPEOP_ARITH2(evfsmul);
5844
GEN_SPEOP_ARITH2(evfsdiv);
5845
GEN_SPEOP_ARITH1(evfsabs);
5846
GEN_SPEOP_ARITH1(evfsnabs);
5847
GEN_SPEOP_ARITH1(evfsneg);
5848
/* Conversion */
5849
GEN_SPEFPUOP_CONV(evfscfui);
5850
GEN_SPEFPUOP_CONV(evfscfsi);
5851
GEN_SPEFPUOP_CONV(evfscfuf);
5852
GEN_SPEFPUOP_CONV(evfscfsf);
5853
GEN_SPEFPUOP_CONV(evfsctui);
5854
GEN_SPEFPUOP_CONV(evfsctsi);
5855
GEN_SPEFPUOP_CONV(evfsctuf);
5856
GEN_SPEFPUOP_CONV(evfsctsf);
5857
GEN_SPEFPUOP_CONV(evfsctuiz);
5858
GEN_SPEFPUOP_CONV(evfsctsiz);
5859
/* Comparison */
5860
GEN_SPEOP_COMP(evfscmpgt);
5861
GEN_SPEOP_COMP(evfscmplt);
5862
GEN_SPEOP_COMP(evfscmpeq);
5863
GEN_SPEOP_COMP(evfststgt);
5864
GEN_SPEOP_COMP(evfststlt);
5865
GEN_SPEOP_COMP(evfststeq);
5866

    
5867
/* Opcodes definitions */
5868
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5869
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5870
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5871
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5872
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5873
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5874
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5875
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5876
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5877
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5878
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5879
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5880
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5881
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5882

    
5883
/* Single precision floating-point operations */
5884
/* Arithmetic */
5885
GEN_SPEOP_ARITH2(efsadd);
5886
GEN_SPEOP_ARITH2(efssub);
5887
GEN_SPEOP_ARITH2(efsmul);
5888
GEN_SPEOP_ARITH2(efsdiv);
5889
GEN_SPEOP_ARITH1(efsabs);
5890
GEN_SPEOP_ARITH1(efsnabs);
5891
GEN_SPEOP_ARITH1(efsneg);
5892
/* Conversion */
5893
GEN_SPEFPUOP_CONV(efscfui);
5894
GEN_SPEFPUOP_CONV(efscfsi);
5895
GEN_SPEFPUOP_CONV(efscfuf);
5896
GEN_SPEFPUOP_CONV(efscfsf);
5897
GEN_SPEFPUOP_CONV(efsctui);
5898
GEN_SPEFPUOP_CONV(efsctsi);
5899
GEN_SPEFPUOP_CONV(efsctuf);
5900
GEN_SPEFPUOP_CONV(efsctsf);
5901
GEN_SPEFPUOP_CONV(efsctuiz);
5902
GEN_SPEFPUOP_CONV(efsctsiz);
5903
GEN_SPEFPUOP_CONV(efscfd);
5904
/* Comparison */
5905
GEN_SPEOP_COMP(efscmpgt);
5906
GEN_SPEOP_COMP(efscmplt);
5907
GEN_SPEOP_COMP(efscmpeq);
5908
GEN_SPEOP_COMP(efststgt);
5909
GEN_SPEOP_COMP(efststlt);
5910
GEN_SPEOP_COMP(efststeq);
5911

    
5912
/* Opcodes definitions */
5913
GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5914
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5915
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5916
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5917
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5918
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5919
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5920
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5921
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5922
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5923
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5924
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5925
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5926

    
5927
/* Double precision floating-point operations */
5928
/* Arithmetic */
5929
GEN_SPEOP_ARITH2(efdadd);
5930
GEN_SPEOP_ARITH2(efdsub);
5931
GEN_SPEOP_ARITH2(efdmul);
5932
GEN_SPEOP_ARITH2(efddiv);
5933
GEN_SPEOP_ARITH1(efdabs);
5934
GEN_SPEOP_ARITH1(efdnabs);
5935
GEN_SPEOP_ARITH1(efdneg);
5936
/* Conversion */
5937

    
5938
GEN_SPEFPUOP_CONV(efdcfui);
5939
GEN_SPEFPUOP_CONV(efdcfsi);
5940
GEN_SPEFPUOP_CONV(efdcfuf);
5941
GEN_SPEFPUOP_CONV(efdcfsf);
5942
GEN_SPEFPUOP_CONV(efdctui);
5943
GEN_SPEFPUOP_CONV(efdctsi);
5944
GEN_SPEFPUOP_CONV(efdctuf);
5945
GEN_SPEFPUOP_CONV(efdctsf);
5946
GEN_SPEFPUOP_CONV(efdctuiz);
5947
GEN_SPEFPUOP_CONV(efdctsiz);
5948
GEN_SPEFPUOP_CONV(efdcfs);
5949
GEN_SPEFPUOP_CONV(efdcfuid);
5950
GEN_SPEFPUOP_CONV(efdcfsid);
5951
GEN_SPEFPUOP_CONV(efdctuidz);
5952
GEN_SPEFPUOP_CONV(efdctsidz);
5953
/* Comparison */
5954
GEN_SPEOP_COMP(efdcmpgt);
5955
GEN_SPEOP_COMP(efdcmplt);
5956
GEN_SPEOP_COMP(efdcmpeq);
5957
GEN_SPEOP_COMP(efdtstgt);
5958
GEN_SPEOP_COMP(efdtstlt);
5959
GEN_SPEOP_COMP(efdtsteq);
5960

    
5961
/* Opcodes definitions */
5962
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
5963
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
5964
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
5965
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
5966
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
5967
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
5968
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
5969
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
5970
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
5971
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
5972
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
5973
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
5974
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
5975
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
5976
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
5977
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
5978
#endif
5979

    
5980
/* End opcode list */
5981
GEN_OPCODE_MARK(end);
5982

    
5983
#include "translate_init.c"
5984

    
5985
/*****************************************************************************/
5986
/* Misc PowerPC helpers */
5987
static inline uint32_t load_xer (CPUState *env)
5988
{
5989
    return (xer_so << XER_SO) |
5990
        (xer_ov << XER_OV) |
5991
        (xer_ca << XER_CA) |
5992
        (xer_bc << XER_BC) |
5993
        (xer_cmp << XER_CMP);
5994
}
5995

    
5996
void cpu_dump_state (CPUState *env, FILE *f,
5997
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5998
                     int flags)
5999
{
6000
#if defined(TARGET_PPC64) || 1
6001
#define FILL ""
6002
#define RGPL  4
6003
#define RFPL  4
6004
#else
6005
#define FILL "        "
6006
#define RGPL  8
6007
#define RFPL  4
6008
#endif
6009

    
6010
    int i;
6011

    
6012
    cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX "\n",
6013
                env->nip, env->lr, env->ctr);
6014
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
6015
#if !defined(NO_TIMER_DUMP)
6016
                "TB %08x %08x "
6017
#if !defined(CONFIG_USER_ONLY)
6018
                "DECR %08x"
6019
#endif
6020
#endif
6021
                "\n",
6022
                do_load_msr(env), load_xer(env)
6023
#if !defined(NO_TIMER_DUMP)
6024
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6025
#if !defined(CONFIG_USER_ONLY)
6026
                , cpu_ppc_load_decr(env)
6027
#endif
6028
#endif
6029
                );
6030
    for (i = 0; i < 32; i++) {
6031
        if ((i & (RGPL - 1)) == 0)
6032
            cpu_fprintf(f, "GPR%02d", i);
6033
        cpu_fprintf(f, " " REGX, (target_ulong)env->gpr[i]);
6034
        if ((i & (RGPL - 1)) == (RGPL - 1))
6035
            cpu_fprintf(f, "\n");
6036
    }
6037
    cpu_fprintf(f, "CR ");
6038
    for (i = 0; i < 8; i++)
6039
        cpu_fprintf(f, "%01x", env->crf[i]);
6040
    cpu_fprintf(f, "  [");
6041
    for (i = 0; i < 8; i++) {
6042
        char a = '-';
6043
        if (env->crf[i] & 0x08)
6044
            a = 'L';
6045
        else if (env->crf[i] & 0x04)
6046
            a = 'G';
6047
        else if (env->crf[i] & 0x02)
6048
            a = 'E';
6049
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6050
    }
6051
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
6052
    for (i = 0; i < 32; i++) {
6053
        if ((i & (RFPL - 1)) == 0)
6054
            cpu_fprintf(f, "FPR%02d", i);
6055
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6056
        if ((i & (RFPL - 1)) == (RFPL - 1))
6057
            cpu_fprintf(f, "\n");
6058
    }
6059
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
6060
                "SDR1 " REGX "\n",
6061
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6062

    
6063
#undef RGPL
6064
#undef RFPL
6065
#undef FILL
6066
}
6067

    
6068
void cpu_dump_statistics (CPUState *env, FILE*f,
6069
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6070
                          int flags)
6071
{
6072
#if defined(DO_PPC_STATISTICS)
6073
    opc_handler_t **t1, **t2, **t3, *handler;
6074
    int op1, op2, op3;
6075

    
6076
    t1 = env->opcodes;
6077
    for (op1 = 0; op1 < 64; op1++) {
6078
        handler = t1[op1];
6079
        if (is_indirect_opcode(handler)) {
6080
            t2 = ind_table(handler);
6081
            for (op2 = 0; op2 < 32; op2++) {
6082
                handler = t2[op2];
6083
                if (is_indirect_opcode(handler)) {
6084
                    t3 = ind_table(handler);
6085
                    for (op3 = 0; op3 < 32; op3++) {
6086
                        handler = t3[op3];
6087
                        if (handler->count == 0)
6088
                            continue;
6089
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6090
                                    "%016llx %lld\n",
6091
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6092
                                    handler->oname,
6093
                                    handler->count, handler->count);
6094
                    }
6095
                } else {
6096
                    if (handler->count == 0)
6097
                        continue;
6098
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6099
                                "%016llx %lld\n",
6100
                                op1, op2, op1, op2, handler->oname,
6101
                                handler->count, handler->count);
6102
                }
6103
            }
6104
        } else {
6105
            if (handler->count == 0)
6106
                continue;
6107
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6108
                        op1, op1, handler->oname,
6109
                        handler->count, handler->count);
6110
        }
6111
    }
6112
#endif
6113
}
6114

    
6115
/*****************************************************************************/
6116
static inline int gen_intermediate_code_internal (CPUState *env,
6117
                                                  TranslationBlock *tb,
6118
                                                  int search_pc)
6119
{
6120
    DisasContext ctx, *ctxp = &ctx;
6121
    opc_handler_t **table, *handler;
6122
    target_ulong pc_start;
6123
    uint16_t *gen_opc_end;
6124
    int j, lj = -1;
6125

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

    
6322
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6323
{
6324
    return gen_intermediate_code_internal(env, tb, 0);
6325
}
6326

    
6327
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6328
{
6329
    return gen_intermediate_code_internal(env, tb, 1);
6330
}