Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 40d0591e

History | View | Annotate | Download (205.2 kB)

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

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

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

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

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

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

    
54
#include "gen-op.h"
55

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

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

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

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

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

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

    
120
/* Floating point condition and status register moves */
121
GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
122
GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
123
GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
124
static inline void gen_op_store_T0_fpscri (int n, uint8_t param)
125
{
126
    gen_op_set_T0(param);
127
    gen_op_store_T0_fpscr(n);
128
}
129

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

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

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

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

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

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

    
200
static inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
201
{
202
#if defined(TARGET_PPC64)
203
    if (ctx->sf_mode)
204
        gen_op_update_nip_64(nip >> 32, nip);
205
    else
206
#endif
207
        gen_op_update_nip(nip);
208
}
209

    
210
#define 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_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1343
{
1344
    if (mask >> 32)
1345
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1346
    else
1347
        gen_op_andi_T0(mask);
1348
}
1349

    
1350
static inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1351
{
1352
    if (mask >> 32)
1353
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1354
    else
1355
        gen_op_andi_T1(mask);
1356
}
1357

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

    
1392
    sh = SH(ctx->opcode) | (shn << 5);
1393
    mb = MB(ctx->opcode) | (mbn << 5);
1394
    gen_rldinm(ctx, mb, 63, sh);
1395
}
1396
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1397
/* rldicr - rldicr. */
1398
static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1399
{
1400
    uint32_t sh, me;
1401

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

    
1412
    sh = SH(ctx->opcode) | (shn << 5);
1413
    mb = MB(ctx->opcode) | (mbn << 5);
1414
    gen_rldinm(ctx, mb, 63 - sh, sh);
1415
}
1416
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1417

    
1418
static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me)
1419
{
1420
    gen_op_load_gpr_T0(rS(ctx->opcode));
1421
    gen_op_load_gpr_T1(rB(ctx->opcode));
1422
    gen_op_rotl64_T0_T1();
1423
    if (unlikely(mb != 0 || me != 63)) {
1424
        gen_andi_T0_64(ctx, MASK(mb, me));
1425
    }
1426
    gen_op_store_T0_gpr(rA(ctx->opcode));
1427
    if (unlikely(Rc(ctx->opcode) != 0))
1428
        gen_set_Rc0(ctx);
1429
}
1430

    
1431
/* rldcl - rldcl. */
1432
static inline void gen_rldcl (DisasContext *ctx, int mbn)
1433
{
1434
    uint32_t mb;
1435

    
1436
    mb = MB(ctx->opcode) | (mbn << 5);
1437
    gen_rldnm(ctx, mb, 63);
1438
}
1439
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1440
/* rldcr - rldcr. */
1441
static inline void gen_rldcr (DisasContext *ctx, int men)
1442
{
1443
    uint32_t me;
1444

    
1445
    me = MB(ctx->opcode) | (men << 5);
1446
    gen_rldnm(ctx, 0, me);
1447
}
1448
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1449
/* rldimi - rldimi. */
1450
static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1451
{
1452
    uint64_t mask;
1453
    uint32_t sh, mb;
1454

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

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

    
1512
#if defined(TARGET_PPC64)
1513
/* sld & sld. */
1514
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1515
/* srad & srad. */
1516
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1517
/* sradi & sradi. */
1518
static inline void gen_sradi (DisasContext *ctx, int n)
1519
{
1520
    uint64_t mask;
1521
    int sh, mb, me;
1522

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

    
1548
/***                       Floating-Point arithmetic                       ***/
1549
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, type)                     \
1550
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1551
{                                                                             \
1552
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1553
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1554
        return;                                                               \
1555
    }                                                                         \
1556
    gen_op_reset_scrfx();                                                     \
1557
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1558
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1559
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1560
    gen_op_f##op();                                                           \
1561
    if (isfloat) {                                                            \
1562
        gen_op_frsp();                                                        \
1563
    }                                                                         \
1564
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1565
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1566
        gen_op_set_Rc1();                                                     \
1567
}
1568

    
1569
#define GEN_FLOAT_ACB(name, op2, type)                                        \
1570
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, type);                               \
1571
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type);
1572

    
1573
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
1574
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1575
{                                                                             \
1576
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1577
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1578
        return;                                                               \
1579
    }                                                                         \
1580
    gen_op_reset_scrfx();                                                     \
1581
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1582
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1583
    gen_op_f##op();                                                           \
1584
    if (isfloat) {                                                            \
1585
        gen_op_frsp();                                                        \
1586
    }                                                                         \
1587
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1588
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1589
        gen_op_set_Rc1();                                                     \
1590
}
1591
#define GEN_FLOAT_AB(name, op2, inval)                                        \
1592
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
1593
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1594

    
1595
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
1596
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1597
{                                                                             \
1598
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1599
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1600
        return;                                                               \
1601
    }                                                                         \
1602
    gen_op_reset_scrfx();                                                     \
1603
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1604
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1605
    gen_op_f##op();                                                           \
1606
    if (isfloat) {                                                            \
1607
        gen_op_frsp();                                                        \
1608
    }                                                                         \
1609
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1610
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1611
        gen_op_set_Rc1();                                                     \
1612
}
1613
#define GEN_FLOAT_AC(name, op2, inval)                                        \
1614
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
1615
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1616

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

    
1632
#define GEN_FLOAT_BS(name, op1, op2, type)                                    \
1633
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1634
{                                                                             \
1635
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1636
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1637
        return;                                                               \
1638
    }                                                                         \
1639
    gen_op_reset_scrfx();                                                     \
1640
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1641
    gen_op_f##name();                                                         \
1642
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1643
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1644
        gen_op_set_Rc1();                                                     \
1645
}
1646

    
1647
/* fadd - fadds */
1648
GEN_FLOAT_AB(add, 0x15, 0x000007C0);
1649
/* fdiv - fdivs */
1650
GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1651
/* fmul - fmuls */
1652
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1653

    
1654
/* fres */
1655
GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
1656

    
1657
/* frsqrte */
1658
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, PPC_FLOAT_FRSQRTE);
1659

    
1660
/* fsel */
1661
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, PPC_FLOAT_FSEL);
1662
/* fsub - fsubs */
1663
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1664
/* Optional: */
1665
/* fsqrt */
1666
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1667
{
1668
    if (unlikely(!ctx->fpu_enabled)) {
1669
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1670
        return;
1671
    }
1672
    gen_op_reset_scrfx();
1673
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1674
    gen_op_fsqrt();
1675
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1676
    if (unlikely(Rc(ctx->opcode) != 0))
1677
        gen_op_set_Rc1();
1678
}
1679

    
1680
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1681
{
1682
    if (unlikely(!ctx->fpu_enabled)) {
1683
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1684
        return;
1685
    }
1686
    gen_op_reset_scrfx();
1687
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1688
    gen_op_fsqrt();
1689
    gen_op_frsp();
1690
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1691
    if (unlikely(Rc(ctx->opcode) != 0))
1692
        gen_op_set_Rc1();
1693
}
1694

    
1695
/***                     Floating-Point multiply-and-add                   ***/
1696
/* fmadd - fmadds */
1697
GEN_FLOAT_ACB(madd, 0x1D, PPC_FLOAT);
1698
/* fmsub - fmsubs */
1699
GEN_FLOAT_ACB(msub, 0x1C, PPC_FLOAT);
1700
/* fnmadd - fnmadds */
1701
GEN_FLOAT_ACB(nmadd, 0x1F, PPC_FLOAT);
1702
/* fnmsub - fnmsubs */
1703
GEN_FLOAT_ACB(nmsub, 0x1E, PPC_FLOAT);
1704

    
1705
/***                     Floating-Point round & convert                    ***/
1706
/* fctiw */
1707
GEN_FLOAT_B(ctiw, 0x0E, 0x00, PPC_FLOAT);
1708
/* fctiwz */
1709
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, PPC_FLOAT);
1710
/* frsp */
1711
GEN_FLOAT_B(rsp, 0x0C, 0x00, PPC_FLOAT);
1712
#if defined(TARGET_PPC64)
1713
/* fcfid */
1714
GEN_FLOAT_B(cfid, 0x0E, 0x1A, PPC_64B);
1715
/* fctid */
1716
GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
1717
/* fctidz */
1718
GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
1719
#endif
1720

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

    
1736
/* fcmpu */
1737
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1738
{
1739
    if (unlikely(!ctx->fpu_enabled)) {
1740
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1741
        return;
1742
    }
1743
    gen_op_reset_scrfx();
1744
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1745
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1746
    gen_op_fcmpu();
1747
    gen_op_store_T0_crf(crfD(ctx->opcode));
1748
}
1749

    
1750
/***                         Floating-point move                           ***/
1751
/* fabs */
1752
GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT);
1753

    
1754
/* fmr  - fmr. */
1755
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1756
{
1757
    if (unlikely(!ctx->fpu_enabled)) {
1758
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1759
        return;
1760
    }
1761
    gen_op_reset_scrfx();
1762
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1763
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1764
    if (unlikely(Rc(ctx->opcode) != 0))
1765
        gen_op_set_Rc1();
1766
}
1767

    
1768
/* fnabs */
1769
GEN_FLOAT_B(nabs, 0x08, 0x04, PPC_FLOAT);
1770
/* fneg */
1771
GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT);
1772

    
1773
/***                  Floating-Point status & ctrl register                ***/
1774
/* mcrfs */
1775
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1776
{
1777
    if (unlikely(!ctx->fpu_enabled)) {
1778
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1779
        return;
1780
    }
1781
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
1782
    gen_op_store_T0_crf(crfD(ctx->opcode));
1783
    gen_op_clear_fpscr(crfS(ctx->opcode));
1784
}
1785

    
1786
/* mffs */
1787
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1788
{
1789
    if (unlikely(!ctx->fpu_enabled)) {
1790
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1791
        return;
1792
    }
1793
    gen_op_load_fpscr();
1794
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1795
    if (unlikely(Rc(ctx->opcode) != 0))
1796
        gen_op_set_Rc1();
1797
}
1798

    
1799
/* mtfsb0 */
1800
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1801
{
1802
    uint8_t crb;
1803

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

    
1816
/* mtfsb1 */
1817
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1818
{
1819
    uint8_t crb;
1820

    
1821
    if (unlikely(!ctx->fpu_enabled)) {
1822
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1823
        return;
1824
    }
1825
    crb = crbD(ctx->opcode) >> 2;
1826
    gen_op_load_fpscr_T0(crb);
1827
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1828
    gen_op_store_T0_fpscr(crb);
1829
    if (unlikely(Rc(ctx->opcode) != 0))
1830
        gen_op_set_Rc1();
1831
}
1832

    
1833
/* mtfsf */
1834
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1835
{
1836
    if (unlikely(!ctx->fpu_enabled)) {
1837
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1838
        return;
1839
    }
1840
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1841
    gen_op_store_fpscr(FM(ctx->opcode));
1842
    if (unlikely(Rc(ctx->opcode) != 0))
1843
        gen_op_set_Rc1();
1844
}
1845

    
1846
/* mtfsfi */
1847
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1848
{
1849
    if (unlikely(!ctx->fpu_enabled)) {
1850
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1851
        return;
1852
    }
1853
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1854
    if (unlikely(Rc(ctx->opcode) != 0))
1855
        gen_op_set_Rc1();
1856
}
1857

    
1858
/***                           Addressing modes                            ***/
1859
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1860
static inline void gen_addr_imm_index (DisasContext *ctx, int maskl)
1861
{
1862
    target_long simm = SIMM(ctx->opcode);
1863

    
1864
    if (maskl)
1865
        simm &= ~0x03;
1866
    if (rA(ctx->opcode) == 0) {
1867
        gen_set_T0(simm);
1868
    } else {
1869
        gen_op_load_gpr_T0(rA(ctx->opcode));
1870
        if (likely(simm != 0))
1871
            gen_op_addi(simm);
1872
    }
1873
#ifdef DEBUG_MEMORY_ACCESSES
1874
    gen_op_print_mem_EA();
1875
#endif
1876
}
1877

    
1878
static inline void gen_addr_reg_index (DisasContext *ctx)
1879
{
1880
    if (rA(ctx->opcode) == 0) {
1881
        gen_op_load_gpr_T0(rB(ctx->opcode));
1882
    } else {
1883
        gen_op_load_gpr_T0(rA(ctx->opcode));
1884
        gen_op_load_gpr_T1(rB(ctx->opcode));
1885
        gen_op_add();
1886
    }
1887
#ifdef DEBUG_MEMORY_ACCESSES
1888
    gen_op_print_mem_EA();
1889
#endif
1890
}
1891

    
1892
static inline void gen_addr_register (DisasContext *ctx)
1893
{
1894
    if (rA(ctx->opcode) == 0) {
1895
        gen_op_reset_T0();
1896
    } else {
1897
        gen_op_load_gpr_T0(rA(ctx->opcode));
1898
    }
1899
#ifdef DEBUG_MEMORY_ACCESSES
1900
    gen_op_print_mem_EA();
1901
#endif
1902
}
1903

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

    
1992
#define GEN_LD(width, opc, type)                                              \
1993
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
1994
{                                                                             \
1995
    gen_addr_imm_index(ctx, 0);                                               \
1996
    op_ldst(l##width);                                                        \
1997
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1998
}
1999

    
2000
#define GEN_LDU(width, opc, type)                                             \
2001
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2002
{                                                                             \
2003
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2004
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2005
        RET_INVAL(ctx);                                                       \
2006
        return;                                                               \
2007
    }                                                                         \
2008
    if (type == PPC_64B)                                                      \
2009
        gen_addr_imm_index(ctx, 1);                                           \
2010
    else                                                                      \
2011
        gen_addr_imm_index(ctx, 0);                                           \
2012
    op_ldst(l##width);                                                        \
2013
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2014
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2015
}
2016

    
2017
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2018
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2019
{                                                                             \
2020
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2021
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2022
        RET_INVAL(ctx);                                                       \
2023
        return;                                                               \
2024
    }                                                                         \
2025
    gen_addr_reg_index(ctx);                                                  \
2026
    op_ldst(l##width);                                                        \
2027
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2028
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2029
}
2030

    
2031
#define GEN_LDX(width, opc2, opc3, type)                                      \
2032
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2033
{                                                                             \
2034
    gen_addr_reg_index(ctx);                                                  \
2035
    op_ldst(l##width);                                                        \
2036
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2037
}
2038

    
2039
#define GEN_LDS(width, op, type)                                              \
2040
OP_LD_TABLE(width);                                                           \
2041
GEN_LD(width, op | 0x20, type);                                               \
2042
GEN_LDU(width, op | 0x21, type);                                              \
2043
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2044
GEN_LDX(width, 0x17, op | 0x00, type)
2045

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

    
2088
/***                              Integer store                            ***/
2089
#define GEN_ST(width, opc, type)                                              \
2090
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2091
{                                                                             \
2092
    gen_addr_imm_index(ctx, 0);                                               \
2093
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2094
    op_ldst(st##width);                                                       \
2095
}
2096

    
2097
#define GEN_STU(width, opc, type)                                             \
2098
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2099
{                                                                             \
2100
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2101
        RET_INVAL(ctx);                                                       \
2102
        return;                                                               \
2103
    }                                                                         \
2104
    if (type == PPC_64B)                                                      \
2105
        gen_addr_imm_index(ctx, 1);                                           \
2106
    else                                                                      \
2107
        gen_addr_imm_index(ctx, 0);                                           \
2108
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2109
    op_ldst(st##width);                                                       \
2110
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2111
}
2112

    
2113
#define GEN_STUX(width, opc2, opc3, type)                                     \
2114
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2115
{                                                                             \
2116
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2117
        RET_INVAL(ctx);                                                       \
2118
        return;                                                               \
2119
    }                                                                         \
2120
    gen_addr_reg_index(ctx);                                                  \
2121
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2122
    op_ldst(st##width);                                                       \
2123
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2124
}
2125

    
2126
#define GEN_STX(width, opc2, opc3, type)                                      \
2127
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2128
{                                                                             \
2129
    gen_addr_reg_index(ctx);                                                  \
2130
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2131
    op_ldst(st##width);                                                       \
2132
}
2133

    
2134
#define GEN_STS(width, op, type)                                              \
2135
OP_ST_TABLE(width);                                                           \
2136
GEN_ST(width, op | 0x20, type);                                               \
2137
GEN_STU(width, op | 0x21, type);                                              \
2138
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2139
GEN_STX(width, 0x17, op | 0x00, type)
2140

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

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

    
2242
/* lmw */
2243
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2244
{
2245
    /* NIP cannot be restored if the memory exception comes from an helper */
2246
    gen_update_nip(ctx, ctx->nip - 4);
2247
    gen_addr_imm_index(ctx, 0);
2248
    op_ldstm(lmw, rD(ctx->opcode));
2249
}
2250

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

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

    
2351
/* lswi */
2352
/* PowerPC32 specification says we must generate an exception if
2353
 * rA is in the range of registers to be loaded.
2354
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2355
 * For now, I'll follow the spec...
2356
 */
2357
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
2358
{
2359
    int nb = NB(ctx->opcode);
2360
    int start = rD(ctx->opcode);
2361
    int ra = rA(ctx->opcode);
2362
    int nr;
2363

    
2364
    if (nb == 0)
2365
        nb = 32;
2366
    nr = nb / 4;
2367
    if (unlikely(((start + nr) > 32  &&
2368
                  start <= ra && (start + nr - 32) > ra) ||
2369
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2370
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
2371
        return;
2372
    }
2373
    /* NIP cannot be restored if the memory exception comes from an helper */
2374
    gen_update_nip(ctx, ctx->nip - 4);
2375
    gen_addr_register(ctx);
2376
    gen_op_set_T1(nb);
2377
    op_ldsts(lswi, start);
2378
}
2379

    
2380
/* lswx */
2381
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
2382
{
2383
    int ra = rA(ctx->opcode);
2384
    int rb = rB(ctx->opcode);
2385

    
2386
    /* NIP cannot be restored if the memory exception comes from an helper */
2387
    gen_update_nip(ctx, ctx->nip - 4);
2388
    gen_addr_reg_index(ctx);
2389
    if (ra == 0) {
2390
        ra = rb;
2391
    }
2392
    gen_op_load_xer_bc();
2393
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2394
}
2395

    
2396
/* stswi */
2397
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
2398
{
2399
    int nb = NB(ctx->opcode);
2400

    
2401
    /* NIP cannot be restored if the memory exception comes from an helper */
2402
    gen_update_nip(ctx, ctx->nip - 4);
2403
    gen_addr_register(ctx);
2404
    if (nb == 0)
2405
        nb = 32;
2406
    gen_op_set_T1(nb);
2407
    op_ldsts(stsw, rS(ctx->opcode));
2408
}
2409

    
2410
/* stswx */
2411
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
2412
{
2413
    /* NIP cannot be restored if the memory exception comes from an helper */
2414
    gen_update_nip(ctx, ctx->nip - 4);
2415
    gen_addr_reg_index(ctx);
2416
    gen_op_load_xer_bc();
2417
    op_ldsts(stsw, rS(ctx->opcode));
2418
}
2419

    
2420
/***                        Memory synchronisation                         ***/
2421
/* eieio */
2422
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
2423
{
2424
}
2425

    
2426
/* isync */
2427
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
2428
{
2429
}
2430

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

    
2495
/* lwarx */
2496
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2497
{
2498
    gen_addr_reg_index(ctx);
2499
    op_lwarx();
2500
    gen_op_store_T1_gpr(rD(ctx->opcode));
2501
}
2502

    
2503
/* stwcx. */
2504
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2505
{
2506
    gen_addr_reg_index(ctx);
2507
    gen_op_load_gpr_T1(rS(ctx->opcode));
2508
    op_stwcx();
2509
}
2510

    
2511
#if defined(TARGET_PPC64)
2512
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2513
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2514
#if defined(CONFIG_USER_ONLY)
2515
static GenOpFunc *gen_op_ldarx[] = {
2516
    &gen_op_ldarx_raw,
2517
    &gen_op_ldarx_le_raw,
2518
    &gen_op_ldarx_64_raw,
2519
    &gen_op_ldarx_le_64_raw,
2520
};
2521
static GenOpFunc *gen_op_stdcx[] = {
2522
    &gen_op_stdcx_raw,
2523
    &gen_op_stdcx_le_raw,
2524
    &gen_op_stdcx_64_raw,
2525
    &gen_op_stdcx_le_64_raw,
2526
};
2527
#else
2528
static GenOpFunc *gen_op_ldarx[] = {
2529
    &gen_op_ldarx_user,
2530
    &gen_op_ldarx_le_user,
2531
    &gen_op_ldarx_kernel,
2532
    &gen_op_ldarx_le_kernel,
2533
    &gen_op_ldarx_64_user,
2534
    &gen_op_ldarx_le_64_user,
2535
    &gen_op_ldarx_64_kernel,
2536
    &gen_op_ldarx_le_64_kernel,
2537
};
2538
static GenOpFunc *gen_op_stdcx[] = {
2539
    &gen_op_stdcx_user,
2540
    &gen_op_stdcx_le_user,
2541
    &gen_op_stdcx_kernel,
2542
    &gen_op_stdcx_le_kernel,
2543
    &gen_op_stdcx_64_user,
2544
    &gen_op_stdcx_le_64_user,
2545
    &gen_op_stdcx_64_kernel,
2546
    &gen_op_stdcx_le_64_kernel,
2547
};
2548
#endif
2549

    
2550
/* ldarx */
2551
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2552
{
2553
    gen_addr_reg_index(ctx);
2554
    op_ldarx();
2555
    gen_op_store_T1_gpr(rD(ctx->opcode));
2556
}
2557

    
2558
/* stdcx. */
2559
GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2560
{
2561
    gen_addr_reg_index(ctx);
2562
    gen_op_load_gpr_T1(rS(ctx->opcode));
2563
    op_stdcx();
2564
}
2565
#endif /* defined(TARGET_PPC64) */
2566

    
2567
/* sync */
2568
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
2569
{
2570
}
2571

    
2572
/***                         Floating-point load                           ***/
2573
#define GEN_LDF(width, opc)                                                   \
2574
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                 \
2575
{                                                                             \
2576
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2577
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
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
}
2584

    
2585
#define GEN_LDUF(width, opc)                                                  \
2586
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)              \
2587
{                                                                             \
2588
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2589
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2590
        return;                                                               \
2591
    }                                                                         \
2592
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2593
        RET_INVAL(ctx);                                                       \
2594
        return;                                                               \
2595
    }                                                                         \
2596
    gen_addr_imm_index(ctx, 0);                                               \
2597
    op_ldst(l##width);                                                        \
2598
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2599
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2600
}
2601

    
2602
#define GEN_LDUXF(width, opc)                                                 \
2603
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
2604
{                                                                             \
2605
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2606
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2607
        return;                                                               \
2608
    }                                                                         \
2609
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2610
        RET_INVAL(ctx);                                                       \
2611
        return;                                                               \
2612
    }                                                                         \
2613
    gen_addr_reg_index(ctx);                                                  \
2614
    op_ldst(l##width);                                                        \
2615
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2616
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2617
}
2618

    
2619
#define GEN_LDXF(width, opc2, opc3)                                           \
2620
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)             \
2621
{                                                                             \
2622
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2623
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2624
        return;                                                               \
2625
    }                                                                         \
2626
    gen_addr_reg_index(ctx);                                                  \
2627
    op_ldst(l##width);                                                        \
2628
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2629
}
2630

    
2631
#define GEN_LDFS(width, op)                                                   \
2632
OP_LD_TABLE(width);                                                           \
2633
GEN_LDF(width, op | 0x20);                                                    \
2634
GEN_LDUF(width, op | 0x21);                                                   \
2635
GEN_LDUXF(width, op | 0x01);                                                  \
2636
GEN_LDXF(width, 0x17, op | 0x00)
2637

    
2638
/* lfd lfdu lfdux lfdx */
2639
GEN_LDFS(fd, 0x12);
2640
/* lfs lfsu lfsux lfsx */
2641
GEN_LDFS(fs, 0x10);
2642

    
2643
/***                         Floating-point store                          ***/
2644
#define GEN_STF(width, opc)                                                   \
2645
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
2646
{                                                                             \
2647
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2648
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
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
}
2655

    
2656
#define GEN_STUF(width, opc)                                                  \
2657
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
2658
{                                                                             \
2659
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2660
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2661
        return;                                                               \
2662
    }                                                                         \
2663
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2664
        RET_INVAL(ctx);                                                       \
2665
        return;                                                               \
2666
    }                                                                         \
2667
    gen_addr_imm_index(ctx, 0);                                               \
2668
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2669
    op_ldst(st##width);                                                       \
2670
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2671
}
2672

    
2673
#define GEN_STUXF(width, opc)                                                 \
2674
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
2675
{                                                                             \
2676
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2677
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2678
        return;                                                               \
2679
    }                                                                         \
2680
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2681
        RET_INVAL(ctx);                                                       \
2682
        return;                                                               \
2683
    }                                                                         \
2684
    gen_addr_reg_index(ctx);                                                  \
2685
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2686
    op_ldst(st##width);                                                       \
2687
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2688
}
2689

    
2690
#define GEN_STXF(width, opc2, opc3)                                           \
2691
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)            \
2692
{                                                                             \
2693
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2694
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2695
        return;                                                               \
2696
    }                                                                         \
2697
    gen_addr_reg_index(ctx);                                                  \
2698
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2699
    op_ldst(st##width);                                                       \
2700
}
2701

    
2702
#define GEN_STFS(width, op)                                                   \
2703
OP_ST_TABLE(width);                                                           \
2704
GEN_STF(width, op | 0x20);                                                    \
2705
GEN_STUF(width, op | 0x21);                                                   \
2706
GEN_STUXF(width, op | 0x01);                                                  \
2707
GEN_STXF(width, 0x17, op | 0x00)
2708

    
2709
/* stfd stfdu stfdux stfdx */
2710
GEN_STFS(fd, 0x16);
2711
/* stfs stfsu stfsux stfsx */
2712
GEN_STFS(fs, 0x14);
2713

    
2714
/* Optional: */
2715
/* stfiwx */
2716
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT_STFIWX)
2717
{
2718
    if (unlikely(!ctx->fpu_enabled)) {
2719
        RET_EXCP(ctx, EXCP_NO_FP, 0);
2720
        return;
2721
    }
2722
    gen_addr_reg_index(ctx);
2723
    /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2724
    RET_INVAL(ctx);
2725
}
2726

    
2727
/***                                Branch                                 ***/
2728
static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
2729
{
2730
    TranslationBlock *tb;
2731
    tb = ctx->tb;
2732
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2733
        if (n == 0)
2734
            gen_op_goto_tb0(TBPARAM(tb));
2735
        else
2736
            gen_op_goto_tb1(TBPARAM(tb));
2737
        gen_set_T1(dest);
2738
#if defined(TARGET_PPC64)
2739
        if (ctx->sf_mode)
2740
            gen_op_b_T1_64();
2741
        else
2742
#endif
2743
            gen_op_b_T1();
2744
        gen_op_set_T0((long)tb + n);
2745
        if (ctx->singlestep_enabled)
2746
            gen_op_debug();
2747
        gen_op_exit_tb();
2748
    } else {
2749
        gen_set_T1(dest);
2750
#if defined(TARGET_PPC64)
2751
        if (ctx->sf_mode)
2752
            gen_op_b_T1_64();
2753
        else
2754
#endif
2755
            gen_op_b_T1();
2756
        gen_op_reset_T0();
2757
        if (ctx->singlestep_enabled)
2758
            gen_op_debug();
2759
        gen_op_exit_tb();
2760
    }
2761
}
2762

    
2763
/* b ba bl bla */
2764
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2765
{
2766
    target_ulong li, target;
2767

    
2768
    /* sign extend LI */
2769
#if defined(TARGET_PPC64)
2770
    if (ctx->sf_mode)
2771
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2772
    else
2773
#endif
2774
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2775
    if (likely(AA(ctx->opcode) == 0))
2776
        target = ctx->nip + li - 4;
2777
    else
2778
        target = li;
2779
    if (LK(ctx->opcode)) {
2780
#if defined(TARGET_PPC64)
2781
        if (ctx->sf_mode)
2782
            gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2783
        else
2784
#endif
2785
            gen_op_setlr(ctx->nip);
2786
    }
2787
    gen_goto_tb(ctx, 0, target);
2788
    ctx->exception = EXCP_BRANCH;
2789
}
2790

    
2791
#define BCOND_IM  0
2792
#define BCOND_LR  1
2793
#define BCOND_CTR 2
2794

    
2795
static inline void gen_bcond (DisasContext *ctx, int type)
2796
{
2797
    target_ulong target = 0;
2798
    target_ulong li;
2799
    uint32_t bo = BO(ctx->opcode);
2800
    uint32_t bi = BI(ctx->opcode);
2801
    uint32_t mask;
2802

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

    
2940
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2941
{
2942
    gen_bcond(ctx, BCOND_IM);
2943
}
2944

    
2945
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
2946
{
2947
    gen_bcond(ctx, BCOND_CTR);
2948
}
2949

    
2950
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
2951
{
2952
    gen_bcond(ctx, BCOND_LR);
2953
}
2954

    
2955
/***                      Condition register logical                       ***/
2956
#define GEN_CRLOGIC(op, opc)                                                  \
2957
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
2958
{                                                                             \
2959
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
2960
    gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
2961
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
2962
    gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
2963
    gen_op_##op();                                                            \
2964
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
2965
    gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
2966
                     3 - (crbD(ctx->opcode) & 0x03));                         \
2967
    gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
2968
}
2969

    
2970
/* crand */
2971
GEN_CRLOGIC(and, 0x08);
2972
/* crandc */
2973
GEN_CRLOGIC(andc, 0x04);
2974
/* creqv */
2975
GEN_CRLOGIC(eqv, 0x09);
2976
/* crnand */
2977
GEN_CRLOGIC(nand, 0x07);
2978
/* crnor */
2979
GEN_CRLOGIC(nor, 0x01);
2980
/* cror */
2981
GEN_CRLOGIC(or, 0x0E);
2982
/* crorc */
2983
GEN_CRLOGIC(orc, 0x0D);
2984
/* crxor */
2985
GEN_CRLOGIC(xor, 0x06);
2986
/* mcrf */
2987
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
2988
{
2989
    gen_op_load_crf_T0(crfS(ctx->opcode));
2990
    gen_op_store_T0_crf(crfD(ctx->opcode));
2991
}
2992

    
2993
/***                           System linkage                              ***/
2994
/* rfi (supervisor only) */
2995
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
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_rfi();
3006
    RET_CHG_FLOW(ctx);
3007
#endif
3008
}
3009

    
3010
#if defined(TARGET_PPC64)
3011
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3012
{
3013
#if defined(CONFIG_USER_ONLY)
3014
    RET_PRIVOPC(ctx);
3015
#else
3016
    /* Restore CPU state */
3017
    if (unlikely(!ctx->supervisor)) {
3018
        RET_PRIVOPC(ctx);
3019
        return;
3020
    }
3021
    gen_op_rfid();
3022
    RET_CHG_FLOW(ctx);
3023
#endif
3024
}
3025
#endif
3026

    
3027
/* sc */
3028
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
3029
{
3030
#if defined(CONFIG_USER_ONLY)
3031
    RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
3032
#else
3033
    RET_EXCP(ctx, EXCP_SYSCALL, 0);
3034
#endif
3035
}
3036

    
3037
/***                                Trap                                   ***/
3038
/* tw */
3039
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3040
{
3041
    gen_op_load_gpr_T0(rA(ctx->opcode));
3042
    gen_op_load_gpr_T1(rB(ctx->opcode));
3043
    /* Update the nip since this might generate a trap exception */
3044
    gen_update_nip(ctx, ctx->nip);
3045
    gen_op_tw(TO(ctx->opcode));
3046
}
3047

    
3048
/* twi */
3049
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3050
{
3051
    gen_op_load_gpr_T0(rA(ctx->opcode));
3052
    gen_set_T1(SIMM(ctx->opcode));
3053
    /* Update the nip since this might generate a trap exception */
3054
    gen_update_nip(ctx, ctx->nip);
3055
    gen_op_tw(TO(ctx->opcode));
3056
}
3057

    
3058
#if defined(TARGET_PPC64)
3059
/* td */
3060
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3061
{
3062
    gen_op_load_gpr_T0(rA(ctx->opcode));
3063
    gen_op_load_gpr_T1(rB(ctx->opcode));
3064
    /* Update the nip since this might generate a trap exception */
3065
    gen_update_nip(ctx, ctx->nip);
3066
    gen_op_td(TO(ctx->opcode));
3067
}
3068

    
3069
/* tdi */
3070
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3071
{
3072
    gen_op_load_gpr_T0(rA(ctx->opcode));
3073
    gen_set_T1(SIMM(ctx->opcode));
3074
    /* Update the nip since this might generate a trap exception */
3075
    gen_update_nip(ctx, ctx->nip);
3076
    gen_op_td(TO(ctx->opcode));
3077
}
3078
#endif
3079

    
3080
/***                          Processor control                            ***/
3081
/* mcrxr */
3082
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3083
{
3084
    gen_op_load_xer_cr();
3085
    gen_op_store_T0_crf(crfD(ctx->opcode));
3086
    gen_op_clear_xer_ov();
3087
    gen_op_clear_xer_ca();
3088
}
3089

    
3090
/* mfcr */
3091
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3092
{
3093
    uint32_t crm, crn;
3094

    
3095
    if (likely(ctx->opcode & 0x00100000)) {
3096
        crm = CRM(ctx->opcode);
3097
        if (likely((crm ^ (crm - 1)) == 0)) {
3098
            crn = ffs(crm);
3099
            gen_op_load_cro(7 - crn);
3100
        }
3101
    } else {
3102
        gen_op_load_cr();
3103
    }
3104
    gen_op_store_T0_gpr(rD(ctx->opcode));
3105
}
3106

    
3107
/* mfmsr */
3108
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3109
{
3110
#if defined(CONFIG_USER_ONLY)
3111
    RET_PRIVREG(ctx);
3112
#else
3113
    if (unlikely(!ctx->supervisor)) {
3114
        RET_PRIVREG(ctx);
3115
        return;
3116
    }
3117
    gen_op_load_msr();
3118
    gen_op_store_T0_gpr(rD(ctx->opcode));
3119
#endif
3120
}
3121

    
3122
#if 0
3123
#define SPR_NOACCESS ((void *)(-1))
3124
#else
3125
static void spr_noaccess (void *opaque, int sprn)
3126
{
3127
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3128
    printf("ERROR: try to access SPR %d !\n", sprn);
3129
}
3130
#define SPR_NOACCESS (&spr_noaccess)
3131
#endif
3132

    
3133
/* mfspr */
3134
static inline void gen_op_mfspr (DisasContext *ctx)
3135
{
3136
    void (*read_cb)(void *opaque, int sprn);
3137
    uint32_t sprn = SPR(ctx->opcode);
3138

    
3139
#if !defined(CONFIG_USER_ONLY)
3140
    if (ctx->supervisor)
3141
        read_cb = ctx->spr_cb[sprn].oea_read;
3142
    else
3143
#endif
3144
        read_cb = ctx->spr_cb[sprn].uea_read;
3145
    if (likely(read_cb != NULL)) {
3146
        if (likely(read_cb != SPR_NOACCESS)) {
3147
            (*read_cb)(ctx, sprn);
3148
            gen_op_store_T0_gpr(rD(ctx->opcode));
3149
        } else {
3150
            /* Privilege exception */
3151
            if (loglevel != 0) {
3152
                fprintf(logfile, "Trying to read privileged spr %d %03x\n",
3153
                        sprn, sprn);
3154
            }
3155
            printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
3156
            RET_PRIVREG(ctx);
3157
        }
3158
    } else {
3159
        /* Not defined */
3160
        if (loglevel != 0) {
3161
            fprintf(logfile, "Trying to read invalid spr %d %03x\n",
3162
                    sprn, sprn);
3163
        }
3164
        printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
3165
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
3166
    }
3167
}
3168

    
3169
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3170
{
3171
    gen_op_mfspr(ctx);
3172
}
3173

    
3174
/* mftb */
3175
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3176
{
3177
    gen_op_mfspr(ctx);
3178
}
3179

    
3180
/* mtcrf */
3181
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3182
{
3183
    uint32_t crm, crn;
3184

    
3185
    gen_op_load_gpr_T0(rS(ctx->opcode));
3186
    crm = CRM(ctx->opcode);
3187
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3188
        crn = ffs(crm);
3189
        gen_op_srli_T0(crn * 4);
3190
        gen_op_andi_T0(0xF);
3191
        gen_op_store_cro(7 - crn);
3192
    } else {
3193
        gen_op_store_cr(crm);
3194
    }
3195
}
3196

    
3197
/* mtmsr */
3198
#if defined(TARGET_PPC64)
3199
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
3200
{
3201
#if defined(CONFIG_USER_ONLY)
3202
    RET_PRIVREG(ctx);
3203
#else
3204
    if (unlikely(!ctx->supervisor)) {
3205
        RET_PRIVREG(ctx);
3206
        return;
3207
    }
3208
    gen_update_nip(ctx, ctx->nip);
3209
    gen_op_load_gpr_T0(rS(ctx->opcode));
3210
    gen_op_store_msr();
3211
    /* Must stop the translation as machine state (may have) changed */
3212
    RET_CHG_FLOW(ctx);
3213
#endif
3214
}
3215
#endif
3216

    
3217
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3218
{
3219
#if defined(CONFIG_USER_ONLY)
3220
    RET_PRIVREG(ctx);
3221
#else
3222
    if (unlikely(!ctx->supervisor)) {
3223
        RET_PRIVREG(ctx);
3224
        return;
3225
    }
3226
    gen_update_nip(ctx, ctx->nip);
3227
    gen_op_load_gpr_T0(rS(ctx->opcode));
3228
#if defined(TARGET_PPC64)
3229
    if (!ctx->sf_mode)
3230
        gen_op_store_msr_32();
3231
    else
3232
#endif
3233
        gen_op_store_msr();
3234
    /* Must stop the translation as machine state (may have) changed */
3235
    RET_CHG_FLOW(ctx);
3236
#endif
3237
}
3238

    
3239
/* mtspr */
3240
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3241
{
3242
    void (*write_cb)(void *opaque, int sprn);
3243
    uint32_t sprn = SPR(ctx->opcode);
3244

    
3245
#if !defined(CONFIG_USER_ONLY)
3246
    if (ctx->supervisor)
3247
        write_cb = ctx->spr_cb[sprn].oea_write;
3248
    else
3249
#endif
3250
        write_cb = ctx->spr_cb[sprn].uea_write;
3251
    if (likely(write_cb != NULL)) {
3252
        if (likely(write_cb != SPR_NOACCESS)) {
3253
            gen_op_load_gpr_T0(rS(ctx->opcode));
3254
            (*write_cb)(ctx, sprn);
3255
        } else {
3256
            /* Privilege exception */
3257
            if (loglevel != 0) {
3258
                fprintf(logfile, "Trying to write privileged spr %d %03x\n",
3259
                        sprn, sprn);
3260
            }
3261
            printf("Trying to write privileged spr %d %03x\n", sprn, sprn);
3262
            RET_PRIVREG(ctx);
3263
        }
3264
    } else {
3265
        /* Not defined */
3266
        if (loglevel != 0) {
3267
            fprintf(logfile, "Trying to write invalid spr %d %03x\n",
3268
                    sprn, sprn);
3269
        }
3270
        printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
3271
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
3272
    }
3273
}
3274

    
3275
/***                         Cache management                              ***/
3276
/* For now, all those will be implemented as nop:
3277
 * this is valid, regarding the PowerPC specs...
3278
 * We just have to flush tb while invalidating instruction cache lines...
3279
 */
3280
/* dcbf */
3281
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
3282
{
3283
    gen_addr_reg_index(ctx);
3284
    op_ldst(lbz);
3285
}
3286

    
3287
/* dcbi (Supervisor only) */
3288
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3289
{
3290
#if defined(CONFIG_USER_ONLY)
3291
    RET_PRIVOPC(ctx);
3292
#else
3293
    if (unlikely(!ctx->supervisor)) {
3294
        RET_PRIVOPC(ctx);
3295
        return;
3296
    }
3297
    gen_addr_reg_index(ctx);
3298
    /* XXX: specification says this should be treated as a store by the MMU */
3299
    //op_ldst(lbz);
3300
    op_ldst(stb);
3301
#endif
3302
}
3303

    
3304
/* dcdst */
3305
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3306
{
3307
    /* XXX: specification say this is treated as a load by the MMU */
3308
    gen_addr_reg_index(ctx);
3309
    op_ldst(lbz);
3310
}
3311

    
3312
/* dcbt */
3313
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
3314
{
3315
    /* XXX: specification say this is treated as a load by the MMU
3316
     *      but does not generate any exception
3317
     */
3318
}
3319

    
3320
/* dcbtst */
3321
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
3322
{
3323
    /* XXX: specification say this is treated as a load by the MMU
3324
     *      but does not generate any exception
3325
     */
3326
}
3327

    
3328
/* dcbz */
3329
#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3330
#if defined(TARGET_PPC64)
3331
#if defined(CONFIG_USER_ONLY)
3332
static GenOpFunc *gen_op_dcbz[] = {
3333
    &gen_op_dcbz_raw,
3334
    &gen_op_dcbz_raw,
3335
    &gen_op_dcbz_64_raw,
3336
    &gen_op_dcbz_64_raw,
3337
};
3338
#else
3339
static GenOpFunc *gen_op_dcbz[] = {
3340
    &gen_op_dcbz_user,
3341
    &gen_op_dcbz_user,
3342
    &gen_op_dcbz_kernel,
3343
    &gen_op_dcbz_kernel,
3344
    &gen_op_dcbz_64_user,
3345
    &gen_op_dcbz_64_user,
3346
    &gen_op_dcbz_64_kernel,
3347
    &gen_op_dcbz_64_kernel,
3348
};
3349
#endif
3350
#else
3351
#if defined(CONFIG_USER_ONLY)
3352
static GenOpFunc *gen_op_dcbz[] = {
3353
    &gen_op_dcbz_raw,
3354
    &gen_op_dcbz_raw,
3355
};
3356
#else
3357
static GenOpFunc *gen_op_dcbz[] = {
3358
    &gen_op_dcbz_user,
3359
    &gen_op_dcbz_user,
3360
    &gen_op_dcbz_kernel,
3361
    &gen_op_dcbz_kernel,
3362
};
3363
#endif
3364
#endif
3365

    
3366
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3367
{
3368
    gen_addr_reg_index(ctx);
3369
    op_dcbz();
3370
    gen_op_check_reservation();
3371
}
3372

    
3373
/* icbi */
3374
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3375
#if defined(TARGET_PPC64)
3376
#if defined(CONFIG_USER_ONLY)
3377
static GenOpFunc *gen_op_icbi[] = {
3378
    &gen_op_icbi_raw,
3379
    &gen_op_icbi_raw,
3380
    &gen_op_icbi_64_raw,
3381
    &gen_op_icbi_64_raw,
3382
};
3383
#else
3384
static GenOpFunc *gen_op_icbi[] = {
3385
    &gen_op_icbi_user,
3386
    &gen_op_icbi_user,
3387
    &gen_op_icbi_kernel,
3388
    &gen_op_icbi_kernel,
3389
    &gen_op_icbi_64_user,
3390
    &gen_op_icbi_64_user,
3391
    &gen_op_icbi_64_kernel,
3392
    &gen_op_icbi_64_kernel,
3393
};
3394
#endif
3395
#else
3396
#if defined(CONFIG_USER_ONLY)
3397
static GenOpFunc *gen_op_icbi[] = {
3398
    &gen_op_icbi_raw,
3399
    &gen_op_icbi_raw,
3400
};
3401
#else
3402
static GenOpFunc *gen_op_icbi[] = {
3403
    &gen_op_icbi_user,
3404
    &gen_op_icbi_user,
3405
    &gen_op_icbi_kernel,
3406
    &gen_op_icbi_kernel,
3407
};
3408
#endif
3409
#endif
3410
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3411
{
3412
    /* NIP cannot be restored if the memory exception comes from an helper */
3413
    gen_update_nip(ctx, ctx->nip - 4);
3414
    gen_addr_reg_index(ctx);
3415
    op_icbi();
3416
    RET_STOP(ctx);
3417
}
3418

    
3419
/* Optional: */
3420
/* dcba */
3421
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3422
{
3423
}
3424

    
3425
/***                    Segment register manipulation                      ***/
3426
/* Supervisor only: */
3427
/* mfsr */
3428
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, 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_set_T1(SR(ctx->opcode));
3438
    gen_op_load_sr();
3439
    gen_op_store_T0_gpr(rD(ctx->opcode));
3440
#endif
3441
}
3442

    
3443
/* mfsrin */
3444
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3445
{
3446
#if defined(CONFIG_USER_ONLY)
3447
    RET_PRIVREG(ctx);
3448
#else
3449
    if (unlikely(!ctx->supervisor)) {
3450
        RET_PRIVREG(ctx);
3451
        return;
3452
    }
3453
    gen_op_load_gpr_T1(rB(ctx->opcode));
3454
    gen_op_srli_T1(28);
3455
    gen_op_load_sr();
3456
    gen_op_store_T0_gpr(rD(ctx->opcode));
3457
#endif
3458
}
3459

    
3460
/* mtsr */
3461
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3462
{
3463
#if defined(CONFIG_USER_ONLY)
3464
    RET_PRIVREG(ctx);
3465
#else
3466
    if (unlikely(!ctx->supervisor)) {
3467
        RET_PRIVREG(ctx);
3468
        return;
3469
    }
3470
    gen_op_load_gpr_T0(rS(ctx->opcode));
3471
    gen_op_set_T1(SR(ctx->opcode));
3472
    gen_op_store_sr();
3473
    RET_STOP(ctx);
3474
#endif
3475
}
3476

    
3477
/* mtsrin */
3478
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3479
{
3480
#if defined(CONFIG_USER_ONLY)
3481
    RET_PRIVREG(ctx);
3482
#else
3483
    if (unlikely(!ctx->supervisor)) {
3484
        RET_PRIVREG(ctx);
3485
        return;
3486
    }
3487
    gen_op_load_gpr_T0(rS(ctx->opcode));
3488
    gen_op_load_gpr_T1(rB(ctx->opcode));
3489
    gen_op_srli_T1(28);
3490
    gen_op_store_sr();
3491
    RET_STOP(ctx);
3492
#endif
3493
}
3494

    
3495
/***                      Lookaside buffer management                      ***/
3496
/* Optional & supervisor only: */
3497
/* tlbia */
3498
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3499
{
3500
#if defined(CONFIG_USER_ONLY)
3501
    RET_PRIVOPC(ctx);
3502
#else
3503
    if (unlikely(!ctx->supervisor)) {
3504
        if (loglevel != 0)
3505
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3506
        RET_PRIVOPC(ctx);
3507
        return;
3508
    }
3509
    gen_op_tlbia();
3510
    RET_STOP(ctx);
3511
#endif
3512
}
3513

    
3514
/* tlbie */
3515
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3516
{
3517
#if defined(CONFIG_USER_ONLY)
3518
    RET_PRIVOPC(ctx);
3519
#else
3520
    if (unlikely(!ctx->supervisor)) {
3521
        RET_PRIVOPC(ctx);
3522
        return;
3523
    }
3524
    gen_op_load_gpr_T0(rB(ctx->opcode));
3525
#if defined(TARGET_PPC64)
3526
    if (ctx->sf_mode)
3527
        gen_op_tlbie_64();
3528
    else
3529
#endif
3530
        gen_op_tlbie();
3531
    RET_STOP(ctx);
3532
#endif
3533
}
3534

    
3535
/* tlbsync */
3536
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3537
{
3538
#if defined(CONFIG_USER_ONLY)
3539
    RET_PRIVOPC(ctx);
3540
#else
3541
    if (unlikely(!ctx->supervisor)) {
3542
        RET_PRIVOPC(ctx);
3543
        return;
3544
    }
3545
    /* This has no effect: it should ensure that all previous
3546
     * tlbie have completed
3547
     */
3548
    RET_STOP(ctx);
3549
#endif
3550
}
3551

    
3552
#if defined(TARGET_PPC64)
3553
/* slbia */
3554
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3555
{
3556
#if defined(CONFIG_USER_ONLY)
3557
    RET_PRIVOPC(ctx);
3558
#else
3559
    if (unlikely(!ctx->supervisor)) {
3560
        if (loglevel != 0)
3561
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3562
        RET_PRIVOPC(ctx);
3563
        return;
3564
    }
3565
    gen_op_slbia();
3566
    RET_STOP(ctx);
3567
#endif
3568
}
3569

    
3570
/* slbie */
3571
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3572
{
3573
#if defined(CONFIG_USER_ONLY)
3574
    RET_PRIVOPC(ctx);
3575
#else
3576
    if (unlikely(!ctx->supervisor)) {
3577
        RET_PRIVOPC(ctx);
3578
        return;
3579
    }
3580
    gen_op_load_gpr_T0(rB(ctx->opcode));
3581
    gen_op_slbie();
3582
    RET_STOP(ctx);
3583
#endif
3584
}
3585
#endif
3586

    
3587
/***                              External control                         ***/
3588
/* Optional: */
3589
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3590
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3591
#if defined(TARGET_PPC64)
3592
#if defined(CONFIG_USER_ONLY)
3593
static GenOpFunc *gen_op_eciwx[] = {
3594
    &gen_op_eciwx_raw,
3595
    &gen_op_eciwx_le_raw,
3596
    &gen_op_eciwx_64_raw,
3597
    &gen_op_eciwx_le_64_raw,
3598
};
3599
static GenOpFunc *gen_op_ecowx[] = {
3600
    &gen_op_ecowx_raw,
3601
    &gen_op_ecowx_le_raw,
3602
    &gen_op_ecowx_64_raw,
3603
    &gen_op_ecowx_le_64_raw,
3604
};
3605
#else
3606
static GenOpFunc *gen_op_eciwx[] = {
3607
    &gen_op_eciwx_user,
3608
    &gen_op_eciwx_le_user,
3609
    &gen_op_eciwx_kernel,
3610
    &gen_op_eciwx_le_kernel,
3611
    &gen_op_eciwx_64_user,
3612
    &gen_op_eciwx_le_64_user,
3613
    &gen_op_eciwx_64_kernel,
3614
    &gen_op_eciwx_le_64_kernel,
3615
};
3616
static GenOpFunc *gen_op_ecowx[] = {
3617
    &gen_op_ecowx_user,
3618
    &gen_op_ecowx_le_user,
3619
    &gen_op_ecowx_kernel,
3620
    &gen_op_ecowx_le_kernel,
3621
    &gen_op_ecowx_64_user,
3622
    &gen_op_ecowx_le_64_user,
3623
    &gen_op_ecowx_64_kernel,
3624
    &gen_op_ecowx_le_64_kernel,
3625
};
3626
#endif
3627
#else
3628
#if defined(CONFIG_USER_ONLY)
3629
static GenOpFunc *gen_op_eciwx[] = {
3630
    &gen_op_eciwx_raw,
3631
    &gen_op_eciwx_le_raw,
3632
};
3633
static GenOpFunc *gen_op_ecowx[] = {
3634
    &gen_op_ecowx_raw,
3635
    &gen_op_ecowx_le_raw,
3636
};
3637
#else
3638
static GenOpFunc *gen_op_eciwx[] = {
3639
    &gen_op_eciwx_user,
3640
    &gen_op_eciwx_le_user,
3641
    &gen_op_eciwx_kernel,
3642
    &gen_op_eciwx_le_kernel,
3643
};
3644
static GenOpFunc *gen_op_ecowx[] = {
3645
    &gen_op_ecowx_user,
3646
    &gen_op_ecowx_le_user,
3647
    &gen_op_ecowx_kernel,
3648
    &gen_op_ecowx_le_kernel,
3649
};
3650
#endif
3651
#endif
3652

    
3653
/* eciwx */
3654
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3655
{
3656
    /* Should check EAR[E] & alignment ! */
3657
    gen_addr_reg_index(ctx);
3658
    op_eciwx();
3659
    gen_op_store_T0_gpr(rD(ctx->opcode));
3660
}
3661

    
3662
/* ecowx */
3663
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3664
{
3665
    /* Should check EAR[E] & alignment ! */
3666
    gen_addr_reg_index(ctx);
3667
    gen_op_load_gpr_T1(rS(ctx->opcode));
3668
    op_ecowx();
3669
}
3670

    
3671
/* PowerPC 601 specific instructions */
3672
/* abs - abs. */
3673
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3674
{
3675
    gen_op_load_gpr_T0(rA(ctx->opcode));
3676
    gen_op_POWER_abs();
3677
    gen_op_store_T0_gpr(rD(ctx->opcode));
3678
    if (unlikely(Rc(ctx->opcode) != 0))
3679
        gen_set_Rc0(ctx);
3680
}
3681

    
3682
/* abso - abso. */
3683
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3684
{
3685
    gen_op_load_gpr_T0(rA(ctx->opcode));
3686
    gen_op_POWER_abso();
3687
    gen_op_store_T0_gpr(rD(ctx->opcode));
3688
    if (unlikely(Rc(ctx->opcode) != 0))
3689
        gen_set_Rc0(ctx);
3690
}
3691

    
3692
/* clcs */
3693
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3694
{
3695
    gen_op_load_gpr_T0(rA(ctx->opcode));
3696
    gen_op_POWER_clcs();
3697
    gen_op_store_T0_gpr(rD(ctx->opcode));
3698
}
3699

    
3700
/* div - div. */
3701
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3702
{
3703
    gen_op_load_gpr_T0(rA(ctx->opcode));
3704
    gen_op_load_gpr_T1(rB(ctx->opcode));
3705
    gen_op_POWER_div();
3706
    gen_op_store_T0_gpr(rD(ctx->opcode));
3707
    if (unlikely(Rc(ctx->opcode) != 0))
3708
        gen_set_Rc0(ctx);
3709
}
3710

    
3711
/* divo - divo. */
3712
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3713
{
3714
    gen_op_load_gpr_T0(rA(ctx->opcode));
3715
    gen_op_load_gpr_T1(rB(ctx->opcode));
3716
    gen_op_POWER_divo();
3717
    gen_op_store_T0_gpr(rD(ctx->opcode));
3718
    if (unlikely(Rc(ctx->opcode) != 0))
3719
        gen_set_Rc0(ctx);
3720
}
3721

    
3722
/* divs - divs. */
3723
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3724
{
3725
    gen_op_load_gpr_T0(rA(ctx->opcode));
3726
    gen_op_load_gpr_T1(rB(ctx->opcode));
3727
    gen_op_POWER_divs();
3728
    gen_op_store_T0_gpr(rD(ctx->opcode));
3729
    if (unlikely(Rc(ctx->opcode) != 0))
3730
        gen_set_Rc0(ctx);
3731
}
3732

    
3733
/* divso - divso. */
3734
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3735
{
3736
    gen_op_load_gpr_T0(rA(ctx->opcode));
3737
    gen_op_load_gpr_T1(rB(ctx->opcode));
3738
    gen_op_POWER_divso();
3739
    gen_op_store_T0_gpr(rD(ctx->opcode));
3740
    if (unlikely(Rc(ctx->opcode) != 0))
3741
        gen_set_Rc0(ctx);
3742
}
3743

    
3744
/* doz - doz. */
3745
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3746
{
3747
    gen_op_load_gpr_T0(rA(ctx->opcode));
3748
    gen_op_load_gpr_T1(rB(ctx->opcode));
3749
    gen_op_POWER_doz();
3750
    gen_op_store_T0_gpr(rD(ctx->opcode));
3751
    if (unlikely(Rc(ctx->opcode) != 0))
3752
        gen_set_Rc0(ctx);
3753
}
3754

    
3755
/* dozo - dozo. */
3756
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3757
{
3758
    gen_op_load_gpr_T0(rA(ctx->opcode));
3759
    gen_op_load_gpr_T1(rB(ctx->opcode));
3760
    gen_op_POWER_dozo();
3761
    gen_op_store_T0_gpr(rD(ctx->opcode));
3762
    if (unlikely(Rc(ctx->opcode) != 0))
3763
        gen_set_Rc0(ctx);
3764
}
3765

    
3766
/* dozi */
3767
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3768
{
3769
    gen_op_load_gpr_T0(rA(ctx->opcode));
3770
    gen_op_set_T1(SIMM(ctx->opcode));
3771
    gen_op_POWER_doz();
3772
    gen_op_store_T0_gpr(rD(ctx->opcode));
3773
}
3774

    
3775
/* As lscbx load from memory byte after byte, it's always endian safe */
3776
#define op_POWER_lscbx(start, ra, rb) \
3777
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3778
#if defined(CONFIG_USER_ONLY)
3779
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3780
    &gen_op_POWER_lscbx_raw,
3781
    &gen_op_POWER_lscbx_raw,
3782
};
3783
#else
3784
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3785
    &gen_op_POWER_lscbx_user,
3786
    &gen_op_POWER_lscbx_user,
3787
    &gen_op_POWER_lscbx_kernel,
3788
    &gen_op_POWER_lscbx_kernel,
3789
};
3790
#endif
3791

    
3792
/* lscbx - lscbx. */
3793
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3794
{
3795
    int ra = rA(ctx->opcode);
3796
    int rb = rB(ctx->opcode);
3797

    
3798
    gen_addr_reg_index(ctx);
3799
    if (ra == 0) {
3800
        ra = rb;
3801
    }
3802
    /* NIP cannot be restored if the memory exception comes from an helper */
3803
    gen_update_nip(ctx, ctx->nip - 4);
3804
    gen_op_load_xer_bc();
3805
    gen_op_load_xer_cmp();
3806
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3807
    gen_op_store_xer_bc();
3808
    if (unlikely(Rc(ctx->opcode) != 0))
3809
        gen_set_Rc0(ctx);
3810
}
3811

    
3812
/* maskg - maskg. */
3813
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3814
{
3815
    gen_op_load_gpr_T0(rS(ctx->opcode));
3816
    gen_op_load_gpr_T1(rB(ctx->opcode));
3817
    gen_op_POWER_maskg();
3818
    gen_op_store_T0_gpr(rA(ctx->opcode));
3819
    if (unlikely(Rc(ctx->opcode) != 0))
3820
        gen_set_Rc0(ctx);
3821
}
3822

    
3823
/* maskir - maskir. */
3824
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3825
{
3826
    gen_op_load_gpr_T0(rA(ctx->opcode));
3827
    gen_op_load_gpr_T1(rS(ctx->opcode));
3828
    gen_op_load_gpr_T2(rB(ctx->opcode));
3829
    gen_op_POWER_maskir();
3830
    gen_op_store_T0_gpr(rA(ctx->opcode));
3831
    if (unlikely(Rc(ctx->opcode) != 0))
3832
        gen_set_Rc0(ctx);
3833
}
3834

    
3835
/* mul - mul. */
3836
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
3837
{
3838
    gen_op_load_gpr_T0(rA(ctx->opcode));
3839
    gen_op_load_gpr_T1(rB(ctx->opcode));
3840
    gen_op_POWER_mul();
3841
    gen_op_store_T0_gpr(rD(ctx->opcode));
3842
    if (unlikely(Rc(ctx->opcode) != 0))
3843
        gen_set_Rc0(ctx);
3844
}
3845

    
3846
/* mulo - mulo. */
3847
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
3848
{
3849
    gen_op_load_gpr_T0(rA(ctx->opcode));
3850
    gen_op_load_gpr_T1(rB(ctx->opcode));
3851
    gen_op_POWER_mulo();
3852
    gen_op_store_T0_gpr(rD(ctx->opcode));
3853
    if (unlikely(Rc(ctx->opcode) != 0))
3854
        gen_set_Rc0(ctx);
3855
}
3856

    
3857
/* nabs - nabs. */
3858
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
3859
{
3860
    gen_op_load_gpr_T0(rA(ctx->opcode));
3861
    gen_op_POWER_nabs();
3862
    gen_op_store_T0_gpr(rD(ctx->opcode));
3863
    if (unlikely(Rc(ctx->opcode) != 0))
3864
        gen_set_Rc0(ctx);
3865
}
3866

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

    
3877
/* rlmi - rlmi. */
3878
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3879
{
3880
    uint32_t mb, me;
3881

    
3882
    mb = MB(ctx->opcode);
3883
    me = ME(ctx->opcode);
3884
    gen_op_load_gpr_T0(rS(ctx->opcode));
3885
    gen_op_load_gpr_T1(rA(ctx->opcode));
3886
    gen_op_load_gpr_T2(rB(ctx->opcode));
3887
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
3888
    gen_op_store_T0_gpr(rA(ctx->opcode));
3889
    if (unlikely(Rc(ctx->opcode) != 0))
3890
        gen_set_Rc0(ctx);
3891
}
3892

    
3893
/* rrib - rrib. */
3894
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
3895
{
3896
    gen_op_load_gpr_T0(rS(ctx->opcode));
3897
    gen_op_load_gpr_T1(rA(ctx->opcode));
3898
    gen_op_load_gpr_T2(rB(ctx->opcode));
3899
    gen_op_POWER_rrib();
3900
    gen_op_store_T0_gpr(rA(ctx->opcode));
3901
    if (unlikely(Rc(ctx->opcode) != 0))
3902
        gen_set_Rc0(ctx);
3903
}
3904

    
3905
/* sle - sle. */
3906
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
3907
{
3908
    gen_op_load_gpr_T0(rS(ctx->opcode));
3909
    gen_op_load_gpr_T1(rB(ctx->opcode));
3910
    gen_op_POWER_sle();
3911
    gen_op_store_T0_gpr(rA(ctx->opcode));
3912
    if (unlikely(Rc(ctx->opcode) != 0))
3913
        gen_set_Rc0(ctx);
3914
}
3915

    
3916
/* sleq - sleq. */
3917
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
3918
{
3919
    gen_op_load_gpr_T0(rS(ctx->opcode));
3920
    gen_op_load_gpr_T1(rB(ctx->opcode));
3921
    gen_op_POWER_sleq();
3922
    gen_op_store_T0_gpr(rA(ctx->opcode));
3923
    if (unlikely(Rc(ctx->opcode) != 0))
3924
        gen_set_Rc0(ctx);
3925
}
3926

    
3927
/* sliq - sliq. */
3928
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
3929
{
3930
    gen_op_load_gpr_T0(rS(ctx->opcode));
3931
    gen_op_set_T1(SH(ctx->opcode));
3932
    gen_op_POWER_sle();
3933
    gen_op_store_T0_gpr(rA(ctx->opcode));
3934
    if (unlikely(Rc(ctx->opcode) != 0))
3935
        gen_set_Rc0(ctx);
3936
}
3937

    
3938
/* slliq - slliq. */
3939
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
3940
{
3941
    gen_op_load_gpr_T0(rS(ctx->opcode));
3942
    gen_op_set_T1(SH(ctx->opcode));
3943
    gen_op_POWER_sleq();
3944
    gen_op_store_T0_gpr(rA(ctx->opcode));
3945
    if (unlikely(Rc(ctx->opcode) != 0))
3946
        gen_set_Rc0(ctx);
3947
}
3948

    
3949
/* sllq - sllq. */
3950
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
3951
{
3952
    gen_op_load_gpr_T0(rS(ctx->opcode));
3953
    gen_op_load_gpr_T1(rB(ctx->opcode));
3954
    gen_op_POWER_sllq();
3955
    gen_op_store_T0_gpr(rA(ctx->opcode));
3956
    if (unlikely(Rc(ctx->opcode) != 0))
3957
        gen_set_Rc0(ctx);
3958
}
3959

    
3960
/* slq - slq. */
3961
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
3962
{
3963
    gen_op_load_gpr_T0(rS(ctx->opcode));
3964
    gen_op_load_gpr_T1(rB(ctx->opcode));
3965
    gen_op_POWER_slq();
3966
    gen_op_store_T0_gpr(rA(ctx->opcode));
3967
    if (unlikely(Rc(ctx->opcode) != 0))
3968
        gen_set_Rc0(ctx);
3969
}
3970

    
3971
/* sraiq - sraiq. */
3972
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
3973
{
3974
    gen_op_load_gpr_T0(rS(ctx->opcode));
3975
    gen_op_set_T1(SH(ctx->opcode));
3976
    gen_op_POWER_sraq();
3977
    gen_op_store_T0_gpr(rA(ctx->opcode));
3978
    if (unlikely(Rc(ctx->opcode) != 0))
3979
        gen_set_Rc0(ctx);
3980
}
3981

    
3982
/* sraq - sraq. */
3983
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
3984
{
3985
    gen_op_load_gpr_T0(rS(ctx->opcode));
3986
    gen_op_load_gpr_T1(rB(ctx->opcode));
3987
    gen_op_POWER_sraq();
3988
    gen_op_store_T0_gpr(rA(ctx->opcode));
3989
    if (unlikely(Rc(ctx->opcode) != 0))
3990
        gen_set_Rc0(ctx);
3991
}
3992

    
3993
/* sre - sre. */
3994
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
3995
{
3996
    gen_op_load_gpr_T0(rS(ctx->opcode));
3997
    gen_op_load_gpr_T1(rB(ctx->opcode));
3998
    gen_op_POWER_sre();
3999
    gen_op_store_T0_gpr(rA(ctx->opcode));
4000
    if (unlikely(Rc(ctx->opcode) != 0))
4001
        gen_set_Rc0(ctx);
4002
}
4003

    
4004
/* srea - srea. */
4005
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4006
{
4007
    gen_op_load_gpr_T0(rS(ctx->opcode));
4008
    gen_op_load_gpr_T1(rB(ctx->opcode));
4009
    gen_op_POWER_srea();
4010
    gen_op_store_T0_gpr(rA(ctx->opcode));
4011
    if (unlikely(Rc(ctx->opcode) != 0))
4012
        gen_set_Rc0(ctx);
4013
}
4014

    
4015
/* sreq */
4016
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4017
{
4018
    gen_op_load_gpr_T0(rS(ctx->opcode));
4019
    gen_op_load_gpr_T1(rB(ctx->opcode));
4020
    gen_op_POWER_sreq();
4021
    gen_op_store_T0_gpr(rA(ctx->opcode));
4022
    if (unlikely(Rc(ctx->opcode) != 0))
4023
        gen_set_Rc0(ctx);
4024
}
4025

    
4026
/* sriq */
4027
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4028
{
4029
    gen_op_load_gpr_T0(rS(ctx->opcode));
4030
    gen_op_set_T1(SH(ctx->opcode));
4031
    gen_op_POWER_srq();
4032
    gen_op_store_T0_gpr(rA(ctx->opcode));
4033
    if (unlikely(Rc(ctx->opcode) != 0))
4034
        gen_set_Rc0(ctx);
4035
}
4036

    
4037
/* srliq */
4038
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4039
{
4040
    gen_op_load_gpr_T0(rS(ctx->opcode));
4041
    gen_op_load_gpr_T1(rB(ctx->opcode));
4042
    gen_op_set_T1(SH(ctx->opcode));
4043
    gen_op_POWER_srlq();
4044
    gen_op_store_T0_gpr(rA(ctx->opcode));
4045
    if (unlikely(Rc(ctx->opcode) != 0))
4046
        gen_set_Rc0(ctx);
4047
}
4048

    
4049
/* srlq */
4050
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4051
{
4052
    gen_op_load_gpr_T0(rS(ctx->opcode));
4053
    gen_op_load_gpr_T1(rB(ctx->opcode));
4054
    gen_op_POWER_srlq();
4055
    gen_op_store_T0_gpr(rA(ctx->opcode));
4056
    if (unlikely(Rc(ctx->opcode) != 0))
4057
        gen_set_Rc0(ctx);
4058
}
4059

    
4060
/* srq */
4061
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4062
{
4063
    gen_op_load_gpr_T0(rS(ctx->opcode));
4064
    gen_op_load_gpr_T1(rB(ctx->opcode));
4065
    gen_op_POWER_srq();
4066
    gen_op_store_T0_gpr(rA(ctx->opcode));
4067
    if (unlikely(Rc(ctx->opcode) != 0))
4068
        gen_set_Rc0(ctx);
4069
}
4070

    
4071
/* PowerPC 602 specific instructions */
4072
/* dsa  */
4073
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4074
{
4075
    /* XXX: TODO */
4076
    RET_INVAL(ctx);
4077
}
4078

    
4079
/* esa */
4080
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4081
{
4082
    /* XXX: TODO */
4083
    RET_INVAL(ctx);
4084
}
4085

    
4086
/* mfrom */
4087
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4088
{
4089
#if defined(CONFIG_USER_ONLY)
4090
    RET_PRIVOPC(ctx);
4091
#else
4092
    if (unlikely(!ctx->supervisor)) {
4093
        RET_PRIVOPC(ctx);
4094
        return;
4095
    }
4096
    gen_op_load_gpr_T0(rA(ctx->opcode));
4097
    gen_op_602_mfrom();
4098
    gen_op_store_T0_gpr(rD(ctx->opcode));
4099
#endif
4100
}
4101

    
4102
/* 602 - 603 - G2 TLB management */
4103
/* tlbld */
4104
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 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_tlbld();
4115
    RET_STOP(ctx);
4116
#endif
4117
}
4118

    
4119
/* tlbli */
4120
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4121
{
4122
#if defined(CONFIG_USER_ONLY)
4123
    RET_PRIVOPC(ctx);
4124
#else
4125
    if (unlikely(!ctx->supervisor)) {
4126
        RET_PRIVOPC(ctx);
4127
        return;
4128
    }
4129
    gen_op_load_gpr_T0(rB(ctx->opcode));
4130
    gen_op_6xx_tlbli();
4131
    RET_STOP(ctx);
4132
#endif
4133
}
4134

    
4135
/* POWER instructions not in PowerPC 601 */
4136
/* clf */
4137
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4138
{
4139
    /* Cache line flush: implemented as no-op */
4140
}
4141

    
4142
/* cli */
4143
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4144
{
4145
    /* Cache line invalidate: privileged and treated as no-op */
4146
#if defined(CONFIG_USER_ONLY)
4147
    RET_PRIVOPC(ctx);
4148
#else
4149
    if (unlikely(!ctx->supervisor)) {
4150
        RET_PRIVOPC(ctx);
4151
        return;
4152
    }
4153
#endif
4154
}
4155

    
4156
/* dclst */
4157
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4158
{
4159
    /* Data cache line store: treated as no-op */
4160
}
4161

    
4162
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4163
{
4164
#if defined(CONFIG_USER_ONLY)
4165
    RET_PRIVOPC(ctx);
4166
#else
4167
    if (unlikely(!ctx->supervisor)) {
4168
        RET_PRIVOPC(ctx);
4169
        return;
4170
    }
4171
    int ra = rA(ctx->opcode);
4172
    int rd = rD(ctx->opcode);
4173

    
4174
    gen_addr_reg_index(ctx);
4175
    gen_op_POWER_mfsri();
4176
    gen_op_store_T0_gpr(rd);
4177
    if (ra != 0 && ra != rd)
4178
        gen_op_store_T1_gpr(ra);
4179
#endif
4180
}
4181

    
4182
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4183
{
4184
#if defined(CONFIG_USER_ONLY)
4185
    RET_PRIVOPC(ctx);
4186
#else
4187
    if (unlikely(!ctx->supervisor)) {
4188
        RET_PRIVOPC(ctx);
4189
        return;
4190
    }
4191
    gen_addr_reg_index(ctx);
4192
    gen_op_POWER_rac();
4193
    gen_op_store_T0_gpr(rD(ctx->opcode));
4194
#endif
4195
}
4196

    
4197
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4198
{
4199
#if defined(CONFIG_USER_ONLY)
4200
    RET_PRIVOPC(ctx);
4201
#else
4202
    if (unlikely(!ctx->supervisor)) {
4203
        RET_PRIVOPC(ctx);
4204
        return;
4205
    }
4206
    gen_op_POWER_rfsvc();
4207
    RET_CHG_FLOW(ctx);
4208
#endif
4209
}
4210

    
4211
/* svc is not implemented for now */
4212

    
4213
/* POWER2 specific instructions */
4214
/* Quad manipulation (load/store two floats at a time) */
4215
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4216
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4217
#if defined(CONFIG_USER_ONLY)
4218
static GenOpFunc *gen_op_POWER2_lfq[] = {
4219
    &gen_op_POWER2_lfq_le_raw,
4220
    &gen_op_POWER2_lfq_raw,
4221
};
4222
static GenOpFunc *gen_op_POWER2_stfq[] = {
4223
    &gen_op_POWER2_stfq_le_raw,
4224
    &gen_op_POWER2_stfq_raw,
4225
};
4226
#else
4227
static GenOpFunc *gen_op_POWER2_lfq[] = {
4228
    &gen_op_POWER2_lfq_le_user,
4229
    &gen_op_POWER2_lfq_user,
4230
    &gen_op_POWER2_lfq_le_kernel,
4231
    &gen_op_POWER2_lfq_kernel,
4232
};
4233
static GenOpFunc *gen_op_POWER2_stfq[] = {
4234
    &gen_op_POWER2_stfq_le_user,
4235
    &gen_op_POWER2_stfq_user,
4236
    &gen_op_POWER2_stfq_le_kernel,
4237
    &gen_op_POWER2_stfq_kernel,
4238
};
4239
#endif
4240

    
4241
/* lfq */
4242
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4243
{
4244
    /* NIP cannot be restored if the memory exception comes from an helper */
4245
    gen_update_nip(ctx, ctx->nip - 4);
4246
    gen_addr_imm_index(ctx, 0);
4247
    op_POWER2_lfq();
4248
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4249
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4250
}
4251

    
4252
/* lfqu */
4253
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4254
{
4255
    int ra = rA(ctx->opcode);
4256

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

    
4267
/* lfqux */
4268
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4269
{
4270
    int ra = rA(ctx->opcode);
4271

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

    
4282
/* lfqx */
4283
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4284
{
4285
    /* NIP cannot be restored if the memory exception comes from an helper */
4286
    gen_update_nip(ctx, ctx->nip - 4);
4287
    gen_addr_reg_index(ctx);
4288
    op_POWER2_lfq();
4289
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4290
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4291
}
4292

    
4293
/* stfq */
4294
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4295
{
4296
    /* NIP cannot be restored if the memory exception comes from an helper */
4297
    gen_update_nip(ctx, ctx->nip - 4);
4298
    gen_addr_imm_index(ctx, 0);
4299
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4300
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4301
    op_POWER2_stfq();
4302
}
4303

    
4304
/* stfqu */
4305
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4306
{
4307
    int ra = rA(ctx->opcode);
4308

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

    
4319
/* stfqux */
4320
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4321
{
4322
    int ra = rA(ctx->opcode);
4323

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

    
4334
/* stfqx */
4335
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4336
{
4337
    /* NIP cannot be restored if the memory exception comes from an helper */
4338
    gen_update_nip(ctx, ctx->nip - 4);
4339
    gen_addr_reg_index(ctx);
4340
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4341
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4342
    op_POWER2_stfq();
4343
}
4344

    
4345
/* BookE specific instructions */
4346
/* XXX: not implemented on 440 ? */
4347
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT)
4348
{
4349
    /* XXX: TODO */
4350
    RET_INVAL(ctx);
4351
}
4352

    
4353
/* XXX: not implemented on 440 ? */
4354
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
4355
{
4356
#if defined(CONFIG_USER_ONLY)
4357
    RET_PRIVOPC(ctx);
4358
#else
4359
    if (unlikely(!ctx->supervisor)) {
4360
        RET_PRIVOPC(ctx);
4361
        return;
4362
    }
4363
    gen_addr_reg_index(ctx);
4364
    /* Use the same micro-ops as for tlbie */
4365
#if defined(TARGET_PPC64)
4366
    if (ctx->sf_mode)
4367
        gen_op_tlbie_64();
4368
    else
4369
#endif
4370
        gen_op_tlbie();
4371
    RET_STOP(ctx);
4372
#endif
4373
}
4374

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

    
4456
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4457
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4458
{                                                                             \
4459
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4460
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4461
}
4462

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

    
4536
/* mulchw  - mulchw.  */
4537
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4538
/* mulchwu - mulchwu. */
4539
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4540
/* mulhhw  - mulhhw.  */
4541
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4542
/* mulhhwu - mulhhwu. */
4543
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4544
/* mullhw  - mullhw.  */
4545
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4546
/* mullhwu - mullhwu. */
4547
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4548

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

    
4557
    if (unlikely(!ctx->supervisor)) {
4558
        RET_PRIVREG(ctx);
4559
        return;
4560
    }
4561
    gen_op_set_T0(dcrn);
4562
    gen_op_load_dcr();
4563
    gen_op_store_T0_gpr(rD(ctx->opcode));
4564
#endif
4565
}
4566

    
4567
/* mtdcr */
4568
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4569
{
4570
#if defined(CONFIG_USER_ONLY)
4571
    RET_PRIVREG(ctx);
4572
#else
4573
    uint32_t dcrn = SPR(ctx->opcode);
4574

    
4575
    if (unlikely(!ctx->supervisor)) {
4576
        RET_PRIVREG(ctx);
4577
        return;
4578
    }
4579
    gen_op_set_T0(dcrn);
4580
    gen_op_load_gpr_T1(rS(ctx->opcode));
4581
    gen_op_store_dcr();
4582
#endif
4583
}
4584

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

    
4603
/* mtdcrx */
4604
/* XXX: not implemented on 440 ? */
4605
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT)
4606
{
4607
#if defined(CONFIG_USER_ONLY)
4608
    RET_PRIVREG(ctx);
4609
#else
4610
    if (unlikely(!ctx->supervisor)) {
4611
        RET_PRIVREG(ctx);
4612
        return;
4613
    }
4614
    gen_op_load_gpr_T0(rA(ctx->opcode));
4615
    gen_op_load_gpr_T1(rS(ctx->opcode));
4616
    gen_op_store_dcr();
4617
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4618
#endif
4619
}
4620

    
4621
/* mfdcrux (PPC 460) : user-mode access to DCR */
4622
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4623
{
4624
    gen_op_load_gpr_T0(rA(ctx->opcode));
4625
    gen_op_load_dcr();
4626
    gen_op_store_T0_gpr(rD(ctx->opcode));
4627
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4628
}
4629

    
4630
/* mtdcrux (PPC 460) : user-mode access to DCR */
4631
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4632
{
4633
    gen_op_load_gpr_T0(rA(ctx->opcode));
4634
    gen_op_load_gpr_T1(rS(ctx->opcode));
4635
    gen_op_store_dcr();
4636
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4637
}
4638

    
4639
/* dccci */
4640
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4641
{
4642
#if defined(CONFIG_USER_ONLY)
4643
    RET_PRIVOPC(ctx);
4644
#else
4645
    if (unlikely(!ctx->supervisor)) {
4646
        RET_PRIVOPC(ctx);
4647
        return;
4648
    }
4649
    /* interpreted as no-op */
4650
#endif
4651
}
4652

    
4653
/* dcread */
4654
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4655
{
4656
#if defined(CONFIG_USER_ONLY)
4657
    RET_PRIVOPC(ctx);
4658
#else
4659
    if (unlikely(!ctx->supervisor)) {
4660
        RET_PRIVOPC(ctx);
4661
        return;
4662
    }
4663
    gen_addr_reg_index(ctx);
4664
    op_ldst(lwz);
4665
    gen_op_store_T0_gpr(rD(ctx->opcode));
4666
#endif
4667
}
4668

    
4669
/* icbt */
4670
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4671
{
4672
    /* interpreted as no-op */
4673
    /* XXX: specification say this is treated as a load by the MMU
4674
     *      but does not generate any exception
4675
     */
4676
}
4677

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

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

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

    
4722
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4723
{
4724
#if defined(CONFIG_USER_ONLY)
4725
    RET_PRIVOPC(ctx);
4726
#else
4727
    if (unlikely(!ctx->supervisor)) {
4728
        RET_PRIVOPC(ctx);
4729
        return;
4730
    }
4731
    /* Restore CPU state */
4732
    gen_op_rfci();
4733
    RET_CHG_FLOW(ctx);
4734
#endif
4735
}
4736

    
4737
/* BookE specific */
4738
/* XXX: not implemented on 440 ? */
4739
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
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_rfdi();
4750
    RET_CHG_FLOW(ctx);
4751
#endif
4752
}
4753

    
4754
/* XXX: not implemented on 440 ? */
4755
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
4756
{
4757
#if defined(CONFIG_USER_ONLY)
4758
    RET_PRIVOPC(ctx);
4759
#else
4760
    if (unlikely(!ctx->supervisor)) {
4761
        RET_PRIVOPC(ctx);
4762
        return;
4763
    }
4764
    /* Restore CPU state */
4765
    gen_op_rfmci();
4766
    RET_CHG_FLOW(ctx);
4767
#endif
4768
}
4769

    
4770
/* TLB management - PowerPC 405 implementation */
4771
/* tlbre */
4772
GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4773
{
4774
#if defined(CONFIG_USER_ONLY)
4775
    RET_PRIVOPC(ctx);
4776
#else
4777
    if (unlikely(!ctx->supervisor)) {
4778
        RET_PRIVOPC(ctx);
4779
        return;
4780
    }
4781
    switch (rB(ctx->opcode)) {
4782
    case 0:
4783
        gen_op_load_gpr_T0(rA(ctx->opcode));
4784
        gen_op_4xx_tlbre_hi();
4785
        gen_op_store_T0_gpr(rD(ctx->opcode));
4786
        break;
4787
    case 1:
4788
        gen_op_load_gpr_T0(rA(ctx->opcode));
4789
        gen_op_4xx_tlbre_lo();
4790
        gen_op_store_T0_gpr(rD(ctx->opcode));
4791
        break;
4792
    default:
4793
        RET_INVAL(ctx);
4794
        break;
4795
    }
4796
#endif
4797
}
4798

    
4799
/* tlbsx - tlbsx. */
4800
GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
4801
{
4802
#if defined(CONFIG_USER_ONLY)
4803
    RET_PRIVOPC(ctx);
4804
#else
4805
    if (unlikely(!ctx->supervisor)) {
4806
        RET_PRIVOPC(ctx);
4807
        return;
4808
    }
4809
    gen_addr_reg_index(ctx);
4810
    if (Rc(ctx->opcode))
4811
        gen_op_4xx_tlbsx_();
4812
    else
4813
        gen_op_4xx_tlbsx();
4814
    gen_op_store_T0_gpr(rD(ctx->opcode));
4815
#endif
4816
}
4817

    
4818
/* tlbwe */
4819
GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
4820
{
4821
#if defined(CONFIG_USER_ONLY)
4822
    RET_PRIVOPC(ctx);
4823
#else
4824
    if (unlikely(!ctx->supervisor)) {
4825
        RET_PRIVOPC(ctx);
4826
        return;
4827
    }
4828
    switch (rB(ctx->opcode)) {
4829
    case 0:
4830
        gen_op_load_gpr_T0(rA(ctx->opcode));
4831
        gen_op_load_gpr_T1(rS(ctx->opcode));
4832
        gen_op_4xx_tlbwe_hi();
4833
        break;
4834
    case 1:
4835
        gen_op_load_gpr_T0(rA(ctx->opcode));
4836
        gen_op_load_gpr_T1(rS(ctx->opcode));
4837
        gen_op_4xx_tlbwe_lo();
4838
        break;
4839
    default:
4840
        RET_INVAL(ctx);
4841
        break;
4842
    }
4843
#endif
4844
}
4845

    
4846
/* TLB management - PowerPC 440 implementation */
4847
/* tlbre */
4848
GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4849
{
4850
#if defined(CONFIG_USER_ONLY)
4851
    RET_PRIVOPC(ctx);
4852
#else
4853
    if (unlikely(!ctx->supervisor)) {
4854
        RET_PRIVOPC(ctx);
4855
        return;
4856
    }
4857
    switch (rB(ctx->opcode)) {
4858
    case 0:
4859
    case 1:
4860
    case 2:
4861
        gen_op_load_gpr_T0(rA(ctx->opcode));
4862
        gen_op_440_tlbre(rB(ctx->opcode));
4863
        gen_op_store_T0_gpr(rD(ctx->opcode));
4864
        break;
4865
    default:
4866
        RET_INVAL(ctx);
4867
        break;
4868
    }
4869
#endif
4870
}
4871

    
4872
/* tlbsx - tlbsx. */
4873
GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
4874
{
4875
#if defined(CONFIG_USER_ONLY)
4876
    RET_PRIVOPC(ctx);
4877
#else
4878
    if (unlikely(!ctx->supervisor)) {
4879
        RET_PRIVOPC(ctx);
4880
        return;
4881
    }
4882
    gen_addr_reg_index(ctx);
4883
    if (Rc(ctx->opcode))
4884
        gen_op_440_tlbsx_();
4885
    else
4886
        gen_op_440_tlbsx();
4887
    gen_op_store_T0_gpr(rD(ctx->opcode));
4888
#endif
4889
}
4890

    
4891
/* tlbwe */
4892
GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
4893
{
4894
#if defined(CONFIG_USER_ONLY)
4895
    RET_PRIVOPC(ctx);
4896
#else
4897
    if (unlikely(!ctx->supervisor)) {
4898
        RET_PRIVOPC(ctx);
4899
        return;
4900
    }
4901
    switch (rB(ctx->opcode)) {
4902
    case 0:
4903
    case 1:
4904
    case 2:
4905
        gen_op_load_gpr_T0(rA(ctx->opcode));
4906
        gen_op_load_gpr_T1(rS(ctx->opcode));
4907
        gen_op_440_tlbwe(rB(ctx->opcode));
4908
        break;
4909
    default:
4910
        RET_INVAL(ctx);
4911
        break;
4912
    }
4913
#endif
4914
}
4915

    
4916
/* wrtee */
4917
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, 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_load_gpr_T0(rD(ctx->opcode));
4927
    gen_op_wrte();
4928
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4929
#endif
4930
}
4931

    
4932
/* wrteei */
4933
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4934
{
4935
#if defined(CONFIG_USER_ONLY)
4936
    RET_PRIVOPC(ctx);
4937
#else
4938
    if (unlikely(!ctx->supervisor)) {
4939
        RET_PRIVOPC(ctx);
4940
        return;
4941
    }
4942
    gen_op_set_T0(ctx->opcode & 0x00010000);
4943
    gen_op_wrte();
4944
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4945
#endif
4946
}
4947

    
4948
/* PowerPC 440 specific instructions */
4949
/* dlmzb */
4950
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
4951
{
4952
    gen_op_load_gpr_T0(rS(ctx->opcode));
4953
    gen_op_load_gpr_T1(rB(ctx->opcode));
4954
    gen_op_440_dlmzb();
4955
    gen_op_store_T0_gpr(rA(ctx->opcode));
4956
    gen_op_store_xer_bc();
4957
    if (Rc(ctx->opcode)) {
4958
        gen_op_440_dlmzb_update_Rc();
4959
        gen_op_store_T0_crf(0);
4960
    }
4961
}
4962

    
4963
/* mbar replaces eieio on 440 */
4964
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
4965
{
4966
    /* interpreted as no-op */
4967
}
4968

    
4969
/* msync replaces sync on 440 */
4970
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
4971
{
4972
    /* interpreted as no-op */
4973
}
4974

    
4975
/* icbt */
4976
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
4977
{
4978
    /* interpreted as no-op */
4979
    /* XXX: specification say this is treated as a load by the MMU
4980
     *      but does not generate any exception
4981
     */
4982
}
4983

    
4984
#if defined(TARGET_PPCEMB)
4985
/***                           SPE extension                               ***/
4986

    
4987
/* Register moves */
4988
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
4989
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
4990
#if 0 // unused
4991
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
4992
#endif
4993

    
4994
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
4995
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
4996
#if 0 // unused
4997
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
4998
#endif
4999

    
5000
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5001
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5002
{                                                                             \
5003
    if (Rc(ctx->opcode))                                                      \
5004
        gen_##name1(ctx);                                                     \
5005
    else                                                                      \
5006
        gen_##name0(ctx);                                                     \
5007
}
5008

    
5009
/* Handler for undefined SPE opcodes */
5010
static inline void gen_speundef (DisasContext *ctx)
5011
{
5012
    RET_INVAL(ctx);
5013
}
5014

    
5015
/* SPE load and stores */
5016
static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5017
{
5018
    target_long simm = rB(ctx->opcode);
5019

    
5020
    if (rA(ctx->opcode) == 0) {
5021
        gen_set_T0(simm << sh);
5022
    } else {
5023
        gen_op_load_gpr_T0(rA(ctx->opcode));
5024
        if (likely(simm != 0))
5025
            gen_op_addi(simm << sh);
5026
    }
5027
}
5028

    
5029
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5030
#if defined(CONFIG_USER_ONLY)
5031
#if defined(TARGET_PPC64)
5032
#define OP_SPE_LD_TABLE(name)                                                 \
5033
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5034
    &gen_op_spe_l##name##_raw,                                                \
5035
    &gen_op_spe_l##name##_le_raw,                                             \
5036
    &gen_op_spe_l##name##_64_raw,                                             \
5037
    &gen_op_spe_l##name##_le_64_raw,                                          \
5038
};
5039
#define OP_SPE_ST_TABLE(name)                                                 \
5040
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5041
    &gen_op_spe_st##name##_raw,                                               \
5042
    &gen_op_spe_st##name##_le_raw,                                            \
5043
    &gen_op_spe_st##name##_64_raw,                                            \
5044
    &gen_op_spe_st##name##_le_64_raw,                                         \
5045
};
5046
#else /* defined(TARGET_PPC64) */
5047
#define OP_SPE_LD_TABLE(name)                                                 \
5048
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5049
    &gen_op_spe_l##name##_raw,                                                \
5050
    &gen_op_spe_l##name##_le_raw,                                             \
5051
};
5052
#define OP_SPE_ST_TABLE(name)                                                 \
5053
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5054
    &gen_op_spe_st##name##_raw,                                               \
5055
    &gen_op_spe_st##name##_le_raw,                                            \
5056
};
5057
#endif /* defined(TARGET_PPC64) */
5058
#else /* defined(CONFIG_USER_ONLY) */
5059
#if defined(TARGET_PPC64)
5060
#define OP_SPE_LD_TABLE(name)                                                 \
5061
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5062
    &gen_op_spe_l##name##_user,                                               \
5063
    &gen_op_spe_l##name##_le_user,                                            \
5064
    &gen_op_spe_l##name##_kernel,                                             \
5065
    &gen_op_spe_l##name##_le_kernel,                                          \
5066
    &gen_op_spe_l##name##_64_user,                                            \
5067
    &gen_op_spe_l##name##_le_64_user,                                         \
5068
    &gen_op_spe_l##name##_64_kernel,                                          \
5069
    &gen_op_spe_l##name##_le_64_kernel,                                       \
5070
};
5071
#define OP_SPE_ST_TABLE(name)                                                 \
5072
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5073
    &gen_op_spe_st##name##_user,                                              \
5074
    &gen_op_spe_st##name##_le_user,                                           \
5075
    &gen_op_spe_st##name##_kernel,                                            \
5076
    &gen_op_spe_st##name##_le_kernel,                                         \
5077
    &gen_op_spe_st##name##_64_user,                                           \
5078
    &gen_op_spe_st##name##_le_64_user,                                        \
5079
    &gen_op_spe_st##name##_64_kernel,                                         \
5080
    &gen_op_spe_st##name##_le_64_kernel,                                      \
5081
};
5082
#else /* defined(TARGET_PPC64) */
5083
#define OP_SPE_LD_TABLE(name)                                                 \
5084
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5085
    &gen_op_spe_l##name##_user,                                               \
5086
    &gen_op_spe_l##name##_le_user,                                            \
5087
    &gen_op_spe_l##name##_kernel,                                             \
5088
    &gen_op_spe_l##name##_le_kernel,                                          \
5089
};
5090
#define OP_SPE_ST_TABLE(name)                                                 \
5091
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5092
    &gen_op_spe_st##name##_user,                                              \
5093
    &gen_op_spe_st##name##_le_user,                                           \
5094
    &gen_op_spe_st##name##_kernel,                                            \
5095
    &gen_op_spe_st##name##_le_kernel,                                         \
5096
};
5097
#endif /* defined(TARGET_PPC64) */
5098
#endif /* defined(CONFIG_USER_ONLY) */
5099

    
5100
#define GEN_SPE_LD(name, sh)                                                  \
5101
static inline void gen_evl##name (DisasContext *ctx)                          \
5102
{                                                                             \
5103
    if (unlikely(!ctx->spe_enabled)) {                                        \
5104
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5105
        return;                                                               \
5106
    }                                                                         \
5107
    gen_addr_spe_imm_index(ctx, sh);                                          \
5108
    op_spe_ldst(spe_l##name);                                                 \
5109
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5110
}
5111

    
5112
#define GEN_SPE_LDX(name)                                                     \
5113
static inline void gen_evl##name##x (DisasContext *ctx)                       \
5114
{                                                                             \
5115
    if (unlikely(!ctx->spe_enabled)) {                                        \
5116
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5117
        return;                                                               \
5118
    }                                                                         \
5119
    gen_addr_reg_index(ctx);                                                  \
5120
    op_spe_ldst(spe_l##name);                                                 \
5121
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5122
}
5123

    
5124
#define GEN_SPEOP_LD(name, sh)                                                \
5125
OP_SPE_LD_TABLE(name);                                                        \
5126
GEN_SPE_LD(name, sh);                                                         \
5127
GEN_SPE_LDX(name)
5128

    
5129
#define GEN_SPE_ST(name, sh)                                                  \
5130
static inline void gen_evst##name (DisasContext *ctx)                         \
5131
{                                                                             \
5132
    if (unlikely(!ctx->spe_enabled)) {                                        \
5133
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5134
        return;                                                               \
5135
    }                                                                         \
5136
    gen_addr_spe_imm_index(ctx, sh);                                          \
5137
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5138
    op_spe_ldst(spe_st##name);                                                \
5139
}
5140

    
5141
#define GEN_SPE_STX(name)                                                     \
5142
static inline void gen_evst##name##x (DisasContext *ctx)                      \
5143
{                                                                             \
5144
    if (unlikely(!ctx->spe_enabled)) {                                        \
5145
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5146
        return;                                                               \
5147
    }                                                                         \
5148
    gen_addr_reg_index(ctx);                                                  \
5149
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5150
    op_spe_ldst(spe_st##name);                                                \
5151
}
5152

    
5153
#define GEN_SPEOP_ST(name, sh)                                                \
5154
OP_SPE_ST_TABLE(name);                                                        \
5155
GEN_SPE_ST(name, sh);                                                         \
5156
GEN_SPE_STX(name)
5157

    
5158
#define GEN_SPEOP_LDST(name, sh)                                              \
5159
GEN_SPEOP_LD(name, sh);                                                       \
5160
GEN_SPEOP_ST(name, sh)
5161

    
5162
/* SPE arithmetic and logic */
5163
#define GEN_SPEOP_ARITH2(name)                                                \
5164
static inline void gen_##name (DisasContext *ctx)                             \
5165
{                                                                             \
5166
    if (unlikely(!ctx->spe_enabled)) {                                        \
5167
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5168
        return;                                                               \
5169
    }                                                                         \
5170
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5171
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5172
    gen_op_##name();                                                          \
5173
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5174
}
5175

    
5176
#define GEN_SPEOP_ARITH1(name)                                                \
5177
static inline void gen_##name (DisasContext *ctx)                             \
5178
{                                                                             \
5179
    if (unlikely(!ctx->spe_enabled)) {                                        \
5180
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5181
        return;                                                               \
5182
    }                                                                         \
5183
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5184
    gen_op_##name();                                                          \
5185
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5186
}
5187

    
5188
#define GEN_SPEOP_COMP(name)                                                  \
5189
static inline void gen_##name (DisasContext *ctx)                             \
5190
{                                                                             \
5191
    if (unlikely(!ctx->spe_enabled)) {                                        \
5192
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5193
        return;                                                               \
5194
    }                                                                         \
5195
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5196
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5197
    gen_op_##name();                                                          \
5198
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5199
}
5200

    
5201
/* Logical */
5202
GEN_SPEOP_ARITH2(evand);
5203
GEN_SPEOP_ARITH2(evandc);
5204
GEN_SPEOP_ARITH2(evxor);
5205
GEN_SPEOP_ARITH2(evor);
5206
GEN_SPEOP_ARITH2(evnor);
5207
GEN_SPEOP_ARITH2(eveqv);
5208
GEN_SPEOP_ARITH2(evorc);
5209
GEN_SPEOP_ARITH2(evnand);
5210
GEN_SPEOP_ARITH2(evsrwu);
5211
GEN_SPEOP_ARITH2(evsrws);
5212
GEN_SPEOP_ARITH2(evslw);
5213
GEN_SPEOP_ARITH2(evrlw);
5214
GEN_SPEOP_ARITH2(evmergehi);
5215
GEN_SPEOP_ARITH2(evmergelo);
5216
GEN_SPEOP_ARITH2(evmergehilo);
5217
GEN_SPEOP_ARITH2(evmergelohi);
5218

    
5219
/* Arithmetic */
5220
GEN_SPEOP_ARITH2(evaddw);
5221
GEN_SPEOP_ARITH2(evsubfw);
5222
GEN_SPEOP_ARITH1(evabs);
5223
GEN_SPEOP_ARITH1(evneg);
5224
GEN_SPEOP_ARITH1(evextsb);
5225
GEN_SPEOP_ARITH1(evextsh);
5226
GEN_SPEOP_ARITH1(evrndw);
5227
GEN_SPEOP_ARITH1(evcntlzw);
5228
GEN_SPEOP_ARITH1(evcntlsw);
5229
static inline void gen_brinc (DisasContext *ctx)
5230
{
5231
    /* Note: brinc is usable even if SPE is disabled */
5232
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5233
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5234
    gen_op_brinc();
5235
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5236
}
5237

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

    
5251
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5252
static inline void gen_##name##i (DisasContext *ctx)                          \
5253
{                                                                             \
5254
    if (unlikely(!ctx->spe_enabled)) {                                        \
5255
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5256
        return;                                                               \
5257
    }                                                                         \
5258
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5259
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5260
    gen_op_##name();                                                          \
5261
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5262
}
5263

    
5264
GEN_SPEOP_ARITH_IMM2(evaddw);
5265
#define gen_evaddiw gen_evaddwi
5266
GEN_SPEOP_ARITH_IMM2(evsubfw);
5267
#define gen_evsubifw gen_evsubfwi
5268
GEN_SPEOP_LOGIC_IMM2(evslw);
5269
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5270
#define gen_evsrwis gen_evsrwsi
5271
GEN_SPEOP_LOGIC_IMM2(evsrws);
5272
#define gen_evsrwiu gen_evsrwui
5273
GEN_SPEOP_LOGIC_IMM2(evrlw);
5274

    
5275
static inline void gen_evsplati (DisasContext *ctx)
5276
{
5277
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5278

    
5279
    gen_op_splatwi_T0_64(imm);
5280
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5281
}
5282

    
5283
static inline void gen_evsplatfi (DisasContext *ctx)
5284
{
5285
    uint32_t imm = rA(ctx->opcode) << 27;
5286

    
5287
    gen_op_splatwi_T0_64(imm);
5288
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5289
}
5290

    
5291
/* Comparison */
5292
GEN_SPEOP_COMP(evcmpgtu);
5293
GEN_SPEOP_COMP(evcmpgts);
5294
GEN_SPEOP_COMP(evcmpltu);
5295
GEN_SPEOP_COMP(evcmplts);
5296
GEN_SPEOP_COMP(evcmpeq);
5297

    
5298
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5299
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5300
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5301
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5302
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5303
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5304
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5305
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5306
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5307
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5308
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5309
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5310
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5311
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5312
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5313
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5314
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5315
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5316
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5317
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5318
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5319
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5320
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5321
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5322
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5323

    
5324
static inline void gen_evsel (DisasContext *ctx)
5325
{
5326
    if (unlikely(!ctx->spe_enabled)) {
5327
        RET_EXCP(ctx, EXCP_NO_SPE, 0);
5328
        return;
5329
    }
5330
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5331
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5332
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5333
    gen_op_evsel();
5334
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5335
}
5336

    
5337
GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5338
{
5339
    gen_evsel(ctx);
5340
}
5341
GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5342
{
5343
    gen_evsel(ctx);
5344
}
5345
GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5346
{
5347
    gen_evsel(ctx);
5348
}
5349
GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5350
{
5351
    gen_evsel(ctx);
5352
}
5353

    
5354
/* Load and stores */
5355
#if defined(TARGET_PPC64)
5356
/* In that case, we already have 64 bits load & stores
5357
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5358
 */
5359
#if defined(CONFIG_USER_ONLY)
5360
#define gen_op_spe_ldd_raw gen_op_ld_raw
5361
#define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
5362
#define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
5363
#define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
5364
#define gen_op_spe_stdd_raw gen_op_ld_raw
5365
#define gen_op_spe_stdd_64_raw gen_op_std_64_raw
5366
#define gen_op_spe_stdd_le_raw gen_op_std_le_raw
5367
#define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
5368
#else /* defined(CONFIG_USER_ONLY) */
5369
#define gen_op_spe_ldd_kernel gen_op_ld_kernel
5370
#define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
5371
#define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
5372
#define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
5373
#define gen_op_spe_ldd_user gen_op_ld_user
5374
#define gen_op_spe_ldd_64_user gen_op_ld_64_user
5375
#define gen_op_spe_ldd_le_user gen_op_ld_le_user
5376
#define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
5377
#define gen_op_spe_stdd_kernel gen_op_std_kernel
5378
#define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
5379
#define gen_op_spe_stdd_le_kernel gen_op_std_kernel
5380
#define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
5381
#define gen_op_spe_stdd_user gen_op_std_user
5382
#define gen_op_spe_stdd_64_user gen_op_std_64_user
5383
#define gen_op_spe_stdd_le_user gen_op_std_le_user
5384
#define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
5385
#endif /* defined(CONFIG_USER_ONLY) */
5386
#endif /* defined(TARGET_PPC64) */
5387
GEN_SPEOP_LDST(dd, 3);
5388
GEN_SPEOP_LDST(dw, 3);
5389
GEN_SPEOP_LDST(dh, 3);
5390
GEN_SPEOP_LDST(whe, 2);
5391
GEN_SPEOP_LD(whou, 2);
5392
GEN_SPEOP_LD(whos, 2);
5393
GEN_SPEOP_ST(who, 2);
5394

    
5395
#if defined(TARGET_PPC64)
5396
/* In that case, spe_stwwo is equivalent to stw */
5397
#if defined(CONFIG_USER_ONLY)
5398
#define gen_op_spe_stwwo_raw gen_op_stw_raw
5399
#define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
5400
#define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
5401
#define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
5402
#else
5403
#define gen_op_spe_stwwo_user gen_op_stw_user
5404
#define gen_op_spe_stwwo_le_user gen_op_stw_le_user
5405
#define gen_op_spe_stwwo_64_user gen_op_stw_64_user
5406
#define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
5407
#define gen_op_spe_stwwo_kernel gen_op_stw_kernel
5408
#define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
5409
#define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
5410
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5411
#endif
5412
#endif
5413
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5414
static inline void gen_op_spe_stwwe_##suffix (void)                           \
5415
{                                                                             \
5416
    gen_op_srli32_T1_64();                                                    \
5417
    gen_op_spe_stwwo_##suffix();                                              \
5418
}
5419
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5420
static inline void gen_op_spe_stwwe_le_##suffix (void)                        \
5421
{                                                                             \
5422
    gen_op_srli32_T1_64();                                                    \
5423
    gen_op_spe_stwwo_le_##suffix();                                           \
5424
}
5425
#if defined(TARGET_PPC64)
5426
#define GEN_OP_SPE_STWWE(suffix)                                              \
5427
_GEN_OP_SPE_STWWE(suffix);                                                    \
5428
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5429
static inline void gen_op_spe_stwwe_64_##suffix (void)                        \
5430
{                                                                             \
5431
    gen_op_srli32_T1_64();                                                    \
5432
    gen_op_spe_stwwo_64_##suffix();                                           \
5433
}                                                                             \
5434
static inline void gen_op_spe_stwwe_le_64_##suffix (void)                     \
5435
{                                                                             \
5436
    gen_op_srli32_T1_64();                                                    \
5437
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5438
}
5439
#else
5440
#define GEN_OP_SPE_STWWE(suffix)                                              \
5441
_GEN_OP_SPE_STWWE(suffix);                                                    \
5442
_GEN_OP_SPE_STWWE_LE(suffix)
5443
#endif
5444
#if defined(CONFIG_USER_ONLY)
5445
GEN_OP_SPE_STWWE(raw);
5446
#else /* defined(CONFIG_USER_ONLY) */
5447
GEN_OP_SPE_STWWE(kernel);
5448
GEN_OP_SPE_STWWE(user);
5449
#endif /* defined(CONFIG_USER_ONLY) */
5450
GEN_SPEOP_ST(wwe, 2);
5451
GEN_SPEOP_ST(wwo, 2);
5452

    
5453
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5454
static inline void gen_op_spe_l##name##_##suffix (void)                       \
5455
{                                                                             \
5456
    gen_op_##op##_##suffix();                                                 \
5457
    gen_op_splatw_T1_64();                                                    \
5458
}
5459

    
5460
#define GEN_OP_SPE_LHE(suffix)                                                \
5461
static inline void gen_op_spe_lhe_##suffix (void)                             \
5462
{                                                                             \
5463
    gen_op_spe_lh_##suffix();                                                 \
5464
    gen_op_sli16_T1_64();                                                     \
5465
}
5466

    
5467
#define GEN_OP_SPE_LHX(suffix)                                                \
5468
static inline void gen_op_spe_lhx_##suffix (void)                             \
5469
{                                                                             \
5470
    gen_op_spe_lh_##suffix();                                                 \
5471
    gen_op_extsh_T1_64();                                                     \
5472
}
5473

    
5474
#if defined(CONFIG_USER_ONLY)
5475
GEN_OP_SPE_LHE(raw);
5476
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5477
GEN_OP_SPE_LHE(le_raw);
5478
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5479
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5480
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5481
GEN_OP_SPE_LHX(raw);
5482
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5483
GEN_OP_SPE_LHX(le_raw);
5484
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5485
#if defined(TARGET_PPC64)
5486
GEN_OP_SPE_LHE(64_raw);
5487
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5488
GEN_OP_SPE_LHE(le_64_raw);
5489
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5490
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5491
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5492
GEN_OP_SPE_LHX(64_raw);
5493
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5494
GEN_OP_SPE_LHX(le_64_raw);
5495
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5496
#endif
5497
#else
5498
GEN_OP_SPE_LHE(kernel);
5499
GEN_OP_SPE_LHE(user);
5500
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5501
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5502
GEN_OP_SPE_LHE(le_kernel);
5503
GEN_OP_SPE_LHE(le_user);
5504
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5505
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5506
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5507
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5508
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5509
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5510
GEN_OP_SPE_LHX(kernel);
5511
GEN_OP_SPE_LHX(user);
5512
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5513
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5514
GEN_OP_SPE_LHX(le_kernel);
5515
GEN_OP_SPE_LHX(le_user);
5516
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5517
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5518
#if defined(TARGET_PPC64)
5519
GEN_OP_SPE_LHE(64_kernel);
5520
GEN_OP_SPE_LHE(64_user);
5521
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5522
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5523
GEN_OP_SPE_LHE(le_64_kernel);
5524
GEN_OP_SPE_LHE(le_64_user);
5525
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5526
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5527
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5528
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5529
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5530
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5531
GEN_OP_SPE_LHX(64_kernel);
5532
GEN_OP_SPE_LHX(64_user);
5533
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5534
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5535
GEN_OP_SPE_LHX(le_64_kernel);
5536
GEN_OP_SPE_LHX(le_64_user);
5537
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5538
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5539
#endif
5540
#endif
5541
GEN_SPEOP_LD(hhesplat, 1);
5542
GEN_SPEOP_LD(hhousplat, 1);
5543
GEN_SPEOP_LD(hhossplat, 1);
5544
GEN_SPEOP_LD(wwsplat, 2);
5545
GEN_SPEOP_LD(whsplat, 2);
5546

    
5547
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5548
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5549
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5550
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5551
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5552
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5553
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5554
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5555
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5556
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5557
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5558
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5559
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5560
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5561
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5562
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5563
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5564
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5565

    
5566
/* Multiply and add - TODO */
5567
#if 0
5568
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5569
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5570
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5571
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5572
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5573
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5574
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5575
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5576
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5577
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5578
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5579
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5580

5581
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5582
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5583
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5584
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5585
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5586
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5587
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5588
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5589
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5590
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5591
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5592
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5593
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5594
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5595

5596
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5597
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5598
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5599
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5600
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5601
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5602

5603
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5604
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5605
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5606
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5607
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5608
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5609
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5610
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5611
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5612
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5613
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5614
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5615

5616
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5617
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5618
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5619
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5620
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5621

5622
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5623
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5624
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5625
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5626
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5627
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5628
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5629
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5630
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5631
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5632
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5633
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5634

5635
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5636
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5637
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5638
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5639
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5640
#endif
5641

    
5642
/***                      SPE floating-point extension                     ***/
5643
#define GEN_SPEFPUOP_CONV(name)                                               \
5644
static inline void gen_##name (DisasContext *ctx)                             \
5645
{                                                                             \
5646
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5647
    gen_op_##name();                                                          \
5648
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5649
}
5650

    
5651
/* Single precision floating-point vectors operations */
5652
/* Arithmetic */
5653
GEN_SPEOP_ARITH2(evfsadd);
5654
GEN_SPEOP_ARITH2(evfssub);
5655
GEN_SPEOP_ARITH2(evfsmul);
5656
GEN_SPEOP_ARITH2(evfsdiv);
5657
GEN_SPEOP_ARITH1(evfsabs);
5658
GEN_SPEOP_ARITH1(evfsnabs);
5659
GEN_SPEOP_ARITH1(evfsneg);
5660
/* Conversion */
5661
GEN_SPEFPUOP_CONV(evfscfui);
5662
GEN_SPEFPUOP_CONV(evfscfsi);
5663
GEN_SPEFPUOP_CONV(evfscfuf);
5664
GEN_SPEFPUOP_CONV(evfscfsf);
5665
GEN_SPEFPUOP_CONV(evfsctui);
5666
GEN_SPEFPUOP_CONV(evfsctsi);
5667
GEN_SPEFPUOP_CONV(evfsctuf);
5668
GEN_SPEFPUOP_CONV(evfsctsf);
5669
GEN_SPEFPUOP_CONV(evfsctuiz);
5670
GEN_SPEFPUOP_CONV(evfsctsiz);
5671
/* Comparison */
5672
GEN_SPEOP_COMP(evfscmpgt);
5673
GEN_SPEOP_COMP(evfscmplt);
5674
GEN_SPEOP_COMP(evfscmpeq);
5675
GEN_SPEOP_COMP(evfststgt);
5676
GEN_SPEOP_COMP(evfststlt);
5677
GEN_SPEOP_COMP(evfststeq);
5678

    
5679
/* Opcodes definitions */
5680
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5681
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5682
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5683
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5684
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5685
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5686
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5687
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5688
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5689
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5690
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5691
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5692
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5693
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5694

    
5695
/* Single precision floating-point operations */
5696
/* Arithmetic */
5697
GEN_SPEOP_ARITH2(efsadd);
5698
GEN_SPEOP_ARITH2(efssub);
5699
GEN_SPEOP_ARITH2(efsmul);
5700
GEN_SPEOP_ARITH2(efsdiv);
5701
GEN_SPEOP_ARITH1(efsabs);
5702
GEN_SPEOP_ARITH1(efsnabs);
5703
GEN_SPEOP_ARITH1(efsneg);
5704
/* Conversion */
5705
GEN_SPEFPUOP_CONV(efscfui);
5706
GEN_SPEFPUOP_CONV(efscfsi);
5707
GEN_SPEFPUOP_CONV(efscfuf);
5708
GEN_SPEFPUOP_CONV(efscfsf);
5709
GEN_SPEFPUOP_CONV(efsctui);
5710
GEN_SPEFPUOP_CONV(efsctsi);
5711
GEN_SPEFPUOP_CONV(efsctuf);
5712
GEN_SPEFPUOP_CONV(efsctsf);
5713
GEN_SPEFPUOP_CONV(efsctuiz);
5714
GEN_SPEFPUOP_CONV(efsctsiz);
5715
GEN_SPEFPUOP_CONV(efscfd);
5716
/* Comparison */
5717
GEN_SPEOP_COMP(efscmpgt);
5718
GEN_SPEOP_COMP(efscmplt);
5719
GEN_SPEOP_COMP(efscmpeq);
5720
GEN_SPEOP_COMP(efststgt);
5721
GEN_SPEOP_COMP(efststlt);
5722
GEN_SPEOP_COMP(efststeq);
5723

    
5724
/* Opcodes definitions */
5725
GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5726
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5727
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5728
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5729
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5730
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5731
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5732
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5733
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5734
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5735
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5736
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5737
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5738

    
5739
/* Double precision floating-point operations */
5740
/* Arithmetic */
5741
GEN_SPEOP_ARITH2(efdadd);
5742
GEN_SPEOP_ARITH2(efdsub);
5743
GEN_SPEOP_ARITH2(efdmul);
5744
GEN_SPEOP_ARITH2(efddiv);
5745
GEN_SPEOP_ARITH1(efdabs);
5746
GEN_SPEOP_ARITH1(efdnabs);
5747
GEN_SPEOP_ARITH1(efdneg);
5748
/* Conversion */
5749

    
5750
GEN_SPEFPUOP_CONV(efdcfui);
5751
GEN_SPEFPUOP_CONV(efdcfsi);
5752
GEN_SPEFPUOP_CONV(efdcfuf);
5753
GEN_SPEFPUOP_CONV(efdcfsf);
5754
GEN_SPEFPUOP_CONV(efdctui);
5755
GEN_SPEFPUOP_CONV(efdctsi);
5756
GEN_SPEFPUOP_CONV(efdctuf);
5757
GEN_SPEFPUOP_CONV(efdctsf);
5758
GEN_SPEFPUOP_CONV(efdctuiz);
5759
GEN_SPEFPUOP_CONV(efdctsiz);
5760
GEN_SPEFPUOP_CONV(efdcfs);
5761
GEN_SPEFPUOP_CONV(efdcfuid);
5762
GEN_SPEFPUOP_CONV(efdcfsid);
5763
GEN_SPEFPUOP_CONV(efdctuidz);
5764
GEN_SPEFPUOP_CONV(efdctsidz);
5765
/* Comparison */
5766
GEN_SPEOP_COMP(efdcmpgt);
5767
GEN_SPEOP_COMP(efdcmplt);
5768
GEN_SPEOP_COMP(efdcmpeq);
5769
GEN_SPEOP_COMP(efdtstgt);
5770
GEN_SPEOP_COMP(efdtstlt);
5771
GEN_SPEOP_COMP(efdtsteq);
5772

    
5773
/* Opcodes definitions */
5774
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
5775
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
5776
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
5777
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
5778
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
5779
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
5780
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
5781
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
5782
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
5783
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
5784
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
5785
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
5786
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
5787
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
5788
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
5789
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
5790
#endif
5791

    
5792
/* End opcode list */
5793
GEN_OPCODE_MARK(end);
5794

    
5795
#include "translate_init.c"
5796

    
5797
/*****************************************************************************/
5798
/* Misc PowerPC helpers */
5799
static inline uint32_t load_xer (CPUState *env)
5800
{
5801
    return (xer_so << XER_SO) |
5802
        (xer_ov << XER_OV) |
5803
        (xer_ca << XER_CA) |
5804
        (xer_bc << XER_BC) |
5805
        (xer_cmp << XER_CMP);
5806
}
5807

    
5808
void cpu_dump_state (CPUState *env, FILE *f,
5809
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5810
                     int flags)
5811
{
5812
#if defined(TARGET_PPC64) || 1
5813
#define FILL ""
5814
#define RGPL  4
5815
#define RFPL  4
5816
#else
5817
#define FILL "        "
5818
#define RGPL  8
5819
#define RFPL  4
5820
#endif
5821

    
5822
    int i;
5823

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

    
5875
#undef RGPL
5876
#undef RFPL
5877
#undef FILL
5878
}
5879

    
5880
void cpu_dump_statistics (CPUState *env, FILE*f,
5881
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5882
                          int flags)
5883
{
5884
#if defined(DO_PPC_STATISTICS)
5885
    opc_handler_t **t1, **t2, **t3, *handler;
5886
    int op1, op2, op3;
5887

    
5888
    t1 = env->opcodes;
5889
    for (op1 = 0; op1 < 64; op1++) {
5890
        handler = t1[op1];
5891
        if (is_indirect_opcode(handler)) {
5892
            t2 = ind_table(handler);
5893
            for (op2 = 0; op2 < 32; op2++) {
5894
                handler = t2[op2];
5895
                if (is_indirect_opcode(handler)) {
5896
                    t3 = ind_table(handler);
5897
                    for (op3 = 0; op3 < 32; op3++) {
5898
                        handler = t3[op3];
5899
                        if (handler->count == 0)
5900
                            continue;
5901
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
5902
                                    "%016llx %lld\n",
5903
                                    op1, op2, op3, op1, (op3 << 5) | op2,
5904
                                    handler->oname,
5905
                                    handler->count, handler->count);
5906
                    }
5907
                } else {
5908
                    if (handler->count == 0)
5909
                        continue;
5910
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
5911
                                "%016llx %lld\n",
5912
                                op1, op2, op1, op2, handler->oname,
5913
                                handler->count, handler->count);
5914
                }
5915
            }
5916
        } else {
5917
            if (handler->count == 0)
5918
                continue;
5919
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
5920
                        op1, op1, handler->oname,
5921
                        handler->count, handler->count);
5922
        }
5923
    }
5924
#endif
5925
}
5926

    
5927
/*****************************************************************************/
5928
static inline int gen_intermediate_code_internal (CPUState *env,
5929
                                                  TranslationBlock *tb,
5930
                                                  int search_pc)
5931
{
5932
    DisasContext ctx, *ctxp = &ctx;
5933
    opc_handler_t **table, *handler;
5934
    target_ulong pc_start;
5935
    uint16_t *gen_opc_end;
5936
    int j, lj = -1;
5937

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

    
6125
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6126
{
6127
    return gen_intermediate_code_internal(env, tb, 0);
6128
}
6129

    
6130
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6131
{
6132
    return gen_intermediate_code_internal(env, tb, 1);
6133
}