Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ a750fc0b

History | View | Annotate | Download (204.8 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 RET_EXCP(ctx, excp, error)                                            \
211
do {                                                                          \
212
    if ((ctx)->exception == 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 RET_INVAL(ctx)                                                        \
220
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
221

    
222
#define RET_PRIVOPC(ctx)                                                      \
223
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
224

    
225
#define RET_PRIVREG(ctx)                                                      \
226
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
227

    
228
/* Stop translation */
229
static inline void RET_STOP (DisasContext *ctx)
230
{
231
    gen_update_nip(ctx, ctx->nip);
232
    ctx->exception = EXCP_MTMSR;
233
}
234

    
235
/* No need to update nip here, as execution flow will change */
236
static inline void RET_CHG_FLOW (DisasContext *ctx)
237
{
238
    ctx->exception = EXCP_MTMSR;
239
}
240

    
241
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
242
static void gen_##name (DisasContext *ctx);                                   \
243
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
244
static void gen_##name (DisasContext *ctx)
245

    
246
typedef struct opcode_t {
247
    unsigned char opc1, opc2, opc3;
248
#if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
249
    unsigned char pad[5];
250
#else
251
    unsigned char pad[1];
252
#endif
253
    opc_handler_t handler;
254
    const unsigned char *oname;
255
} opcode_t;
256

    
257
/*****************************************************************************/
258
/***                           Instruction decoding                        ***/
259
#define EXTRACT_HELPER(name, shift, nb)                                       \
260
static inline uint32_t name (uint32_t opcode)                                 \
261
{                                                                             \
262
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
263
}
264

    
265
#define EXTRACT_SHELPER(name, shift, nb)                                      \
266
static inline int32_t name (uint32_t opcode)                                  \
267
{                                                                             \
268
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
269
}
270

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

    
301
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
302
}
303
/***                              Get constants                            ***/
304
EXTRACT_HELPER(IMM, 12, 8);
305
/* 16 bits signed immediate value */
306
EXTRACT_SHELPER(SIMM, 0, 16);
307
/* 16 bits unsigned immediate value */
308
EXTRACT_HELPER(UIMM, 0, 16);
309
/* Bit count */
310
EXTRACT_HELPER(NB, 11, 5);
311
/* Shift count */
312
EXTRACT_HELPER(SH, 11, 5);
313
/* Mask start */
314
EXTRACT_HELPER(MB, 6, 5);
315
/* Mask end */
316
EXTRACT_HELPER(ME, 1, 5);
317
/* Trap operand */
318
EXTRACT_HELPER(TO, 21, 5);
319

    
320
EXTRACT_HELPER(CRM, 12, 8);
321
EXTRACT_HELPER(FM, 17, 8);
322
EXTRACT_HELPER(SR, 16, 4);
323
EXTRACT_HELPER(FPIMM, 20, 4);
324

    
325
/***                            Jump target decoding                       ***/
326
/* Displacement */
327
EXTRACT_SHELPER(d, 0, 16);
328
/* Immediate address */
329
static inline target_ulong LI (uint32_t opcode)
330
{
331
    return (opcode >> 0) & 0x03FFFFFC;
332
}
333

    
334
static inline uint32_t BD (uint32_t opcode)
335
{
336
    return (opcode >> 0) & 0xFFFC;
337
}
338

    
339
EXTRACT_HELPER(BO, 21, 5);
340
EXTRACT_HELPER(BI, 16, 5);
341
/* Absolute/relative address */
342
EXTRACT_HELPER(AA, 1, 1);
343
/* Link */
344
EXTRACT_HELPER(LK, 0, 1);
345

    
346
/* Create a mask between <start> and <end> bits */
347
static inline target_ulong MASK (uint32_t start, uint32_t end)
348
{
349
    target_ulong ret;
350

    
351
#if defined(TARGET_PPC64)
352
    if (likely(start == 0)) {
353
        ret = (uint64_t)(-1ULL) << (63 - end);
354
    } else if (likely(end == 63)) {
355
        ret = (uint64_t)(-1ULL) >> start;
356
    }
357
#else
358
    if (likely(start == 0)) {
359
        ret = (uint32_t)(-1ULL) << (31  - end);
360
    } else if (likely(end == 31)) {
361
        ret = (uint32_t)(-1ULL) >> start;
362
    }
363
#endif
364
    else {
365
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
366
            (((target_ulong)(-1ULL) >> (end)) >> 1);
367
        if (unlikely(start > end))
368
            return ~ret;
369
    }
370

    
371
    return ret;
372
}
373

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

    
472
/*****************************************************************************/
473
/* PowerPC instructions table                                                */
474
#if HOST_LONG_BITS == 64
475
#define OPC_ALIGN 8
476
#else
477
#define OPC_ALIGN 4
478
#endif
479
#if defined(__APPLE__)
480
#define OPCODES_SECTION                                                       \
481
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
482
#else
483
#define OPCODES_SECTION                                                       \
484
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
485
#endif
486

    
487
#if defined(DO_PPC_STATISTICS)
488
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
489
OPCODES_SECTION opcode_t opc_##name = {                                       \
490
    .opc1 = op1,                                                              \
491
    .opc2 = op2,                                                              \
492
    .opc3 = op3,                                                              \
493
    .pad  = { 0, },                                                           \
494
    .handler = {                                                              \
495
        .inval   = invl,                                                      \
496
        .type = _typ,                                                         \
497
        .handler = &gen_##name,                                               \
498
        .oname = stringify(name),                                             \
499
    },                                                                        \
500
    .oname = stringify(name),                                                 \
501
}
502
#else
503
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
504
OPCODES_SECTION opcode_t opc_##name = {                                       \
505
    .opc1 = op1,                                                              \
506
    .opc2 = op2,                                                              \
507
    .opc3 = op3,                                                              \
508
    .pad  = { 0, },                                                           \
509
    .handler = {                                                              \
510
        .inval   = invl,                                                      \
511
        .type = _typ,                                                         \
512
        .handler = &gen_##name,                                               \
513
    },                                                                        \
514
    .oname = stringify(name),                                                 \
515
}
516
#endif
517

    
518
#define GEN_OPCODE_MARK(name)                                                 \
519
OPCODES_SECTION opcode_t opc_##name = {                                       \
520
    .opc1 = 0xFF,                                                             \
521
    .opc2 = 0xFF,                                                             \
522
    .opc3 = 0xFF,                                                             \
523
    .pad  = { 0, },                                                           \
524
    .handler = {                                                              \
525
        .inval   = 0x00000000,                                                \
526
        .type = 0x00,                                                         \
527
        .handler = NULL,                                                      \
528
    },                                                                        \
529
    .oname = stringify(name),                                                 \
530
}
531

    
532
/* Start opcode list */
533
GEN_OPCODE_MARK(start);
534

    
535
/* Invalid instruction */
536
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
537
{
538
    RET_INVAL(ctx);
539
}
540

    
541
static opc_handler_t invalid_handler = {
542
    .inval   = 0xFFFFFFFF,
543
    .type    = PPC_NONE,
544
    .handler = gen_invalid,
545
};
546

    
547
/***                           Integer arithmetic                          ***/
548
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
549
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
550
{                                                                             \
551
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
552
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
553
    gen_op_##name();                                                          \
554
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
555
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
556
        gen_set_Rc0(ctx);                                                     \
557
}
558

    
559
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
560
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
561
{                                                                             \
562
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
563
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
564
    gen_op_##name();                                                          \
565
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
566
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
567
        gen_set_Rc0(ctx);                                                     \
568
}
569

    
570
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
571
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
572
{                                                                             \
573
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
574
    gen_op_##name();                                                          \
575
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
576
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
577
        gen_set_Rc0(ctx);                                                     \
578
}
579
#define __GEN_INT_ARITH1_O(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

    
589
/* Two operands arithmetic functions */
590
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
591
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
592
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
593

    
594
/* Two operands arithmetic functions with no overflow allowed */
595
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
596
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
597

    
598
/* One operand arithmetic functions */
599
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
600
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
601
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
602

    
603
#if defined(TARGET_PPC64)
604
#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
605
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
606
{                                                                             \
607
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
608
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
609
    if (ctx->sf_mode)                                                         \
610
        gen_op_##name##_64();                                                 \
611
    else                                                                      \
612
        gen_op_##name();                                                      \
613
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
614
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
615
        gen_set_Rc0(ctx);                                                     \
616
}
617

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

    
632
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
633
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
634
{                                                                             \
635
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
636
    if (ctx->sf_mode)                                                         \
637
        gen_op_##name##_64();                                                 \
638
    else                                                                      \
639
        gen_op_##name();                                                      \
640
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
641
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
642
        gen_set_Rc0(ctx);                                                     \
643
}
644
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
645
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
646
{                                                                             \
647
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
648
    if (ctx->sf_mode)                                                         \
649
        gen_op_##name##_64();                                                 \
650
    else                                                                      \
651
        gen_op_##name();                                                      \
652
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
653
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
654
        gen_set_Rc0(ctx);                                                     \
655
}
656

    
657
/* Two operands arithmetic functions */
658
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
659
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
660
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
661

    
662
/* Two operands arithmetic functions with no overflow allowed */
663
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
664
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
665

    
666
/* One operand arithmetic functions */
667
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
668
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
669
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
670
#else
671
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
672
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
673
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
674
#endif
675

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

    
866
    if (rA(ctx->opcode) == 0) {
867
        /* li case */
868
        gen_set_T0(simm);
869
    } else {
870
        gen_op_load_gpr_T0(rA(ctx->opcode));
871
        if (likely(simm != 0))
872
            gen_op_addi(simm);
873
    }
874
    gen_op_store_T0_gpr(rD(ctx->opcode));
875
}
876
/* addic */
877
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
878
{
879
    target_long simm = SIMM(ctx->opcode);
880

    
881
    gen_op_load_gpr_T0(rA(ctx->opcode));
882
    if (likely(simm != 0)) {
883
        gen_op_move_T2_T0();
884
        gen_op_addi(simm);
885
#if defined(TARGET_PPC64)
886
        if (ctx->sf_mode)
887
            gen_op_check_addc_64();
888
        else
889
#endif
890
            gen_op_check_addc();
891
    } else {
892
        gen_op_clear_xer_ca();
893
    }
894
    gen_op_store_T0_gpr(rD(ctx->opcode));
895
}
896
/* addic. */
897
GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
898
{
899
    target_long simm = SIMM(ctx->opcode);
900

    
901
    gen_op_load_gpr_T0(rA(ctx->opcode));
902
    if (likely(simm != 0)) {
903
        gen_op_move_T2_T0();
904
        gen_op_addi(simm);
905
#if defined(TARGET_PPC64)
906
        if (ctx->sf_mode)
907
            gen_op_check_addc_64();
908
        else
909
#endif
910
            gen_op_check_addc();
911
    } else {
912
        gen_op_clear_xer_ca();
913
    }
914
    gen_op_store_T0_gpr(rD(ctx->opcode));
915
    gen_set_Rc0(ctx);
916
}
917
/* addis */
918
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
919
{
920
    target_long simm = SIMM(ctx->opcode);
921

    
922
    if (rA(ctx->opcode) == 0) {
923
        /* lis case */
924
        gen_set_T0(simm << 16);
925
    } else {
926
        gen_op_load_gpr_T0(rA(ctx->opcode));
927
        if (likely(simm != 0))
928
            gen_op_addi(simm << 16);
929
    }
930
    gen_op_store_T0_gpr(rD(ctx->opcode));
931
}
932
/* mulli */
933
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
934
{
935
    gen_op_load_gpr_T0(rA(ctx->opcode));
936
    gen_op_mulli(SIMM(ctx->opcode));
937
    gen_op_store_T0_gpr(rD(ctx->opcode));
938
}
939
/* subfic */
940
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
941
{
942
    gen_op_load_gpr_T0(rA(ctx->opcode));
943
#if defined(TARGET_PPC64)
944
    if (ctx->sf_mode)
945
        gen_op_subfic_64(SIMM(ctx->opcode));
946
    else
947
#endif
948
        gen_op_subfic(SIMM(ctx->opcode));
949
    gen_op_store_T0_gpr(rD(ctx->opcode));
950
}
951

    
952
#if defined(TARGET_PPC64)
953
/* mulhd  mulhd.                   */
954
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
955
/* mulhdu mulhdu.                  */
956
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
957
/* mulld  mulld.  mulldo  mulldo.  */
958
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
959
/* divd   divd.   divdo   divdo.   */
960
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
961
/* divdu  divdu.  divduo  divduo.  */
962
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
963
#endif
964

    
965
/***                           Integer comparison                          ***/
966
#if defined(TARGET_PPC64)
967
#define GEN_CMP(name, opc, type)                                              \
968
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
969
{                                                                             \
970
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
971
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
972
    if (ctx->sf_mode)                                                         \
973
        gen_op_##name##_64();                                                 \
974
    else                                                                      \
975
        gen_op_##name();                                                      \
976
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
977
}
978
#else
979
#define GEN_CMP(name, opc, type)                                              \
980
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
981
{                                                                             \
982
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
983
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
984
    gen_op_##name();                                                          \
985
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
986
}
987
#endif
988

    
989
/* cmp */
990
GEN_CMP(cmp, 0x00, PPC_INTEGER);
991
/* cmpi */
992
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
993
{
994
    gen_op_load_gpr_T0(rA(ctx->opcode));
995
#if defined(TARGET_PPC64)
996
    if (ctx->sf_mode)
997
        gen_op_cmpi_64(SIMM(ctx->opcode));
998
    else
999
#endif
1000
        gen_op_cmpi(SIMM(ctx->opcode));
1001
    gen_op_store_T0_crf(crfD(ctx->opcode));
1002
}
1003
/* cmpl */
1004
GEN_CMP(cmpl, 0x01, PPC_INTEGER);
1005
/* cmpli */
1006
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1007
{
1008
    gen_op_load_gpr_T0(rA(ctx->opcode));
1009
#if defined(TARGET_PPC64)
1010
    if (ctx->sf_mode)
1011
        gen_op_cmpli_64(UIMM(ctx->opcode));
1012
    else
1013
#endif
1014
        gen_op_cmpli(UIMM(ctx->opcode));
1015
    gen_op_store_T0_crf(crfD(ctx->opcode));
1016
}
1017

    
1018
/* isel (PowerPC 2.03 specification) */
1019
GEN_HANDLER(isel, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203)
1020
{
1021
    uint32_t bi = rC(ctx->opcode);
1022
    uint32_t mask;
1023

    
1024
    if (rA(ctx->opcode) == 0) {
1025
        gen_set_T0(0);
1026
    } else {
1027
        gen_op_load_gpr_T1(rA(ctx->opcode));
1028
    }
1029
    gen_op_load_gpr_T2(rB(ctx->opcode));
1030
    mask = 1 << (3 - (bi & 0x03));
1031
    gen_op_load_crf_T0(bi >> 2);
1032
    gen_op_test_true(mask);
1033
    gen_op_isel();
1034
    gen_op_store_T0_gpr(rD(ctx->opcode));
1035
}
1036

    
1037
/***                            Integer logical                            ***/
1038
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1039
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1040
{                                                                             \
1041
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1042
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1043
    gen_op_##name();                                                          \
1044
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1045
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1046
        gen_set_Rc0(ctx);                                                     \
1047
}
1048
#define GEN_LOGICAL2(name, opc, type)                                         \
1049
__GEN_LOGICAL2(name, 0x1C, opc, type)
1050

    
1051
#define GEN_LOGICAL1(name, opc, type)                                         \
1052
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1053
{                                                                             \
1054
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1055
    gen_op_##name();                                                          \
1056
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1057
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1058
        gen_set_Rc0(ctx);                                                     \
1059
}
1060

    
1061
/* and & and. */
1062
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1063
/* andc & andc. */
1064
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1065
/* andi. */
1066
GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1067
{
1068
    gen_op_load_gpr_T0(rS(ctx->opcode));
1069
    gen_op_andi_T0(UIMM(ctx->opcode));
1070
    gen_op_store_T0_gpr(rA(ctx->opcode));
1071
    gen_set_Rc0(ctx);
1072
}
1073
/* andis. */
1074
GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1075
{
1076
    gen_op_load_gpr_T0(rS(ctx->opcode));
1077
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
1078
    gen_op_store_T0_gpr(rA(ctx->opcode));
1079
    gen_set_Rc0(ctx);
1080
}
1081

    
1082
/* cntlzw */
1083
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1084
/* eqv & eqv. */
1085
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1086
/* extsb & extsb. */
1087
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1088
/* extsh & extsh. */
1089
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1090
/* nand & nand. */
1091
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1092
/* nor & nor. */
1093
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1094

    
1095
/* or & or. */
1096
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1097
{
1098
    int rs, ra, rb;
1099

    
1100
    rs = rS(ctx->opcode);
1101
    ra = rA(ctx->opcode);
1102
    rb = rB(ctx->opcode);
1103
    /* Optimisation for mr. ri case */
1104
    if (rs != ra || rs != rb) {
1105
        gen_op_load_gpr_T0(rs);
1106
        if (rs != rb) {
1107
            gen_op_load_gpr_T1(rb);
1108
            gen_op_or();
1109
        }
1110
        gen_op_store_T0_gpr(ra);
1111
        if (unlikely(Rc(ctx->opcode) != 0))
1112
            gen_set_Rc0(ctx);
1113
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1114
        gen_op_load_gpr_T0(rs);
1115
        gen_set_Rc0(ctx);
1116
    }
1117
}
1118

    
1119
/* orc & orc. */
1120
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1121
/* xor & xor. */
1122
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1123
{
1124
    gen_op_load_gpr_T0(rS(ctx->opcode));
1125
    /* Optimisation for "set to zero" case */
1126
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1127
        gen_op_load_gpr_T1(rB(ctx->opcode));
1128
        gen_op_xor();
1129
    } else {
1130
        gen_op_reset_T0();
1131
    }
1132
    gen_op_store_T0_gpr(rA(ctx->opcode));
1133
    if (unlikely(Rc(ctx->opcode) != 0))
1134
        gen_set_Rc0(ctx);
1135
}
1136
/* ori */
1137
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1138
{
1139
    target_ulong uimm = UIMM(ctx->opcode);
1140

    
1141
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1142
        /* NOP */
1143
        /* XXX: should handle special NOPs for POWER series */
1144
        return;
1145
    }
1146
    gen_op_load_gpr_T0(rS(ctx->opcode));
1147
    if (likely(uimm != 0))
1148
        gen_op_ori(uimm);
1149
    gen_op_store_T0_gpr(rA(ctx->opcode));
1150
}
1151
/* oris */
1152
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1153
{
1154
    target_ulong uimm = UIMM(ctx->opcode);
1155

    
1156
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1157
        /* NOP */
1158
        return;
1159
    }
1160
    gen_op_load_gpr_T0(rS(ctx->opcode));
1161
    if (likely(uimm != 0))
1162
        gen_op_ori(uimm << 16);
1163
    gen_op_store_T0_gpr(rA(ctx->opcode));
1164
}
1165
/* xori */
1166
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1167
{
1168
    target_ulong uimm = UIMM(ctx->opcode);
1169

    
1170
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1171
        /* NOP */
1172
        return;
1173
    }
1174
    gen_op_load_gpr_T0(rS(ctx->opcode));
1175
    if (likely(uimm != 0))
1176
        gen_op_xori(uimm);
1177
    gen_op_store_T0_gpr(rA(ctx->opcode));
1178
}
1179

    
1180
/* xoris */
1181
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1182
{
1183
    target_ulong uimm = UIMM(ctx->opcode);
1184

    
1185
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1186
        /* NOP */
1187
        return;
1188
    }
1189
    gen_op_load_gpr_T0(rS(ctx->opcode));
1190
    if (likely(uimm != 0))
1191
        gen_op_xori(uimm << 16);
1192
    gen_op_store_T0_gpr(rA(ctx->opcode));
1193
}
1194

    
1195
/* popcntb : PowerPC 2.03 specification */
1196
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_203)
1197
{
1198
    gen_op_load_gpr_T0(rS(ctx->opcode));
1199
#if defined(TARGET_PPC64)
1200
    if (ctx->sf_mode)
1201
        gen_op_popcntb_64();
1202
    else
1203
#endif
1204
        gen_op_popcntb();
1205
    gen_op_store_T0_gpr(rA(ctx->opcode));
1206
}
1207

    
1208
#if defined(TARGET_PPC64)
1209
/* extsw & extsw. */
1210
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1211
/* cntlzd */
1212
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1213
#endif
1214

    
1215
/***                             Integer rotate                            ***/
1216
/* rlwimi & rlwimi. */
1217
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1218
{
1219
    target_ulong mask;
1220
    uint32_t mb, me, sh;
1221

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

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

    
1297
    mb = MB(ctx->opcode);
1298
    me = ME(ctx->opcode);
1299
    gen_op_load_gpr_T0(rS(ctx->opcode));
1300
    gen_op_load_gpr_T1(rB(ctx->opcode));
1301
    gen_op_rotl32_T0_T1();
1302
    if (unlikely(mb != 0 || me != 31)) {
1303
#if defined(TARGET_PPC64)
1304
        mb += 32;
1305
        me += 32;
1306
#endif
1307
        gen_op_andi_T0(MASK(mb, me));
1308
    }
1309
    gen_op_store_T0_gpr(rA(ctx->opcode));
1310
    if (unlikely(Rc(ctx->opcode) != 0))
1311
        gen_set_Rc0(ctx);
1312
}
1313

    
1314
#if defined(TARGET_PPC64)
1315
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1316
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1317
{                                                                             \
1318
    gen_##name(ctx, 0);                                                       \
1319
}                                                                             \
1320
GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1321
{                                                                             \
1322
    gen_##name(ctx, 1);                                                       \
1323
}
1324
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1325
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1326
{                                                                             \
1327
    gen_##name(ctx, 0, 0);                                                    \
1328
}                                                                             \
1329
GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B)            \
1330
{                                                                             \
1331
    gen_##name(ctx, 0, 1);                                                    \
1332
}                                                                             \
1333
GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1334
{                                                                             \
1335
    gen_##name(ctx, 1, 0);                                                    \
1336
}                                                                             \
1337
GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B)            \
1338
{                                                                             \
1339
    gen_##name(ctx, 1, 1);                                                    \
1340
}
1341

    
1342
static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me,
1343
                               uint32_t sh)
1344
{
1345
    gen_op_load_gpr_T0(rS(ctx->opcode));
1346
    if (likely(sh == 0)) {
1347
        goto do_mask;
1348
    }
1349
    if (likely(mb == 0)) {
1350
        if (likely(me == 63)) {
1351
            gen_op_rotli32_T0(sh);
1352
            goto do_store;
1353
        } else if (likely(me == (63 - sh))) {
1354
            gen_op_sli_T0(sh);
1355
            goto do_store;
1356
        }
1357
    } else if (likely(me == 63)) {
1358
        if (likely(sh == (64 - mb))) {
1359
            gen_op_srli_T0(mb);
1360
            goto do_store;
1361
        }
1362
    }
1363
    gen_op_rotli64_T0(sh);
1364
 do_mask:
1365
    gen_op_andi_T0(MASK(mb, me));
1366
 do_store:
1367
    gen_op_store_T0_gpr(rA(ctx->opcode));
1368
    if (unlikely(Rc(ctx->opcode) != 0))
1369
        gen_set_Rc0(ctx);
1370
}
1371
/* rldicl - rldicl. */
1372
static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1373
{
1374
    uint32_t sh, mb;
1375

    
1376
    sh = SH(ctx->opcode) | (shn << 5);
1377
    mb = MB(ctx->opcode) | (mbn << 5);
1378
    gen_rldinm(ctx, mb, 63, sh);
1379
}
1380
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1381
/* rldicr - rldicr. */
1382
static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1383
{
1384
    uint32_t sh, me;
1385

    
1386
    sh = SH(ctx->opcode) | (shn << 5);
1387
    me = MB(ctx->opcode) | (men << 5);
1388
    gen_rldinm(ctx, 0, me, sh);
1389
}
1390
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1391
/* rldic - rldic. */
1392
static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1393
{
1394
    uint32_t sh, mb;
1395

    
1396
    sh = SH(ctx->opcode) | (shn << 5);
1397
    mb = MB(ctx->opcode) | (mbn << 5);
1398
    gen_rldinm(ctx, mb, 63 - sh, sh);
1399
}
1400
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1401

    
1402
static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me)
1403
{
1404
    gen_op_load_gpr_T0(rS(ctx->opcode));
1405
    gen_op_load_gpr_T1(rB(ctx->opcode));
1406
    gen_op_rotl64_T0_T1();
1407
    if (unlikely(mb != 0 || me != 63)) {
1408
        gen_op_andi_T0(MASK(mb, me));
1409
    }
1410
    gen_op_store_T0_gpr(rA(ctx->opcode));
1411
    if (unlikely(Rc(ctx->opcode) != 0))
1412
        gen_set_Rc0(ctx);
1413
}
1414

    
1415
/* rldcl - rldcl. */
1416
static inline void gen_rldcl (DisasContext *ctx, int mbn)
1417
{
1418
    uint32_t mb;
1419

    
1420
    mb = MB(ctx->opcode) | (mbn << 5);
1421
    gen_rldnm(ctx, mb, 63);
1422
}
1423
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1424
/* rldcr - rldcr. */
1425
static inline void gen_rldcr (DisasContext *ctx, int men)
1426
{
1427
    uint32_t me;
1428

    
1429
    me = MB(ctx->opcode) | (men << 5);
1430
    gen_rldnm(ctx, 0, me);
1431
}
1432
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1433
/* rldimi - rldimi. */
1434
static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1435
{
1436
    uint64_t mask;
1437
    uint32_t sh, mb;
1438

    
1439
    sh = SH(ctx->opcode) | (shn << 5);
1440
    mb = MB(ctx->opcode) | (mbn << 5);
1441
    if (likely(sh == 0)) {
1442
        if (likely(mb == 0)) {
1443
            gen_op_load_gpr_T0(rS(ctx->opcode));
1444
            goto do_store;
1445
        } else if (likely(mb == 63)) {
1446
            gen_op_load_gpr_T0(rA(ctx->opcode));
1447
            goto do_store;
1448
        }
1449
        gen_op_load_gpr_T0(rS(ctx->opcode));
1450
        gen_op_load_gpr_T1(rA(ctx->opcode));
1451
        goto do_mask;
1452
    }
1453
    gen_op_load_gpr_T0(rS(ctx->opcode));
1454
    gen_op_load_gpr_T1(rA(ctx->opcode));
1455
    gen_op_rotli64_T0(SH(ctx->opcode));
1456
 do_mask:
1457
    mask = MASK(mb, 63 - sh);
1458
    gen_op_andi_T0(mask);
1459
    gen_op_andi_T1(~mask);
1460
    gen_op_or();
1461
 do_store:
1462
    gen_op_store_T0_gpr(rA(ctx->opcode));
1463
    if (unlikely(Rc(ctx->opcode) != 0))
1464
        gen_set_Rc0(ctx);
1465
}
1466
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1467
#endif
1468

    
1469
/***                             Integer shift                             ***/
1470
/* slw & slw. */
1471
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1472
/* sraw & sraw. */
1473
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1474
/* srawi & srawi. */
1475
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1476
{
1477
    int mb, me;
1478
    gen_op_load_gpr_T0(rS(ctx->opcode));
1479
    if (SH(ctx->opcode) != 0) {
1480
        gen_op_move_T1_T0();
1481
        mb = 32 - SH(ctx->opcode);
1482
        me = 31;
1483
#if defined(TARGET_PPC64)
1484
        mb += 32;
1485
        me += 32;
1486
#endif
1487
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1488
    }
1489
    gen_op_store_T0_gpr(rA(ctx->opcode));
1490
    if (unlikely(Rc(ctx->opcode) != 0))
1491
        gen_set_Rc0(ctx);
1492
}
1493
/* srw & srw. */
1494
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1495

    
1496
#if defined(TARGET_PPC64)
1497
/* sld & sld. */
1498
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1499
/* srad & srad. */
1500
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1501
/* sradi & sradi. */
1502
static inline void gen_sradi (DisasContext *ctx, int n)
1503
{
1504
    uint64_t mask;
1505
    int sh, mb, me;
1506

    
1507
    gen_op_load_gpr_T0(rS(ctx->opcode));
1508
    sh = SH(ctx->opcode) + (n << 5);
1509
    if (sh != 0) {
1510
        gen_op_move_T1_T0();
1511
        mb = 64 - SH(ctx->opcode);
1512
        me = 63;
1513
        mask = MASK(mb, me);
1514
        gen_op_sradi(sh, mask >> 32, mask);
1515
    }
1516
    gen_op_store_T0_gpr(rA(ctx->opcode));
1517
    if (unlikely(Rc(ctx->opcode) != 0))
1518
        gen_set_Rc0(ctx);
1519
}
1520
GEN_HANDLER(sradi0, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1521
{
1522
    gen_sradi(ctx, 0);
1523
}
1524
GEN_HANDLER(sradi1, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1525
{
1526
    gen_sradi(ctx, 1);
1527
}
1528
/* srd & srd. */
1529
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1530
#endif
1531

    
1532
/***                       Floating-Point arithmetic                       ***/
1533
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, type)                     \
1534
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1535
{                                                                             \
1536
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1537
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1538
        return;                                                               \
1539
    }                                                                         \
1540
    gen_op_reset_scrfx();                                                     \
1541
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1542
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1543
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1544
    gen_op_f##op();                                                           \
1545
    if (isfloat) {                                                            \
1546
        gen_op_frsp();                                                        \
1547
    }                                                                         \
1548
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1549
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1550
        gen_op_set_Rc1();                                                     \
1551
}
1552

    
1553
#define GEN_FLOAT_ACB(name, op2, type)                                        \
1554
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, type);                               \
1555
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type);
1556

    
1557
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
1558
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1559
{                                                                             \
1560
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1561
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1562
        return;                                                               \
1563
    }                                                                         \
1564
    gen_op_reset_scrfx();                                                     \
1565
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1566
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1567
    gen_op_f##op();                                                           \
1568
    if (isfloat) {                                                            \
1569
        gen_op_frsp();                                                        \
1570
    }                                                                         \
1571
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1572
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1573
        gen_op_set_Rc1();                                                     \
1574
}
1575
#define GEN_FLOAT_AB(name, op2, inval)                                        \
1576
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
1577
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1578

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

    
1601
#define GEN_FLOAT_B(name, op2, op3, type)                                     \
1602
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1603
{                                                                             \
1604
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1605
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1606
        return;                                                               \
1607
    }                                                                         \
1608
    gen_op_reset_scrfx();                                                     \
1609
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1610
    gen_op_f##name();                                                         \
1611
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1612
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1613
        gen_op_set_Rc1();                                                     \
1614
}
1615

    
1616
#define GEN_FLOAT_BS(name, op1, op2, type)                                    \
1617
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1618
{                                                                             \
1619
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1620
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1621
        return;                                                               \
1622
    }                                                                         \
1623
    gen_op_reset_scrfx();                                                     \
1624
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1625
    gen_op_f##name();                                                         \
1626
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1627
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1628
        gen_op_set_Rc1();                                                     \
1629
}
1630

    
1631
/* fadd - fadds */
1632
GEN_FLOAT_AB(add, 0x15, 0x000007C0);
1633
/* fdiv - fdivs */
1634
GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1635
/* fmul - fmuls */
1636
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1637

    
1638
/* fres */
1639
GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
1640

    
1641
/* frsqrte */
1642
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, PPC_FLOAT_FRSQRTE);
1643

    
1644
/* fsel */
1645
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, PPC_FLOAT_FSEL);
1646
/* fsub - fsubs */
1647
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1648
/* Optional: */
1649
/* fsqrt */
1650
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1651
{
1652
    if (unlikely(!ctx->fpu_enabled)) {
1653
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1654
        return;
1655
    }
1656
    gen_op_reset_scrfx();
1657
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1658
    gen_op_fsqrt();
1659
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1660
    if (unlikely(Rc(ctx->opcode) != 0))
1661
        gen_op_set_Rc1();
1662
}
1663

    
1664
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1665
{
1666
    if (unlikely(!ctx->fpu_enabled)) {
1667
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1668
        return;
1669
    }
1670
    gen_op_reset_scrfx();
1671
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1672
    gen_op_fsqrt();
1673
    gen_op_frsp();
1674
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1675
    if (unlikely(Rc(ctx->opcode) != 0))
1676
        gen_op_set_Rc1();
1677
}
1678

    
1679
/***                     Floating-Point multiply-and-add                   ***/
1680
/* fmadd - fmadds */
1681
GEN_FLOAT_ACB(madd, 0x1D, PPC_FLOAT);
1682
/* fmsub - fmsubs */
1683
GEN_FLOAT_ACB(msub, 0x1C, PPC_FLOAT);
1684
/* fnmadd - fnmadds */
1685
GEN_FLOAT_ACB(nmadd, 0x1F, PPC_FLOAT);
1686
/* fnmsub - fnmsubs */
1687
GEN_FLOAT_ACB(nmsub, 0x1E, PPC_FLOAT);
1688

    
1689
/***                     Floating-Point round & convert                    ***/
1690
/* fctiw */
1691
GEN_FLOAT_B(ctiw, 0x0E, 0x00, PPC_FLOAT);
1692
/* fctiwz */
1693
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, PPC_FLOAT);
1694
/* frsp */
1695
GEN_FLOAT_B(rsp, 0x0C, 0x00, PPC_FLOAT);
1696
#if defined(TARGET_PPC64)
1697
/* fcfid */
1698
GEN_FLOAT_B(cfid, 0x0E, 0x1A, PPC_64B);
1699
/* fctid */
1700
GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
1701
/* fctidz */
1702
GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
1703
#endif
1704

    
1705
/***                         Floating-Point compare                        ***/
1706
/* fcmpo */
1707
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1708
{
1709
    if (unlikely(!ctx->fpu_enabled)) {
1710
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1711
        return;
1712
    }
1713
    gen_op_reset_scrfx();
1714
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1715
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1716
    gen_op_fcmpo();
1717
    gen_op_store_T0_crf(crfD(ctx->opcode));
1718
}
1719

    
1720
/* fcmpu */
1721
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1722
{
1723
    if (unlikely(!ctx->fpu_enabled)) {
1724
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1725
        return;
1726
    }
1727
    gen_op_reset_scrfx();
1728
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1729
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1730
    gen_op_fcmpu();
1731
    gen_op_store_T0_crf(crfD(ctx->opcode));
1732
}
1733

    
1734
/***                         Floating-point move                           ***/
1735
/* fabs */
1736
GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT);
1737

    
1738
/* fmr  - fmr. */
1739
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1740
{
1741
    if (unlikely(!ctx->fpu_enabled)) {
1742
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1743
        return;
1744
    }
1745
    gen_op_reset_scrfx();
1746
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1747
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1748
    if (unlikely(Rc(ctx->opcode) != 0))
1749
        gen_op_set_Rc1();
1750
}
1751

    
1752
/* fnabs */
1753
GEN_FLOAT_B(nabs, 0x08, 0x04, PPC_FLOAT);
1754
/* fneg */
1755
GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT);
1756

    
1757
/***                  Floating-Point status & ctrl register                ***/
1758
/* mcrfs */
1759
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1760
{
1761
    if (unlikely(!ctx->fpu_enabled)) {
1762
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1763
        return;
1764
    }
1765
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
1766
    gen_op_store_T0_crf(crfD(ctx->opcode));
1767
    gen_op_clear_fpscr(crfS(ctx->opcode));
1768
}
1769

    
1770
/* mffs */
1771
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1772
{
1773
    if (unlikely(!ctx->fpu_enabled)) {
1774
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1775
        return;
1776
    }
1777
    gen_op_load_fpscr();
1778
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1779
    if (unlikely(Rc(ctx->opcode) != 0))
1780
        gen_op_set_Rc1();
1781
}
1782

    
1783
/* mtfsb0 */
1784
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1785
{
1786
    uint8_t crb;
1787

    
1788
    if (unlikely(!ctx->fpu_enabled)) {
1789
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1790
        return;
1791
    }
1792
    crb = crbD(ctx->opcode) >> 2;
1793
    gen_op_load_fpscr_T0(crb);
1794
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1795
    gen_op_store_T0_fpscr(crb);
1796
    if (unlikely(Rc(ctx->opcode) != 0))
1797
        gen_op_set_Rc1();
1798
}
1799

    
1800
/* mtfsb1 */
1801
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1802
{
1803
    uint8_t crb;
1804

    
1805
    if (unlikely(!ctx->fpu_enabled)) {
1806
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1807
        return;
1808
    }
1809
    crb = crbD(ctx->opcode) >> 2;
1810
    gen_op_load_fpscr_T0(crb);
1811
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1812
    gen_op_store_T0_fpscr(crb);
1813
    if (unlikely(Rc(ctx->opcode) != 0))
1814
        gen_op_set_Rc1();
1815
}
1816

    
1817
/* mtfsf */
1818
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1819
{
1820
    if (unlikely(!ctx->fpu_enabled)) {
1821
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1822
        return;
1823
    }
1824
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1825
    gen_op_store_fpscr(FM(ctx->opcode));
1826
    if (unlikely(Rc(ctx->opcode) != 0))
1827
        gen_op_set_Rc1();
1828
}
1829

    
1830
/* mtfsfi */
1831
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1832
{
1833
    if (unlikely(!ctx->fpu_enabled)) {
1834
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1835
        return;
1836
    }
1837
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1838
    if (unlikely(Rc(ctx->opcode) != 0))
1839
        gen_op_set_Rc1();
1840
}
1841

    
1842
/***                           Addressing modes                            ***/
1843
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1844
static inline void gen_addr_imm_index (DisasContext *ctx, int maskl)
1845
{
1846
    target_long simm = SIMM(ctx->opcode);
1847

    
1848
    if (maskl)
1849
        simm &= ~0x03;
1850
    if (rA(ctx->opcode) == 0) {
1851
        gen_set_T0(simm);
1852
    } else {
1853
        gen_op_load_gpr_T0(rA(ctx->opcode));
1854
        if (likely(simm != 0))
1855
            gen_op_addi(simm);
1856
    }
1857
#ifdef DEBUG_MEMORY_ACCESSES
1858
    gen_op_print_mem_EA();
1859
#endif
1860
}
1861

    
1862
static inline void gen_addr_reg_index (DisasContext *ctx)
1863
{
1864
    if (rA(ctx->opcode) == 0) {
1865
        gen_op_load_gpr_T0(rB(ctx->opcode));
1866
    } else {
1867
        gen_op_load_gpr_T0(rA(ctx->opcode));
1868
        gen_op_load_gpr_T1(rB(ctx->opcode));
1869
        gen_op_add();
1870
    }
1871
#ifdef DEBUG_MEMORY_ACCESSES
1872
    gen_op_print_mem_EA();
1873
#endif
1874
}
1875

    
1876
static inline void gen_addr_register (DisasContext *ctx)
1877
{
1878
    if (rA(ctx->opcode) == 0) {
1879
        gen_op_reset_T0();
1880
    } else {
1881
        gen_op_load_gpr_T0(rA(ctx->opcode));
1882
    }
1883
#ifdef DEBUG_MEMORY_ACCESSES
1884
    gen_op_print_mem_EA();
1885
#endif
1886
}
1887

    
1888
/***                             Integer load                              ***/
1889
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1890
#if defined(CONFIG_USER_ONLY)
1891
#if defined(TARGET_PPC64)
1892
#define OP_LD_TABLE(width)                                                    \
1893
static GenOpFunc *gen_op_l##width[] = {                                       \
1894
    &gen_op_l##width##_raw,                                                   \
1895
    &gen_op_l##width##_le_raw,                                                \
1896
    &gen_op_l##width##_64_raw,                                                \
1897
    &gen_op_l##width##_le_64_raw,                                             \
1898
};
1899
#define OP_ST_TABLE(width)                                                    \
1900
static GenOpFunc *gen_op_st##width[] = {                                      \
1901
    &gen_op_st##width##_raw,                                                  \
1902
    &gen_op_st##width##_le_raw,                                               \
1903
    &gen_op_st##width##_64_raw,                                               \
1904
    &gen_op_st##width##_le_64_raw,                                            \
1905
};
1906
/* Byte access routine are endian safe */
1907
#define gen_op_stb_le_64_raw gen_op_stb_64_raw
1908
#define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1909
#else
1910
#define OP_LD_TABLE(width)                                                    \
1911
static GenOpFunc *gen_op_l##width[] = {                                       \
1912
    &gen_op_l##width##_raw,                                                   \
1913
    &gen_op_l##width##_le_raw,                                                \
1914
};
1915
#define OP_ST_TABLE(width)                                                    \
1916
static GenOpFunc *gen_op_st##width[] = {                                      \
1917
    &gen_op_st##width##_raw,                                                  \
1918
    &gen_op_st##width##_le_raw,                                               \
1919
};
1920
#endif
1921
/* Byte access routine are endian safe */
1922
#define gen_op_stb_le_raw gen_op_stb_raw
1923
#define gen_op_lbz_le_raw gen_op_lbz_raw
1924
#else
1925
#if defined(TARGET_PPC64)
1926
#define OP_LD_TABLE(width)                                                    \
1927
static GenOpFunc *gen_op_l##width[] = {                                       \
1928
    &gen_op_l##width##_user,                                                  \
1929
    &gen_op_l##width##_le_user,                                               \
1930
    &gen_op_l##width##_kernel,                                                \
1931
    &gen_op_l##width##_le_kernel,                                             \
1932
    &gen_op_l##width##_64_user,                                               \
1933
    &gen_op_l##width##_le_64_user,                                            \
1934
    &gen_op_l##width##_64_kernel,                                             \
1935
    &gen_op_l##width##_le_64_kernel,                                          \
1936
};
1937
#define OP_ST_TABLE(width)                                                    \
1938
static GenOpFunc *gen_op_st##width[] = {                                      \
1939
    &gen_op_st##width##_user,                                                 \
1940
    &gen_op_st##width##_le_user,                                              \
1941
    &gen_op_st##width##_kernel,                                               \
1942
    &gen_op_st##width##_le_kernel,                                            \
1943
    &gen_op_st##width##_64_user,                                              \
1944
    &gen_op_st##width##_le_64_user,                                           \
1945
    &gen_op_st##width##_64_kernel,                                            \
1946
    &gen_op_st##width##_le_64_kernel,                                         \
1947
};
1948
/* Byte access routine are endian safe */
1949
#define gen_op_stb_le_64_user gen_op_stb_64_user
1950
#define gen_op_lbz_le_64_user gen_op_lbz_64_user
1951
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
1952
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
1953
#else
1954
#define OP_LD_TABLE(width)                                                    \
1955
static GenOpFunc *gen_op_l##width[] = {                                       \
1956
    &gen_op_l##width##_user,                                                  \
1957
    &gen_op_l##width##_le_user,                                               \
1958
    &gen_op_l##width##_kernel,                                                \
1959
    &gen_op_l##width##_le_kernel,                                             \
1960
};
1961
#define OP_ST_TABLE(width)                                                    \
1962
static GenOpFunc *gen_op_st##width[] = {                                      \
1963
    &gen_op_st##width##_user,                                                 \
1964
    &gen_op_st##width##_le_user,                                              \
1965
    &gen_op_st##width##_kernel,                                               \
1966
    &gen_op_st##width##_le_kernel,                                            \
1967
};
1968
#endif
1969
/* Byte access routine are endian safe */
1970
#define gen_op_stb_le_user gen_op_stb_user
1971
#define gen_op_lbz_le_user gen_op_lbz_user
1972
#define gen_op_stb_le_kernel gen_op_stb_kernel
1973
#define gen_op_lbz_le_kernel gen_op_lbz_kernel
1974
#endif
1975

    
1976
#define GEN_LD(width, opc, type)                                              \
1977
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
1978
{                                                                             \
1979
    gen_addr_imm_index(ctx, 0);                                               \
1980
    op_ldst(l##width);                                                        \
1981
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1982
}
1983

    
1984
#define GEN_LDU(width, opc, type)                                             \
1985
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
1986
{                                                                             \
1987
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1988
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1989
        RET_INVAL(ctx);                                                       \
1990
        return;                                                               \
1991
    }                                                                         \
1992
    if (type == PPC_64B)                                                      \
1993
        gen_addr_imm_index(ctx, 1);                                           \
1994
    else                                                                      \
1995
        gen_addr_imm_index(ctx, 0);                                           \
1996
    op_ldst(l##width);                                                        \
1997
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1998
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1999
}
2000

    
2001
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2002
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2003
{                                                                             \
2004
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2005
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2006
        RET_INVAL(ctx);                                                       \
2007
        return;                                                               \
2008
    }                                                                         \
2009
    gen_addr_reg_index(ctx);                                                  \
2010
    op_ldst(l##width);                                                        \
2011
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2012
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2013
}
2014

    
2015
#define GEN_LDX(width, opc2, opc3, type)                                      \
2016
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2017
{                                                                             \
2018
    gen_addr_reg_index(ctx);                                                  \
2019
    op_ldst(l##width);                                                        \
2020
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2021
}
2022

    
2023
#define GEN_LDS(width, op, type)                                              \
2024
OP_LD_TABLE(width);                                                           \
2025
GEN_LD(width, op | 0x20, type);                                               \
2026
GEN_LDU(width, op | 0x21, type);                                              \
2027
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2028
GEN_LDX(width, 0x17, op | 0x00, type)
2029

    
2030
/* lbz lbzu lbzux lbzx */
2031
GEN_LDS(bz, 0x02, PPC_INTEGER);
2032
/* lha lhau lhaux lhax */
2033
GEN_LDS(ha, 0x0A, PPC_INTEGER);
2034
/* lhz lhzu lhzux lhzx */
2035
GEN_LDS(hz, 0x08, PPC_INTEGER);
2036
/* lwz lwzu lwzux lwzx */
2037
GEN_LDS(wz, 0x00, PPC_INTEGER);
2038
#if defined(TARGET_PPC64)
2039
OP_LD_TABLE(wa);
2040
OP_LD_TABLE(d);
2041
/* lwaux */
2042
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
2043
/* lwax */
2044
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
2045
/* ldux */
2046
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
2047
/* ldx */
2048
GEN_LDX(d, 0x15, 0x00, PPC_64B);
2049
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2050
{
2051
    if (Rc(ctx->opcode)) {
2052
        if (unlikely(rA(ctx->opcode) == 0 ||
2053
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2054
            RET_INVAL(ctx);
2055
            return;
2056
        }
2057
    }
2058
    gen_addr_imm_index(ctx, 1);
2059
    if (ctx->opcode & 0x02) {
2060
        /* lwa (lwau is undefined) */
2061
        op_ldst(lwa);
2062
    } else {
2063
        /* ld - ldu */
2064
        op_ldst(ld);
2065
    }
2066
    gen_op_store_T1_gpr(rD(ctx->opcode));
2067
    if (Rc(ctx->opcode))
2068
        gen_op_store_T0_gpr(rA(ctx->opcode));
2069
}
2070
#endif
2071

    
2072
/***                              Integer store                            ***/
2073
#define GEN_ST(width, opc, type)                                              \
2074
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2075
{                                                                             \
2076
    gen_addr_imm_index(ctx, 0);                                               \
2077
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2078
    op_ldst(st##width);                                                       \
2079
}
2080

    
2081
#define GEN_STU(width, opc, type)                                             \
2082
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2083
{                                                                             \
2084
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2085
        RET_INVAL(ctx);                                                       \
2086
        return;                                                               \
2087
    }                                                                         \
2088
    if (type == PPC_64B)                                                      \
2089
        gen_addr_imm_index(ctx, 1);                                           \
2090
    else                                                                      \
2091
        gen_addr_imm_index(ctx, 0);                                           \
2092
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2093
    op_ldst(st##width);                                                       \
2094
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2095
}
2096

    
2097
#define GEN_STUX(width, opc2, opc3, type)                                     \
2098
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2099
{                                                                             \
2100
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2101
        RET_INVAL(ctx);                                                       \
2102
        return;                                                               \
2103
    }                                                                         \
2104
    gen_addr_reg_index(ctx);                                                  \
2105
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2106
    op_ldst(st##width);                                                       \
2107
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2108
}
2109

    
2110
#define GEN_STX(width, opc2, opc3, type)                                      \
2111
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2112
{                                                                             \
2113
    gen_addr_reg_index(ctx);                                                  \
2114
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2115
    op_ldst(st##width);                                                       \
2116
}
2117

    
2118
#define GEN_STS(width, op, type)                                              \
2119
OP_ST_TABLE(width);                                                           \
2120
GEN_ST(width, op | 0x20, type);                                               \
2121
GEN_STU(width, op | 0x21, type);                                              \
2122
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2123
GEN_STX(width, 0x17, op | 0x00, type)
2124

    
2125
/* stb stbu stbux stbx */
2126
GEN_STS(b, 0x06, PPC_INTEGER);
2127
/* sth sthu sthux sthx */
2128
GEN_STS(h, 0x0C, PPC_INTEGER);
2129
/* stw stwu stwux stwx */
2130
GEN_STS(w, 0x04, PPC_INTEGER);
2131
#if defined(TARGET_PPC64)
2132
OP_ST_TABLE(d);
2133
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2134
GEN_STX(d, 0x15, 0x04, PPC_64B);
2135
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
2136
{
2137
    if (Rc(ctx->opcode)) {
2138
        if (unlikely(rA(ctx->opcode) == 0)) {
2139
            RET_INVAL(ctx);
2140
            return;
2141
        }
2142
    }
2143
    gen_addr_imm_index(ctx, 1);
2144
    gen_op_load_gpr_T1(rS(ctx->opcode));
2145
    op_ldst(std);
2146
    if (Rc(ctx->opcode))
2147
        gen_op_store_T0_gpr(rA(ctx->opcode));
2148
}
2149
#endif
2150
/***                Integer load and store with byte reverse               ***/
2151
/* lhbrx */
2152
OP_LD_TABLE(hbr);
2153
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2154
/* lwbrx */
2155
OP_LD_TABLE(wbr);
2156
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2157
/* sthbrx */
2158
OP_ST_TABLE(hbr);
2159
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2160
/* stwbrx */
2161
OP_ST_TABLE(wbr);
2162
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2163

    
2164
/***                    Integer load and store multiple                    ***/
2165
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2166
#if defined(TARGET_PPC64)
2167
#if defined(CONFIG_USER_ONLY)
2168
static GenOpFunc1 *gen_op_lmw[] = {
2169
    &gen_op_lmw_raw,
2170
    &gen_op_lmw_le_raw,
2171
    &gen_op_lmw_64_raw,
2172
    &gen_op_lmw_le_64_raw,
2173
};
2174
static GenOpFunc1 *gen_op_stmw[] = {
2175
    &gen_op_stmw_64_raw,
2176
    &gen_op_stmw_le_64_raw,
2177
};
2178
#else
2179
static GenOpFunc1 *gen_op_lmw[] = {
2180
    &gen_op_lmw_user,
2181
    &gen_op_lmw_le_user,
2182
    &gen_op_lmw_kernel,
2183
    &gen_op_lmw_le_kernel,
2184
    &gen_op_lmw_64_user,
2185
    &gen_op_lmw_le_64_user,
2186
    &gen_op_lmw_64_kernel,
2187
    &gen_op_lmw_le_64_kernel,
2188
};
2189
static GenOpFunc1 *gen_op_stmw[] = {
2190
    &gen_op_stmw_user,
2191
    &gen_op_stmw_le_user,
2192
    &gen_op_stmw_kernel,
2193
    &gen_op_stmw_le_kernel,
2194
    &gen_op_stmw_64_user,
2195
    &gen_op_stmw_le_64_user,
2196
    &gen_op_stmw_64_kernel,
2197
    &gen_op_stmw_le_64_kernel,
2198
};
2199
#endif
2200
#else
2201
#if defined(CONFIG_USER_ONLY)
2202
static GenOpFunc1 *gen_op_lmw[] = {
2203
    &gen_op_lmw_raw,
2204
    &gen_op_lmw_le_raw,
2205
};
2206
static GenOpFunc1 *gen_op_stmw[] = {
2207
    &gen_op_stmw_raw,
2208
    &gen_op_stmw_le_raw,
2209
};
2210
#else
2211
static GenOpFunc1 *gen_op_lmw[] = {
2212
    &gen_op_lmw_user,
2213
    &gen_op_lmw_le_user,
2214
    &gen_op_lmw_kernel,
2215
    &gen_op_lmw_le_kernel,
2216
};
2217
static GenOpFunc1 *gen_op_stmw[] = {
2218
    &gen_op_stmw_user,
2219
    &gen_op_stmw_le_user,
2220
    &gen_op_stmw_kernel,
2221
    &gen_op_stmw_le_kernel,
2222
};
2223
#endif
2224
#endif
2225

    
2226
/* lmw */
2227
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2228
{
2229
    /* NIP cannot be restored if the memory exception comes from an helper */
2230
    gen_update_nip(ctx, ctx->nip - 4);
2231
    gen_addr_imm_index(ctx, 0);
2232
    op_ldstm(lmw, rD(ctx->opcode));
2233
}
2234

    
2235
/* stmw */
2236
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2237
{
2238
    /* NIP cannot be restored if the memory exception comes from an helper */
2239
    gen_update_nip(ctx, ctx->nip - 4);
2240
    gen_addr_imm_index(ctx, 0);
2241
    op_ldstm(stmw, rS(ctx->opcode));
2242
}
2243

    
2244
/***                    Integer load and store strings                     ***/
2245
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2246
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2247
#if defined(TARGET_PPC64)
2248
#if defined(CONFIG_USER_ONLY)
2249
static GenOpFunc1 *gen_op_lswi[] = {
2250
    &gen_op_lswi_raw,
2251
    &gen_op_lswi_le_raw,
2252
    &gen_op_lswi_64_raw,
2253
    &gen_op_lswi_le_64_raw,
2254
};
2255
static GenOpFunc3 *gen_op_lswx[] = {
2256
    &gen_op_lswx_raw,
2257
    &gen_op_lswx_le_raw,
2258
    &gen_op_lswx_64_raw,
2259
    &gen_op_lswx_le_64_raw,
2260
};
2261
static GenOpFunc1 *gen_op_stsw[] = {
2262
    &gen_op_stsw_raw,
2263
    &gen_op_stsw_le_raw,
2264
    &gen_op_stsw_64_raw,
2265
    &gen_op_stsw_le_64_raw,
2266
};
2267
#else
2268
static GenOpFunc1 *gen_op_lswi[] = {
2269
    &gen_op_lswi_user,
2270
    &gen_op_lswi_le_user,
2271
    &gen_op_lswi_kernel,
2272
    &gen_op_lswi_le_kernel,
2273
    &gen_op_lswi_64_user,
2274
    &gen_op_lswi_le_64_user,
2275
    &gen_op_lswi_64_kernel,
2276
    &gen_op_lswi_le_64_kernel,
2277
};
2278
static GenOpFunc3 *gen_op_lswx[] = {
2279
    &gen_op_lswx_user,
2280
    &gen_op_lswx_le_user,
2281
    &gen_op_lswx_kernel,
2282
    &gen_op_lswx_le_kernel,
2283
    &gen_op_lswx_64_user,
2284
    &gen_op_lswx_le_64_user,
2285
    &gen_op_lswx_64_kernel,
2286
    &gen_op_lswx_le_64_kernel,
2287
};
2288
static GenOpFunc1 *gen_op_stsw[] = {
2289
    &gen_op_stsw_user,
2290
    &gen_op_stsw_le_user,
2291
    &gen_op_stsw_kernel,
2292
    &gen_op_stsw_le_kernel,
2293
    &gen_op_stsw_64_user,
2294
    &gen_op_stsw_le_64_user,
2295
    &gen_op_stsw_64_kernel,
2296
    &gen_op_stsw_le_64_kernel,
2297
};
2298
#endif
2299
#else
2300
#if defined(CONFIG_USER_ONLY)
2301
static GenOpFunc1 *gen_op_lswi[] = {
2302
    &gen_op_lswi_raw,
2303
    &gen_op_lswi_le_raw,
2304
};
2305
static GenOpFunc3 *gen_op_lswx[] = {
2306
    &gen_op_lswx_raw,
2307
    &gen_op_lswx_le_raw,
2308
};
2309
static GenOpFunc1 *gen_op_stsw[] = {
2310
    &gen_op_stsw_raw,
2311
    &gen_op_stsw_le_raw,
2312
};
2313
#else
2314
static GenOpFunc1 *gen_op_lswi[] = {
2315
    &gen_op_lswi_user,
2316
    &gen_op_lswi_le_user,
2317
    &gen_op_lswi_kernel,
2318
    &gen_op_lswi_le_kernel,
2319
};
2320
static GenOpFunc3 *gen_op_lswx[] = {
2321
    &gen_op_lswx_user,
2322
    &gen_op_lswx_le_user,
2323
    &gen_op_lswx_kernel,
2324
    &gen_op_lswx_le_kernel,
2325
};
2326
static GenOpFunc1 *gen_op_stsw[] = {
2327
    &gen_op_stsw_user,
2328
    &gen_op_stsw_le_user,
2329
    &gen_op_stsw_kernel,
2330
    &gen_op_stsw_le_kernel,
2331
};
2332
#endif
2333
#endif
2334

    
2335
/* lswi */
2336
/* PowerPC32 specification says we must generate an exception if
2337
 * rA is in the range of registers to be loaded.
2338
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2339
 * For now, I'll follow the spec...
2340
 */
2341
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
2342
{
2343
    int nb = NB(ctx->opcode);
2344
    int start = rD(ctx->opcode);
2345
    int ra = rA(ctx->opcode);
2346
    int nr;
2347

    
2348
    if (nb == 0)
2349
        nb = 32;
2350
    nr = nb / 4;
2351
    if (unlikely(((start + nr) > 32  &&
2352
                  start <= ra && (start + nr - 32) > ra) ||
2353
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2354
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
2355
        return;
2356
    }
2357
    /* NIP cannot be restored if the memory exception comes from an helper */
2358
    gen_update_nip(ctx, ctx->nip - 4);
2359
    gen_addr_register(ctx);
2360
    gen_op_set_T1(nb);
2361
    op_ldsts(lswi, start);
2362
}
2363

    
2364
/* lswx */
2365
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
2366
{
2367
    int ra = rA(ctx->opcode);
2368
    int rb = rB(ctx->opcode);
2369

    
2370
    /* NIP cannot be restored if the memory exception comes from an helper */
2371
    gen_update_nip(ctx, ctx->nip - 4);
2372
    gen_addr_reg_index(ctx);
2373
    if (ra == 0) {
2374
        ra = rb;
2375
    }
2376
    gen_op_load_xer_bc();
2377
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2378
}
2379

    
2380
/* stswi */
2381
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
2382
{
2383
    int nb = NB(ctx->opcode);
2384

    
2385
    /* NIP cannot be restored if the memory exception comes from an helper */
2386
    gen_update_nip(ctx, ctx->nip - 4);
2387
    gen_addr_register(ctx);
2388
    if (nb == 0)
2389
        nb = 32;
2390
    gen_op_set_T1(nb);
2391
    op_ldsts(stsw, rS(ctx->opcode));
2392
}
2393

    
2394
/* stswx */
2395
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
2396
{
2397
    /* NIP cannot be restored if the memory exception comes from an helper */
2398
    gen_update_nip(ctx, ctx->nip - 4);
2399
    gen_addr_reg_index(ctx);
2400
    gen_op_load_xer_bc();
2401
    op_ldsts(stsw, rS(ctx->opcode));
2402
}
2403

    
2404
/***                        Memory synchronisation                         ***/
2405
/* eieio */
2406
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
2407
{
2408
}
2409

    
2410
/* isync */
2411
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
2412
{
2413
}
2414

    
2415
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2416
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2417
#if defined(TARGET_PPC64)
2418
#if defined(CONFIG_USER_ONLY)
2419
static GenOpFunc *gen_op_lwarx[] = {
2420
    &gen_op_lwarx_raw,
2421
    &gen_op_lwarx_le_raw,
2422
    &gen_op_lwarx_64_raw,
2423
    &gen_op_lwarx_le_64_raw,
2424
};
2425
static GenOpFunc *gen_op_stwcx[] = {
2426
    &gen_op_stwcx_raw,
2427
    &gen_op_stwcx_le_raw,
2428
    &gen_op_stwcx_64_raw,
2429
    &gen_op_stwcx_le_64_raw,
2430
};
2431
#else
2432
static GenOpFunc *gen_op_lwarx[] = {
2433
    &gen_op_lwarx_user,
2434
    &gen_op_lwarx_le_user,
2435
    &gen_op_lwarx_kernel,
2436
    &gen_op_lwarx_le_kernel,
2437
    &gen_op_lwarx_64_user,
2438
    &gen_op_lwarx_le_64_user,
2439
    &gen_op_lwarx_64_kernel,
2440
    &gen_op_lwarx_le_64_kernel,
2441
};
2442
static GenOpFunc *gen_op_stwcx[] = {
2443
    &gen_op_stwcx_user,
2444
    &gen_op_stwcx_le_user,
2445
    &gen_op_stwcx_kernel,
2446
    &gen_op_stwcx_le_kernel,
2447
    &gen_op_stwcx_64_user,
2448
    &gen_op_stwcx_le_64_user,
2449
    &gen_op_stwcx_64_kernel,
2450
    &gen_op_stwcx_le_64_kernel,
2451
};
2452
#endif
2453
#else
2454
#if defined(CONFIG_USER_ONLY)
2455
static GenOpFunc *gen_op_lwarx[] = {
2456
    &gen_op_lwarx_raw,
2457
    &gen_op_lwarx_le_raw,
2458
};
2459
static GenOpFunc *gen_op_stwcx[] = {
2460
    &gen_op_stwcx_raw,
2461
    &gen_op_stwcx_le_raw,
2462
};
2463
#else
2464
static GenOpFunc *gen_op_lwarx[] = {
2465
    &gen_op_lwarx_user,
2466
    &gen_op_lwarx_le_user,
2467
    &gen_op_lwarx_kernel,
2468
    &gen_op_lwarx_le_kernel,
2469
};
2470
static GenOpFunc *gen_op_stwcx[] = {
2471
    &gen_op_stwcx_user,
2472
    &gen_op_stwcx_le_user,
2473
    &gen_op_stwcx_kernel,
2474
    &gen_op_stwcx_le_kernel,
2475
};
2476
#endif
2477
#endif
2478

    
2479
/* lwarx */
2480
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2481
{
2482
    gen_addr_reg_index(ctx);
2483
    op_lwarx();
2484
    gen_op_store_T1_gpr(rD(ctx->opcode));
2485
}
2486

    
2487
/* stwcx. */
2488
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2489
{
2490
    gen_addr_reg_index(ctx);
2491
    gen_op_load_gpr_T1(rS(ctx->opcode));
2492
    op_stwcx();
2493
}
2494

    
2495
#if defined(TARGET_PPC64)
2496
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2497
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2498
#if defined(CONFIG_USER_ONLY)
2499
static GenOpFunc *gen_op_ldarx[] = {
2500
    &gen_op_ldarx_raw,
2501
    &gen_op_ldarx_le_raw,
2502
    &gen_op_ldarx_64_raw,
2503
    &gen_op_ldarx_le_64_raw,
2504
};
2505
static GenOpFunc *gen_op_stdcx[] = {
2506
    &gen_op_stdcx_raw,
2507
    &gen_op_stdcx_le_raw,
2508
    &gen_op_stdcx_64_raw,
2509
    &gen_op_stdcx_le_64_raw,
2510
};
2511
#else
2512
static GenOpFunc *gen_op_ldarx[] = {
2513
    &gen_op_ldarx_user,
2514
    &gen_op_ldarx_le_user,
2515
    &gen_op_ldarx_kernel,
2516
    &gen_op_ldarx_le_kernel,
2517
    &gen_op_ldarx_64_user,
2518
    &gen_op_ldarx_le_64_user,
2519
    &gen_op_ldarx_64_kernel,
2520
    &gen_op_ldarx_le_64_kernel,
2521
};
2522
static GenOpFunc *gen_op_stdcx[] = {
2523
    &gen_op_stdcx_user,
2524
    &gen_op_stdcx_le_user,
2525
    &gen_op_stdcx_kernel,
2526
    &gen_op_stdcx_le_kernel,
2527
    &gen_op_stdcx_64_user,
2528
    &gen_op_stdcx_le_64_user,
2529
    &gen_op_stdcx_64_kernel,
2530
    &gen_op_stdcx_le_64_kernel,
2531
};
2532
#endif
2533

    
2534
/* ldarx */
2535
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2536
{
2537
    gen_addr_reg_index(ctx);
2538
    op_ldarx();
2539
    gen_op_store_T1_gpr(rD(ctx->opcode));
2540
}
2541

    
2542
/* stdcx. */
2543
GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2544
{
2545
    gen_addr_reg_index(ctx);
2546
    gen_op_load_gpr_T1(rS(ctx->opcode));
2547
    op_stdcx();
2548
}
2549
#endif /* defined(TARGET_PPC64) */
2550

    
2551
/* sync */
2552
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
2553
{
2554
}
2555

    
2556
/***                         Floating-point load                           ***/
2557
#define GEN_LDF(width, opc)                                                   \
2558
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                 \
2559
{                                                                             \
2560
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2561
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2562
        return;                                                               \
2563
    }                                                                         \
2564
    gen_addr_imm_index(ctx, 0);                                               \
2565
    op_ldst(l##width);                                                        \
2566
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2567
}
2568

    
2569
#define GEN_LDUF(width, opc)                                                  \
2570
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)              \
2571
{                                                                             \
2572
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2573
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2574
        return;                                                               \
2575
    }                                                                         \
2576
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2577
        RET_INVAL(ctx);                                                       \
2578
        return;                                                               \
2579
    }                                                                         \
2580
    gen_addr_imm_index(ctx, 0);                                               \
2581
    op_ldst(l##width);                                                        \
2582
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2583
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2584
}
2585

    
2586
#define GEN_LDUXF(width, opc)                                                 \
2587
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
2588
{                                                                             \
2589
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2590
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2591
        return;                                                               \
2592
    }                                                                         \
2593
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2594
        RET_INVAL(ctx);                                                       \
2595
        return;                                                               \
2596
    }                                                                         \
2597
    gen_addr_reg_index(ctx);                                                  \
2598
    op_ldst(l##width);                                                        \
2599
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2600
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2601
}
2602

    
2603
#define GEN_LDXF(width, opc2, opc3)                                           \
2604
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)             \
2605
{                                                                             \
2606
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2607
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2608
        return;                                                               \
2609
    }                                                                         \
2610
    gen_addr_reg_index(ctx);                                                  \
2611
    op_ldst(l##width);                                                        \
2612
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2613
}
2614

    
2615
#define GEN_LDFS(width, op)                                                   \
2616
OP_LD_TABLE(width);                                                           \
2617
GEN_LDF(width, op | 0x20);                                                    \
2618
GEN_LDUF(width, op | 0x21);                                                   \
2619
GEN_LDUXF(width, op | 0x01);                                                  \
2620
GEN_LDXF(width, 0x17, op | 0x00)
2621

    
2622
/* lfd lfdu lfdux lfdx */
2623
GEN_LDFS(fd, 0x12);
2624
/* lfs lfsu lfsux lfsx */
2625
GEN_LDFS(fs, 0x10);
2626

    
2627
/***                         Floating-point store                          ***/
2628
#define GEN_STF(width, opc)                                                   \
2629
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
2630
{                                                                             \
2631
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2632
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2633
        return;                                                               \
2634
    }                                                                         \
2635
    gen_addr_imm_index(ctx, 0);                                               \
2636
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2637
    op_ldst(st##width);                                                       \
2638
}
2639

    
2640
#define GEN_STUF(width, opc)                                                  \
2641
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
2642
{                                                                             \
2643
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2644
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2645
        return;                                                               \
2646
    }                                                                         \
2647
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2648
        RET_INVAL(ctx);                                                       \
2649
        return;                                                               \
2650
    }                                                                         \
2651
    gen_addr_imm_index(ctx, 0);                                               \
2652
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2653
    op_ldst(st##width);                                                       \
2654
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2655
}
2656

    
2657
#define GEN_STUXF(width, opc)                                                 \
2658
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
2659
{                                                                             \
2660
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2661
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2662
        return;                                                               \
2663
    }                                                                         \
2664
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2665
        RET_INVAL(ctx);                                                       \
2666
        return;                                                               \
2667
    }                                                                         \
2668
    gen_addr_reg_index(ctx);                                                  \
2669
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2670
    op_ldst(st##width);                                                       \
2671
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2672
}
2673

    
2674
#define GEN_STXF(width, opc2, opc3)                                           \
2675
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)            \
2676
{                                                                             \
2677
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2678
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2679
        return;                                                               \
2680
    }                                                                         \
2681
    gen_addr_reg_index(ctx);                                                  \
2682
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2683
    op_ldst(st##width);                                                       \
2684
}
2685

    
2686
#define GEN_STFS(width, op)                                                   \
2687
OP_ST_TABLE(width);                                                           \
2688
GEN_STF(width, op | 0x20);                                                    \
2689
GEN_STUF(width, op | 0x21);                                                   \
2690
GEN_STUXF(width, op | 0x01);                                                  \
2691
GEN_STXF(width, 0x17, op | 0x00)
2692

    
2693
/* stfd stfdu stfdux stfdx */
2694
GEN_STFS(fd, 0x16);
2695
/* stfs stfsu stfsux stfsx */
2696
GEN_STFS(fs, 0x14);
2697

    
2698
/* Optional: */
2699
/* stfiwx */
2700
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT_STFIWX)
2701
{
2702
    if (unlikely(!ctx->fpu_enabled)) {
2703
        RET_EXCP(ctx, EXCP_NO_FP, 0);
2704
        return;
2705
    }
2706
    gen_addr_reg_index(ctx);
2707
    /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2708
    RET_INVAL(ctx);
2709
}
2710

    
2711
/***                                Branch                                 ***/
2712
static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
2713
{
2714
    TranslationBlock *tb;
2715
    tb = ctx->tb;
2716
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2717
        if (n == 0)
2718
            gen_op_goto_tb0(TBPARAM(tb));
2719
        else
2720
            gen_op_goto_tb1(TBPARAM(tb));
2721
        gen_set_T1(dest);
2722
#if defined(TARGET_PPC64)
2723
        if (ctx->sf_mode)
2724
            gen_op_b_T1_64();
2725
        else
2726
#endif
2727
            gen_op_b_T1();
2728
        gen_op_set_T0((long)tb + n);
2729
        if (ctx->singlestep_enabled)
2730
            gen_op_debug();
2731
        gen_op_exit_tb();
2732
    } else {
2733
        gen_set_T1(dest);
2734
#if defined(TARGET_PPC64)
2735
        if (ctx->sf_mode)
2736
            gen_op_b_T1_64();
2737
        else
2738
#endif
2739
            gen_op_b_T1();
2740
        gen_op_reset_T0();
2741
        if (ctx->singlestep_enabled)
2742
            gen_op_debug();
2743
        gen_op_exit_tb();
2744
    }
2745
}
2746

    
2747
/* b ba bl bla */
2748
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2749
{
2750
    target_ulong li, target;
2751

    
2752
    /* sign extend LI */
2753
#if defined(TARGET_PPC64)
2754
    if (ctx->sf_mode)
2755
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2756
    else
2757
#endif
2758
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2759
    if (likely(AA(ctx->opcode) == 0))
2760
        target = ctx->nip + li - 4;
2761
    else
2762
        target = li;
2763
    if (LK(ctx->opcode)) {
2764
#if defined(TARGET_PPC64)
2765
        if (ctx->sf_mode)
2766
            gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2767
        else
2768
#endif
2769
            gen_op_setlr(ctx->nip);
2770
    }
2771
    gen_goto_tb(ctx, 0, target);
2772
    ctx->exception = EXCP_BRANCH;
2773
}
2774

    
2775
#define BCOND_IM  0
2776
#define BCOND_LR  1
2777
#define BCOND_CTR 2
2778

    
2779
static inline void gen_bcond (DisasContext *ctx, int type)
2780
{
2781
    target_ulong target = 0;
2782
    target_ulong li;
2783
    uint32_t bo = BO(ctx->opcode);
2784
    uint32_t bi = BI(ctx->opcode);
2785
    uint32_t mask;
2786

    
2787
    if ((bo & 0x4) == 0)
2788
        gen_op_dec_ctr();
2789
    switch(type) {
2790
    case BCOND_IM:
2791
        li = (target_long)((int16_t)(BD(ctx->opcode)));
2792
        if (likely(AA(ctx->opcode) == 0)) {
2793
            target = ctx->nip + li - 4;
2794
        } else {
2795
            target = li;
2796
        }
2797
        break;
2798
    case BCOND_CTR:
2799
        gen_op_movl_T1_ctr();
2800
        break;
2801
    default:
2802
    case BCOND_LR:
2803
        gen_op_movl_T1_lr();
2804
        break;
2805
    }
2806
    if (LK(ctx->opcode)) {
2807
#if defined(TARGET_PPC64)
2808
        if (ctx->sf_mode)
2809
            gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2810
        else
2811
#endif
2812
            gen_op_setlr(ctx->nip);
2813
    }
2814
    if (bo & 0x10) {
2815
        /* No CR condition */
2816
        switch (bo & 0x6) {
2817
        case 0:
2818
#if defined(TARGET_PPC64)
2819
            if (ctx->sf_mode)
2820
                gen_op_test_ctr_64();
2821
            else
2822
#endif
2823
                gen_op_test_ctr();
2824
            break;
2825
        case 2:
2826
#if defined(TARGET_PPC64)
2827
            if (ctx->sf_mode)
2828
                gen_op_test_ctrz_64();
2829
            else
2830
#endif
2831
                gen_op_test_ctrz();
2832
            break;
2833
        default:
2834
        case 4:
2835
        case 6:
2836
            if (type == BCOND_IM) {
2837
                gen_goto_tb(ctx, 0, target);
2838
            } else {
2839
#if defined(TARGET_PPC64)
2840
                if (ctx->sf_mode)
2841
                    gen_op_b_T1_64();
2842
                else
2843
#endif
2844
                    gen_op_b_T1();
2845
                gen_op_reset_T0();
2846
            }
2847
            goto no_test;
2848
        }
2849
    } else {
2850
        mask = 1 << (3 - (bi & 0x03));
2851
        gen_op_load_crf_T0(bi >> 2);
2852
        if (bo & 0x8) {
2853
            switch (bo & 0x6) {
2854
            case 0:
2855
#if defined(TARGET_PPC64)
2856
                if (ctx->sf_mode)
2857
                    gen_op_test_ctr_true_64(mask);
2858
                else
2859
#endif
2860
                    gen_op_test_ctr_true(mask);
2861
                break;
2862
            case 2:
2863
#if defined(TARGET_PPC64)
2864
                if (ctx->sf_mode)
2865
                    gen_op_test_ctrz_true_64(mask);
2866
                else
2867
#endif
2868
                    gen_op_test_ctrz_true(mask);
2869
                break;
2870
            default:
2871
            case 4:
2872
            case 6:
2873
                gen_op_test_true(mask);
2874
                break;
2875
            }
2876
        } else {
2877
            switch (bo & 0x6) {
2878
            case 0:
2879
#if defined(TARGET_PPC64)
2880
                if (ctx->sf_mode)
2881
                    gen_op_test_ctr_false_64(mask);
2882
                else
2883
#endif
2884
                    gen_op_test_ctr_false(mask);
2885
                break;
2886
            case 2:
2887
#if defined(TARGET_PPC64)
2888
                if (ctx->sf_mode)
2889
                    gen_op_test_ctrz_false_64(mask);
2890
                else
2891
#endif
2892
                    gen_op_test_ctrz_false(mask);
2893
                break;
2894
            default:
2895
            case 4:
2896
            case 6:
2897
                gen_op_test_false(mask);
2898
                break;
2899
            }
2900
        }
2901
    }
2902
    if (type == BCOND_IM) {
2903
        int l1 = gen_new_label();
2904
        gen_op_jz_T0(l1);
2905
        gen_goto_tb(ctx, 0, target);
2906
        gen_set_label(l1);
2907
        gen_goto_tb(ctx, 1, ctx->nip);
2908
    } else {
2909
#if defined(TARGET_PPC64)
2910
        if (ctx->sf_mode)
2911
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
2912
        else
2913
#endif
2914
            gen_op_btest_T1(ctx->nip);
2915
        gen_op_reset_T0();
2916
    no_test:
2917
        if (ctx->singlestep_enabled)
2918
            gen_op_debug();
2919
        gen_op_exit_tb();
2920
    }
2921
    ctx->exception = EXCP_BRANCH;
2922
}
2923

    
2924
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2925
{
2926
    gen_bcond(ctx, BCOND_IM);
2927
}
2928

    
2929
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
2930
{
2931
    gen_bcond(ctx, BCOND_CTR);
2932
}
2933

    
2934
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
2935
{
2936
    gen_bcond(ctx, BCOND_LR);
2937
}
2938

    
2939
/***                      Condition register logical                       ***/
2940
#define GEN_CRLOGIC(op, opc)                                                  \
2941
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
2942
{                                                                             \
2943
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
2944
    gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
2945
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
2946
    gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
2947
    gen_op_##op();                                                            \
2948
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
2949
    gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
2950
                     3 - (crbD(ctx->opcode) & 0x03));                         \
2951
    gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
2952
}
2953

    
2954
/* crand */
2955
GEN_CRLOGIC(and, 0x08);
2956
/* crandc */
2957
GEN_CRLOGIC(andc, 0x04);
2958
/* creqv */
2959
GEN_CRLOGIC(eqv, 0x09);
2960
/* crnand */
2961
GEN_CRLOGIC(nand, 0x07);
2962
/* crnor */
2963
GEN_CRLOGIC(nor, 0x01);
2964
/* cror */
2965
GEN_CRLOGIC(or, 0x0E);
2966
/* crorc */
2967
GEN_CRLOGIC(orc, 0x0D);
2968
/* crxor */
2969
GEN_CRLOGIC(xor, 0x06);
2970
/* mcrf */
2971
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
2972
{
2973
    gen_op_load_crf_T0(crfS(ctx->opcode));
2974
    gen_op_store_T0_crf(crfD(ctx->opcode));
2975
}
2976

    
2977
/***                           System linkage                              ***/
2978
/* rfi (supervisor only) */
2979
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
2980
{
2981
#if defined(CONFIG_USER_ONLY)
2982
    RET_PRIVOPC(ctx);
2983
#else
2984
    /* Restore CPU state */
2985
    if (unlikely(!ctx->supervisor)) {
2986
        RET_PRIVOPC(ctx);
2987
        return;
2988
    }
2989
    gen_op_rfi();
2990
    RET_CHG_FLOW(ctx);
2991
#endif
2992
}
2993

    
2994
#if defined(TARGET_PPC64)
2995
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
2996
{
2997
#if defined(CONFIG_USER_ONLY)
2998
    RET_PRIVOPC(ctx);
2999
#else
3000
    /* Restore CPU state */
3001
    if (unlikely(!ctx->supervisor)) {
3002
        RET_PRIVOPC(ctx);
3003
        return;
3004
    }
3005
    gen_op_rfid();
3006
    RET_CHG_FLOW(ctx);
3007
#endif
3008
}
3009
#endif
3010

    
3011
/* sc */
3012
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
3013
{
3014
#if defined(CONFIG_USER_ONLY)
3015
    RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
3016
#else
3017
    RET_EXCP(ctx, EXCP_SYSCALL, 0);
3018
#endif
3019
}
3020

    
3021
/***                                Trap                                   ***/
3022
/* tw */
3023
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3024
{
3025
    gen_op_load_gpr_T0(rA(ctx->opcode));
3026
    gen_op_load_gpr_T1(rB(ctx->opcode));
3027
    /* Update the nip since this might generate a trap exception */
3028
    gen_update_nip(ctx, ctx->nip);
3029
    gen_op_tw(TO(ctx->opcode));
3030
}
3031

    
3032
/* twi */
3033
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3034
{
3035
    gen_op_load_gpr_T0(rA(ctx->opcode));
3036
    gen_set_T1(SIMM(ctx->opcode));
3037
    /* Update the nip since this might generate a trap exception */
3038
    gen_update_nip(ctx, ctx->nip);
3039
    gen_op_tw(TO(ctx->opcode));
3040
}
3041

    
3042
#if defined(TARGET_PPC64)
3043
/* td */
3044
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3045
{
3046
    gen_op_load_gpr_T0(rA(ctx->opcode));
3047
    gen_op_load_gpr_T1(rB(ctx->opcode));
3048
    /* Update the nip since this might generate a trap exception */
3049
    gen_update_nip(ctx, ctx->nip);
3050
    gen_op_td(TO(ctx->opcode));
3051
}
3052

    
3053
/* tdi */
3054
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3055
{
3056
    gen_op_load_gpr_T0(rA(ctx->opcode));
3057
    gen_set_T1(SIMM(ctx->opcode));
3058
    /* Update the nip since this might generate a trap exception */
3059
    gen_update_nip(ctx, ctx->nip);
3060
    gen_op_td(TO(ctx->opcode));
3061
}
3062
#endif
3063

    
3064
/***                          Processor control                            ***/
3065
/* mcrxr */
3066
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3067
{
3068
    gen_op_load_xer_cr();
3069
    gen_op_store_T0_crf(crfD(ctx->opcode));
3070
    gen_op_clear_xer_ov();
3071
    gen_op_clear_xer_ca();
3072
}
3073

    
3074
/* mfcr */
3075
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3076
{
3077
    uint32_t crm, crn;
3078

    
3079
    if (likely(ctx->opcode & 0x00100000)) {
3080
        crm = CRM(ctx->opcode);
3081
        if (likely((crm ^ (crm - 1)) == 0)) {
3082
            crn = ffs(crm);
3083
            gen_op_load_cro(7 - crn);
3084
        }
3085
    } else {
3086
        gen_op_load_cr();
3087
    }
3088
    gen_op_store_T0_gpr(rD(ctx->opcode));
3089
}
3090

    
3091
/* mfmsr */
3092
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3093
{
3094
#if defined(CONFIG_USER_ONLY)
3095
    RET_PRIVREG(ctx);
3096
#else
3097
    if (unlikely(!ctx->supervisor)) {
3098
        RET_PRIVREG(ctx);
3099
        return;
3100
    }
3101
    gen_op_load_msr();
3102
    gen_op_store_T0_gpr(rD(ctx->opcode));
3103
#endif
3104
}
3105

    
3106
#if 0
3107
#define SPR_NOACCESS ((void *)(-1))
3108
#else
3109
static void spr_noaccess (void *opaque, int sprn)
3110
{
3111
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3112
    printf("ERROR: try to access SPR %d !\n", sprn);
3113
}
3114
#define SPR_NOACCESS (&spr_noaccess)
3115
#endif
3116

    
3117
/* mfspr */
3118
static inline void gen_op_mfspr (DisasContext *ctx)
3119
{
3120
    void (*read_cb)(void *opaque, int sprn);
3121
    uint32_t sprn = SPR(ctx->opcode);
3122

    
3123
#if !defined(CONFIG_USER_ONLY)
3124
    if (ctx->supervisor)
3125
        read_cb = ctx->spr_cb[sprn].oea_read;
3126
    else
3127
#endif
3128
        read_cb = ctx->spr_cb[sprn].uea_read;
3129
    if (likely(read_cb != NULL)) {
3130
        if (likely(read_cb != SPR_NOACCESS)) {
3131
            (*read_cb)(ctx, sprn);
3132
            gen_op_store_T0_gpr(rD(ctx->opcode));
3133
        } else {
3134
            /* Privilege exception */
3135
            if (loglevel != 0) {
3136
                fprintf(logfile, "Trying to read privileged spr %d %03x\n",
3137
                        sprn, sprn);
3138
            }
3139
            printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
3140
            RET_PRIVREG(ctx);
3141
        }
3142
    } else {
3143
        /* Not defined */
3144
        if (loglevel != 0) {
3145
            fprintf(logfile, "Trying to read invalid spr %d %03x\n",
3146
                    sprn, sprn);
3147
        }
3148
        printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
3149
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
3150
    }
3151
}
3152

    
3153
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3154
{
3155
    gen_op_mfspr(ctx);
3156
}
3157

    
3158
/* mftb */
3159
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3160
{
3161
    gen_op_mfspr(ctx);
3162
}
3163

    
3164
/* mtcrf */
3165
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3166
{
3167
    uint32_t crm, crn;
3168

    
3169
    gen_op_load_gpr_T0(rS(ctx->opcode));
3170
    crm = CRM(ctx->opcode);
3171
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3172
        crn = ffs(crm);
3173
        gen_op_srli_T0(crn * 4);
3174
        gen_op_andi_T0(0xF);
3175
        gen_op_store_cro(7 - crn);
3176
    } else {
3177
        gen_op_store_cr(crm);
3178
    }
3179
}
3180

    
3181
/* mtmsr */
3182
#if defined(TARGET_PPC64)
3183
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
3184
{
3185
#if defined(CONFIG_USER_ONLY)
3186
    RET_PRIVREG(ctx);
3187
#else
3188
    if (unlikely(!ctx->supervisor)) {
3189
        RET_PRIVREG(ctx);
3190
        return;
3191
    }
3192
    gen_update_nip(ctx, ctx->nip);
3193
    gen_op_load_gpr_T0(rS(ctx->opcode));
3194
    gen_op_store_msr();
3195
    /* Must stop the translation as machine state (may have) changed */
3196
    RET_CHG_FLOW(ctx);
3197
#endif
3198
}
3199
#endif
3200

    
3201
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3202
{
3203
#if defined(CONFIG_USER_ONLY)
3204
    RET_PRIVREG(ctx);
3205
#else
3206
    if (unlikely(!ctx->supervisor)) {
3207
        RET_PRIVREG(ctx);
3208
        return;
3209
    }
3210
    gen_update_nip(ctx, ctx->nip);
3211
    gen_op_load_gpr_T0(rS(ctx->opcode));
3212
#if defined(TARGET_PPC64)
3213
    if (!ctx->sf_mode)
3214
        gen_op_store_msr_32();
3215
    else
3216
#endif
3217
        gen_op_store_msr();
3218
    /* Must stop the translation as machine state (may have) changed */
3219
    RET_CHG_FLOW(ctx);
3220
#endif
3221
}
3222

    
3223
/* mtspr */
3224
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3225
{
3226
    void (*write_cb)(void *opaque, int sprn);
3227
    uint32_t sprn = SPR(ctx->opcode);
3228

    
3229
#if !defined(CONFIG_USER_ONLY)
3230
    if (ctx->supervisor)
3231
        write_cb = ctx->spr_cb[sprn].oea_write;
3232
    else
3233
#endif
3234
        write_cb = ctx->spr_cb[sprn].uea_write;
3235
    if (likely(write_cb != NULL)) {
3236
        if (likely(write_cb != SPR_NOACCESS)) {
3237
            gen_op_load_gpr_T0(rS(ctx->opcode));
3238
            (*write_cb)(ctx, sprn);
3239
        } else {
3240
            /* Privilege exception */
3241
            if (loglevel != 0) {
3242
                fprintf(logfile, "Trying to write privileged spr %d %03x\n",
3243
                        sprn, sprn);
3244
            }
3245
            printf("Trying to write privileged spr %d %03x\n", sprn, sprn);
3246
            RET_PRIVREG(ctx);
3247
        }
3248
    } else {
3249
        /* Not defined */
3250
        if (loglevel != 0) {
3251
            fprintf(logfile, "Trying to write invalid spr %d %03x\n",
3252
                    sprn, sprn);
3253
        }
3254
        printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
3255
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
3256
    }
3257
}
3258

    
3259
/***                         Cache management                              ***/
3260
/* For now, all those will be implemented as nop:
3261
 * this is valid, regarding the PowerPC specs...
3262
 * We just have to flush tb while invalidating instruction cache lines...
3263
 */
3264
/* dcbf */
3265
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
3266
{
3267
    gen_addr_reg_index(ctx);
3268
    op_ldst(lbz);
3269
}
3270

    
3271
/* dcbi (Supervisor only) */
3272
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3273
{
3274
#if defined(CONFIG_USER_ONLY)
3275
    RET_PRIVOPC(ctx);
3276
#else
3277
    if (unlikely(!ctx->supervisor)) {
3278
        RET_PRIVOPC(ctx);
3279
        return;
3280
    }
3281
    gen_addr_reg_index(ctx);
3282
    /* XXX: specification says this should be treated as a store by the MMU */
3283
    //op_ldst(lbz);
3284
    op_ldst(stb);
3285
#endif
3286
}
3287

    
3288
/* dcdst */
3289
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3290
{
3291
    /* XXX: specification say this is treated as a load by the MMU */
3292
    gen_addr_reg_index(ctx);
3293
    op_ldst(lbz);
3294
}
3295

    
3296
/* dcbt */
3297
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
3298
{
3299
    /* XXX: specification say this is treated as a load by the MMU
3300
     *      but does not generate any exception
3301
     */
3302
}
3303

    
3304
/* dcbtst */
3305
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
3306
{
3307
    /* XXX: specification say this is treated as a load by the MMU
3308
     *      but does not generate any exception
3309
     */
3310
}
3311

    
3312
/* dcbz */
3313
#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3314
#if defined(TARGET_PPC64)
3315
#if defined(CONFIG_USER_ONLY)
3316
static GenOpFunc *gen_op_dcbz[] = {
3317
    &gen_op_dcbz_raw,
3318
    &gen_op_dcbz_raw,
3319
    &gen_op_dcbz_64_raw,
3320
    &gen_op_dcbz_64_raw,
3321
};
3322
#else
3323
static GenOpFunc *gen_op_dcbz[] = {
3324
    &gen_op_dcbz_user,
3325
    &gen_op_dcbz_user,
3326
    &gen_op_dcbz_kernel,
3327
    &gen_op_dcbz_kernel,
3328
    &gen_op_dcbz_64_user,
3329
    &gen_op_dcbz_64_user,
3330
    &gen_op_dcbz_64_kernel,
3331
    &gen_op_dcbz_64_kernel,
3332
};
3333
#endif
3334
#else
3335
#if defined(CONFIG_USER_ONLY)
3336
static GenOpFunc *gen_op_dcbz[] = {
3337
    &gen_op_dcbz_raw,
3338
    &gen_op_dcbz_raw,
3339
};
3340
#else
3341
static GenOpFunc *gen_op_dcbz[] = {
3342
    &gen_op_dcbz_user,
3343
    &gen_op_dcbz_user,
3344
    &gen_op_dcbz_kernel,
3345
    &gen_op_dcbz_kernel,
3346
};
3347
#endif
3348
#endif
3349

    
3350
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3351
{
3352
    gen_addr_reg_index(ctx);
3353
    op_dcbz();
3354
    gen_op_check_reservation();
3355
}
3356

    
3357
/* icbi */
3358
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3359
#if defined(TARGET_PPC64)
3360
#if defined(CONFIG_USER_ONLY)
3361
static GenOpFunc *gen_op_icbi[] = {
3362
    &gen_op_icbi_raw,
3363
    &gen_op_icbi_raw,
3364
    &gen_op_icbi_64_raw,
3365
    &gen_op_icbi_64_raw,
3366
};
3367
#else
3368
static GenOpFunc *gen_op_icbi[] = {
3369
    &gen_op_icbi_user,
3370
    &gen_op_icbi_user,
3371
    &gen_op_icbi_kernel,
3372
    &gen_op_icbi_kernel,
3373
    &gen_op_icbi_64_user,
3374
    &gen_op_icbi_64_user,
3375
    &gen_op_icbi_64_kernel,
3376
    &gen_op_icbi_64_kernel,
3377
};
3378
#endif
3379
#else
3380
#if defined(CONFIG_USER_ONLY)
3381
static GenOpFunc *gen_op_icbi[] = {
3382
    &gen_op_icbi_raw,
3383
    &gen_op_icbi_raw,
3384
};
3385
#else
3386
static GenOpFunc *gen_op_icbi[] = {
3387
    &gen_op_icbi_user,
3388
    &gen_op_icbi_user,
3389
    &gen_op_icbi_kernel,
3390
    &gen_op_icbi_kernel,
3391
};
3392
#endif
3393
#endif
3394
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3395
{
3396
    /* NIP cannot be restored if the memory exception comes from an helper */
3397
    gen_update_nip(ctx, ctx->nip - 4);
3398
    gen_addr_reg_index(ctx);
3399
    op_icbi();
3400
    RET_STOP(ctx);
3401
}
3402

    
3403
/* Optional: */
3404
/* dcba */
3405
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3406
{
3407
}
3408

    
3409
/***                    Segment register manipulation                      ***/
3410
/* Supervisor only: */
3411
/* mfsr */
3412
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3413
{
3414
#if defined(CONFIG_USER_ONLY)
3415
    RET_PRIVREG(ctx);
3416
#else
3417
    if (unlikely(!ctx->supervisor)) {
3418
        RET_PRIVREG(ctx);
3419
        return;
3420
    }
3421
    gen_op_set_T1(SR(ctx->opcode));
3422
    gen_op_load_sr();
3423
    gen_op_store_T0_gpr(rD(ctx->opcode));
3424
#endif
3425
}
3426

    
3427
/* mfsrin */
3428
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3429
{
3430
#if defined(CONFIG_USER_ONLY)
3431
    RET_PRIVREG(ctx);
3432
#else
3433
    if (unlikely(!ctx->supervisor)) {
3434
        RET_PRIVREG(ctx);
3435
        return;
3436
    }
3437
    gen_op_load_gpr_T1(rB(ctx->opcode));
3438
    gen_op_srli_T1(28);
3439
    gen_op_load_sr();
3440
    gen_op_store_T0_gpr(rD(ctx->opcode));
3441
#endif
3442
}
3443

    
3444
/* mtsr */
3445
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3446
{
3447
#if defined(CONFIG_USER_ONLY)
3448
    RET_PRIVREG(ctx);
3449
#else
3450
    if (unlikely(!ctx->supervisor)) {
3451
        RET_PRIVREG(ctx);
3452
        return;
3453
    }
3454
    gen_op_load_gpr_T0(rS(ctx->opcode));
3455
    gen_op_set_T1(SR(ctx->opcode));
3456
    gen_op_store_sr();
3457
    RET_STOP(ctx);
3458
#endif
3459
}
3460

    
3461
/* mtsrin */
3462
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3463
{
3464
#if defined(CONFIG_USER_ONLY)
3465
    RET_PRIVREG(ctx);
3466
#else
3467
    if (unlikely(!ctx->supervisor)) {
3468
        RET_PRIVREG(ctx);
3469
        return;
3470
    }
3471
    gen_op_load_gpr_T0(rS(ctx->opcode));
3472
    gen_op_load_gpr_T1(rB(ctx->opcode));
3473
    gen_op_srli_T1(28);
3474
    gen_op_store_sr();
3475
    RET_STOP(ctx);
3476
#endif
3477
}
3478

    
3479
/***                      Lookaside buffer management                      ***/
3480
/* Optional & supervisor only: */
3481
/* tlbia */
3482
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3483
{
3484
#if defined(CONFIG_USER_ONLY)
3485
    RET_PRIVOPC(ctx);
3486
#else
3487
    if (unlikely(!ctx->supervisor)) {
3488
        if (loglevel != 0)
3489
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3490
        RET_PRIVOPC(ctx);
3491
        return;
3492
    }
3493
    gen_op_tlbia();
3494
    RET_STOP(ctx);
3495
#endif
3496
}
3497

    
3498
/* tlbie */
3499
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3500
{
3501
#if defined(CONFIG_USER_ONLY)
3502
    RET_PRIVOPC(ctx);
3503
#else
3504
    if (unlikely(!ctx->supervisor)) {
3505
        RET_PRIVOPC(ctx);
3506
        return;
3507
    }
3508
    gen_op_load_gpr_T0(rB(ctx->opcode));
3509
#if defined(TARGET_PPC64)
3510
    if (ctx->sf_mode)
3511
        gen_op_tlbie_64();
3512
    else
3513
#endif
3514
        gen_op_tlbie();
3515
    RET_STOP(ctx);
3516
#endif
3517
}
3518

    
3519
/* tlbsync */
3520
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3521
{
3522
#if defined(CONFIG_USER_ONLY)
3523
    RET_PRIVOPC(ctx);
3524
#else
3525
    if (unlikely(!ctx->supervisor)) {
3526
        RET_PRIVOPC(ctx);
3527
        return;
3528
    }
3529
    /* This has no effect: it should ensure that all previous
3530
     * tlbie have completed
3531
     */
3532
    RET_STOP(ctx);
3533
#endif
3534
}
3535

    
3536
#if defined(TARGET_PPC64)
3537
/* slbia */
3538
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3539
{
3540
#if defined(CONFIG_USER_ONLY)
3541
    RET_PRIVOPC(ctx);
3542
#else
3543
    if (unlikely(!ctx->supervisor)) {
3544
        if (loglevel != 0)
3545
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3546
        RET_PRIVOPC(ctx);
3547
        return;
3548
    }
3549
    gen_op_slbia();
3550
    RET_STOP(ctx);
3551
#endif
3552
}
3553

    
3554
/* slbie */
3555
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3556
{
3557
#if defined(CONFIG_USER_ONLY)
3558
    RET_PRIVOPC(ctx);
3559
#else
3560
    if (unlikely(!ctx->supervisor)) {
3561
        RET_PRIVOPC(ctx);
3562
        return;
3563
    }
3564
    gen_op_load_gpr_T0(rB(ctx->opcode));
3565
    gen_op_slbie();
3566
    RET_STOP(ctx);
3567
#endif
3568
}
3569
#endif
3570

    
3571
/***                              External control                         ***/
3572
/* Optional: */
3573
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3574
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3575
#if defined(TARGET_PPC64)
3576
#if defined(CONFIG_USER_ONLY)
3577
static GenOpFunc *gen_op_eciwx[] = {
3578
    &gen_op_eciwx_raw,
3579
    &gen_op_eciwx_le_raw,
3580
    &gen_op_eciwx_64_raw,
3581
    &gen_op_eciwx_le_64_raw,
3582
};
3583
static GenOpFunc *gen_op_ecowx[] = {
3584
    &gen_op_ecowx_raw,
3585
    &gen_op_ecowx_le_raw,
3586
    &gen_op_ecowx_64_raw,
3587
    &gen_op_ecowx_le_64_raw,
3588
};
3589
#else
3590
static GenOpFunc *gen_op_eciwx[] = {
3591
    &gen_op_eciwx_user,
3592
    &gen_op_eciwx_le_user,
3593
    &gen_op_eciwx_kernel,
3594
    &gen_op_eciwx_le_kernel,
3595
    &gen_op_eciwx_64_user,
3596
    &gen_op_eciwx_le_64_user,
3597
    &gen_op_eciwx_64_kernel,
3598
    &gen_op_eciwx_le_64_kernel,
3599
};
3600
static GenOpFunc *gen_op_ecowx[] = {
3601
    &gen_op_ecowx_user,
3602
    &gen_op_ecowx_le_user,
3603
    &gen_op_ecowx_kernel,
3604
    &gen_op_ecowx_le_kernel,
3605
    &gen_op_ecowx_64_user,
3606
    &gen_op_ecowx_le_64_user,
3607
    &gen_op_ecowx_64_kernel,
3608
    &gen_op_ecowx_le_64_kernel,
3609
};
3610
#endif
3611
#else
3612
#if defined(CONFIG_USER_ONLY)
3613
static GenOpFunc *gen_op_eciwx[] = {
3614
    &gen_op_eciwx_raw,
3615
    &gen_op_eciwx_le_raw,
3616
};
3617
static GenOpFunc *gen_op_ecowx[] = {
3618
    &gen_op_ecowx_raw,
3619
    &gen_op_ecowx_le_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
};
3628
static GenOpFunc *gen_op_ecowx[] = {
3629
    &gen_op_ecowx_user,
3630
    &gen_op_ecowx_le_user,
3631
    &gen_op_ecowx_kernel,
3632
    &gen_op_ecowx_le_kernel,
3633
};
3634
#endif
3635
#endif
3636

    
3637
/* eciwx */
3638
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3639
{
3640
    /* Should check EAR[E] & alignment ! */
3641
    gen_addr_reg_index(ctx);
3642
    op_eciwx();
3643
    gen_op_store_T0_gpr(rD(ctx->opcode));
3644
}
3645

    
3646
/* ecowx */
3647
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3648
{
3649
    /* Should check EAR[E] & alignment ! */
3650
    gen_addr_reg_index(ctx);
3651
    gen_op_load_gpr_T1(rS(ctx->opcode));
3652
    op_ecowx();
3653
}
3654

    
3655
/* PowerPC 601 specific instructions */
3656
/* abs - abs. */
3657
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3658
{
3659
    gen_op_load_gpr_T0(rA(ctx->opcode));
3660
    gen_op_POWER_abs();
3661
    gen_op_store_T0_gpr(rD(ctx->opcode));
3662
    if (unlikely(Rc(ctx->opcode) != 0))
3663
        gen_set_Rc0(ctx);
3664
}
3665

    
3666
/* abso - abso. */
3667
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3668
{
3669
    gen_op_load_gpr_T0(rA(ctx->opcode));
3670
    gen_op_POWER_abso();
3671
    gen_op_store_T0_gpr(rD(ctx->opcode));
3672
    if (unlikely(Rc(ctx->opcode) != 0))
3673
        gen_set_Rc0(ctx);
3674
}
3675

    
3676
/* clcs */
3677
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3678
{
3679
    gen_op_load_gpr_T0(rA(ctx->opcode));
3680
    gen_op_POWER_clcs();
3681
    gen_op_store_T0_gpr(rD(ctx->opcode));
3682
}
3683

    
3684
/* div - div. */
3685
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3686
{
3687
    gen_op_load_gpr_T0(rA(ctx->opcode));
3688
    gen_op_load_gpr_T1(rB(ctx->opcode));
3689
    gen_op_POWER_div();
3690
    gen_op_store_T0_gpr(rD(ctx->opcode));
3691
    if (unlikely(Rc(ctx->opcode) != 0))
3692
        gen_set_Rc0(ctx);
3693
}
3694

    
3695
/* divo - divo. */
3696
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3697
{
3698
    gen_op_load_gpr_T0(rA(ctx->opcode));
3699
    gen_op_load_gpr_T1(rB(ctx->opcode));
3700
    gen_op_POWER_divo();
3701
    gen_op_store_T0_gpr(rD(ctx->opcode));
3702
    if (unlikely(Rc(ctx->opcode) != 0))
3703
        gen_set_Rc0(ctx);
3704
}
3705

    
3706
/* divs - divs. */
3707
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3708
{
3709
    gen_op_load_gpr_T0(rA(ctx->opcode));
3710
    gen_op_load_gpr_T1(rB(ctx->opcode));
3711
    gen_op_POWER_divs();
3712
    gen_op_store_T0_gpr(rD(ctx->opcode));
3713
    if (unlikely(Rc(ctx->opcode) != 0))
3714
        gen_set_Rc0(ctx);
3715
}
3716

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

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

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

    
3750
/* dozi */
3751
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3752
{
3753
    gen_op_load_gpr_T0(rA(ctx->opcode));
3754
    gen_op_set_T1(SIMM(ctx->opcode));
3755
    gen_op_POWER_doz();
3756
    gen_op_store_T0_gpr(rD(ctx->opcode));
3757
}
3758

    
3759
/* As lscbx load from memory byte after byte, it's always endian safe */
3760
#define op_POWER_lscbx(start, ra, rb) \
3761
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3762
#if defined(CONFIG_USER_ONLY)
3763
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3764
    &gen_op_POWER_lscbx_raw,
3765
    &gen_op_POWER_lscbx_raw,
3766
};
3767
#else
3768
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3769
    &gen_op_POWER_lscbx_user,
3770
    &gen_op_POWER_lscbx_user,
3771
    &gen_op_POWER_lscbx_kernel,
3772
    &gen_op_POWER_lscbx_kernel,
3773
};
3774
#endif
3775

    
3776
/* lscbx - lscbx. */
3777
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3778
{
3779
    int ra = rA(ctx->opcode);
3780
    int rb = rB(ctx->opcode);
3781

    
3782
    gen_addr_reg_index(ctx);
3783
    if (ra == 0) {
3784
        ra = rb;
3785
    }
3786
    /* NIP cannot be restored if the memory exception comes from an helper */
3787
    gen_update_nip(ctx, ctx->nip - 4);
3788
    gen_op_load_xer_bc();
3789
    gen_op_load_xer_cmp();
3790
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3791
    gen_op_store_xer_bc();
3792
    if (unlikely(Rc(ctx->opcode) != 0))
3793
        gen_set_Rc0(ctx);
3794
}
3795

    
3796
/* maskg - maskg. */
3797
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3798
{
3799
    gen_op_load_gpr_T0(rS(ctx->opcode));
3800
    gen_op_load_gpr_T1(rB(ctx->opcode));
3801
    gen_op_POWER_maskg();
3802
    gen_op_store_T0_gpr(rA(ctx->opcode));
3803
    if (unlikely(Rc(ctx->opcode) != 0))
3804
        gen_set_Rc0(ctx);
3805
}
3806

    
3807
/* maskir - maskir. */
3808
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3809
{
3810
    gen_op_load_gpr_T0(rA(ctx->opcode));
3811
    gen_op_load_gpr_T1(rS(ctx->opcode));
3812
    gen_op_load_gpr_T2(rB(ctx->opcode));
3813
    gen_op_POWER_maskir();
3814
    gen_op_store_T0_gpr(rA(ctx->opcode));
3815
    if (unlikely(Rc(ctx->opcode) != 0))
3816
        gen_set_Rc0(ctx);
3817
}
3818

    
3819
/* mul - mul. */
3820
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
3821
{
3822
    gen_op_load_gpr_T0(rA(ctx->opcode));
3823
    gen_op_load_gpr_T1(rB(ctx->opcode));
3824
    gen_op_POWER_mul();
3825
    gen_op_store_T0_gpr(rD(ctx->opcode));
3826
    if (unlikely(Rc(ctx->opcode) != 0))
3827
        gen_set_Rc0(ctx);
3828
}
3829

    
3830
/* mulo - mulo. */
3831
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
3832
{
3833
    gen_op_load_gpr_T0(rA(ctx->opcode));
3834
    gen_op_load_gpr_T1(rB(ctx->opcode));
3835
    gen_op_POWER_mulo();
3836
    gen_op_store_T0_gpr(rD(ctx->opcode));
3837
    if (unlikely(Rc(ctx->opcode) != 0))
3838
        gen_set_Rc0(ctx);
3839
}
3840

    
3841
/* nabs - nabs. */
3842
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
3843
{
3844
    gen_op_load_gpr_T0(rA(ctx->opcode));
3845
    gen_op_POWER_nabs();
3846
    gen_op_store_T0_gpr(rD(ctx->opcode));
3847
    if (unlikely(Rc(ctx->opcode) != 0))
3848
        gen_set_Rc0(ctx);
3849
}
3850

    
3851
/* nabso - nabso. */
3852
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
3853
{
3854
    gen_op_load_gpr_T0(rA(ctx->opcode));
3855
    gen_op_POWER_nabso();
3856
    gen_op_store_T0_gpr(rD(ctx->opcode));
3857
    if (unlikely(Rc(ctx->opcode) != 0))
3858
        gen_set_Rc0(ctx);
3859
}
3860

    
3861
/* rlmi - rlmi. */
3862
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3863
{
3864
    uint32_t mb, me;
3865

    
3866
    mb = MB(ctx->opcode);
3867
    me = ME(ctx->opcode);
3868
    gen_op_load_gpr_T0(rS(ctx->opcode));
3869
    gen_op_load_gpr_T1(rA(ctx->opcode));
3870
    gen_op_load_gpr_T2(rB(ctx->opcode));
3871
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
3872
    gen_op_store_T0_gpr(rA(ctx->opcode));
3873
    if (unlikely(Rc(ctx->opcode) != 0))
3874
        gen_set_Rc0(ctx);
3875
}
3876

    
3877
/* rrib - rrib. */
3878
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
3879
{
3880
    gen_op_load_gpr_T0(rS(ctx->opcode));
3881
    gen_op_load_gpr_T1(rA(ctx->opcode));
3882
    gen_op_load_gpr_T2(rB(ctx->opcode));
3883
    gen_op_POWER_rrib();
3884
    gen_op_store_T0_gpr(rA(ctx->opcode));
3885
    if (unlikely(Rc(ctx->opcode) != 0))
3886
        gen_set_Rc0(ctx);
3887
}
3888

    
3889
/* sle - sle. */
3890
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
3891
{
3892
    gen_op_load_gpr_T0(rS(ctx->opcode));
3893
    gen_op_load_gpr_T1(rB(ctx->opcode));
3894
    gen_op_POWER_sle();
3895
    gen_op_store_T0_gpr(rA(ctx->opcode));
3896
    if (unlikely(Rc(ctx->opcode) != 0))
3897
        gen_set_Rc0(ctx);
3898
}
3899

    
3900
/* sleq - sleq. */
3901
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
3902
{
3903
    gen_op_load_gpr_T0(rS(ctx->opcode));
3904
    gen_op_load_gpr_T1(rB(ctx->opcode));
3905
    gen_op_POWER_sleq();
3906
    gen_op_store_T0_gpr(rA(ctx->opcode));
3907
    if (unlikely(Rc(ctx->opcode) != 0))
3908
        gen_set_Rc0(ctx);
3909
}
3910

    
3911
/* sliq - sliq. */
3912
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
3913
{
3914
    gen_op_load_gpr_T0(rS(ctx->opcode));
3915
    gen_op_set_T1(SH(ctx->opcode));
3916
    gen_op_POWER_sle();
3917
    gen_op_store_T0_gpr(rA(ctx->opcode));
3918
    if (unlikely(Rc(ctx->opcode) != 0))
3919
        gen_set_Rc0(ctx);
3920
}
3921

    
3922
/* slliq - slliq. */
3923
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
3924
{
3925
    gen_op_load_gpr_T0(rS(ctx->opcode));
3926
    gen_op_set_T1(SH(ctx->opcode));
3927
    gen_op_POWER_sleq();
3928
    gen_op_store_T0_gpr(rA(ctx->opcode));
3929
    if (unlikely(Rc(ctx->opcode) != 0))
3930
        gen_set_Rc0(ctx);
3931
}
3932

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

    
3944
/* slq - slq. */
3945
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
3946
{
3947
    gen_op_load_gpr_T0(rS(ctx->opcode));
3948
    gen_op_load_gpr_T1(rB(ctx->opcode));
3949
    gen_op_POWER_slq();
3950
    gen_op_store_T0_gpr(rA(ctx->opcode));
3951
    if (unlikely(Rc(ctx->opcode) != 0))
3952
        gen_set_Rc0(ctx);
3953
}
3954

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

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

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

    
3988
/* srea - srea. */
3989
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
3990
{
3991
    gen_op_load_gpr_T0(rS(ctx->opcode));
3992
    gen_op_load_gpr_T1(rB(ctx->opcode));
3993
    gen_op_POWER_srea();
3994
    gen_op_store_T0_gpr(rA(ctx->opcode));
3995
    if (unlikely(Rc(ctx->opcode) != 0))
3996
        gen_set_Rc0(ctx);
3997
}
3998

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

    
4010
/* sriq */
4011
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4012
{
4013
    gen_op_load_gpr_T0(rS(ctx->opcode));
4014
    gen_op_set_T1(SH(ctx->opcode));
4015
    gen_op_POWER_srq();
4016
    gen_op_store_T0_gpr(rA(ctx->opcode));
4017
    if (unlikely(Rc(ctx->opcode) != 0))
4018
        gen_set_Rc0(ctx);
4019
}
4020

    
4021
/* srliq */
4022
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4023
{
4024
    gen_op_load_gpr_T0(rS(ctx->opcode));
4025
    gen_op_load_gpr_T1(rB(ctx->opcode));
4026
    gen_op_set_T1(SH(ctx->opcode));
4027
    gen_op_POWER_srlq();
4028
    gen_op_store_T0_gpr(rA(ctx->opcode));
4029
    if (unlikely(Rc(ctx->opcode) != 0))
4030
        gen_set_Rc0(ctx);
4031
}
4032

    
4033
/* srlq */
4034
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4035
{
4036
    gen_op_load_gpr_T0(rS(ctx->opcode));
4037
    gen_op_load_gpr_T1(rB(ctx->opcode));
4038
    gen_op_POWER_srlq();
4039
    gen_op_store_T0_gpr(rA(ctx->opcode));
4040
    if (unlikely(Rc(ctx->opcode) != 0))
4041
        gen_set_Rc0(ctx);
4042
}
4043

    
4044
/* srq */
4045
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4046
{
4047
    gen_op_load_gpr_T0(rS(ctx->opcode));
4048
    gen_op_load_gpr_T1(rB(ctx->opcode));
4049
    gen_op_POWER_srq();
4050
    gen_op_store_T0_gpr(rA(ctx->opcode));
4051
    if (unlikely(Rc(ctx->opcode) != 0))
4052
        gen_set_Rc0(ctx);
4053
}
4054

    
4055
/* PowerPC 602 specific instructions */
4056
/* dsa  */
4057
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4058
{
4059
    /* XXX: TODO */
4060
    RET_INVAL(ctx);
4061
}
4062

    
4063
/* esa */
4064
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4065
{
4066
    /* XXX: TODO */
4067
    RET_INVAL(ctx);
4068
}
4069

    
4070
/* mfrom */
4071
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4072
{
4073
#if defined(CONFIG_USER_ONLY)
4074
    RET_PRIVOPC(ctx);
4075
#else
4076
    if (unlikely(!ctx->supervisor)) {
4077
        RET_PRIVOPC(ctx);
4078
        return;
4079
    }
4080
    gen_op_load_gpr_T0(rA(ctx->opcode));
4081
    gen_op_602_mfrom();
4082
    gen_op_store_T0_gpr(rD(ctx->opcode));
4083
#endif
4084
}
4085

    
4086
/* 602 - 603 - G2 TLB management */
4087
/* tlbld */
4088
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4089
{
4090
#if defined(CONFIG_USER_ONLY)
4091
    RET_PRIVOPC(ctx);
4092
#else
4093
    if (unlikely(!ctx->supervisor)) {
4094
        RET_PRIVOPC(ctx);
4095
        return;
4096
    }
4097
    gen_op_load_gpr_T0(rB(ctx->opcode));
4098
    gen_op_6xx_tlbld();
4099
    RET_STOP(ctx);
4100
#endif
4101
}
4102

    
4103
/* tlbli */
4104
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4105
{
4106
#if defined(CONFIG_USER_ONLY)
4107
    RET_PRIVOPC(ctx);
4108
#else
4109
    if (unlikely(!ctx->supervisor)) {
4110
        RET_PRIVOPC(ctx);
4111
        return;
4112
    }
4113
    gen_op_load_gpr_T0(rB(ctx->opcode));
4114
    gen_op_6xx_tlbli();
4115
    RET_STOP(ctx);
4116
#endif
4117
}
4118

    
4119
/* POWER instructions not in PowerPC 601 */
4120
/* clf */
4121
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4122
{
4123
    /* Cache line flush: implemented as no-op */
4124
}
4125

    
4126
/* cli */
4127
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4128
{
4129
    /* Cache line invalidate: privileged and treated as no-op */
4130
#if defined(CONFIG_USER_ONLY)
4131
    RET_PRIVOPC(ctx);
4132
#else
4133
    if (unlikely(!ctx->supervisor)) {
4134
        RET_PRIVOPC(ctx);
4135
        return;
4136
    }
4137
#endif
4138
}
4139

    
4140
/* dclst */
4141
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4142
{
4143
    /* Data cache line store: treated as no-op */
4144
}
4145

    
4146
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4147
{
4148
#if defined(CONFIG_USER_ONLY)
4149
    RET_PRIVOPC(ctx);
4150
#else
4151
    if (unlikely(!ctx->supervisor)) {
4152
        RET_PRIVOPC(ctx);
4153
        return;
4154
    }
4155
    int ra = rA(ctx->opcode);
4156
    int rd = rD(ctx->opcode);
4157

    
4158
    gen_addr_reg_index(ctx);
4159
    gen_op_POWER_mfsri();
4160
    gen_op_store_T0_gpr(rd);
4161
    if (ra != 0 && ra != rd)
4162
        gen_op_store_T1_gpr(ra);
4163
#endif
4164
}
4165

    
4166
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4167
{
4168
#if defined(CONFIG_USER_ONLY)
4169
    RET_PRIVOPC(ctx);
4170
#else
4171
    if (unlikely(!ctx->supervisor)) {
4172
        RET_PRIVOPC(ctx);
4173
        return;
4174
    }
4175
    gen_addr_reg_index(ctx);
4176
    gen_op_POWER_rac();
4177
    gen_op_store_T0_gpr(rD(ctx->opcode));
4178
#endif
4179
}
4180

    
4181
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4182
{
4183
#if defined(CONFIG_USER_ONLY)
4184
    RET_PRIVOPC(ctx);
4185
#else
4186
    if (unlikely(!ctx->supervisor)) {
4187
        RET_PRIVOPC(ctx);
4188
        return;
4189
    }
4190
    gen_op_POWER_rfsvc();
4191
    RET_CHG_FLOW(ctx);
4192
#endif
4193
}
4194

    
4195
/* svc is not implemented for now */
4196

    
4197
/* POWER2 specific instructions */
4198
/* Quad manipulation (load/store two floats at a time) */
4199
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4200
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4201
#if defined(CONFIG_USER_ONLY)
4202
static GenOpFunc *gen_op_POWER2_lfq[] = {
4203
    &gen_op_POWER2_lfq_le_raw,
4204
    &gen_op_POWER2_lfq_raw,
4205
};
4206
static GenOpFunc *gen_op_POWER2_stfq[] = {
4207
    &gen_op_POWER2_stfq_le_raw,
4208
    &gen_op_POWER2_stfq_raw,
4209
};
4210
#else
4211
static GenOpFunc *gen_op_POWER2_lfq[] = {
4212
    &gen_op_POWER2_lfq_le_user,
4213
    &gen_op_POWER2_lfq_user,
4214
    &gen_op_POWER2_lfq_le_kernel,
4215
    &gen_op_POWER2_lfq_kernel,
4216
};
4217
static GenOpFunc *gen_op_POWER2_stfq[] = {
4218
    &gen_op_POWER2_stfq_le_user,
4219
    &gen_op_POWER2_stfq_user,
4220
    &gen_op_POWER2_stfq_le_kernel,
4221
    &gen_op_POWER2_stfq_kernel,
4222
};
4223
#endif
4224

    
4225
/* lfq */
4226
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4227
{
4228
    /* NIP cannot be restored if the memory exception comes from an helper */
4229
    gen_update_nip(ctx, ctx->nip - 4);
4230
    gen_addr_imm_index(ctx, 0);
4231
    op_POWER2_lfq();
4232
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4233
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4234
}
4235

    
4236
/* lfqu */
4237
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4238
{
4239
    int ra = rA(ctx->opcode);
4240

    
4241
    /* NIP cannot be restored if the memory exception comes from an helper */
4242
    gen_update_nip(ctx, ctx->nip - 4);
4243
    gen_addr_imm_index(ctx, 0);
4244
    op_POWER2_lfq();
4245
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4246
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4247
    if (ra != 0)
4248
        gen_op_store_T0_gpr(ra);
4249
}
4250

    
4251
/* lfqux */
4252
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4253
{
4254
    int ra = rA(ctx->opcode);
4255

    
4256
    /* NIP cannot be restored if the memory exception comes from an helper */
4257
    gen_update_nip(ctx, ctx->nip - 4);
4258
    gen_addr_reg_index(ctx);
4259
    op_POWER2_lfq();
4260
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4261
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4262
    if (ra != 0)
4263
        gen_op_store_T0_gpr(ra);
4264
}
4265

    
4266
/* lfqx */
4267
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4268
{
4269
    /* NIP cannot be restored if the memory exception comes from an helper */
4270
    gen_update_nip(ctx, ctx->nip - 4);
4271
    gen_addr_reg_index(ctx);
4272
    op_POWER2_lfq();
4273
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4274
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4275
}
4276

    
4277
/* stfq */
4278
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4279
{
4280
    /* NIP cannot be restored if the memory exception comes from an helper */
4281
    gen_update_nip(ctx, ctx->nip - 4);
4282
    gen_addr_imm_index(ctx, 0);
4283
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4284
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4285
    op_POWER2_stfq();
4286
}
4287

    
4288
/* stfqu */
4289
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4290
{
4291
    int ra = rA(ctx->opcode);
4292

    
4293
    /* NIP cannot be restored if the memory exception comes from an helper */
4294
    gen_update_nip(ctx, ctx->nip - 4);
4295
    gen_addr_imm_index(ctx, 0);
4296
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4297
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4298
    op_POWER2_stfq();
4299
    if (ra != 0)
4300
        gen_op_store_T0_gpr(ra);
4301
}
4302

    
4303
/* stfqux */
4304
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4305
{
4306
    int ra = rA(ctx->opcode);
4307

    
4308
    /* NIP cannot be restored if the memory exception comes from an helper */
4309
    gen_update_nip(ctx, ctx->nip - 4);
4310
    gen_addr_reg_index(ctx);
4311
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4312
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4313
    op_POWER2_stfq();
4314
    if (ra != 0)
4315
        gen_op_store_T0_gpr(ra);
4316
}
4317

    
4318
/* stfqx */
4319
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4320
{
4321
    /* NIP cannot be restored if the memory exception comes from an helper */
4322
    gen_update_nip(ctx, ctx->nip - 4);
4323
    gen_addr_reg_index(ctx);
4324
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4325
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4326
    op_POWER2_stfq();
4327
}
4328

    
4329
/* BookE specific instructions */
4330
/* XXX: not implemented on 440 ? */
4331
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT)
4332
{
4333
    /* XXX: TODO */
4334
    RET_INVAL(ctx);
4335
}
4336

    
4337
/* XXX: not implemented on 440 ? */
4338
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
4339
{
4340
#if defined(CONFIG_USER_ONLY)
4341
    RET_PRIVOPC(ctx);
4342
#else
4343
    if (unlikely(!ctx->supervisor)) {
4344
        RET_PRIVOPC(ctx);
4345
        return;
4346
    }
4347
    gen_addr_reg_index(ctx);
4348
    /* Use the same micro-ops as for tlbie */
4349
#if defined(TARGET_PPC64)
4350
    if (ctx->sf_mode)
4351
        gen_op_tlbie_64();
4352
    else
4353
#endif
4354
        gen_op_tlbie();
4355
    RET_STOP(ctx);
4356
#endif
4357
}
4358

    
4359
/* All 405 MAC instructions are translated here */
4360
static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
4361
                                         int ra, int rb, int rt, int Rc)
4362
{
4363
    gen_op_load_gpr_T0(ra);
4364
    gen_op_load_gpr_T1(rb);
4365
    switch (opc3 & 0x0D) {
4366
    case 0x05:
4367
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4368
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4369
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4370
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4371
        /* mulchw - mulchw. */
4372
        gen_op_405_mulchw();
4373
        break;
4374
    case 0x04:
4375
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4376
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4377
        /* mulchwu - mulchwu. */
4378
        gen_op_405_mulchwu();
4379
        break;
4380
    case 0x01:
4381
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4382
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4383
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4384
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4385
        /* mulhhw - mulhhw. */
4386
        gen_op_405_mulhhw();
4387
        break;
4388
    case 0x00:
4389
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4390
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4391
        /* mulhhwu - mulhhwu. */
4392
        gen_op_405_mulhhwu();
4393
        break;
4394
    case 0x0D:
4395
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4396
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4397
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4398
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4399
        /* mullhw - mullhw. */
4400
        gen_op_405_mullhw();
4401
        break;
4402
    case 0x0C:
4403
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4404
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4405
        /* mullhwu - mullhwu. */
4406
        gen_op_405_mullhwu();
4407
        break;
4408
    }
4409
    if (opc2 & 0x02) {
4410
        /* nmultiply-and-accumulate (0x0E) */
4411
        gen_op_neg();
4412
    }
4413
    if (opc2 & 0x04) {
4414
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4415
        gen_op_load_gpr_T2(rt);
4416
        gen_op_move_T1_T0();
4417
        gen_op_405_add_T0_T2();
4418
    }
4419
    if (opc3 & 0x10) {
4420
        /* Check overflow */
4421
        if (opc3 & 0x01)
4422
            gen_op_405_check_ov();
4423
        else
4424
            gen_op_405_check_ovu();
4425
    }
4426
    if (opc3 & 0x02) {
4427
        /* Saturate */
4428
        if (opc3 & 0x01)
4429
            gen_op_405_check_sat();
4430
        else
4431
            gen_op_405_check_satu();
4432
    }
4433
    gen_op_store_T0_gpr(rt);
4434
    if (unlikely(Rc) != 0) {
4435
        /* Update Rc0 */
4436
        gen_set_Rc0(ctx);
4437
    }
4438
}
4439

    
4440
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4441
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4442
{                                                                             \
4443
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4444
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4445
}
4446

    
4447
/* macchw    - macchw.    */
4448
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4449
/* macchwo   - macchwo.   */
4450
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4451
/* macchws   - macchws.   */
4452
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4453
/* macchwso  - macchwso.  */
4454
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4455
/* macchwsu  - macchwsu.  */
4456
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4457
/* macchwsuo - macchwsuo. */
4458
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4459
/* macchwu   - macchwu.   */
4460
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4461
/* macchwuo  - macchwuo.  */
4462
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4463
/* machhw    - machhw.    */
4464
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4465
/* machhwo   - machhwo.   */
4466
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4467
/* machhws   - machhws.   */
4468
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4469
/* machhwso  - machhwso.  */
4470
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4471
/* machhwsu  - machhwsu.  */
4472
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4473
/* machhwsuo - machhwsuo. */
4474
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4475
/* machhwu   - machhwu.   */
4476
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4477
/* machhwuo  - machhwuo.  */
4478
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4479
/* maclhw    - maclhw.    */
4480
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4481
/* maclhwo   - maclhwo.   */
4482
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4483
/* maclhws   - maclhws.   */
4484
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4485
/* maclhwso  - maclhwso.  */
4486
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4487
/* maclhwu   - maclhwu.   */
4488
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4489
/* maclhwuo  - maclhwuo.  */
4490
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4491
/* maclhwsu  - maclhwsu.  */
4492
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4493
/* maclhwsuo - maclhwsuo. */
4494
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4495
/* nmacchw   - nmacchw.   */
4496
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4497
/* nmacchwo  - nmacchwo.  */
4498
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4499
/* nmacchws  - nmacchws.  */
4500
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4501
/* nmacchwso - nmacchwso. */
4502
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4503
/* nmachhw   - nmachhw.   */
4504
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4505
/* nmachhwo  - nmachhwo.  */
4506
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4507
/* nmachhws  - nmachhws.  */
4508
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4509
/* nmachhwso - nmachhwso. */
4510
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4511
/* nmaclhw   - nmaclhw.   */
4512
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4513
/* nmaclhwo  - nmaclhwo.  */
4514
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4515
/* nmaclhws  - nmaclhws.  */
4516
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4517
/* nmaclhwso - nmaclhwso. */
4518
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4519

    
4520
/* mulchw  - mulchw.  */
4521
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4522
/* mulchwu - mulchwu. */
4523
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4524
/* mulhhw  - mulhhw.  */
4525
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4526
/* mulhhwu - mulhhwu. */
4527
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4528
/* mullhw  - mullhw.  */
4529
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4530
/* mullhwu - mullhwu. */
4531
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4532

    
4533
/* mfdcr */
4534
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4535
{
4536
#if defined(CONFIG_USER_ONLY)
4537
    RET_PRIVREG(ctx);
4538
#else
4539
    uint32_t dcrn = SPR(ctx->opcode);
4540

    
4541
    if (unlikely(!ctx->supervisor)) {
4542
        RET_PRIVREG(ctx);
4543
        return;
4544
    }
4545
    gen_op_set_T0(dcrn);
4546
    gen_op_load_dcr();
4547
    gen_op_store_T0_gpr(rD(ctx->opcode));
4548
#endif
4549
}
4550

    
4551
/* mtdcr */
4552
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4553
{
4554
#if defined(CONFIG_USER_ONLY)
4555
    RET_PRIVREG(ctx);
4556
#else
4557
    uint32_t dcrn = SPR(ctx->opcode);
4558

    
4559
    if (unlikely(!ctx->supervisor)) {
4560
        RET_PRIVREG(ctx);
4561
        return;
4562
    }
4563
    gen_op_set_T0(dcrn);
4564
    gen_op_load_gpr_T1(rS(ctx->opcode));
4565
    gen_op_store_dcr();
4566
#endif
4567
}
4568

    
4569
/* mfdcrx */
4570
/* XXX: not implemented on 440 ? */
4571
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT)
4572
{
4573
#if defined(CONFIG_USER_ONLY)
4574
    RET_PRIVREG(ctx);
4575
#else
4576
    if (unlikely(!ctx->supervisor)) {
4577
        RET_PRIVREG(ctx);
4578
        return;
4579
    }
4580
    gen_op_load_gpr_T0(rA(ctx->opcode));
4581
    gen_op_load_dcr();
4582
    gen_op_store_T0_gpr(rD(ctx->opcode));
4583
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4584
#endif
4585
}
4586

    
4587
/* mtdcrx */
4588
/* XXX: not implemented on 440 ? */
4589
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT)
4590
{
4591
#if defined(CONFIG_USER_ONLY)
4592
    RET_PRIVREG(ctx);
4593
#else
4594
    if (unlikely(!ctx->supervisor)) {
4595
        RET_PRIVREG(ctx);
4596
        return;
4597
    }
4598
    gen_op_load_gpr_T0(rA(ctx->opcode));
4599
    gen_op_load_gpr_T1(rS(ctx->opcode));
4600
    gen_op_store_dcr();
4601
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4602
#endif
4603
}
4604

    
4605
/* mfdcrux (PPC 460) : user-mode access to DCR */
4606
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4607
{
4608
    gen_op_load_gpr_T0(rA(ctx->opcode));
4609
    gen_op_load_dcr();
4610
    gen_op_store_T0_gpr(rD(ctx->opcode));
4611
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4612
}
4613

    
4614
/* mtdcrux (PPC 460) : user-mode access to DCR */
4615
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4616
{
4617
    gen_op_load_gpr_T0(rA(ctx->opcode));
4618
    gen_op_load_gpr_T1(rS(ctx->opcode));
4619
    gen_op_store_dcr();
4620
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4621
}
4622

    
4623
/* dccci */
4624
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4625
{
4626
#if defined(CONFIG_USER_ONLY)
4627
    RET_PRIVOPC(ctx);
4628
#else
4629
    if (unlikely(!ctx->supervisor)) {
4630
        RET_PRIVOPC(ctx);
4631
        return;
4632
    }
4633
    /* interpreted as no-op */
4634
#endif
4635
}
4636

    
4637
/* dcread */
4638
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4639
{
4640
#if defined(CONFIG_USER_ONLY)
4641
    RET_PRIVOPC(ctx);
4642
#else
4643
    if (unlikely(!ctx->supervisor)) {
4644
        RET_PRIVOPC(ctx);
4645
        return;
4646
    }
4647
    gen_addr_reg_index(ctx);
4648
    op_ldst(lwz);
4649
    gen_op_store_T0_gpr(rD(ctx->opcode));
4650
#endif
4651
}
4652

    
4653
/* icbt */
4654
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4655
{
4656
    /* interpreted as no-op */
4657
    /* XXX: specification say this is treated as a load by the MMU
4658
     *      but does not generate any exception
4659
     */
4660
}
4661

    
4662
/* iccci */
4663
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4664
{
4665
#if defined(CONFIG_USER_ONLY)
4666
    RET_PRIVOPC(ctx);
4667
#else
4668
    if (unlikely(!ctx->supervisor)) {
4669
        RET_PRIVOPC(ctx);
4670
        return;
4671
    }
4672
    /* interpreted as no-op */
4673
#endif
4674
}
4675

    
4676
/* icread */
4677
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4678
{
4679
#if defined(CONFIG_USER_ONLY)
4680
    RET_PRIVOPC(ctx);
4681
#else
4682
    if (unlikely(!ctx->supervisor)) {
4683
        RET_PRIVOPC(ctx);
4684
        return;
4685
    }
4686
    /* interpreted as no-op */
4687
#endif
4688
}
4689

    
4690
/* rfci (supervisor only) */
4691
GEN_HANDLER(rfci_40x, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4692
{
4693
#if defined(CONFIG_USER_ONLY)
4694
    RET_PRIVOPC(ctx);
4695
#else
4696
    if (unlikely(!ctx->supervisor)) {
4697
        RET_PRIVOPC(ctx);
4698
        return;
4699
    }
4700
    /* Restore CPU state */
4701
    gen_op_40x_rfci();
4702
    RET_CHG_FLOW(ctx);
4703
#endif
4704
}
4705

    
4706
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4707
{
4708
#if defined(CONFIG_USER_ONLY)
4709
    RET_PRIVOPC(ctx);
4710
#else
4711
    if (unlikely(!ctx->supervisor)) {
4712
        RET_PRIVOPC(ctx);
4713
        return;
4714
    }
4715
    /* Restore CPU state */
4716
    gen_op_rfci();
4717
    RET_CHG_FLOW(ctx);
4718
#endif
4719
}
4720

    
4721
/* BookE specific */
4722
/* XXX: not implemented on 440 ? */
4723
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
4724
{
4725
#if defined(CONFIG_USER_ONLY)
4726
    RET_PRIVOPC(ctx);
4727
#else
4728
    if (unlikely(!ctx->supervisor)) {
4729
        RET_PRIVOPC(ctx);
4730
        return;
4731
    }
4732
    /* Restore CPU state */
4733
    gen_op_rfdi();
4734
    RET_CHG_FLOW(ctx);
4735
#endif
4736
}
4737

    
4738
/* XXX: not implemented on 440 ? */
4739
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
4740
{
4741
#if defined(CONFIG_USER_ONLY)
4742
    RET_PRIVOPC(ctx);
4743
#else
4744
    if (unlikely(!ctx->supervisor)) {
4745
        RET_PRIVOPC(ctx);
4746
        return;
4747
    }
4748
    /* Restore CPU state */
4749
    gen_op_rfmci();
4750
    RET_CHG_FLOW(ctx);
4751
#endif
4752
}
4753

    
4754
/* TLB management - PowerPC 405 implementation */
4755
/* tlbre */
4756
GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4757
{
4758
#if defined(CONFIG_USER_ONLY)
4759
    RET_PRIVOPC(ctx);
4760
#else
4761
    if (unlikely(!ctx->supervisor)) {
4762
        RET_PRIVOPC(ctx);
4763
        return;
4764
    }
4765
    switch (rB(ctx->opcode)) {
4766
    case 0:
4767
        gen_op_load_gpr_T0(rA(ctx->opcode));
4768
        gen_op_4xx_tlbre_hi();
4769
        gen_op_store_T0_gpr(rD(ctx->opcode));
4770
        break;
4771
    case 1:
4772
        gen_op_load_gpr_T0(rA(ctx->opcode));
4773
        gen_op_4xx_tlbre_lo();
4774
        gen_op_store_T0_gpr(rD(ctx->opcode));
4775
        break;
4776
    default:
4777
        RET_INVAL(ctx);
4778
        break;
4779
    }
4780
#endif
4781
}
4782

    
4783
/* tlbsx - tlbsx. */
4784
GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
4785
{
4786
#if defined(CONFIG_USER_ONLY)
4787
    RET_PRIVOPC(ctx);
4788
#else
4789
    if (unlikely(!ctx->supervisor)) {
4790
        RET_PRIVOPC(ctx);
4791
        return;
4792
    }
4793
    gen_addr_reg_index(ctx);
4794
    if (Rc(ctx->opcode))
4795
        gen_op_4xx_tlbsx_();
4796
    else
4797
        gen_op_4xx_tlbsx();
4798
    gen_op_store_T0_gpr(rD(ctx->opcode));
4799
#endif
4800
}
4801

    
4802
/* tlbwe */
4803
GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
4804
{
4805
#if defined(CONFIG_USER_ONLY)
4806
    RET_PRIVOPC(ctx);
4807
#else
4808
    if (unlikely(!ctx->supervisor)) {
4809
        RET_PRIVOPC(ctx);
4810
        return;
4811
    }
4812
    switch (rB(ctx->opcode)) {
4813
    case 0:
4814
        gen_op_load_gpr_T0(rA(ctx->opcode));
4815
        gen_op_load_gpr_T1(rS(ctx->opcode));
4816
        gen_op_4xx_tlbwe_hi();
4817
        break;
4818
    case 1:
4819
        gen_op_load_gpr_T0(rA(ctx->opcode));
4820
        gen_op_load_gpr_T1(rS(ctx->opcode));
4821
        gen_op_4xx_tlbwe_lo();
4822
        break;
4823
    default:
4824
        RET_INVAL(ctx);
4825
        break;
4826
    }
4827
#endif
4828
}
4829

    
4830
/* TLB management - PowerPC 440 implementation */
4831
/* tlbre */
4832
GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4833
{
4834
#if defined(CONFIG_USER_ONLY)
4835
    RET_PRIVOPC(ctx);
4836
#else
4837
    if (unlikely(!ctx->supervisor)) {
4838
        RET_PRIVOPC(ctx);
4839
        return;
4840
    }
4841
    switch (rB(ctx->opcode)) {
4842
    case 0:
4843
    case 1:
4844
    case 2:
4845
        gen_op_load_gpr_T0(rA(ctx->opcode));
4846
        gen_op_440_tlbre(rB(ctx->opcode));
4847
        gen_op_store_T0_gpr(rD(ctx->opcode));
4848
        break;
4849
    default:
4850
        RET_INVAL(ctx);
4851
        break;
4852
    }
4853
#endif
4854
}
4855

    
4856
/* tlbsx - tlbsx. */
4857
GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
4858
{
4859
#if defined(CONFIG_USER_ONLY)
4860
    RET_PRIVOPC(ctx);
4861
#else
4862
    if (unlikely(!ctx->supervisor)) {
4863
        RET_PRIVOPC(ctx);
4864
        return;
4865
    }
4866
    gen_addr_reg_index(ctx);
4867
    if (Rc(ctx->opcode))
4868
        gen_op_440_tlbsx_();
4869
    else
4870
        gen_op_440_tlbsx();
4871
    gen_op_store_T0_gpr(rD(ctx->opcode));
4872
#endif
4873
}
4874

    
4875
/* tlbwe */
4876
GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
4877
{
4878
#if defined(CONFIG_USER_ONLY)
4879
    RET_PRIVOPC(ctx);
4880
#else
4881
    if (unlikely(!ctx->supervisor)) {
4882
        RET_PRIVOPC(ctx);
4883
        return;
4884
    }
4885
    switch (rB(ctx->opcode)) {
4886
    case 0:
4887
    case 1:
4888
    case 2:
4889
        gen_op_load_gpr_T0(rA(ctx->opcode));
4890
        gen_op_load_gpr_T1(rS(ctx->opcode));
4891
        gen_op_440_tlbwe(rB(ctx->opcode));
4892
        break;
4893
    default:
4894
        RET_INVAL(ctx);
4895
        break;
4896
    }
4897
#endif
4898
}
4899

    
4900
/* wrtee */
4901
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4902
{
4903
#if defined(CONFIG_USER_ONLY)
4904
    RET_PRIVOPC(ctx);
4905
#else
4906
    if (unlikely(!ctx->supervisor)) {
4907
        RET_PRIVOPC(ctx);
4908
        return;
4909
    }
4910
    gen_op_load_gpr_T0(rD(ctx->opcode));
4911
    gen_op_wrte();
4912
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4913
#endif
4914
}
4915

    
4916
/* wrteei */
4917
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4918
{
4919
#if defined(CONFIG_USER_ONLY)
4920
    RET_PRIVOPC(ctx);
4921
#else
4922
    if (unlikely(!ctx->supervisor)) {
4923
        RET_PRIVOPC(ctx);
4924
        return;
4925
    }
4926
    gen_op_set_T0(ctx->opcode & 0x00010000);
4927
    gen_op_wrte();
4928
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4929
#endif
4930
}
4931

    
4932
/* PowerPC 440 specific instructions */
4933
/* dlmzb */
4934
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
4935
{
4936
    gen_op_load_gpr_T0(rS(ctx->opcode));
4937
    gen_op_load_gpr_T1(rB(ctx->opcode));
4938
    gen_op_440_dlmzb();
4939
    gen_op_store_T0_gpr(rA(ctx->opcode));
4940
    gen_op_store_xer_bc();
4941
    if (Rc(ctx->opcode)) {
4942
        gen_op_440_dlmzb_update_Rc();
4943
        gen_op_store_T0_crf(0);
4944
    }
4945
}
4946

    
4947
/* mbar replaces eieio on 440 */
4948
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
4949
{
4950
    /* interpreted as no-op */
4951
}
4952

    
4953
/* msync replaces sync on 440 */
4954
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
4955
{
4956
    /* interpreted as no-op */
4957
}
4958

    
4959
/* icbt */
4960
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
4961
{
4962
    /* interpreted as no-op */
4963
    /* XXX: specification say this is treated as a load by the MMU
4964
     *      but does not generate any exception
4965
     */
4966
}
4967

    
4968
#if defined(TARGET_PPCEMB)
4969
/***                           SPE extension                               ***/
4970

    
4971
/* Register moves */
4972
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
4973
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
4974
#if 0 // unused
4975
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
4976
#endif
4977

    
4978
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
4979
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
4980
#if 0 // unused
4981
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
4982
#endif
4983

    
4984
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
4985
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
4986
{                                                                             \
4987
    if (Rc(ctx->opcode))                                                      \
4988
        gen_##name1(ctx);                                                     \
4989
    else                                                                      \
4990
        gen_##name0(ctx);                                                     \
4991
}
4992

    
4993
/* Handler for undefined SPE opcodes */
4994
static inline void gen_speundef (DisasContext *ctx)
4995
{
4996
    RET_INVAL(ctx);
4997
}
4998

    
4999
/* SPE load and stores */
5000
static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5001
{
5002
    target_long simm = rB(ctx->opcode);
5003

    
5004
    if (rA(ctx->opcode) == 0) {
5005
        gen_set_T0(simm << sh);
5006
    } else {
5007
        gen_op_load_gpr_T0(rA(ctx->opcode));
5008
        if (likely(simm != 0))
5009
            gen_op_addi(simm << sh);
5010
    }
5011
}
5012

    
5013
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5014
#if defined(CONFIG_USER_ONLY)
5015
#if defined(TARGET_PPC64)
5016
#define OP_SPE_LD_TABLE(name)                                                 \
5017
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5018
    &gen_op_spe_l##name##_raw,                                                \
5019
    &gen_op_spe_l##name##_le_raw,                                             \
5020
    &gen_op_spe_l##name##_64_raw,                                             \
5021
    &gen_op_spe_l##name##_le_64_raw,                                          \
5022
};
5023
#define OP_SPE_ST_TABLE(name)                                                 \
5024
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5025
    &gen_op_spe_st##name##_raw,                                               \
5026
    &gen_op_spe_st##name##_le_raw,                                            \
5027
    &gen_op_spe_st##name##_64_raw,                                            \
5028
    &gen_op_spe_st##name##_le_64_raw,                                         \
5029
};
5030
#else /* defined(TARGET_PPC64) */
5031
#define OP_SPE_LD_TABLE(name)                                                 \
5032
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5033
    &gen_op_spe_l##name##_raw,                                                \
5034
    &gen_op_spe_l##name##_le_raw,                                             \
5035
};
5036
#define OP_SPE_ST_TABLE(name)                                                 \
5037
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5038
    &gen_op_spe_st##name##_raw,                                               \
5039
    &gen_op_spe_st##name##_le_raw,                                            \
5040
};
5041
#endif /* defined(TARGET_PPC64) */
5042
#else /* defined(CONFIG_USER_ONLY) */
5043
#if defined(TARGET_PPC64)
5044
#define OP_SPE_LD_TABLE(name)                                                 \
5045
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5046
    &gen_op_spe_l##name##_user,                                               \
5047
    &gen_op_spe_l##name##_le_user,                                            \
5048
    &gen_op_spe_l##name##_kernel,                                             \
5049
    &gen_op_spe_l##name##_le_kernel,                                          \
5050
    &gen_op_spe_l##name##_64_user,                                            \
5051
    &gen_op_spe_l##name##_le_64_user,                                         \
5052
    &gen_op_spe_l##name##_64_kernel,                                          \
5053
    &gen_op_spe_l##name##_le_64_kernel,                                       \
5054
};
5055
#define OP_SPE_ST_TABLE(name)                                                 \
5056
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5057
    &gen_op_spe_st##name##_user,                                              \
5058
    &gen_op_spe_st##name##_le_user,                                           \
5059
    &gen_op_spe_st##name##_kernel,                                            \
5060
    &gen_op_spe_st##name##_le_kernel,                                         \
5061
    &gen_op_spe_st##name##_64_user,                                           \
5062
    &gen_op_spe_st##name##_le_64_user,                                        \
5063
    &gen_op_spe_st##name##_64_kernel,                                         \
5064
    &gen_op_spe_st##name##_le_64_kernel,                                      \
5065
};
5066
#else /* defined(TARGET_PPC64) */
5067
#define OP_SPE_LD_TABLE(name)                                                 \
5068
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5069
    &gen_op_spe_l##name##_user,                                               \
5070
    &gen_op_spe_l##name##_le_user,                                            \
5071
    &gen_op_spe_l##name##_kernel,                                             \
5072
    &gen_op_spe_l##name##_le_kernel,                                          \
5073
};
5074
#define OP_SPE_ST_TABLE(name)                                                 \
5075
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5076
    &gen_op_spe_st##name##_user,                                              \
5077
    &gen_op_spe_st##name##_le_user,                                           \
5078
    &gen_op_spe_st##name##_kernel,                                            \
5079
    &gen_op_spe_st##name##_le_kernel,                                         \
5080
};
5081
#endif /* defined(TARGET_PPC64) */
5082
#endif /* defined(CONFIG_USER_ONLY) */
5083

    
5084
#define GEN_SPE_LD(name, sh)                                                  \
5085
static inline void gen_evl##name (DisasContext *ctx)                          \
5086
{                                                                             \
5087
    if (unlikely(!ctx->spe_enabled)) {                                        \
5088
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5089
        return;                                                               \
5090
    }                                                                         \
5091
    gen_addr_spe_imm_index(ctx, sh);                                          \
5092
    op_spe_ldst(spe_l##name);                                                 \
5093
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5094
}
5095

    
5096
#define GEN_SPE_LDX(name)                                                     \
5097
static inline void gen_evl##name##x (DisasContext *ctx)                       \
5098
{                                                                             \
5099
    if (unlikely(!ctx->spe_enabled)) {                                        \
5100
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5101
        return;                                                               \
5102
    }                                                                         \
5103
    gen_addr_reg_index(ctx);                                                  \
5104
    op_spe_ldst(spe_l##name);                                                 \
5105
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5106
}
5107

    
5108
#define GEN_SPEOP_LD(name, sh)                                                \
5109
OP_SPE_LD_TABLE(name);                                                        \
5110
GEN_SPE_LD(name, sh);                                                         \
5111
GEN_SPE_LDX(name)
5112

    
5113
#define GEN_SPE_ST(name, sh)                                                  \
5114
static inline void gen_evst##name (DisasContext *ctx)                         \
5115
{                                                                             \
5116
    if (unlikely(!ctx->spe_enabled)) {                                        \
5117
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5118
        return;                                                               \
5119
    }                                                                         \
5120
    gen_addr_spe_imm_index(ctx, sh);                                          \
5121
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5122
    op_spe_ldst(spe_st##name);                                                \
5123
}
5124

    
5125
#define GEN_SPE_STX(name)                                                     \
5126
static inline void gen_evst##name##x (DisasContext *ctx)                      \
5127
{                                                                             \
5128
    if (unlikely(!ctx->spe_enabled)) {                                        \
5129
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5130
        return;                                                               \
5131
    }                                                                         \
5132
    gen_addr_reg_index(ctx);                                                  \
5133
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5134
    op_spe_ldst(spe_st##name);                                                \
5135
}
5136

    
5137
#define GEN_SPEOP_ST(name, sh)                                                \
5138
OP_SPE_ST_TABLE(name);                                                        \
5139
GEN_SPE_ST(name, sh);                                                         \
5140
GEN_SPE_STX(name)
5141

    
5142
#define GEN_SPEOP_LDST(name, sh)                                              \
5143
GEN_SPEOP_LD(name, sh);                                                       \
5144
GEN_SPEOP_ST(name, sh)
5145

    
5146
/* SPE arithmetic and logic */
5147
#define GEN_SPEOP_ARITH2(name)                                                \
5148
static inline void gen_##name (DisasContext *ctx)                             \
5149
{                                                                             \
5150
    if (unlikely(!ctx->spe_enabled)) {                                        \
5151
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5152
        return;                                                               \
5153
    }                                                                         \
5154
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5155
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5156
    gen_op_##name();                                                          \
5157
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5158
}
5159

    
5160
#define GEN_SPEOP_ARITH1(name)                                                \
5161
static inline void gen_##name (DisasContext *ctx)                             \
5162
{                                                                             \
5163
    if (unlikely(!ctx->spe_enabled)) {                                        \
5164
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5165
        return;                                                               \
5166
    }                                                                         \
5167
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5168
    gen_op_##name();                                                          \
5169
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5170
}
5171

    
5172
#define GEN_SPEOP_COMP(name)                                                  \
5173
static inline void gen_##name (DisasContext *ctx)                             \
5174
{                                                                             \
5175
    if (unlikely(!ctx->spe_enabled)) {                                        \
5176
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5177
        return;                                                               \
5178
    }                                                                         \
5179
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5180
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5181
    gen_op_##name();                                                          \
5182
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5183
}
5184

    
5185
/* Logical */
5186
GEN_SPEOP_ARITH2(evand);
5187
GEN_SPEOP_ARITH2(evandc);
5188
GEN_SPEOP_ARITH2(evxor);
5189
GEN_SPEOP_ARITH2(evor);
5190
GEN_SPEOP_ARITH2(evnor);
5191
GEN_SPEOP_ARITH2(eveqv);
5192
GEN_SPEOP_ARITH2(evorc);
5193
GEN_SPEOP_ARITH2(evnand);
5194
GEN_SPEOP_ARITH2(evsrwu);
5195
GEN_SPEOP_ARITH2(evsrws);
5196
GEN_SPEOP_ARITH2(evslw);
5197
GEN_SPEOP_ARITH2(evrlw);
5198
GEN_SPEOP_ARITH2(evmergehi);
5199
GEN_SPEOP_ARITH2(evmergelo);
5200
GEN_SPEOP_ARITH2(evmergehilo);
5201
GEN_SPEOP_ARITH2(evmergelohi);
5202

    
5203
/* Arithmetic */
5204
GEN_SPEOP_ARITH2(evaddw);
5205
GEN_SPEOP_ARITH2(evsubfw);
5206
GEN_SPEOP_ARITH1(evabs);
5207
GEN_SPEOP_ARITH1(evneg);
5208
GEN_SPEOP_ARITH1(evextsb);
5209
GEN_SPEOP_ARITH1(evextsh);
5210
GEN_SPEOP_ARITH1(evrndw);
5211
GEN_SPEOP_ARITH1(evcntlzw);
5212
GEN_SPEOP_ARITH1(evcntlsw);
5213
static inline void gen_brinc (DisasContext *ctx)
5214
{
5215
    /* Note: brinc is usable even if SPE is disabled */
5216
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5217
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5218
    gen_op_brinc();
5219
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5220
}
5221

    
5222
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5223
static inline void gen_##name##i (DisasContext *ctx)                          \
5224
{                                                                             \
5225
    if (unlikely(!ctx->spe_enabled)) {                                        \
5226
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5227
        return;                                                               \
5228
    }                                                                         \
5229
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5230
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5231
    gen_op_##name();                                                          \
5232
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5233
}
5234

    
5235
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5236
static inline void gen_##name##i (DisasContext *ctx)                          \
5237
{                                                                             \
5238
    if (unlikely(!ctx->spe_enabled)) {                                        \
5239
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5240
        return;                                                               \
5241
    }                                                                         \
5242
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5243
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5244
    gen_op_##name();                                                          \
5245
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5246
}
5247

    
5248
GEN_SPEOP_ARITH_IMM2(evaddw);
5249
#define gen_evaddiw gen_evaddwi
5250
GEN_SPEOP_ARITH_IMM2(evsubfw);
5251
#define gen_evsubifw gen_evsubfwi
5252
GEN_SPEOP_LOGIC_IMM2(evslw);
5253
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5254
#define gen_evsrwis gen_evsrwsi
5255
GEN_SPEOP_LOGIC_IMM2(evsrws);
5256
#define gen_evsrwiu gen_evsrwui
5257
GEN_SPEOP_LOGIC_IMM2(evrlw);
5258

    
5259
static inline void gen_evsplati (DisasContext *ctx)
5260
{
5261
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5262

    
5263
    gen_op_splatwi_T0_64(imm);
5264
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5265
}
5266

    
5267
static inline void gen_evsplatfi (DisasContext *ctx)
5268
{
5269
    uint32_t imm = rA(ctx->opcode) << 27;
5270

    
5271
    gen_op_splatwi_T0_64(imm);
5272
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5273
}
5274

    
5275
/* Comparison */
5276
GEN_SPEOP_COMP(evcmpgtu);
5277
GEN_SPEOP_COMP(evcmpgts);
5278
GEN_SPEOP_COMP(evcmpltu);
5279
GEN_SPEOP_COMP(evcmplts);
5280
GEN_SPEOP_COMP(evcmpeq);
5281

    
5282
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5283
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5284
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5285
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5286
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5287
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5288
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5289
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5290
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5291
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5292
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5293
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5294
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5295
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5296
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5297
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5298
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5299
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5300
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5301
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5302
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5303
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5304
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5305
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5306
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5307

    
5308
static inline void gen_evsel (DisasContext *ctx)
5309
{
5310
    if (unlikely(!ctx->spe_enabled)) {
5311
        RET_EXCP(ctx, EXCP_NO_SPE, 0);
5312
        return;
5313
    }
5314
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5315
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5316
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5317
    gen_op_evsel();
5318
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5319
}
5320

    
5321
GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5322
{
5323
    gen_evsel(ctx);
5324
}
5325
GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5326
{
5327
    gen_evsel(ctx);
5328
}
5329
GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5330
{
5331
    gen_evsel(ctx);
5332
}
5333
GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5334
{
5335
    gen_evsel(ctx);
5336
}
5337

    
5338
/* Load and stores */
5339
#if defined(TARGET_PPC64)
5340
/* In that case, we already have 64 bits load & stores
5341
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5342
 */
5343
#if defined(CONFIG_USER_ONLY)
5344
#define gen_op_spe_ldd_raw gen_op_ld_raw
5345
#define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
5346
#define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
5347
#define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
5348
#define gen_op_spe_stdd_raw gen_op_ld_raw
5349
#define gen_op_spe_stdd_64_raw gen_op_std_64_raw
5350
#define gen_op_spe_stdd_le_raw gen_op_std_le_raw
5351
#define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
5352
#else /* defined(CONFIG_USER_ONLY) */
5353
#define gen_op_spe_ldd_kernel gen_op_ld_kernel
5354
#define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
5355
#define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
5356
#define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
5357
#define gen_op_spe_ldd_user gen_op_ld_user
5358
#define gen_op_spe_ldd_64_user gen_op_ld_64_user
5359
#define gen_op_spe_ldd_le_user gen_op_ld_le_user
5360
#define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
5361
#define gen_op_spe_stdd_kernel gen_op_std_kernel
5362
#define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
5363
#define gen_op_spe_stdd_le_kernel gen_op_std_kernel
5364
#define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
5365
#define gen_op_spe_stdd_user gen_op_std_user
5366
#define gen_op_spe_stdd_64_user gen_op_std_64_user
5367
#define gen_op_spe_stdd_le_user gen_op_std_le_user
5368
#define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
5369
#endif /* defined(CONFIG_USER_ONLY) */
5370
#endif /* defined(TARGET_PPC64) */
5371
GEN_SPEOP_LDST(dd, 3);
5372
GEN_SPEOP_LDST(dw, 3);
5373
GEN_SPEOP_LDST(dh, 3);
5374
GEN_SPEOP_LDST(whe, 2);
5375
GEN_SPEOP_LD(whou, 2);
5376
GEN_SPEOP_LD(whos, 2);
5377
GEN_SPEOP_ST(who, 2);
5378

    
5379
#if defined(TARGET_PPC64)
5380
/* In that case, spe_stwwo is equivalent to stw */
5381
#if defined(CONFIG_USER_ONLY)
5382
#define gen_op_spe_stwwo_raw gen_op_stw_raw
5383
#define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
5384
#define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
5385
#define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
5386
#else
5387
#define gen_op_spe_stwwo_user gen_op_stw_user
5388
#define gen_op_spe_stwwo_le_user gen_op_stw_le_user
5389
#define gen_op_spe_stwwo_64_user gen_op_stw_64_user
5390
#define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
5391
#define gen_op_spe_stwwo_kernel gen_op_stw_kernel
5392
#define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
5393
#define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
5394
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5395
#endif
5396
#endif
5397
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5398
static inline void gen_op_spe_stwwe_##suffix (void)                           \
5399
{                                                                             \
5400
    gen_op_srli32_T1_64();                                                    \
5401
    gen_op_spe_stwwo_##suffix();                                              \
5402
}
5403
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5404
static inline void gen_op_spe_stwwe_le_##suffix (void)                        \
5405
{                                                                             \
5406
    gen_op_srli32_T1_64();                                                    \
5407
    gen_op_spe_stwwo_le_##suffix();                                           \
5408
}
5409
#if defined(TARGET_PPC64)
5410
#define GEN_OP_SPE_STWWE(suffix)                                              \
5411
_GEN_OP_SPE_STWWE(suffix);                                                    \
5412
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5413
static inline void gen_op_spe_stwwe_64_##suffix (void)                        \
5414
{                                                                             \
5415
    gen_op_srli32_T1_64();                                                    \
5416
    gen_op_spe_stwwo_64_##suffix();                                           \
5417
}                                                                             \
5418
static inline void gen_op_spe_stwwe_le_64_##suffix (void)                     \
5419
{                                                                             \
5420
    gen_op_srli32_T1_64();                                                    \
5421
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5422
}
5423
#else
5424
#define GEN_OP_SPE_STWWE(suffix)                                              \
5425
_GEN_OP_SPE_STWWE(suffix);                                                    \
5426
_GEN_OP_SPE_STWWE_LE(suffix)
5427
#endif
5428
#if defined(CONFIG_USER_ONLY)
5429
GEN_OP_SPE_STWWE(raw);
5430
#else /* defined(CONFIG_USER_ONLY) */
5431
GEN_OP_SPE_STWWE(kernel);
5432
GEN_OP_SPE_STWWE(user);
5433
#endif /* defined(CONFIG_USER_ONLY) */
5434
GEN_SPEOP_ST(wwe, 2);
5435
GEN_SPEOP_ST(wwo, 2);
5436

    
5437
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5438
static inline void gen_op_spe_l##name##_##suffix (void)                       \
5439
{                                                                             \
5440
    gen_op_##op##_##suffix();                                                 \
5441
    gen_op_splatw_T1_64();                                                    \
5442
}
5443

    
5444
#define GEN_OP_SPE_LHE(suffix)                                                \
5445
static inline void gen_op_spe_lhe_##suffix (void)                             \
5446
{                                                                             \
5447
    gen_op_spe_lh_##suffix();                                                 \
5448
    gen_op_sli16_T1_64();                                                     \
5449
}
5450

    
5451
#define GEN_OP_SPE_LHX(suffix)                                                \
5452
static inline void gen_op_spe_lhx_##suffix (void)                             \
5453
{                                                                             \
5454
    gen_op_spe_lh_##suffix();                                                 \
5455
    gen_op_extsh_T1_64();                                                     \
5456
}
5457

    
5458
#if defined(CONFIG_USER_ONLY)
5459
GEN_OP_SPE_LHE(raw);
5460
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5461
GEN_OP_SPE_LHE(le_raw);
5462
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5463
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5464
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5465
GEN_OP_SPE_LHX(raw);
5466
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5467
GEN_OP_SPE_LHX(le_raw);
5468
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5469
#if defined(TARGET_PPC64)
5470
GEN_OP_SPE_LHE(64_raw);
5471
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5472
GEN_OP_SPE_LHE(le_64_raw);
5473
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5474
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5475
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5476
GEN_OP_SPE_LHX(64_raw);
5477
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5478
GEN_OP_SPE_LHX(le_64_raw);
5479
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5480
#endif
5481
#else
5482
GEN_OP_SPE_LHE(kernel);
5483
GEN_OP_SPE_LHE(user);
5484
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5485
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5486
GEN_OP_SPE_LHE(le_kernel);
5487
GEN_OP_SPE_LHE(le_user);
5488
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5489
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5490
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5491
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5492
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5493
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5494
GEN_OP_SPE_LHX(kernel);
5495
GEN_OP_SPE_LHX(user);
5496
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5497
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5498
GEN_OP_SPE_LHX(le_kernel);
5499
GEN_OP_SPE_LHX(le_user);
5500
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5501
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5502
#if defined(TARGET_PPC64)
5503
GEN_OP_SPE_LHE(64_kernel);
5504
GEN_OP_SPE_LHE(64_user);
5505
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5506
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5507
GEN_OP_SPE_LHE(le_64_kernel);
5508
GEN_OP_SPE_LHE(le_64_user);
5509
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5510
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5511
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5512
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5513
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5514
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5515
GEN_OP_SPE_LHX(64_kernel);
5516
GEN_OP_SPE_LHX(64_user);
5517
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5518
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5519
GEN_OP_SPE_LHX(le_64_kernel);
5520
GEN_OP_SPE_LHX(le_64_user);
5521
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5522
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5523
#endif
5524
#endif
5525
GEN_SPEOP_LD(hhesplat, 1);
5526
GEN_SPEOP_LD(hhousplat, 1);
5527
GEN_SPEOP_LD(hhossplat, 1);
5528
GEN_SPEOP_LD(wwsplat, 2);
5529
GEN_SPEOP_LD(whsplat, 2);
5530

    
5531
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5532
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5533
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5534
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5535
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5536
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5537
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5538
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5539
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5540
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5541
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5542
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5543
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5544
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5545
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5546
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5547
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5548
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5549

    
5550
/* Multiply and add - TODO */
5551
#if 0
5552
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5553
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5554
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5555
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5556
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5557
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5558
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5559
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5560
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5561
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5562
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5563
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5564

5565
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5566
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5567
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5568
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5569
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5570
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5571
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5572
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5573
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5574
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5575
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5576
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5577
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5578
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5579

5580
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5581
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5582
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5583
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5584
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5585
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5586

5587
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5588
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5589
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5590
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5591
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5592
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5593
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5594
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5595
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5596
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5597
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5598
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5599

5600
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5601
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5602
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5603
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5604
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5605

5606
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5607
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5608
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5609
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5610
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5611
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5612
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5613
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5614
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5615
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5616
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5617
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5618

5619
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5620
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5621
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5622
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5623
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5624
#endif
5625

    
5626
/***                      SPE floating-point extension                     ***/
5627
#define GEN_SPEFPUOP_CONV(name)                                               \
5628
static inline void gen_##name (DisasContext *ctx)                             \
5629
{                                                                             \
5630
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5631
    gen_op_##name();                                                          \
5632
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5633
}
5634

    
5635
/* Single precision floating-point vectors operations */
5636
/* Arithmetic */
5637
GEN_SPEOP_ARITH2(evfsadd);
5638
GEN_SPEOP_ARITH2(evfssub);
5639
GEN_SPEOP_ARITH2(evfsmul);
5640
GEN_SPEOP_ARITH2(evfsdiv);
5641
GEN_SPEOP_ARITH1(evfsabs);
5642
GEN_SPEOP_ARITH1(evfsnabs);
5643
GEN_SPEOP_ARITH1(evfsneg);
5644
/* Conversion */
5645
GEN_SPEFPUOP_CONV(evfscfui);
5646
GEN_SPEFPUOP_CONV(evfscfsi);
5647
GEN_SPEFPUOP_CONV(evfscfuf);
5648
GEN_SPEFPUOP_CONV(evfscfsf);
5649
GEN_SPEFPUOP_CONV(evfsctui);
5650
GEN_SPEFPUOP_CONV(evfsctsi);
5651
GEN_SPEFPUOP_CONV(evfsctuf);
5652
GEN_SPEFPUOP_CONV(evfsctsf);
5653
GEN_SPEFPUOP_CONV(evfsctuiz);
5654
GEN_SPEFPUOP_CONV(evfsctsiz);
5655
/* Comparison */
5656
GEN_SPEOP_COMP(evfscmpgt);
5657
GEN_SPEOP_COMP(evfscmplt);
5658
GEN_SPEOP_COMP(evfscmpeq);
5659
GEN_SPEOP_COMP(evfststgt);
5660
GEN_SPEOP_COMP(evfststlt);
5661
GEN_SPEOP_COMP(evfststeq);
5662

    
5663
/* Opcodes definitions */
5664
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5665
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5666
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5667
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5668
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5669
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5670
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5671
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5672
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5673
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5674
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5675
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5676
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5677
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5678

    
5679
/* Single precision floating-point operations */
5680
/* Arithmetic */
5681
GEN_SPEOP_ARITH2(efsadd);
5682
GEN_SPEOP_ARITH2(efssub);
5683
GEN_SPEOP_ARITH2(efsmul);
5684
GEN_SPEOP_ARITH2(efsdiv);
5685
GEN_SPEOP_ARITH1(efsabs);
5686
GEN_SPEOP_ARITH1(efsnabs);
5687
GEN_SPEOP_ARITH1(efsneg);
5688
/* Conversion */
5689
GEN_SPEFPUOP_CONV(efscfui);
5690
GEN_SPEFPUOP_CONV(efscfsi);
5691
GEN_SPEFPUOP_CONV(efscfuf);
5692
GEN_SPEFPUOP_CONV(efscfsf);
5693
GEN_SPEFPUOP_CONV(efsctui);
5694
GEN_SPEFPUOP_CONV(efsctsi);
5695
GEN_SPEFPUOP_CONV(efsctuf);
5696
GEN_SPEFPUOP_CONV(efsctsf);
5697
GEN_SPEFPUOP_CONV(efsctuiz);
5698
GEN_SPEFPUOP_CONV(efsctsiz);
5699
GEN_SPEFPUOP_CONV(efscfd);
5700
/* Comparison */
5701
GEN_SPEOP_COMP(efscmpgt);
5702
GEN_SPEOP_COMP(efscmplt);
5703
GEN_SPEOP_COMP(efscmpeq);
5704
GEN_SPEOP_COMP(efststgt);
5705
GEN_SPEOP_COMP(efststlt);
5706
GEN_SPEOP_COMP(efststeq);
5707

    
5708
/* Opcodes definitions */
5709
GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5710
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5711
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5712
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5713
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5714
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5715
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5716
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5717
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5718
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5719
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5720
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5721
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5722

    
5723
/* Double precision floating-point operations */
5724
/* Arithmetic */
5725
GEN_SPEOP_ARITH2(efdadd);
5726
GEN_SPEOP_ARITH2(efdsub);
5727
GEN_SPEOP_ARITH2(efdmul);
5728
GEN_SPEOP_ARITH2(efddiv);
5729
GEN_SPEOP_ARITH1(efdabs);
5730
GEN_SPEOP_ARITH1(efdnabs);
5731
GEN_SPEOP_ARITH1(efdneg);
5732
/* Conversion */
5733

    
5734
GEN_SPEFPUOP_CONV(efdcfui);
5735
GEN_SPEFPUOP_CONV(efdcfsi);
5736
GEN_SPEFPUOP_CONV(efdcfuf);
5737
GEN_SPEFPUOP_CONV(efdcfsf);
5738
GEN_SPEFPUOP_CONV(efdctui);
5739
GEN_SPEFPUOP_CONV(efdctsi);
5740
GEN_SPEFPUOP_CONV(efdctuf);
5741
GEN_SPEFPUOP_CONV(efdctsf);
5742
GEN_SPEFPUOP_CONV(efdctuiz);
5743
GEN_SPEFPUOP_CONV(efdctsiz);
5744
GEN_SPEFPUOP_CONV(efdcfs);
5745
GEN_SPEFPUOP_CONV(efdcfuid);
5746
GEN_SPEFPUOP_CONV(efdcfsid);
5747
GEN_SPEFPUOP_CONV(efdctuidz);
5748
GEN_SPEFPUOP_CONV(efdctsidz);
5749
/* Comparison */
5750
GEN_SPEOP_COMP(efdcmpgt);
5751
GEN_SPEOP_COMP(efdcmplt);
5752
GEN_SPEOP_COMP(efdcmpeq);
5753
GEN_SPEOP_COMP(efdtstgt);
5754
GEN_SPEOP_COMP(efdtstlt);
5755
GEN_SPEOP_COMP(efdtsteq);
5756

    
5757
/* Opcodes definitions */
5758
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
5759
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
5760
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
5761
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
5762
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
5763
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
5764
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
5765
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
5766
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
5767
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
5768
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
5769
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
5770
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
5771
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
5772
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
5773
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
5774
#endif
5775

    
5776
/* End opcode list */
5777
GEN_OPCODE_MARK(end);
5778

    
5779
#include "translate_init.c"
5780

    
5781
/*****************************************************************************/
5782
/* Misc PowerPC helpers */
5783
static inline uint32_t load_xer (CPUState *env)
5784
{
5785
    return (xer_so << XER_SO) |
5786
        (xer_ov << XER_OV) |
5787
        (xer_ca << XER_CA) |
5788
        (xer_bc << XER_BC) |
5789
        (xer_cmp << XER_CMP);
5790
}
5791

    
5792
void cpu_dump_state (CPUState *env, FILE *f,
5793
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5794
                     int flags)
5795
{
5796
#if defined(TARGET_PPC64) || 1
5797
#define FILL ""
5798
#define RGPL  4
5799
#define RFPL  4
5800
#else
5801
#define FILL "        "
5802
#define RGPL  8
5803
#define RFPL  4
5804
#endif
5805

    
5806
    int i;
5807

    
5808
    cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX "\n",
5809
                env->nip, env->lr, env->ctr);
5810
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
5811
#if !defined(NO_TIMER_DUMP)
5812
                "TB %08x %08x "
5813
#if !defined(CONFIG_USER_ONLY)
5814
                "DECR %08x"
5815
#endif
5816
#endif
5817
                "\n",
5818
                do_load_msr(env), load_xer(env)
5819
#if !defined(NO_TIMER_DUMP)
5820
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
5821
#if !defined(CONFIG_USER_ONLY)
5822
                , cpu_ppc_load_decr(env)
5823
#endif
5824
#endif
5825
                );
5826
    for (i = 0; i < 32; i++) {
5827
        if ((i & (RGPL - 1)) == 0)
5828
            cpu_fprintf(f, "GPR%02d", i);
5829
        cpu_fprintf(f, " " REGX, (target_ulong)env->gpr[i]);
5830
        if ((i & (RGPL - 1)) == (RGPL - 1))
5831
            cpu_fprintf(f, "\n");
5832
    }
5833
    cpu_fprintf(f, "CR ");
5834
    for (i = 0; i < 8; i++)
5835
        cpu_fprintf(f, "%01x", env->crf[i]);
5836
    cpu_fprintf(f, "  [");
5837
    for (i = 0; i < 8; i++) {
5838
        char a = '-';
5839
        if (env->crf[i] & 0x08)
5840
            a = 'L';
5841
        else if (env->crf[i] & 0x04)
5842
            a = 'G';
5843
        else if (env->crf[i] & 0x02)
5844
            a = 'E';
5845
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
5846
    }
5847
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
5848
    for (i = 0; i < 32; i++) {
5849
        if ((i & (RFPL - 1)) == 0)
5850
            cpu_fprintf(f, "FPR%02d", i);
5851
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
5852
        if ((i & (RFPL - 1)) == (RFPL - 1))
5853
            cpu_fprintf(f, "\n");
5854
    }
5855
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
5856
                "SDR1 " REGX "\n",
5857
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
5858

    
5859
#undef RGPL
5860
#undef RFPL
5861
#undef FILL
5862
}
5863

    
5864
void cpu_dump_statistics (CPUState *env, FILE*f,
5865
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5866
                          int flags)
5867
{
5868
#if defined(DO_PPC_STATISTICS)
5869
    opc_handler_t **t1, **t2, **t3, *handler;
5870
    int op1, op2, op3;
5871

    
5872
    t1 = env->opcodes;
5873
    for (op1 = 0; op1 < 64; op1++) {
5874
        handler = t1[op1];
5875
        if (is_indirect_opcode(handler)) {
5876
            t2 = ind_table(handler);
5877
            for (op2 = 0; op2 < 32; op2++) {
5878
                handler = t2[op2];
5879
                if (is_indirect_opcode(handler)) {
5880
                    t3 = ind_table(handler);
5881
                    for (op3 = 0; op3 < 32; op3++) {
5882
                        handler = t3[op3];
5883
                        if (handler->count == 0)
5884
                            continue;
5885
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
5886
                                    "%016llx %lld\n",
5887
                                    op1, op2, op3, op1, (op3 << 5) | op2,
5888
                                    handler->oname,
5889
                                    handler->count, handler->count);
5890
                    }
5891
                } else {
5892
                    if (handler->count == 0)
5893
                        continue;
5894
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
5895
                                "%016llx %lld\n",
5896
                                op1, op2, op1, op2, handler->oname,
5897
                                handler->count, handler->count);
5898
                }
5899
            }
5900
        } else {
5901
            if (handler->count == 0)
5902
                continue;
5903
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
5904
                        op1, op1, handler->oname,
5905
                        handler->count, handler->count);
5906
        }
5907
    }
5908
#endif
5909
}
5910

    
5911
/*****************************************************************************/
5912
static inline int gen_intermediate_code_internal (CPUState *env,
5913
                                                  TranslationBlock *tb,
5914
                                                  int search_pc)
5915
{
5916
    DisasContext ctx, *ctxp = &ctx;
5917
    opc_handler_t **table, *handler;
5918
    target_ulong pc_start;
5919
    uint16_t *gen_opc_end;
5920
    int j, lj = -1;
5921

    
5922
    pc_start = tb->pc;
5923
    gen_opc_ptr = gen_opc_buf;
5924
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5925
    gen_opparam_ptr = gen_opparam_buf;
5926
    nb_gen_labels = 0;
5927
    ctx.nip = pc_start;
5928
    ctx.tb = tb;
5929
    ctx.exception = EXCP_NONE;
5930
    ctx.spr_cb = env->spr_cb;
5931
#if defined(CONFIG_USER_ONLY)
5932
    ctx.mem_idx = msr_le;
5933
#if defined(TARGET_PPC64)
5934
    ctx.mem_idx |= msr_sf << 1;
5935
#endif
5936
#else
5937
    ctx.supervisor = 1 - msr_pr;
5938
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
5939
#if defined(TARGET_PPC64)
5940
    ctx.mem_idx |= msr_sf << 2;
5941
#endif
5942
#endif
5943
#if defined(TARGET_PPC64)
5944
    ctx.sf_mode = msr_sf;
5945
#endif
5946
    ctx.fpu_enabled = msr_fp;
5947
#if defined(TARGET_PPCEMB)
5948
    ctx.spe_enabled = msr_spe;
5949
#endif
5950
    ctx.singlestep_enabled = env->singlestep_enabled;
5951
#if defined (DO_SINGLE_STEP) && 0
5952
    /* Single step trace mode */
5953
    msr_se = 1;
5954
#endif
5955
    /* Set env in case of segfault during code fetch */
5956
    while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
5957
        if (unlikely(env->nb_breakpoints > 0)) {
5958
            for (j = 0; j < env->nb_breakpoints; j++) {
5959
                if (env->breakpoints[j] == ctx.nip) {
5960
                    gen_update_nip(&ctx, ctx.nip);
5961
                    gen_op_debug();
5962
                    break;
5963
                }
5964
            }
5965
        }
5966
        if (unlikely(search_pc)) {
5967
            j = gen_opc_ptr - gen_opc_buf;
5968
            if (lj < j) {
5969
                lj++;
5970
                while (lj < j)
5971
                    gen_opc_instr_start[lj++] = 0;
5972
                gen_opc_pc[lj] = ctx.nip;
5973
                gen_opc_instr_start[lj] = 1;
5974
            }
5975
        }
5976
#if defined PPC_DEBUG_DISAS
5977
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5978
            fprintf(logfile, "----------------\n");
5979
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
5980
                    ctx.nip, 1 - msr_pr, msr_ir);
5981
        }
5982
#endif
5983
        ctx.opcode = ldl_code(ctx.nip);
5984
        if (msr_le) {
5985
            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
5986
                ((ctx.opcode & 0x00FF0000) >> 8) |
5987
                ((ctx.opcode & 0x0000FF00) << 8) |
5988
                ((ctx.opcode & 0x000000FF) << 24);
5989
        }
5990
#if defined PPC_DEBUG_DISAS
5991
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5992
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
5993
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
5994
                    opc3(ctx.opcode), msr_le ? "little" : "big");
5995
        }
5996
#endif
5997
        ctx.nip += 4;
5998
        table = env->opcodes;
5999
        handler = table[opc1(ctx.opcode)];
6000
        if (is_indirect_opcode(handler)) {
6001
            table = ind_table(handler);
6002
            handler = table[opc2(ctx.opcode)];
6003
            if (is_indirect_opcode(handler)) {
6004
                table = ind_table(handler);
6005
                handler = table[opc3(ctx.opcode)];
6006
            }
6007
        }
6008
        /* Is opcode *REALLY* valid ? */
6009
        if (unlikely(handler->handler == &gen_invalid)) {
6010
            if (loglevel != 0) {
6011
                fprintf(logfile, "invalid/unsupported opcode: "
6012
                        "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6013
                        opc1(ctx.opcode), opc2(ctx.opcode),
6014
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
6015
            } else {
6016
                printf("invalid/unsupported opcode: "
6017
                       "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6018
                       opc1(ctx.opcode), opc2(ctx.opcode),
6019
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
6020
            }
6021
        } else {
6022
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6023
                if (loglevel != 0) {
6024
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6025
                            "%02x -%02x - %02x (%08x) 0x" ADDRX "\n",
6026
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6027
                            opc2(ctx.opcode), opc3(ctx.opcode),
6028
                            ctx.opcode, ctx.nip - 4);
6029
                } else {
6030
                    printf("invalid bits: %08x for opcode: "
6031
                           "%02x -%02x - %02x (%08x) 0x" ADDRX "\n",
6032
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6033
                           opc2(ctx.opcode), opc3(ctx.opcode),
6034
                           ctx.opcode, ctx.nip - 4);
6035
                }
6036
                RET_INVAL(ctxp);
6037
                break;
6038
            }
6039
        }
6040
        (*(handler->handler))(&ctx);
6041
#if defined(DO_PPC_STATISTICS)
6042
        handler->count++;
6043
#endif
6044
        /* Check trace mode exceptions */
6045
#if 0 // XXX: buggy on embedded PowerPC
6046
        if (unlikely((msr_be && ctx.exception == EXCP_BRANCH) ||
6047
                     /* Check in single step trace mode
6048
                      * we need to stop except if:
6049
                      * - rfi, trap or syscall
6050
                      * - first instruction of an exception handler
6051
                      */
6052
                     (msr_se && (ctx.nip < 0x100 ||
6053
                                 ctx.nip > 0xF00 ||
6054
                                 (ctx.nip & 0xFC) != 0x04) &&
6055
                      ctx.exception != EXCP_SYSCALL &&
6056
                      ctx.exception != EXCP_SYSCALL_USER &&
6057
                      ctx.exception != EXCP_TRAP))) {
6058
            RET_EXCP(ctxp, EXCP_TRACE, 0);
6059
        }
6060
#endif
6061
        /* if we reach a page boundary or are single stepping, stop
6062
         * generation
6063
         */
6064
        if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6065
                     (env->singlestep_enabled))) {
6066
            break;
6067
        }
6068
#if defined (DO_SINGLE_STEP)
6069
        break;
6070
#endif
6071
    }
6072
    if (ctx.exception == EXCP_NONE) {
6073
        gen_goto_tb(&ctx, 0, ctx.nip);
6074
    } else if (ctx.exception != EXCP_BRANCH) {
6075
        gen_op_reset_T0();
6076
        /* Generate the return instruction */
6077
        gen_op_exit_tb();
6078
    }
6079
    *gen_opc_ptr = INDEX_op_end;
6080
    if (unlikely(search_pc)) {
6081
        j = gen_opc_ptr - gen_opc_buf;
6082
        lj++;
6083
        while (lj <= j)
6084
            gen_opc_instr_start[lj++] = 0;
6085
    } else {
6086
        tb->size = ctx.nip - pc_start;
6087
    }
6088
#if defined(DEBUG_DISAS)
6089
    if (loglevel & CPU_LOG_TB_CPU) {
6090
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6091
        cpu_dump_state(env, logfile, fprintf, 0);
6092
    }
6093
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6094
        int flags;
6095
        flags = msr_le;
6096
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6097
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6098
        fprintf(logfile, "\n");
6099
    }
6100
    if (loglevel & CPU_LOG_TB_OP) {
6101
        fprintf(logfile, "OP:\n");
6102
        dump_ops(gen_opc_buf, gen_opparam_buf);
6103
        fprintf(logfile, "\n");
6104
    }
6105
#endif
6106
    return 0;
6107
}
6108

    
6109
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6110
{
6111
    return gen_intermediate_code_internal(env, tb, 0);
6112
}
6113

    
6114
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6115
{
6116
    return gen_intermediate_code_internal(env, tb, 1);
6117
}