Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ e1833e1f

History | View | Annotate | Download (206.2 kB)

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

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

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

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

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

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

    
54
#include "gen-op.h"
55

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
380
    return ret;
381
}
382

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1730
/***                         Floating-Point compare                        ***/
1731
/* fcmpo */
1732
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1733
{
1734
    if (unlikely(!ctx->fpu_enabled)) {
1735
        GEN_EXCP_NO_FP(ctx);
1736
        return;
1737
    }
1738
    gen_op_reset_scrfx();
1739
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1740
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1741
    gen_op_fcmpo();
1742
    gen_op_store_T0_crf(crfD(ctx->opcode));
1743
}
1744

    
1745
/* fcmpu */
1746
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1747
{
1748
    if (unlikely(!ctx->fpu_enabled)) {
1749
        GEN_EXCP_NO_FP(ctx);
1750
        return;
1751
    }
1752
    gen_op_reset_scrfx();
1753
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1754
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1755
    gen_op_fcmpu();
1756
    gen_op_store_T0_crf(crfD(ctx->opcode));
1757
}
1758

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4223
/* svc is not implemented for now */
4224

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4927
/* wrtee */
4928
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4929
{
4930
#if defined(CONFIG_USER_ONLY)
4931
    GEN_EXCP_PRIVOPC(ctx);
4932
#else
4933
    if (unlikely(!ctx->supervisor)) {
4934
        GEN_EXCP_PRIVOPC(ctx);
4935
        return;
4936
    }
4937
    gen_op_load_gpr_T0(rD(ctx->opcode));
4938
    gen_op_wrte();
4939
    GEN_STOP(ctx);
4940
#endif
4941
}
4942

    
4943
/* wrteei */
4944
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4945
{
4946
#if defined(CONFIG_USER_ONLY)
4947
    GEN_EXCP_PRIVOPC(ctx);
4948
#else
4949
    if (unlikely(!ctx->supervisor)) {
4950
        GEN_EXCP_PRIVOPC(ctx);
4951
        return;
4952
    }
4953
    gen_op_set_T0(ctx->opcode & 0x00010000);
4954
    gen_op_wrte();
4955
    GEN_STOP(ctx);
4956
#endif
4957
}
4958

    
4959
/* PowerPC 440 specific instructions */
4960
/* dlmzb */
4961
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
4962
{
4963
    gen_op_load_gpr_T0(rS(ctx->opcode));
4964
    gen_op_load_gpr_T1(rB(ctx->opcode));
4965
    gen_op_440_dlmzb();
4966
    gen_op_store_T0_gpr(rA(ctx->opcode));
4967
    gen_op_store_xer_bc();
4968
    if (Rc(ctx->opcode)) {
4969
        gen_op_440_dlmzb_update_Rc();
4970
        gen_op_store_T0_crf(0);
4971
    }
4972
}
4973

    
4974
/* mbar replaces eieio on 440 */
4975
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
4976
{
4977<