Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 966439a6

History | View | Annotate | Download (196.9 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
//#define DO_SINGLE_STEP
31
//#define PPC_DEBUG_DISAS
32
//#define DEBUG_MEMORY_ACCESSES
33
//#define DO_PPC_STATISTICS
34

    
35
#if defined(USE_DIRECT_JUMP)
36
#define TBPARAM(x)
37
#else
38
#define TBPARAM(x) (long)(x)
39
#endif
40

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

    
48
static uint16_t *gen_opc_ptr;
49
static uint32_t *gen_opparam_ptr;
50

    
51
#include "gen-op.h"
52

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

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

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

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

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

    
111
/* Condition register moves */
112
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
113
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
114
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
115
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
116

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

    
127
/* General purpose registers moves */
128
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
129
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
130
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
131

    
132
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
133
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
134
#if 0 // unused
135
GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
136
#endif
137

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

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

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

    
184
static inline void gen_set_Rc0 (DisasContext *ctx)
185
{
186
#if defined(TARGET_PPC64)
187
    if (ctx->sf_mode)
188
        gen_op_cmpi_64(0);
189
    else
190
#endif
191
        gen_op_cmpi(0);
192
    gen_op_set_Rc0();
193
}
194

    
195
static inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
196
{
197
#if defined(TARGET_PPC64)
198
    if (ctx->sf_mode)
199
        gen_op_update_nip_64(nip >> 32, nip);
200
    else
201
#endif
202
        gen_op_update_nip(nip);
203
}
204

    
205
#define RET_EXCP(ctx, excp, error)                                            \
206
do {                                                                          \
207
    if ((ctx)->exception == EXCP_NONE) {                                      \
208
        gen_update_nip(ctx, (ctx)->nip);                                      \
209
    }                                                                         \
210
    gen_op_raise_exception_err((excp), (error));                              \
211
    ctx->exception = (excp);                                                  \
212
} while (0)
213

    
214
#define RET_INVAL(ctx)                                                        \
215
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
216

    
217
#define RET_PRIVOPC(ctx)                                                      \
218
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
219

    
220
#define RET_PRIVREG(ctx)                                                      \
221
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
222

    
223
/* Stop translation */
224
static inline void RET_STOP (DisasContext *ctx)
225
{
226
    gen_update_nip(ctx, ctx->nip);
227
    ctx->exception = EXCP_MTMSR;
228
}
229

    
230
/* No need to update nip here, as execution flow will change */
231
static inline void RET_CHG_FLOW (DisasContext *ctx)
232
{
233
    ctx->exception = EXCP_MTMSR;
234
}
235

    
236
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
237
static void gen_##name (DisasContext *ctx);                                   \
238
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
239
static void gen_##name (DisasContext *ctx)
240

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

    
252
/***                           Instruction decoding                        ***/
253
#define EXTRACT_HELPER(name, shift, nb)                                       \
254
static inline uint32_t name (uint32_t opcode)                                 \
255
{                                                                             \
256
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
257
}
258

    
259
#define EXTRACT_SHELPER(name, shift, nb)                                      \
260
static inline int32_t name (uint32_t opcode)                                  \
261
{                                                                             \
262
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
263
}
264

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

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

    
314
EXTRACT_HELPER(CRM, 12, 8);
315
EXTRACT_HELPER(FM, 17, 8);
316
EXTRACT_HELPER(SR, 16, 4);
317
EXTRACT_HELPER(FPIMM, 20, 4);
318

    
319
/***                            Jump target decoding                       ***/
320
/* Displacement */
321
EXTRACT_SHELPER(d, 0, 16);
322
/* Immediate address */
323
static inline target_ulong LI (uint32_t opcode)
324
{
325
    return (opcode >> 0) & 0x03FFFFFC;
326
}
327

    
328
static inline uint32_t BD (uint32_t opcode)
329
{
330
    return (opcode >> 0) & 0xFFFC;
331
}
332

    
333
EXTRACT_HELPER(BO, 21, 5);
334
EXTRACT_HELPER(BI, 16, 5);
335
/* Absolute/relative address */
336
EXTRACT_HELPER(AA, 1, 1);
337
/* Link */
338
EXTRACT_HELPER(LK, 0, 1);
339

    
340
/* Create a mask between <start> and <end> bits */
341
static inline target_ulong MASK (uint32_t start, uint32_t end)
342
{
343
    target_ulong ret;
344

    
345
#if defined(TARGET_PPC64)
346
    if (likely(start == 0)) {
347
        ret = (uint64_t)(-1ULL) << (63 - end);
348
    } else if (likely(end == 63)) {
349
        ret = (uint64_t)(-1ULL) >> start;
350
    }
351
#else
352
    if (likely(start == 0)) {
353
        ret = (uint32_t)(-1ULL) << (31  - end);
354
    } else if (likely(end == 31)) {
355
        ret = (uint32_t)(-1ULL) >> start;
356
    }
357
#endif
358
    else {
359
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
360
            (((target_ulong)(-1ULL) >> (end)) >> 1);
361
        if (unlikely(start > end))
362
            return ~ret;
363
    }
364

    
365
    return ret;
366
}
367

    
368
#if HOST_LONG_BITS == 64
369
#define OPC_ALIGN 8
370
#else
371
#define OPC_ALIGN 4
372
#endif
373
#if defined(__APPLE__)
374
#define OPCODES_SECTION                                                       \
375
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
376
#else
377
#define OPCODES_SECTION                                                       \
378
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
379
#endif
380

    
381
#if defined(DO_PPC_STATISTICS)
382
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
383
OPCODES_SECTION opcode_t opc_##name = {                                       \
384
    .opc1 = op1,                                                              \
385
    .opc2 = op2,                                                              \
386
    .opc3 = op3,                                                              \
387
    .pad  = { 0, },                                                           \
388
    .handler = {                                                              \
389
        .inval   = invl,                                                      \
390
        .type = _typ,                                                         \
391
        .handler = &gen_##name,                                               \
392
        .oname = stringify(name),                                             \
393
    },                                                                        \
394
    .oname = stringify(name),                                                 \
395
}
396
#else
397
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
398
OPCODES_SECTION opcode_t opc_##name = {                                       \
399
    .opc1 = op1,                                                              \
400
    .opc2 = op2,                                                              \
401
    .opc3 = op3,                                                              \
402
    .pad  = { 0, },                                                           \
403
    .handler = {                                                              \
404
        .inval   = invl,                                                      \
405
        .type = _typ,                                                         \
406
        .handler = &gen_##name,                                               \
407
    },                                                                        \
408
    .oname = stringify(name),                                                 \
409
}
410
#endif
411

    
412
#define GEN_OPCODE_MARK(name)                                                 \
413
OPCODES_SECTION opcode_t opc_##name = {                                       \
414
    .opc1 = 0xFF,                                                             \
415
    .opc2 = 0xFF,                                                             \
416
    .opc3 = 0xFF,                                                             \
417
    .pad  = { 0, },                                                           \
418
    .handler = {                                                              \
419
        .inval   = 0x00000000,                                                \
420
        .type = 0x00,                                                         \
421
        .handler = NULL,                                                      \
422
    },                                                                        \
423
    .oname = stringify(name),                                                 \
424
}
425

    
426
/* Start opcode list */
427
GEN_OPCODE_MARK(start);
428

    
429
/* Invalid instruction */
430
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
431
{
432
    RET_INVAL(ctx);
433
}
434

    
435
static opc_handler_t invalid_handler = {
436
    .inval   = 0xFFFFFFFF,
437
    .type    = PPC_NONE,
438
    .handler = gen_invalid,
439
};
440

    
441
/***                           Integer arithmetic                          ***/
442
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
443
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
444
{                                                                             \
445
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
446
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
447
    gen_op_##name();                                                          \
448
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
449
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
450
        gen_set_Rc0(ctx);                                                     \
451
}
452

    
453
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
454
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
455
{                                                                             \
456
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
457
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
458
    gen_op_##name();                                                          \
459
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
460
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
461
        gen_set_Rc0(ctx);                                                     \
462
}
463

    
464
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
465
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
466
{                                                                             \
467
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
468
    gen_op_##name();                                                          \
469
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
470
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
471
        gen_set_Rc0(ctx);                                                     \
472
}
473
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
474
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
475
{                                                                             \
476
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
477
    gen_op_##name();                                                          \
478
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
479
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
480
        gen_set_Rc0(ctx);                                                     \
481
}
482

    
483
/* Two operands arithmetic functions */
484
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
485
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
486
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
487

    
488
/* Two operands arithmetic functions with no overflow allowed */
489
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
490
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
491

    
492
/* One operand arithmetic functions */
493
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
494
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
495
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
496

    
497
#if defined(TARGET_PPC64)
498
#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
499
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
500
{                                                                             \
501
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
502
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
503
    if (ctx->sf_mode)                                                         \
504
        gen_op_##name##_64();                                                 \
505
    else                                                                      \
506
        gen_op_##name();                                                      \
507
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
508
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
509
        gen_set_Rc0(ctx);                                                     \
510
}
511

    
512
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
513
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
514
{                                                                             \
515
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
516
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
517
    if (ctx->sf_mode)                                                         \
518
        gen_op_##name##_64();                                                 \
519
    else                                                                      \
520
        gen_op_##name();                                                      \
521
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
522
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
523
        gen_set_Rc0(ctx);                                                     \
524
}
525

    
526
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
527
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
528
{                                                                             \
529
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
530
    if (ctx->sf_mode)                                                         \
531
        gen_op_##name##_64();                                                 \
532
    else                                                                      \
533
        gen_op_##name();                                                      \
534
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
535
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
536
        gen_set_Rc0(ctx);                                                     \
537
}
538
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
539
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
540
{                                                                             \
541
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
542
    if (ctx->sf_mode)                                                         \
543
        gen_op_##name##_64();                                                 \
544
    else                                                                      \
545
        gen_op_##name();                                                      \
546
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
547
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
548
        gen_set_Rc0(ctx);                                                     \
549
}
550

    
551
/* Two operands arithmetic functions */
552
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
553
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
554
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
555

    
556
/* Two operands arithmetic functions with no overflow allowed */
557
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
558
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
559

    
560
/* One operand arithmetic functions */
561
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
562
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
563
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
564
#else
565
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
566
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
567
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
568
#endif
569

    
570
/* add    add.    addo    addo.    */
571
static inline void gen_op_addo (void)
572
{
573
    gen_op_move_T2_T0();
574
    gen_op_add();
575
    gen_op_check_addo();
576
}
577
#if defined(TARGET_PPC64)
578
#define gen_op_add_64 gen_op_add
579
static inline void gen_op_addo_64 (void)
580
{
581
    gen_op_move_T2_T0();
582
    gen_op_add();
583
    gen_op_check_addo_64();
584
}
585
#endif
586
GEN_INT_ARITH2_64 (add,    0x1F, 0x0A, 0x08, PPC_INTEGER);
587
/* addc   addc.   addco   addco.   */
588
static inline void gen_op_addc (void)
589
{
590
    gen_op_move_T2_T0();
591
    gen_op_add();
592
    gen_op_check_addc();
593
}
594
static inline void gen_op_addco (void)
595
{
596
    gen_op_move_T2_T0();
597
    gen_op_add();
598
    gen_op_check_addc();
599
    gen_op_check_addo();
600
}
601
#if defined(TARGET_PPC64)
602
static inline void gen_op_addc_64 (void)
603
{
604
    gen_op_move_T2_T0();
605
    gen_op_add();
606
    gen_op_check_addc_64();
607
}
608
static inline void gen_op_addco_64 (void)
609
{
610
    gen_op_move_T2_T0();
611
    gen_op_add();
612
    gen_op_check_addc_64();
613
    gen_op_check_addo_64();
614
}
615
#endif
616
GEN_INT_ARITH2_64 (addc,   0x1F, 0x0A, 0x00, PPC_INTEGER);
617
/* adde   adde.   addeo   addeo.   */
618
static inline void gen_op_addeo (void)
619
{
620
    gen_op_move_T2_T0();
621
    gen_op_adde();
622
    gen_op_check_addo();
623
}
624
#if defined(TARGET_PPC64)
625
static inline void gen_op_addeo_64 (void)
626
{
627
    gen_op_move_T2_T0();
628
    gen_op_adde_64();
629
    gen_op_check_addo_64();
630
}
631
#endif
632
GEN_INT_ARITH2_64 (adde,   0x1F, 0x0A, 0x04, PPC_INTEGER);
633
/* addme  addme.  addmeo  addmeo.  */
634
static inline void gen_op_addme (void)
635
{
636
    gen_op_move_T1_T0();
637
    gen_op_add_me();
638
}
639
#if defined(TARGET_PPC64)
640
static inline void gen_op_addme_64 (void)
641
{
642
    gen_op_move_T1_T0();
643
    gen_op_add_me_64();
644
}
645
#endif
646
GEN_INT_ARITH1_64 (addme,  0x1F, 0x0A, 0x07, PPC_INTEGER);
647
/* addze  addze.  addzeo  addzeo.  */
648
static inline void gen_op_addze (void)
649
{
650
    gen_op_move_T2_T0();
651
    gen_op_add_ze();
652
    gen_op_check_addc();
653
}
654
static inline void gen_op_addzeo (void)
655
{
656
    gen_op_move_T2_T0();
657
    gen_op_add_ze();
658
    gen_op_check_addc();
659
    gen_op_check_addo();
660
}
661
#if defined(TARGET_PPC64)
662
static inline void gen_op_addze_64 (void)
663
{
664
    gen_op_move_T2_T0();
665
    gen_op_add_ze();
666
    gen_op_check_addc_64();
667
}
668
static inline void gen_op_addzeo_64 (void)
669
{
670
    gen_op_move_T2_T0();
671
    gen_op_add_ze();
672
    gen_op_check_addc_64();
673
    gen_op_check_addo_64();
674
}
675
#endif
676
GEN_INT_ARITH1_64 (addze,  0x1F, 0x0A, 0x06, PPC_INTEGER);
677
/* divw   divw.   divwo   divwo.   */
678
GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F, PPC_INTEGER);
679
/* divwu  divwu.  divwuo  divwuo.  */
680
GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E, PPC_INTEGER);
681
/* mulhw  mulhw.                   */
682
GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02, PPC_INTEGER);
683
/* mulhwu mulhwu.                  */
684
GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);
685
/* mullw  mullw.  mullwo  mullwo.  */
686
GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07, PPC_INTEGER);
687
/* neg    neg.    nego    nego.    */
688
GEN_INT_ARITH1_64 (neg,    0x1F, 0x08, 0x03, PPC_INTEGER);
689
/* subf   subf.   subfo   subfo.   */
690
static inline void gen_op_subfo (void)
691
{
692
    gen_op_move_T2_T0();
693
    gen_op_subf();
694
    gen_op_check_subfo();
695
}
696
#if defined(TARGET_PPC64)
697
#define gen_op_subf_64 gen_op_subf
698
static inline void gen_op_subfo_64 (void)
699
{
700
    gen_op_move_T2_T0();
701
    gen_op_subf();
702
    gen_op_check_subfo_64();
703
}
704
#endif
705
GEN_INT_ARITH2_64 (subf,   0x1F, 0x08, 0x01, PPC_INTEGER);
706
/* subfc  subfc.  subfco  subfco.  */
707
static inline void gen_op_subfc (void)
708
{
709
    gen_op_subf();
710
    gen_op_check_subfc();
711
}
712
static inline void gen_op_subfco (void)
713
{
714
    gen_op_move_T2_T0();
715
    gen_op_subf();
716
    gen_op_check_subfc();
717
    gen_op_check_subfo();
718
}
719
#if defined(TARGET_PPC64)
720
static inline void gen_op_subfc_64 (void)
721
{
722
    gen_op_subf();
723
    gen_op_check_subfc_64();
724
}
725
static inline void gen_op_subfco_64 (void)
726
{
727
    gen_op_move_T2_T0();
728
    gen_op_subf();
729
    gen_op_check_subfc_64();
730
    gen_op_check_subfo_64();
731
}
732
#endif
733
GEN_INT_ARITH2_64 (subfc,  0x1F, 0x08, 0x00, PPC_INTEGER);
734
/* subfe  subfe.  subfeo  subfeo.  */
735
static inline void gen_op_subfeo (void)
736
{
737
    gen_op_move_T2_T0();
738
    gen_op_subfe();
739
    gen_op_check_subfo();
740
}
741
#if defined(TARGET_PPC64)
742
#define gen_op_subfe_64 gen_op_subfe
743
static inline void gen_op_subfeo_64 (void)
744
{
745
    gen_op_move_T2_T0();
746
    gen_op_subfe_64();
747
    gen_op_check_subfo_64();
748
}
749
#endif
750
GEN_INT_ARITH2_64 (subfe,  0x1F, 0x08, 0x04, PPC_INTEGER);
751
/* subfme subfme. subfmeo subfmeo. */
752
GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);
753
/* subfze subfze. subfzeo subfzeo. */
754
GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);
755
/* addi */
756
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
757
{
758
    target_long simm = SIMM(ctx->opcode);
759

    
760
    if (rA(ctx->opcode) == 0) {
761
        /* li case */
762
        gen_set_T0(simm);
763
    } else {
764
        gen_op_load_gpr_T0(rA(ctx->opcode));
765
        if (likely(simm != 0))
766
            gen_op_addi(simm);
767
    }
768
    gen_op_store_T0_gpr(rD(ctx->opcode));
769
}
770
/* addic */
771
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
772
{
773
    target_long simm = SIMM(ctx->opcode);
774

    
775
    gen_op_load_gpr_T0(rA(ctx->opcode));
776
    if (likely(simm != 0)) {
777
        gen_op_move_T2_T0();
778
        gen_op_addi(simm);
779
#if defined(TARGET_PPC64)
780
        if (ctx->sf_mode)
781
            gen_op_check_addc_64();
782
        else
783
#endif
784
            gen_op_check_addc();
785
    } else {
786
        gen_op_clear_xer_ca();
787
    }
788
    gen_op_store_T0_gpr(rD(ctx->opcode));
789
}
790
/* addic. */
791
GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
792
{
793
    target_long simm = SIMM(ctx->opcode);
794

    
795
    gen_op_load_gpr_T0(rA(ctx->opcode));
796
    if (likely(simm != 0)) {
797
        gen_op_move_T2_T0();
798
        gen_op_addi(simm);
799
#if defined(TARGET_PPC64)
800
        if (ctx->sf_mode)
801
            gen_op_check_addc_64();
802
        else
803
#endif
804
            gen_op_check_addc();
805
    } else {
806
        gen_op_clear_xer_ca();
807
    }
808
    gen_op_store_T0_gpr(rD(ctx->opcode));
809
    gen_set_Rc0(ctx);
810
}
811
/* addis */
812
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
813
{
814
    target_long simm = SIMM(ctx->opcode);
815

    
816
    if (rA(ctx->opcode) == 0) {
817
        /* lis case */
818
        gen_set_T0(simm << 16);
819
    } else {
820
        gen_op_load_gpr_T0(rA(ctx->opcode));
821
        if (likely(simm != 0))
822
            gen_op_addi(simm << 16);
823
    }
824
    gen_op_store_T0_gpr(rD(ctx->opcode));
825
}
826
/* mulli */
827
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
828
{
829
    gen_op_load_gpr_T0(rA(ctx->opcode));
830
    gen_op_mulli(SIMM(ctx->opcode));
831
    gen_op_store_T0_gpr(rD(ctx->opcode));
832
}
833
/* subfic */
834
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
835
{
836
    gen_op_load_gpr_T0(rA(ctx->opcode));
837
#if defined(TARGET_PPC64)
838
    if (ctx->sf_mode)
839
        gen_op_subfic_64(SIMM(ctx->opcode));
840
    else
841
#endif
842
        gen_op_subfic(SIMM(ctx->opcode));
843
    gen_op_store_T0_gpr(rD(ctx->opcode));
844
}
845

    
846
#if defined(TARGET_PPC64)
847
/* mulhd  mulhd.                   */
848
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_INTEGER);
849
/* mulhdu mulhdu.                  */
850
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_INTEGER);
851
/* mulld  mulld.  mulldo  mulldo.  */
852
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_INTEGER);
853
/* divd   divd.   divdo   divdo.   */
854
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_INTEGER);
855
/* divdu  divdu.  divduo  divduo.  */
856
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_INTEGER);
857
#endif
858

    
859
/***                           Integer comparison                          ***/
860
#if defined(TARGET_PPC64)
861
#define GEN_CMP(name, opc, type)                                              \
862
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
863
{                                                                             \
864
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
865
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
866
    if (ctx->sf_mode)                                                         \
867
        gen_op_##name##_64();                                                 \
868
    else                                                                      \
869
        gen_op_##name();                                                      \
870
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
871
}
872
#else
873
#define GEN_CMP(name, opc, type)                                              \
874
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
875
{                                                                             \
876
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
877
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
878
    gen_op_##name();                                                          \
879
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
880
}
881
#endif
882

    
883
/* cmp */
884
GEN_CMP(cmp, 0x00, PPC_INTEGER);
885
/* cmpi */
886
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
887
{
888
    gen_op_load_gpr_T0(rA(ctx->opcode));
889
#if defined(TARGET_PPC64)
890
    if (ctx->sf_mode)
891
        gen_op_cmpi_64(SIMM(ctx->opcode));
892
    else
893
#endif
894
        gen_op_cmpi(SIMM(ctx->opcode));
895
    gen_op_store_T0_crf(crfD(ctx->opcode));
896
}
897
/* cmpl */
898
GEN_CMP(cmpl, 0x01, PPC_INTEGER);
899
/* cmpli */
900
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
901
{
902
    gen_op_load_gpr_T0(rA(ctx->opcode));
903
#if defined(TARGET_PPC64)
904
    if (ctx->sf_mode)
905
        gen_op_cmpli_64(UIMM(ctx->opcode));
906
    else
907
#endif
908
        gen_op_cmpli(UIMM(ctx->opcode));
909
    gen_op_store_T0_crf(crfD(ctx->opcode));
910
}
911

    
912
/* isel (PowerPC 2.03 specification) */
913
GEN_HANDLER(isel, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203)
914
{
915
    uint32_t bi = rC(ctx->opcode);
916
    uint32_t mask;
917

    
918
    if (rA(ctx->opcode) == 0) {
919
        gen_set_T0(0);
920
    } else {
921
        gen_op_load_gpr_T1(rA(ctx->opcode));
922
    }
923
    gen_op_load_gpr_T2(rB(ctx->opcode));
924
    mask = 1 << (3 - (bi & 0x03));
925
    gen_op_load_crf_T0(bi >> 2);
926
    gen_op_test_true(mask);
927
    gen_op_isel();
928
    gen_op_store_T0_gpr(rD(ctx->opcode));
929
}
930

    
931
/***                            Integer logical                            ***/
932
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
933
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
934
{                                                                             \
935
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
936
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
937
    gen_op_##name();                                                          \
938
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
939
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
940
        gen_set_Rc0(ctx);                                                     \
941
}
942
#define GEN_LOGICAL2(name, opc, type)                                         \
943
__GEN_LOGICAL2(name, 0x1C, opc, type)
944

    
945
#define GEN_LOGICAL1(name, opc, type)                                         \
946
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
947
{                                                                             \
948
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
949
    gen_op_##name();                                                          \
950
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
951
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
952
        gen_set_Rc0(ctx);                                                     \
953
}
954

    
955
/* and & and. */
956
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
957
/* andc & andc. */
958
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
959
/* andi. */
960
GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
961
{
962
    gen_op_load_gpr_T0(rS(ctx->opcode));
963
    gen_op_andi_T0(UIMM(ctx->opcode));
964
    gen_op_store_T0_gpr(rA(ctx->opcode));
965
    gen_set_Rc0(ctx);
966
}
967
/* andis. */
968
GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
969
{
970
    gen_op_load_gpr_T0(rS(ctx->opcode));
971
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
972
    gen_op_store_T0_gpr(rA(ctx->opcode));
973
    gen_set_Rc0(ctx);
974
}
975

    
976
/* cntlzw */
977
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
978
/* eqv & eqv. */
979
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
980
/* extsb & extsb. */
981
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
982
/* extsh & extsh. */
983
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
984
/* nand & nand. */
985
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
986
/* nor & nor. */
987
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
988

    
989
/* or & or. */
990
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
991
{
992
    int rs, ra, rb;
993

    
994
    rs = rS(ctx->opcode);
995
    ra = rA(ctx->opcode);
996
    rb = rB(ctx->opcode);
997
    /* Optimisation for mr. ri case */
998
    if (rs != ra || rs != rb) {
999
        gen_op_load_gpr_T0(rs);
1000
        if (rs != rb) {
1001
            gen_op_load_gpr_T1(rb);
1002
            gen_op_or();
1003
        }
1004
        gen_op_store_T0_gpr(ra);
1005
        if (unlikely(Rc(ctx->opcode) != 0))
1006
            gen_set_Rc0(ctx);
1007
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1008
        gen_op_load_gpr_T0(rs);
1009
        gen_set_Rc0(ctx);
1010
    }
1011
}
1012

    
1013
/* orc & orc. */
1014
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1015
/* xor & xor. */
1016
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1017
{
1018
    gen_op_load_gpr_T0(rS(ctx->opcode));
1019
    /* Optimisation for "set to zero" case */
1020
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1021
        gen_op_load_gpr_T1(rB(ctx->opcode));
1022
        gen_op_xor();
1023
    } else {
1024
        gen_op_reset_T0();
1025
    }
1026
    gen_op_store_T0_gpr(rA(ctx->opcode));
1027
    if (unlikely(Rc(ctx->opcode) != 0))
1028
        gen_set_Rc0(ctx);
1029
}
1030
/* ori */
1031
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1032
{
1033
    target_ulong uimm = UIMM(ctx->opcode);
1034

    
1035
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1036
        /* NOP */
1037
        /* XXX: should handle special NOPs for POWER series */
1038
        return;
1039
    }
1040
    gen_op_load_gpr_T0(rS(ctx->opcode));
1041
    if (likely(uimm != 0))
1042
        gen_op_ori(uimm);
1043
    gen_op_store_T0_gpr(rA(ctx->opcode));
1044
}
1045
/* oris */
1046
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1047
{
1048
    target_ulong uimm = UIMM(ctx->opcode);
1049

    
1050
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1051
        /* NOP */
1052
        return;
1053
    }
1054
    gen_op_load_gpr_T0(rS(ctx->opcode));
1055
    if (likely(uimm != 0))
1056
        gen_op_ori(uimm << 16);
1057
    gen_op_store_T0_gpr(rA(ctx->opcode));
1058
}
1059
/* xori */
1060
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1061
{
1062
    target_ulong uimm = UIMM(ctx->opcode);
1063

    
1064
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1065
        /* NOP */
1066
        return;
1067
    }
1068
    gen_op_load_gpr_T0(rS(ctx->opcode));
1069
    if (likely(uimm != 0))
1070
        gen_op_xori(uimm);
1071
    gen_op_store_T0_gpr(rA(ctx->opcode));
1072
}
1073

    
1074
/* xoris */
1075
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1076
{
1077
    target_ulong uimm = UIMM(ctx->opcode);
1078

    
1079
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1080
        /* NOP */
1081
        return;
1082
    }
1083
    gen_op_load_gpr_T0(rS(ctx->opcode));
1084
    if (likely(uimm != 0))
1085
        gen_op_xori(uimm << 16);
1086
    gen_op_store_T0_gpr(rA(ctx->opcode));
1087
}
1088

    
1089
/* popcntb : PowerPC 2.03 specification */
1090
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_203)
1091
{
1092
    gen_op_load_gpr_T0(rS(ctx->opcode));
1093
#if defined(TARGET_PPC64)
1094
    if (ctx->sf_mode)
1095
        gen_op_popcntb_64();
1096
    else
1097
#endif
1098
        gen_op_popcntb();
1099
    gen_op_store_T0_gpr(rA(ctx->opcode));
1100
}
1101

    
1102
#if defined(TARGET_PPC64)
1103
/* extsw & extsw. */
1104
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1105
/* cntlzd */
1106
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1107
#endif
1108

    
1109
/***                             Integer rotate                            ***/
1110
/* rlwimi & rlwimi. */
1111
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1112
{
1113
    target_ulong mask;
1114
    uint32_t mb, me, sh;
1115

    
1116
    mb = MB(ctx->opcode);
1117
    me = ME(ctx->opcode);
1118
    sh = SH(ctx->opcode);
1119
    if (likely(sh == 0)) {
1120
        if (likely(mb == 0 && me == 31)) {
1121
            gen_op_load_gpr_T0(rS(ctx->opcode));
1122
            goto do_store;
1123
        } else if (likely(mb == 31 && me == 0)) {
1124
            gen_op_load_gpr_T0(rA(ctx->opcode));
1125
            goto do_store;
1126
        }
1127
        gen_op_load_gpr_T0(rS(ctx->opcode));
1128
        gen_op_load_gpr_T1(rA(ctx->opcode));
1129
        goto do_mask;
1130
    }
1131
    gen_op_load_gpr_T0(rS(ctx->opcode));
1132
    gen_op_load_gpr_T1(rA(ctx->opcode));
1133
    gen_op_rotli32_T0(SH(ctx->opcode));
1134
 do_mask:
1135
#if defined(TARGET_PPC64)
1136
    mb += 32;
1137
    me += 32;
1138
#endif
1139
    mask = MASK(mb, me);
1140
    gen_op_andi_T0(mask);
1141
    gen_op_andi_T1(~mask);
1142
    gen_op_or();
1143
 do_store:
1144
    gen_op_store_T0_gpr(rA(ctx->opcode));
1145
    if (unlikely(Rc(ctx->opcode) != 0))
1146
        gen_set_Rc0(ctx);
1147
}
1148
/* rlwinm & rlwinm. */
1149
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1150
{
1151
    uint32_t mb, me, sh;
1152

    
1153
    sh = SH(ctx->opcode);
1154
    mb = MB(ctx->opcode);
1155
    me = ME(ctx->opcode);
1156
    gen_op_load_gpr_T0(rS(ctx->opcode));
1157
    if (likely(sh == 0)) {
1158
        goto do_mask;
1159
    }
1160
    if (likely(mb == 0)) {
1161
        if (likely(me == 31)) {
1162
            gen_op_rotli32_T0(sh);
1163
            goto do_store;
1164
        } else if (likely(me == (31 - sh))) {
1165
            gen_op_sli_T0(sh);
1166
            goto do_store;
1167
        }
1168
    } else if (likely(me == 31)) {
1169
        if (likely(sh == (32 - mb))) {
1170
            gen_op_srli_T0(mb);
1171
            goto do_store;
1172
        }
1173
    }
1174
    gen_op_rotli32_T0(sh);
1175
 do_mask:
1176
#if defined(TARGET_PPC64)
1177
    mb += 32;
1178
    me += 32;
1179
#endif
1180
    gen_op_andi_T0(MASK(mb, me));
1181
 do_store:
1182
    gen_op_store_T0_gpr(rA(ctx->opcode));
1183
    if (unlikely(Rc(ctx->opcode) != 0))
1184
        gen_set_Rc0(ctx);
1185
}
1186
/* rlwnm & rlwnm. */
1187
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1188
{
1189
    uint32_t mb, me;
1190

    
1191
    mb = MB(ctx->opcode);
1192
    me = ME(ctx->opcode);
1193
    gen_op_load_gpr_T0(rS(ctx->opcode));
1194
    gen_op_load_gpr_T1(rB(ctx->opcode));
1195
    gen_op_rotl32_T0_T1();
1196
    if (unlikely(mb != 0 || me != 31)) {
1197
#if defined(TARGET_PPC64)
1198
        mb += 32;
1199
        me += 32;
1200
#endif
1201
        gen_op_andi_T0(MASK(mb, me));
1202
    }
1203
    gen_op_store_T0_gpr(rA(ctx->opcode));
1204
    if (unlikely(Rc(ctx->opcode) != 0))
1205
        gen_set_Rc0(ctx);
1206
}
1207

    
1208
#if defined(TARGET_PPC64)
1209
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1210
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1211
{                                                                             \
1212
    gen_##name(ctx, 0);                                                       \
1213
}                                                                             \
1214
GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1215
{                                                                             \
1216
    gen_##name(ctx, 1);                                                       \
1217
}
1218
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1219
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1220
{                                                                             \
1221
    gen_##name(ctx, 0, 0);                                                    \
1222
}                                                                             \
1223
GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B)            \
1224
{                                                                             \
1225
    gen_##name(ctx, 0, 1);                                                    \
1226
}                                                                             \
1227
GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1228
{                                                                             \
1229
    gen_##name(ctx, 1, 0);                                                    \
1230
}                                                                             \
1231
GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B)            \
1232
{                                                                             \
1233
    gen_##name(ctx, 1, 1);                                                    \
1234
}
1235

    
1236
static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me,
1237
                               uint32_t sh)
1238
{
1239
    gen_op_load_gpr_T0(rS(ctx->opcode));
1240
    if (likely(sh == 0)) {
1241
        goto do_mask;
1242
    }
1243
    if (likely(mb == 0)) {
1244
        if (likely(me == 63)) {
1245
            gen_op_rotli32_T0(sh);
1246
            goto do_store;
1247
        } else if (likely(me == (63 - sh))) {
1248
            gen_op_sli_T0(sh);
1249
            goto do_store;
1250
        }
1251
    } else if (likely(me == 63)) {
1252
        if (likely(sh == (64 - mb))) {
1253
            gen_op_srli_T0(mb);
1254
            goto do_store;
1255
        }
1256
    }
1257
    gen_op_rotli64_T0(sh);
1258
 do_mask:
1259
    gen_op_andi_T0(MASK(mb, me));
1260
 do_store:
1261
    gen_op_store_T0_gpr(rA(ctx->opcode));
1262
    if (unlikely(Rc(ctx->opcode) != 0))
1263
        gen_set_Rc0(ctx);
1264
}
1265
/* rldicl - rldicl. */
1266
static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1267
{
1268
    uint32_t sh, mb;
1269

    
1270
    sh = SH(ctx->opcode) | (shn << 5);
1271
    mb = MB(ctx->opcode) | (mbn << 5);
1272
    gen_rldinm(ctx, mb, 63, sh);
1273
}
1274
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1275
/* rldicr - rldicr. */
1276
static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1277
{
1278
    uint32_t sh, me;
1279

    
1280
    sh = SH(ctx->opcode) | (shn << 5);
1281
    me = MB(ctx->opcode) | (men << 5);
1282
    gen_rldinm(ctx, 0, me, sh);
1283
}
1284
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1285
/* rldic - rldic. */
1286
static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1287
{
1288
    uint32_t sh, mb;
1289

    
1290
    sh = SH(ctx->opcode) | (shn << 5);
1291
    mb = MB(ctx->opcode) | (mbn << 5);
1292
    gen_rldinm(ctx, mb, 63 - sh, sh);
1293
}
1294
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1295

    
1296
static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me)
1297
{
1298
    gen_op_load_gpr_T0(rS(ctx->opcode));
1299
    gen_op_load_gpr_T1(rB(ctx->opcode));
1300
    gen_op_rotl64_T0_T1();
1301
    if (unlikely(mb != 0 || me != 63)) {
1302
        gen_op_andi_T0(MASK(mb, me));
1303
    }
1304
    gen_op_store_T0_gpr(rA(ctx->opcode));
1305
    if (unlikely(Rc(ctx->opcode) != 0))
1306
        gen_set_Rc0(ctx);
1307
}
1308

    
1309
/* rldcl - rldcl. */
1310
static inline void gen_rldcl (DisasContext *ctx, int mbn)
1311
{
1312
    uint32_t mb;
1313

    
1314
    mb = MB(ctx->opcode) | (mbn << 5);
1315
    gen_rldnm(ctx, mb, 63);
1316
}
1317
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1318
/* rldcr - rldcr. */
1319
static inline void gen_rldcr (DisasContext *ctx, int men)
1320
{
1321
    uint32_t me;
1322

    
1323
    me = MB(ctx->opcode) | (men << 5);
1324
    gen_rldnm(ctx, 0, me);
1325
}
1326
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1327
/* rldimi - rldimi. */
1328
static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1329
{
1330
    uint64_t mask;
1331
    uint32_t sh, mb;
1332

    
1333
    sh = SH(ctx->opcode) | (shn << 5);
1334
    mb = MB(ctx->opcode) | (mbn << 5);
1335
    if (likely(sh == 0)) {
1336
        if (likely(mb == 0)) {
1337
            gen_op_load_gpr_T0(rS(ctx->opcode));
1338
            goto do_store;
1339
        } else if (likely(mb == 63)) {
1340
            gen_op_load_gpr_T0(rA(ctx->opcode));
1341
            goto do_store;
1342
        }
1343
        gen_op_load_gpr_T0(rS(ctx->opcode));
1344
        gen_op_load_gpr_T1(rA(ctx->opcode));
1345
        goto do_mask;
1346
    }
1347
    gen_op_load_gpr_T0(rS(ctx->opcode));
1348
    gen_op_load_gpr_T1(rA(ctx->opcode));
1349
    gen_op_rotli64_T0(SH(ctx->opcode));
1350
 do_mask:
1351
    mask = MASK(mb, 63 - sh);
1352
    gen_op_andi_T0(mask);
1353
    gen_op_andi_T1(~mask);
1354
    gen_op_or();
1355
 do_store:
1356
    gen_op_store_T0_gpr(rA(ctx->opcode));
1357
    if (unlikely(Rc(ctx->opcode) != 0))
1358
        gen_set_Rc0(ctx);
1359
}
1360
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1361
#endif
1362

    
1363
/***                             Integer shift                             ***/
1364
/* slw & slw. */
1365
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1366
/* sraw & sraw. */
1367
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1368
/* srawi & srawi. */
1369
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1370
{
1371
    int mb, me;
1372
    gen_op_load_gpr_T0(rS(ctx->opcode));
1373
    if (SH(ctx->opcode) != 0) {
1374
        gen_op_move_T1_T0();
1375
        mb = 32 - SH(ctx->opcode);
1376
        me = 31;
1377
#if defined(TARGET_PPC64)
1378
        mb += 32;
1379
        me += 32;
1380
#endif
1381
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1382
    }
1383
    gen_op_store_T0_gpr(rA(ctx->opcode));
1384
    if (unlikely(Rc(ctx->opcode) != 0))
1385
        gen_set_Rc0(ctx);
1386
}
1387
/* srw & srw. */
1388
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1389

    
1390
#if defined(TARGET_PPC64)
1391
/* sld & sld. */
1392
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1393
/* srad & srad. */
1394
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1395
/* sradi & sradi. */
1396
static inline void gen_sradi (DisasContext *ctx, int n)
1397
{
1398
    uint64_t mask;
1399
    int sh, mb, me;
1400

    
1401
    gen_op_load_gpr_T0(rS(ctx->opcode));
1402
    sh = SH(ctx->opcode) + (n << 5);
1403
    if (sh != 0) {
1404
        gen_op_move_T1_T0();
1405
        mb = 64 - SH(ctx->opcode);
1406
        me = 63;
1407
        mask = MASK(mb, me);
1408
        gen_op_sradi(sh, mask >> 32, mask);
1409
    }
1410
    gen_op_store_T0_gpr(rA(ctx->opcode));
1411
    if (unlikely(Rc(ctx->opcode) != 0))
1412
        gen_set_Rc0(ctx);
1413
}
1414
GEN_HANDLER(sradi0, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1415
{
1416
    gen_sradi(ctx, 0);
1417
}
1418
GEN_HANDLER(sradi1, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1419
{
1420
    gen_sradi(ctx, 1);
1421
}
1422
/* srd & srd. */
1423
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1424
#endif
1425

    
1426
/***                       Floating-Point arithmetic                       ***/
1427
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat)                           \
1428
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT)                   \
1429
{                                                                             \
1430
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1431
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1432
        return;                                                               \
1433
    }                                                                         \
1434
    gen_op_reset_scrfx();                                                     \
1435
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1436
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1437
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1438
    gen_op_f##op();                                                           \
1439
    if (isfloat) {                                                            \
1440
        gen_op_frsp();                                                        \
1441
    }                                                                         \
1442
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1443
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1444
        gen_op_set_Rc1();                                                     \
1445
}
1446

    
1447
#define GEN_FLOAT_ACB(name, op2)                                              \
1448
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0);                                     \
1449
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
1450

    
1451
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
1452
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1453
{                                                                             \
1454
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1455
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1456
        return;                                                               \
1457
    }                                                                         \
1458
    gen_op_reset_scrfx();                                                     \
1459
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1460
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1461
    gen_op_f##op();                                                           \
1462
    if (isfloat) {                                                            \
1463
        gen_op_frsp();                                                        \
1464
    }                                                                         \
1465
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1466
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1467
        gen_op_set_Rc1();                                                     \
1468
}
1469
#define GEN_FLOAT_AB(name, op2, inval)                                        \
1470
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
1471
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1472

    
1473
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
1474
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1475
{                                                                             \
1476
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1477
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1478
        return;                                                               \
1479
    }                                                                         \
1480
    gen_op_reset_scrfx();                                                     \
1481
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1482
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1483
    gen_op_f##op();                                                           \
1484
    if (isfloat) {                                                            \
1485
        gen_op_frsp();                                                        \
1486
    }                                                                         \
1487
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1488
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1489
        gen_op_set_Rc1();                                                     \
1490
}
1491
#define GEN_FLOAT_AC(name, op2, inval)                                        \
1492
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
1493
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1494

    
1495
#define GEN_FLOAT_B(name, op2, op3)                                           \
1496
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT)                   \
1497
{                                                                             \
1498
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1499
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1500
        return;                                                               \
1501
    }                                                                         \
1502
    gen_op_reset_scrfx();                                                     \
1503
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1504
    gen_op_f##name();                                                         \
1505
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1506
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1507
        gen_op_set_Rc1();                                                     \
1508
}
1509

    
1510
#define GEN_FLOAT_BS(name, op1, op2)                                          \
1511
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT)                   \
1512
{                                                                             \
1513
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1514
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1515
        return;                                                               \
1516
    }                                                                         \
1517
    gen_op_reset_scrfx();                                                     \
1518
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1519
    gen_op_f##name();                                                         \
1520
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1521
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1522
        gen_op_set_Rc1();                                                     \
1523
}
1524

    
1525
/* fadd - fadds */
1526
GEN_FLOAT_AB(add, 0x15, 0x000007C0);
1527
/* fdiv - fdivs */
1528
GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1529
/* fmul - fmuls */
1530
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1531

    
1532
/* fres */ /* XXX: not in 601 */
1533
GEN_FLOAT_BS(res, 0x3B, 0x18);
1534

    
1535
/* frsqrte */ /* XXX: not in 601 */
1536
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
1537

    
1538
/* fsel */ /* XXX: not in 601 */
1539
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0);
1540
/* fsub - fsubs */
1541
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1542
/* Optional: */
1543
/* fsqrt */
1544
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
1545
{
1546
    if (unlikely(!ctx->fpu_enabled)) {
1547
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1548
        return;
1549
    }
1550
    gen_op_reset_scrfx();
1551
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1552
    gen_op_fsqrt();
1553
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1554
    if (unlikely(Rc(ctx->opcode) != 0))
1555
        gen_op_set_Rc1();
1556
}
1557

    
1558
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
1559
{
1560
    if (unlikely(!ctx->fpu_enabled)) {
1561
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1562
        return;
1563
    }
1564
    gen_op_reset_scrfx();
1565
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1566
    gen_op_fsqrt();
1567
    gen_op_frsp();
1568
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1569
    if (unlikely(Rc(ctx->opcode) != 0))
1570
        gen_op_set_Rc1();
1571
}
1572

    
1573
/***                     Floating-Point multiply-and-add                   ***/
1574
/* fmadd - fmadds */
1575
GEN_FLOAT_ACB(madd, 0x1D);
1576
/* fmsub - fmsubs */
1577
GEN_FLOAT_ACB(msub, 0x1C);
1578
/* fnmadd - fnmadds */
1579
GEN_FLOAT_ACB(nmadd, 0x1F);
1580
/* fnmsub - fnmsubs */
1581
GEN_FLOAT_ACB(nmsub, 0x1E);
1582

    
1583
/***                     Floating-Point round & convert                    ***/
1584
/* fctiw */
1585
GEN_FLOAT_B(ctiw, 0x0E, 0x00);
1586
/* fctiwz */
1587
GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
1588
/* frsp */
1589
GEN_FLOAT_B(rsp, 0x0C, 0x00);
1590
#if defined(TARGET_PPC64)
1591
/* fcfid */
1592
GEN_FLOAT_B(cfid, 0x0E, 0x1A);
1593
/* fctid */
1594
GEN_FLOAT_B(ctid, 0x0E, 0x19);
1595
/* fctidz */
1596
GEN_FLOAT_B(ctidz, 0x0F, 0x19);
1597
#endif
1598

    
1599
/***                         Floating-Point compare                        ***/
1600
/* fcmpo */
1601
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1602
{
1603
    if (unlikely(!ctx->fpu_enabled)) {
1604
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1605
        return;
1606
    }
1607
    gen_op_reset_scrfx();
1608
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1609
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1610
    gen_op_fcmpo();
1611
    gen_op_store_T0_crf(crfD(ctx->opcode));
1612
}
1613

    
1614
/* fcmpu */
1615
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1616
{
1617
    if (unlikely(!ctx->fpu_enabled)) {
1618
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1619
        return;
1620
    }
1621
    gen_op_reset_scrfx();
1622
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1623
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1624
    gen_op_fcmpu();
1625
    gen_op_store_T0_crf(crfD(ctx->opcode));
1626
}
1627

    
1628
/***                         Floating-point move                           ***/
1629
/* fabs */
1630
GEN_FLOAT_B(abs, 0x08, 0x08);
1631

    
1632
/* fmr  - fmr. */
1633
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1634
{
1635
    if (unlikely(!ctx->fpu_enabled)) {
1636
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1637
        return;
1638
    }
1639
    gen_op_reset_scrfx();
1640
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1641
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1642
    if (unlikely(Rc(ctx->opcode) != 0))
1643
        gen_op_set_Rc1();
1644
}
1645

    
1646
/* fnabs */
1647
GEN_FLOAT_B(nabs, 0x08, 0x04);
1648
/* fneg */
1649
GEN_FLOAT_B(neg, 0x08, 0x01);
1650

    
1651
/***                  Floating-Point status & ctrl register                ***/
1652
/* mcrfs */
1653
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1654
{
1655
    if (unlikely(!ctx->fpu_enabled)) {
1656
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1657
        return;
1658
    }
1659
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
1660
    gen_op_store_T0_crf(crfD(ctx->opcode));
1661
    gen_op_clear_fpscr(crfS(ctx->opcode));
1662
}
1663

    
1664
/* mffs */
1665
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1666
{
1667
    if (unlikely(!ctx->fpu_enabled)) {
1668
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1669
        return;
1670
    }
1671
    gen_op_load_fpscr();
1672
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1673
    if (unlikely(Rc(ctx->opcode) != 0))
1674
        gen_op_set_Rc1();
1675
}
1676

    
1677
/* mtfsb0 */
1678
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1679
{
1680
    uint8_t crb;
1681

    
1682
    if (unlikely(!ctx->fpu_enabled)) {
1683
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1684
        return;
1685
    }
1686
    crb = crbD(ctx->opcode) >> 2;
1687
    gen_op_load_fpscr_T0(crb);
1688
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1689
    gen_op_store_T0_fpscr(crb);
1690
    if (unlikely(Rc(ctx->opcode) != 0))
1691
        gen_op_set_Rc1();
1692
}
1693

    
1694
/* mtfsb1 */
1695
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1696
{
1697
    uint8_t crb;
1698

    
1699
    if (unlikely(!ctx->fpu_enabled)) {
1700
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1701
        return;
1702
    }
1703
    crb = crbD(ctx->opcode) >> 2;
1704
    gen_op_load_fpscr_T0(crb);
1705
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1706
    gen_op_store_T0_fpscr(crb);
1707
    if (unlikely(Rc(ctx->opcode) != 0))
1708
        gen_op_set_Rc1();
1709
}
1710

    
1711
/* mtfsf */
1712
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1713
{
1714
    if (unlikely(!ctx->fpu_enabled)) {
1715
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1716
        return;
1717
    }
1718
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1719
    gen_op_store_fpscr(FM(ctx->opcode));
1720
    if (unlikely(Rc(ctx->opcode) != 0))
1721
        gen_op_set_Rc1();
1722
}
1723

    
1724
/* mtfsfi */
1725
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1726
{
1727
    if (unlikely(!ctx->fpu_enabled)) {
1728
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1729
        return;
1730
    }
1731
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1732
    if (unlikely(Rc(ctx->opcode) != 0))
1733
        gen_op_set_Rc1();
1734
}
1735

    
1736
/***                           Addressing modes                            ***/
1737
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1738
static inline void gen_addr_imm_index (DisasContext *ctx, int maskl)
1739
{
1740
    target_long simm = SIMM(ctx->opcode);
1741

    
1742
    if (maskl)
1743
        simm &= ~0x03;
1744
    if (rA(ctx->opcode) == 0) {
1745
        gen_set_T0(simm);
1746
    } else {
1747
        gen_op_load_gpr_T0(rA(ctx->opcode));
1748
        if (likely(simm != 0))
1749
            gen_op_addi(simm);
1750
    }
1751
#ifdef DEBUG_MEMORY_ACCESSES
1752
    gen_op_print_mem_EA();
1753
#endif
1754
}
1755

    
1756
static inline void gen_addr_reg_index (DisasContext *ctx)
1757
{
1758
    if (rA(ctx->opcode) == 0) {
1759
        gen_op_load_gpr_T0(rB(ctx->opcode));
1760
    } else {
1761
        gen_op_load_gpr_T0(rA(ctx->opcode));
1762
        gen_op_load_gpr_T1(rB(ctx->opcode));
1763
        gen_op_add();
1764
    }
1765
#ifdef DEBUG_MEMORY_ACCESSES
1766
    gen_op_print_mem_EA();
1767
#endif
1768
}
1769

    
1770
static inline void gen_addr_register (DisasContext *ctx)
1771
{
1772
    if (rA(ctx->opcode) == 0) {
1773
        gen_op_reset_T0();
1774
    } else {
1775
        gen_op_load_gpr_T0(rA(ctx->opcode));
1776
    }
1777
#ifdef DEBUG_MEMORY_ACCESSES
1778
    gen_op_print_mem_EA();
1779
#endif
1780
}
1781

    
1782
/***                             Integer load                              ***/
1783
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1784
#if defined(CONFIG_USER_ONLY)
1785
#if defined(TARGET_PPC64)
1786
#define OP_LD_TABLE(width)                                                    \
1787
static GenOpFunc *gen_op_l##width[] = {                                       \
1788
    &gen_op_l##width##_raw,                                                   \
1789
    &gen_op_l##width##_le_raw,                                                \
1790
    &gen_op_l##width##_64_raw,                                                \
1791
    &gen_op_l##width##_le_64_raw,                                             \
1792
};
1793
#define OP_ST_TABLE(width)                                                    \
1794
static GenOpFunc *gen_op_st##width[] = {                                      \
1795
    &gen_op_st##width##_raw,                                                  \
1796
    &gen_op_st##width##_le_raw,                                               \
1797
    &gen_op_st##width##_64_raw,                                               \
1798
    &gen_op_st##width##_le_64_raw,                                            \
1799
};
1800
/* Byte access routine are endian safe */
1801
#define gen_op_stb_le_64_raw gen_op_stb_64_raw
1802
#define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1803
#else
1804
#define OP_LD_TABLE(width)                                                    \
1805
static GenOpFunc *gen_op_l##width[] = {                                       \
1806
    &gen_op_l##width##_raw,                                                   \
1807
    &gen_op_l##width##_le_raw,                                                \
1808
};
1809
#define OP_ST_TABLE(width)                                                    \
1810
static GenOpFunc *gen_op_st##width[] = {                                      \
1811
    &gen_op_st##width##_raw,                                                  \
1812
    &gen_op_st##width##_le_raw,                                               \
1813
};
1814
#endif
1815
/* Byte access routine are endian safe */
1816
#define gen_op_stb_le_raw gen_op_stb_raw
1817
#define gen_op_lbz_le_raw gen_op_lbz_raw
1818
#else
1819
#if defined(TARGET_PPC64)
1820
#define OP_LD_TABLE(width)                                                    \
1821
static GenOpFunc *gen_op_l##width[] = {                                       \
1822
    &gen_op_l##width##_user,                                                  \
1823
    &gen_op_l##width##_le_user,                                               \
1824
    &gen_op_l##width##_kernel,                                                \
1825
    &gen_op_l##width##_le_kernel,                                             \
1826
    &gen_op_l##width##_64_user,                                               \
1827
    &gen_op_l##width##_le_64_user,                                            \
1828
    &gen_op_l##width##_64_kernel,                                             \
1829
    &gen_op_l##width##_le_64_kernel,                                          \
1830
};
1831
#define OP_ST_TABLE(width)                                                    \
1832
static GenOpFunc *gen_op_st##width[] = {                                      \
1833
    &gen_op_st##width##_user,                                                 \
1834
    &gen_op_st##width##_le_user,                                              \
1835
    &gen_op_st##width##_kernel,                                               \
1836
    &gen_op_st##width##_le_kernel,                                            \
1837
    &gen_op_st##width##_64_user,                                              \
1838
    &gen_op_st##width##_le_64_user,                                           \
1839
    &gen_op_st##width##_64_kernel,                                            \
1840
    &gen_op_st##width##_le_64_kernel,                                         \
1841
};
1842
/* Byte access routine are endian safe */
1843
#define gen_op_stb_le_64_user gen_op_stb_64_user
1844
#define gen_op_lbz_le_64_user gen_op_lbz_64_user
1845
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
1846
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
1847
#else
1848
#define OP_LD_TABLE(width)                                                    \
1849
static GenOpFunc *gen_op_l##width[] = {                                       \
1850
    &gen_op_l##width##_user,                                                  \
1851
    &gen_op_l##width##_le_user,                                               \
1852
    &gen_op_l##width##_kernel,                                                \
1853
    &gen_op_l##width##_le_kernel,                                             \
1854
};
1855
#define OP_ST_TABLE(width)                                                    \
1856
static GenOpFunc *gen_op_st##width[] = {                                      \
1857
    &gen_op_st##width##_user,                                                 \
1858
    &gen_op_st##width##_le_user,                                              \
1859
    &gen_op_st##width##_kernel,                                               \
1860
    &gen_op_st##width##_le_kernel,                                            \
1861
};
1862
#endif
1863
/* Byte access routine are endian safe */
1864
#define gen_op_stb_le_user gen_op_stb_user
1865
#define gen_op_lbz_le_user gen_op_lbz_user
1866
#define gen_op_stb_le_kernel gen_op_stb_kernel
1867
#define gen_op_lbz_le_kernel gen_op_lbz_kernel
1868
#endif
1869

    
1870
#define GEN_LD(width, opc, type)                                              \
1871
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
1872
{                                                                             \
1873
    gen_addr_imm_index(ctx, 0);                                               \
1874
    op_ldst(l##width);                                                        \
1875
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1876
}
1877

    
1878
#define GEN_LDU(width, opc, type)                                             \
1879
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
1880
{                                                                             \
1881
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1882
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1883
        RET_INVAL(ctx);                                                       \
1884
        return;                                                               \
1885
    }                                                                         \
1886
    if (type == PPC_64B)                                                      \
1887
        gen_addr_imm_index(ctx, 1);                                           \
1888
    else                                                                      \
1889
        gen_addr_imm_index(ctx, 0);                                           \
1890
    op_ldst(l##width);                                                        \
1891
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1892
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1893
}
1894

    
1895
#define GEN_LDUX(width, opc2, opc3, type)                                     \
1896
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
1897
{                                                                             \
1898
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1899
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1900
        RET_INVAL(ctx);                                                       \
1901
        return;                                                               \
1902
    }                                                                         \
1903
    gen_addr_reg_index(ctx);                                                  \
1904
    op_ldst(l##width);                                                        \
1905
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1906
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1907
}
1908

    
1909
#define GEN_LDX(width, opc2, opc3, type)                                      \
1910
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
1911
{                                                                             \
1912
    gen_addr_reg_index(ctx);                                                  \
1913
    op_ldst(l##width);                                                        \
1914
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1915
}
1916

    
1917
#define GEN_LDS(width, op, type)                                              \
1918
OP_LD_TABLE(width);                                                           \
1919
GEN_LD(width, op | 0x20, type);                                               \
1920
GEN_LDU(width, op | 0x21, type);                                              \
1921
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
1922
GEN_LDX(width, 0x17, op | 0x00, type)
1923

    
1924
/* lbz lbzu lbzux lbzx */
1925
GEN_LDS(bz, 0x02, PPC_INTEGER);
1926
/* lha lhau lhaux lhax */
1927
GEN_LDS(ha, 0x0A, PPC_INTEGER);
1928
/* lhz lhzu lhzux lhzx */
1929
GEN_LDS(hz, 0x08, PPC_INTEGER);
1930
/* lwz lwzu lwzux lwzx */
1931
GEN_LDS(wz, 0x00, PPC_INTEGER);
1932
#if defined(TARGET_PPC64)
1933
OP_LD_TABLE(wa);
1934
OP_LD_TABLE(d);
1935
/* lwaux */
1936
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
1937
/* lwax */
1938
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
1939
/* ldux */
1940
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
1941
/* ldx */
1942
GEN_LDX(d, 0x15, 0x00, PPC_64B);
1943
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
1944
{
1945
    if (Rc(ctx->opcode)) {
1946
        if (unlikely(rA(ctx->opcode) == 0 ||
1947
                     rA(ctx->opcode) == rD(ctx->opcode))) {
1948
            RET_INVAL(ctx);
1949
            return;
1950
        }
1951
    }
1952
    gen_addr_imm_index(ctx, 1);
1953
    if (ctx->opcode & 0x02) {
1954
        /* lwa (lwau is undefined) */
1955
        op_ldst(lwa);
1956
    } else {
1957
        /* ld - ldu */
1958
        op_ldst(ld);
1959
    }
1960
    gen_op_store_T1_gpr(rD(ctx->opcode));
1961
    if (Rc(ctx->opcode))
1962
        gen_op_store_T0_gpr(rA(ctx->opcode));
1963
}
1964
#endif
1965

    
1966
/***                              Integer store                            ***/
1967
#define GEN_ST(width, opc, type)                                              \
1968
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
1969
{                                                                             \
1970
    gen_addr_imm_index(ctx, 0);                                               \
1971
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1972
    op_ldst(st##width);                                                       \
1973
}
1974

    
1975
#define GEN_STU(width, opc, type)                                             \
1976
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
1977
{                                                                             \
1978
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1979
        RET_INVAL(ctx);                                                       \
1980
        return;                                                               \
1981
    }                                                                         \
1982
    if (type == PPC_64B)                                                      \
1983
        gen_addr_imm_index(ctx, 1);                                           \
1984
    else                                                                      \
1985
        gen_addr_imm_index(ctx, 0);                                           \
1986
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1987
    op_ldst(st##width);                                                       \
1988
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1989
}
1990

    
1991
#define GEN_STUX(width, opc2, opc3, type)                                     \
1992
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
1993
{                                                                             \
1994
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1995
        RET_INVAL(ctx);                                                       \
1996
        return;                                                               \
1997
    }                                                                         \
1998
    gen_addr_reg_index(ctx);                                                  \
1999
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2000
    op_ldst(st##width);                                                       \
2001
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2002
}
2003

    
2004
#define GEN_STX(width, opc2, opc3, type)                                      \
2005
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2006
{                                                                             \
2007
    gen_addr_reg_index(ctx);                                                  \
2008
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2009
    op_ldst(st##width);                                                       \
2010
}
2011

    
2012
#define GEN_STS(width, op, type)                                              \
2013
OP_ST_TABLE(width);                                                           \
2014
GEN_ST(width, op | 0x20, type);                                               \
2015
GEN_STU(width, op | 0x21, type);                                              \
2016
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2017
GEN_STX(width, 0x17, op | 0x00, type)
2018

    
2019
/* stb stbu stbux stbx */
2020
GEN_STS(b, 0x06, PPC_INTEGER);
2021
/* sth sthu sthux sthx */
2022
GEN_STS(h, 0x0C, PPC_INTEGER);
2023
/* stw stwu stwux stwx */
2024
GEN_STS(w, 0x04, PPC_INTEGER);
2025
#if defined(TARGET_PPC64)
2026
OP_ST_TABLE(d);
2027
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2028
GEN_STX(d, 0x15, 0x04, PPC_64B);
2029
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
2030
{
2031
    if (Rc(ctx->opcode)) {
2032
        if (unlikely(rA(ctx->opcode) == 0)) {
2033
            RET_INVAL(ctx);
2034
            return;
2035
        }
2036
    }
2037
    gen_addr_imm_index(ctx, 1);
2038
    gen_op_load_gpr_T1(rS(ctx->opcode));
2039
    op_ldst(std);
2040
    if (Rc(ctx->opcode))
2041
        gen_op_store_T0_gpr(rA(ctx->opcode));
2042
}
2043
#endif
2044
/***                Integer load and store with byte reverse               ***/
2045
/* lhbrx */
2046
OP_LD_TABLE(hbr);
2047
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2048
/* lwbrx */
2049
OP_LD_TABLE(wbr);
2050
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2051
/* sthbrx */
2052
OP_ST_TABLE(hbr);
2053
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2054
/* stwbrx */
2055
OP_ST_TABLE(wbr);
2056
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2057

    
2058
/***                    Integer load and store multiple                    ***/
2059
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2060
#if defined(TARGET_PPC64)
2061
#if defined(CONFIG_USER_ONLY)
2062
static GenOpFunc1 *gen_op_lmw[] = {
2063
    &gen_op_lmw_raw,
2064
    &gen_op_lmw_le_raw,
2065
    &gen_op_lmw_64_raw,
2066
    &gen_op_lmw_le_64_raw,
2067
};
2068
static GenOpFunc1 *gen_op_stmw[] = {
2069
    &gen_op_stmw_64_raw,
2070
    &gen_op_stmw_le_64_raw,
2071
};
2072
#else
2073
static GenOpFunc1 *gen_op_lmw[] = {
2074
    &gen_op_lmw_user,
2075
    &gen_op_lmw_le_user,
2076
    &gen_op_lmw_kernel,
2077
    &gen_op_lmw_le_kernel,
2078
    &gen_op_lmw_64_user,
2079
    &gen_op_lmw_le_64_user,
2080
    &gen_op_lmw_64_kernel,
2081
    &gen_op_lmw_le_64_kernel,
2082
};
2083
static GenOpFunc1 *gen_op_stmw[] = {
2084
    &gen_op_stmw_user,
2085
    &gen_op_stmw_le_user,
2086
    &gen_op_stmw_kernel,
2087
    &gen_op_stmw_le_kernel,
2088
    &gen_op_stmw_64_user,
2089
    &gen_op_stmw_le_64_user,
2090
    &gen_op_stmw_64_kernel,
2091
    &gen_op_stmw_le_64_kernel,
2092
};
2093
#endif
2094
#else
2095
#if defined(CONFIG_USER_ONLY)
2096
static GenOpFunc1 *gen_op_lmw[] = {
2097
    &gen_op_lmw_raw,
2098
    &gen_op_lmw_le_raw,
2099
};
2100
static GenOpFunc1 *gen_op_stmw[] = {
2101
    &gen_op_stmw_raw,
2102
    &gen_op_stmw_le_raw,
2103
};
2104
#else
2105
static GenOpFunc1 *gen_op_lmw[] = {
2106
    &gen_op_lmw_user,
2107
    &gen_op_lmw_le_user,
2108
    &gen_op_lmw_kernel,
2109
    &gen_op_lmw_le_kernel,
2110
};
2111
static GenOpFunc1 *gen_op_stmw[] = {
2112
    &gen_op_stmw_user,
2113
    &gen_op_stmw_le_user,
2114
    &gen_op_stmw_kernel,
2115
    &gen_op_stmw_le_kernel,
2116
};
2117
#endif
2118
#endif
2119

    
2120
/* lmw */
2121
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2122
{
2123
    /* NIP cannot be restored if the memory exception comes from an helper */
2124
    gen_update_nip(ctx, ctx->nip - 4);
2125
    gen_addr_imm_index(ctx, 0);
2126
    op_ldstm(lmw, rD(ctx->opcode));
2127
}
2128

    
2129
/* stmw */
2130
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2131
{
2132
    /* NIP cannot be restored if the memory exception comes from an helper */
2133
    gen_update_nip(ctx, ctx->nip - 4);
2134
    gen_addr_imm_index(ctx, 0);
2135
    op_ldstm(stmw, rS(ctx->opcode));
2136
}
2137

    
2138
/***                    Integer load and store strings                     ***/
2139
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2140
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2141
#if defined(TARGET_PPC64)
2142
#if defined(CONFIG_USER_ONLY)
2143
static GenOpFunc1 *gen_op_lswi[] = {
2144
    &gen_op_lswi_raw,
2145
    &gen_op_lswi_le_raw,
2146
    &gen_op_lswi_64_raw,
2147
    &gen_op_lswi_le_64_raw,
2148
};
2149
static GenOpFunc3 *gen_op_lswx[] = {
2150
    &gen_op_lswx_raw,
2151
    &gen_op_lswx_le_raw,
2152
    &gen_op_lswx_64_raw,
2153
    &gen_op_lswx_le_64_raw,
2154
};
2155
static GenOpFunc1 *gen_op_stsw[] = {
2156
    &gen_op_stsw_raw,
2157
    &gen_op_stsw_le_raw,
2158
    &gen_op_stsw_64_raw,
2159
    &gen_op_stsw_le_64_raw,
2160
};
2161
#else
2162
static GenOpFunc1 *gen_op_lswi[] = {
2163
    &gen_op_lswi_user,
2164
    &gen_op_lswi_le_user,
2165
    &gen_op_lswi_kernel,
2166
    &gen_op_lswi_le_kernel,
2167
    &gen_op_lswi_64_user,
2168
    &gen_op_lswi_le_64_user,
2169
    &gen_op_lswi_64_kernel,
2170
    &gen_op_lswi_le_64_kernel,
2171
};
2172
static GenOpFunc3 *gen_op_lswx[] = {
2173
    &gen_op_lswx_user,
2174
    &gen_op_lswx_le_user,
2175
    &gen_op_lswx_kernel,
2176
    &gen_op_lswx_le_kernel,
2177
    &gen_op_lswx_64_user,
2178
    &gen_op_lswx_le_64_user,
2179
    &gen_op_lswx_64_kernel,
2180
    &gen_op_lswx_le_64_kernel,
2181
};
2182
static GenOpFunc1 *gen_op_stsw[] = {
2183
    &gen_op_stsw_user,
2184
    &gen_op_stsw_le_user,
2185
    &gen_op_stsw_kernel,
2186
    &gen_op_stsw_le_kernel,
2187
    &gen_op_stsw_64_user,
2188
    &gen_op_stsw_le_64_user,
2189
    &gen_op_stsw_64_kernel,
2190
    &gen_op_stsw_le_64_kernel,
2191
};
2192
#endif
2193
#else
2194
#if defined(CONFIG_USER_ONLY)
2195
static GenOpFunc1 *gen_op_lswi[] = {
2196
    &gen_op_lswi_raw,
2197
    &gen_op_lswi_le_raw,
2198
};
2199
static GenOpFunc3 *gen_op_lswx[] = {
2200
    &gen_op_lswx_raw,
2201
    &gen_op_lswx_le_raw,
2202
};
2203
static GenOpFunc1 *gen_op_stsw[] = {
2204
    &gen_op_stsw_raw,
2205
    &gen_op_stsw_le_raw,
2206
};
2207
#else
2208
static GenOpFunc1 *gen_op_lswi[] = {
2209
    &gen_op_lswi_user,
2210
    &gen_op_lswi_le_user,
2211
    &gen_op_lswi_kernel,
2212
    &gen_op_lswi_le_kernel,
2213
};
2214
static GenOpFunc3 *gen_op_lswx[] = {
2215
    &gen_op_lswx_user,
2216
    &gen_op_lswx_le_user,
2217
    &gen_op_lswx_kernel,
2218
    &gen_op_lswx_le_kernel,
2219
};
2220
static GenOpFunc1 *gen_op_stsw[] = {
2221
    &gen_op_stsw_user,
2222
    &gen_op_stsw_le_user,
2223
    &gen_op_stsw_kernel,
2224
    &gen_op_stsw_le_kernel,
2225
};
2226
#endif
2227
#endif
2228

    
2229
/* lswi */
2230
/* PowerPC32 specification says we must generate an exception if
2231
 * rA is in the range of registers to be loaded.
2232
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2233
 * For now, I'll follow the spec...
2234
 */
2235
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
2236
{
2237
    int nb = NB(ctx->opcode);
2238
    int start = rD(ctx->opcode);
2239
    int ra = rA(ctx->opcode);
2240
    int nr;
2241

    
2242
    if (nb == 0)
2243
        nb = 32;
2244
    nr = nb / 4;
2245
    if (unlikely(((start + nr) > 32  &&
2246
                  start <= ra && (start + nr - 32) > ra) ||
2247
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2248
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
2249
        return;
2250
    }
2251
    /* NIP cannot be restored if the memory exception comes from an helper */
2252
    gen_update_nip(ctx, ctx->nip - 4);
2253
    gen_addr_register(ctx);
2254
    gen_op_set_T1(nb);
2255
    op_ldsts(lswi, start);
2256
}
2257

    
2258
/* lswx */
2259
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
2260
{
2261
    int ra = rA(ctx->opcode);
2262
    int rb = rB(ctx->opcode);
2263

    
2264
    /* NIP cannot be restored if the memory exception comes from an helper */
2265
    gen_update_nip(ctx, ctx->nip - 4);
2266
    gen_addr_reg_index(ctx);
2267
    if (ra == 0) {
2268
        ra = rb;
2269
    }
2270
    gen_op_load_xer_bc();
2271
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2272
}
2273

    
2274
/* stswi */
2275
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
2276
{
2277
    int nb = NB(ctx->opcode);
2278

    
2279
    /* NIP cannot be restored if the memory exception comes from an helper */
2280
    gen_update_nip(ctx, ctx->nip - 4);
2281
    gen_addr_register(ctx);
2282
    if (nb == 0)
2283
        nb = 32;
2284
    gen_op_set_T1(nb);
2285
    op_ldsts(stsw, rS(ctx->opcode));
2286
}
2287

    
2288
/* stswx */
2289
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
2290
{
2291
    /* NIP cannot be restored if the memory exception comes from an helper */
2292
    gen_update_nip(ctx, ctx->nip - 4);
2293
    gen_addr_reg_index(ctx);
2294
    gen_op_load_xer_bc();
2295
    op_ldsts(stsw, rS(ctx->opcode));
2296
}
2297

    
2298
/***                        Memory synchronisation                         ***/
2299
/* eieio */
2300
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
2301
{
2302
}
2303

    
2304
/* isync */
2305
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
2306
{
2307
}
2308

    
2309
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2310
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2311
#if defined(TARGET_PPC64)
2312
#if defined(CONFIG_USER_ONLY)
2313
static GenOpFunc *gen_op_lwarx[] = {
2314
    &gen_op_lwarx_raw,
2315
    &gen_op_lwarx_le_raw,
2316
    &gen_op_lwarx_64_raw,
2317
    &gen_op_lwarx_le_64_raw,
2318
};
2319
static GenOpFunc *gen_op_stwcx[] = {
2320
    &gen_op_stwcx_raw,
2321
    &gen_op_stwcx_le_raw,
2322
    &gen_op_stwcx_64_raw,
2323
    &gen_op_stwcx_le_64_raw,
2324
};
2325
#else
2326
static GenOpFunc *gen_op_lwarx[] = {
2327
    &gen_op_lwarx_user,
2328
    &gen_op_lwarx_le_user,
2329
    &gen_op_lwarx_kernel,
2330
    &gen_op_lwarx_le_kernel,
2331
    &gen_op_lwarx_64_user,
2332
    &gen_op_lwarx_le_64_user,
2333
    &gen_op_lwarx_64_kernel,
2334
    &gen_op_lwarx_le_64_kernel,
2335
};
2336
static GenOpFunc *gen_op_stwcx[] = {
2337
    &gen_op_stwcx_user,
2338
    &gen_op_stwcx_le_user,
2339
    &gen_op_stwcx_kernel,
2340
    &gen_op_stwcx_le_kernel,
2341
    &gen_op_stwcx_64_user,
2342
    &gen_op_stwcx_le_64_user,
2343
    &gen_op_stwcx_64_kernel,
2344
    &gen_op_stwcx_le_64_kernel,
2345
};
2346
#endif
2347
#else
2348
#if defined(CONFIG_USER_ONLY)
2349
static GenOpFunc *gen_op_lwarx[] = {
2350
    &gen_op_lwarx_raw,
2351
    &gen_op_lwarx_le_raw,
2352
};
2353
static GenOpFunc *gen_op_stwcx[] = {
2354
    &gen_op_stwcx_raw,
2355
    &gen_op_stwcx_le_raw,
2356
};
2357
#else
2358
static GenOpFunc *gen_op_lwarx[] = {
2359
    &gen_op_lwarx_user,
2360
    &gen_op_lwarx_le_user,
2361
    &gen_op_lwarx_kernel,
2362
    &gen_op_lwarx_le_kernel,
2363
};
2364
static GenOpFunc *gen_op_stwcx[] = {
2365
    &gen_op_stwcx_user,
2366
    &gen_op_stwcx_le_user,
2367
    &gen_op_stwcx_kernel,
2368
    &gen_op_stwcx_le_kernel,
2369
};
2370
#endif
2371
#endif
2372

    
2373
/* lwarx */
2374
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2375
{
2376
    gen_addr_reg_index(ctx);
2377
    op_lwarx();
2378
    gen_op_store_T1_gpr(rD(ctx->opcode));
2379
}
2380

    
2381
/* stwcx. */
2382
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2383
{
2384
    gen_addr_reg_index(ctx);
2385
    gen_op_load_gpr_T1(rS(ctx->opcode));
2386
    op_stwcx();
2387
}
2388

    
2389
#if defined(TARGET_PPC64)
2390
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2391
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2392
#if defined(CONFIG_USER_ONLY)
2393
static GenOpFunc *gen_op_ldarx[] = {
2394
    &gen_op_ldarx_raw,
2395
    &gen_op_ldarx_le_raw,
2396
    &gen_op_ldarx_64_raw,
2397
    &gen_op_ldarx_le_64_raw,
2398
};
2399
static GenOpFunc *gen_op_stdcx[] = {
2400
    &gen_op_stdcx_raw,
2401
    &gen_op_stdcx_le_raw,
2402
    &gen_op_stdcx_64_raw,
2403
    &gen_op_stdcx_le_64_raw,
2404
};
2405
#else
2406
static GenOpFunc *gen_op_ldarx[] = {
2407
    &gen_op_ldarx_user,
2408
    &gen_op_ldarx_le_user,
2409
    &gen_op_ldarx_kernel,
2410
    &gen_op_ldarx_le_kernel,
2411
    &gen_op_ldarx_64_user,
2412
    &gen_op_ldarx_le_64_user,
2413
    &gen_op_ldarx_64_kernel,
2414
    &gen_op_ldarx_le_64_kernel,
2415
};
2416
static GenOpFunc *gen_op_stdcx[] = {
2417
    &gen_op_stdcx_user,
2418
    &gen_op_stdcx_le_user,
2419
    &gen_op_stdcx_kernel,
2420
    &gen_op_stdcx_le_kernel,
2421
    &gen_op_stdcx_64_user,
2422
    &gen_op_stdcx_le_64_user,
2423
    &gen_op_stdcx_64_kernel,
2424
    &gen_op_stdcx_le_64_kernel,
2425
};
2426
#endif
2427

    
2428
/* ldarx */
2429
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_RES)
2430
{
2431
    gen_addr_reg_index(ctx);
2432
    op_ldarx();
2433
    gen_op_store_T1_gpr(rD(ctx->opcode));
2434
}
2435

    
2436
/* stdcx. */
2437
GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_RES)
2438
{
2439
    gen_addr_reg_index(ctx);
2440
    gen_op_load_gpr_T1(rS(ctx->opcode));
2441
    op_stdcx();
2442
}
2443
#endif /* defined(TARGET_PPC64) */
2444

    
2445
/* sync */
2446
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
2447
{
2448
}
2449

    
2450
/***                         Floating-point load                           ***/
2451
#define GEN_LDF(width, opc)                                                   \
2452
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                 \
2453
{                                                                             \
2454
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2455
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2456
        return;                                                               \
2457
    }                                                                         \
2458
    gen_addr_imm_index(ctx, 0);                                               \
2459
    op_ldst(l##width);                                                        \
2460
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2461
}
2462

    
2463
#define GEN_LDUF(width, opc)                                                  \
2464
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)              \
2465
{                                                                             \
2466
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2467
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2468
        return;                                                               \
2469
    }                                                                         \
2470
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2471
        RET_INVAL(ctx);                                                       \
2472
        return;                                                               \
2473
    }                                                                         \
2474
    gen_addr_imm_index(ctx, 0);                                               \
2475
    op_ldst(l##width);                                                        \
2476
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2477
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2478
}
2479

    
2480
#define GEN_LDUXF(width, opc)                                                 \
2481
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
2482
{                                                                             \
2483
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2484
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2485
        return;                                                               \
2486
    }                                                                         \
2487
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2488
        RET_INVAL(ctx);                                                       \
2489
        return;                                                               \
2490
    }                                                                         \
2491
    gen_addr_reg_index(ctx);                                                  \
2492
    op_ldst(l##width);                                                        \
2493
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2494
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2495
}
2496

    
2497
#define GEN_LDXF(width, opc2, opc3)                                           \
2498
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)             \
2499
{                                                                             \
2500
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2501
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2502
        return;                                                               \
2503
    }                                                                         \
2504
    gen_addr_reg_index(ctx);                                                  \
2505
    op_ldst(l##width);                                                        \
2506
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2507
}
2508

    
2509
#define GEN_LDFS(width, op)                                                   \
2510
OP_LD_TABLE(width);                                                           \
2511
GEN_LDF(width, op | 0x20);                                                    \
2512
GEN_LDUF(width, op | 0x21);                                                   \
2513
GEN_LDUXF(width, op | 0x01);                                                  \
2514
GEN_LDXF(width, 0x17, op | 0x00)
2515

    
2516
/* lfd lfdu lfdux lfdx */
2517
GEN_LDFS(fd, 0x12);
2518
/* lfs lfsu lfsux lfsx */
2519
GEN_LDFS(fs, 0x10);
2520

    
2521
/***                         Floating-point store                          ***/
2522
#define GEN_STF(width, opc)                                                   \
2523
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
2524
{                                                                             \
2525
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2526
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2527
        return;                                                               \
2528
    }                                                                         \
2529
    gen_addr_imm_index(ctx, 0);                                               \
2530
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2531
    op_ldst(st##width);                                                       \
2532
}
2533

    
2534
#define GEN_STUF(width, opc)                                                  \
2535
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
2536
{                                                                             \
2537
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2538
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2539
        return;                                                               \
2540
    }                                                                         \
2541
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2542
        RET_INVAL(ctx);                                                       \
2543
        return;                                                               \
2544
    }                                                                         \
2545
    gen_addr_imm_index(ctx, 0);                                               \
2546
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2547
    op_ldst(st##width);                                                       \
2548
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2549
}
2550

    
2551
#define GEN_STUXF(width, opc)                                                 \
2552
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
2553
{                                                                             \
2554
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2555
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2556
        return;                                                               \
2557
    }                                                                         \
2558
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2559
        RET_INVAL(ctx);                                                       \
2560
        return;                                                               \
2561
    }                                                                         \
2562
    gen_addr_reg_index(ctx);                                                  \
2563
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2564
    op_ldst(st##width);                                                       \
2565
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2566
}
2567

    
2568
#define GEN_STXF(width, opc2, opc3)                                           \
2569
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)            \
2570
{                                                                             \
2571
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2572
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2573
        return;                                                               \
2574
    }                                                                         \
2575
    gen_addr_reg_index(ctx);                                                  \
2576
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2577
    op_ldst(st##width);                                                       \
2578
}
2579

    
2580
#define GEN_STFS(width, op)                                                   \
2581
OP_ST_TABLE(width);                                                           \
2582
GEN_STF(width, op | 0x20);                                                    \
2583
GEN_STUF(width, op | 0x21);                                                   \
2584
GEN_STUXF(width, op | 0x01);                                                  \
2585
GEN_STXF(width, 0x17, op | 0x00)
2586

    
2587
/* stfd stfdu stfdux stfdx */
2588
GEN_STFS(fd, 0x16);
2589
/* stfs stfsu stfsux stfsx */
2590
GEN_STFS(fs, 0x14);
2591

    
2592
/* Optional: */
2593
/* stfiwx */
2594
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
2595
{
2596
    if (unlikely(!ctx->fpu_enabled)) {
2597
        RET_EXCP(ctx, EXCP_NO_FP, 0);
2598
        return;
2599
    }
2600
    gen_addr_reg_index(ctx);
2601
    /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2602
    RET_INVAL(ctx);
2603
}
2604

    
2605
/***                                Branch                                 ***/
2606
static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
2607
{
2608
    TranslationBlock *tb;
2609
    tb = ctx->tb;
2610
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2611
        if (n == 0)
2612
            gen_op_goto_tb0(TBPARAM(tb));
2613
        else
2614
            gen_op_goto_tb1(TBPARAM(tb));
2615
        gen_set_T1(dest);
2616
#if defined(TARGET_PPC64)
2617
        if (ctx->sf_mode)
2618
            gen_op_b_T1_64();
2619
        else
2620
#endif
2621
            gen_op_b_T1();
2622
        gen_op_set_T0((long)tb + n);
2623
        if (ctx->singlestep_enabled)
2624
            gen_op_debug();
2625
        gen_op_exit_tb();
2626
    } else {
2627
        gen_set_T1(dest);
2628
#if defined(TARGET_PPC64)
2629
        if (ctx->sf_mode)
2630
            gen_op_b_T1_64();
2631
        else
2632
#endif
2633
            gen_op_b_T1();
2634
        gen_op_reset_T0();
2635
        if (ctx->singlestep_enabled)
2636
            gen_op_debug();
2637
        gen_op_exit_tb();
2638
    }
2639
}
2640

    
2641
/* b ba bl bla */
2642
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2643
{
2644
    target_ulong li, target;
2645

    
2646
    /* sign extend LI */
2647
#if defined(TARGET_PPC64)
2648
    if (ctx->sf_mode)
2649
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2650
    else
2651
#endif
2652
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2653
    if (likely(AA(ctx->opcode) == 0))
2654
        target = ctx->nip + li - 4;
2655
    else
2656
        target = li;
2657
    if (LK(ctx->opcode)) {
2658
#if defined(TARGET_PPC64)
2659
        if (ctx->sf_mode)
2660
            gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2661
        else
2662
#endif
2663
            gen_op_setlr(ctx->nip);
2664
    }
2665
    gen_goto_tb(ctx, 0, target);
2666
    ctx->exception = EXCP_BRANCH;
2667
}
2668

    
2669
#define BCOND_IM  0
2670
#define BCOND_LR  1
2671
#define BCOND_CTR 2
2672

    
2673
static inline void gen_bcond (DisasContext *ctx, int type)
2674
{
2675
    target_ulong target = 0;
2676
    target_ulong li;
2677
    uint32_t bo = BO(ctx->opcode);
2678
    uint32_t bi = BI(ctx->opcode);
2679
    uint32_t mask;
2680

    
2681
    if ((bo & 0x4) == 0)
2682
        gen_op_dec_ctr();
2683
    switch(type) {
2684
    case BCOND_IM:
2685
        li = (target_long)((int16_t)(BD(ctx->opcode)));
2686
        if (likely(AA(ctx->opcode) == 0)) {
2687
            target = ctx->nip + li - 4;
2688
        } else {
2689
            target = li;
2690
        }
2691
        break;
2692
    case BCOND_CTR:
2693
        gen_op_movl_T1_ctr();
2694
        break;
2695
    default:
2696
    case BCOND_LR:
2697
        gen_op_movl_T1_lr();
2698
        break;
2699
    }
2700
    if (LK(ctx->opcode)) {
2701
#if defined(TARGET_PPC64)
2702
        if (ctx->sf_mode)
2703
            gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2704
        else
2705
#endif
2706
            gen_op_setlr(ctx->nip);
2707
    }
2708
    if (bo & 0x10) {
2709
        /* No CR condition */
2710
        switch (bo & 0x6) {
2711
        case 0:
2712
#if defined(TARGET_PPC64)
2713
            if (ctx->sf_mode)
2714
                gen_op_test_ctr_64();
2715
            else
2716
#endif
2717
                gen_op_test_ctr();
2718
            break;
2719
        case 2:
2720
#if defined(TARGET_PPC64)
2721
            if (ctx->sf_mode)
2722
                gen_op_test_ctrz_64();
2723
            else
2724
#endif
2725
                gen_op_test_ctrz();
2726
            break;
2727
        default:
2728
        case 4:
2729
        case 6:
2730
            if (type == BCOND_IM) {
2731
                gen_goto_tb(ctx, 0, target);
2732
            } else {
2733
#if defined(TARGET_PPC64)
2734
                if (ctx->sf_mode)
2735
                    gen_op_b_T1_64();
2736
                else
2737
#endif
2738
                    gen_op_b_T1();
2739
                gen_op_reset_T0();
2740
            }
2741
            goto no_test;
2742
        }
2743
    } else {
2744
        mask = 1 << (3 - (bi & 0x03));
2745
        gen_op_load_crf_T0(bi >> 2);
2746
        if (bo & 0x8) {
2747
            switch (bo & 0x6) {
2748
            case 0:
2749
#if defined(TARGET_PPC64)
2750
                if (ctx->sf_mode)
2751
                    gen_op_test_ctr_true_64(mask);
2752
                else
2753
#endif
2754
                    gen_op_test_ctr_true(mask);
2755
                break;
2756
            case 2:
2757
#if defined(TARGET_PPC64)
2758
                if (ctx->sf_mode)
2759
                    gen_op_test_ctrz_true_64(mask);
2760
                else
2761
#endif
2762
                    gen_op_test_ctrz_true(mask);
2763
                break;
2764
            default:
2765
            case 4:
2766
            case 6:
2767
                gen_op_test_true(mask);
2768
                break;
2769
            }
2770
        } else {
2771
            switch (bo & 0x6) {
2772
            case 0:
2773
#if defined(TARGET_PPC64)
2774
                if (ctx->sf_mode)
2775
                    gen_op_test_ctr_false_64(mask);
2776
                else
2777
#endif
2778
                    gen_op_test_ctr_false(mask);
2779
                break;
2780
            case 2:
2781
#if defined(TARGET_PPC64)
2782
                if (ctx->sf_mode)
2783
                    gen_op_test_ctrz_false_64(mask);
2784
                else
2785
#endif
2786
                    gen_op_test_ctrz_false(mask);
2787
                break;
2788
            default:
2789
            case 4:
2790
            case 6:
2791
                gen_op_test_false(mask);
2792
                break;
2793
            }
2794
        }
2795
    }
2796
    if (type == BCOND_IM) {
2797
        int l1 = gen_new_label();
2798
        gen_op_jz_T0(l1);
2799
        gen_goto_tb(ctx, 0, target);
2800
        gen_set_label(l1);
2801
        gen_goto_tb(ctx, 1, ctx->nip);
2802
    } else {
2803
#if defined(TARGET_PPC64)
2804
        if (ctx->sf_mode)
2805
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
2806
        else
2807
#endif
2808
            gen_op_btest_T1(ctx->nip);
2809
        gen_op_reset_T0();
2810
    no_test:
2811
        if (ctx->singlestep_enabled)
2812
            gen_op_debug();
2813
        gen_op_exit_tb();
2814
    }
2815
    ctx->exception = EXCP_BRANCH;
2816
}
2817

    
2818
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2819
{
2820
    gen_bcond(ctx, BCOND_IM);
2821
}
2822

    
2823
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
2824
{
2825
    gen_bcond(ctx, BCOND_CTR);
2826
}
2827

    
2828
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
2829
{
2830
    gen_bcond(ctx, BCOND_LR);
2831
}
2832

    
2833
/***                      Condition register logical                       ***/
2834
#define GEN_CRLOGIC(op, opc)                                                  \
2835
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
2836
{                                                                             \
2837
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
2838
    gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
2839
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
2840
    gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
2841
    gen_op_##op();                                                            \
2842
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
2843
    gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
2844
                     3 - (crbD(ctx->opcode) & 0x03));                         \
2845
    gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
2846
}
2847

    
2848
/* crand */
2849
GEN_CRLOGIC(and, 0x08);
2850
/* crandc */
2851
GEN_CRLOGIC(andc, 0x04);
2852
/* creqv */
2853
GEN_CRLOGIC(eqv, 0x09);
2854
/* crnand */
2855
GEN_CRLOGIC(nand, 0x07);
2856
/* crnor */
2857
GEN_CRLOGIC(nor, 0x01);
2858
/* cror */
2859
GEN_CRLOGIC(or, 0x0E);
2860
/* crorc */
2861
GEN_CRLOGIC(orc, 0x0D);
2862
/* crxor */
2863
GEN_CRLOGIC(xor, 0x06);
2864
/* mcrf */
2865
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
2866
{
2867
    gen_op_load_crf_T0(crfS(ctx->opcode));
2868
    gen_op_store_T0_crf(crfD(ctx->opcode));
2869
}
2870

    
2871
/***                           System linkage                              ***/
2872
/* rfi (supervisor only) */
2873
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
2874
{
2875
#if defined(CONFIG_USER_ONLY)
2876
    RET_PRIVOPC(ctx);
2877
#else
2878
    /* Restore CPU state */
2879
    if (unlikely(!ctx->supervisor)) {
2880
        RET_PRIVOPC(ctx);
2881
        return;
2882
    }
2883
    gen_op_rfi();
2884
    RET_CHG_FLOW(ctx);
2885
#endif
2886
}
2887

    
2888
#if defined(TARGET_PPC64)
2889
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_FLOW)
2890
{
2891
#if defined(CONFIG_USER_ONLY)
2892
    RET_PRIVOPC(ctx);
2893
#else
2894
    /* Restore CPU state */
2895
    if (unlikely(!ctx->supervisor)) {
2896
        RET_PRIVOPC(ctx);
2897
        return;
2898
    }
2899
    gen_op_rfid();
2900
    RET_CHG_FLOW(ctx);
2901
#endif
2902
}
2903
#endif
2904

    
2905
/* sc */
2906
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
2907
{
2908
#if defined(CONFIG_USER_ONLY)
2909
    RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
2910
#else
2911
    RET_EXCP(ctx, EXCP_SYSCALL, 0);
2912
#endif
2913
}
2914

    
2915
/***                                Trap                                   ***/
2916
/* tw */
2917
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
2918
{
2919
    gen_op_load_gpr_T0(rA(ctx->opcode));
2920
    gen_op_load_gpr_T1(rB(ctx->opcode));
2921
    /* Update the nip since this might generate a trap exception */
2922
    gen_update_nip(ctx, ctx->nip);
2923
    gen_op_tw(TO(ctx->opcode));
2924
}
2925

    
2926
/* twi */
2927
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2928
{
2929
    gen_op_load_gpr_T0(rA(ctx->opcode));
2930
    gen_set_T1(SIMM(ctx->opcode));
2931
    /* Update the nip since this might generate a trap exception */
2932
    gen_update_nip(ctx, ctx->nip);
2933
    gen_op_tw(TO(ctx->opcode));
2934
}
2935

    
2936
#if defined(TARGET_PPC64)
2937
/* td */
2938
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
2939
{
2940
    gen_op_load_gpr_T0(rA(ctx->opcode));
2941
    gen_op_load_gpr_T1(rB(ctx->opcode));
2942
    /* Update the nip since this might generate a trap exception */
2943
    gen_update_nip(ctx, ctx->nip);
2944
    gen_op_td(TO(ctx->opcode));
2945
}
2946

    
2947
/* tdi */
2948
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
2949
{
2950
    gen_op_load_gpr_T0(rA(ctx->opcode));
2951
    gen_set_T1(SIMM(ctx->opcode));
2952
    /* Update the nip since this might generate a trap exception */
2953
    gen_update_nip(ctx, ctx->nip);
2954
    gen_op_td(TO(ctx->opcode));
2955
}
2956
#endif
2957

    
2958
/***                          Processor control                            ***/
2959
/* mcrxr */
2960
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
2961
{
2962
    gen_op_load_xer_cr();
2963
    gen_op_store_T0_crf(crfD(ctx->opcode));
2964
    gen_op_clear_xer_ov();
2965
    gen_op_clear_xer_ca();
2966
}
2967

    
2968
/* mfcr */
2969
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
2970
{
2971
    uint32_t crm, crn;
2972

    
2973
    if (likely(ctx->opcode & 0x00100000)) {
2974
        crm = CRM(ctx->opcode);
2975
        if (likely((crm ^ (crm - 1)) == 0)) {
2976
            crn = ffs(crm);
2977
            gen_op_load_cro(7 - crn);
2978
        }
2979
    } else {
2980
        gen_op_load_cr();
2981
    }
2982
    gen_op_store_T0_gpr(rD(ctx->opcode));
2983
}
2984

    
2985
/* mfmsr */
2986
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
2987
{
2988
#if defined(CONFIG_USER_ONLY)
2989
    RET_PRIVREG(ctx);
2990
#else
2991
    if (unlikely(!ctx->supervisor)) {
2992
        RET_PRIVREG(ctx);
2993
        return;
2994
    }
2995
    gen_op_load_msr();
2996
    gen_op_store_T0_gpr(rD(ctx->opcode));
2997
#endif
2998
}
2999

    
3000
#if 0
3001
#define SPR_NOACCESS ((void *)(-1))
3002
#else
3003
static void spr_noaccess (void *opaque, int sprn)
3004
{
3005
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3006
    printf("ERROR: try to access SPR %d !\n", sprn);
3007
}
3008
#define SPR_NOACCESS (&spr_noaccess)
3009
#endif
3010

    
3011
/* mfspr */
3012
static inline void gen_op_mfspr (DisasContext *ctx)
3013
{
3014
    void (*read_cb)(void *opaque, int sprn);
3015
    uint32_t sprn = SPR(ctx->opcode);
3016

    
3017
#if !defined(CONFIG_USER_ONLY)
3018
    if (ctx->supervisor)
3019
        read_cb = ctx->spr_cb[sprn].oea_read;
3020
    else
3021
#endif
3022
        read_cb = ctx->spr_cb[sprn].uea_read;
3023
    if (likely(read_cb != NULL)) {
3024
        if (likely(read_cb != SPR_NOACCESS)) {
3025
            (*read_cb)(ctx, sprn);
3026
            gen_op_store_T0_gpr(rD(ctx->opcode));
3027
        } else {
3028
            /* Privilege exception */
3029
            if (loglevel != 0) {
3030
                fprintf(logfile, "Trying to read privileged spr %d %03x\n",
3031
                        sprn, sprn);
3032
            }
3033
            printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
3034
            RET_PRIVREG(ctx);
3035
        }
3036
    } else {
3037
        /* Not defined */
3038
        if (loglevel != 0) {
3039
            fprintf(logfile, "Trying to read invalid spr %d %03x\n",
3040
                    sprn, sprn);
3041
        }
3042
        printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
3043
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
3044
    }
3045
}
3046

    
3047
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3048
{
3049
    gen_op_mfspr(ctx);
3050
}
3051

    
3052
/* mftb */
3053
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB)
3054
{
3055
    gen_op_mfspr(ctx);
3056
}
3057

    
3058
/* mtcrf */
3059
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3060
{
3061
    uint32_t crm, crn;
3062

    
3063
    gen_op_load_gpr_T0(rS(ctx->opcode));
3064
    crm = CRM(ctx->opcode);
3065
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3066
        crn = ffs(crm);
3067
        gen_op_srli_T0(crn * 4);
3068
        gen_op_andi_T0(0xF);
3069
        gen_op_store_cro(7 - crn);
3070
    } else {
3071
        gen_op_store_cr(crm);
3072
    }
3073
}
3074

    
3075
/* mtmsr */
3076
#if defined(TARGET_PPC64)
3077
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_MISC)
3078
{
3079
#if defined(CONFIG_USER_ONLY)
3080
    RET_PRIVREG(ctx);
3081
#else
3082
    if (unlikely(!ctx->supervisor)) {
3083
        RET_PRIVREG(ctx);
3084
        return;
3085
    }
3086
    gen_update_nip(ctx, ctx->nip);
3087
    gen_op_load_gpr_T0(rS(ctx->opcode));
3088
    gen_op_store_msr();
3089
    /* Must stop the translation as machine state (may have) changed */
3090
    RET_CHG_FLOW(ctx);
3091
#endif
3092
}
3093
#endif
3094

    
3095
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3096
{
3097
#if defined(CONFIG_USER_ONLY)
3098
    RET_PRIVREG(ctx);
3099
#else
3100
    if (unlikely(!ctx->supervisor)) {
3101
        RET_PRIVREG(ctx);
3102
        return;
3103
    }
3104
    gen_update_nip(ctx, ctx->nip);
3105
    gen_op_load_gpr_T0(rS(ctx->opcode));
3106
#if defined(TARGET_PPC64)
3107
    if (!ctx->sf_mode)
3108
        gen_op_store_msr_32();
3109
    else
3110
#endif
3111
        gen_op_store_msr();
3112
    /* Must stop the translation as machine state (may have) changed */
3113
    RET_CHG_FLOW(ctx);
3114
#endif
3115
}
3116

    
3117
/* mtspr */
3118
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3119
{
3120
    void (*write_cb)(void *opaque, int sprn);
3121
    uint32_t sprn = SPR(ctx->opcode);
3122

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

    
3153
/***                         Cache management                              ***/
3154
/* For now, all those will be implemented as nop:
3155
 * this is valid, regarding the PowerPC specs...
3156
 * We just have to flush tb while invalidating instruction cache lines...
3157
 */
3158
/* dcbf */
3159
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
3160
{
3161
    gen_addr_reg_index(ctx);
3162
    op_ldst(lbz);
3163
}
3164

    
3165
/* dcbi (Supervisor only) */
3166
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3167
{
3168
#if defined(CONFIG_USER_ONLY)
3169
    RET_PRIVOPC(ctx);
3170
#else
3171
    if (unlikely(!ctx->supervisor)) {
3172
        RET_PRIVOPC(ctx);
3173
        return;
3174
    }
3175
    gen_addr_reg_index(ctx);
3176
    /* XXX: specification says this should be treated as a store by the MMU */
3177
    //op_ldst(lbz);
3178
    op_ldst(stb);
3179
#endif
3180
}
3181

    
3182
/* dcdst */
3183
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3184
{
3185
    /* XXX: specification say this is treated as a load by the MMU */
3186
    gen_addr_reg_index(ctx);
3187
    op_ldst(lbz);
3188
}
3189

    
3190
/* dcbt */
3191
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
3192
{
3193
    /* XXX: specification say this is treated as a load by the MMU
3194
     *      but does not generate any exception
3195
     */
3196
}
3197

    
3198
/* dcbtst */
3199
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
3200
{
3201
    /* XXX: specification say this is treated as a load by the MMU
3202
     *      but does not generate any exception
3203
     */
3204
}
3205

    
3206
/* dcbz */
3207
#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3208
#if defined(TARGET_PPC64)
3209
#if defined(CONFIG_USER_ONLY)
3210
static GenOpFunc *gen_op_dcbz[] = {
3211
    &gen_op_dcbz_raw,
3212
    &gen_op_dcbz_raw,
3213
    &gen_op_dcbz_64_raw,
3214
    &gen_op_dcbz_64_raw,
3215
};
3216
#else
3217
static GenOpFunc *gen_op_dcbz[] = {
3218
    &gen_op_dcbz_user,
3219
    &gen_op_dcbz_user,
3220
    &gen_op_dcbz_kernel,
3221
    &gen_op_dcbz_kernel,
3222
    &gen_op_dcbz_64_user,
3223
    &gen_op_dcbz_64_user,
3224
    &gen_op_dcbz_64_kernel,
3225
    &gen_op_dcbz_64_kernel,
3226
};
3227
#endif
3228
#else
3229
#if defined(CONFIG_USER_ONLY)
3230
static GenOpFunc *gen_op_dcbz[] = {
3231
    &gen_op_dcbz_raw,
3232
    &gen_op_dcbz_raw,
3233
};
3234
#else
3235
static GenOpFunc *gen_op_dcbz[] = {
3236
    &gen_op_dcbz_user,
3237
    &gen_op_dcbz_user,
3238
    &gen_op_dcbz_kernel,
3239
    &gen_op_dcbz_kernel,
3240
};
3241
#endif
3242
#endif
3243

    
3244
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3245
{
3246
    gen_addr_reg_index(ctx);
3247
    op_dcbz();
3248
    gen_op_check_reservation();
3249
}
3250

    
3251
/* icbi */
3252
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3253
#if defined(TARGET_PPC64)
3254
#if defined(CONFIG_USER_ONLY)
3255
static GenOpFunc *gen_op_icbi[] = {
3256
    &gen_op_icbi_raw,
3257
    &gen_op_icbi_raw,
3258
    &gen_op_icbi_64_raw,
3259
    &gen_op_icbi_64_raw,
3260
};
3261
#else
3262
static GenOpFunc *gen_op_icbi[] = {
3263
    &gen_op_icbi_user,
3264
    &gen_op_icbi_user,
3265
    &gen_op_icbi_kernel,
3266
    &gen_op_icbi_kernel,
3267
    &gen_op_icbi_64_user,
3268
    &gen_op_icbi_64_user,
3269
    &gen_op_icbi_64_kernel,
3270
    &gen_op_icbi_64_kernel,
3271
};
3272
#endif
3273
#else
3274
#if defined(CONFIG_USER_ONLY)
3275
static GenOpFunc *gen_op_icbi[] = {
3276
    &gen_op_icbi_raw,
3277
    &gen_op_icbi_raw,
3278
};
3279
#else
3280
static GenOpFunc *gen_op_icbi[] = {
3281
    &gen_op_icbi_user,
3282
    &gen_op_icbi_user,
3283
    &gen_op_icbi_kernel,
3284
    &gen_op_icbi_kernel,
3285
};
3286
#endif
3287
#endif
3288
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3289
{
3290
    /* NIP cannot be restored if the memory exception comes from an helper */
3291
    gen_update_nip(ctx, ctx->nip - 4);
3292
    gen_addr_reg_index(ctx);
3293
    op_icbi();
3294
    RET_STOP(ctx);
3295
}
3296

    
3297
/* Optional: */
3298
/* dcba */
3299
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT)
3300
{
3301
}
3302

    
3303
/***                    Segment register manipulation                      ***/
3304
/* Supervisor only: */
3305
/* mfsr */
3306
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3307
{
3308
#if defined(CONFIG_USER_ONLY)
3309
    RET_PRIVREG(ctx);
3310
#else
3311
    if (unlikely(!ctx->supervisor)) {
3312
        RET_PRIVREG(ctx);
3313
        return;
3314
    }
3315
    gen_op_set_T1(SR(ctx->opcode));
3316
    gen_op_load_sr();
3317
    gen_op_store_T0_gpr(rD(ctx->opcode));
3318
#endif
3319
}
3320

    
3321
/* mfsrin */
3322
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3323
{
3324
#if defined(CONFIG_USER_ONLY)
3325
    RET_PRIVREG(ctx);
3326
#else
3327
    if (unlikely(!ctx->supervisor)) {
3328
        RET_PRIVREG(ctx);
3329
        return;
3330
    }
3331
    gen_op_load_gpr_T1(rB(ctx->opcode));
3332
    gen_op_srli_T1(28);
3333
    gen_op_load_sr();
3334
    gen_op_store_T0_gpr(rD(ctx->opcode));
3335
#endif
3336
}
3337

    
3338
/* mtsr */
3339
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3340
{
3341
#if defined(CONFIG_USER_ONLY)
3342
    RET_PRIVREG(ctx);
3343
#else
3344
    if (unlikely(!ctx->supervisor)) {
3345
        RET_PRIVREG(ctx);
3346
        return;
3347
    }
3348
    gen_op_load_gpr_T0(rS(ctx->opcode));
3349
    gen_op_set_T1(SR(ctx->opcode));
3350
    gen_op_store_sr();
3351
    RET_STOP(ctx);
3352
#endif
3353
}
3354

    
3355
/* mtsrin */
3356
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3357
{
3358
#if defined(CONFIG_USER_ONLY)
3359
    RET_PRIVREG(ctx);
3360
#else
3361
    if (unlikely(!ctx->supervisor)) {
3362
        RET_PRIVREG(ctx);
3363
        return;
3364
    }
3365
    gen_op_load_gpr_T0(rS(ctx->opcode));
3366
    gen_op_load_gpr_T1(rB(ctx->opcode));
3367
    gen_op_srli_T1(28);
3368
    gen_op_store_sr();
3369
    RET_STOP(ctx);
3370
#endif
3371
}
3372

    
3373
/***                      Lookaside buffer management                      ***/
3374
/* Optional & supervisor only: */
3375
/* tlbia */
3376
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3377
{
3378
#if defined(CONFIG_USER_ONLY)
3379
    RET_PRIVOPC(ctx);
3380
#else
3381
    if (unlikely(!ctx->supervisor)) {
3382
        if (loglevel != 0)
3383
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3384
        RET_PRIVOPC(ctx);
3385
        return;
3386
    }
3387
    gen_op_tlbia();
3388
    RET_STOP(ctx);
3389
#endif
3390
}
3391

    
3392
/* tlbie */
3393
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3394
{
3395
#if defined(CONFIG_USER_ONLY)
3396
    RET_PRIVOPC(ctx);
3397
#else
3398
    if (unlikely(!ctx->supervisor)) {
3399
        RET_PRIVOPC(ctx);
3400
        return;
3401
    }
3402
    gen_op_load_gpr_T0(rB(ctx->opcode));
3403
#if defined(TARGET_PPC64)
3404
    if (ctx->sf_mode)
3405
        gen_op_tlbie_64();
3406
    else
3407
#endif
3408
        gen_op_tlbie();
3409
    RET_STOP(ctx);
3410
#endif
3411
}
3412

    
3413
/* tlbsync */
3414
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3415
{
3416
#if defined(CONFIG_USER_ONLY)
3417
    RET_PRIVOPC(ctx);
3418
#else
3419
    if (unlikely(!ctx->supervisor)) {
3420
        RET_PRIVOPC(ctx);
3421
        return;
3422
    }
3423
    /* This has no effect: it should ensure that all previous
3424
     * tlbie have completed
3425
     */
3426
    RET_STOP(ctx);
3427
#endif
3428
}
3429

    
3430
#if defined(TARGET_PPC64)
3431
/* slbia */
3432
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3433
{
3434
#if defined(CONFIG_USER_ONLY)
3435
    RET_PRIVOPC(ctx);
3436
#else
3437
    if (unlikely(!ctx->supervisor)) {
3438
        if (loglevel != 0)
3439
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3440
        RET_PRIVOPC(ctx);
3441
        return;
3442
    }
3443
    gen_op_slbia();
3444
    RET_STOP(ctx);
3445
#endif
3446
}
3447

    
3448
/* slbie */
3449
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3450
{
3451
#if defined(CONFIG_USER_ONLY)
3452
    RET_PRIVOPC(ctx);
3453
#else
3454
    if (unlikely(!ctx->supervisor)) {
3455
        RET_PRIVOPC(ctx);
3456
        return;
3457
    }
3458
    gen_op_load_gpr_T0(rB(ctx->opcode));
3459
    gen_op_slbie();
3460
    RET_STOP(ctx);
3461
#endif
3462
}
3463
#endif
3464

    
3465
/***                              External control                         ***/
3466
/* Optional: */
3467
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3468
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3469
#if defined(TARGET_PPC64)
3470
#if defined(CONFIG_USER_ONLY)
3471
static GenOpFunc *gen_op_eciwx[] = {
3472
    &gen_op_eciwx_raw,
3473
    &gen_op_eciwx_le_raw,
3474
    &gen_op_eciwx_64_raw,
3475
    &gen_op_eciwx_le_64_raw,
3476
};
3477
static GenOpFunc *gen_op_ecowx[] = {
3478
    &gen_op_ecowx_raw,
3479
    &gen_op_ecowx_le_raw,
3480
    &gen_op_ecowx_64_raw,
3481
    &gen_op_ecowx_le_64_raw,
3482
};
3483
#else
3484
static GenOpFunc *gen_op_eciwx[] = {
3485
    &gen_op_eciwx_user,
3486
    &gen_op_eciwx_le_user,
3487
    &gen_op_eciwx_kernel,
3488
    &gen_op_eciwx_le_kernel,
3489
    &gen_op_eciwx_64_user,
3490
    &gen_op_eciwx_le_64_user,
3491
    &gen_op_eciwx_64_kernel,
3492
    &gen_op_eciwx_le_64_kernel,
3493
};
3494
static GenOpFunc *gen_op_ecowx[] = {
3495
    &gen_op_ecowx_user,
3496
    &gen_op_ecowx_le_user,
3497
    &gen_op_ecowx_kernel,
3498
    &gen_op_ecowx_le_kernel,
3499
    &gen_op_ecowx_64_user,
3500
    &gen_op_ecowx_le_64_user,
3501
    &gen_op_ecowx_64_kernel,
3502
    &gen_op_ecowx_le_64_kernel,
3503
};
3504
#endif
3505
#else
3506
#if defined(CONFIG_USER_ONLY)
3507
static GenOpFunc *gen_op_eciwx[] = {
3508
    &gen_op_eciwx_raw,
3509
    &gen_op_eciwx_le_raw,
3510
};
3511
static GenOpFunc *gen_op_ecowx[] = {
3512
    &gen_op_ecowx_raw,
3513
    &gen_op_ecowx_le_raw,
3514
};
3515
#else
3516
static GenOpFunc *gen_op_eciwx[] = {
3517
    &gen_op_eciwx_user,
3518
    &gen_op_eciwx_le_user,
3519
    &gen_op_eciwx_kernel,
3520
    &gen_op_eciwx_le_kernel,
3521
};
3522
static GenOpFunc *gen_op_ecowx[] = {
3523
    &gen_op_ecowx_user,
3524
    &gen_op_ecowx_le_user,
3525
    &gen_op_ecowx_kernel,
3526
    &gen_op_ecowx_le_kernel,
3527
};
3528
#endif
3529
#endif
3530

    
3531
/* eciwx */
3532
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3533
{
3534
    /* Should check EAR[E] & alignment ! */
3535
    gen_addr_reg_index(ctx);
3536
    op_eciwx();
3537
    gen_op_store_T0_gpr(rD(ctx->opcode));
3538
}
3539

    
3540
/* ecowx */
3541
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3542
{
3543
    /* Should check EAR[E] & alignment ! */
3544
    gen_addr_reg_index(ctx);
3545
    gen_op_load_gpr_T1(rS(ctx->opcode));
3546
    op_ecowx();
3547
}
3548

    
3549
/* PowerPC 601 specific instructions */
3550
/* abs - abs. */
3551
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3552
{
3553
    gen_op_load_gpr_T0(rA(ctx->opcode));
3554
    gen_op_POWER_abs();
3555
    gen_op_store_T0_gpr(rD(ctx->opcode));
3556
    if (unlikely(Rc(ctx->opcode) != 0))
3557
        gen_set_Rc0(ctx);
3558
}
3559

    
3560
/* abso - abso. */
3561
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3562
{
3563
    gen_op_load_gpr_T0(rA(ctx->opcode));
3564
    gen_op_POWER_abso();
3565
    gen_op_store_T0_gpr(rD(ctx->opcode));
3566
    if (unlikely(Rc(ctx->opcode) != 0))
3567
        gen_set_Rc0(ctx);
3568
}
3569

    
3570
/* clcs */
3571
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR) /* 601 ? */
3572
{
3573
    gen_op_load_gpr_T0(rA(ctx->opcode));
3574
    gen_op_POWER_clcs();
3575
    gen_op_store_T0_gpr(rD(ctx->opcode));
3576
}
3577

    
3578
/* div - div. */
3579
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3580
{
3581
    gen_op_load_gpr_T0(rA(ctx->opcode));
3582
    gen_op_load_gpr_T1(rB(ctx->opcode));
3583
    gen_op_POWER_div();
3584
    gen_op_store_T0_gpr(rD(ctx->opcode));
3585
    if (unlikely(Rc(ctx->opcode) != 0))
3586
        gen_set_Rc0(ctx);
3587
}
3588

    
3589
/* divo - divo. */
3590
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3591
{
3592
    gen_op_load_gpr_T0(rA(ctx->opcode));
3593
    gen_op_load_gpr_T1(rB(ctx->opcode));
3594
    gen_op_POWER_divo();
3595
    gen_op_store_T0_gpr(rD(ctx->opcode));
3596
    if (unlikely(Rc(ctx->opcode) != 0))
3597
        gen_set_Rc0(ctx);
3598
}
3599

    
3600
/* divs - divs. */
3601
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3602
{
3603
    gen_op_load_gpr_T0(rA(ctx->opcode));
3604
    gen_op_load_gpr_T1(rB(ctx->opcode));
3605
    gen_op_POWER_divs();
3606
    gen_op_store_T0_gpr(rD(ctx->opcode));
3607
    if (unlikely(Rc(ctx->opcode) != 0))
3608
        gen_set_Rc0(ctx);
3609
}
3610

    
3611
/* divso - divso. */
3612
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3613
{
3614
    gen_op_load_gpr_T0(rA(ctx->opcode));
3615
    gen_op_load_gpr_T1(rB(ctx->opcode));
3616
    gen_op_POWER_divso();
3617
    gen_op_store_T0_gpr(rD(ctx->opcode));
3618
    if (unlikely(Rc(ctx->opcode) != 0))
3619
        gen_set_Rc0(ctx);
3620
}
3621

    
3622
/* doz - doz. */
3623
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3624
{
3625
    gen_op_load_gpr_T0(rA(ctx->opcode));
3626
    gen_op_load_gpr_T1(rB(ctx->opcode));
3627
    gen_op_POWER_doz();
3628
    gen_op_store_T0_gpr(rD(ctx->opcode));
3629
    if (unlikely(Rc(ctx->opcode) != 0))
3630
        gen_set_Rc0(ctx);
3631
}
3632

    
3633
/* dozo - dozo. */
3634
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3635
{
3636
    gen_op_load_gpr_T0(rA(ctx->opcode));
3637
    gen_op_load_gpr_T1(rB(ctx->opcode));
3638
    gen_op_POWER_dozo();
3639
    gen_op_store_T0_gpr(rD(ctx->opcode));
3640
    if (unlikely(Rc(ctx->opcode) != 0))
3641
        gen_set_Rc0(ctx);
3642
}
3643

    
3644
/* dozi */
3645
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3646
{
3647
    gen_op_load_gpr_T0(rA(ctx->opcode));
3648
    gen_op_set_T1(SIMM(ctx->opcode));
3649
    gen_op_POWER_doz();
3650
    gen_op_store_T0_gpr(rD(ctx->opcode));
3651
}
3652

    
3653
/* As lscbx load from memory byte after byte, it's always endian safe */
3654
#define op_POWER_lscbx(start, ra, rb) \
3655
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3656
#if defined(CONFIG_USER_ONLY)
3657
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3658
    &gen_op_POWER_lscbx_raw,
3659
    &gen_op_POWER_lscbx_raw,
3660
};
3661
#else
3662
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3663
    &gen_op_POWER_lscbx_user,
3664
    &gen_op_POWER_lscbx_user,
3665
    &gen_op_POWER_lscbx_kernel,
3666
    &gen_op_POWER_lscbx_kernel,
3667
};
3668
#endif
3669

    
3670
/* lscbx - lscbx. */
3671
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3672
{
3673
    int ra = rA(ctx->opcode);
3674
    int rb = rB(ctx->opcode);
3675

    
3676
    gen_addr_reg_index(ctx);
3677
    if (ra == 0) {
3678
        ra = rb;
3679
    }
3680
    /* NIP cannot be restored if the memory exception comes from an helper */
3681
    gen_update_nip(ctx, ctx->nip - 4);
3682
    gen_op_load_xer_bc();
3683
    gen_op_load_xer_cmp();
3684
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3685
    gen_op_store_xer_bc();
3686
    if (unlikely(Rc(ctx->opcode) != 0))
3687
        gen_set_Rc0(ctx);
3688
}
3689

    
3690
/* maskg - maskg. */
3691
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3692
{
3693
    gen_op_load_gpr_T0(rS(ctx->opcode));
3694
    gen_op_load_gpr_T1(rB(ctx->opcode));
3695
    gen_op_POWER_maskg();
3696
    gen_op_store_T0_gpr(rA(ctx->opcode));
3697
    if (unlikely(Rc(ctx->opcode) != 0))
3698
        gen_set_Rc0(ctx);
3699
}
3700

    
3701
/* maskir - maskir. */
3702
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3703
{
3704
    gen_op_load_gpr_T0(rA(ctx->opcode));
3705
    gen_op_load_gpr_T1(rS(ctx->opcode));
3706
    gen_op_load_gpr_T2(rB(ctx->opcode));
3707
    gen_op_POWER_maskir();
3708
    gen_op_store_T0_gpr(rA(ctx->opcode));
3709
    if (unlikely(Rc(ctx->opcode) != 0))
3710
        gen_set_Rc0(ctx);
3711
}
3712

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

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

    
3735
/* nabs - nabs. */
3736
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
3737
{
3738
    gen_op_load_gpr_T0(rA(ctx->opcode));
3739
    gen_op_POWER_nabs();
3740
    gen_op_store_T0_gpr(rD(ctx->opcode));
3741
    if (unlikely(Rc(ctx->opcode) != 0))
3742
        gen_set_Rc0(ctx);
3743
}
3744

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

    
3755
/* rlmi - rlmi. */
3756
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3757
{
3758
    uint32_t mb, me;
3759

    
3760
    mb = MB(ctx->opcode);
3761
    me = ME(ctx->opcode);
3762
    gen_op_load_gpr_T0(rS(ctx->opcode));
3763
    gen_op_load_gpr_T1(rA(ctx->opcode));
3764
    gen_op_load_gpr_T2(rB(ctx->opcode));
3765
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
3766
    gen_op_store_T0_gpr(rA(ctx->opcode));
3767
    if (unlikely(Rc(ctx->opcode) != 0))
3768
        gen_set_Rc0(ctx);
3769
}
3770

    
3771
/* rrib - rrib. */
3772
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
3773
{
3774
    gen_op_load_gpr_T0(rS(ctx->opcode));
3775
    gen_op_load_gpr_T1(rA(ctx->opcode));
3776
    gen_op_load_gpr_T2(rB(ctx->opcode));
3777
    gen_op_POWER_rrib();
3778
    gen_op_store_T0_gpr(rA(ctx->opcode));
3779
    if (unlikely(Rc(ctx->opcode) != 0))
3780
        gen_set_Rc0(ctx);
3781
}
3782

    
3783
/* sle - sle. */
3784
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
3785
{
3786
    gen_op_load_gpr_T0(rS(ctx->opcode));
3787
    gen_op_load_gpr_T1(rB(ctx->opcode));
3788
    gen_op_POWER_sle();
3789
    gen_op_store_T0_gpr(rA(ctx->opcode));
3790
    if (unlikely(Rc(ctx->opcode) != 0))
3791
        gen_set_Rc0(ctx);
3792
}
3793

    
3794
/* sleq - sleq. */
3795
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
3796
{
3797
    gen_op_load_gpr_T0(rS(ctx->opcode));
3798
    gen_op_load_gpr_T1(rB(ctx->opcode));
3799
    gen_op_POWER_sleq();
3800
    gen_op_store_T0_gpr(rA(ctx->opcode));
3801
    if (unlikely(Rc(ctx->opcode) != 0))
3802
        gen_set_Rc0(ctx);
3803
}
3804

    
3805
/* sliq - sliq. */
3806
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
3807
{
3808
    gen_op_load_gpr_T0(rS(ctx->opcode));
3809
    gen_op_set_T1(SH(ctx->opcode));
3810
    gen_op_POWER_sle();
3811
    gen_op_store_T0_gpr(rA(ctx->opcode));
3812
    if (unlikely(Rc(ctx->opcode) != 0))
3813
        gen_set_Rc0(ctx);
3814
}
3815

    
3816
/* slliq - slliq. */
3817
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
3818
{
3819
    gen_op_load_gpr_T0(rS(ctx->opcode));
3820
    gen_op_set_T1(SH(ctx->opcode));
3821
    gen_op_POWER_sleq();
3822
    gen_op_store_T0_gpr(rA(ctx->opcode));
3823
    if (unlikely(Rc(ctx->opcode) != 0))
3824
        gen_set_Rc0(ctx);
3825
}
3826

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

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

    
3849
/* sraiq - sraiq. */
3850
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
3851
{
3852
    gen_op_load_gpr_T0(rS(ctx->opcode));
3853
    gen_op_set_T1(SH(ctx->opcode));
3854
    gen_op_POWER_sraq();
3855
    gen_op_store_T0_gpr(rA(ctx->opcode));
3856
    if (unlikely(Rc(ctx->opcode) != 0))
3857
        gen_set_Rc0(ctx);
3858
}
3859

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

    
3871
/* sre - sre. */
3872
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
3873
{
3874
    gen_op_load_gpr_T0(rS(ctx->opcode));
3875
    gen_op_load_gpr_T1(rB(ctx->opcode));
3876
    gen_op_POWER_sre();
3877
    gen_op_store_T0_gpr(rA(ctx->opcode));
3878
    if (unlikely(Rc(ctx->opcode) != 0))
3879
        gen_set_Rc0(ctx);
3880
}
3881

    
3882
/* srea - srea. */
3883
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
3884
{
3885
    gen_op_load_gpr_T0(rS(ctx->opcode));
3886
    gen_op_load_gpr_T1(rB(ctx->opcode));
3887
    gen_op_POWER_srea();
3888
    gen_op_store_T0_gpr(rA(ctx->opcode));
3889
    if (unlikely(Rc(ctx->opcode) != 0))
3890
        gen_set_Rc0(ctx);
3891
}
3892

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

    
3904
/* sriq */
3905
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
3906
{
3907
    gen_op_load_gpr_T0(rS(ctx->opcode));
3908
    gen_op_set_T1(SH(ctx->opcode));
3909
    gen_op_POWER_srq();
3910
    gen_op_store_T0_gpr(rA(ctx->opcode));
3911
    if (unlikely(Rc(ctx->opcode) != 0))
3912
        gen_set_Rc0(ctx);
3913
}
3914

    
3915
/* srliq */
3916
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
3917
{
3918
    gen_op_load_gpr_T0(rS(ctx->opcode));
3919
    gen_op_load_gpr_T1(rB(ctx->opcode));
3920
    gen_op_set_T1(SH(ctx->opcode));
3921
    gen_op_POWER_srlq();
3922
    gen_op_store_T0_gpr(rA(ctx->opcode));
3923
    if (unlikely(Rc(ctx->opcode) != 0))
3924
        gen_set_Rc0(ctx);
3925
}
3926

    
3927
/* srlq */
3928
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
3929
{
3930
    gen_op_load_gpr_T0(rS(ctx->opcode));
3931
    gen_op_load_gpr_T1(rB(ctx->opcode));
3932
    gen_op_POWER_srlq();
3933
    gen_op_store_T0_gpr(rA(ctx->opcode));
3934
    if (unlikely(Rc(ctx->opcode) != 0))
3935
        gen_set_Rc0(ctx);
3936
}
3937

    
3938
/* srq */
3939
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
3940
{
3941
    gen_op_load_gpr_T0(rS(ctx->opcode));
3942
    gen_op_load_gpr_T1(rB(ctx->opcode));
3943
    gen_op_POWER_srq();
3944
    gen_op_store_T0_gpr(rA(ctx->opcode));
3945
    if (unlikely(Rc(ctx->opcode) != 0))
3946
        gen_set_Rc0(ctx);
3947
}
3948

    
3949
/* PowerPC 602 specific instructions */
3950
/* dsa  */
3951
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
3952
{
3953
    /* XXX: TODO */
3954
    RET_INVAL(ctx);
3955
}
3956

    
3957
/* esa */
3958
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
3959
{
3960
    /* XXX: TODO */
3961
    RET_INVAL(ctx);
3962
}
3963

    
3964
/* mfrom */
3965
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
3966
{
3967
#if defined(CONFIG_USER_ONLY)
3968
    RET_PRIVOPC(ctx);
3969
#else
3970
    if (unlikely(!ctx->supervisor)) {
3971
        RET_PRIVOPC(ctx);
3972
        return;
3973
    }
3974
    gen_op_load_gpr_T0(rA(ctx->opcode));
3975
    gen_op_602_mfrom();
3976
    gen_op_store_T0_gpr(rD(ctx->opcode));
3977
#endif
3978
}
3979

    
3980
/* 602 - 603 - G2 TLB management */
3981
/* tlbld */
3982
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
3983
{
3984
#if defined(CONFIG_USER_ONLY)
3985
    RET_PRIVOPC(ctx);
3986
#else
3987
    if (unlikely(!ctx->supervisor)) {
3988
        RET_PRIVOPC(ctx);
3989
        return;
3990
    }
3991
    gen_op_load_gpr_T0(rB(ctx->opcode));
3992
    gen_op_6xx_tlbld();
3993
    RET_STOP(ctx);
3994
#endif
3995
}
3996

    
3997
/* tlbli */
3998
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
3999
{
4000
#if defined(CONFIG_USER_ONLY)
4001
    RET_PRIVOPC(ctx);
4002
#else
4003
    if (unlikely(!ctx->supervisor)) {
4004
        RET_PRIVOPC(ctx);
4005
        return;
4006
    }
4007
    gen_op_load_gpr_T0(rB(ctx->opcode));
4008
    gen_op_6xx_tlbli();
4009
    RET_STOP(ctx);
4010
#endif
4011
}
4012

    
4013
/* POWER instructions not in PowerPC 601 */
4014
/* clf */
4015
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4016
{
4017
    /* Cache line flush: implemented as no-op */
4018
}
4019

    
4020
/* cli */
4021
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4022
{
4023
    /* Cache line invalidate: privileged and treated as no-op */
4024
#if defined(CONFIG_USER_ONLY)
4025
    RET_PRIVOPC(ctx);
4026
#else
4027
    if (unlikely(!ctx->supervisor)) {
4028
        RET_PRIVOPC(ctx);
4029
        return;
4030
    }
4031
#endif
4032
}
4033

    
4034
/* dclst */
4035
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4036
{
4037
    /* Data cache line store: treated as no-op */
4038
}
4039

    
4040
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4041
{
4042
#if defined(CONFIG_USER_ONLY)
4043
    RET_PRIVOPC(ctx);
4044
#else
4045
    if (unlikely(!ctx->supervisor)) {
4046
        RET_PRIVOPC(ctx);
4047
        return;
4048
    }
4049
    int ra = rA(ctx->opcode);
4050
    int rd = rD(ctx->opcode);
4051

    
4052
    gen_addr_reg_index(ctx);
4053
    gen_op_POWER_mfsri();
4054
    gen_op_store_T0_gpr(rd);
4055
    if (ra != 0 && ra != rd)
4056
        gen_op_store_T1_gpr(ra);
4057
#endif
4058
}
4059

    
4060
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4061
{
4062
#if defined(CONFIG_USER_ONLY)
4063
    RET_PRIVOPC(ctx);
4064
#else
4065
    if (unlikely(!ctx->supervisor)) {
4066
        RET_PRIVOPC(ctx);
4067
        return;
4068
    }
4069
    gen_addr_reg_index(ctx);
4070
    gen_op_POWER_rac();
4071
    gen_op_store_T0_gpr(rD(ctx->opcode));
4072
#endif
4073
}
4074

    
4075
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4076
{
4077
#if defined(CONFIG_USER_ONLY)
4078
    RET_PRIVOPC(ctx);
4079
#else
4080
    if (unlikely(!ctx->supervisor)) {
4081
        RET_PRIVOPC(ctx);
4082
        return;
4083
    }
4084
    gen_op_POWER_rfsvc();
4085
    RET_CHG_FLOW(ctx);
4086
#endif
4087
}
4088

    
4089
/* svc is not implemented for now */
4090

    
4091
/* POWER2 specific instructions */
4092
/* Quad manipulation (load/store two floats at a time) */
4093
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4094
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4095
#if defined(CONFIG_USER_ONLY)
4096
static GenOpFunc *gen_op_POWER2_lfq[] = {
4097
    &gen_op_POWER2_lfq_le_raw,
4098
    &gen_op_POWER2_lfq_raw,
4099
};
4100
static GenOpFunc *gen_op_POWER2_stfq[] = {
4101
    &gen_op_POWER2_stfq_le_raw,
4102
    &gen_op_POWER2_stfq_raw,
4103
};
4104
#else
4105
static GenOpFunc *gen_op_POWER2_lfq[] = {
4106
    &gen_op_POWER2_lfq_le_user,
4107
    &gen_op_POWER2_lfq_user,
4108
    &gen_op_POWER2_lfq_le_kernel,
4109
    &gen_op_POWER2_lfq_kernel,
4110
};
4111
static GenOpFunc *gen_op_POWER2_stfq[] = {
4112
    &gen_op_POWER2_stfq_le_user,
4113
    &gen_op_POWER2_stfq_user,
4114
    &gen_op_POWER2_stfq_le_kernel,
4115
    &gen_op_POWER2_stfq_kernel,
4116
};
4117
#endif
4118

    
4119
/* lfq */
4120
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4121
{
4122
    /* NIP cannot be restored if the memory exception comes from an helper */
4123
    gen_update_nip(ctx, ctx->nip - 4);
4124
    gen_addr_imm_index(ctx, 0);
4125
    op_POWER2_lfq();
4126
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4127
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4128
}
4129

    
4130
/* lfqu */
4131
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4132
{
4133
    int ra = rA(ctx->opcode);
4134

    
4135
    /* NIP cannot be restored if the memory exception comes from an helper */
4136
    gen_update_nip(ctx, ctx->nip - 4);
4137
    gen_addr_imm_index(ctx, 0);
4138
    op_POWER2_lfq();
4139
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4140
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4141
    if (ra != 0)
4142
        gen_op_store_T0_gpr(ra);
4143
}
4144

    
4145
/* lfqux */
4146
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4147
{
4148
    int ra = rA(ctx->opcode);
4149

    
4150
    /* NIP cannot be restored if the memory exception comes from an helper */
4151
    gen_update_nip(ctx, ctx->nip - 4);
4152
    gen_addr_reg_index(ctx);
4153
    op_POWER2_lfq();
4154
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4155
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4156
    if (ra != 0)
4157
        gen_op_store_T0_gpr(ra);
4158
}
4159

    
4160
/* lfqx */
4161
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4162
{
4163
    /* NIP cannot be restored if the memory exception comes from an helper */
4164
    gen_update_nip(ctx, ctx->nip - 4);
4165
    gen_addr_reg_index(ctx);
4166
    op_POWER2_lfq();
4167
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4168
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4169
}
4170

    
4171
/* stfq */
4172
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4173
{
4174
    /* NIP cannot be restored if the memory exception comes from an helper */
4175
    gen_update_nip(ctx, ctx->nip - 4);
4176
    gen_addr_imm_index(ctx, 0);
4177
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4178
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4179
    op_POWER2_stfq();
4180
}
4181

    
4182
/* stfqu */
4183
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4184
{
4185
    int ra = rA(ctx->opcode);
4186

    
4187
    /* NIP cannot be restored if the memory exception comes from an helper */
4188
    gen_update_nip(ctx, ctx->nip - 4);
4189
    gen_addr_imm_index(ctx, 0);
4190
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4191
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4192
    op_POWER2_stfq();
4193
    if (ra != 0)
4194
        gen_op_store_T0_gpr(ra);
4195
}
4196

    
4197
/* stfqux */
4198
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4199
{
4200
    int ra = rA(ctx->opcode);
4201

    
4202
    /* NIP cannot be restored if the memory exception comes from an helper */
4203
    gen_update_nip(ctx, ctx->nip - 4);
4204
    gen_addr_reg_index(ctx);
4205
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4206
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4207
    op_POWER2_stfq();
4208
    if (ra != 0)
4209
        gen_op_store_T0_gpr(ra);
4210
}
4211

    
4212
/* stfqx */
4213
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4214
{
4215
    /* NIP cannot be restored if the memory exception comes from an helper */
4216
    gen_update_nip(ctx, ctx->nip - 4);
4217
    gen_addr_reg_index(ctx);
4218
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4219
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4220
    op_POWER2_stfq();
4221
}
4222

    
4223
/* BookE specific instructions */
4224
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE)
4225
{
4226
    /* XXX: TODO */
4227
    RET_INVAL(ctx);
4228
}
4229

    
4230
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE)
4231
{
4232
#if defined(CONFIG_USER_ONLY)
4233
    RET_PRIVOPC(ctx);
4234
#else
4235
    if (unlikely(!ctx->supervisor)) {
4236
        RET_PRIVOPC(ctx);
4237
        return;
4238
    }
4239
    gen_addr_reg_index(ctx);
4240
    /* Use the same micro-ops as for tlbie */
4241
#if defined(TARGET_PPC64)
4242
    if (ctx->sf_mode)
4243
        gen_op_tlbie_64();
4244
    else
4245
#endif
4246
        gen_op_tlbie();
4247
    RET_STOP(ctx);
4248
#endif
4249
}
4250

    
4251
/* All 405 MAC instructions are translated here */
4252
static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
4253
                                         int ra, int rb, int rt, int Rc)
4254
{
4255
    gen_op_load_gpr_T0(ra);
4256
    gen_op_load_gpr_T1(rb);
4257
    switch (opc3 & 0x0D) {
4258
    case 0x05:
4259
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4260
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4261
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4262
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4263
        /* mulchw - mulchw. */
4264
        gen_op_405_mulchw();
4265
        break;
4266
    case 0x04:
4267
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4268
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4269
        /* mulchwu - mulchwu. */
4270
        gen_op_405_mulchwu();
4271
        break;
4272
    case 0x01:
4273
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4274
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4275
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4276
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4277
        /* mulhhw - mulhhw. */
4278
        gen_op_405_mulhhw();
4279
        break;
4280
    case 0x00:
4281
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4282
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4283
        /* mulhhwu - mulhhwu. */
4284
        gen_op_405_mulhhwu();
4285
        break;
4286
    case 0x0D:
4287
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4288
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4289
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4290
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4291
        /* mullhw - mullhw. */
4292
        gen_op_405_mullhw();
4293
        break;
4294
    case 0x0C:
4295
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4296
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4297
        /* mullhwu - mullhwu. */
4298
        gen_op_405_mullhwu();
4299
        break;
4300
    }
4301
    if (opc2 & 0x02) {
4302
        /* nmultiply-and-accumulate (0x0E) */
4303
        gen_op_neg();
4304
    }
4305
    if (opc2 & 0x04) {
4306
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4307
        gen_op_load_gpr_T2(rt);
4308
        gen_op_move_T1_T0();
4309
        gen_op_405_add_T0_T2();
4310
    }
4311
    if (opc3 & 0x10) {
4312
        /* Check overflow */
4313
        if (opc3 & 0x01)
4314
            gen_op_405_check_ov();
4315
        else
4316
            gen_op_405_check_ovu();
4317
    }
4318
    if (opc3 & 0x02) {
4319
        /* Saturate */
4320
        if (opc3 & 0x01)
4321
            gen_op_405_check_sat();
4322
        else
4323
            gen_op_405_check_satu();
4324
    }
4325
    gen_op_store_T0_gpr(rt);
4326
    if (unlikely(Rc) != 0) {
4327
        /* Update Rc0 */
4328
        gen_set_Rc0(ctx);
4329
    }
4330
}
4331

    
4332
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4333
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4334
{                                                                             \
4335
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4336
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4337
}
4338

    
4339
/* macchw    - macchw.    */
4340
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4341
/* macchwo   - macchwo.   */
4342
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4343
/* macchws   - macchws.   */
4344
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4345
/* macchwso  - macchwso.  */
4346
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4347
/* macchwsu  - macchwsu.  */
4348
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4349
/* macchwsuo - macchwsuo. */
4350
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4351
/* macchwu   - macchwu.   */
4352
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4353
/* macchwuo  - macchwuo.  */
4354
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4355
/* machhw    - machhw.    */
4356
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4357
/* machhwo   - machhwo.   */
4358
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4359
/* machhws   - machhws.   */
4360
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4361
/* machhwso  - machhwso.  */
4362
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4363
/* machhwsu  - machhwsu.  */
4364
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4365
/* machhwsuo - machhwsuo. */
4366
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4367
/* machhwu   - machhwu.   */
4368
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4369
/* machhwuo  - machhwuo.  */
4370
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4371
/* maclhw    - maclhw.    */
4372
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4373
/* maclhwo   - maclhwo.   */
4374
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4375
/* maclhws   - maclhws.   */
4376
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4377
/* maclhwso  - maclhwso.  */
4378
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4379
/* maclhwu   - maclhwu.   */
4380
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4381
/* maclhwuo  - maclhwuo.  */
4382
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4383
/* maclhwsu  - maclhwsu.  */
4384
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4385
/* maclhwsuo - maclhwsuo. */
4386
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4387
/* nmacchw   - nmacchw.   */
4388
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4389
/* nmacchwo  - nmacchwo.  */
4390
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4391
/* nmacchws  - nmacchws.  */
4392
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4393
/* nmacchwso - nmacchwso. */
4394
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4395
/* nmachhw   - nmachhw.   */
4396
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4397
/* nmachhwo  - nmachhwo.  */
4398
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4399
/* nmachhws  - nmachhws.  */
4400
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4401
/* nmachhwso - nmachhwso. */
4402
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4403
/* nmaclhw   - nmaclhw.   */
4404
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4405
/* nmaclhwo  - nmaclhwo.  */
4406
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4407
/* nmaclhws  - nmaclhws.  */
4408
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4409
/* nmaclhwso - nmaclhwso. */
4410
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4411

    
4412
/* mulchw  - mulchw.  */
4413
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4414
/* mulchwu - mulchwu. */
4415
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4416
/* mulhhw  - mulhhw.  */
4417
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4418
/* mulhhwu - mulhhwu. */
4419
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4420
/* mullhw  - mullhw.  */
4421
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4422
/* mullhwu - mullhwu. */
4423
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4424

    
4425
/* mfdcr */
4426
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4427
{
4428
#if defined(CONFIG_USER_ONLY)
4429
    RET_PRIVREG(ctx);
4430
#else
4431
    uint32_t dcrn = SPR(ctx->opcode);
4432

    
4433
    if (unlikely(!ctx->supervisor)) {
4434
        RET_PRIVREG(ctx);
4435
        return;
4436
    }
4437
    gen_op_set_T0(dcrn);
4438
    gen_op_load_dcr();
4439
    gen_op_store_T0_gpr(rD(ctx->opcode));
4440
#endif
4441
}
4442

    
4443
/* mtdcr */
4444
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4445
{
4446
#if defined(CONFIG_USER_ONLY)
4447
    RET_PRIVREG(ctx);
4448
#else
4449
    uint32_t dcrn = SPR(ctx->opcode);
4450

    
4451
    if (unlikely(!ctx->supervisor)) {
4452
        RET_PRIVREG(ctx);
4453
        return;
4454
    }
4455
    gen_op_set_T0(dcrn);
4456
    gen_op_load_gpr_T1(rS(ctx->opcode));
4457
    gen_op_store_dcr();
4458
#endif
4459
}
4460

    
4461
/* mfdcrx */
4462
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000001, PPC_BOOKE)
4463
{
4464
#if defined(CONFIG_USER_ONLY)
4465
    RET_PRIVREG(ctx);
4466
#else
4467
    if (unlikely(!ctx->supervisor)) {
4468
        RET_PRIVREG(ctx);
4469
        return;
4470
    }
4471
    gen_op_load_gpr_T0(rA(ctx->opcode));
4472
    gen_op_load_dcr();
4473
    gen_op_store_T0_gpr(rD(ctx->opcode));
4474
#endif
4475
}
4476

    
4477
/* mtdcrx */
4478
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000001, PPC_BOOKE)
4479
{
4480
#if defined(CONFIG_USER_ONLY)
4481
    RET_PRIVREG(ctx);
4482
#else
4483
    if (unlikely(!ctx->supervisor)) {
4484
        RET_PRIVREG(ctx);
4485
        return;
4486
    }
4487
    gen_op_load_gpr_T0(rA(ctx->opcode));
4488
    gen_op_load_gpr_T1(rS(ctx->opcode));
4489
    gen_op_store_dcr();
4490
#endif
4491
}
4492

    
4493
/* dccci */
4494
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4495
{
4496
#if defined(CONFIG_USER_ONLY)
4497
    RET_PRIVOPC(ctx);
4498
#else
4499
    if (unlikely(!ctx->supervisor)) {
4500
        RET_PRIVOPC(ctx);
4501
        return;
4502
    }
4503
    /* interpreted as no-op */
4504
#endif
4505
}
4506

    
4507
/* dcread */
4508
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4509
{
4510
#if defined(CONFIG_USER_ONLY)
4511
    RET_PRIVOPC(ctx);
4512
#else
4513
    if (unlikely(!ctx->supervisor)) {
4514
        RET_PRIVOPC(ctx);
4515
        return;
4516
    }
4517
    gen_addr_reg_index(ctx);
4518
    op_ldst(lwz);
4519
    gen_op_store_T0_gpr(rD(ctx->opcode));
4520
#endif
4521
}
4522

    
4523
/* icbt */
4524
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC)
4525
{
4526
    /* interpreted as no-op */
4527
    /* XXX: specification say this is treated as a load by the MMU
4528
     *      but does not generate any exception
4529
     */
4530
}
4531

    
4532
/* iccci */
4533
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4534
{
4535
#if defined(CONFIG_USER_ONLY)
4536
    RET_PRIVOPC(ctx);
4537
#else
4538
    if (unlikely(!ctx->supervisor)) {
4539
        RET_PRIVOPC(ctx);
4540
        return;
4541
    }
4542
    /* interpreted as no-op */
4543
#endif
4544
}
4545

    
4546
/* icread */
4547
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4548
{
4549
#if defined(CONFIG_USER_ONLY)
4550
    RET_PRIVOPC(ctx);
4551
#else
4552
    if (unlikely(!ctx->supervisor)) {
4553
        RET_PRIVOPC(ctx);
4554
        return;
4555
    }
4556
    /* interpreted as no-op */
4557
#endif
4558
}
4559

    
4560
/* rfci (supervisor only) */
4561
GEN_HANDLER(rfci_40x, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4562
{
4563
#if defined(CONFIG_USER_ONLY)
4564
    RET_PRIVOPC(ctx);
4565
#else
4566
    if (unlikely(!ctx->supervisor)) {
4567
        RET_PRIVOPC(ctx);
4568
        return;
4569
    }
4570
    /* Restore CPU state */
4571
    gen_op_40x_rfci();
4572
    RET_CHG_FLOW(ctx);
4573
#endif
4574
}
4575

    
4576
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4577
{
4578
#if defined(CONFIG_USER_ONLY)
4579
    RET_PRIVOPC(ctx);
4580
#else
4581
    if (unlikely(!ctx->supervisor)) {
4582
        RET_PRIVOPC(ctx);
4583
        return;
4584
    }
4585
    /* Restore CPU state */
4586
    gen_op_rfci();
4587
    RET_CHG_FLOW(ctx);
4588
#endif
4589
}
4590

    
4591
/* BookE specific */
4592
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE)
4593
{
4594
#if defined(CONFIG_USER_ONLY)
4595
    RET_PRIVOPC(ctx);
4596
#else
4597
    if (unlikely(!ctx->supervisor)) {
4598
        RET_PRIVOPC(ctx);
4599
        return;
4600
    }
4601
    /* Restore CPU state */
4602
    gen_op_rfdi();
4603
    RET_CHG_FLOW(ctx);
4604
#endif
4605
}
4606

    
4607
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_BOOKE)
4608
{
4609
#if defined(CONFIG_USER_ONLY)
4610
    RET_PRIVOPC(ctx);
4611
#else
4612
    if (unlikely(!ctx->supervisor)) {
4613
        RET_PRIVOPC(ctx);
4614
        return;
4615
    }
4616
    /* Restore CPU state */
4617
    gen_op_rfmci();
4618
    RET_CHG_FLOW(ctx);
4619
#endif
4620
}
4621
/* TLB management - PowerPC 405 implementation */
4622
/* tlbre */
4623
GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC)
4624
{
4625
#if defined(CONFIG_USER_ONLY)
4626
    RET_PRIVOPC(ctx);
4627
#else
4628
    if (unlikely(!ctx->supervisor)) {
4629
        RET_PRIVOPC(ctx);
4630
        return;
4631
    }
4632
    switch (rB(ctx->opcode)) {
4633
    case 0:
4634
        gen_op_load_gpr_T0(rA(ctx->opcode));
4635
        gen_op_4xx_tlbre_hi();
4636
        gen_op_store_T0_gpr(rD(ctx->opcode));
4637
        break;
4638
    case 1:
4639
        gen_op_load_gpr_T0(rA(ctx->opcode));
4640
        gen_op_4xx_tlbre_lo();
4641
        gen_op_store_T0_gpr(rD(ctx->opcode));
4642
        break;
4643
    default:
4644
        RET_INVAL(ctx);
4645
        break;
4646
    }
4647
#endif
4648
}
4649

    
4650
/* tlbsx - tlbsx. */
4651
GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC)
4652
{
4653
#if defined(CONFIG_USER_ONLY)
4654
    RET_PRIVOPC(ctx);
4655
#else
4656
    if (unlikely(!ctx->supervisor)) {
4657
        RET_PRIVOPC(ctx);
4658
        return;
4659
    }
4660
    gen_addr_reg_index(ctx);
4661
    if (Rc(ctx->opcode))
4662
        gen_op_4xx_tlbsx_();
4663
    else
4664
        gen_op_4xx_tlbsx();
4665
    gen_op_store_T0_gpr(rD(ctx->opcode));
4666
#endif
4667
}
4668

    
4669
/* tlbwe */
4670
GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC)
4671
{
4672
#if defined(CONFIG_USER_ONLY)
4673
    RET_PRIVOPC(ctx);
4674
#else
4675
    if (unlikely(!ctx->supervisor)) {
4676
        RET_PRIVOPC(ctx);
4677
        return;
4678
    }
4679
    switch (rB(ctx->opcode)) {
4680
    case 0:
4681
        gen_op_load_gpr_T0(rA(ctx->opcode));
4682
        gen_op_load_gpr_T1(rS(ctx->opcode));
4683
        gen_op_4xx_tlbwe_hi();
4684
        break;
4685
    case 1:
4686
        gen_op_load_gpr_T0(rA(ctx->opcode));
4687
        gen_op_load_gpr_T1(rS(ctx->opcode));
4688
        gen_op_4xx_tlbwe_lo();
4689
        break;
4690
    default:
4691
        RET_INVAL(ctx);
4692
        break;
4693
    }
4694
#endif
4695
}
4696

    
4697
/* wrtee */
4698
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4699
{
4700
#if defined(CONFIG_USER_ONLY)
4701
    RET_PRIVOPC(ctx);
4702
#else
4703
    if (unlikely(!ctx->supervisor)) {
4704
        RET_PRIVOPC(ctx);
4705
        return;
4706
    }
4707
    gen_op_load_gpr_T0(rD(ctx->opcode));
4708
    gen_op_wrte();
4709
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4710
#endif
4711
}
4712

    
4713
/* wrteei */
4714
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4715
{
4716
#if defined(CONFIG_USER_ONLY)
4717
    RET_PRIVOPC(ctx);
4718
#else
4719
    if (unlikely(!ctx->supervisor)) {
4720
        RET_PRIVOPC(ctx);
4721
        return;
4722
    }
4723
    gen_op_set_T0(ctx->opcode & 0x00010000);
4724
    gen_op_wrte();
4725
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4726
#endif
4727
}
4728

    
4729
/* PowerPC 440 specific instructions */
4730
/* dlmzb */
4731
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
4732
{
4733
    gen_op_load_gpr_T0(rS(ctx->opcode));
4734
    gen_op_load_gpr_T1(rB(ctx->opcode));
4735
    gen_op_440_dlmzb();
4736
    gen_op_store_T0_gpr(rA(ctx->opcode));
4737
    gen_op_store_xer_bc();
4738
    if (Rc(ctx->opcode)) {
4739
        gen_op_440_dlmzb_update_Rc();
4740
        gen_op_store_T0_crf(0);
4741
    }
4742
}
4743

    
4744
/* mbar replaces eieio on 440 */
4745
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
4746
{
4747
    /* interpreted as no-op */
4748
}
4749

    
4750
/* msync replaces sync on 440 */
4751
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
4752
{
4753
    /* interpreted as no-op */
4754
}
4755

    
4756
/* icbt */
4757
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
4758
{
4759
    /* interpreted as no-op */
4760
    /* XXX: specification say this is treated as a load by the MMU
4761
     *      but does not generate any exception
4762
     */
4763
}
4764

    
4765
#if defined(TARGET_PPCEMB)
4766
/***                           SPE extension                               ***/
4767

    
4768
/* Register moves */
4769
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
4770
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
4771
#if 0 // unused
4772
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
4773
#endif
4774

    
4775
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
4776
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
4777
#if 0 // unused
4778
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
4779
#endif
4780

    
4781
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
4782
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
4783
{                                                                             \
4784
    if (Rc(ctx->opcode))                                                      \
4785
        gen_##name1(ctx);                                                     \
4786
    else                                                                      \
4787
        gen_##name0(ctx);                                                     \
4788
}
4789

    
4790
/* Handler for undefined SPE opcodes */
4791
static inline void gen_speundef (DisasContext *ctx)
4792
{
4793
    RET_INVAL(ctx);
4794
}
4795

    
4796
/* SPE load and stores */
4797
static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
4798
{
4799
    target_long simm = rB(ctx->opcode);
4800

    
4801
    if (rA(ctx->opcode) == 0) {
4802
        gen_set_T0(simm << sh);
4803
    } else {
4804
        gen_op_load_gpr_T0(rA(ctx->opcode));
4805
        if (likely(simm != 0))
4806
            gen_op_addi(simm << sh);
4807
    }
4808
}
4809

    
4810
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
4811
#if defined(CONFIG_USER_ONLY)
4812
#if defined(TARGET_PPC64)
4813
#define OP_SPE_LD_TABLE(name)                                                 \
4814
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4815
    &gen_op_spe_l##name##_raw,                                                \
4816
    &gen_op_spe_l##name##_le_raw,                                             \
4817
    &gen_op_spe_l##name##_64_raw,                                             \
4818
    &gen_op_spe_l##name##_le_64_raw,                                          \
4819
};
4820
#define OP_SPE_ST_TABLE(name)                                                 \
4821
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4822
    &gen_op_spe_st##name##_raw,                                               \
4823
    &gen_op_spe_st##name##_le_raw,                                            \
4824
    &gen_op_spe_st##name##_64_raw,                                            \
4825
    &gen_op_spe_st##name##_le_64_raw,                                         \
4826
};
4827
#else /* defined(TARGET_PPC64) */
4828
#define OP_SPE_LD_TABLE(name)                                                 \
4829
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4830
    &gen_op_spe_l##name##_raw,                                                \
4831
    &gen_op_spe_l##name##_le_raw,                                             \
4832
};
4833
#define OP_SPE_ST_TABLE(name)                                                 \
4834
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4835
    &gen_op_spe_st##name##_raw,                                               \
4836
    &gen_op_spe_st##name##_le_raw,                                            \
4837
};
4838
#endif /* defined(TARGET_PPC64) */
4839
#else /* defined(CONFIG_USER_ONLY) */
4840
#if defined(TARGET_PPC64)
4841
#define OP_SPE_LD_TABLE(name)                                                 \
4842
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4843
    &gen_op_spe_l##name##_user,                                               \
4844
    &gen_op_spe_l##name##_le_user,                                            \
4845
    &gen_op_spe_l##name##_kernel,                                             \
4846
    &gen_op_spe_l##name##_le_kernel,                                          \
4847
    &gen_op_spe_l##name##_64_user,                                            \
4848
    &gen_op_spe_l##name##_le_64_user,                                         \
4849
    &gen_op_spe_l##name##_64_kernel,                                          \
4850
    &gen_op_spe_l##name##_le_64_kernel,                                       \
4851
};
4852
#define OP_SPE_ST_TABLE(name)                                                 \
4853
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4854
    &gen_op_spe_st##name##_user,                                              \
4855
    &gen_op_spe_st##name##_le_user,                                           \
4856
    &gen_op_spe_st##name##_kernel,                                            \
4857
    &gen_op_spe_st##name##_le_kernel,                                         \
4858
    &gen_op_spe_st##name##_64_user,                                           \
4859
    &gen_op_spe_st##name##_le_64_user,                                        \
4860
    &gen_op_spe_st##name##_64_kernel,                                         \
4861
    &gen_op_spe_st##name##_le_64_kernel,                                      \
4862
};
4863
#else /* defined(TARGET_PPC64) */
4864
#define OP_SPE_LD_TABLE(name)                                                 \
4865
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4866
    &gen_op_spe_l##name##_user,                                               \
4867
    &gen_op_spe_l##name##_le_user,                                            \
4868
    &gen_op_spe_l##name##_kernel,                                             \
4869
    &gen_op_spe_l##name##_le_kernel,                                          \
4870
};
4871
#define OP_SPE_ST_TABLE(name)                                                 \
4872
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4873
    &gen_op_spe_st##name##_user,                                              \
4874
    &gen_op_spe_st##name##_le_user,                                           \
4875
    &gen_op_spe_st##name##_kernel,                                            \
4876
    &gen_op_spe_st##name##_le_kernel,                                         \
4877
};
4878
#endif /* defined(TARGET_PPC64) */
4879
#endif /* defined(CONFIG_USER_ONLY) */
4880

    
4881
#define GEN_SPE_LD(name, sh)                                                  \
4882
static inline void gen_evl##name (DisasContext *ctx)                          \
4883
{                                                                             \
4884
    if (unlikely(!ctx->spe_enabled)) {                                        \
4885
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4886
        return;                                                               \
4887
    }                                                                         \
4888
    gen_addr_spe_imm_index(ctx, sh);                                          \
4889
    op_spe_ldst(spe_l##name);                                                 \
4890
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
4891
}
4892

    
4893
#define GEN_SPE_LDX(name)                                                     \
4894
static inline void gen_evl##name##x (DisasContext *ctx)                       \
4895
{                                                                             \
4896
    if (unlikely(!ctx->spe_enabled)) {                                        \
4897
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4898
        return;                                                               \
4899
    }                                                                         \
4900
    gen_addr_reg_index(ctx);                                                  \
4901
    op_spe_ldst(spe_l##name);                                                 \
4902
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
4903
}
4904

    
4905
#define GEN_SPEOP_LD(name, sh)                                                \
4906
OP_SPE_LD_TABLE(name);                                                        \
4907
GEN_SPE_LD(name, sh);                                                         \
4908
GEN_SPE_LDX(name)
4909

    
4910
#define GEN_SPE_ST(name, sh)                                                  \
4911
static inline void gen_evst##name (DisasContext *ctx)                         \
4912
{                                                                             \
4913
    if (unlikely(!ctx->spe_enabled)) {                                        \
4914
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4915
        return;                                                               \
4916
    }                                                                         \
4917
    gen_addr_spe_imm_index(ctx, sh);                                          \
4918
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
4919
    op_spe_ldst(spe_st##name);                                                \
4920
}
4921

    
4922
#define GEN_SPE_STX(name)                                                     \
4923
static inline void gen_evst##name##x (DisasContext *ctx)                      \
4924
{                                                                             \
4925
    if (unlikely(!ctx->spe_enabled)) {                                        \
4926
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4927
        return;                                                               \
4928
    }                                                                         \
4929
    gen_addr_reg_index(ctx);                                                  \
4930
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
4931
    op_spe_ldst(spe_st##name);                                                \
4932
}
4933

    
4934
#define GEN_SPEOP_ST(name, sh)                                                \
4935
OP_SPE_ST_TABLE(name);                                                        \
4936
GEN_SPE_ST(name, sh);                                                         \
4937
GEN_SPE_STX(name)
4938

    
4939
#define GEN_SPEOP_LDST(name, sh)                                              \
4940
GEN_SPEOP_LD(name, sh);                                                       \
4941
GEN_SPEOP_ST(name, sh)
4942

    
4943
/* SPE arithmetic and logic */
4944
#define GEN_SPEOP_ARITH2(name)                                                \
4945
static inline void gen_##name (DisasContext *ctx)                             \
4946
{                                                                             \
4947
    if (unlikely(!ctx->spe_enabled)) {                                        \
4948
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4949
        return;                                                               \
4950
    }                                                                         \
4951
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
4952
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
4953
    gen_op_##name();                                                          \
4954
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
4955
}
4956

    
4957
#define GEN_SPEOP_ARITH1(name)                                                \
4958
static inline void gen_##name (DisasContext *ctx)                             \
4959
{                                                                             \
4960
    if (unlikely(!ctx->spe_enabled)) {                                        \
4961
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4962
        return;                                                               \
4963
    }                                                                         \
4964
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
4965
    gen_op_##name();                                                          \
4966
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
4967
}
4968

    
4969
#define GEN_SPEOP_COMP(name)                                                  \
4970
static inline void gen_##name (DisasContext *ctx)                             \
4971
{                                                                             \
4972
    if (unlikely(!ctx->spe_enabled)) {                                        \
4973
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4974
        return;                                                               \
4975
    }                                                                         \
4976
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
4977
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
4978
    gen_op_##name();                                                          \
4979
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
4980
}
4981

    
4982
/* Logical */
4983
GEN_SPEOP_ARITH2(evand);
4984
GEN_SPEOP_ARITH2(evandc);
4985
GEN_SPEOP_ARITH2(evxor);
4986
GEN_SPEOP_ARITH2(evor);
4987
GEN_SPEOP_ARITH2(evnor);
4988
GEN_SPEOP_ARITH2(eveqv);
4989
GEN_SPEOP_ARITH2(evorc);
4990
GEN_SPEOP_ARITH2(evnand);
4991
GEN_SPEOP_ARITH2(evsrwu);
4992
GEN_SPEOP_ARITH2(evsrws);
4993
GEN_SPEOP_ARITH2(evslw);
4994
GEN_SPEOP_ARITH2(evrlw);
4995
GEN_SPEOP_ARITH2(evmergehi);
4996
GEN_SPEOP_ARITH2(evmergelo);
4997
GEN_SPEOP_ARITH2(evmergehilo);
4998
GEN_SPEOP_ARITH2(evmergelohi);
4999

    
5000
/* Arithmetic */
5001
GEN_SPEOP_ARITH2(evaddw);
5002
GEN_SPEOP_ARITH2(evsubfw);
5003
GEN_SPEOP_ARITH1(evabs);
5004
GEN_SPEOP_ARITH1(evneg);
5005
GEN_SPEOP_ARITH1(evextsb);
5006
GEN_SPEOP_ARITH1(evextsh);
5007
GEN_SPEOP_ARITH1(evrndw);
5008
GEN_SPEOP_ARITH1(evcntlzw);
5009
GEN_SPEOP_ARITH1(evcntlsw);
5010
static inline void gen_brinc (DisasContext *ctx)
5011
{
5012
    /* Note: brinc is usable even if SPE is disabled */
5013
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5014
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5015
    gen_op_brinc();
5016
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5017
}
5018

    
5019
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5020
static inline void gen_##name##i (DisasContext *ctx)                          \
5021
{                                                                             \
5022
    if (unlikely(!ctx->spe_enabled)) {                                        \
5023
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5024
        return;                                                               \
5025
    }                                                                         \
5026
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5027
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5028
    gen_op_##name();                                                          \
5029
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5030
}
5031

    
5032
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5033
static inline void gen_##name##i (DisasContext *ctx)                          \
5034
{                                                                             \
5035
    if (unlikely(!ctx->spe_enabled)) {                                        \
5036
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
5037
        return;                                                               \
5038
    }                                                                         \
5039
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5040
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5041
    gen_op_##name();                                                          \
5042
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5043
}
5044

    
5045
GEN_SPEOP_ARITH_IMM2(evaddw);
5046
#define gen_evaddiw gen_evaddwi
5047
GEN_SPEOP_ARITH_IMM2(evsubfw);
5048
#define gen_evsubifw gen_evsubfwi
5049
GEN_SPEOP_LOGIC_IMM2(evslw);
5050
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5051
#define gen_evsrwis gen_evsrwsi
5052
GEN_SPEOP_LOGIC_IMM2(evsrws);
5053
#define gen_evsrwiu gen_evsrwui
5054
GEN_SPEOP_LOGIC_IMM2(evrlw);
5055

    
5056
static inline void gen_evsplati (DisasContext *ctx)
5057
{
5058
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5059

    
5060
    gen_op_splatwi_T0_64(imm);
5061
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5062
}
5063

    
5064
static inline void gen_evsplatfi (DisasContext *ctx)
5065
{
5066
    uint32_t imm = rA(ctx->opcode) << 27;
5067

    
5068
    gen_op_splatwi_T0_64(imm);
5069
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5070
}
5071

    
5072
/* Comparison */
5073
GEN_SPEOP_COMP(evcmpgtu);
5074
GEN_SPEOP_COMP(evcmpgts);
5075
GEN_SPEOP_COMP(evcmpltu);
5076
GEN_SPEOP_COMP(evcmplts);
5077
GEN_SPEOP_COMP(evcmpeq);
5078

    
5079
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5080
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5081
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5082
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5083
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5084
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5085
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5086
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5087
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5088
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5089
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5090
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5091
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5092
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5093
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5094
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5095
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5096
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5097
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5098
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5099
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5100
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5101
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5102
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5103
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5104

    
5105
static inline void gen_evsel (DisasContext *ctx)
5106
{
5107
    if (unlikely(!ctx->spe_enabled)) {
5108
        RET_EXCP(ctx, EXCP_NO_SPE, 0);
5109
        return;
5110
    }
5111
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5112
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5113
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5114
    gen_op_evsel();
5115
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5116
}
5117

    
5118
GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5119
{
5120
    gen_evsel(ctx);
5121
}
5122
GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5123
{
5124
    gen_evsel(ctx);
5125
}
5126
GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5127
{
5128
    gen_evsel(ctx);
5129
}
5130
GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5131
{
5132
    gen_evsel(ctx);
5133
}
5134

    
5135
/* Load and stores */
5136
#if defined(TARGET_PPC64)
5137
/* In that case, we already have 64 bits load & stores
5138
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5139
 */
5140
#if defined(CONFIG_USER_ONLY)
5141
#define gen_op_spe_ldd_raw gen_op_ld_raw
5142
#define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
5143
#define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
5144
#define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
5145
#define gen_op_spe_stdd_raw gen_op_ld_raw
5146
#define gen_op_spe_stdd_64_raw gen_op_std_64_raw
5147
#define gen_op_spe_stdd_le_raw gen_op_std_le_raw
5148
#define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
5149
#else /* defined(CONFIG_USER_ONLY) */
5150
#define gen_op_spe_ldd_kernel gen_op_ld_kernel
5151
#define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
5152
#define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
5153
#define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
5154
#define gen_op_spe_ldd_user gen_op_ld_user
5155
#define gen_op_spe_ldd_64_user gen_op_ld_64_user
5156
#define gen_op_spe_ldd_le_user gen_op_ld_le_user
5157
#define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
5158
#define gen_op_spe_stdd_kernel gen_op_std_kernel
5159
#define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
5160
#define gen_op_spe_stdd_le_kernel gen_op_std_kernel
5161
#define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
5162
#define gen_op_spe_stdd_user gen_op_std_user
5163
#define gen_op_spe_stdd_64_user gen_op_std_64_user
5164
#define gen_op_spe_stdd_le_user gen_op_std_le_user
5165
#define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
5166
#endif /* defined(CONFIG_USER_ONLY) */
5167
#endif /* defined(TARGET_PPC64) */
5168
GEN_SPEOP_LDST(dd, 3);
5169
GEN_SPEOP_LDST(dw, 3);
5170
GEN_SPEOP_LDST(dh, 3);
5171
GEN_SPEOP_LDST(whe, 2);
5172
GEN_SPEOP_LD(whou, 2);
5173
GEN_SPEOP_LD(whos, 2);
5174
GEN_SPEOP_ST(who, 2);
5175

    
5176
#if defined(TARGET_PPC64)
5177
/* In that case, spe_stwwo is equivalent to stw */
5178
#if defined(CONFIG_USER_ONLY)
5179
#define gen_op_spe_stwwo_raw gen_op_stw_raw
5180
#define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
5181
#define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
5182
#define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
5183
#else
5184
#define gen_op_spe_stwwo_user gen_op_stw_user
5185
#define gen_op_spe_stwwo_le_user gen_op_stw_le_user
5186
#define gen_op_spe_stwwo_64_user gen_op_stw_64_user
5187
#define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
5188
#define gen_op_spe_stwwo_kernel gen_op_stw_kernel
5189
#define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
5190
#define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
5191
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5192
#endif
5193
#endif
5194
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5195
static inline void gen_op_spe_stwwe_##suffix (void)                           \
5196
{                                                                             \
5197
    gen_op_srli32_T1_64();                                                    \
5198
    gen_op_spe_stwwo_##suffix();                                              \
5199
}
5200
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5201
static inline void gen_op_spe_stwwe_le_##suffix (void)                        \
5202
{                                                                             \
5203
    gen_op_srli32_T1_64();                                                    \
5204
    gen_op_spe_stwwo_le_##suffix();                                           \
5205
}
5206
#if defined(TARGET_PPC64)
5207
#define GEN_OP_SPE_STWWE(suffix)                                              \
5208
_GEN_OP_SPE_STWWE(suffix);                                                    \
5209
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5210
static inline void gen_op_spe_stwwe_64_##suffix (void)                        \
5211
{                                                                             \
5212
    gen_op_srli32_T1_64();                                                    \
5213
    gen_op_spe_stwwo_64_##suffix();                                           \
5214
}                                                                             \
5215
static inline void gen_op_spe_stwwe_le_64_##suffix (void)                     \
5216
{                                                                             \
5217
    gen_op_srli32_T1_64();                                                    \
5218
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5219
}
5220
#else
5221
#define GEN_OP_SPE_STWWE(suffix)                                              \
5222
_GEN_OP_SPE_STWWE(suffix);                                                    \
5223
_GEN_OP_SPE_STWWE_LE(suffix)
5224
#endif
5225
#if defined(CONFIG_USER_ONLY)
5226
GEN_OP_SPE_STWWE(raw);
5227
#else /* defined(CONFIG_USER_ONLY) */
5228
GEN_OP_SPE_STWWE(kernel);
5229
GEN_OP_SPE_STWWE(user);
5230
#endif /* defined(CONFIG_USER_ONLY) */
5231
GEN_SPEOP_ST(wwe, 2);
5232
GEN_SPEOP_ST(wwo, 2);
5233

    
5234
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5235
static inline void gen_op_spe_l##name##_##suffix (void)                       \
5236
{                                                                             \
5237
    gen_op_##op##_##suffix();                                                 \
5238
    gen_op_splatw_T1_64();                                                    \
5239
}
5240

    
5241
#define GEN_OP_SPE_LHE(suffix)                                                \
5242
static inline void gen_op_spe_lhe_##suffix (void)                             \
5243
{                                                                             \
5244
    gen_op_spe_lh_##suffix();                                                 \
5245
    gen_op_sli16_T1_64();                                                     \
5246
}
5247

    
5248
#define GEN_OP_SPE_LHX(suffix)                                                \
5249
static inline void gen_op_spe_lhx_##suffix (void)                             \
5250
{                                                                             \
5251
    gen_op_spe_lh_##suffix();                                                 \
5252
    gen_op_extsh_T1_64();                                                     \
5253
}
5254

    
5255
#if defined(CONFIG_USER_ONLY)
5256
GEN_OP_SPE_LHE(raw);
5257
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5258
GEN_OP_SPE_LHE(le_raw);
5259
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5260
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5261
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5262
GEN_OP_SPE_LHX(raw);
5263
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5264
GEN_OP_SPE_LHX(le_raw);
5265
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5266
#if defined(TARGET_PPC64)
5267
GEN_OP_SPE_LHE(64_raw);
5268
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5269
GEN_OP_SPE_LHE(le_64_raw);
5270
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5271
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5272
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5273
GEN_OP_SPE_LHX(64_raw);
5274
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5275
GEN_OP_SPE_LHX(le_64_raw);
5276
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5277
#endif
5278
#else
5279
GEN_OP_SPE_LHE(kernel);
5280
GEN_OP_SPE_LHE(user);
5281
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5282
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5283
GEN_OP_SPE_LHE(le_kernel);
5284
GEN_OP_SPE_LHE(le_user);
5285
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5286
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5287
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5288
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5289
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5290
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5291
GEN_OP_SPE_LHX(kernel);
5292
GEN_OP_SPE_LHX(user);
5293
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5294
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5295
GEN_OP_SPE_LHX(le_kernel);
5296
GEN_OP_SPE_LHX(le_user);
5297
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5298
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5299
#if defined(TARGET_PPC64)
5300
GEN_OP_SPE_LHE(64_kernel);
5301
GEN_OP_SPE_LHE(64_user);
5302
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5303
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5304
GEN_OP_SPE_LHE(le_64_kernel);
5305
GEN_OP_SPE_LHE(le_64_user);
5306
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5307
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5308
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5309
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5310
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5311
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5312
GEN_OP_SPE_LHX(64_kernel);
5313
GEN_OP_SPE_LHX(64_user);
5314
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5315
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5316
GEN_OP_SPE_LHX(le_64_kernel);
5317
GEN_OP_SPE_LHX(le_64_user);
5318
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5319
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5320
#endif
5321
#endif
5322
GEN_SPEOP_LD(hhesplat, 1);
5323
GEN_SPEOP_LD(hhousplat, 1);
5324
GEN_SPEOP_LD(hhossplat, 1);
5325
GEN_SPEOP_LD(wwsplat, 2);
5326
GEN_SPEOP_LD(whsplat, 2);
5327

    
5328
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5329
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5330
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5331
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5332
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5333
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5334
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5335
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5336
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5337
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5338
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5339
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5340
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5341
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5342
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5343
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5344
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5345
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5346

    
5347
/* Multiply and add - TODO */
5348
#if 0
5349
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5350
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5351
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5352
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5353
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5354
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5355
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5356
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5357
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5358
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5359
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5360
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5361

5362
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5363
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5364
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5365
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5366
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5367
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5368
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5369
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5370
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5371
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5372
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5373
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5374
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5375
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5376

5377
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5378
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5379
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5380
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5381
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5382
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5383

5384
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5385
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5386
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5387
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5388
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5389
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5390
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5391
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5392
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5393
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5394
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5395
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5396

5397
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5398
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5399
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5400
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5401
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5402

5403
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5404
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5405
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5406
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5407
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5408
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5409
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5410
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5411
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5412
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5413
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5414
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5415

5416
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5417
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5418
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5419
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5420
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5421
#endif
5422

    
5423
/***                      SPE floating-point extension                     ***/
5424
#define GEN_SPEFPUOP_CONV(name)                                               \
5425
static inline void gen_##name (DisasContext *ctx)                             \
5426
{                                                                             \
5427
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5428
    gen_op_##name();                                                          \
5429
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5430
}
5431

    
5432
/* Single precision floating-point vectors operations */
5433
/* Arithmetic */
5434
GEN_SPEOP_ARITH2(evfsadd);
5435
GEN_SPEOP_ARITH2(evfssub);
5436
GEN_SPEOP_ARITH2(evfsmul);
5437
GEN_SPEOP_ARITH2(evfsdiv);
5438
GEN_SPEOP_ARITH1(evfsabs);
5439
GEN_SPEOP_ARITH1(evfsnabs);
5440
GEN_SPEOP_ARITH1(evfsneg);
5441
/* Conversion */
5442
GEN_SPEFPUOP_CONV(evfscfui);
5443
GEN_SPEFPUOP_CONV(evfscfsi);
5444
GEN_SPEFPUOP_CONV(evfscfuf);
5445
GEN_SPEFPUOP_CONV(evfscfsf);
5446
GEN_SPEFPUOP_CONV(evfsctui);
5447
GEN_SPEFPUOP_CONV(evfsctsi);
5448
GEN_SPEFPUOP_CONV(evfsctuf);
5449
GEN_SPEFPUOP_CONV(evfsctsf);
5450
GEN_SPEFPUOP_CONV(evfsctuiz);
5451
GEN_SPEFPUOP_CONV(evfsctsiz);
5452
/* Comparison */
5453
GEN_SPEOP_COMP(evfscmpgt);
5454
GEN_SPEOP_COMP(evfscmplt);
5455
GEN_SPEOP_COMP(evfscmpeq);
5456
GEN_SPEOP_COMP(evfststgt);
5457
GEN_SPEOP_COMP(evfststlt);
5458
GEN_SPEOP_COMP(evfststeq);
5459

    
5460
/* Opcodes definitions */
5461
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5462
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5463
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5464
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5465
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5466
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5467
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5468
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5469
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5470
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5471
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5472
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5473
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5474
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5475

    
5476
/* Single precision floating-point operations */
5477
/* Arithmetic */
5478
GEN_SPEOP_ARITH2(efsadd);
5479
GEN_SPEOP_ARITH2(efssub);
5480
GEN_SPEOP_ARITH2(efsmul);
5481
GEN_SPEOP_ARITH2(efsdiv);
5482
GEN_SPEOP_ARITH1(efsabs);
5483
GEN_SPEOP_ARITH1(efsnabs);
5484
GEN_SPEOP_ARITH1(efsneg);
5485
/* Conversion */
5486
GEN_SPEFPUOP_CONV(efscfui);
5487
GEN_SPEFPUOP_CONV(efscfsi);
5488
GEN_SPEFPUOP_CONV(efscfuf);
5489
GEN_SPEFPUOP_CONV(efscfsf);
5490
GEN_SPEFPUOP_CONV(efsctui);
5491
GEN_SPEFPUOP_CONV(efsctsi);
5492
GEN_SPEFPUOP_CONV(efsctuf);
5493
GEN_SPEFPUOP_CONV(efsctsf);
5494
GEN_SPEFPUOP_CONV(efsctuiz);
5495
GEN_SPEFPUOP_CONV(efsctsiz);
5496
GEN_SPEFPUOP_CONV(efscfd);
5497
/* Comparison */
5498
GEN_SPEOP_COMP(efscmpgt);
5499
GEN_SPEOP_COMP(efscmplt);
5500
GEN_SPEOP_COMP(efscmpeq);
5501
GEN_SPEOP_COMP(efststgt);
5502
GEN_SPEOP_COMP(efststlt);
5503
GEN_SPEOP_COMP(efststeq);
5504

    
5505
/* Opcodes definitions */
5506
GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5507
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5508
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5509
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5510
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5511
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5512
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5513
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5514
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5515
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5516
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5517
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5518
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5519

    
5520
/* Double precision floating-point operations */
5521
/* Arithmetic */
5522
GEN_SPEOP_ARITH2(efdadd);
5523
GEN_SPEOP_ARITH2(efdsub);
5524
GEN_SPEOP_ARITH2(efdmul);
5525
GEN_SPEOP_ARITH2(efddiv);
5526
GEN_SPEOP_ARITH1(efdabs);
5527
GEN_SPEOP_ARITH1(efdnabs);
5528
GEN_SPEOP_ARITH1(efdneg);
5529
/* Conversion */
5530

    
5531
GEN_SPEFPUOP_CONV(efdcfui);
5532
GEN_SPEFPUOP_CONV(efdcfsi);
5533
GEN_SPEFPUOP_CONV(efdcfuf);
5534
GEN_SPEFPUOP_CONV(efdcfsf);
5535
GEN_SPEFPUOP_CONV(efdctui);
5536
GEN_SPEFPUOP_CONV(efdctsi);
5537
GEN_SPEFPUOP_CONV(efdctuf);
5538
GEN_SPEFPUOP_CONV(efdctsf);
5539
GEN_SPEFPUOP_CONV(efdctuiz);
5540
GEN_SPEFPUOP_CONV(efdctsiz);
5541
GEN_SPEFPUOP_CONV(efdcfs);
5542
GEN_SPEFPUOP_CONV(efdcfuid);
5543
GEN_SPEFPUOP_CONV(efdcfsid);
5544
GEN_SPEFPUOP_CONV(efdctuidz);
5545
GEN_SPEFPUOP_CONV(efdctsidz);
5546
/* Comparison */
5547
GEN_SPEOP_COMP(efdcmpgt);
5548
GEN_SPEOP_COMP(efdcmplt);
5549
GEN_SPEOP_COMP(efdcmpeq);
5550
GEN_SPEOP_COMP(efdtstgt);
5551
GEN_SPEOP_COMP(efdtstlt);
5552
GEN_SPEOP_COMP(efdtsteq);
5553

    
5554
/* Opcodes definitions */
5555
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
5556
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
5557
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
5558
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
5559
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
5560
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
5561
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
5562
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
5563
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
5564
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
5565
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
5566
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
5567
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
5568
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
5569
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
5570
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
5571
#endif
5572

    
5573
/* End opcode list */
5574
GEN_OPCODE_MARK(end);
5575

    
5576
#include "translate_init.c"
5577

    
5578
/*****************************************************************************/
5579
/* Misc PowerPC helpers */
5580
static inline uint32_t load_xer (CPUState *env)
5581
{
5582
    return (xer_so << XER_SO) |
5583
        (xer_ov << XER_OV) |
5584
        (xer_ca << XER_CA) |
5585
        (xer_bc << XER_BC) |
5586
        (xer_cmp << XER_CMP);
5587
}
5588

    
5589
void cpu_dump_state (CPUState *env, FILE *f,
5590
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5591
                     int flags)
5592
{
5593
#if defined(TARGET_PPC64) || 1
5594
#define FILL ""
5595
#define RGPL  4
5596
#define RFPL  4
5597
#else
5598
#define FILL "        "
5599
#define RGPL  8
5600
#define RFPL  4
5601
#endif
5602

    
5603
    int i;
5604

    
5605
    cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX "\n",
5606
                env->nip, env->lr, env->ctr);
5607
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
5608
#if !defined(NO_TIMER_DUMP)
5609
                "TB %08x %08x "
5610
#if !defined(CONFIG_USER_ONLY)
5611
                "DECR %08x"
5612
#endif
5613
#endif
5614
                "\n",
5615
                do_load_msr(env), load_xer(env)
5616
#if !defined(NO_TIMER_DUMP)
5617
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
5618
#if !defined(CONFIG_USER_ONLY)
5619
                , cpu_ppc_load_decr(env)
5620
#endif
5621
#endif
5622
                );
5623
    for (i = 0; i < 32; i++) {
5624
        if ((i & (RGPL - 1)) == 0)
5625
            cpu_fprintf(f, "GPR%02d", i);
5626
        cpu_fprintf(f, " " REGX, env->gpr[i]);
5627
        if ((i & (RGPL - 1)) == (RGPL - 1))
5628
            cpu_fprintf(f, "\n");
5629
    }
5630
    cpu_fprintf(f, "CR ");
5631
    for (i = 0; i < 8; i++)
5632
        cpu_fprintf(f, "%01x", env->crf[i]);
5633
    cpu_fprintf(f, "  [");
5634
    for (i = 0; i < 8; i++) {
5635
        char a = '-';
5636
        if (env->crf[i] & 0x08)
5637
            a = 'L';
5638
        else if (env->crf[i] & 0x04)
5639
            a = 'G';
5640
        else if (env->crf[i] & 0x02)
5641
            a = 'E';
5642
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
5643
    }
5644
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
5645
    for (i = 0; i < 32; i++) {
5646
        if ((i & (RFPL - 1)) == 0)
5647
            cpu_fprintf(f, "FPR%02d", i);
5648
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
5649
        if ((i & (RFPL - 1)) == (RFPL - 1))
5650
            cpu_fprintf(f, "\n");
5651
    }
5652
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
5653
                "SDR1 " REGX "\n",
5654
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
5655

    
5656
#undef RGPL
5657
#undef RFPL
5658
#undef FILL
5659
}
5660

    
5661
void cpu_dump_statistics (CPUState *env, FILE*f,
5662
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5663
                          int flags)
5664
{
5665
#if defined(DO_PPC_STATISTICS)
5666
    opc_handler_t **t1, **t2, **t3, *handler;
5667
    int op1, op2, op3;
5668

    
5669
    t1 = env->opcodes;
5670
    for (op1 = 0; op1 < 64; op1++) {
5671
        handler = t1[op1];
5672
        if (is_indirect_opcode(handler)) {
5673
            t2 = ind_table(handler);
5674
            for (op2 = 0; op2 < 32; op2++) {
5675
                handler = t2[op2];
5676
                if (is_indirect_opcode(handler)) {
5677
                    t3 = ind_table(handler);
5678
                    for (op3 = 0; op3 < 32; op3++) {
5679
                        handler = t3[op3];
5680
                        if (handler->count == 0)
5681
                            continue;
5682
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
5683
                                    "%016llx %lld\n",
5684
                                    op1, op2, op3, op1, (op3 << 5) | op2,
5685
                                    handler->oname,
5686
                                    handler->count, handler->count);
5687
                    }
5688
                } else {
5689
                    if (handler->count == 0)
5690
                        continue;
5691
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
5692
                                "%016llx %lld\n",
5693
                                op1, op2, op1, op2, handler->oname,
5694
                                handler->count, handler->count);
5695
                }
5696
            }
5697
        } else {
5698
            if (handler->count == 0)
5699
                continue;
5700
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
5701
                        op1, op1, handler->oname,
5702
                        handler->count, handler->count);
5703
        }
5704
    }
5705
#endif
5706
}
5707

    
5708
/*****************************************************************************/
5709
static inline int gen_intermediate_code_internal (CPUState *env,
5710
                                                  TranslationBlock *tb,
5711
                                                  int search_pc)
5712
{
5713
    DisasContext ctx, *ctxp = &ctx;
5714
    opc_handler_t **table, *handler;
5715
    target_ulong pc_start;
5716
    uint16_t *gen_opc_end;
5717
    int j, lj = -1;
5718

    
5719
    pc_start = tb->pc;
5720
    gen_opc_ptr = gen_opc_buf;
5721
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5722
    gen_opparam_ptr = gen_opparam_buf;
5723
    nb_gen_labels = 0;
5724
    ctx.nip = pc_start;
5725
    ctx.tb = tb;
5726
    ctx.exception = EXCP_NONE;
5727
    ctx.spr_cb = env->spr_cb;
5728
#if defined(CONFIG_USER_ONLY)
5729
    ctx.mem_idx = msr_le;
5730
#if defined(TARGET_PPC64)
5731
    ctx.mem_idx |= msr_sf << 1;
5732
#endif
5733
#else
5734
    ctx.supervisor = 1 - msr_pr;
5735
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
5736
#if defined(TARGET_PPC64)
5737
    ctx.mem_idx |= msr_sf << 2;
5738
#endif
5739
#endif
5740
#if defined(TARGET_PPC64)
5741
    ctx.sf_mode = msr_sf;
5742
#endif
5743
    ctx.fpu_enabled = msr_fp;
5744
#if defined(TARGET_PPCEMB)
5745
    ctx.spe_enabled = msr_spe;
5746
#endif
5747
    ctx.singlestep_enabled = env->singlestep_enabled;
5748
#if defined (DO_SINGLE_STEP) && 0
5749
    /* Single step trace mode */
5750
    msr_se = 1;
5751
#endif
5752
    /* Set env in case of segfault during code fetch */
5753
    while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
5754
        if (unlikely(env->nb_breakpoints > 0)) {
5755
            for (j = 0; j < env->nb_breakpoints; j++) {
5756
                if (env->breakpoints[j] == ctx.nip) {
5757
                    gen_update_nip(&ctx, ctx.nip);
5758
                    gen_op_debug();
5759
                    break;
5760
                }
5761
            }
5762
        }
5763
        if (unlikely(search_pc)) {
5764
            j = gen_opc_ptr - gen_opc_buf;
5765
            if (lj < j) {
5766
                lj++;
5767
                while (lj < j)
5768
                    gen_opc_instr_start[lj++] = 0;
5769
                gen_opc_pc[lj] = ctx.nip;
5770
                gen_opc_instr_start[lj] = 1;
5771
            }
5772
        }
5773
#if defined PPC_DEBUG_DISAS
5774
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5775
            fprintf(logfile, "----------------\n");
5776
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
5777
                    ctx.nip, 1 - msr_pr, msr_ir);
5778
        }
5779
#endif
5780
        ctx.opcode = ldl_code(ctx.nip);
5781
        if (msr_le) {
5782
            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
5783
                ((ctx.opcode & 0x00FF0000) >> 8) |
5784
                ((ctx.opcode & 0x0000FF00) << 8) |
5785
                ((ctx.opcode & 0x000000FF) << 24);
5786
        }
5787
#if defined PPC_DEBUG_DISAS
5788
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5789
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
5790
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
5791
                    opc3(ctx.opcode), msr_le ? "little" : "big");
5792
        }
5793
#endif
5794
        ctx.nip += 4;
5795
        table = env->opcodes;
5796
        handler = table[opc1(ctx.opcode)];
5797
        if (is_indirect_opcode(handler)) {
5798
            table = ind_table(handler);
5799
            handler = table[opc2(ctx.opcode)];
5800
            if (is_indirect_opcode(handler)) {
5801
                table = ind_table(handler);
5802
                handler = table[opc3(ctx.opcode)];
5803
            }
5804
        }
5805
        /* Is opcode *REALLY* valid ? */
5806
        if (unlikely(handler->handler == &gen_invalid)) {
5807
            if (loglevel != 0) {
5808
                fprintf(logfile, "invalid/unsupported opcode: "
5809
                        "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
5810
                        opc1(ctx.opcode), opc2(ctx.opcode),
5811
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
5812
            } else {
5813
                printf("invalid/unsupported opcode: "
5814
                       "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
5815
                       opc1(ctx.opcode), opc2(ctx.opcode),
5816
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
5817
            }
5818
        } else {
5819
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
5820
                if (loglevel != 0) {
5821
                    fprintf(logfile, "invalid bits: %08x for opcode: "
5822
                            "%02x -%02x - %02x (%08x) 0x" ADDRX "\n",
5823
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
5824
                            opc2(ctx.opcode), opc3(ctx.opcode),
5825
                            ctx.opcode, ctx.nip - 4);
5826
                } else {
5827
                    printf("invalid bits: %08x for opcode: "
5828
                           "%02x -%02x - %02x (%08x) 0x" ADDRX "\n",
5829
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
5830
                           opc2(ctx.opcode), opc3(ctx.opcode),
5831
                           ctx.opcode, ctx.nip - 4);
5832
                }
5833
                RET_INVAL(ctxp);
5834
                break;
5835
            }
5836
        }
5837
        (*(handler->handler))(&ctx);
5838
#if defined(DO_PPC_STATISTICS)
5839
        handler->count++;
5840
#endif
5841
        /* Check trace mode exceptions */
5842
#if 0 // XXX: buggy on embedded PowerPC
5843
        if (unlikely((msr_be && ctx.exception == EXCP_BRANCH) ||
5844
                     /* Check in single step trace mode
5845
                      * we need to stop except if:
5846
                      * - rfi, trap or syscall
5847
                      * - first instruction of an exception handler
5848
                      */
5849
                     (msr_se && (ctx.nip < 0x100 ||
5850
                                 ctx.nip > 0xF00 ||
5851
                                 (ctx.nip & 0xFC) != 0x04) &&
5852
                      ctx.exception != EXCP_SYSCALL &&
5853
                      ctx.exception != EXCP_SYSCALL_USER &&
5854
                      ctx.exception != EXCP_TRAP))) {
5855
            RET_EXCP(ctxp, EXCP_TRACE, 0);
5856
        }
5857
#endif
5858
        /* if we reach a page boundary or are single stepping, stop
5859
         * generation
5860
         */
5861
        if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
5862
                     (env->singlestep_enabled))) {
5863
            break;
5864
        }
5865
#if defined (DO_SINGLE_STEP)
5866
        break;
5867
#endif
5868
    }
5869
    if (ctx.exception == EXCP_NONE) {
5870
        gen_goto_tb(&ctx, 0, ctx.nip);
5871
    } else if (ctx.exception != EXCP_BRANCH) {
5872
        gen_op_reset_T0();
5873
        /* Generate the return instruction */
5874
        gen_op_exit_tb();
5875
    }
5876
    *gen_opc_ptr = INDEX_op_end;
5877
    if (unlikely(search_pc)) {
5878
        j = gen_opc_ptr - gen_opc_buf;
5879
        lj++;
5880
        while (lj <= j)
5881
            gen_opc_instr_start[lj++] = 0;
5882
    } else {
5883
        tb->size = ctx.nip - pc_start;
5884
    }
5885
#if defined(DEBUG_DISAS)
5886
    if (loglevel & CPU_LOG_TB_CPU) {
5887
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
5888
        cpu_dump_state(env, logfile, fprintf, 0);
5889
    }
5890
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5891
        int flags;
5892
        flags = msr_le;
5893
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5894
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
5895
        fprintf(logfile, "\n");
5896
    }
5897
    if (loglevel & CPU_LOG_TB_OP) {
5898
        fprintf(logfile, "OP:\n");
5899
        dump_ops(gen_opc_buf, gen_opparam_buf);
5900
        fprintf(logfile, "\n");
5901
    }
5902
#endif
5903
    return 0;
5904
}
5905

    
5906
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5907
{
5908
    return gen_intermediate_code_internal(env, tb, 0);
5909
}
5910

    
5911
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5912
{
5913
    return gen_intermediate_code_internal(env, tb, 1);
5914
}