Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ dee96f6c

History | View | Annotate | Download (206.6 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
};
480

    
481
/*****************************************************************************/
482
/* PowerPC instructions table                                                */
483
#if HOST_LONG_BITS == 64
484
#define OPC_ALIGN 8
485
#else
486
#define OPC_ALIGN 4
487
#endif
488
#if defined(__APPLE__)
489
#define OPCODES_SECTION                                                       \
490
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
491
#else
492
#define OPCODES_SECTION                                                       \
493
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
494
#endif
495

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

    
527
#define GEN_OPCODE_MARK(name)                                                 \
528
OPCODES_SECTION opcode_t opc_##name = {                                       \
529
    .opc1 = 0xFF,                                                             \
530
    .opc2 = 0xFF,                                                             \
531
    .opc3 = 0xFF,                                                             \
532
    .pad  = { 0, },                                                           \
533
    .handler = {                                                              \
534
        .inval   = 0x00000000,                                                \
535
        .type = 0x00,                                                         \
536
        .handler = NULL,                                                      \
537
    },                                                                        \
538
    .oname = stringify(name),                                                 \
539
}
540

    
541
/* Start opcode list */
542
GEN_OPCODE_MARK(start);
543

    
544
/* Invalid instruction */
545
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
546
{
547
    GEN_EXCP_INVAL(ctx);
548
}
549

    
550
static opc_handler_t invalid_handler = {
551
    .inval   = 0xFFFFFFFF,
552
    .type    = PPC_NONE,
553
    .handler = gen_invalid,
554
};
555

    
556
/***                           Integer arithmetic                          ***/
557
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
558
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
559
{                                                                             \
560
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
561
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
562
    gen_op_##name();                                                          \
563
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
564
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
565
        gen_set_Rc0(ctx);                                                     \
566
}
567

    
568
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
569
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
570
{                                                                             \
571
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
572
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
573
    gen_op_##name();                                                          \
574
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
575
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
576
        gen_set_Rc0(ctx);                                                     \
577
}
578

    
579
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
580
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
581
{                                                                             \
582
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
583
    gen_op_##name();                                                          \
584
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
585
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
586
        gen_set_Rc0(ctx);                                                     \
587
}
588
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
589
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
590
{                                                                             \
591
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
592
    gen_op_##name();                                                          \
593
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
594
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
595
        gen_set_Rc0(ctx);                                                     \
596
}
597

    
598
/* Two operands arithmetic functions */
599
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
600
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
601
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
602

    
603
/* Two operands arithmetic functions with no overflow allowed */
604
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
605
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
606

    
607
/* One operand arithmetic functions */
608
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
609
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
610
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
611

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

    
627
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
628
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
629
{                                                                             \
630
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
631
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
632
    if (ctx->sf_mode)                                                         \
633
        gen_op_##name##_64();                                                 \
634
    else                                                                      \
635
        gen_op_##name();                                                      \
636
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
637
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
638
        gen_set_Rc0(ctx);                                                     \
639
}
640

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

    
666
/* Two operands arithmetic functions */
667
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
668
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
669
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
670

    
671
/* Two operands arithmetic functions with no overflow allowed */
672
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
673
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
674

    
675
/* One operand arithmetic functions */
676
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
677
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
678
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
679
#else
680
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
681
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
682
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
683
#endif
684

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

    
875
    if (rA(ctx->opcode) == 0) {
876
        /* li case */
877
        gen_set_T0(simm);
878
    } else {
879
        gen_op_load_gpr_T0(rA(ctx->opcode));
880
        if (likely(simm != 0))
881
            gen_op_addi(simm);
882
    }
883
    gen_op_store_T0_gpr(rD(ctx->opcode));
884
}
885
/* addic */
886
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
887
{
888
    target_long simm = SIMM(ctx->opcode);
889

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

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

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

    
961
#if defined(TARGET_PPC64)
962
/* mulhd  mulhd.                   */
963
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
964
/* mulhdu mulhdu.                  */
965
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
966
/* mulld  mulld.  mulldo  mulldo.  */
967
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
968
/* divd   divd.   divdo   divdo.   */
969
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
970
/* divdu  divdu.  divduo  divduo.  */
971
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
972
#endif
973

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

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

    
1027
/* isel (PowerPC 2.03 specification) */
1028
GEN_HANDLER(isel, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203)
1029
{
1030
    uint32_t bi = rC(ctx->opcode);
1031
    uint32_t mask;
1032

    
1033
    if (rA(ctx->opcode) == 0) {
1034
        gen_set_T0(0);
1035
    } else {
1036
        gen_op_load_gpr_T1(rA(ctx->opcode));
1037
    }
1038
    gen_op_load_gpr_T2(rB(ctx->opcode));
1039
    mask = 1 << (3 - (bi & 0x03));
1040
    gen_op_load_crf_T0(bi >> 2);
1041
    gen_op_test_true(mask);
1042
    gen_op_isel();
1043
    gen_op_store_T0_gpr(rD(ctx->opcode));
1044
}
1045

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

    
1060
#define GEN_LOGICAL1(name, opc, type)                                         \
1061
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1062
{                                                                             \
1063
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1064
    gen_op_##name();                                                          \
1065
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1066
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1067
        gen_set_Rc0(ctx);                                                     \
1068
}
1069

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

    
1091
/* cntlzw */
1092
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1093
/* eqv & eqv. */
1094
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1095
/* extsb & extsb. */
1096
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1097
/* extsh & extsh. */
1098
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1099
/* nand & nand. */
1100
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1101
/* nor & nor. */
1102
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1103

    
1104
/* or & or. */
1105
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1106
{
1107
    int rs, ra, rb;
1108

    
1109
    rs = rS(ctx->opcode);
1110
    ra = rA(ctx->opcode);
1111
    rb = rB(ctx->opcode);
1112
    /* Optimisation for mr. ri case */
1113
    if (rs != ra || rs != rb) {
1114
        gen_op_load_gpr_T0(rs);
1115
        if (rs != rb) {
1116
            gen_op_load_gpr_T1(rb);
1117
            gen_op_or();
1118
        }
1119
        gen_op_store_T0_gpr(ra);
1120
        if (unlikely(Rc(ctx->opcode) != 0))
1121
            gen_set_Rc0(ctx);
1122
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1123
        gen_op_load_gpr_T0(rs);
1124
        gen_set_Rc0(ctx);
1125
    }
1126
}
1127

    
1128
/* orc & orc. */
1129
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1130
/* xor & xor. */
1131
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1132
{
1133
    gen_op_load_gpr_T0(rS(ctx->opcode));
1134
    /* Optimisation for "set to zero" case */
1135
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1136
        gen_op_load_gpr_T1(rB(ctx->opcode));
1137
        gen_op_xor();
1138
    } else {
1139
        gen_op_reset_T0();
1140
    }
1141
    gen_op_store_T0_gpr(rA(ctx->opcode));
1142
    if (unlikely(Rc(ctx->opcode) != 0))
1143
        gen_set_Rc0(ctx);
1144
}
1145
/* ori */
1146
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1147
{
1148
    target_ulong uimm = UIMM(ctx->opcode);
1149

    
1150
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1151
        /* NOP */
1152
        /* XXX: should handle special NOPs for POWER series */
1153
        return;
1154
    }
1155
    gen_op_load_gpr_T0(rS(ctx->opcode));
1156
    if (likely(uimm != 0))
1157
        gen_op_ori(uimm);
1158
    gen_op_store_T0_gpr(rA(ctx->opcode));
1159
}
1160
/* oris */
1161
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1162
{
1163
    target_ulong uimm = UIMM(ctx->opcode);
1164

    
1165
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1166
        /* NOP */
1167
        return;
1168
    }
1169
    gen_op_load_gpr_T0(rS(ctx->opcode));
1170
    if (likely(uimm != 0))
1171
        gen_op_ori(uimm << 16);
1172
    gen_op_store_T0_gpr(rA(ctx->opcode));
1173
}
1174
/* xori */
1175
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1176
{
1177
    target_ulong uimm = UIMM(ctx->opcode);
1178

    
1179
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1180
        /* NOP */
1181
        return;
1182
    }
1183
    gen_op_load_gpr_T0(rS(ctx->opcode));
1184
    if (likely(uimm != 0))
1185
        gen_op_xori(uimm);
1186
    gen_op_store_T0_gpr(rA(ctx->opcode));
1187
}
1188

    
1189
/* xoris */
1190
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1191
{
1192
    target_ulong uimm = UIMM(ctx->opcode);
1193

    
1194
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1195
        /* NOP */
1196
        return;
1197
    }
1198
    gen_op_load_gpr_T0(rS(ctx->opcode));
1199
    if (likely(uimm != 0))
1200
        gen_op_xori(uimm << 16);
1201
    gen_op_store_T0_gpr(rA(ctx->opcode));
1202
}
1203

    
1204
/* popcntb : PowerPC 2.03 specification */
1205
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_203)
1206
{
1207
    gen_op_load_gpr_T0(rS(ctx->opcode));
1208
#if defined(TARGET_PPC64)
1209
    if (ctx->sf_mode)
1210
        gen_op_popcntb_64();
1211
    else
1212
#endif
1213
        gen_op_popcntb();
1214
    gen_op_store_T0_gpr(rA(ctx->opcode));
1215
}
1216

    
1217
#if defined(TARGET_PPC64)
1218
/* extsw & extsw. */
1219
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1220
/* cntlzd */
1221
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1222
#endif
1223

    
1224
/***                             Integer rotate                            ***/
1225
/* rlwimi & rlwimi. */
1226
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1227
{
1228
    target_ulong mask;
1229
    uint32_t mb, me, sh;
1230

    
1231
    mb = MB(ctx->opcode);
1232
    me = ME(ctx->opcode);
1233
    sh = SH(ctx->opcode);
1234
    if (likely(sh == 0)) {
1235
        if (likely(mb == 0 && me == 31)) {
1236
            gen_op_load_gpr_T0(rS(ctx->opcode));
1237
            goto do_store;
1238
        } else if (likely(mb == 31 && me == 0)) {
1239
            gen_op_load_gpr_T0(rA(ctx->opcode));
1240
            goto do_store;
1241
        }
1242
        gen_op_load_gpr_T0(rS(ctx->opcode));
1243
        gen_op_load_gpr_T1(rA(ctx->opcode));
1244
        goto do_mask;
1245
    }
1246
    gen_op_load_gpr_T0(rS(ctx->opcode));
1247
    gen_op_load_gpr_T1(rA(ctx->opcode));
1248
    gen_op_rotli32_T0(SH(ctx->opcode));
1249
 do_mask:
1250
#if defined(TARGET_PPC64)
1251
    mb += 32;
1252
    me += 32;
1253
#endif
1254
    mask = MASK(mb, me);
1255
    gen_op_andi_T0(mask);
1256
    gen_op_andi_T1(~mask);
1257
    gen_op_or();
1258
 do_store:
1259
    gen_op_store_T0_gpr(rA(ctx->opcode));
1260
    if (unlikely(Rc(ctx->opcode) != 0))
1261
        gen_set_Rc0(ctx);
1262
}
1263
/* rlwinm & rlwinm. */
1264
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1265
{
1266
    uint32_t mb, me, sh;
1267

    
1268
    sh = SH(ctx->opcode);
1269
    mb = MB(ctx->opcode);
1270
    me = ME(ctx->opcode);
1271
    gen_op_load_gpr_T0(rS(ctx->opcode));
1272
    if (likely(sh == 0)) {
1273
        goto do_mask;
1274
    }
1275
    if (likely(mb == 0)) {
1276
        if (likely(me == 31)) {
1277
            gen_op_rotli32_T0(sh);
1278
            goto do_store;
1279
        } else if (likely(me == (31 - sh))) {
1280
            gen_op_sli_T0(sh);
1281
            goto do_store;
1282
        }
1283
    } else if (likely(me == 31)) {
1284
        if (likely(sh == (32 - mb))) {
1285
            gen_op_srli_T0(mb);
1286
            goto do_store;
1287
        }
1288
    }
1289
    gen_op_rotli32_T0(sh);
1290
 do_mask:
1291
#if defined(TARGET_PPC64)
1292
    mb += 32;
1293
    me += 32;
1294
#endif
1295
    gen_op_andi_T0(MASK(mb, me));
1296
 do_store:
1297
    gen_op_store_T0_gpr(rA(ctx->opcode));
1298
    if (unlikely(Rc(ctx->opcode) != 0))
1299
        gen_set_Rc0(ctx);
1300
}
1301
/* rlwnm & rlwnm. */
1302
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1303
{
1304
    uint32_t mb, me;
1305

    
1306
    mb = MB(ctx->opcode);
1307
    me = ME(ctx->opcode);
1308
    gen_op_load_gpr_T0(rS(ctx->opcode));
1309
    gen_op_load_gpr_T1(rB(ctx->opcode));
1310
    gen_op_rotl32_T0_T1();
1311
    if (unlikely(mb != 0 || me != 31)) {
1312
#if defined(TARGET_PPC64)
1313
        mb += 32;
1314
        me += 32;
1315
#endif
1316
        gen_op_andi_T0(MASK(mb, me));
1317
    }
1318
    gen_op_store_T0_gpr(rA(ctx->opcode));
1319
    if (unlikely(Rc(ctx->opcode) != 0))
1320
        gen_set_Rc0(ctx);
1321
}
1322

    
1323
#if defined(TARGET_PPC64)
1324
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1325
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1326
{                                                                             \
1327
    gen_##name(ctx, 0);                                                       \
1328
}                                                                             \
1329
GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1330
{                                                                             \
1331
    gen_##name(ctx, 1);                                                       \
1332
}
1333
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1334
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1335
{                                                                             \
1336
    gen_##name(ctx, 0, 0);                                                    \
1337
}                                                                             \
1338
GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B)            \
1339
{                                                                             \
1340
    gen_##name(ctx, 0, 1);                                                    \
1341
}                                                                             \
1342
GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1343
{                                                                             \
1344
    gen_##name(ctx, 1, 0);                                                    \
1345
}                                                                             \
1346
GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B)            \
1347
{                                                                             \
1348
    gen_##name(ctx, 1, 1);                                                    \
1349
}
1350

    
1351
static inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1352
{
1353
    if (mask >> 32)
1354
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1355
    else
1356
        gen_op_andi_T0(mask);
1357
}
1358

    
1359
static inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1360
{
1361
    if (mask >> 32)
1362
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1363
    else
1364
        gen_op_andi_T1(mask);
1365
}
1366

    
1367
static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me,
1368
                               uint32_t sh)
1369
{
1370
    gen_op_load_gpr_T0(rS(ctx->opcode));
1371
    if (likely(sh == 0)) {
1372
        goto do_mask;
1373
    }
1374
    if (likely(mb == 0)) {
1375
        if (likely(me == 63)) {
1376
            gen_op_rotli64_T0(sh);
1377
            goto do_store;
1378
        } else if (likely(me == (63 - sh))) {
1379
            gen_op_sli_T0(sh);
1380
            goto do_store;
1381
        }
1382
    } else if (likely(me == 63)) {
1383
        if (likely(sh == (64 - mb))) {
1384
            gen_op_srli_T0_64(mb);
1385
            goto do_store;
1386
        }
1387
    }
1388
    gen_op_rotli64_T0(sh);
1389
 do_mask:
1390
    gen_andi_T0_64(ctx, MASK(mb, me));
1391
 do_store:
1392
    gen_op_store_T0_gpr(rA(ctx->opcode));
1393
    if (unlikely(Rc(ctx->opcode) != 0))
1394
        gen_set_Rc0(ctx);
1395
}
1396
/* rldicl - rldicl. */
1397
static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1398
{
1399
    uint32_t sh, mb;
1400

    
1401
    sh = SH(ctx->opcode) | (shn << 5);
1402
    mb = MB(ctx->opcode) | (mbn << 5);
1403
    gen_rldinm(ctx, mb, 63, sh);
1404
}
1405
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1406
/* rldicr - rldicr. */
1407
static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1408
{
1409
    uint32_t sh, me;
1410

    
1411
    sh = SH(ctx->opcode) | (shn << 5);
1412
    me = MB(ctx->opcode) | (men << 5);
1413
    gen_rldinm(ctx, 0, me, sh);
1414
}
1415
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1416
/* rldic - rldic. */
1417
static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1418
{
1419
    uint32_t sh, mb;
1420

    
1421
    sh = SH(ctx->opcode) | (shn << 5);
1422
    mb = MB(ctx->opcode) | (mbn << 5);
1423
    gen_rldinm(ctx, mb, 63 - sh, sh);
1424
}
1425
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1426

    
1427
static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me)
1428
{
1429
    gen_op_load_gpr_T0(rS(ctx->opcode));
1430
    gen_op_load_gpr_T1(rB(ctx->opcode));
1431
    gen_op_rotl64_T0_T1();
1432
    if (unlikely(mb != 0 || me != 63)) {
1433
        gen_andi_T0_64(ctx, MASK(mb, me));
1434
    }
1435
    gen_op_store_T0_gpr(rA(ctx->opcode));
1436
    if (unlikely(Rc(ctx->opcode) != 0))
1437
        gen_set_Rc0(ctx);
1438
}
1439

    
1440
/* rldcl - rldcl. */
1441
static inline void gen_rldcl (DisasContext *ctx, int mbn)
1442
{
1443
    uint32_t mb;
1444

    
1445
    mb = MB(ctx->opcode) | (mbn << 5);
1446
    gen_rldnm(ctx, mb, 63);
1447
}
1448
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1449
/* rldcr - rldcr. */
1450
static inline void gen_rldcr (DisasContext *ctx, int men)
1451
{
1452
    uint32_t me;
1453

    
1454
    me = MB(ctx->opcode) | (men << 5);
1455
    gen_rldnm(ctx, 0, me);
1456
}
1457
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1458
/* rldimi - rldimi. */
1459
static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1460
{
1461
    uint64_t mask;
1462
    uint32_t sh, mb;
1463

    
1464
    sh = SH(ctx->opcode) | (shn << 5);
1465
    mb = MB(ctx->opcode) | (mbn << 5);
1466
    if (likely(sh == 0)) {
1467
        if (likely(mb == 0)) {
1468
            gen_op_load_gpr_T0(rS(ctx->opcode));
1469
            goto do_store;
1470
        } else if (likely(mb == 63)) {
1471
            gen_op_load_gpr_T0(rA(ctx->opcode));
1472
            goto do_store;
1473
        }
1474
        gen_op_load_gpr_T0(rS(ctx->opcode));
1475
        gen_op_load_gpr_T1(rA(ctx->opcode));
1476
        goto do_mask;
1477
    }
1478
    gen_op_load_gpr_T0(rS(ctx->opcode));
1479
    gen_op_load_gpr_T1(rA(ctx->opcode));
1480
    gen_op_rotli64_T0(sh);
1481
 do_mask:
1482
    mask = MASK(mb, 63 - sh);
1483
    gen_andi_T0_64(ctx, mask);
1484
    gen_andi_T1_64(ctx, ~mask);
1485
    gen_op_or();
1486
 do_store:
1487
    gen_op_store_T0_gpr(rA(ctx->opcode));
1488
    if (unlikely(Rc(ctx->opcode) != 0))
1489
        gen_set_Rc0(ctx);
1490
}
1491
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1492
#endif
1493

    
1494
/***                             Integer shift                             ***/
1495
/* slw & slw. */
1496
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1497
/* sraw & sraw. */
1498
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1499
/* srawi & srawi. */
1500
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1501
{
1502
    int mb, me;
1503
    gen_op_load_gpr_T0(rS(ctx->opcode));
1504
    if (SH(ctx->opcode) != 0) {
1505
        gen_op_move_T1_T0();
1506
        mb = 32 - SH(ctx->opcode);
1507
        me = 31;
1508
#if defined(TARGET_PPC64)
1509
        mb += 32;
1510
        me += 32;
1511
#endif
1512
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1513
    }
1514
    gen_op_store_T0_gpr(rA(ctx->opcode));
1515
    if (unlikely(Rc(ctx->opcode) != 0))
1516
        gen_set_Rc0(ctx);
1517
}
1518
/* srw & srw. */
1519
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1520

    
1521
#if defined(TARGET_PPC64)
1522
/* sld & sld. */
1523
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1524
/* srad & srad. */
1525
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1526
/* sradi & sradi. */
1527
static inline void gen_sradi (DisasContext *ctx, int n)
1528
{
1529
    uint64_t mask;
1530
    int sh, mb, me;
1531

    
1532
    gen_op_load_gpr_T0(rS(ctx->opcode));
1533
    sh = SH(ctx->opcode) + (n << 5);
1534
    if (sh != 0) {
1535
        gen_op_move_T1_T0();
1536
        mb = 64 - SH(ctx->opcode);
1537
        me = 63;
1538
        mask = MASK(mb, me);
1539
        gen_op_sradi(sh, mask >> 32, mask);
1540
    }
1541
    gen_op_store_T0_gpr(rA(ctx->opcode));
1542
    if (unlikely(Rc(ctx->opcode) != 0))
1543
        gen_set_Rc0(ctx);
1544
}
1545
GEN_HANDLER(sradi0, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1546
{
1547
    gen_sradi(ctx, 0);
1548
}
1549
GEN_HANDLER(sradi1, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1550
{
1551
    gen_sradi(ctx, 1);
1552
}
1553
/* srd & srd. */
1554
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1555
#endif
1556

    
1557
/***                       Floating-Point arithmetic                       ***/
1558
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, type)                     \
1559
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1560
{                                                                             \
1561
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1562
        GEN_EXCP_NO_FP(ctx);                                                  \
1563
        return;                                                               \
1564
    }                                                                         \
1565
    gen_op_reset_scrfx();                                                     \
1566
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1567
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1568
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1569
    gen_op_f##op();                                                           \
1570
    if (isfloat) {                                                            \
1571
        gen_op_frsp();                                                        \
1572
    }                                                                         \
1573
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1574
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1575
        gen_op_set_Rc1();                                                     \
1576
}
1577

    
1578
#define GEN_FLOAT_ACB(name, op2, type)                                        \
1579
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, type);                               \
1580
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type);
1581

    
1582
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
1583
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1584
{                                                                             \
1585
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1586
        GEN_EXCP_NO_FP(ctx);                                                  \
1587
        return;                                                               \
1588
    }                                                                         \
1589
    gen_op_reset_scrfx();                                                     \
1590
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1591
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1592
    gen_op_f##op();                                                           \
1593
    if (isfloat) {                                                            \
1594
        gen_op_frsp();                                                        \
1595
    }                                                                         \
1596
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1597
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1598
        gen_op_set_Rc1();                                                     \
1599
}
1600
#define GEN_FLOAT_AB(name, op2, inval)                                        \
1601
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
1602
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1603

    
1604
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
1605
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1606
{                                                                             \
1607
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1608
        GEN_EXCP_NO_FP(ctx);                                                  \
1609
        return;                                                               \
1610
    }                                                                         \
1611
    gen_op_reset_scrfx();                                                     \
1612
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1613
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1614
    gen_op_f##op();                                                           \
1615
    if (isfloat) {                                                            \
1616
        gen_op_frsp();                                                        \
1617
    }                                                                         \
1618
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1619
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1620
        gen_op_set_Rc1();                                                     \
1621
}
1622
#define GEN_FLOAT_AC(name, op2, inval)                                        \
1623
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
1624
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1625

    
1626
#define GEN_FLOAT_B(name, op2, op3, type)                                     \
1627
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1628
{                                                                             \
1629
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1630
        GEN_EXCP_NO_FP(ctx);                                                  \
1631
        return;                                                               \
1632
    }                                                                         \
1633
    gen_op_reset_scrfx();                                                     \
1634
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1635
    gen_op_f##name();                                                         \
1636
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1637
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1638
        gen_op_set_Rc1();                                                     \
1639
}
1640

    
1641
#define GEN_FLOAT_BS(name, op1, op2, type)                                    \
1642
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1643
{                                                                             \
1644
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1645
        GEN_EXCP_NO_FP(ctx);                                                  \
1646
        return;                                                               \
1647
    }                                                                         \
1648
    gen_op_reset_scrfx();                                                     \
1649
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1650
    gen_op_f##name();                                                         \
1651
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1652
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1653
        gen_op_set_Rc1();                                                     \
1654
}
1655

    
1656
/* fadd - fadds */
1657
GEN_FLOAT_AB(add, 0x15, 0x000007C0);
1658
/* fdiv - fdivs */
1659
GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1660
/* fmul - fmuls */
1661
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1662

    
1663
/* fres */
1664
GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
1665

    
1666
/* frsqrte */
1667
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, PPC_FLOAT_FRSQRTE);
1668

    
1669
/* fsel */
1670
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, PPC_FLOAT_FSEL);
1671
/* fsub - fsubs */
1672
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1673
/* Optional: */
1674
/* fsqrt */
1675
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1676
{
1677
    if (unlikely(!ctx->fpu_enabled)) {
1678
        GEN_EXCP_NO_FP(ctx);
1679
        return;
1680
    }
1681
    gen_op_reset_scrfx();
1682
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1683
    gen_op_fsqrt();
1684
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1685
    if (unlikely(Rc(ctx->opcode) != 0))
1686
        gen_op_set_Rc1();
1687
}
1688

    
1689
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1690
{
1691
    if (unlikely(!ctx->fpu_enabled)) {
1692
        GEN_EXCP_NO_FP(ctx);
1693
        return;
1694
    }
1695
    gen_op_reset_scrfx();
1696
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1697
    gen_op_fsqrt();
1698
    gen_op_frsp();
1699
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1700
    if (unlikely(Rc(ctx->opcode) != 0))
1701
        gen_op_set_Rc1();
1702
}
1703

    
1704
/***                     Floating-Point multiply-and-add                   ***/
1705
/* fmadd - fmadds */
1706
GEN_FLOAT_ACB(madd, 0x1D, PPC_FLOAT);
1707
/* fmsub - fmsubs */
1708
GEN_FLOAT_ACB(msub, 0x1C, PPC_FLOAT);
1709
/* fnmadd - fnmadds */
1710
GEN_FLOAT_ACB(nmadd, 0x1F, PPC_FLOAT);
1711
/* fnmsub - fnmsubs */
1712
GEN_FLOAT_ACB(nmsub, 0x1E, PPC_FLOAT);
1713

    
1714
/***                     Floating-Point round & convert                    ***/
1715
/* fctiw */
1716
GEN_FLOAT_B(ctiw, 0x0E, 0x00, PPC_FLOAT);
1717
/* fctiwz */
1718
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, PPC_FLOAT);
1719
/* frsp */
1720
GEN_FLOAT_B(rsp, 0x0C, 0x00, PPC_FLOAT);
1721
#if defined(TARGET_PPC64)
1722
/* fcfid */
1723
GEN_FLOAT_B(cfid, 0x0E, 0x1A, PPC_64B);
1724
/* fctid */
1725
GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
1726
/* fctidz */
1727
GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
1728
#endif
1729

    
1730
/***                         Floating-Point compare                        ***/
1731
/* fcmpo */
1732
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
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(rA(ctx->opcode));
1740
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1741
    gen_op_fcmpo();
1742
    gen_op_store_T0_crf(crfD(ctx->opcode));
1743
}
1744

    
1745
/* fcmpu */
1746
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
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(rA(ctx->opcode));
1754
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1755
    gen_op_fcmpu();
1756
    gen_op_store_T0_crf(crfD(ctx->opcode));
1757
}
1758

    
1759
/***                         Floating-point move                           ***/
1760
/* fabs */
1761
GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT);
1762

    
1763
/* fmr  - fmr. */
1764
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1765
{
1766
    if (unlikely(!ctx->fpu_enabled)) {
1767
        GEN_EXCP_NO_FP(ctx);
1768
        return;
1769
    }
1770
    gen_op_reset_scrfx();
1771
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1772
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1773
    if (unlikely(Rc(ctx->opcode) != 0))
1774
        gen_op_set_Rc1();
1775
}
1776

    
1777
/* fnabs */
1778
GEN_FLOAT_B(nabs, 0x08, 0x04, PPC_FLOAT);
1779
/* fneg */
1780
GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT);
1781

    
1782
/***                  Floating-Point status & ctrl register                ***/
1783
/* mcrfs */
1784
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1785
{
1786
    if (unlikely(!ctx->fpu_enabled)) {
1787
        GEN_EXCP_NO_FP(ctx);
1788
        return;
1789
    }
1790
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
1791
    gen_op_store_T0_crf(crfD(ctx->opcode));
1792
    gen_op_clear_fpscr(crfS(ctx->opcode));
1793
}
1794

    
1795
/* mffs */
1796
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1797
{
1798
    if (unlikely(!ctx->fpu_enabled)) {
1799
        GEN_EXCP_NO_FP(ctx);
1800
        return;
1801
    }
1802
    gen_op_load_fpscr();
1803
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1804
    if (unlikely(Rc(ctx->opcode) != 0))
1805
        gen_op_set_Rc1();
1806
}
1807

    
1808
/* mtfsb0 */
1809
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1810
{
1811
    uint8_t crb;
1812

    
1813
    if (unlikely(!ctx->fpu_enabled)) {
1814
        GEN_EXCP_NO_FP(ctx);
1815
        return;
1816
    }
1817
    crb = crbD(ctx->opcode) >> 2;
1818
    gen_op_load_fpscr_T0(crb);
1819
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1820
    gen_op_store_T0_fpscr(crb);
1821
    if (unlikely(Rc(ctx->opcode) != 0))
1822
        gen_op_set_Rc1();
1823
}
1824

    
1825
/* mtfsb1 */
1826
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1827
{
1828
    uint8_t crb;
1829

    
1830
    if (unlikely(!ctx->fpu_enabled)) {
1831
        GEN_EXCP_NO_FP(ctx);
1832
        return;
1833
    }
1834
    crb = crbD(ctx->opcode) >> 2;
1835
    gen_op_load_fpscr_T0(crb);
1836
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1837
    gen_op_store_T0_fpscr(crb);
1838
    if (unlikely(Rc(ctx->opcode) != 0))
1839
        gen_op_set_Rc1();
1840
}
1841

    
1842
/* mtfsf */
1843
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1844
{
1845
    if (unlikely(!ctx->fpu_enabled)) {
1846
        GEN_EXCP_NO_FP(ctx);
1847
        return;
1848
    }
1849
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1850
    gen_op_store_fpscr(FM(ctx->opcode));
1851
    if (unlikely(Rc(ctx->opcode) != 0))
1852
        gen_op_set_Rc1();
1853
}
1854

    
1855
/* mtfsfi */
1856
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1857
{
1858
    if (unlikely(!ctx->fpu_enabled)) {
1859
        GEN_EXCP_NO_FP(ctx);
1860
        return;
1861
    }
1862
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1863
    if (unlikely(Rc(ctx->opcode) != 0))
1864
        gen_op_set_Rc1();
1865
}
1866

    
1867
/***                           Addressing modes                            ***/
1868
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1869
static inline void gen_addr_imm_index (DisasContext *ctx, int maskl)
1870
{
1871
    target_long simm = SIMM(ctx->opcode);
1872

    
1873
    if (maskl)
1874
        simm &= ~0x03;
1875
    if (rA(ctx->opcode) == 0) {
1876
        gen_set_T0(simm);
1877
    } else {
1878
        gen_op_load_gpr_T0(rA(ctx->opcode));
1879
        if (likely(simm != 0))
1880
            gen_op_addi(simm);
1881
    }
1882
#ifdef DEBUG_MEMORY_ACCESSES
1883
    gen_op_print_mem_EA();
1884
#endif
1885
}
1886

    
1887
static inline void gen_addr_reg_index (DisasContext *ctx)
1888
{
1889
    if (rA(ctx->opcode) == 0) {
1890
        gen_op_load_gpr_T0(rB(ctx->opcode));
1891
    } else {
1892
        gen_op_load_gpr_T0(rA(ctx->opcode));
1893
        gen_op_load_gpr_T1(rB(ctx->opcode));
1894
        gen_op_add();
1895
    }
1896
#ifdef DEBUG_MEMORY_ACCESSES
1897
    gen_op_print_mem_EA();
1898
#endif
1899
}
1900

    
1901
static inline void gen_addr_register (DisasContext *ctx)
1902
{
1903
    if (rA(ctx->opcode) == 0) {
1904
        gen_op_reset_T0();
1905
    } else {
1906
        gen_op_load_gpr_T0(rA(ctx->opcode));
1907
    }
1908
#ifdef DEBUG_MEMORY_ACCESSES
1909
    gen_op_print_mem_EA();
1910
#endif
1911
}
1912

    
1913
/***                             Integer load                              ***/
1914
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1915
#if defined(CONFIG_USER_ONLY)
1916
#if defined(TARGET_PPC64)
1917
#define OP_LD_TABLE(width)                                                    \
1918
static GenOpFunc *gen_op_l##width[] = {                                       \
1919
    &gen_op_l##width##_raw,                                                   \
1920
    &gen_op_l##width##_le_raw,                                                \
1921
    &gen_op_l##width##_64_raw,                                                \
1922
    &gen_op_l##width##_le_64_raw,                                             \
1923
};
1924
#define OP_ST_TABLE(width)                                                    \
1925
static GenOpFunc *gen_op_st##width[] = {                                      \
1926
    &gen_op_st##width##_raw,                                                  \
1927
    &gen_op_st##width##_le_raw,                                               \
1928
    &gen_op_st##width##_64_raw,                                               \
1929
    &gen_op_st##width##_le_64_raw,                                            \
1930
};
1931
/* Byte access routine are endian safe */
1932
#define gen_op_stb_le_64_raw gen_op_stb_64_raw
1933
#define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1934
#else
1935
#define OP_LD_TABLE(width)                                                    \
1936
static GenOpFunc *gen_op_l##width[] = {                                       \
1937
    &gen_op_l##width##_raw,                                                   \
1938
    &gen_op_l##width##_le_raw,                                                \
1939
};
1940
#define OP_ST_TABLE(width)                                                    \
1941
static GenOpFunc *gen_op_st##width[] = {                                      \
1942
    &gen_op_st##width##_raw,                                                  \
1943
    &gen_op_st##width##_le_raw,                                               \
1944
};
1945
#endif
1946
/* Byte access routine are endian safe */
1947
#define gen_op_stb_le_raw gen_op_stb_raw
1948
#define gen_op_lbz_le_raw gen_op_lbz_raw
1949
#else
1950
#if defined(TARGET_PPC64)
1951
#define OP_LD_TABLE(width)                                                    \
1952
static GenOpFunc *gen_op_l##width[] = {                                       \
1953
    &gen_op_l##width##_user,                                                  \
1954
    &gen_op_l##width##_le_user,                                               \
1955
    &gen_op_l##width##_kernel,                                                \
1956
    &gen_op_l##width##_le_kernel,                                             \
1957
    &gen_op_l##width##_64_user,                                               \
1958
    &gen_op_l##width##_le_64_user,                                            \
1959
    &gen_op_l##width##_64_kernel,                                             \
1960
    &gen_op_l##width##_le_64_kernel,                                          \
1961
};
1962
#define OP_ST_TABLE(width)                                                    \
1963
static GenOpFunc *gen_op_st##width[] = {                                      \
1964
    &gen_op_st##width##_user,                                                 \
1965
    &gen_op_st##width##_le_user,                                              \
1966
    &gen_op_st##width##_kernel,                                               \
1967
    &gen_op_st##width##_le_kernel,                                            \
1968
    &gen_op_st##width##_64_user,                                              \
1969
    &gen_op_st##width##_le_64_user,                                           \
1970
    &gen_op_st##width##_64_kernel,                                            \
1971
    &gen_op_st##width##_le_64_kernel,                                         \
1972
};
1973
/* Byte access routine are endian safe */
1974
#define gen_op_stb_le_64_user gen_op_stb_64_user
1975
#define gen_op_lbz_le_64_user gen_op_lbz_64_user
1976
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
1977
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
1978
#else
1979
#define OP_LD_TABLE(width)                                                    \
1980
static GenOpFunc *gen_op_l##width[] = {                                       \
1981
    &gen_op_l##width##_user,                                                  \
1982
    &gen_op_l##width##_le_user,                                               \
1983
    &gen_op_l##width##_kernel,                                                \
1984
    &gen_op_l##width##_le_kernel,                                             \
1985
};
1986
#define OP_ST_TABLE(width)                                                    \
1987
static GenOpFunc *gen_op_st##width[] = {                                      \
1988
    &gen_op_st##width##_user,                                                 \
1989
    &gen_op_st##width##_le_user,                                              \
1990
    &gen_op_st##width##_kernel,                                               \
1991
    &gen_op_st##width##_le_kernel,                                            \
1992
};
1993
#endif
1994
/* Byte access routine are endian safe */
1995
#define gen_op_stb_le_user gen_op_stb_user
1996
#define gen_op_lbz_le_user gen_op_lbz_user
1997
#define gen_op_stb_le_kernel gen_op_stb_kernel
1998
#define gen_op_lbz_le_kernel gen_op_lbz_kernel
1999
#endif
2000

    
2001
#define GEN_LD(width, opc, type)                                              \
2002
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2003
{                                                                             \
2004
    gen_addr_imm_index(ctx, 0);                                               \
2005
    op_ldst(l##width);                                                        \
2006
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2007
}
2008

    
2009
#define GEN_LDU(width, opc, type)                                             \
2010
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2011
{                                                                             \
2012
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2013
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2014
        GEN_EXCP_INVAL(ctx);                                                  \
2015
        return;                                                               \
2016
    }                                                                         \
2017
    if (type == PPC_64B)                                                      \
2018
        gen_addr_imm_index(ctx, 1);                                           \
2019
    else                                                                      \
2020
        gen_addr_imm_index(ctx, 0);                                           \
2021
    op_ldst(l##width);                                                        \
2022
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2023
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2024
}
2025

    
2026
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2027
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2028
{                                                                             \
2029
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2030
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2031
        GEN_EXCP_INVAL(ctx);                                                  \
2032
        return;                                                               \
2033
    }                                                                         \
2034
    gen_addr_reg_index(ctx);                                                  \
2035
    op_ldst(l##width);                                                        \
2036
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2037
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2038
}
2039

    
2040
#define GEN_LDX(width, opc2, opc3, type)                                      \
2041
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2042
{                                                                             \
2043
    gen_addr_reg_index(ctx);                                                  \
2044
    op_ldst(l##width);                                                        \
2045
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2046
}
2047

    
2048
#define GEN_LDS(width, op, type)                                              \
2049
OP_LD_TABLE(width);                                                           \
2050
GEN_LD(width, op | 0x20, type);                                               \
2051
GEN_LDU(width, op | 0x21, type);                                              \
2052
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2053
GEN_LDX(width, 0x17, op | 0x00, type)
2054

    
2055
/* lbz lbzu lbzux lbzx */
2056
GEN_LDS(bz, 0x02, PPC_INTEGER);
2057
/* lha lhau lhaux lhax */
2058
GEN_LDS(ha, 0x0A, PPC_INTEGER);
2059
/* lhz lhzu lhzux lhzx */
2060
GEN_LDS(hz, 0x08, PPC_INTEGER);
2061
/* lwz lwzu lwzux lwzx */
2062
GEN_LDS(wz, 0x00, PPC_INTEGER);
2063
#if defined(TARGET_PPC64)
2064
OP_LD_TABLE(wa);
2065
OP_LD_TABLE(d);
2066
/* lwaux */
2067
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
2068
/* lwax */
2069
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
2070
/* ldux */
2071
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
2072
/* ldx */
2073
GEN_LDX(d, 0x15, 0x00, PPC_64B);
2074
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2075
{
2076
    if (Rc(ctx->opcode)) {
2077
        if (unlikely(rA(ctx->opcode) == 0 ||
2078
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2079
            GEN_EXCP_INVAL(ctx);
2080
            return;
2081
        }
2082
    }
2083
    gen_addr_imm_index(ctx, 1);
2084
    if (ctx->opcode & 0x02) {
2085
        /* lwa (lwau is undefined) */
2086
        op_ldst(lwa);
2087
    } else {
2088
        /* ld - ldu */
2089
        op_ldst(ld);
2090
    }
2091
    gen_op_store_T1_gpr(rD(ctx->opcode));
2092
    if (Rc(ctx->opcode))
2093
        gen_op_store_T0_gpr(rA(ctx->opcode));
2094
}
2095
#endif
2096

    
2097
/***                              Integer store                            ***/
2098
#define GEN_ST(width, opc, type)                                              \
2099
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2100
{                                                                             \
2101
    gen_addr_imm_index(ctx, 0);                                               \
2102
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2103
    op_ldst(st##width);                                                       \
2104
}
2105

    
2106
#define GEN_STU(width, opc, type)                                             \
2107
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2108
{                                                                             \
2109
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2110
        GEN_EXCP_INVAL(ctx);                                                  \
2111
        return;                                                               \
2112
    }                                                                         \
2113
    if (type == PPC_64B)                                                      \
2114
        gen_addr_imm_index(ctx, 1);                                           \
2115
    else                                                                      \
2116
        gen_addr_imm_index(ctx, 0);                                           \
2117
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2118
    op_ldst(st##width);                                                       \
2119
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2120
}
2121

    
2122
#define GEN_STUX(width, opc2, opc3, type)                                     \
2123
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2124
{                                                                             \
2125
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2126
        GEN_EXCP_INVAL(ctx);                                                  \
2127
        return;                                                               \
2128
    }                                                                         \
2129
    gen_addr_reg_index(ctx);                                                  \
2130
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2131
    op_ldst(st##width);                                                       \
2132
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2133
}
2134

    
2135
#define GEN_STX(width, opc2, opc3, type)                                      \
2136
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2137
{                                                                             \
2138
    gen_addr_reg_index(ctx);                                                  \
2139
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2140
    op_ldst(st##width);                                                       \
2141
}
2142

    
2143
#define GEN_STS(width, op, type)                                              \
2144
OP_ST_TABLE(width);                                                           \
2145
GEN_ST(width, op | 0x20, type);                                               \
2146
GEN_STU(width, op | 0x21, type);                                              \
2147
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2148
GEN_STX(width, 0x17, op | 0x00, type)
2149

    
2150
/* stb stbu stbux stbx */
2151
GEN_STS(b, 0x06, PPC_INTEGER);
2152
/* sth sthu sthux sthx */
2153
GEN_STS(h, 0x0C, PPC_INTEGER);
2154
/* stw stwu stwux stwx */
2155
GEN_STS(w, 0x04, PPC_INTEGER);
2156
#if defined(TARGET_PPC64)
2157
OP_ST_TABLE(d);
2158
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2159
GEN_STX(d, 0x15, 0x04, PPC_64B);
2160
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
2161
{
2162
    if (Rc(ctx->opcode)) {
2163
        if (unlikely(rA(ctx->opcode) == 0)) {
2164
            GEN_EXCP_INVAL(ctx);
2165
            return;
2166
        }
2167
    }
2168
    gen_addr_imm_index(ctx, 1);
2169
    gen_op_load_gpr_T1(rS(ctx->opcode));
2170
    op_ldst(std);
2171
    if (Rc(ctx->opcode))
2172
        gen_op_store_T0_gpr(rA(ctx->opcode));
2173
}
2174
#endif
2175
/***                Integer load and store with byte reverse               ***/
2176
/* lhbrx */
2177
OP_LD_TABLE(hbr);
2178
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2179
/* lwbrx */
2180
OP_LD_TABLE(wbr);
2181
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2182
/* sthbrx */
2183
OP_ST_TABLE(hbr);
2184
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2185
/* stwbrx */
2186
OP_ST_TABLE(wbr);
2187
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2188

    
2189
/***                    Integer load and store multiple                    ***/
2190
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2191
#if defined(TARGET_PPC64)
2192
#if defined(CONFIG_USER_ONLY)
2193
static GenOpFunc1 *gen_op_lmw[] = {
2194
    &gen_op_lmw_raw,
2195
    &gen_op_lmw_le_raw,
2196
    &gen_op_lmw_64_raw,
2197
    &gen_op_lmw_le_64_raw,
2198
};
2199
static GenOpFunc1 *gen_op_stmw[] = {
2200
    &gen_op_stmw_64_raw,
2201
    &gen_op_stmw_le_64_raw,
2202
};
2203
#else
2204
static GenOpFunc1 *gen_op_lmw[] = {
2205
    &gen_op_lmw_user,
2206
    &gen_op_lmw_le_user,
2207
    &gen_op_lmw_kernel,
2208
    &gen_op_lmw_le_kernel,
2209
    &gen_op_lmw_64_user,
2210
    &gen_op_lmw_le_64_user,
2211
    &gen_op_lmw_64_kernel,
2212
    &gen_op_lmw_le_64_kernel,
2213
};
2214
static GenOpFunc1 *gen_op_stmw[] = {
2215
    &gen_op_stmw_user,
2216
    &gen_op_stmw_le_user,
2217
    &gen_op_stmw_kernel,
2218
    &gen_op_stmw_le_kernel,
2219
    &gen_op_stmw_64_user,
2220
    &gen_op_stmw_le_64_user,
2221
    &gen_op_stmw_64_kernel,
2222
    &gen_op_stmw_le_64_kernel,
2223
};
2224
#endif
2225
#else
2226
#if defined(CONFIG_USER_ONLY)
2227
static GenOpFunc1 *gen_op_lmw[] = {
2228
    &gen_op_lmw_raw,
2229
    &gen_op_lmw_le_raw,
2230
};
2231
static GenOpFunc1 *gen_op_stmw[] = {
2232
    &gen_op_stmw_raw,
2233
    &gen_op_stmw_le_raw,
2234
};
2235
#else
2236
static GenOpFunc1 *gen_op_lmw[] = {
2237
    &gen_op_lmw_user,
2238
    &gen_op_lmw_le_user,
2239
    &gen_op_lmw_kernel,
2240
    &gen_op_lmw_le_kernel,
2241
};
2242
static GenOpFunc1 *gen_op_stmw[] = {
2243
    &gen_op_stmw_user,
2244
    &gen_op_stmw_le_user,
2245
    &gen_op_stmw_kernel,
2246
    &gen_op_stmw_le_kernel,
2247
};
2248
#endif
2249
#endif
2250

    
2251
/* lmw */
2252
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2253
{
2254
    /* NIP cannot be restored if the memory exception comes from an helper */
2255
    gen_update_nip(ctx, ctx->nip - 4);
2256
    gen_addr_imm_index(ctx, 0);
2257
    op_ldstm(lmw, rD(ctx->opcode));
2258
}
2259

    
2260
/* stmw */
2261
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2262
{
2263
    /* NIP cannot be restored if the memory exception comes from an helper */
2264
    gen_update_nip(ctx, ctx->nip - 4);
2265
    gen_addr_imm_index(ctx, 0);
2266
    op_ldstm(stmw, rS(ctx->opcode));
2267
}
2268

    
2269
/***                    Integer load and store strings                     ***/
2270
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2271
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2272
#if defined(TARGET_PPC64)
2273
#if defined(CONFIG_USER_ONLY)
2274
static GenOpFunc1 *gen_op_lswi[] = {
2275
    &gen_op_lswi_raw,
2276
    &gen_op_lswi_le_raw,
2277
    &gen_op_lswi_64_raw,
2278
    &gen_op_lswi_le_64_raw,
2279
};
2280
static GenOpFunc3 *gen_op_lswx[] = {
2281
    &gen_op_lswx_raw,
2282
    &gen_op_lswx_le_raw,
2283
    &gen_op_lswx_64_raw,
2284
    &gen_op_lswx_le_64_raw,
2285
};
2286
static GenOpFunc1 *gen_op_stsw[] = {
2287
    &gen_op_stsw_raw,
2288
    &gen_op_stsw_le_raw,
2289
    &gen_op_stsw_64_raw,
2290
    &gen_op_stsw_le_64_raw,
2291
};
2292
#else
2293
static GenOpFunc1 *gen_op_lswi[] = {
2294
    &gen_op_lswi_user,
2295
    &gen_op_lswi_le_user,
2296
    &gen_op_lswi_kernel,
2297
    &gen_op_lswi_le_kernel,
2298
    &gen_op_lswi_64_user,
2299
    &gen_op_lswi_le_64_user,
2300
    &gen_op_lswi_64_kernel,
2301
    &gen_op_lswi_le_64_kernel,
2302
};
2303
static GenOpFunc3 *gen_op_lswx[] = {
2304
    &gen_op_lswx_user,
2305
    &gen_op_lswx_le_user,
2306
    &gen_op_lswx_kernel,
2307
    &gen_op_lswx_le_kernel,
2308
    &gen_op_lswx_64_user,
2309
    &gen_op_lswx_le_64_user,
2310
    &gen_op_lswx_64_kernel,
2311
    &gen_op_lswx_le_64_kernel,
2312
};
2313
static GenOpFunc1 *gen_op_stsw[] = {
2314
    &gen_op_stsw_user,
2315
    &gen_op_stsw_le_user,
2316
    &gen_op_stsw_kernel,
2317
    &gen_op_stsw_le_kernel,
2318
    &gen_op_stsw_64_user,
2319
    &gen_op_stsw_le_64_user,
2320
    &gen_op_stsw_64_kernel,
2321
    &gen_op_stsw_le_64_kernel,
2322
};
2323
#endif
2324
#else
2325
#if defined(CONFIG_USER_ONLY)
2326
static GenOpFunc1 *gen_op_lswi[] = {
2327
    &gen_op_lswi_raw,
2328
    &gen_op_lswi_le_raw,
2329
};
2330
static GenOpFunc3 *gen_op_lswx[] = {
2331
    &gen_op_lswx_raw,
2332
    &gen_op_lswx_le_raw,
2333
};
2334
static GenOpFunc1 *gen_op_stsw[] = {
2335
    &gen_op_stsw_raw,
2336
    &gen_op_stsw_le_raw,
2337
};
2338
#else
2339
static GenOpFunc1 *gen_op_lswi[] = {
2340
    &gen_op_lswi_user,
2341
    &gen_op_lswi_le_user,
2342
    &gen_op_lswi_kernel,
2343
    &gen_op_lswi_le_kernel,
2344
};
2345
static GenOpFunc3 *gen_op_lswx[] = {
2346
    &gen_op_lswx_user,
2347
    &gen_op_lswx_le_user,
2348
    &gen_op_lswx_kernel,
2349
    &gen_op_lswx_le_kernel,
2350
};
2351
static GenOpFunc1 *gen_op_stsw[] = {
2352
    &gen_op_stsw_user,
2353
    &gen_op_stsw_le_user,
2354
    &gen_op_stsw_kernel,
2355
    &gen_op_stsw_le_kernel,
2356
};
2357
#endif
2358
#endif
2359

    
2360
/* lswi */
2361
/* PowerPC32 specification says we must generate an exception if
2362
 * rA is in the range of registers to be loaded.
2363
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2364
 * For now, I'll follow the spec...
2365
 */
2366
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
2367
{
2368
    int nb = NB(ctx->opcode);
2369
    int start = rD(ctx->opcode);
2370
    int ra = rA(ctx->opcode);
2371
    int nr;
2372

    
2373
    if (nb == 0)
2374
        nb = 32;
2375
    nr = nb / 4;
2376
    if (unlikely(((start + nr) > 32  &&
2377
                  start <= ra && (start + nr - 32) > ra) ||
2378
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2379
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
2380
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
2381
        return;
2382
    }
2383
    /* NIP cannot be restored if the memory exception comes from an helper */
2384
    gen_update_nip(ctx, ctx->nip - 4);
2385
    gen_addr_register(ctx);
2386
    gen_op_set_T1(nb);
2387
    op_ldsts(lswi, start);
2388
}
2389

    
2390
/* lswx */
2391
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
2392
{
2393
    int ra = rA(ctx->opcode);
2394
    int rb = rB(ctx->opcode);
2395

    
2396
    /* NIP cannot be restored if the memory exception comes from an helper */
2397
    gen_update_nip(ctx, ctx->nip - 4);
2398
    gen_addr_reg_index(ctx);
2399
    if (ra == 0) {
2400
        ra = rb;
2401
    }
2402
    gen_op_load_xer_bc();
2403
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2404
}
2405

    
2406
/* stswi */
2407
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
2408
{
2409
    int nb = NB(ctx->opcode);
2410

    
2411
    /* NIP cannot be restored if the memory exception comes from an helper */
2412
    gen_update_nip(ctx, ctx->nip - 4);
2413
    gen_addr_register(ctx);
2414
    if (nb == 0)
2415
        nb = 32;
2416
    gen_op_set_T1(nb);
2417
    op_ldsts(stsw, rS(ctx->opcode));
2418
}
2419

    
2420
/* stswx */
2421
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
2422
{
2423
    /* NIP cannot be restored if the memory exception comes from an helper */
2424
    gen_update_nip(ctx, ctx->nip - 4);
2425
    gen_addr_reg_index(ctx);
2426
    gen_op_load_xer_bc();
2427
    op_ldsts(stsw, rS(ctx->opcode));
2428
}
2429

    
2430
/***                        Memory synchronisation                         ***/
2431
/* eieio */
2432
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
2433
{
2434
}
2435

    
2436
/* isync */
2437
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
2438
{
2439
    GEN_STOP(ctx);
2440
}
2441

    
2442
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2443
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2444
#if defined(TARGET_PPC64)
2445
#if defined(CONFIG_USER_ONLY)
2446
static GenOpFunc *gen_op_lwarx[] = {
2447
    &gen_op_lwarx_raw,
2448
    &gen_op_lwarx_le_raw,
2449
    &gen_op_lwarx_64_raw,
2450
    &gen_op_lwarx_le_64_raw,
2451
};
2452
static GenOpFunc *gen_op_stwcx[] = {
2453
    &gen_op_stwcx_raw,
2454
    &gen_op_stwcx_le_raw,
2455
    &gen_op_stwcx_64_raw,
2456
    &gen_op_stwcx_le_64_raw,
2457
};
2458
#else
2459
static GenOpFunc *gen_op_lwarx[] = {
2460
    &gen_op_lwarx_user,
2461
    &gen_op_lwarx_le_user,
2462
    &gen_op_lwarx_kernel,
2463
    &gen_op_lwarx_le_kernel,
2464
    &gen_op_lwarx_64_user,
2465
    &gen_op_lwarx_le_64_user,
2466
    &gen_op_lwarx_64_kernel,
2467
    &gen_op_lwarx_le_64_kernel,
2468
};
2469
static GenOpFunc *gen_op_stwcx[] = {
2470
    &gen_op_stwcx_user,
2471
    &gen_op_stwcx_le_user,
2472
    &gen_op_stwcx_kernel,
2473
    &gen_op_stwcx_le_kernel,
2474
    &gen_op_stwcx_64_user,
2475
    &gen_op_stwcx_le_64_user,
2476
    &gen_op_stwcx_64_kernel,
2477
    &gen_op_stwcx_le_64_kernel,
2478
};
2479
#endif
2480
#else
2481
#if defined(CONFIG_USER_ONLY)
2482
static GenOpFunc *gen_op_lwarx[] = {
2483
    &gen_op_lwarx_raw,
2484
    &gen_op_lwarx_le_raw,
2485
};
2486
static GenOpFunc *gen_op_stwcx[] = {
2487
    &gen_op_stwcx_raw,
2488
    &gen_op_stwcx_le_raw,
2489
};
2490
#else
2491
static GenOpFunc *gen_op_lwarx[] = {
2492
    &gen_op_lwarx_user,
2493
    &gen_op_lwarx_le_user,
2494
    &gen_op_lwarx_kernel,
2495
    &gen_op_lwarx_le_kernel,
2496
};
2497
static GenOpFunc *gen_op_stwcx[] = {
2498
    &gen_op_stwcx_user,
2499
    &gen_op_stwcx_le_user,
2500
    &gen_op_stwcx_kernel,
2501
    &gen_op_stwcx_le_kernel,
2502
};
2503
#endif
2504
#endif
2505

    
2506
/* lwarx */
2507
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2508
{
2509
    gen_addr_reg_index(ctx);
2510
    op_lwarx();
2511
    gen_op_store_T1_gpr(rD(ctx->opcode));
2512
}
2513

    
2514
/* stwcx. */
2515
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2516
{
2517
    gen_addr_reg_index(ctx);
2518
    gen_op_load_gpr_T1(rS(ctx->opcode));
2519
    op_stwcx();
2520
}
2521

    
2522
#if defined(TARGET_PPC64)
2523
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2524
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2525
#if defined(CONFIG_USER_ONLY)
2526
static GenOpFunc *gen_op_ldarx[] = {
2527
    &gen_op_ldarx_raw,
2528
    &gen_op_ldarx_le_raw,
2529
    &gen_op_ldarx_64_raw,
2530
    &gen_op_ldarx_le_64_raw,
2531
};
2532
static GenOpFunc *gen_op_stdcx[] = {
2533
    &gen_op_stdcx_raw,
2534
    &gen_op_stdcx_le_raw,
2535
    &gen_op_stdcx_64_raw,
2536
    &gen_op_stdcx_le_64_raw,
2537
};
2538
#else
2539
static GenOpFunc *gen_op_ldarx[] = {
2540
    &gen_op_ldarx_user,
2541
    &gen_op_ldarx_le_user,
2542
    &gen_op_ldarx_kernel,
2543
    &gen_op_ldarx_le_kernel,
2544
    &gen_op_ldarx_64_user,
2545
    &gen_op_ldarx_le_64_user,
2546
    &gen_op_ldarx_64_kernel,
2547
    &gen_op_ldarx_le_64_kernel,
2548
};
2549
static GenOpFunc *gen_op_stdcx[] = {
2550
    &gen_op_stdcx_user,
2551
    &gen_op_stdcx_le_user,
2552
    &gen_op_stdcx_kernel,
2553
    &gen_op_stdcx_le_kernel,
2554
    &gen_op_stdcx_64_user,
2555
    &gen_op_stdcx_le_64_user,
2556
    &gen_op_stdcx_64_kernel,
2557
    &gen_op_stdcx_le_64_kernel,
2558
};
2559
#endif
2560

    
2561
/* ldarx */
2562
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2563
{
2564
    gen_addr_reg_index(ctx);
2565
    op_ldarx();
2566
    gen_op_store_T1_gpr(rD(ctx->opcode));
2567
}
2568

    
2569
/* stdcx. */
2570
GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2571
{
2572
    gen_addr_reg_index(ctx);
2573
    gen_op_load_gpr_T1(rS(ctx->opcode));
2574
    op_stdcx();
2575
}
2576
#endif /* defined(TARGET_PPC64) */
2577

    
2578
/* sync */
2579
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03CF0801, PPC_MEM_SYNC)
2580
{
2581
}
2582

    
2583
/***                         Floating-point load                           ***/
2584
#define GEN_LDF(width, opc)                                                   \
2585
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                 \
2586
{                                                                             \
2587
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2588
        GEN_EXCP_NO_FP(ctx);                                                  \
2589
        return;                                                               \
2590
    }                                                                         \
2591
    gen_addr_imm_index(ctx, 0);                                               \
2592
    op_ldst(l##width);                                                        \
2593
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2594
}
2595

    
2596
#define GEN_LDUF(width, opc)                                                  \
2597
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)              \
2598
{                                                                             \
2599
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2600
        GEN_EXCP_NO_FP(ctx);                                                  \
2601
        return;                                                               \
2602
    }                                                                         \
2603
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2604
        GEN_EXCP_INVAL(ctx);                                                  \
2605
        return;                                                               \
2606
    }                                                                         \
2607
    gen_addr_imm_index(ctx, 0);                                               \
2608
    op_ldst(l##width);                                                        \
2609
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2610
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2611
}
2612

    
2613
#define GEN_LDUXF(width, opc)                                                 \
2614
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
2615
{                                                                             \
2616
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2617
        GEN_EXCP_NO_FP(ctx);                                                  \
2618
        return;                                                               \
2619
    }                                                                         \
2620
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2621
        GEN_EXCP_INVAL(ctx);                                                  \
2622
        return;                                                               \
2623
    }                                                                         \
2624
    gen_addr_reg_index(ctx);                                                  \
2625
    op_ldst(l##width);                                                        \
2626
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2627
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2628
}
2629

    
2630
#define GEN_LDXF(width, opc2, opc3)                                           \
2631
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)             \
2632
{                                                                             \
2633
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2634
        GEN_EXCP_NO_FP(ctx);                                                  \
2635
        return;                                                               \
2636
    }                                                                         \
2637
    gen_addr_reg_index(ctx);                                                  \
2638
    op_ldst(l##width);                                                        \
2639
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2640
}
2641

    
2642
#define GEN_LDFS(width, op)                                                   \
2643
OP_LD_TABLE(width);                                                           \
2644
GEN_LDF(width, op | 0x20);                                                    \
2645
GEN_LDUF(width, op | 0x21);                                                   \
2646
GEN_LDUXF(width, op | 0x01);                                                  \
2647
GEN_LDXF(width, 0x17, op | 0x00)
2648

    
2649
/* lfd lfdu lfdux lfdx */
2650
GEN_LDFS(fd, 0x12);
2651
/* lfs lfsu lfsux lfsx */
2652
GEN_LDFS(fs, 0x10);
2653

    
2654
/***                         Floating-point store                          ***/
2655
#define GEN_STF(width, opc)                                                   \
2656
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
2657
{                                                                             \
2658
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2659
        GEN_EXCP_NO_FP(ctx);                                                  \
2660
        return;                                                               \
2661
    }                                                                         \
2662
    gen_addr_imm_index(ctx, 0);                                               \
2663
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2664
    op_ldst(st##width);                                                       \
2665
}
2666

    
2667
#define GEN_STUF(width, opc)                                                  \
2668
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
2669
{                                                                             \
2670
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2671
        GEN_EXCP_NO_FP(ctx);                                                  \
2672
        return;                                                               \
2673
    }                                                                         \
2674
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2675
        GEN_EXCP_INVAL(ctx);                                                  \
2676
        return;                                                               \
2677
    }                                                                         \
2678
    gen_addr_imm_index(ctx, 0);                                               \
2679
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2680
    op_ldst(st##width);                                                       \
2681
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2682
}
2683

    
2684
#define GEN_STUXF(width, opc)                                                 \
2685
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
2686
{                                                                             \
2687
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2688
        GEN_EXCP_NO_FP(ctx);                                                  \
2689
        return;                                                               \
2690
    }                                                                         \
2691
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2692
        GEN_EXCP_INVAL(ctx);                                                  \
2693
        return;                                                               \
2694
    }                                                                         \
2695
    gen_addr_reg_index(ctx);                                                  \
2696
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2697
    op_ldst(st##width);                                                       \
2698
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2699
}
2700

    
2701
#define GEN_STXF(width, opc2, opc3)                                           \
2702
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)            \
2703
{                                                                             \
2704
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2705
        GEN_EXCP_NO_FP(ctx);                                                  \
2706
        return;                                                               \
2707
    }                                                                         \
2708
    gen_addr_reg_index(ctx);                                                  \
2709
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2710
    op_ldst(st##width);                                                       \
2711
}
2712

    
2713
#define GEN_STFS(width, op)                                                   \
2714
OP_ST_TABLE(width);                                                           \
2715
GEN_STF(width, op | 0x20);                                                    \
2716
GEN_STUF(width, op | 0x21);                                                   \
2717
GEN_STUXF(width, op | 0x01);                                                  \
2718
GEN_STXF(width, 0x17, op | 0x00)
2719

    
2720
/* stfd stfdu stfdux stfdx */
2721
GEN_STFS(fd, 0x16);
2722
/* stfs stfsu stfsux stfsx */
2723
GEN_STFS(fs, 0x14);
2724

    
2725
/* Optional: */
2726
/* stfiwx */
2727
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT_STFIWX)
2728
{
2729
    if (unlikely(!ctx->fpu_enabled)) {
2730
        GEN_EXCP_NO_FP(ctx);
2731
        return;
2732
    }
2733
    gen_addr_reg_index(ctx);
2734
    /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2735
    GEN_EXCP_INVAL(ctx);
2736
}
2737

    
2738
/***                                Branch                                 ***/
2739
static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
2740
{
2741
    TranslationBlock *tb;
2742
    tb = ctx->tb;
2743
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2744
        if (n == 0)
2745
            gen_op_goto_tb0(TBPARAM(tb));
2746
        else
2747
            gen_op_goto_tb1(TBPARAM(tb));
2748
        gen_set_T1(dest);
2749
#if defined(TARGET_PPC64)
2750
        if (ctx->sf_mode)
2751
            gen_op_b_T1_64();
2752
        else
2753
#endif
2754
            gen_op_b_T1();
2755
        gen_op_set_T0((long)tb + n);
2756
        if (ctx->singlestep_enabled)
2757
            gen_op_debug();
2758
        gen_op_exit_tb();
2759
    } else {
2760
        gen_set_T1(dest);
2761
#if defined(TARGET_PPC64)
2762
        if (ctx->sf_mode)
2763
            gen_op_b_T1_64();
2764
        else
2765
#endif
2766
            gen_op_b_T1();
2767
        gen_op_reset_T0();
2768
        if (ctx->singlestep_enabled)
2769
            gen_op_debug();
2770
        gen_op_exit_tb();
2771
    }
2772
}
2773

    
2774
static inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2775
{
2776
#if defined(TARGET_PPC64)
2777
    if (ctx->sf_mode != 0 && (nip >> 32))
2778
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2779
    else
2780
#endif
2781
        gen_op_setlr(ctx->nip);
2782
}
2783

    
2784
/* b ba bl bla */
2785
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2786
{
2787
    target_ulong li, target;
2788

    
2789
    /* sign extend LI */
2790
#if defined(TARGET_PPC64)
2791
    if (ctx->sf_mode)
2792
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2793
    else
2794
#endif
2795
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2796
    if (likely(AA(ctx->opcode) == 0))
2797
        target = ctx->nip + li - 4;
2798
    else
2799
        target = li;
2800
#if defined(TARGET_PPC64)
2801
    if (!ctx->sf_mode)
2802
        target = (uint32_t)target;
2803
#endif
2804
    if (LK(ctx->opcode))
2805
        gen_setlr(ctx, ctx->nip);
2806
    gen_goto_tb(ctx, 0, target);
2807
    ctx->exception = POWERPC_EXCP_BRANCH;
2808
}
2809

    
2810
#define BCOND_IM  0
2811
#define BCOND_LR  1
2812
#define BCOND_CTR 2
2813

    
2814
static inline void gen_bcond (DisasContext *ctx, int type)
2815
{
2816
    target_ulong target = 0;
2817
    target_ulong li;
2818
    uint32_t bo = BO(ctx->opcode);
2819
    uint32_t bi = BI(ctx->opcode);
2820
    uint32_t mask;
2821

    
2822
    if ((bo & 0x4) == 0)
2823
        gen_op_dec_ctr();
2824
    switch(type) {
2825
    case BCOND_IM:
2826
        li = (target_long)((int16_t)(BD(ctx->opcode)));
2827
        if (likely(AA(ctx->opcode) == 0)) {
2828
            target = ctx->nip + li - 4;
2829
        } else {
2830
            target = li;
2831
        }
2832
#if defined(TARGET_PPC64)
2833
        if (!ctx->sf_mode)
2834
            target = (uint32_t)target;
2835
#endif
2836
        break;
2837
    case BCOND_CTR:
2838
        gen_op_movl_T1_ctr();
2839
        break;
2840
    default:
2841
    case BCOND_LR:
2842
        gen_op_movl_T1_lr();
2843
        break;
2844
    }
2845
    if (LK(ctx->opcode))
2846
        gen_setlr(ctx, ctx->nip);
2847
    if (bo & 0x10) {
2848
        /* No CR condition */
2849
        switch (bo & 0x6) {
2850
        case 0:
2851
#if defined(TARGET_PPC64)
2852
            if (ctx->sf_mode)
2853
                gen_op_test_ctr_64();
2854
            else
2855
#endif
2856
                gen_op_test_ctr();
2857
            break;
2858
        case 2:
2859
#if defined(TARGET_PPC64)
2860
            if (ctx->sf_mode)
2861
                gen_op_test_ctrz_64();
2862
            else
2863
#endif
2864
                gen_op_test_ctrz();
2865
            break;
2866
        default:
2867
        case 4:
2868
        case 6:
2869
            if (type == BCOND_IM) {
2870
                gen_goto_tb(ctx, 0, target);
2871
            } else {
2872
#if defined(TARGET_PPC64)
2873
                if (ctx->sf_mode)
2874
                    gen_op_b_T1_64();
2875
                else
2876
#endif
2877
                    gen_op_b_T1();
2878
                gen_op_reset_T0();
2879
            }
2880
            goto no_test;
2881
        }
2882
    } else {
2883
        mask = 1 << (3 - (bi & 0x03));
2884
        gen_op_load_crf_T0(bi >> 2);
2885
        if (bo & 0x8) {
2886
            switch (bo & 0x6) {
2887
            case 0:
2888
#if defined(TARGET_PPC64)
2889
                if (ctx->sf_mode)
2890
                    gen_op_test_ctr_true_64(mask);
2891
                else
2892
#endif
2893
                    gen_op_test_ctr_true(mask);
2894
                break;
2895
            case 2:
2896
#if defined(TARGET_PPC64)
2897
                if (ctx->sf_mode)
2898
                    gen_op_test_ctrz_true_64(mask);
2899
                else
2900
#endif
2901
                    gen_op_test_ctrz_true(mask);
2902
                break;
2903
            default:
2904
            case 4:
2905
            case 6:
2906
                gen_op_test_true(mask);
2907
                break;
2908
            }
2909
        } else {
2910
            switch (bo & 0x6) {
2911
            case 0:
2912
#if defined(TARGET_PPC64)
2913
                if (ctx->sf_mode)
2914
                    gen_op_test_ctr_false_64(mask);
2915
                else
2916
#endif
2917
                    gen_op_test_ctr_false(mask);
2918
                break;
2919
            case 2:
2920
#if defined(TARGET_PPC64)
2921
                if (ctx->sf_mode)
2922
                    gen_op_test_ctrz_false_64(mask);
2923
                else
2924
#endif
2925
                    gen_op_test_ctrz_false(mask);
2926
                break;
2927
            default:
2928
            case 4:
2929
            case 6:
2930
                gen_op_test_false(mask);
2931
                break;
2932
            }
2933
        }
2934
    }
2935
    if (type == BCOND_IM) {
2936
        int l1 = gen_new_label();
2937
        gen_op_jz_T0(l1);
2938
        gen_goto_tb(ctx, 0, target);
2939
        gen_set_label(l1);
2940
        gen_goto_tb(ctx, 1, ctx->nip);
2941
    } else {
2942
#if defined(TARGET_PPC64)
2943
        if (ctx->sf_mode)
2944
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
2945
        else
2946
#endif
2947
            gen_op_btest_T1(ctx->nip);
2948
        gen_op_reset_T0();
2949
    no_test:
2950
        if (ctx->singlestep_enabled)
2951
            gen_op_debug();
2952
        gen_op_exit_tb();
2953
    }
2954
    ctx->exception = POWERPC_EXCP_BRANCH;
2955
}
2956

    
2957
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2958
{
2959
    gen_bcond(ctx, BCOND_IM);
2960
}
2961

    
2962
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
2963
{
2964
    gen_bcond(ctx, BCOND_CTR);
2965
}
2966

    
2967
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
2968
{
2969
    gen_bcond(ctx, BCOND_LR);
2970
}
2971

    
2972
/***                      Condition register logical                       ***/
2973
#define GEN_CRLOGIC(op, opc)                                                  \
2974
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
2975
{                                                                             \
2976
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
2977
    gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
2978
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
2979
    gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
2980
    gen_op_##op();                                                            \
2981
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
2982
    gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
2983
                     3 - (crbD(ctx->opcode) & 0x03));                         \
2984
    gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
2985
}
2986

    
2987
/* crand */
2988
GEN_CRLOGIC(and, 0x08);
2989
/* crandc */
2990
GEN_CRLOGIC(andc, 0x04);
2991
/* creqv */
2992
GEN_CRLOGIC(eqv, 0x09);
2993
/* crnand */
2994
GEN_CRLOGIC(nand, 0x07);
2995
/* crnor */
2996
GEN_CRLOGIC(nor, 0x01);
2997
/* cror */
2998
GEN_CRLOGIC(or, 0x0E);
2999
/* crorc */
3000
GEN_CRLOGIC(orc, 0x0D);
3001
/* crxor */
3002
GEN_CRLOGIC(xor, 0x06);
3003
/* mcrf */
3004
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3005
{
3006
    gen_op_load_crf_T0(crfS(ctx->opcode));
3007
    gen_op_store_T0_crf(crfD(ctx->opcode));
3008
}
3009

    
3010
/***                           System linkage                              ***/
3011
/* rfi (supervisor only) */
3012
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3013
{
3014
#if defined(CONFIG_USER_ONLY)
3015
    GEN_EXCP_PRIVOPC(ctx);
3016
#else
3017
    /* Restore CPU state */
3018
    if (unlikely(!ctx->supervisor)) {
3019
        GEN_EXCP_PRIVOPC(ctx);
3020
        return;
3021
    }
3022
    gen_op_rfi();
3023
    GEN_SYNC(ctx);
3024
#endif
3025
}
3026

    
3027
#if defined(TARGET_PPC64)
3028
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3029
{
3030
#if defined(CONFIG_USER_ONLY)
3031
    GEN_EXCP_PRIVOPC(ctx);
3032
#else
3033
    /* Restore CPU state */
3034
    if (unlikely(!ctx->supervisor)) {
3035
        GEN_EXCP_PRIVOPC(ctx);
3036
        return;
3037
    }
3038
    gen_op_rfid();
3039
    GEN_SYNC(ctx);
3040
#endif
3041
}
3042
#endif
3043

    
3044
/* sc */
3045
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3046
{
3047
    uint32_t lev;
3048

    
3049
    lev = (ctx->opcode >> 5) & 0x7F;
3050
#if defined(CONFIG_USER_ONLY)
3051
    GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
3052
#else
3053
    GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL, lev);
3054
#endif
3055
}
3056

    
3057
/***                                Trap                                   ***/
3058
/* tw */
3059
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3060
{
3061
    gen_op_load_gpr_T0(rA(ctx->opcode));
3062
    gen_op_load_gpr_T1(rB(ctx->opcode));
3063
    /* Update the nip since this might generate a trap exception */
3064
    gen_update_nip(ctx, ctx->nip);
3065
    gen_op_tw(TO(ctx->opcode));
3066
}
3067

    
3068
/* twi */
3069
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3070
{
3071
    gen_op_load_gpr_T0(rA(ctx->opcode));
3072
    gen_set_T1(SIMM(ctx->opcode));
3073
    /* Update the nip since this might generate a trap exception */
3074
    gen_update_nip(ctx, ctx->nip);
3075
    gen_op_tw(TO(ctx->opcode));
3076
}
3077

    
3078
#if defined(TARGET_PPC64)
3079
/* td */
3080
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3081
{
3082
    gen_op_load_gpr_T0(rA(ctx->opcode));
3083
    gen_op_load_gpr_T1(rB(ctx->opcode));
3084
    /* Update the nip since this might generate a trap exception */
3085
    gen_update_nip(ctx, ctx->nip);
3086
    gen_op_td(TO(ctx->opcode));
3087
}
3088

    
3089
/* tdi */
3090
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3091
{
3092
    gen_op_load_gpr_T0(rA(ctx->opcode));
3093
    gen_set_T1(SIMM(ctx->opcode));
3094
    /* Update the nip since this might generate a trap exception */
3095
    gen_update_nip(ctx, ctx->nip);
3096
    gen_op_td(TO(ctx->opcode));
3097
}
3098
#endif
3099

    
3100
/***                          Processor control                            ***/
3101
/* mcrxr */
3102
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3103
{
3104
    gen_op_load_xer_cr();
3105
    gen_op_store_T0_crf(crfD(ctx->opcode));
3106
    gen_op_clear_xer_ov();
3107
    gen_op_clear_xer_ca();
3108
}
3109

    
3110
/* mfcr */
3111
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3112
{
3113
    uint32_t crm, crn;
3114

    
3115
    if (likely(ctx->opcode & 0x00100000)) {
3116
        crm = CRM(ctx->opcode);
3117
        if (likely((crm ^ (crm - 1)) == 0)) {
3118
            crn = ffs(crm);
3119
            gen_op_load_cro(7 - crn);
3120
        }
3121
    } else {
3122
        gen_op_load_cr();
3123
    }
3124
    gen_op_store_T0_gpr(rD(ctx->opcode));
3125
}
3126

    
3127
/* mfmsr */
3128
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3129
{
3130
#if defined(CONFIG_USER_ONLY)
3131
    GEN_EXCP_PRIVREG(ctx);
3132
#else
3133
    if (unlikely(!ctx->supervisor)) {
3134
        GEN_EXCP_PRIVREG(ctx);
3135
        return;
3136
    }
3137
    gen_op_load_msr();
3138
    gen_op_store_T0_gpr(rD(ctx->opcode));
3139
#endif
3140
}
3141

    
3142
#if 0
3143
#define SPR_NOACCESS ((void *)(-1))
3144
#else
3145
static void spr_noaccess (void *opaque, int sprn)
3146
{
3147
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3148
    printf("ERROR: try to access SPR %d !\n", sprn);
3149
}
3150
#define SPR_NOACCESS (&spr_noaccess)
3151
#endif
3152

    
3153
/* mfspr */
3154
static inline void gen_op_mfspr (DisasContext *ctx)
3155
{
3156
    void (*read_cb)(void *opaque, int sprn);
3157
    uint32_t sprn = SPR(ctx->opcode);
3158

    
3159
#if !defined(CONFIG_USER_ONLY)
3160
    if (ctx->supervisor)
3161
        read_cb = ctx->spr_cb[sprn].oea_read;
3162
    else
3163
#endif
3164
        read_cb = ctx->spr_cb[sprn].uea_read;
3165
    if (likely(read_cb != NULL)) {
3166
        if (likely(read_cb != SPR_NOACCESS)) {
3167
            (*read_cb)(ctx, sprn);
3168
            gen_op_store_T0_gpr(rD(ctx->opcode));
3169
        } else {
3170
            /* Privilege exception */
3171
            if (loglevel != 0) {
3172
                fprintf(logfile, "Trying to read privileged spr %d %03x\n",
3173
                        sprn, sprn);
3174
            }
3175
            printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
3176
            GEN_EXCP_PRIVREG(ctx);
3177
        }
3178
    } else {
3179
        /* Not defined */
3180
        if (loglevel != 0) {
3181
            fprintf(logfile, "Trying to read invalid spr %d %03x\n",
3182
                    sprn, sprn);
3183
        }
3184
        printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
3185
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3186
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3187
    }
3188
}
3189

    
3190
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3191
{
3192
    gen_op_mfspr(ctx);
3193
}
3194

    
3195
/* mftb */
3196
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3197
{
3198
    gen_op_mfspr(ctx);
3199
}
3200

    
3201
/* mtcrf */
3202
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3203
{
3204
    uint32_t crm, crn;
3205

    
3206
    gen_op_load_gpr_T0(rS(ctx->opcode));
3207
    crm = CRM(ctx->opcode);
3208
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3209
        crn = ffs(crm);
3210
        gen_op_srli_T0(crn * 4);
3211
        gen_op_andi_T0(0xF);
3212
        gen_op_store_cro(7 - crn);
3213
    } else {
3214
        gen_op_store_cr(crm);
3215
    }
3216
}
3217

    
3218
/* mtmsr */
3219
#if defined(TARGET_PPC64)
3220
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
3221
{
3222
#if defined(CONFIG_USER_ONLY)
3223
    GEN_EXCP_PRIVREG(ctx);
3224
#else
3225
    if (unlikely(!ctx->supervisor)) {
3226
        GEN_EXCP_PRIVREG(ctx);
3227
        return;
3228
    }
3229
    gen_update_nip(ctx, ctx->nip);
3230
    gen_op_load_gpr_T0(rS(ctx->opcode));
3231
    gen_op_store_msr();
3232
    /* Must stop the translation as machine state (may have) changed */
3233
    /* Note that mtmsr is not always defined as context-synchronizing */
3234
    GEN_STOP(ctx);
3235
#endif
3236
}
3237
#endif
3238

    
3239
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3240
{
3241
#if defined(CONFIG_USER_ONLY)
3242
    GEN_EXCP_PRIVREG(ctx);
3243
#else
3244
    if (unlikely(!ctx->supervisor)) {
3245
        GEN_EXCP_PRIVREG(ctx);
3246
        return;
3247
    }
3248
    gen_update_nip(ctx, ctx->nip);
3249
    gen_op_load_gpr_T0(rS(ctx->opcode));
3250
#if defined(TARGET_PPC64)
3251
    if (!ctx->sf_mode)
3252
        gen_op_store_msr_32();
3253
    else
3254
#endif
3255
        gen_op_store_msr();
3256
    /* Must stop the translation as machine state (may have) changed */
3257
    /* Note that mtmsrd is not always defined as context-synchronizing */
3258
    GEN_STOP(ctx);
3259
#endif
3260
}
3261

    
3262
/* mtspr */
3263
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3264
{
3265
    void (*write_cb)(void *opaque, int sprn);
3266
    uint32_t sprn = SPR(ctx->opcode);
3267

    
3268
#if !defined(CONFIG_USER_ONLY)
3269
    if (ctx->supervisor)
3270
        write_cb = ctx->spr_cb[sprn].oea_write;
3271
    else
3272
#endif
3273
        write_cb = ctx->spr_cb[sprn].uea_write;
3274
    if (likely(write_cb != NULL)) {
3275
        if (likely(write_cb != SPR_NOACCESS)) {
3276
            gen_op_load_gpr_T0(rS(ctx->opcode));
3277
            (*write_cb)(ctx, sprn);
3278
        } else {
3279
            /* Privilege exception */
3280
            if (loglevel != 0) {
3281
                fprintf(logfile, "Trying to write privileged spr %d %03x\n",
3282
                        sprn, sprn);
3283
            }
3284
            printf("Trying to write privileged spr %d %03x\n", sprn, sprn);
3285
            GEN_EXCP_PRIVREG(ctx);
3286
        }
3287
    } else {
3288
        /* Not defined */
3289
        if (loglevel != 0) {
3290
            fprintf(logfile, "Trying to write invalid spr %d %03x\n",
3291
                    sprn, sprn);
3292
        }
3293
        printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
3294
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3295
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3296
    }
3297
}
3298

    
3299
/***                         Cache management                              ***/
3300
/* For now, all those will be implemented as nop:
3301
 * this is valid, regarding the PowerPC specs...
3302
 * We just have to flush tb while invalidating instruction cache lines...
3303
 */
3304
/* dcbf */
3305
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
3306
{
3307
    gen_addr_reg_index(ctx);
3308
    op_ldst(lbz);
3309
}
3310

    
3311
/* dcbi (Supervisor only) */
3312
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3313
{
3314
#if defined(CONFIG_USER_ONLY)
3315
    GEN_EXCP_PRIVOPC(ctx);
3316
#else
3317
    if (unlikely(!ctx->supervisor)) {
3318
        GEN_EXCP_PRIVOPC(ctx);
3319
        return;
3320
    }
3321
    gen_addr_reg_index(ctx);
3322
    /* XXX: specification says this should be treated as a store by the MMU */
3323
    //op_ldst(lbz);
3324
    op_ldst(stb);
3325
#endif
3326
}
3327

    
3328
/* dcdst */
3329
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3330
{
3331
    /* XXX: specification say this is treated as a load by the MMU */
3332
    gen_addr_reg_index(ctx);
3333
    op_ldst(lbz);
3334
}
3335

    
3336
/* dcbt */
3337
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
3338
{
3339
    /* XXX: specification say this is treated as a load by the MMU
3340
     *      but does not generate any exception
3341
     */
3342
}
3343

    
3344
/* dcbtst */
3345
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
3346
{
3347
    /* XXX: specification say this is treated as a load by the MMU
3348
     *      but does not generate any exception
3349
     */
3350
}
3351

    
3352
/* dcbz */
3353
#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3354
#if defined(TARGET_PPC64)
3355
#if defined(CONFIG_USER_ONLY)
3356
static GenOpFunc *gen_op_dcbz[] = {
3357
    &gen_op_dcbz_raw,
3358
    &gen_op_dcbz_raw,
3359
    &gen_op_dcbz_64_raw,
3360
    &gen_op_dcbz_64_raw,
3361
};
3362
#else
3363
static GenOpFunc *gen_op_dcbz[] = {
3364
    &gen_op_dcbz_user,
3365
    &gen_op_dcbz_user,
3366
    &gen_op_dcbz_kernel,
3367
    &gen_op_dcbz_kernel,
3368
    &gen_op_dcbz_64_user,
3369
    &gen_op_dcbz_64_user,
3370
    &gen_op_dcbz_64_kernel,
3371
    &gen_op_dcbz_64_kernel,
3372
};
3373
#endif
3374
#else
3375
#if defined(CONFIG_USER_ONLY)
3376
static GenOpFunc *gen_op_dcbz[] = {
3377
    &gen_op_dcbz_raw,
3378
    &gen_op_dcbz_raw,
3379
};
3380
#else
3381
static GenOpFunc *gen_op_dcbz[] = {
3382
    &gen_op_dcbz_user,
3383
    &gen_op_dcbz_user,
3384
    &gen_op_dcbz_kernel,
3385
    &gen_op_dcbz_kernel,
3386
};
3387
#endif
3388
#endif
3389

    
3390
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3391
{
3392
    gen_addr_reg_index(ctx);
3393
    op_dcbz();
3394
    gen_op_check_reservation();
3395
}
3396

    
3397
/* icbi */
3398
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3399
#if defined(TARGET_PPC64)
3400
#if defined(CONFIG_USER_ONLY)
3401
static GenOpFunc *gen_op_icbi[] = {
3402
    &gen_op_icbi_raw,
3403
    &gen_op_icbi_raw,
3404
    &gen_op_icbi_64_raw,
3405
    &gen_op_icbi_64_raw,
3406
};
3407
#else
3408
static GenOpFunc *gen_op_icbi[] = {
3409
    &gen_op_icbi_user,
3410
    &gen_op_icbi_user,
3411
    &gen_op_icbi_kernel,
3412
    &gen_op_icbi_kernel,
3413
    &gen_op_icbi_64_user,
3414
    &gen_op_icbi_64_user,
3415
    &gen_op_icbi_64_kernel,
3416
    &gen_op_icbi_64_kernel,
3417
};
3418
#endif
3419
#else
3420
#if defined(CONFIG_USER_ONLY)
3421
static GenOpFunc *gen_op_icbi[] = {
3422
    &gen_op_icbi_raw,
3423
    &gen_op_icbi_raw,
3424
};
3425
#else
3426
static GenOpFunc *gen_op_icbi[] = {
3427
    &gen_op_icbi_user,
3428
    &gen_op_icbi_user,
3429
    &gen_op_icbi_kernel,
3430
    &gen_op_icbi_kernel,
3431
};
3432
#endif
3433
#endif
3434

    
3435
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3436
{
3437
    gen_addr_reg_index(ctx);
3438
    op_icbi();
3439
}
3440

    
3441
/* Optional: */
3442
/* dcba */
3443
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3444
{
3445
}
3446

    
3447
/***                    Segment register manipulation                      ***/
3448
/* Supervisor only: */
3449
/* mfsr */
3450
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3451
{
3452
#if defined(CONFIG_USER_ONLY)
3453
    GEN_EXCP_PRIVREG(ctx);
3454
#else
3455
    if (unlikely(!ctx->supervisor)) {
3456
        GEN_EXCP_PRIVREG(ctx);
3457
        return;
3458
    }
3459
    gen_op_set_T1(SR(ctx->opcode));
3460
    gen_op_load_sr();
3461
    gen_op_store_T0_gpr(rD(ctx->opcode));
3462
#endif
3463
}
3464

    
3465
/* mfsrin */
3466
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3467
{
3468
#if defined(CONFIG_USER_ONLY)
3469
    GEN_EXCP_PRIVREG(ctx);
3470
#else
3471
    if (unlikely(!ctx->supervisor)) {
3472
        GEN_EXCP_PRIVREG(ctx);
3473
        return;
3474
    }
3475
    gen_op_load_gpr_T1(rB(ctx->opcode));
3476
    gen_op_srli_T1(28);
3477
    gen_op_load_sr();
3478
    gen_op_store_T0_gpr(rD(ctx->opcode));
3479
#endif
3480
}
3481

    
3482
/* mtsr */
3483
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3484
{
3485
#if defined(CONFIG_USER_ONLY)
3486
    GEN_EXCP_PRIVREG(ctx);
3487
#else
3488
    if (unlikely(!ctx->supervisor)) {
3489
        GEN_EXCP_PRIVREG(ctx);
3490
        return;
3491
    }
3492
    gen_op_load_gpr_T0(rS(ctx->opcode));
3493
    gen_op_set_T1(SR(ctx->opcode));
3494
    gen_op_store_sr();
3495
#endif
3496
}
3497

    
3498
/* mtsrin */
3499
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3500
{
3501
#if defined(CONFIG_USER_ONLY)
3502
    GEN_EXCP_PRIVREG(ctx);
3503
#else
3504
    if (unlikely(!ctx->supervisor)) {
3505
        GEN_EXCP_PRIVREG(ctx);
3506
        return;
3507
    }
3508
    gen_op_load_gpr_T0(rS(ctx->opcode));
3509
    gen_op_load_gpr_T1(rB(ctx->opcode));
3510
    gen_op_srli_T1(28);
3511
    gen_op_store_sr();
3512
#endif
3513
}
3514

    
3515
/***                      Lookaside buffer management                      ***/
3516
/* Optional & supervisor only: */
3517
/* tlbia */
3518
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3519
{
3520
#if defined(CONFIG_USER_ONLY)
3521
    GEN_EXCP_PRIVOPC(ctx);
3522
#else
3523
    if (unlikely(!ctx->supervisor)) {
3524
        if (loglevel != 0)
3525
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3526
        GEN_EXCP_PRIVOPC(ctx);
3527
        return;
3528
    }
3529
    gen_op_tlbia();
3530
#endif
3531
}
3532

    
3533
/* tlbie */
3534
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3535
{
3536
#if defined(CONFIG_USER_ONLY)
3537
    GEN_EXCP_PRIVOPC(ctx);
3538
#else
3539
    if (unlikely(!ctx->supervisor)) {
3540
        GEN_EXCP_PRIVOPC(ctx);
3541
        return;
3542
    }
3543
    gen_op_load_gpr_T0(rB(ctx->opcode));
3544
#if defined(TARGET_PPC64)
3545
    if (ctx->sf_mode)
3546
        gen_op_tlbie_64();
3547
    else
3548
#endif
3549
        gen_op_tlbie();
3550
#endif
3551
}
3552

    
3553
/* tlbsync */
3554
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3555
{
3556
#if defined(CONFIG_USER_ONLY)
3557
    GEN_EXCP_PRIVOPC(ctx);
3558
#else
3559
    if (unlikely(!ctx->supervisor)) {
3560
        GEN_EXCP_PRIVOPC(ctx);
3561
        return;
3562
    }
3563
    /* This has no effect: it should ensure that all previous
3564
     * tlbie have completed
3565
     */
3566
    GEN_STOP(ctx);
3567
#endif
3568
}
3569

    
3570
#if defined(TARGET_PPC64)
3571
/* slbia */
3572
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3573
{
3574
#if defined(CONFIG_USER_ONLY)
3575
    GEN_EXCP_PRIVOPC(ctx);
3576
#else
3577
    if (unlikely(!ctx->supervisor)) {
3578
        if (loglevel != 0)
3579
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3580
        GEN_EXCP_PRIVOPC(ctx);
3581
        return;
3582
    }
3583
    gen_op_slbia();
3584
#endif
3585
}
3586

    
3587
/* slbie */
3588
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3589
{
3590
#if defined(CONFIG_USER_ONLY)
3591
    GEN_EXCP_PRIVOPC(ctx);
3592
#else
3593
    if (unlikely(!ctx->supervisor)) {
3594
        GEN_EXCP_PRIVOPC(ctx);
3595
        return;
3596
    }
3597
    gen_op_load_gpr_T0(rB(ctx->opcode));
3598
    gen_op_slbie();
3599
#endif
3600
}
3601
#endif
3602

    
3603
/***                              External control                         ***/
3604
/* Optional: */
3605
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3606
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3607
#if defined(TARGET_PPC64)
3608
#if defined(CONFIG_USER_ONLY)
3609
static GenOpFunc *gen_op_eciwx[] = {
3610
    &gen_op_eciwx_raw,
3611
    &gen_op_eciwx_le_raw,
3612
    &gen_op_eciwx_64_raw,
3613
    &gen_op_eciwx_le_64_raw,
3614
};
3615
static GenOpFunc *gen_op_ecowx[] = {
3616
    &gen_op_ecowx_raw,
3617
    &gen_op_ecowx_le_raw,
3618
    &gen_op_ecowx_64_raw,
3619
    &gen_op_ecowx_le_64_raw,
3620
};
3621
#else
3622
static GenOpFunc *gen_op_eciwx[] = {
3623
    &gen_op_eciwx_user,
3624
    &gen_op_eciwx_le_user,
3625
    &gen_op_eciwx_kernel,
3626
    &gen_op_eciwx_le_kernel,
3627
    &gen_op_eciwx_64_user,
3628
    &gen_op_eciwx_le_64_user,
3629
    &gen_op_eciwx_64_kernel,
3630
    &gen_op_eciwx_le_64_kernel,
3631
};
3632
static GenOpFunc *gen_op_ecowx[] = {
3633
    &gen_op_ecowx_user,
3634
    &gen_op_ecowx_le_user,
3635
    &gen_op_ecowx_kernel,
3636
    &gen_op_ecowx_le_kernel,
3637
    &gen_op_ecowx_64_user,
3638
    &gen_op_ecowx_le_64_user,
3639
    &gen_op_ecowx_64_kernel,
3640
    &gen_op_ecowx_le_64_kernel,
3641
};
3642
#endif
3643
#else
3644
#if defined(CONFIG_USER_ONLY)
3645
static GenOpFunc *gen_op_eciwx[] = {
3646
    &gen_op_eciwx_raw,
3647
    &gen_op_eciwx_le_raw,
3648
};
3649
static GenOpFunc *gen_op_ecowx[] = {
3650
    &gen_op_ecowx_raw,
3651
    &gen_op_ecowx_le_raw,
3652
};
3653
#else
3654
static GenOpFunc *gen_op_eciwx[] = {
3655
    &gen_op_eciwx_user,
3656
    &gen_op_eciwx_le_user,
3657
    &gen_op_eciwx_kernel,
3658
    &gen_op_eciwx_le_kernel,
3659
};
3660
static GenOpFunc *gen_op_ecowx[] = {
3661
    &gen_op_ecowx_user,
3662
    &gen_op_ecowx_le_user,
3663
    &gen_op_ecowx_kernel,
3664
    &gen_op_ecowx_le_kernel,
3665
};
3666
#endif
3667
#endif
3668

    
3669
/* eciwx */
3670
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3671
{
3672
    /* Should check EAR[E] & alignment ! */
3673
    gen_addr_reg_index(ctx);
3674
    op_eciwx();
3675
    gen_op_store_T0_gpr(rD(ctx->opcode));
3676
}
3677

    
3678
/* ecowx */
3679
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3680
{
3681
    /* Should check EAR[E] & alignment ! */
3682
    gen_addr_reg_index(ctx);
3683
    gen_op_load_gpr_T1(rS(ctx->opcode));
3684
    op_ecowx();
3685
}
3686

    
3687
/* PowerPC 601 specific instructions */
3688
/* abs - abs. */
3689
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3690
{
3691
    gen_op_load_gpr_T0(rA(ctx->opcode));
3692
    gen_op_POWER_abs();
3693
    gen_op_store_T0_gpr(rD(ctx->opcode));
3694
    if (unlikely(Rc(ctx->opcode) != 0))
3695
        gen_set_Rc0(ctx);
3696
}
3697

    
3698
/* abso - abso. */
3699
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3700
{
3701
    gen_op_load_gpr_T0(rA(ctx->opcode));
3702
    gen_op_POWER_abso();
3703
    gen_op_store_T0_gpr(rD(ctx->opcode));
3704
    if (unlikely(Rc(ctx->opcode) != 0))
3705
        gen_set_Rc0(ctx);
3706
}
3707

    
3708
/* clcs */
3709
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3710
{
3711
    gen_op_load_gpr_T0(rA(ctx->opcode));
3712
    gen_op_POWER_clcs();
3713
    gen_op_store_T0_gpr(rD(ctx->opcode));
3714
}
3715

    
3716
/* div - div. */
3717
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3718
{
3719
    gen_op_load_gpr_T0(rA(ctx->opcode));
3720
    gen_op_load_gpr_T1(rB(ctx->opcode));
3721
    gen_op_POWER_div();
3722
    gen_op_store_T0_gpr(rD(ctx->opcode));
3723
    if (unlikely(Rc(ctx->opcode) != 0))
3724
        gen_set_Rc0(ctx);
3725
}
3726

    
3727
/* divo - divo. */
3728
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3729
{
3730
    gen_op_load_gpr_T0(rA(ctx->opcode));
3731
    gen_op_load_gpr_T1(rB(ctx->opcode));
3732
    gen_op_POWER_divo();
3733
    gen_op_store_T0_gpr(rD(ctx->opcode));
3734
    if (unlikely(Rc(ctx->opcode) != 0))
3735
        gen_set_Rc0(ctx);
3736
}
3737

    
3738
/* divs - divs. */
3739
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3740
{
3741
    gen_op_load_gpr_T0(rA(ctx->opcode));
3742
    gen_op_load_gpr_T1(rB(ctx->opcode));
3743
    gen_op_POWER_divs();
3744
    gen_op_store_T0_gpr(rD(ctx->opcode));
3745
    if (unlikely(Rc(ctx->opcode) != 0))
3746
        gen_set_Rc0(ctx);
3747
}
3748

    
3749
/* divso - divso. */
3750
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3751
{
3752
    gen_op_load_gpr_T0(rA(ctx->opcode));
3753
    gen_op_load_gpr_T1(rB(ctx->opcode));
3754
    gen_op_POWER_divso();
3755
    gen_op_store_T0_gpr(rD(ctx->opcode));
3756
    if (unlikely(Rc(ctx->opcode) != 0))
3757
        gen_set_Rc0(ctx);
3758
}
3759

    
3760
/* doz - doz. */
3761
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3762
{
3763
    gen_op_load_gpr_T0(rA(ctx->opcode));
3764
    gen_op_load_gpr_T1(rB(ctx->opcode));
3765
    gen_op_POWER_doz();
3766
    gen_op_store_T0_gpr(rD(ctx->opcode));
3767
    if (unlikely(Rc(ctx->opcode) != 0))
3768
        gen_set_Rc0(ctx);
3769
}
3770

    
3771
/* dozo - dozo. */
3772
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3773
{
3774
    gen_op_load_gpr_T0(rA(ctx->opcode));
3775
    gen_op_load_gpr_T1(rB(ctx->opcode));
3776
    gen_op_POWER_dozo();
3777
    gen_op_store_T0_gpr(rD(ctx->opcode));
3778
    if (unlikely(Rc(ctx->opcode) != 0))
3779
        gen_set_Rc0(ctx);
3780
}
3781

    
3782
/* dozi */
3783
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3784
{
3785
    gen_op_load_gpr_T0(rA(ctx->opcode));
3786
    gen_op_set_T1(SIMM(ctx->opcode));
3787
    gen_op_POWER_doz();
3788
    gen_op_store_T0_gpr(rD(ctx->opcode));
3789
}
3790

    
3791
/* As lscbx load from memory byte after byte, it's always endian safe */
3792
#define op_POWER_lscbx(start, ra, rb) \
3793
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3794
#if defined(CONFIG_USER_ONLY)
3795
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3796
    &gen_op_POWER_lscbx_raw,
3797
    &gen_op_POWER_lscbx_raw,
3798
};
3799
#else
3800
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3801
    &gen_op_POWER_lscbx_user,
3802
    &gen_op_POWER_lscbx_user,
3803
    &gen_op_POWER_lscbx_kernel,
3804
    &gen_op_POWER_lscbx_kernel,
3805
};
3806
#endif
3807

    
3808
/* lscbx - lscbx. */
3809
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3810
{
3811
    int ra = rA(ctx->opcode);
3812
    int rb = rB(ctx->opcode);
3813

    
3814
    gen_addr_reg_index(ctx);
3815
    if (ra == 0) {
3816
        ra = rb;
3817
    }
3818
    /* NIP cannot be restored if the memory exception comes from an helper */
3819
    gen_update_nip(ctx, ctx->nip - 4);
3820
    gen_op_load_xer_bc();
3821
    gen_op_load_xer_cmp();
3822
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3823
    gen_op_store_xer_bc();
3824
    if (unlikely(Rc(ctx->opcode) != 0))
3825
        gen_set_Rc0(ctx);
3826
}
3827

    
3828
/* maskg - maskg. */
3829
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3830
{
3831
    gen_op_load_gpr_T0(rS(ctx->opcode));
3832
    gen_op_load_gpr_T1(rB(ctx->opcode));
3833
    gen_op_POWER_maskg();
3834
    gen_op_store_T0_gpr(rA(ctx->opcode));
3835
    if (unlikely(Rc(ctx->opcode) != 0))
3836
        gen_set_Rc0(ctx);
3837
}
3838

    
3839
/* maskir - maskir. */
3840
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3841
{
3842
    gen_op_load_gpr_T0(rA(ctx->opcode));
3843
    gen_op_load_gpr_T1(rS(ctx->opcode));
3844
    gen_op_load_gpr_T2(rB(ctx->opcode));
3845
    gen_op_POWER_maskir();
3846
    gen_op_store_T0_gpr(rA(ctx->opcode));
3847
    if (unlikely(Rc(ctx->opcode) != 0))
3848
        gen_set_Rc0(ctx);
3849
}
3850

    
3851
/* mul - mul. */
3852
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
3853
{
3854
    gen_op_load_gpr_T0(rA(ctx->opcode));
3855
    gen_op_load_gpr_T1(rB(ctx->opcode));
3856
    gen_op_POWER_mul();
3857
    gen_op_store_T0_gpr(rD(ctx->opcode));
3858
    if (unlikely(Rc(ctx->opcode) != 0))
3859
        gen_set_Rc0(ctx);
3860
}
3861

    
3862
/* mulo - mulo. */
3863
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
3864
{
3865
    gen_op_load_gpr_T0(rA(ctx->opcode));
3866
    gen_op_load_gpr_T1(rB(ctx->opcode));
3867
    gen_op_POWER_mulo();
3868
    gen_op_store_T0_gpr(rD(ctx->opcode));
3869
    if (unlikely(Rc(ctx->opcode) != 0))
3870
        gen_set_Rc0(ctx);
3871
}
3872

    
3873
/* nabs - nabs. */
3874
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
3875
{
3876
    gen_op_load_gpr_T0(rA(ctx->opcode));
3877
    gen_op_POWER_nabs();
3878
    gen_op_store_T0_gpr(rD(ctx->opcode));
3879
    if (unlikely(Rc(ctx->opcode) != 0))
3880
        gen_set_Rc0(ctx);
3881
}
3882

    
3883
/* nabso - nabso. */
3884
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
3885
{
3886
    gen_op_load_gpr_T0(rA(ctx->opcode));
3887
    gen_op_POWER_nabso();
3888
    gen_op_store_T0_gpr(rD(ctx->opcode));
3889
    if (unlikely(Rc(ctx->opcode) != 0))
3890
        gen_set_Rc0(ctx);
3891
}
3892

    
3893
/* rlmi - rlmi. */
3894
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3895
{
3896
    uint32_t mb, me;
3897

    
3898
    mb = MB(ctx->opcode);
3899
    me = ME(ctx->opcode);
3900
    gen_op_load_gpr_T0(rS(ctx->opcode));
3901
    gen_op_load_gpr_T1(rA(ctx->opcode));
3902
    gen_op_load_gpr_T2(rB(ctx->opcode));
3903
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
3904
    gen_op_store_T0_gpr(rA(ctx->opcode));
3905
    if (unlikely(Rc(ctx->opcode) != 0))
3906
        gen_set_Rc0(ctx);
3907
}
3908

    
3909
/* rrib - rrib. */
3910
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
3911
{
3912
    gen_op_load_gpr_T0(rS(ctx->opcode));
3913
    gen_op_load_gpr_T1(rA(ctx->opcode));
3914
    gen_op_load_gpr_T2(rB(ctx->opcode));
3915
    gen_op_POWER_rrib();
3916
    gen_op_store_T0_gpr(rA(ctx->opcode));
3917
    if (unlikely(Rc(ctx->opcode) != 0))
3918
        gen_set_Rc0(ctx);
3919
}
3920

    
3921
/* sle - sle. */
3922
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
3923
{
3924
    gen_op_load_gpr_T0(rS(ctx->opcode));
3925
    gen_op_load_gpr_T1(rB(ctx->opcode));
3926
    gen_op_POWER_sle();
3927
    gen_op_store_T0_gpr(rA(ctx->opcode));
3928
    if (unlikely(Rc(ctx->opcode) != 0))
3929
        gen_set_Rc0(ctx);
3930
}
3931

    
3932
/* sleq - sleq. */
3933
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
3934
{
3935
    gen_op_load_gpr_T0(rS(ctx->opcode));
3936
    gen_op_load_gpr_T1(rB(ctx->opcode));
3937
    gen_op_POWER_sleq();
3938
    gen_op_store_T0_gpr(rA(ctx->opcode));
3939
    if (unlikely(Rc(ctx->opcode) != 0))
3940
        gen_set_Rc0(ctx);
3941
}
3942

    
3943
/* sliq - sliq. */
3944
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
3945
{
3946
    gen_op_load_gpr_T0(rS(ctx->opcode));
3947
    gen_op_set_T1(SH(ctx->opcode));
3948
    gen_op_POWER_sle();
3949
    gen_op_store_T0_gpr(rA(ctx->opcode));
3950
    if (unlikely(Rc(ctx->opcode) != 0))
3951
        gen_set_Rc0(ctx);
3952
}
3953

    
3954
/* slliq - slliq. */
3955
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
3956
{
3957
    gen_op_load_gpr_T0(rS(ctx->opcode));
3958
    gen_op_set_T1(SH(ctx->opcode));
3959
    gen_op_POWER_sleq();
3960
    gen_op_store_T0_gpr(rA(ctx->opcode));
3961
    if (unlikely(Rc(ctx->opcode) != 0))
3962
        gen_set_Rc0(ctx);
3963
}
3964

    
3965
/* sllq - sllq. */
3966
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
3967
{
3968
    gen_op_load_gpr_T0(rS(ctx->opcode));
3969
    gen_op_load_gpr_T1(rB(ctx->opcode));
3970
    gen_op_POWER_sllq();
3971
    gen_op_store_T0_gpr(rA(ctx->opcode));
3972
    if (unlikely(Rc(ctx->opcode) != 0))
3973
        gen_set_Rc0(ctx);
3974
}
3975

    
3976
/* slq - slq. */
3977
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
3978
{
3979
    gen_op_load_gpr_T0(rS(ctx->opcode));
3980
    gen_op_load_gpr_T1(rB(ctx->opcode));
3981
    gen_op_POWER_slq();
3982
    gen_op_store_T0_gpr(rA(ctx->opcode));
3983
    if (unlikely(Rc(ctx->opcode) != 0))
3984
        gen_set_Rc0(ctx);
3985
}
3986

    
3987
/* sraiq - sraiq. */
3988
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
3989
{
3990
    gen_op_load_gpr_T0(rS(ctx->opcode));
3991
    gen_op_set_T1(SH(ctx->opcode));
3992
    gen_op_POWER_sraq();
3993
    gen_op_store_T0_gpr(rA(ctx->opcode));
3994
    if (unlikely(Rc(ctx->opcode) != 0))
3995
        gen_set_Rc0(ctx);
3996
}
3997

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

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

    
4020
/* srea - srea. */
4021
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4022
{
4023
    gen_op_load_gpr_T0(rS(ctx->opcode));
4024
    gen_op_load_gpr_T1(rB(ctx->opcode));
4025
    gen_op_POWER_srea();
4026
    gen_op_store_T0_gpr(rA(ctx->opcode));
4027
    if (unlikely(Rc(ctx->opcode) != 0))
4028
        gen_set_Rc0(ctx);
4029
}
4030

    
4031
/* sreq */
4032
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4033
{
4034
    gen_op_load_gpr_T0(rS(ctx->opcode));
4035
    gen_op_load_gpr_T1(rB(ctx->opcode));
4036
    gen_op_POWER_sreq();
4037
    gen_op_store_T0_gpr(rA(ctx->opcode));
4038
    if (unlikely(Rc(ctx->opcode) != 0))
4039
        gen_set_Rc0(ctx);
4040
}
4041

    
4042
/* sriq */
4043
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4044
{
4045
    gen_op_load_gpr_T0(rS(ctx->opcode));
4046
    gen_op_set_T1(SH(ctx->opcode));
4047
    gen_op_POWER_srq();
4048
    gen_op_store_T0_gpr(rA(ctx->opcode));
4049
    if (unlikely(Rc(ctx->opcode) != 0))
4050
        gen_set_Rc0(ctx);
4051
}
4052

    
4053
/* srliq */
4054
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4055
{
4056
    gen_op_load_gpr_T0(rS(ctx->opcode));
4057
    gen_op_load_gpr_T1(rB(ctx->opcode));
4058
    gen_op_set_T1(SH(ctx->opcode));
4059
    gen_op_POWER_srlq();
4060
    gen_op_store_T0_gpr(rA(ctx->opcode));
4061
    if (unlikely(Rc(ctx->opcode) != 0))
4062
        gen_set_Rc0(ctx);
4063
}
4064

    
4065
/* srlq */
4066
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4067
{
4068
    gen_op_load_gpr_T0(rS(ctx->opcode));
4069
    gen_op_load_gpr_T1(rB(ctx->opcode));
4070
    gen_op_POWER_srlq();
4071
    gen_op_store_T0_gpr(rA(ctx->opcode));
4072
    if (unlikely(Rc(ctx->opcode) != 0))
4073
        gen_set_Rc0(ctx);
4074
}
4075

    
4076
/* srq */
4077
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4078
{
4079
    gen_op_load_gpr_T0(rS(ctx->opcode));
4080
    gen_op_load_gpr_T1(rB(ctx->opcode));
4081
    gen_op_POWER_srq();
4082
    gen_op_store_T0_gpr(rA(ctx->opcode));
4083
    if (unlikely(Rc(ctx->opcode) != 0))
4084
        gen_set_Rc0(ctx);
4085
}
4086

    
4087
/* PowerPC 602 specific instructions */
4088
/* dsa  */
4089
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4090
{
4091
    /* XXX: TODO */
4092
    GEN_EXCP_INVAL(ctx);
4093
}
4094

    
4095
/* esa */
4096
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4097
{
4098
    /* XXX: TODO */
4099
    GEN_EXCP_INVAL(ctx);
4100
}
4101

    
4102
/* mfrom */
4103
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4104
{
4105
#if defined(CONFIG_USER_ONLY)
4106
    GEN_EXCP_PRIVOPC(ctx);
4107
#else
4108
    if (unlikely(!ctx->supervisor)) {
4109
        GEN_EXCP_PRIVOPC(ctx);
4110
        return;
4111
    }
4112
    gen_op_load_gpr_T0(rA(ctx->opcode));
4113
    gen_op_602_mfrom();
4114
    gen_op_store_T0_gpr(rD(ctx->opcode));
4115
#endif
4116
}
4117

    
4118
/* 602 - 603 - G2 TLB management */
4119
/* tlbld */
4120
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4121
{
4122
#if defined(CONFIG_USER_ONLY)
4123
    GEN_EXCP_PRIVOPC(ctx);
4124
#else
4125
    if (unlikely(!ctx->supervisor)) {
4126
        GEN_EXCP_PRIVOPC(ctx);
4127
        return;
4128
    }
4129
    gen_op_load_gpr_T0(rB(ctx->opcode));
4130
    gen_op_6xx_tlbld();
4131
#endif
4132
}
4133

    
4134
/* tlbli */
4135
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4136
{
4137
#if defined(CONFIG_USER_ONLY)
4138
    GEN_EXCP_PRIVOPC(ctx);
4139
#else
4140
    if (unlikely(!ctx->supervisor)) {
4141
        GEN_EXCP_PRIVOPC(ctx);
4142
        return;
4143
    }
4144
    gen_op_load_gpr_T0(rB(ctx->opcode));
4145
    gen_op_6xx_tlbli();
4146
#endif
4147
}
4148

    
4149
/* POWER instructions not in PowerPC 601 */
4150
/* clf */
4151
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4152
{
4153
    /* Cache line flush: implemented as no-op */
4154
}
4155

    
4156
/* cli */
4157
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4158
{
4159
    /* Cache line invalidate: privileged and treated as no-op */
4160
#if defined(CONFIG_USER_ONLY)
4161
    GEN_EXCP_PRIVOPC(ctx);
4162
#else
4163
    if (unlikely(!ctx->supervisor)) {
4164
        GEN_EXCP_PRIVOPC(ctx);
4165
        return;
4166
    }
4167
#endif
4168
}
4169

    
4170
/* dclst */
4171
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4172
{
4173
    /* Data cache line store: treated as no-op */
4174
}
4175

    
4176
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4177
{
4178
#if defined(CONFIG_USER_ONLY)
4179
    GEN_EXCP_PRIVOPC(ctx);
4180
#else
4181
    if (unlikely(!ctx->supervisor)) {
4182
        GEN_EXCP_PRIVOPC(ctx);
4183
        return;
4184
    }
4185
    int ra = rA(ctx->opcode);
4186
    int rd = rD(ctx->opcode);
4187

    
4188
    gen_addr_reg_index(ctx);
4189
    gen_op_POWER_mfsri();
4190
    gen_op_store_T0_gpr(rd);
4191
    if (ra != 0 && ra != rd)
4192
        gen_op_store_T1_gpr(ra);
4193
#endif
4194
}
4195

    
4196
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4197
{
4198
#if defined(CONFIG_USER_ONLY)
4199
    GEN_EXCP_PRIVOPC(ctx);
4200
#else
4201
    if (unlikely(!ctx->supervisor)) {
4202
        GEN_EXCP_PRIVOPC(ctx);
4203
        return;
4204
    }
4205
    gen_addr_reg_index(ctx);
4206
    gen_op_POWER_rac();
4207
    gen_op_store_T0_gpr(rD(ctx->opcode));
4208
#endif
4209
}
4210

    
4211
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4212
{
4213
#if defined(CONFIG_USER_ONLY)
4214
    GEN_EXCP_PRIVOPC(ctx);
4215
#else
4216
    if (unlikely(!ctx->supervisor)) {
4217
        GEN_EXCP_PRIVOPC(ctx);
4218
        return;
4219
    }
4220
    gen_op_POWER_rfsvc();
4221
    GEN_SYNC(ctx);
4222
#endif
4223
}
4224

    
4225
/* svc is not implemented for now */
4226

    
4227
/* POWER2 specific instructions */
4228
/* Quad manipulation (load/store two floats at a time) */
4229
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4230
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4231
#if defined(CONFIG_USER_ONLY)
4232
static GenOpFunc *gen_op_POWER2_lfq[] = {
4233
    &gen_op_POWER2_lfq_le_raw,
4234
    &gen_op_POWER2_lfq_raw,
4235
};
4236
static GenOpFunc *gen_op_POWER2_stfq[] = {
4237
    &gen_op_POWER2_stfq_le_raw,
4238
    &gen_op_POWER2_stfq_raw,
4239
};
4240
#else
4241
static GenOpFunc *gen_op_POWER2_lfq[] = {
4242
    &gen_op_POWER2_lfq_le_user,
4243
    &gen_op_POWER2_lfq_user,
4244
    &gen_op_POWER2_lfq_le_kernel,
4245
    &gen_op_POWER2_lfq_kernel,
4246
};
4247
static GenOpFunc *gen_op_POWER2_stfq[] = {
4248
    &gen_op_POWER2_stfq_le_user,
4249
    &gen_op_POWER2_stfq_user,
4250
    &gen_op_POWER2_stfq_le_kernel,
4251
    &gen_op_POWER2_stfq_kernel,
4252
};
4253
#endif
4254

    
4255
/* lfq */
4256
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4257
{
4258
    /* NIP cannot be restored if the memory exception comes from an helper */
4259
    gen_update_nip(ctx, ctx->nip - 4);
4260
    gen_addr_imm_index(ctx, 0);
4261
    op_POWER2_lfq();
4262
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4263
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4264
}
4265

    
4266
/* lfqu */
4267
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4268
{
4269
    int ra = rA(ctx->opcode);
4270

    
4271
    /* NIP cannot be restored if the memory exception comes from an helper */
4272
    gen_update_nip(ctx, ctx->nip - 4);
4273
    gen_addr_imm_index(ctx, 0);
4274
    op_POWER2_lfq();
4275
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4276
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4277
    if (ra != 0)
4278
        gen_op_store_T0_gpr(ra);
4279
}
4280

    
4281
/* lfqux */
4282
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4283
{
4284
    int ra = rA(ctx->opcode);
4285

    
4286
    /* NIP cannot be restored if the memory exception comes from an helper */
4287
    gen_update_nip(ctx, ctx->nip - 4);
4288
    gen_addr_reg_index(ctx);
4289
    op_POWER2_lfq();
4290
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4291
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4292
    if (ra != 0)
4293
        gen_op_store_T0_gpr(ra);
4294
}
4295

    
4296
/* lfqx */
4297
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4298
{
4299
    /* NIP cannot be restored if the memory exception comes from an helper */
4300
    gen_update_nip(ctx, ctx->nip - 4);
4301
    gen_addr_reg_index(ctx);
4302
    op_POWER2_lfq();
4303
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4304
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4305
}
4306

    
4307
/* stfq */
4308
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4309
{
4310
    /* NIP cannot be restored if the memory exception comes from an helper */
4311
    gen_update_nip(ctx, ctx->nip - 4);
4312
    gen_addr_imm_index(ctx, 0);
4313
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4314
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4315
    op_POWER2_stfq();
4316
}
4317

    
4318
/* stfqu */
4319
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4320
{
4321
    int ra = rA(ctx->opcode);
4322

    
4323
    /* NIP cannot be restored if the memory exception comes from an helper */
4324
    gen_update_nip(ctx, ctx->nip - 4);
4325
    gen_addr_imm_index(ctx, 0);
4326
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4327
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4328
    op_POWER2_stfq();
4329
    if (ra != 0)
4330
        gen_op_store_T0_gpr(ra);
4331
}
4332

    
4333
/* stfqux */
4334
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4335
{
4336
    int ra = rA(ctx->opcode);
4337

    
4338
    /* NIP cannot be restored if the memory exception comes from an helper */
4339
    gen_update_nip(ctx, ctx->nip - 4);
4340
    gen_addr_reg_index(ctx);
4341
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4342
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4343
    op_POWER2_stfq();
4344
    if (ra != 0)
4345
        gen_op_store_T0_gpr(ra);
4346
}
4347

    
4348
/* stfqx */
4349
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4350
{
4351
    /* NIP cannot be restored if the memory exception comes from an helper */
4352
    gen_update_nip(ctx, ctx->nip - 4);
4353
    gen_addr_reg_index(ctx);
4354
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4355
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4356
    op_POWER2_stfq();
4357
}
4358

    
4359
/* BookE specific instructions */
4360
/* XXX: not implemented on 440 ? */
4361
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT)
4362
{
4363
    /* XXX: TODO */
4364
    GEN_EXCP_INVAL(ctx);
4365
}
4366

    
4367
/* XXX: not implemented on 440 ? */
4368
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
4369
{
4370
#if defined(CONFIG_USER_ONLY)
4371
    GEN_EXCP_PRIVOPC(ctx);
4372
#else
4373
    if (unlikely(!ctx->supervisor)) {
4374
        GEN_EXCP_PRIVOPC(ctx);
4375
        return;
4376
    }
4377
    gen_addr_reg_index(ctx);
4378
    /* Use the same micro-ops as for tlbie */
4379
#if defined(TARGET_PPC64)
4380
    if (ctx->sf_mode)
4381
        gen_op_tlbie_64();
4382
    else
4383
#endif
4384
        gen_op_tlbie();
4385
#endif
4386
}
4387

    
4388
/* All 405 MAC instructions are translated here */
4389
static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
4390
                                         int ra, int rb, int rt, int Rc)
4391
{
4392
    gen_op_load_gpr_T0(ra);
4393
    gen_op_load_gpr_T1(rb);
4394
    switch (opc3 & 0x0D) {
4395
    case 0x05:
4396
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4397
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4398
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4399
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4400
        /* mulchw - mulchw. */
4401
        gen_op_405_mulchw();
4402
        break;
4403
    case 0x04:
4404
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4405
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4406
        /* mulchwu - mulchwu. */
4407
        gen_op_405_mulchwu();
4408
        break;
4409
    case 0x01:
4410
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4411
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4412
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4413
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4414
        /* mulhhw - mulhhw. */
4415
        gen_op_405_mulhhw();
4416
        break;
4417
    case 0x00:
4418
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4419
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4420
        /* mulhhwu - mulhhwu. */
4421
        gen_op_405_mulhhwu();
4422
        break;
4423
    case 0x0D:
4424
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4425
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4426
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4427
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4428
        /* mullhw - mullhw. */
4429
        gen_op_405_mullhw();
4430
        break;
4431
    case 0x0C:
4432
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4433
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4434
        /* mullhwu - mullhwu. */
4435
        gen_op_405_mullhwu();
4436
        break;
4437
    }
4438
    if (opc2 & 0x02) {
4439
        /* nmultiply-and-accumulate (0x0E) */
4440
        gen_op_neg();
4441
    }
4442
    if (opc2 & 0x04) {
4443
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4444
        gen_op_load_gpr_T2(rt);
4445
        gen_op_move_T1_T0();
4446
        gen_op_405_add_T0_T2();
4447
    }
4448
    if (opc3 & 0x10) {
4449
        /* Check overflow */
4450
        if (opc3 & 0x01)
4451
            gen_op_405_check_ov();
4452
        else
4453
            gen_op_405_check_ovu();
4454
    }
4455
    if (opc3 & 0x02) {
4456
        /* Saturate */
4457
        if (opc3 & 0x01)
4458
            gen_op_405_check_sat();
4459
        else
4460
            gen_op_405_check_satu();
4461
    }
4462
    gen_op_store_T0_gpr(rt);
4463
    if (unlikely(Rc) != 0) {
4464
        /* Update Rc0 */
4465
        gen_set_Rc0(ctx);
4466
    }
4467
}
4468

    
4469
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4470
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4471
{                                                                             \
4472
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4473
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4474
}
4475

    
4476
/* macchw    - macchw.    */
4477
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4478
/* macchwo   - macchwo.   */
4479
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4480
/* macchws   - macchws.   */
4481
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4482
/* macchwso  - macchwso.  */
4483
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4484
/* macchwsu  - macchwsu.  */
4485
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4486
/* macchwsuo - macchwsuo. */
4487
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4488
/* macchwu   - macchwu.   */
4489
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4490
/* macchwuo  - macchwuo.  */
4491
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4492
/* machhw    - machhw.    */
4493
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4494
/* machhwo   - machhwo.   */
4495
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4496
/* machhws   - machhws.   */
4497
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4498
/* machhwso  - machhwso.  */
4499
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4500
/* machhwsu  - machhwsu.  */
4501
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4502
/* machhwsuo - machhwsuo. */
4503
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4504
/* machhwu   - machhwu.   */
4505
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4506
/* machhwuo  - machhwuo.  */
4507
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4508
/* maclhw    - maclhw.    */
4509
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4510
/* maclhwo   - maclhwo.   */
4511
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4512
/* maclhws   - maclhws.   */
4513
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4514
/* maclhwso  - maclhwso.  */
4515
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4516
/* maclhwu   - maclhwu.   */
4517
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4518
/* maclhwuo  - maclhwuo.  */
4519
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4520
/* maclhwsu  - maclhwsu.  */
4521
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4522
/* maclhwsuo - maclhwsuo. */
4523
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4524
/* nmacchw   - nmacchw.   */
4525
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4526
/* nmacchwo  - nmacchwo.  */
4527
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4528
/* nmacchws  - nmacchws.  */
4529
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4530
/* nmacchwso - nmacchwso. */
4531
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4532
/* nmachhw   - nmachhw.   */
4533
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4534
/* nmachhwo  - nmachhwo.  */
4535
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4536
/* nmachhws  - nmachhws.  */
4537
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4538
/* nmachhwso - nmachhwso. */
4539
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4540
/* nmaclhw   - nmaclhw.   */
4541
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4542
/* nmaclhwo  - nmaclhwo.  */
4543
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4544
/* nmaclhws  - nmaclhws.  */
4545
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4546
/* nmaclhwso - nmaclhwso. */
4547
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4548

    
4549
/* mulchw  - mulchw.  */
4550
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4551
/* mulchwu - mulchwu. */
4552
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4553
/* mulhhw  - mulhhw.  */
4554
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4555
/* mulhhwu - mulhhwu. */
4556
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4557
/* mullhw  - mullhw.  */
4558
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4559
/* mullhwu - mullhwu. */
4560
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4561

    
4562
/* mfdcr */
4563
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4564
{
4565
#if defined(CONFIG_USER_ONLY)
4566
    GEN_EXCP_PRIVREG(ctx);
4567
#else
4568
    uint32_t dcrn = SPR(ctx->opcode);
4569

    
4570
    if (unlikely(!ctx->supervisor)) {
4571
        GEN_EXCP_PRIVREG(ctx);
4572
        return;
4573
    }
4574
    gen_op_set_T0(dcrn);
4575
    gen_op_load_dcr();
4576
    gen_op_store_T0_gpr(rD(ctx->opcode));
4577
#endif
4578
}
4579

    
4580
/* mtdcr */
4581
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4582
{
4583
#if defined(CONFIG_USER_ONLY)
4584
    GEN_EXCP_PRIVREG(ctx);
4585
#else
4586
    uint32_t dcrn = SPR(ctx->opcode);
4587

    
4588
    if (unlikely(!ctx->supervisor)) {
4589
        GEN_EXCP_PRIVREG(ctx);
4590
        return;
4591
    }
4592
    gen_op_set_T0(dcrn);
4593
    gen_op_load_gpr_T1(rS(ctx->opcode));
4594
    gen_op_store_dcr();
4595
#endif
4596
}
4597

    
4598
/* mfdcrx */
4599
/* XXX: not implemented on 440 ? */
4600
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT)
4601
{
4602
#if defined(CONFIG_USER_ONLY)
4603
    GEN_EXCP_PRIVREG(ctx);
4604
#else
4605
    if (unlikely(!ctx->supervisor)) {
4606
        GEN_EXCP_PRIVREG(ctx);
4607
        return;
4608
    }
4609
    gen_op_load_gpr_T0(rA(ctx->opcode));
4610
    gen_op_load_dcr();
4611
    gen_op_store_T0_gpr(rD(ctx->opcode));
4612
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4613
#endif
4614
}
4615

    
4616
/* mtdcrx */
4617
/* XXX: not implemented on 440 ? */
4618
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT)
4619
{
4620
#if defined(CONFIG_USER_ONLY)
4621
    GEN_EXCP_PRIVREG(ctx);
4622
#else
4623
    if (unlikely(!ctx->supervisor)) {
4624
        GEN_EXCP_PRIVREG(ctx);
4625
        return;
4626
    }
4627
    gen_op_load_gpr_T0(rA(ctx->opcode));
4628
    gen_op_load_gpr_T1(rS(ctx->opcode));
4629
    gen_op_store_dcr();
4630
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4631
#endif
4632
}
4633

    
4634
/* mfdcrux (PPC 460) : user-mode access to DCR */
4635
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4636
{
4637
    gen_op_load_gpr_T0(rA(ctx->opcode));
4638
    gen_op_load_dcr();
4639
    gen_op_store_T0_gpr(rD(ctx->opcode));
4640
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4641
}
4642

    
4643
/* mtdcrux (PPC 460) : user-mode access to DCR */
4644
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4645
{
4646
    gen_op_load_gpr_T0(rA(ctx->opcode));
4647
    gen_op_load_gpr_T1(rS(ctx->opcode));
4648
    gen_op_store_dcr();
4649
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4650
}
4651

    
4652
/* dccci */
4653
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4654
{
4655
#if defined(CONFIG_USER_ONLY)
4656
    GEN_EXCP_PRIVOPC(ctx);
4657
#else
4658
    if (unlikely(!ctx->supervisor)) {
4659
        GEN_EXCP_PRIVOPC(ctx);
4660
        return;
4661
    }
4662
    /* interpreted as no-op */
4663
#endif
4664
}
4665

    
4666
/* dcread */
4667
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4668
{
4669
#if defined(CONFIG_USER_ONLY)
4670
    GEN_EXCP_PRIVOPC(ctx);
4671
#else
4672
    if (unlikely(!ctx->supervisor)) {
4673
        GEN_EXCP_PRIVOPC(ctx);
4674
        return;
4675
    }
4676
    gen_addr_reg_index(ctx);
4677
    op_ldst(lwz);
4678
    gen_op_store_T0_gpr(rD(ctx->opcode));
4679
#endif
4680
}
4681

    
4682
/* icbt */
4683
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4684
{
4685
    /* interpreted as no-op */
4686
    /* XXX: specification say this is treated as a load by the MMU
4687
     *      but does not generate any exception
4688
     */
4689
}
4690

    
4691
/* iccci */
4692
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4693
{
4694
#if defined(CONFIG_USER_ONLY)
4695
    GEN_EXCP_PRIVOPC(ctx);
4696
#else
4697
    if (unlikely(!ctx->supervisor)) {
4698
        GEN_EXCP_PRIVOPC(ctx);
4699
        return;
4700
    }
4701
    /* interpreted as no-op */
4702
#endif
4703
}
4704

    
4705
/* icread */
4706
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4707
{
4708
#if defined(CONFIG_USER_ONLY)
4709
    GEN_EXCP_PRIVOPC(ctx);
4710
#else
4711
    if (unlikely(!ctx->supervisor)) {
4712
        GEN_EXCP_PRIVOPC(ctx);
4713
        return;
4714
    }
4715
    /* interpreted as no-op */
4716
#endif
4717
}
4718

    
4719
/* rfci (supervisor only) */
4720
GEN_HANDLER(rfci_40x, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4721
{
4722
#if defined(CONFIG_USER_ONLY)
4723
    GEN_EXCP_PRIVOPC(ctx);
4724
#else
4725
    if (unlikely(!ctx->supervisor)) {
4726
        GEN_EXCP_PRIVOPC(ctx);
4727
        return;
4728
    }
4729
    /* Restore CPU state */
4730
    gen_op_40x_rfci();
4731
    GEN_SYNC(ctx);
4732
#endif
4733
}
4734

    
4735
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4736
{
4737
#if defined(CONFIG_USER_ONLY)
4738
    GEN_EXCP_PRIVOPC(ctx);
4739
#else
4740
    if (unlikely(!ctx->supervisor)) {
4741
        GEN_EXCP_PRIVOPC(ctx);
4742
        return;
4743
    }
4744
    /* Restore CPU state */
4745
    gen_op_rfci();
4746
    GEN_SYNC(ctx);
4747
#endif
4748
}
4749

    
4750
/* BookE specific */
4751
/* XXX: not implemented on 440 ? */
4752
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
4753
{
4754
#if defined(CONFIG_USER_ONLY)
4755
    GEN_EXCP_PRIVOPC(ctx);
4756
#else
4757
    if (unlikely(!ctx->supervisor)) {
4758
        GEN_EXCP_PRIVOPC(ctx);
4759
        return;
4760
    }
4761
    /* Restore CPU state */
4762
    gen_op_rfdi();
4763
    GEN_SYNC(ctx);
4764
#endif
4765
}
4766

    
4767
/* XXX: not implemented on 440 ? */
4768
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
4769
{
4770
#if defined(CONFIG_USER_ONLY)
4771
    GEN_EXCP_PRIVOPC(ctx);
4772
#else
4773
    if (unlikely(!ctx->supervisor)) {
4774
        GEN_EXCP_PRIVOPC(ctx);
4775
        return;
4776
    }
4777
    /* Restore CPU state */
4778
    gen_op_rfmci();
4779
    GEN_SYNC(ctx);
4780
#endif
4781
}
4782

    
4783
/* TLB management - PowerPC 405 implementation */
4784
/* tlbre */
4785
GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4786
{
4787
#if defined(CONFIG_USER_ONLY)
4788
    GEN_EXCP_PRIVOPC(ctx);
4789
#else
4790
    if (unlikely(!ctx->supervisor)) {
4791
        GEN_EXCP_PRIVOPC(ctx);
4792
        return;
4793
    }
4794
    switch (rB(ctx->opcode)) {
4795
    case 0:
4796
        gen_op_load_gpr_T0(rA(ctx->opcode));
4797
        gen_op_4xx_tlbre_hi();
4798
        gen_op_store_T0_gpr(rD(ctx->opcode));
4799
        break;
4800
    case 1:
4801
        gen_op_load_gpr_T0(rA(ctx->opcode));
4802
        gen_op_4xx_tlbre_lo();
4803
        gen_op_store_T0_gpr(rD(ctx->opcode));
4804
        break;
4805
    default:
4806
        GEN_EXCP_INVAL(ctx);
4807
        break;
4808
    }
4809
#endif
4810
}
4811

    
4812
/* tlbsx - tlbsx. */
4813
GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
4814
{
4815
#if defined(CONFIG_USER_ONLY)
4816
    GEN_EXCP_PRIVOPC(ctx);
4817
#else
4818
    if (unlikely(!ctx->supervisor)) {
4819
        GEN_EXCP_PRIVOPC(ctx);
4820
        return;
4821
    }
4822
    gen_addr_reg_index(ctx);
4823
    if (Rc(ctx->opcode))
4824
        gen_op_4xx_tlbsx_();
4825
    else
4826
        gen_op_4xx_tlbsx();
4827
    gen_op_store_T0_gpr(rD(ctx->opcode));
4828
#endif
4829
}
4830

    
4831
/* tlbwe */
4832
GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
4833
{
4834
#if defined(CONFIG_USER_ONLY)
4835
    GEN_EXCP_PRIVOPC(ctx);
4836
#else
4837
    if (unlikely(!ctx->supervisor)) {
4838
        GEN_EXCP_PRIVOPC(ctx);
4839
        return;
4840
    }
4841
    switch (rB(ctx->opcode)) {
4842
    case 0:
4843
        gen_op_load_gpr_T0(rA(ctx->opcode));
4844
        gen_op_load_gpr_T1(rS(ctx->opcode));
4845
        gen_op_4xx_tlbwe_hi();
4846
        break;
4847
    case 1:
4848
        gen_op_load_gpr_T0(rA(ctx->opcode));
4849
        gen_op_load_gpr_T1(rS(ctx->opcode));
4850
        gen_op_4xx_tlbwe_lo();
4851
        break;
4852
    default:
4853
        GEN_EXCP_INVAL(ctx);
4854
        break;
4855
    }
4856
#endif
4857
}
4858

    
4859
/* TLB management - PowerPC 440 implementation */
4860
/* tlbre */
4861
GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4862
{
4863
#if defined(CONFIG_USER_ONLY)
4864
    GEN_EXCP_PRIVOPC(ctx);
4865
#else
4866
    if (unlikely(!ctx->supervisor)) {
4867
        GEN_EXCP_PRIVOPC(ctx);
4868
        return;
4869
    }
4870
    switch (rB(ctx->opcode)) {
4871
    case 0:
4872
    case 1:
4873
    case 2:
4874
        gen_op_load_gpr_T0(rA(ctx->opcode));
4875
        gen_op_440_tlbre(rB(ctx->opcode));
4876
        gen_op_store_T0_gpr(rD(ctx->opcode));
4877
        break;
4878
    default:
4879
        GEN_EXCP_INVAL(ctx);
4880
        break;
4881
    }
4882
#endif
4883
}
4884

    
4885
/* tlbsx - tlbsx. */
4886
GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
4887
{
4888
#if defined(CONFIG_USER_ONLY)
4889
    GEN_EXCP_PRIVOPC(ctx);
4890
#else
4891
    if (unlikely(!ctx->supervisor)) {
4892
        GEN_EXCP_PRIVOPC(ctx);
4893
        return;
4894
    }
4895
    gen_addr_reg_index(ctx);
4896
    if (Rc(ctx->opcode))
4897
        gen_op_440_tlbsx_();
4898
    else
4899
        gen_op_440_tlbsx();
4900
    gen_op_store_T0_gpr(rD(ctx->opcode));
4901
#endif
4902
}
4903

    
4904
/* tlbwe */
4905
GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
4906
{
4907
#if defined(CONFIG_USER_ONLY)
4908
    GEN_EXCP_PRIVOPC(ctx);
4909
#else
4910
    if (unlikely(!ctx->supervisor)) {
4911
        GEN_EXCP_PRIVOPC(ctx);
4912
        return;
4913
    }
4914
    switch (rB(ctx->opcode)) {
4915
    case 0:
4916
    case 1:
4917
    case 2:
4918
        gen_op_load_gpr_T0(rA(ctx->opcode));
4919
        gen_op_load_gpr_T1(rS(ctx->opcode));
4920
        gen_op_440_tlbwe(rB(ctx->opcode));
4921
        break;
4922
    default:
4923
        GEN_EXCP_INVAL(ctx);
4924
        break;
4925
    }
4926
#endif
4927
}
4928

    
4929
/* wrtee */
4930
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4931
{
4932
#if defined(CONFIG_USER_ONLY)
4933
    GEN_EXCP_PRIVOPC(ctx);
4934
#else
4935
    if (unlikely(!ctx->supervisor)) {
4936
        GEN_EXCP_PRIVOPC(ctx);
4937
        return;
4938
    }
4939
    gen_op_load_gpr_T0(rD(ctx->opcode));
4940
    gen_op_wrte();
4941
    /* Stop translation to have a chance to raise an exception
4942
     * if we just set msr_ee to 1
4943
     */
4944
    GEN_STOP(ctx);
4945
#endif
4946
}
4947

    
4948
/* wrteei */
4949
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4950
{
4951
#if defined(CONFIG_USER_ONLY)
4952
    GEN_EXCP_PRIVOPC(ctx);
4953
#else
4954
    if (unlikely(!ctx->supervisor)) {
4955
        GEN_EXCP_PRIVOPC(ctx);
4956
        return;
4957
    }
4958
    gen_op_set_T0(ctx->opcode & 0x00010000);
4959
    gen_op_wrte();
4960
    /* Stop translation to have a chance to raise an exception
4961
     * if we just set msr_ee to 1
4962
     */
4963
    GEN_STOP(ctx);
4964
#endif
4965
}
4966

    
4967
/* PowerPC 440 specific instructions */
4968
/* dlmzb */
4969
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
4970
{
4971
    gen_op_load_gpr_T0(rS(ctx->opcode));
4972
    gen_op_load_gpr_T1(rB(ctx->opcode));
4973
    gen_op_440_dlmzb();
4974
    gen_op_store_T0_gpr(rA(ctx->opcode));
4975
    gen_op_store_xer_bc();
4976
    if (Rc(ctx->opcode)) {
4977
        gen_op_440_dlmzb_update_Rc();
4978
        gen_op_store_T0_crf(0);
4979
    }
4980
}
4981

    
4982
/* mbar replaces eieio on 440 */
4983
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
4984
{
4985
    /* interpreted as no-op */
4986
}
4987

    
4988
/* msync replaces sync on 440 */
4989
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
4990
{
4991
    /* interpreted as no-op */
4992
}
4993

    
4994
/* icbt */
4995
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
4996
{
4997
    /* interpreted as no-op */
4998
    /* XXX: specification say this is treated as a load by the MMU
4999
     *      but does not generate any exception
5000
     */
5001
}
5002

    
5003
#if defined(TARGET_PPCEMB)
5004
/***                           SPE extension                               ***/
5005

    
5006
/* Register moves */
5007
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
5008
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
5009
#if 0 // unused
5010
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
5011
#endif
5012

    
5013
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
5014
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
5015
#if 0 // unused
5016
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
5017
#endif
5018

    
5019
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5020
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5021
{                                                                             \
5022
    if (Rc(ctx->opcode))                                                      \
5023
        gen_##name1(ctx);                                                     \
5024
    else                                                                      \
5025
        gen_##name0(ctx);                                                     \
5026
}
5027

    
5028
/* Handler for undefined SPE opcodes */
5029
static inline void gen_speundef (DisasContext *ctx)
5030
{
5031
    GEN_EXCP_INVAL(ctx);
5032
}
5033

    
5034
/* SPE load and stores */
5035
static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5036
{
5037
    target_long simm = rB(ctx->opcode);
5038

    
5039
    if (rA(ctx->opcode) == 0) {
5040
        gen_set_T0(simm << sh);
5041
    } else {
5042
        gen_op_load_gpr_T0(rA(ctx->opcode));
5043
        if (likely(simm != 0))
5044
            gen_op_addi(simm << sh);
5045
    }
5046
}
5047

    
5048
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5049
#if defined(CONFIG_USER_ONLY)
5050
#if defined(TARGET_PPC64)
5051
#define OP_SPE_LD_TABLE(name)                                                 \
5052
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5053
    &gen_op_spe_l##name##_raw,                                                \
5054
    &gen_op_spe_l##name##_le_raw,                                             \
5055
    &gen_op_spe_l##name##_64_raw,                                             \
5056
    &gen_op_spe_l##name##_le_64_raw,                                          \
5057
};
5058
#define OP_SPE_ST_TABLE(name)                                                 \
5059
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5060
    &gen_op_spe_st##name##_raw,                                               \
5061
    &gen_op_spe_st##name##_le_raw,                                            \
5062
    &gen_op_spe_st##name##_64_raw,                                            \
5063
    &gen_op_spe_st##name##_le_64_raw,                                         \
5064
};
5065
#else /* defined(TARGET_PPC64) */
5066
#define OP_SPE_LD_TABLE(name)                                                 \
5067
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5068
    &gen_op_spe_l##name##_raw,                                                \
5069
    &gen_op_spe_l##name##_le_raw,                                             \
5070
};
5071
#define OP_SPE_ST_TABLE(name)                                                 \
5072
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5073
    &gen_op_spe_st##name##_raw,                                               \
5074
    &gen_op_spe_st##name##_le_raw,                                            \
5075
};
5076
#endif /* defined(TARGET_PPC64) */
5077
#else /* defined(CONFIG_USER_ONLY) */
5078
#if defined(TARGET_PPC64)
5079
#define OP_SPE_LD_TABLE(name)                                                 \
5080
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5081
    &gen_op_spe_l##name##_user,                                               \
5082
    &gen_op_spe_l##name##_le_user,                                            \
5083
    &gen_op_spe_l##name##_kernel,                                             \
5084
    &gen_op_spe_l##name##_le_kernel,                                          \
5085
    &gen_op_spe_l##name##_64_user,                                            \
5086
    &gen_op_spe_l##name##_le_64_user,                                         \
5087
    &gen_op_spe_l##name##_64_kernel,                                          \
5088
    &gen_op_spe_l##name##_le_64_kernel,                                       \
5089
};
5090
#define OP_SPE_ST_TABLE(name)                                                 \
5091
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5092
    &gen_op_spe_st##name##_user,                                              \
5093
    &gen_op_spe_st##name##_le_user,                                           \
5094
    &gen_op_spe_st##name##_kernel,                                            \
5095
    &gen_op_spe_st##name##_le_kernel,                                         \
5096
    &gen_op_spe_st##name##_64_user,                                           \
5097
    &gen_op_spe_st##name##_le_64_user,                                        \
5098
    &gen_op_spe_st##name##_64_kernel,                                         \
5099
    &gen_op_spe_st##name##_le_64_kernel,                                      \
5100
};
5101
#else /* defined(TARGET_PPC64) */
5102
#define OP_SPE_LD_TABLE(name)                                                 \
5103
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5104
    &gen_op_spe_l##name##_user,                                               \
5105
    &gen_op_spe_l##name##_le_user,                                            \
5106
    &gen_op_spe_l##name##_kernel,                                             \
5107
    &gen_op_spe_l##name##_le_kernel,                                          \
5108
};
5109
#define OP_SPE_ST_TABLE(name)                                                 \
5110
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5111
    &gen_op_spe_st##name##_user,                                              \
5112
    &gen_op_spe_st##name##_le_user,                                           \
5113
    &gen_op_spe_st##name##_kernel,                                            \
5114
    &gen_op_spe_st##name##_le_kernel,                                         \
5115
};
5116
#endif /* defined(TARGET_PPC64) */
5117
#endif /* defined(CONFIG_USER_ONLY) */
5118

    
5119
#define GEN_SPE_LD(name, sh)                                                  \
5120
static inline void gen_evl##name (DisasContext *ctx)                          \
5121
{                                                                             \
5122
    if (unlikely(!ctx->spe_enabled)) {                                        \
5123
        GEN_EXCP_NO_AP(ctx);                                                  \
5124
        return;                                                               \
5125
    }                                                                         \
5126
    gen_addr_spe_imm_index(ctx, sh);                                          \
5127
    op_spe_ldst(spe_l##name);                                                 \
5128
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5129
}
5130

    
5131
#define GEN_SPE_LDX(name)                                                     \
5132
static inline void gen_evl##name##x (DisasContext *ctx)                       \
5133
{                                                                             \
5134
    if (unlikely(!ctx->spe_enabled)) {                                        \
5135
        GEN_EXCP_NO_AP(ctx);                                                  \
5136
        return;                                                               \
5137
    }                                                                         \
5138
    gen_addr_reg_index(ctx);                                                  \
5139
    op_spe_ldst(spe_l##name);                                                 \
5140
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5141
}
5142

    
5143
#define GEN_SPEOP_LD(name, sh)                                                \
5144
OP_SPE_LD_TABLE(name);                                                        \
5145
GEN_SPE_LD(name, sh);                                                         \
5146
GEN_SPE_LDX(name)
5147

    
5148
#define GEN_SPE_ST(name, sh)                                                  \
5149
static inline void gen_evst##name (DisasContext *ctx)                         \
5150
{                                                                             \
5151
    if (unlikely(!ctx->spe_enabled)) {                                        \
5152
        GEN_EXCP_NO_AP(ctx);                                                  \
5153
        return;                                                               \
5154
    }                                                                         \
5155
    gen_addr_spe_imm_index(ctx, sh);                                          \
5156
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5157
    op_spe_ldst(spe_st##name);                                                \
5158
}
5159

    
5160
#define GEN_SPE_STX(name)                                                     \
5161
static inline void gen_evst##name##x (DisasContext *ctx)                      \
5162
{                                                                             \
5163
    if (unlikely(!ctx->spe_enabled)) {                                        \
5164
        GEN_EXCP_NO_AP(ctx);                                                  \
5165
        return;                                                               \
5166
    }                                                                         \
5167
    gen_addr_reg_index(ctx);                                                  \
5168
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5169
    op_spe_ldst(spe_st##name);                                                \
5170
}
5171

    
5172
#define GEN_SPEOP_ST(name, sh)                                                \
5173
OP_SPE_ST_TABLE(name);                                                        \
5174
GEN_SPE_ST(name, sh);                                                         \
5175
GEN_SPE_STX(name)
5176

    
5177
#define GEN_SPEOP_LDST(name, sh)                                              \
5178
GEN_SPEOP_LD(name, sh);                                                       \
5179
GEN_SPEOP_ST(name, sh)
5180

    
5181
/* SPE arithmetic and logic */
5182
#define GEN_SPEOP_ARITH2(name)                                                \
5183
static inline void gen_##name (DisasContext *ctx)                             \
5184
{                                                                             \
5185
    if (unlikely(!ctx->spe_enabled)) {                                        \
5186
        GEN_EXCP_NO_AP(ctx);                                                  \
5187
        return;                                                               \
5188
    }                                                                         \
5189
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5190
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5191
    gen_op_##name();                                                          \
5192
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5193
}
5194

    
5195
#define GEN_SPEOP_ARITH1(name)                                                \
5196
static inline void gen_##name (DisasContext *ctx)                             \
5197
{                                                                             \
5198
    if (unlikely(!ctx->spe_enabled)) {                                        \
5199
        GEN_EXCP_NO_AP(ctx);                                                  \
5200
        return;                                                               \
5201
    }                                                                         \
5202
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5203
    gen_op_##name();                                                          \
5204
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5205
}
5206

    
5207
#define GEN_SPEOP_COMP(name)                                                  \
5208
static inline void gen_##name (DisasContext *ctx)                             \
5209
{                                                                             \
5210
    if (unlikely(!ctx->spe_enabled)) {                                        \
5211
        GEN_EXCP_NO_AP(ctx);                                                  \
5212
        return;                                                               \
5213
    }                                                                         \
5214
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5215
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5216
    gen_op_##name();                                                          \
5217
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5218
}
5219

    
5220
/* Logical */
5221
GEN_SPEOP_ARITH2(evand);
5222
GEN_SPEOP_ARITH2(evandc);
5223
GEN_SPEOP_ARITH2(evxor);
5224
GEN_SPEOP_ARITH2(evor);
5225
GEN_SPEOP_ARITH2(evnor);
5226
GEN_SPEOP_ARITH2(eveqv);
5227
GEN_SPEOP_ARITH2(evorc);
5228
GEN_SPEOP_ARITH2(evnand);
5229
GEN_SPEOP_ARITH2(evsrwu);
5230
GEN_SPEOP_ARITH2(evsrws);
5231
GEN_SPEOP_ARITH2(evslw);
5232
GEN_SPEOP_ARITH2(evrlw);
5233
GEN_SPEOP_ARITH2(evmergehi);
5234
GEN_SPEOP_ARITH2(evmergelo);
5235
GEN_SPEOP_ARITH2(evmergehilo);
5236
GEN_SPEOP_ARITH2(evmergelohi);
5237

    
5238
/* Arithmetic */
5239
GEN_SPEOP_ARITH2(evaddw);
5240
GEN_SPEOP_ARITH2(evsubfw);
5241
GEN_SPEOP_ARITH1(evabs);
5242
GEN_SPEOP_ARITH1(evneg);
5243
GEN_SPEOP_ARITH1(evextsb);
5244
GEN_SPEOP_ARITH1(evextsh);
5245
GEN_SPEOP_ARITH1(evrndw);
5246
GEN_SPEOP_ARITH1(evcntlzw);
5247
GEN_SPEOP_ARITH1(evcntlsw);
5248
static inline void gen_brinc (DisasContext *ctx)
5249
{
5250
    /* Note: brinc is usable even if SPE is disabled */
5251
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5252
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5253
    gen_op_brinc();
5254
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5255
}
5256

    
5257
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5258
static inline void gen_##name##i (DisasContext *ctx)                          \
5259
{                                                                             \
5260
    if (unlikely(!ctx->spe_enabled)) {                                        \
5261
        GEN_EXCP_NO_AP(ctx);                                                  \
5262
        return;                                                               \
5263
    }                                                                         \
5264
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5265
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5266
    gen_op_##name();                                                          \
5267
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5268
}
5269

    
5270
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5271
static inline void gen_##name##i (DisasContext *ctx)                          \
5272
{                                                                             \
5273
    if (unlikely(!ctx->spe_enabled)) {                                        \
5274
        GEN_EXCP_NO_AP(ctx);                                                  \
5275
        return;                                                               \
5276
    }                                                                         \
5277
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5278
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5279
    gen_op_##name();                                                          \
5280
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5281
}
5282

    
5283
GEN_SPEOP_ARITH_IMM2(evaddw);
5284
#define gen_evaddiw gen_evaddwi
5285
GEN_SPEOP_ARITH_IMM2(evsubfw);
5286
#define gen_evsubifw gen_evsubfwi
5287
GEN_SPEOP_LOGIC_IMM2(evslw);
5288
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5289
#define gen_evsrwis gen_evsrwsi
5290
GEN_SPEOP_LOGIC_IMM2(evsrws);
5291
#define gen_evsrwiu gen_evsrwui
5292
GEN_SPEOP_LOGIC_IMM2(evrlw);
5293

    
5294
static inline void gen_evsplati (DisasContext *ctx)
5295
{
5296
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5297

    
5298
    gen_op_splatwi_T0_64(imm);
5299
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5300
}
5301

    
5302
static inline void gen_evsplatfi (DisasContext *ctx)
5303
{
5304
    uint32_t imm = rA(ctx->opcode) << 27;
5305

    
5306
    gen_op_splatwi_T0_64(imm);
5307
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5308
}
5309

    
5310
/* Comparison */
5311
GEN_SPEOP_COMP(evcmpgtu);
5312
GEN_SPEOP_COMP(evcmpgts);
5313
GEN_SPEOP_COMP(evcmpltu);
5314
GEN_SPEOP_COMP(evcmplts);
5315
GEN_SPEOP_COMP(evcmpeq);
5316

    
5317
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5318
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5319
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5320
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5321
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5322
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5323
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5324
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5325
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5326
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5327
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5328
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5329
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5330
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5331
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5332
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5333
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5334
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5335
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5336
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5337
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5338
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5339
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5340
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5341
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5342

    
5343
static inline void gen_evsel (DisasContext *ctx)
5344
{
5345
    if (unlikely(!ctx->spe_enabled)) {
5346
        GEN_EXCP_NO_AP(ctx);
5347
        return;
5348
    }
5349
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5350
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5351
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5352
    gen_op_evsel();
5353
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5354
}
5355

    
5356
GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5357
{
5358
    gen_evsel(ctx);
5359
}
5360
GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5361
{
5362
    gen_evsel(ctx);
5363
}
5364
GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5365
{
5366
    gen_evsel(ctx);
5367
}
5368
GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5369
{
5370
    gen_evsel(ctx);
5371
}
5372

    
5373
/* Load and stores */
5374
#if defined(TARGET_PPC64)
5375
/* In that case, we already have 64 bits load & stores
5376
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5377
 */
5378
#if defined(CONFIG_USER_ONLY)
5379
#define gen_op_spe_ldd_raw gen_op_ld_raw
5380
#define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
5381
#define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
5382
#define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
5383
#define gen_op_spe_stdd_raw gen_op_ld_raw
5384
#define gen_op_spe_stdd_64_raw gen_op_std_64_raw
5385
#define gen_op_spe_stdd_le_raw gen_op_std_le_raw
5386
#define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
5387
#else /* defined(CONFIG_USER_ONLY) */
5388
#define gen_op_spe_ldd_kernel gen_op_ld_kernel
5389
#define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
5390
#define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
5391
#define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
5392
#define gen_op_spe_ldd_user gen_op_ld_user
5393
#define gen_op_spe_ldd_64_user gen_op_ld_64_user
5394
#define gen_op_spe_ldd_le_user gen_op_ld_le_user
5395
#define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
5396
#define gen_op_spe_stdd_kernel gen_op_std_kernel
5397
#define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
5398
#define gen_op_spe_stdd_le_kernel gen_op_std_kernel
5399
#define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
5400
#define gen_op_spe_stdd_user gen_op_std_user
5401
#define gen_op_spe_stdd_64_user gen_op_std_64_user
5402
#define gen_op_spe_stdd_le_user gen_op_std_le_user
5403
#define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
5404
#endif /* defined(CONFIG_USER_ONLY) */
5405
#endif /* defined(TARGET_PPC64) */
5406
GEN_SPEOP_LDST(dd, 3);
5407
GEN_SPEOP_LDST(dw, 3);
5408
GEN_SPEOP_LDST(dh, 3);
5409
GEN_SPEOP_LDST(whe, 2);
5410
GEN_SPEOP_LD(whou, 2);
5411
GEN_SPEOP_LD(whos, 2);
5412
GEN_SPEOP_ST(who, 2);
5413

    
5414
#if defined(TARGET_PPC64)
5415
/* In that case, spe_stwwo is equivalent to stw */
5416
#if defined(CONFIG_USER_ONLY)
5417
#define gen_op_spe_stwwo_raw gen_op_stw_raw
5418
#define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
5419
#define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
5420
#define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
5421
#else
5422
#define gen_op_spe_stwwo_user gen_op_stw_user
5423
#define gen_op_spe_stwwo_le_user gen_op_stw_le_user
5424
#define gen_op_spe_stwwo_64_user gen_op_stw_64_user
5425
#define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
5426
#define gen_op_spe_stwwo_kernel gen_op_stw_kernel
5427
#define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
5428
#define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
5429
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5430
#endif
5431
#endif
5432
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5433
static inline void gen_op_spe_stwwe_##suffix (void)                           \
5434
{                                                                             \
5435
    gen_op_srli32_T1_64();                                                    \
5436
    gen_op_spe_stwwo_##suffix();                                              \
5437
}
5438
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5439
static inline void gen_op_spe_stwwe_le_##suffix (void)                        \
5440
{                                                                             \
5441
    gen_op_srli32_T1_64();                                                    \
5442
    gen_op_spe_stwwo_le_##suffix();                                           \
5443
}
5444
#if defined(TARGET_PPC64)
5445
#define GEN_OP_SPE_STWWE(suffix)                                              \
5446
_GEN_OP_SPE_STWWE(suffix);                                                    \
5447
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5448
static inline void gen_op_spe_stwwe_64_##suffix (void)                        \
5449
{                                                                             \
5450
    gen_op_srli32_T1_64();                                                    \
5451
    gen_op_spe_stwwo_64_##suffix();                                           \
5452
}                                                                             \
5453
static inline void gen_op_spe_stwwe_le_64_##suffix (void)                     \
5454
{                                                                             \
5455
    gen_op_srli32_T1_64();                                                    \
5456
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5457
}
5458
#else
5459
#define GEN_OP_SPE_STWWE(suffix)                                              \
5460
_GEN_OP_SPE_STWWE(suffix);                                                    \
5461
_GEN_OP_SPE_STWWE_LE(suffix)
5462
#endif
5463
#if defined(CONFIG_USER_ONLY)
5464
GEN_OP_SPE_STWWE(raw);
5465
#else /* defined(CONFIG_USER_ONLY) */
5466
GEN_OP_SPE_STWWE(kernel);
5467
GEN_OP_SPE_STWWE(user);
5468
#endif /* defined(CONFIG_USER_ONLY) */
5469
GEN_SPEOP_ST(wwe, 2);
5470
GEN_SPEOP_ST(wwo, 2);
5471

    
5472
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5473
static inline void gen_op_spe_l##name##_##suffix (void)                       \
5474
{                                                                             \
5475
    gen_op_##op##_##suffix();                                                 \
5476
    gen_op_splatw_T1_64();                                                    \
5477
}
5478

    
5479
#define GEN_OP_SPE_LHE(suffix)                                                \
5480
static inline void gen_op_spe_lhe_##suffix (void)                             \
5481
{                                                                             \
5482
    gen_op_spe_lh_##suffix();                                                 \
5483
    gen_op_sli16_T1_64();                                                     \
5484
}
5485

    
5486
#define GEN_OP_SPE_LHX(suffix)                                                \
5487
static inline void gen_op_spe_lhx_##suffix (void)                             \
5488
{                                                                             \
5489
    gen_op_spe_lh_##suffix();                                                 \
5490
    gen_op_extsh_T1_64();                                                     \
5491
}
5492

    
5493
#if defined(CONFIG_USER_ONLY)
5494
GEN_OP_SPE_LHE(raw);
5495
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5496
GEN_OP_SPE_LHE(le_raw);
5497
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5498
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5499
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5500
GEN_OP_SPE_LHX(raw);
5501
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5502
GEN_OP_SPE_LHX(le_raw);
5503
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5504
#if defined(TARGET_PPC64)
5505
GEN_OP_SPE_LHE(64_raw);
5506
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5507
GEN_OP_SPE_LHE(le_64_raw);
5508
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5509
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5510
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5511
GEN_OP_SPE_LHX(64_raw);
5512
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5513
GEN_OP_SPE_LHX(le_64_raw);
5514
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5515
#endif
5516
#else
5517
GEN_OP_SPE_LHE(kernel);
5518
GEN_OP_SPE_LHE(user);
5519
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5520
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5521
GEN_OP_SPE_LHE(le_kernel);
5522
GEN_OP_SPE_LHE(le_user);
5523
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5524
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5525
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5526
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5527
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5528
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5529
GEN_OP_SPE_LHX(kernel);
5530
GEN_OP_SPE_LHX(user);
5531
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5532
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5533
GEN_OP_SPE_LHX(le_kernel);
5534
GEN_OP_SPE_LHX(le_user);
5535
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5536
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5537
#if defined(TARGET_PPC64)
5538
GEN_OP_SPE_LHE(64_kernel);
5539
GEN_OP_SPE_LHE(64_user);
5540
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5541
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5542
GEN_OP_SPE_LHE(le_64_kernel);
5543
GEN_OP_SPE_LHE(le_64_user);
5544
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5545
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5546
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5547
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5548
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5549
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5550
GEN_OP_SPE_LHX(64_kernel);
5551
GEN_OP_SPE_LHX(64_user);
5552
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5553
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5554
GEN_OP_SPE_LHX(le_64_kernel);
5555
GEN_OP_SPE_LHX(le_64_user);
5556
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5557
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5558
#endif
5559
#endif
5560
GEN_SPEOP_LD(hhesplat, 1);
5561
GEN_SPEOP_LD(hhousplat, 1);
5562
GEN_SPEOP_LD(hhossplat, 1);
5563
GEN_SPEOP_LD(wwsplat, 2);
5564
GEN_SPEOP_LD(whsplat, 2);
5565

    
5566
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5567
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5568
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5569
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5570
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5571
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5572
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5573
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5574
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5575
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5576
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5577
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5578
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5579
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5580
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5581
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5582
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5583
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5584

    
5585
/* Multiply and add - TODO */
5586
#if 0
5587
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5588
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5589
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5590
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5591
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5592
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5593
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5594
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5595
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5596
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5597
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5598
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5599

5600
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5601
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5602
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5603
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5604
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5605
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5606
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5607
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5608
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5609
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5610
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5611
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5612
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5613
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5614

5615
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5616
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5617
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5618
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5619
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5620
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5621

5622
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5623
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5624
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5625
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5626
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5627
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5628
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5629
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5630
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5631
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5632
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5633
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5634

5635
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5636
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5637
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5638
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5639
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5640

5641
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5642
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5643
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5644
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5645
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5646
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5647
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5648
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5649
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5650
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5651
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5652
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5653

5654
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5655
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5656
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5657
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5658
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5659
#endif
5660

    
5661
/***                      SPE floating-point extension                     ***/
5662
#define GEN_SPEFPUOP_CONV(name)                                               \
5663
static inline void gen_##name (DisasContext *ctx)                             \
5664
{                                                                             \
5665
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5666
    gen_op_##name();                                                          \
5667
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5668
}
5669

    
5670
/* Single precision floating-point vectors operations */
5671
/* Arithmetic */
5672
GEN_SPEOP_ARITH2(evfsadd);
5673
GEN_SPEOP_ARITH2(evfssub);
5674
GEN_SPEOP_ARITH2(evfsmul);
5675
GEN_SPEOP_ARITH2(evfsdiv);
5676
GEN_SPEOP_ARITH1(evfsabs);
5677
GEN_SPEOP_ARITH1(evfsnabs);
5678
GEN_SPEOP_ARITH1(evfsneg);
5679
/* Conversion */
5680
GEN_SPEFPUOP_CONV(evfscfui);
5681
GEN_SPEFPUOP_CONV(evfscfsi);
5682
GEN_SPEFPUOP_CONV(evfscfuf);
5683
GEN_SPEFPUOP_CONV(evfscfsf);
5684
GEN_SPEFPUOP_CONV(evfsctui);
5685
GEN_SPEFPUOP_CONV(evfsctsi);
5686
GEN_SPEFPUOP_CONV(evfsctuf);
5687
GEN_SPEFPUOP_CONV(evfsctsf);
5688
GEN_SPEFPUOP_CONV(evfsctuiz);
5689
GEN_SPEFPUOP_CONV(evfsctsiz);
5690
/* Comparison */
5691
GEN_SPEOP_COMP(evfscmpgt);
5692
GEN_SPEOP_COMP(evfscmplt);
5693
GEN_SPEOP_COMP(evfscmpeq);
5694
GEN_SPEOP_COMP(evfststgt);
5695
GEN_SPEOP_COMP(evfststlt);
5696
GEN_SPEOP_COMP(evfststeq);
5697

    
5698
/* Opcodes definitions */
5699
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5700
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5701
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5702
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5703
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5704
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5705
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5706
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5707
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5708
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5709
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5710
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5711
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5712
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5713

    
5714
/* Single precision floating-point operations */
5715
/* Arithmetic */
5716
GEN_SPEOP_ARITH2(efsadd);
5717
GEN_SPEOP_ARITH2(efssub);
5718
GEN_SPEOP_ARITH2(efsmul);
5719
GEN_SPEOP_ARITH2(efsdiv);
5720
GEN_SPEOP_ARITH1(efsabs);
5721
GEN_SPEOP_ARITH1(efsnabs);
5722
GEN_SPEOP_ARITH1(efsneg);
5723
/* Conversion */
5724
GEN_SPEFPUOP_CONV(efscfui);
5725
GEN_SPEFPUOP_CONV(efscfsi);
5726
GEN_SPEFPUOP_CONV(efscfuf);
5727
GEN_SPEFPUOP_CONV(efscfsf);
5728
GEN_SPEFPUOP_CONV(efsctui);
5729
GEN_SPEFPUOP_CONV(efsctsi);
5730
GEN_SPEFPUOP_CONV(efsctuf);
5731
GEN_SPEFPUOP_CONV(efsctsf);
5732
GEN_SPEFPUOP_CONV(efsctuiz);
5733
GEN_SPEFPUOP_CONV(efsctsiz);
5734
GEN_SPEFPUOP_CONV(efscfd);
5735
/* Comparison */
5736
GEN_SPEOP_COMP(efscmpgt);
5737
GEN_SPEOP_COMP(efscmplt);
5738
GEN_SPEOP_COMP(efscmpeq);
5739
GEN_SPEOP_COMP(efststgt);
5740
GEN_SPEOP_COMP(efststlt);
5741
GEN_SPEOP_COMP(efststeq);
5742

    
5743
/* Opcodes definitions */
5744
GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5745
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5746
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5747
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5748
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5749
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5750
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5751
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5752
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5753
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5754
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5755
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5756
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5757

    
5758
/* Double precision floating-point operations */
5759
/* Arithmetic */
5760
GEN_SPEOP_ARITH2(efdadd);
5761
GEN_SPEOP_ARITH2(efdsub);
5762
GEN_SPEOP_ARITH2(efdmul);
5763
GEN_SPEOP_ARITH2(efddiv);
5764
GEN_SPEOP_ARITH1(efdabs);
5765
GEN_SPEOP_ARITH1(efdnabs);
5766
GEN_SPEOP_ARITH1(efdneg);
5767
/* Conversion */
5768

    
5769
GEN_SPEFPUOP_CONV(efdcfui);
5770
GEN_SPEFPUOP_CONV(efdcfsi);
5771
GEN_SPEFPUOP_CONV(efdcfuf);
5772
GEN_SPEFPUOP_CONV(efdcfsf);
5773
GEN_SPEFPUOP_CONV(efdctui);
5774
GEN_SPEFPUOP_CONV(efdctsi);
5775
GEN_SPEFPUOP_CONV(efdctuf);
5776
GEN_SPEFPUOP_CONV(efdctsf);
5777
GEN_SPEFPUOP_CONV(efdctuiz);
5778
GEN_SPEFPUOP_CONV(efdctsiz);
5779
GEN_SPEFPUOP_CONV(efdcfs);
5780
GEN_SPEFPUOP_CONV(efdcfuid);
5781
GEN_SPEFPUOP_CONV(efdcfsid);
5782
GEN_SPEFPUOP_CONV(efdctuidz);
5783
GEN_SPEFPUOP_CONV(efdctsidz);
5784
/* Comparison */
5785
GEN_SPEOP_COMP(efdcmpgt);
5786
GEN_SPEOP_COMP(efdcmplt);
5787
GEN_SPEOP_COMP(efdcmpeq);
5788
GEN_SPEOP_COMP(efdtstgt);
5789
GEN_SPEOP_COMP(efdtstlt);
5790
GEN_SPEOP_COMP(efdtsteq);
5791

    
5792
/* Opcodes definitions */
5793
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
5794
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
5795
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
5796
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
5797
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
5798
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
5799
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
5800
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
5801
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
5802
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
5803
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
5804
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
5805
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
5806
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
5807
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
5808
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
5809
#endif
5810

    
5811
/* End opcode list */
5812
GEN_OPCODE_MARK(end);
5813

    
5814
#include "translate_init.c"
5815

    
5816
/*****************************************************************************/
5817
/* Misc PowerPC helpers */
5818
static inline uint32_t load_xer (CPUState *env)
5819
{
5820
    return (xer_so << XER_SO) |
5821
        (xer_ov << XER_OV) |
5822
        (xer_ca << XER_CA) |
5823
        (xer_bc << XER_BC) |
5824
        (xer_cmp << XER_CMP);
5825
}
5826

    
5827
void cpu_dump_state (CPUState *env, FILE *f,
5828
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5829
                     int flags)
5830
{
5831
#if defined(TARGET_PPC64) || 1
5832
#define FILL ""
5833
#define RGPL  4
5834
#define RFPL  4
5835
#else
5836
#define FILL "        "
5837
#define RGPL  8
5838
#define RFPL  4
5839
#endif
5840

    
5841
    int i;
5842

    
5843
    cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX "\n",
5844
                env->nip, env->lr, env->ctr);
5845
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
5846
#if !defined(NO_TIMER_DUMP)
5847
                "TB %08x %08x "
5848
#if !defined(CONFIG_USER_ONLY)
5849
                "DECR %08x"
5850
#endif
5851
#endif
5852
                "\n",
5853
                do_load_msr(env), load_xer(env)
5854
#if !defined(NO_TIMER_DUMP)
5855
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
5856
#if !defined(CONFIG_USER_ONLY)
5857
                , cpu_ppc_load_decr(env)
5858
#endif
5859
#endif
5860
                );
5861
    for (i = 0; i < 32; i++) {
5862
        if ((i & (RGPL - 1)) == 0)
5863
            cpu_fprintf(f, "GPR%02d", i);
5864
        cpu_fprintf(f, " " REGX, (target_ulong)env->gpr[i]);
5865
        if ((i & (RGPL - 1)) == (RGPL - 1))
5866
            cpu_fprintf(f, "\n");
5867
    }
5868
    cpu_fprintf(f, "CR ");
5869
    for (i = 0; i < 8; i++)
5870
        cpu_fprintf(f, "%01x", env->crf[i]);
5871
    cpu_fprintf(f, "  [");
5872
    for (i = 0; i < 8; i++) {
5873
        char a = '-';
5874
        if (env->crf[i] & 0x08)
5875
            a = 'L';
5876
        else if (env->crf[i] & 0x04)
5877
            a = 'G';
5878
        else if (env->crf[i] & 0x02)
5879
            a = 'E';
5880
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
5881
    }
5882
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
5883
    for (i = 0; i < 32; i++) {
5884
        if ((i & (RFPL - 1)) == 0)
5885
            cpu_fprintf(f, "FPR%02d", i);
5886
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
5887
        if ((i & (RFPL - 1)) == (RFPL - 1))
5888
            cpu_fprintf(f, "\n");
5889
    }
5890
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
5891
                "SDR1 " REGX "\n",
5892
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
5893

    
5894
#undef RGPL
5895
#undef RFPL
5896
#undef FILL
5897
}
5898

    
5899
void cpu_dump_statistics (CPUState *env, FILE*f,
5900
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5901
                          int flags)
5902
{
5903
#if defined(DO_PPC_STATISTICS)
5904
    opc_handler_t **t1, **t2, **t3, *handler;
5905
    int op1, op2, op3;
5906

    
5907
    t1 = env->opcodes;
5908
    for (op1 = 0; op1 < 64; op1++) {
5909
        handler = t1[op1];
5910
        if (is_indirect_opcode(handler)) {
5911
            t2 = ind_table(handler);
5912
            for (op2 = 0; op2 < 32; op2++) {
5913
                handler = t2[op2];
5914
                if (is_indirect_opcode(handler)) {
5915
                    t3 = ind_table(handler);
5916
                    for (op3 = 0; op3 < 32; op3++) {
5917
                        handler = t3[op3];
5918
                        if (handler->count == 0)
5919
                            continue;
5920
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
5921
                                    "%016llx %lld\n",
5922
                                    op1, op2, op3, op1, (op3 << 5) | op2,
5923
                                    handler->oname,
5924
                                    handler->count, handler->count);
5925
                    }
5926
                } else {
5927
                    if (handler->count == 0)
5928
                        continue;
5929
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
5930
                                "%016llx %lld\n",
5931
                                op1, op2, op1, op2, handler->oname,
5932
                                handler->count, handler->count);
5933
                }
5934
            }
5935
        } else {
5936
            if (handler->count == 0)
5937
                continue;
5938
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
5939
                        op1, op1, handler->oname,
5940
                        handler->count, handler->count);
5941
        }
5942
    }
5943
#endif
5944
}
5945

    
5946
/*****************************************************************************/
5947
static inline int gen_intermediate_code_internal (CPUState *env,
5948
                                                  TranslationBlock *tb,
5949
                                                  int search_pc)
5950
{
5951
    DisasContext ctx, *ctxp = &ctx;
5952
    opc_handler_t **table, *handler;
5953
    target_ulong pc_start;
5954
    uint16_t *gen_opc_end;
5955
    int j, lj = -1;
5956

    
5957
    pc_start = tb->pc;
5958
    gen_opc_ptr = gen_opc_buf;
5959
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5960
    gen_opparam_ptr = gen_opparam_buf;
5961
    nb_gen_labels = 0;
5962
    ctx.nip = pc_start;
5963
    ctx.tb = tb;
5964
    ctx.exception = POWERPC_EXCP_NONE;
5965
    ctx.spr_cb = env->spr_cb;
5966
#if defined(CONFIG_USER_ONLY)
5967
    ctx.mem_idx = msr_le;
5968
#if defined(TARGET_PPC64)
5969
    ctx.mem_idx |= msr_sf << 1;
5970
#endif
5971
#else
5972
    ctx.supervisor = 1 - msr_pr;
5973
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
5974
#if defined(TARGET_PPC64)
5975
    ctx.mem_idx |= msr_sf << 2;
5976
#endif
5977
#endif
5978
#if defined(TARGET_PPC64)
5979
    ctx.sf_mode = msr_sf;
5980
#endif
5981
    ctx.fpu_enabled = msr_fp;
5982
#if defined(TARGET_PPCEMB)
5983
    ctx.spe_enabled = msr_spe;
5984
#endif
5985
    ctx.singlestep_enabled = env->singlestep_enabled;
5986
#if defined (DO_SINGLE_STEP) && 0
5987
    /* Single step trace mode */
5988
    msr_se = 1;
5989
#endif
5990
    /* Set env in case of segfault during code fetch */
5991
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
5992
        if (unlikely(env->nb_breakpoints > 0)) {
5993
            for (j = 0; j < env->nb_breakpoints; j++) {
5994
                if (env->breakpoints[j] == ctx.nip) {
5995
                    gen_update_nip(&ctx, ctx.nip);
5996
                    gen_op_debug();
5997
                    break;
5998
                }
5999
            }
6000
        }
6001
        if (unlikely(search_pc)) {
6002
            j = gen_opc_ptr - gen_opc_buf;
6003
            if (lj < j) {
6004
                lj++;
6005
                while (lj < j)
6006
                    gen_opc_instr_start[lj++] = 0;
6007
                gen_opc_pc[lj] = ctx.nip;
6008
                gen_opc_instr_start[lj] = 1;
6009
            }
6010
        }
6011
#if defined PPC_DEBUG_DISAS
6012
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6013
            fprintf(logfile, "----------------\n");
6014
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6015
                    ctx.nip, 1 - msr_pr, msr_ir);
6016
        }
6017
#endif
6018
        ctx.opcode = ldl_code(ctx.nip);
6019
        if (msr_le) {
6020
            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
6021
                ((ctx.opcode & 0x00FF0000) >> 8) |
6022
                ((ctx.opcode & 0x0000FF00) << 8) |
6023
                ((ctx.opcode & 0x000000FF) << 24);
6024
        }
6025
#if defined PPC_DEBUG_DISAS
6026
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6027
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6028
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6029
                    opc3(ctx.opcode), msr_le ? "little" : "big");
6030
        }
6031
#endif
6032
        ctx.nip += 4;
6033
        table = env->opcodes;
6034
        handler = table[opc1(ctx.opcode)];
6035
        if (is_indirect_opcode(handler)) {
6036
            table = ind_table(handler);
6037
            handler = table[opc2(ctx.opcode)];
6038
            if (is_indirect_opcode(handler)) {
6039
                table = ind_table(handler);
6040
                handler = table[opc3(ctx.opcode)];
6041
            }
6042
        }
6043
        /* Is opcode *REALLY* valid ? */
6044
        if (unlikely(handler->handler == &gen_invalid)) {
6045
            if (loglevel != 0) {
6046
                fprintf(logfile, "invalid/unsupported opcode: "
6047
                        "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6048
                        opc1(ctx.opcode), opc2(ctx.opcode),
6049
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
6050
            } else {
6051
                printf("invalid/unsupported opcode: "
6052
                       "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6053
                       opc1(ctx.opcode), opc2(ctx.opcode),
6054
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
6055
            }
6056
        } else {
6057
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6058
                if (loglevel != 0) {
6059
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6060
                            "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6061
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6062
                            opc2(ctx.opcode), opc3(ctx.opcode),
6063
                            ctx.opcode, ctx.nip - 4);
6064
                } else {
6065
                    printf("invalid bits: %08x for opcode: "
6066
                           "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6067
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6068
                           opc2(ctx.opcode), opc3(ctx.opcode),
6069
                           ctx.opcode, ctx.nip - 4);
6070
                }
6071
                GEN_EXCP_INVAL(ctxp);
6072
                break;
6073
            }
6074
        }
6075
        (*(handler->handler))(&ctx);
6076
#if defined(DO_PPC_STATISTICS)
6077
        handler->count++;
6078
#endif
6079
        /* Check trace mode exceptions */
6080
#if 0 // XXX: buggy on embedded PowerPC
6081
        if (unlikely((msr_be && ctx.exception == POWERPC_EXCP_BRANCH) ||
6082
                     /* Check in single step trace mode
6083
                      * we need to stop except if:
6084
                      * - rfi, trap or syscall
6085
                      * - first instruction of an exception handler
6086
                      */
6087
                     (msr_se && (ctx.nip < 0x100 ||
6088
                                 ctx.nip > 0xF00 ||
6089
                                 (ctx.nip & 0xFC) != 0x04) &&
6090
#if defined(CONFIG_USER_ONLY)
6091
                      ctx.exception != POWERPC_EXCP_SYSCALL_USER &&
6092
#else
6093
                      ctx.exception != POWERPC_EXCP_SYSCALL &&
6094
#endif
6095
                      ctx.exception != POWERPC_EXCP_TRAP))) {
6096
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6097
        }
6098
#endif
6099
        /* if we reach a page boundary or are single stepping, stop
6100
         * generation
6101
         */
6102
        if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6103
                     (env->singlestep_enabled))) {
6104
            break;
6105
        }
6106
#if defined (DO_SINGLE_STEP)
6107
        break;
6108
#endif
6109
    }
6110
    if (ctx.exception == POWERPC_EXCP_NONE) {
6111
        gen_goto_tb(&ctx, 0, ctx.nip);
6112
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6113
        gen_op_reset_T0();
6114
        /* Generate the return instruction */
6115
        gen_op_exit_tb();
6116
    }
6117
    *gen_opc_ptr = INDEX_op_end;
6118
    if (unlikely(search_pc)) {
6119
        j = gen_opc_ptr - gen_opc_buf;
6120
        lj++;
6121
        while (lj <= j)
6122
            gen_opc_instr_start[lj++] = 0;
6123
    } else {
6124
        tb->size = ctx.nip - pc_start;
6125
    }
6126
#if defined(DEBUG_DISAS)
6127
    if (loglevel & CPU_LOG_TB_CPU) {
6128
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6129
        cpu_dump_state(env, logfile, fprintf, 0);
6130
    }
6131
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6132
        int flags;
6133
        flags = env->bfd_mach;
6134
        flags |= msr_le << 16;
6135
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6136
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6137
        fprintf(logfile, "\n");
6138
    }
6139
    if (loglevel & CPU_LOG_TB_OP) {
6140
        fprintf(logfile, "OP:\n");
6141
        dump_ops(gen_opc_buf, gen_opparam_buf);
6142
        fprintf(logfile, "\n");
6143
    }
6144
#endif
6145
    return 0;
6146
}
6147

    
6148
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6149
{
6150
    return gen_intermediate_code_internal(env, tb, 0);
6151
}
6152

    
6153
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6154
{
6155
    return gen_intermediate_code_internal(env, tb, 1);
6156
}