Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 0487d6a8

History | View | Annotate | Download (190 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 DO_PPC_STATISTICS
33

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

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

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

    
50
#include "gen-op.h"
51

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
364
    return ret;
365
}
366

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
841
#if defined(TARGET_PPC64)
842
/* mulhd  mulhd.                   */
843
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_INTEGER);
844
/* mulhdu mulhdu.                  */
845
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_INTEGER);
846
/* mulld  mulld.  mulldo  mulldo.  */
847
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_INTEGER);
848
/* divd   divd.   divdo   divdo.   */
849
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_INTEGER);
850
/* divdu  divdu.  divduo  divduo.  */
851
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_INTEGER);
852
#endif
853

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

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

    
907
/* isel (PowerPC 2.03 specification) */
908
GEN_HANDLER(isel, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203)
909
{
910
    uint32_t bi = rC(ctx->opcode);
911
    uint32_t mask;
912

    
913
    if (rA(ctx->opcode) == 0) {
914
        gen_set_T0(0);
915
    } else {
916
        gen_op_load_gpr_T1(rA(ctx->opcode));
917
    }
918
    gen_op_load_gpr_T2(rB(ctx->opcode));
919
    mask = 1 << (3 - (bi & 0x03));
920
    gen_op_load_crf_T0(bi >> 2);
921
    gen_op_test_true(mask);
922
    gen_op_isel();
923
    gen_op_store_T0_gpr(rD(ctx->opcode));
924
}
925

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

    
940
#define GEN_LOGICAL1(name, opc, type)                                         \
941
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
942
{                                                                             \
943
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
944
    gen_op_##name();                                                          \
945
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
946
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
947
        gen_set_Rc0(ctx);                                                     \
948
}
949

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

    
971
/* cntlzw */
972
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
973
/* eqv & eqv. */
974
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
975
/* extsb & extsb. */
976
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
977
/* extsh & extsh. */
978
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
979
/* nand & nand. */
980
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
981
/* nor & nor. */
982
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
983

    
984
/* or & or. */
985
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
986
{
987
    int rs, ra, rb;
988

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

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

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

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

    
1059
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1060
        /* NOP */
1061
        return;
1062
    }
1063
    gen_op_load_gpr_T0(rS(ctx->opcode));
1064
    if (likely(uimm != 0))
1065
        gen_op_xori(uimm);
1066
    gen_op_store_T0_gpr(rA(ctx->opcode));
1067
}
1068

    
1069
/* xoris */
1070
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1071
{
1072
    target_ulong uimm = UIMM(ctx->opcode);
1073

    
1074
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1075
        /* NOP */
1076
        return;
1077
    }
1078
    gen_op_load_gpr_T0(rS(ctx->opcode));
1079
    if (likely(uimm != 0))
1080
        gen_op_xori(uimm << 16);
1081
    gen_op_store_T0_gpr(rA(ctx->opcode));
1082
}
1083

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

    
1097
#if defined(TARGET_PPC64)
1098
/* extsw & extsw. */
1099
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1100
/* cntlzd */
1101
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1102
#endif
1103

    
1104
/***                             Integer rotate                            ***/
1105
/* rlwimi & rlwimi. */
1106
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1107
{
1108
    target_ulong mask;
1109
    uint32_t mb, me, sh;
1110
    int n;
1111

    
1112
    mb = MB(ctx->opcode);
1113
    me = ME(ctx->opcode);
1114
    sh = SH(ctx->opcode);
1115
    n = me + 1 - mb;
1116
    if (likely(sh == 0)) {
1117
        if (likely(mb == 0 && me == 31)) {
1118
            gen_op_load_gpr_T0(rS(ctx->opcode));
1119
            goto do_store;
1120
        } else if (likely(mb == 31 && me == 0)) {
1121
            gen_op_load_gpr_T0(rA(ctx->opcode));
1122
            goto do_store;
1123
        }
1124
        gen_op_load_gpr_T0(rS(ctx->opcode));
1125
        gen_op_load_gpr_T1(rA(ctx->opcode));
1126
        goto do_mask;
1127
    }
1128
    gen_op_load_gpr_T0(rS(ctx->opcode));
1129
    gen_op_load_gpr_T1(rA(ctx->opcode));
1130
    gen_op_rotli32_T0(SH(ctx->opcode));
1131
 do_mask:
1132
#if defined(TARGET_PPC64)
1133
    mb += 32;
1134
    me += 32;
1135
#endif
1136
    mask = MASK(mb, me);
1137
    gen_op_andi_T0(mask);
1138
    gen_op_andi_T1(~mask);
1139
    gen_op_or();
1140
 do_store:
1141
    gen_op_store_T0_gpr(rA(ctx->opcode));
1142
    if (unlikely(Rc(ctx->opcode) != 0))
1143
        gen_set_Rc0(ctx);
1144
}
1145
/* rlwinm & rlwinm. */
1146
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1147
{
1148
    uint32_t mb, me, sh;
1149
    
1150
    sh = SH(ctx->opcode);
1151
    mb = MB(ctx->opcode);
1152
    me = ME(ctx->opcode);
1153
    gen_op_load_gpr_T0(rS(ctx->opcode));
1154
    if (likely(sh == 0)) {
1155
        goto do_mask;
1156
    }
1157
    if (likely(mb == 0)) {
1158
        if (likely(me == 31)) {
1159
            gen_op_rotli32_T0(sh);
1160
            goto do_store;
1161
        } else if (likely(me == (31 - sh))) {
1162
            gen_op_sli_T0(sh);
1163
            goto do_store;
1164
        }
1165
    } else if (likely(me == 31)) {
1166
        if (likely(sh == (32 - mb))) {
1167
            gen_op_srli_T0(mb);
1168
            goto do_store;
1169
        }
1170
    }
1171
    gen_op_rotli32_T0(sh);
1172
 do_mask:
1173
#if defined(TARGET_PPC64)
1174
    mb += 32;
1175
    me += 32;
1176
#endif
1177
    gen_op_andi_T0(MASK(mb, me));
1178
 do_store:
1179
    gen_op_store_T0_gpr(rA(ctx->opcode));
1180
    if (unlikely(Rc(ctx->opcode) != 0))
1181
        gen_set_Rc0(ctx);
1182
}
1183
/* rlwnm & rlwnm. */
1184
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1185
{
1186
    uint32_t mb, me;
1187

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

    
1205
#if defined(TARGET_PPC64)
1206
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1207
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1208
{                                                                             \
1209
    gen_##name(ctx, 0);                                                       \
1210
}                                                                             \
1211
GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1212
{                                                                             \
1213
    gen_##name(ctx, 1);                                                       \
1214
}
1215
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1216
GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1217
{                                                                             \
1218
    gen_##name(ctx, 0, 0);                                                    \
1219
}                                                                             \
1220
GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B)            \
1221
{                                                                             \
1222
    gen_##name(ctx, 0, 1);                                                    \
1223
}                                                                             \
1224
GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1225
{                                                                             \
1226
    gen_##name(ctx, 1, 0);                                                    \
1227
}                                                                             \
1228
GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B)            \
1229
{                                                                             \
1230
    gen_##name(ctx, 1, 1);                                                    \
1231
}
1232
/* rldicl - rldicl. */
1233
static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1234
{
1235
    int sh, mb;
1236

    
1237
    sh = SH(ctx->opcode) | (1 << shn);
1238
    mb = (MB(ctx->opcode) << 1) | mbn;
1239
    /* XXX: TODO */
1240
    RET_INVAL(ctx);
1241
}
1242
GEN_PPC64_R4(rldicl, 0x1E, 0x00)
1243
/* rldicr - rldicr. */
1244
static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1245
{
1246
    int sh, me;
1247

    
1248
    sh = SH(ctx->opcode) | (1 << shn);
1249
    me = (MB(ctx->opcode) << 1) | men;
1250
    /* XXX: TODO */
1251
    RET_INVAL(ctx);
1252
}
1253
GEN_PPC64_R4(rldicr, 0x1E, 0x02)
1254
/* rldic - rldic. */
1255
static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1256
{
1257
    int sh, mb;
1258

    
1259
    sh = SH(ctx->opcode) | (1 << shn);
1260
    mb = (MB(ctx->opcode) << 1) | mbn;
1261
    /* XXX: TODO */
1262
    RET_INVAL(ctx);
1263
}
1264
GEN_PPC64_R4(rldic, 0x1E, 0x04)
1265
/* rldcl - rldcl. */
1266
static inline void gen_rldcl (DisasContext *ctx, int mbn)
1267
{
1268
    int mb;
1269

    
1270
    mb = (MB(ctx->opcode) << 1) | mbn;
1271
    /* XXX: TODO */
1272
    RET_INVAL(ctx);
1273
}
1274
GEN_PPC64_R2(rldcl, 0x1E, 0x08)
1275
/* rldcr - rldcr. */
1276
static inline void gen_rldcr (DisasContext *ctx, int men)
1277
{
1278
    int me;
1279

    
1280
    me = (MB(ctx->opcode) << 1) | men;
1281
    /* XXX: TODO */
1282
    RET_INVAL(ctx);
1283
}
1284
GEN_PPC64_R2(rldcr, 0x1E, 0x09)
1285
/* rldimi - rldimi. */
1286
static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1287
{
1288
    int sh, mb;
1289

    
1290
    sh = SH(ctx->opcode) | (1 << shn);
1291
    mb = (MB(ctx->opcode) << 1) | mbn;
1292
    /* XXX: TODO */
1293
    RET_INVAL(ctx);
1294
}
1295
GEN_PPC64_R4(rldimi, 0x1E, 0x06)
1296
#endif
1297

    
1298
/***                             Integer shift                             ***/
1299
/* slw & slw. */
1300
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1301
/* sraw & sraw. */
1302
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1303
/* srawi & srawi. */
1304
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1305
{
1306
    int mb, me;
1307
    gen_op_load_gpr_T0(rS(ctx->opcode));
1308
    if (SH(ctx->opcode) != 0) {
1309
        gen_op_move_T1_T0();
1310
        mb = 32 - SH(ctx->opcode);
1311
        me = 31;
1312
#if defined(TARGET_PPC64)
1313
        mb += 32;
1314
        me += 32;
1315
#endif
1316
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1317
    }
1318
    gen_op_store_T0_gpr(rA(ctx->opcode));
1319
    if (unlikely(Rc(ctx->opcode) != 0))
1320
        gen_set_Rc0(ctx);
1321
}
1322
/* srw & srw. */
1323
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1324

    
1325
#if defined(TARGET_PPC64)
1326
/* sld & sld. */
1327
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1328
/* srad & srad. */
1329
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1330
/* sradi & sradi. */
1331
static inline void gen_sradi (DisasContext *ctx, int n)
1332
{
1333
    uint64_t mask;
1334
    int sh, mb, me;
1335

    
1336
    gen_op_load_gpr_T0(rS(ctx->opcode));
1337
    sh = SH(ctx->opcode) + (n << 5);
1338
    if (sh != 0) {
1339
        gen_op_move_T1_T0();
1340
        mb = 64 - SH(ctx->opcode);
1341
        me = 63;
1342
        mask = MASK(mb, me);
1343
        gen_op_sradi(sh, mask >> 32, mask);
1344
    }
1345
    gen_op_store_T0_gpr(rA(ctx->opcode));
1346
    if (unlikely(Rc(ctx->opcode) != 0))
1347
        gen_set_Rc0(ctx);
1348
}
1349
GEN_HANDLER(sradi0, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1350
{
1351
    gen_sradi(ctx, 0);
1352
}
1353
GEN_HANDLER(sradi1, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1354
{
1355
    gen_sradi(ctx, 1);
1356
}
1357
/* srd & srd. */
1358
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1359
#endif
1360

    
1361
/***                       Floating-Point arithmetic                       ***/
1362
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat)                           \
1363
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT)                   \
1364
{                                                                             \
1365
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1366
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1367
        return;                                                               \
1368
    }                                                                         \
1369
    gen_op_reset_scrfx();                                                     \
1370
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1371
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1372
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1373
    gen_op_f##op();                                                           \
1374
    if (isfloat) {                                                            \
1375
        gen_op_frsp();                                                        \
1376
    }                                                                         \
1377
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1378
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1379
        gen_op_set_Rc1();                                                     \
1380
}
1381

    
1382
#define GEN_FLOAT_ACB(name, op2)                                              \
1383
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0);                                     \
1384
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
1385

    
1386
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
1387
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1388
{                                                                             \
1389
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1390
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1391
        return;                                                               \
1392
    }                                                                         \
1393
    gen_op_reset_scrfx();                                                     \
1394
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1395
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1396
    gen_op_f##op();                                                           \
1397
    if (isfloat) {                                                            \
1398
        gen_op_frsp();                                                        \
1399
    }                                                                         \
1400
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1401
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1402
        gen_op_set_Rc1();                                                     \
1403
}
1404
#define GEN_FLOAT_AB(name, op2, inval)                                        \
1405
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
1406
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1407

    
1408
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
1409
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1410
{                                                                             \
1411
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1412
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1413
        return;                                                               \
1414
    }                                                                         \
1415
    gen_op_reset_scrfx();                                                     \
1416
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1417
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1418
    gen_op_f##op();                                                           \
1419
    if (isfloat) {                                                            \
1420
        gen_op_frsp();                                                        \
1421
    }                                                                         \
1422
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1423
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1424
        gen_op_set_Rc1();                                                     \
1425
}
1426
#define GEN_FLOAT_AC(name, op2, inval)                                        \
1427
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
1428
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1429

    
1430
#define GEN_FLOAT_B(name, op2, op3)                                           \
1431
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT)                   \
1432
{                                                                             \
1433
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1434
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1435
        return;                                                               \
1436
    }                                                                         \
1437
    gen_op_reset_scrfx();                                                     \
1438
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1439
    gen_op_f##name();                                                         \
1440
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1441
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1442
        gen_op_set_Rc1();                                                     \
1443
}
1444

    
1445
#define GEN_FLOAT_BS(name, op1, op2)                                          \
1446
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT)                   \
1447
{                                                                             \
1448
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1449
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1450
        return;                                                               \
1451
    }                                                                         \
1452
    gen_op_reset_scrfx();                                                     \
1453
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1454
    gen_op_f##name();                                                         \
1455
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1456
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1457
        gen_op_set_Rc1();                                                     \
1458
}
1459

    
1460
/* fadd - fadds */
1461
GEN_FLOAT_AB(add, 0x15, 0x000007C0);
1462
/* fdiv - fdivs */
1463
GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1464
/* fmul - fmuls */
1465
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1466

    
1467
/* fres */ /* XXX: not in 601 */
1468
GEN_FLOAT_BS(res, 0x3B, 0x18);
1469

    
1470
/* frsqrte */ /* XXX: not in 601 */
1471
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
1472

    
1473
/* fsel */ /* XXX: not in 601 */
1474
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0);
1475
/* fsub - fsubs */
1476
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1477
/* Optional: */
1478
/* fsqrt */
1479
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
1480
{
1481
    if (unlikely(!ctx->fpu_enabled)) {
1482
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1483
        return;
1484
    }
1485
    gen_op_reset_scrfx();
1486
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1487
    gen_op_fsqrt();
1488
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1489
    if (unlikely(Rc(ctx->opcode) != 0))
1490
        gen_op_set_Rc1();
1491
}
1492

    
1493
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
1494
{
1495
    if (unlikely(!ctx->fpu_enabled)) {
1496
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1497
        return;
1498
    }
1499
    gen_op_reset_scrfx();
1500
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1501
    gen_op_fsqrt();
1502
    gen_op_frsp();
1503
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1504
    if (unlikely(Rc(ctx->opcode) != 0))
1505
        gen_op_set_Rc1();
1506
}
1507

    
1508
/***                     Floating-Point multiply-and-add                   ***/
1509
/* fmadd - fmadds */
1510
GEN_FLOAT_ACB(madd, 0x1D);
1511
/* fmsub - fmsubs */
1512
GEN_FLOAT_ACB(msub, 0x1C);
1513
/* fnmadd - fnmadds */
1514
GEN_FLOAT_ACB(nmadd, 0x1F);
1515
/* fnmsub - fnmsubs */
1516
GEN_FLOAT_ACB(nmsub, 0x1E);
1517

    
1518
/***                     Floating-Point round & convert                    ***/
1519
/* fctiw */
1520
GEN_FLOAT_B(ctiw, 0x0E, 0x00);
1521
/* fctiwz */
1522
GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
1523
/* frsp */
1524
GEN_FLOAT_B(rsp, 0x0C, 0x00);
1525

    
1526
/***                         Floating-Point compare                        ***/
1527
/* fcmpo */
1528
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1529
{
1530
    if (unlikely(!ctx->fpu_enabled)) {
1531
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1532
        return;
1533
    }
1534
    gen_op_reset_scrfx();
1535
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1536
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1537
    gen_op_fcmpo();
1538
    gen_op_store_T0_crf(crfD(ctx->opcode));
1539
}
1540

    
1541
/* fcmpu */
1542
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1543
{
1544
    if (unlikely(!ctx->fpu_enabled)) {
1545
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1546
        return;
1547
    }
1548
    gen_op_reset_scrfx();
1549
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1550
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1551
    gen_op_fcmpu();
1552
    gen_op_store_T0_crf(crfD(ctx->opcode));
1553
}
1554

    
1555
/***                         Floating-point move                           ***/
1556
/* fabs */
1557
GEN_FLOAT_B(abs, 0x08, 0x08);
1558

    
1559
/* fmr  - fmr. */
1560
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1561
{
1562
    if (unlikely(!ctx->fpu_enabled)) {
1563
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1564
        return;
1565
    }
1566
    gen_op_reset_scrfx();
1567
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1568
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1569
    if (unlikely(Rc(ctx->opcode) != 0))
1570
        gen_op_set_Rc1();
1571
}
1572

    
1573
/* fnabs */
1574
GEN_FLOAT_B(nabs, 0x08, 0x04);
1575
/* fneg */
1576
GEN_FLOAT_B(neg, 0x08, 0x01);
1577

    
1578
/***                  Floating-Point status & ctrl register                ***/
1579
/* mcrfs */
1580
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1581
{
1582
    if (unlikely(!ctx->fpu_enabled)) {
1583
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1584
        return;
1585
    }
1586
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
1587
    gen_op_store_T0_crf(crfD(ctx->opcode));
1588
    gen_op_clear_fpscr(crfS(ctx->opcode));
1589
}
1590

    
1591
/* mffs */
1592
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1593
{
1594
    if (unlikely(!ctx->fpu_enabled)) {
1595
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1596
        return;
1597
    }
1598
    gen_op_load_fpscr();
1599
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1600
    if (unlikely(Rc(ctx->opcode) != 0))
1601
        gen_op_set_Rc1();
1602
}
1603

    
1604
/* mtfsb0 */
1605
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1606
{
1607
    uint8_t crb;
1608
    
1609
    if (unlikely(!ctx->fpu_enabled)) {
1610
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1611
        return;
1612
    }
1613
    crb = crbD(ctx->opcode) >> 2;
1614
    gen_op_load_fpscr_T0(crb);
1615
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1616
    gen_op_store_T0_fpscr(crb);
1617
    if (unlikely(Rc(ctx->opcode) != 0))
1618
        gen_op_set_Rc1();
1619
}
1620

    
1621
/* mtfsb1 */
1622
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1623
{
1624
    uint8_t crb;
1625
    
1626
    if (unlikely(!ctx->fpu_enabled)) {
1627
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1628
        return;
1629
    }
1630
    crb = crbD(ctx->opcode) >> 2;
1631
    gen_op_load_fpscr_T0(crb);
1632
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1633
    gen_op_store_T0_fpscr(crb);
1634
    if (unlikely(Rc(ctx->opcode) != 0))
1635
        gen_op_set_Rc1();
1636
}
1637

    
1638
/* mtfsf */
1639
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1640
{
1641
    if (unlikely(!ctx->fpu_enabled)) {
1642
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1643
        return;
1644
    }
1645
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1646
    gen_op_store_fpscr(FM(ctx->opcode));
1647
    if (unlikely(Rc(ctx->opcode) != 0))
1648
        gen_op_set_Rc1();
1649
}
1650

    
1651
/* mtfsfi */
1652
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1653
{
1654
    if (unlikely(!ctx->fpu_enabled)) {
1655
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1656
        return;
1657
    }
1658
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1659
    if (unlikely(Rc(ctx->opcode) != 0))
1660
        gen_op_set_Rc1();
1661
}
1662

    
1663
/***                           Addressing modes                            ***/
1664
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1665
static inline void gen_addr_imm_index (DisasContext *ctx)
1666
{
1667
    target_long simm = SIMM(ctx->opcode);
1668

    
1669
    if (rA(ctx->opcode) == 0) {
1670
        gen_set_T0(simm);
1671
    } else {
1672
        gen_op_load_gpr_T0(rA(ctx->opcode));
1673
        if (likely(simm != 0))
1674
            gen_op_addi(simm);
1675
    }
1676
}
1677

    
1678
static inline void gen_addr_reg_index (DisasContext *ctx)
1679
{
1680
    if (rA(ctx->opcode) == 0) {
1681
        gen_op_load_gpr_T0(rB(ctx->opcode));
1682
    } else {
1683
        gen_op_load_gpr_T0(rA(ctx->opcode));
1684
        gen_op_load_gpr_T1(rB(ctx->opcode));
1685
        gen_op_add();
1686
    }
1687
}
1688

    
1689
static inline void gen_addr_register (DisasContext *ctx)
1690
{
1691
    if (rA(ctx->opcode) == 0) {
1692
        gen_op_reset_T0();
1693
    } else {
1694
        gen_op_load_gpr_T0(rA(ctx->opcode));
1695
    }
1696
}
1697

    
1698
/***                             Integer load                              ***/
1699
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1700
#if defined(CONFIG_USER_ONLY)
1701
#if defined(TARGET_PPC64)
1702
#define OP_LD_TABLE(width)                                                    \
1703
static GenOpFunc *gen_op_l##width[] = {                                       \
1704
    &gen_op_l##width##_raw,                                                   \
1705
    &gen_op_l##width##_le_raw,                                                \
1706
    &gen_op_l##width##_64_raw,                                                \
1707
    &gen_op_l##width##_le_64_raw,                                             \
1708
};
1709
#define OP_ST_TABLE(width)                                                    \
1710
static GenOpFunc *gen_op_st##width[] = {                                      \
1711
    &gen_op_st##width##_raw,                                                  \
1712
    &gen_op_st##width##_le_raw,                                               \
1713
    &gen_op_st##width##_64_raw,                                               \
1714
    &gen_op_st##width##_le_64_raw,                                            \
1715
};
1716
/* Byte access routine are endian safe */
1717
#define gen_op_stb_le_64_raw gen_op_stb_64_raw
1718
#define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1719
#else
1720
#define OP_LD_TABLE(width)                                                    \
1721
static GenOpFunc *gen_op_l##width[] = {                                       \
1722
    &gen_op_l##width##_raw,                                                   \
1723
    &gen_op_l##width##_le_raw,                                                \
1724
};
1725
#define OP_ST_TABLE(width)                                                    \
1726
static GenOpFunc *gen_op_st##width[] = {                                      \
1727
    &gen_op_st##width##_raw,                                                  \
1728
    &gen_op_st##width##_le_raw,                                               \
1729
};
1730
#endif
1731
/* Byte access routine are endian safe */
1732
#define gen_op_stb_le_raw gen_op_stb_raw
1733
#define gen_op_lbz_le_raw gen_op_lbz_raw
1734
#else
1735
#if defined(TARGET_PPC64)
1736
#define OP_LD_TABLE(width)                                                    \
1737
static GenOpFunc *gen_op_l##width[] = {                                       \
1738
    &gen_op_l##width##_user,                                                  \
1739
    &gen_op_l##width##_le_user,                                               \
1740
    &gen_op_l##width##_kernel,                                                \
1741
    &gen_op_l##width##_le_kernel,                                             \
1742
    &gen_op_l##width##_64_user,                                               \
1743
    &gen_op_l##width##_le_64_user,                                            \
1744
    &gen_op_l##width##_64_kernel,                                             \
1745
    &gen_op_l##width##_le_64_kernel,                                          \
1746
};
1747
#define OP_ST_TABLE(width)                                                    \
1748
static GenOpFunc *gen_op_st##width[] = {                                      \
1749
    &gen_op_st##width##_user,                                                 \
1750
    &gen_op_st##width##_le_user,                                              \
1751
    &gen_op_st##width##_kernel,                                               \
1752
    &gen_op_st##width##_le_kernel,                                            \
1753
    &gen_op_st##width##_64_user,                                              \
1754
    &gen_op_st##width##_le_64_user,                                           \
1755
    &gen_op_st##width##_64_kernel,                                            \
1756
    &gen_op_st##width##_le_64_kernel,                                         \
1757
};
1758
/* Byte access routine are endian safe */
1759
#define gen_op_stb_le_64_user gen_op_stb_64_user
1760
#define gen_op_lbz_le_64_user gen_op_lbz_64_user
1761
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
1762
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
1763
#else
1764
#define OP_LD_TABLE(width)                                                    \
1765
static GenOpFunc *gen_op_l##width[] = {                                       \
1766
    &gen_op_l##width##_user,                                                  \
1767
    &gen_op_l##width##_le_user,                                               \
1768
    &gen_op_l##width##_kernel,                                                \
1769
    &gen_op_l##width##_le_kernel,                                             \
1770
};
1771
#define OP_ST_TABLE(width)                                                    \
1772
static GenOpFunc *gen_op_st##width[] = {                                      \
1773
    &gen_op_st##width##_user,                                                 \
1774
    &gen_op_st##width##_le_user,                                              \
1775
    &gen_op_st##width##_kernel,                                               \
1776
    &gen_op_st##width##_le_kernel,                                            \
1777
};
1778
#endif
1779
/* Byte access routine are endian safe */
1780
#define gen_op_stb_le_user gen_op_stb_user
1781
#define gen_op_lbz_le_user gen_op_lbz_user
1782
#define gen_op_stb_le_kernel gen_op_stb_kernel
1783
#define gen_op_lbz_le_kernel gen_op_lbz_kernel
1784
#endif
1785

    
1786
#define GEN_LD(width, opc, type)                                              \
1787
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
1788
{                                                                             \
1789
    gen_addr_imm_index(ctx);                                                  \
1790
    op_ldst(l##width);                                                        \
1791
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1792
}
1793

    
1794
#define GEN_LDU(width, opc, type)                                             \
1795
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
1796
{                                                                             \
1797
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1798
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1799
        RET_INVAL(ctx);                                                       \
1800
        return;                                                               \
1801
    }                                                                         \
1802
    gen_addr_imm_index(ctx);                                                  \
1803
    op_ldst(l##width);                                                        \
1804
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1805
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1806
}
1807

    
1808
#define GEN_LDUX(width, opc2, opc3, type)                                     \
1809
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
1810
{                                                                             \
1811
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1812
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1813
        RET_INVAL(ctx);                                                       \
1814
        return;                                                               \
1815
    }                                                                         \
1816
    gen_addr_reg_index(ctx);                                                  \
1817
    op_ldst(l##width);                                                        \
1818
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1819
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1820
}
1821

    
1822
#define GEN_LDX(width, opc2, opc3, type)                                      \
1823
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
1824
{                                                                             \
1825
    gen_addr_reg_index(ctx);                                                  \
1826
    op_ldst(l##width);                                                        \
1827
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1828
}
1829

    
1830
#define GEN_LDS(width, op, type)                                              \
1831
OP_LD_TABLE(width);                                                           \
1832
GEN_LD(width, op | 0x20, type);                                               \
1833
GEN_LDU(width, op | 0x21, type);                                              \
1834
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
1835
GEN_LDX(width, 0x17, op | 0x00, type)
1836

    
1837
/* lbz lbzu lbzux lbzx */
1838
GEN_LDS(bz, 0x02, PPC_INTEGER);
1839
/* lha lhau lhaux lhax */
1840
GEN_LDS(ha, 0x0A, PPC_INTEGER);
1841
/* lhz lhzu lhzux lhzx */
1842
GEN_LDS(hz, 0x08, PPC_INTEGER);
1843
/* lwz lwzu lwzux lwzx */
1844
GEN_LDS(wz, 0x00, PPC_INTEGER);
1845
#if defined(TARGET_PPC64)
1846
OP_LD_TABLE(wa);
1847
OP_LD_TABLE(d);
1848
/* lwaux */
1849
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
1850
/* lwax */
1851
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
1852
/* ldux */
1853
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
1854
/* ldx */
1855
GEN_LDX(d, 0x15, 0x00, PPC_64B);
1856
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
1857
{
1858
    if (Rc(ctx->opcode)) {
1859
        if (unlikely(rA(ctx->opcode) == 0 ||
1860
                     rA(ctx->opcode) == rD(ctx->opcode))) {
1861
            RET_INVAL(ctx);
1862
            return;
1863
        }
1864
    }
1865
    gen_addr_imm_index(ctx);
1866
    if (ctx->opcode & 0x02) {
1867
        /* lwa (lwau is undefined) */
1868
        op_ldst(lwa);
1869
    } else {
1870
        /* ld - ldu */
1871
        op_ldst(ld);
1872
    }
1873
    gen_op_store_T1_gpr(rD(ctx->opcode));
1874
    if (Rc(ctx->opcode))
1875
        gen_op_store_T0_gpr(rA(ctx->opcode));
1876
}
1877
#endif
1878

    
1879
/***                              Integer store                            ***/
1880
#define GEN_ST(width, opc, type)                                              \
1881
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
1882
{                                                                             \
1883
    gen_addr_imm_index(ctx);                                                  \
1884
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1885
    op_ldst(st##width);                                                       \
1886
}
1887

    
1888
#define GEN_STU(width, opc, type)                                             \
1889
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
1890
{                                                                             \
1891
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1892
        RET_INVAL(ctx);                                                       \
1893
        return;                                                               \
1894
    }                                                                         \
1895
    gen_addr_imm_index(ctx);                                                  \
1896
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1897
    op_ldst(st##width);                                                       \
1898
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1899
}
1900

    
1901
#define GEN_STUX(width, opc2, opc3, type)                                     \
1902
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
1903
{                                                                             \
1904
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1905
        RET_INVAL(ctx);                                                       \
1906
        return;                                                               \
1907
    }                                                                         \
1908
    gen_addr_reg_index(ctx);                                                  \
1909
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1910
    op_ldst(st##width);                                                       \
1911
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1912
}
1913

    
1914
#define GEN_STX(width, opc2, opc3, type)                                      \
1915
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
1916
{                                                                             \
1917
    gen_addr_reg_index(ctx);                                                  \
1918
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1919
    op_ldst(st##width);                                                       \
1920
}
1921

    
1922
#define GEN_STS(width, op, type)                                              \
1923
OP_ST_TABLE(width);                                                           \
1924
GEN_ST(width, op | 0x20, type);                                               \
1925
GEN_STU(width, op | 0x21, type);                                              \
1926
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
1927
GEN_STX(width, 0x17, op | 0x00, type)
1928

    
1929
/* stb stbu stbux stbx */
1930
GEN_STS(b, 0x06, PPC_INTEGER);
1931
/* sth sthu sthux sthx */
1932
GEN_STS(h, 0x0C, PPC_INTEGER);
1933
/* stw stwu stwux stwx */
1934
GEN_STS(w, 0x04, PPC_INTEGER);
1935
#if defined(TARGET_PPC64)
1936
OP_ST_TABLE(d);
1937
GEN_STUX(d, 0x15, 0x01, PPC_64B);
1938
GEN_STX(d, 0x15, 0x00, PPC_64B);
1939
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
1940
{
1941
    if (Rc(ctx->opcode)) {
1942
        if (unlikely(rA(ctx->opcode) == 0)) {
1943
            RET_INVAL(ctx);
1944
            return;
1945
        }
1946
    }
1947
    gen_addr_imm_index(ctx);
1948
    gen_op_load_gpr_T1(rS(ctx->opcode));
1949
    op_ldst(std);
1950
    if (Rc(ctx->opcode))
1951
        gen_op_store_T0_gpr(rA(ctx->opcode));
1952
}
1953
#endif
1954
/***                Integer load and store with byte reverse               ***/
1955
/* lhbrx */
1956
OP_LD_TABLE(hbr);
1957
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
1958
/* lwbrx */
1959
OP_LD_TABLE(wbr);
1960
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
1961
/* sthbrx */
1962
OP_ST_TABLE(hbr);
1963
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
1964
/* stwbrx */
1965
OP_ST_TABLE(wbr);
1966
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
1967

    
1968
/***                    Integer load and store multiple                    ***/
1969
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
1970
#if defined(TARGET_PPC64)
1971
#if defined(CONFIG_USER_ONLY)
1972
static GenOpFunc1 *gen_op_lmw[] = {
1973
    &gen_op_lmw_raw,
1974
    &gen_op_lmw_le_raw,
1975
    &gen_op_lmw_64_raw,
1976
    &gen_op_lmw_le_64_raw,
1977
};
1978
static GenOpFunc1 *gen_op_stmw[] = {
1979
    &gen_op_stmw_64_raw,
1980
    &gen_op_stmw_le_64_raw,
1981
};
1982
#else
1983
static GenOpFunc1 *gen_op_lmw[] = {
1984
    &gen_op_lmw_user,
1985
    &gen_op_lmw_le_user,
1986
    &gen_op_lmw_kernel,
1987
    &gen_op_lmw_le_kernel,
1988
    &gen_op_lmw_64_user,
1989
    &gen_op_lmw_le_64_user,
1990
    &gen_op_lmw_64_kernel,
1991
    &gen_op_lmw_le_64_kernel,
1992
};
1993
static GenOpFunc1 *gen_op_stmw[] = {
1994
    &gen_op_stmw_user,
1995
    &gen_op_stmw_le_user,
1996
    &gen_op_stmw_kernel,
1997
    &gen_op_stmw_le_kernel,
1998
    &gen_op_stmw_64_user,
1999
    &gen_op_stmw_le_64_user,
2000
    &gen_op_stmw_64_kernel,
2001
    &gen_op_stmw_le_64_kernel,
2002
};
2003
#endif
2004
#else
2005
#if defined(CONFIG_USER_ONLY)
2006
static GenOpFunc1 *gen_op_lmw[] = {
2007
    &gen_op_lmw_raw,
2008
    &gen_op_lmw_le_raw,
2009
};
2010
static GenOpFunc1 *gen_op_stmw[] = {
2011
    &gen_op_stmw_raw,
2012
    &gen_op_stmw_le_raw,
2013
};
2014
#else
2015
static GenOpFunc1 *gen_op_lmw[] = {
2016
    &gen_op_lmw_user,
2017
    &gen_op_lmw_le_user,
2018
    &gen_op_lmw_kernel,
2019
    &gen_op_lmw_le_kernel,
2020
};
2021
static GenOpFunc1 *gen_op_stmw[] = {
2022
    &gen_op_stmw_user,
2023
    &gen_op_stmw_le_user,
2024
    &gen_op_stmw_kernel,
2025
    &gen_op_stmw_le_kernel,
2026
};
2027
#endif
2028
#endif
2029

    
2030
/* lmw */
2031
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2032
{
2033
    /* NIP cannot be restored if the memory exception comes from an helper */
2034
    gen_update_nip(ctx, ctx->nip - 4);
2035
    gen_addr_imm_index(ctx);
2036
    op_ldstm(lmw, rD(ctx->opcode));
2037
}
2038

    
2039
/* stmw */
2040
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2041
{
2042
    /* NIP cannot be restored if the memory exception comes from an helper */
2043
    gen_update_nip(ctx, ctx->nip - 4);
2044
    gen_addr_imm_index(ctx);
2045
    op_ldstm(stmw, rS(ctx->opcode));
2046
}
2047

    
2048
/***                    Integer load and store strings                     ***/
2049
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2050
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2051
#if defined(TARGET_PPC64)
2052
#if defined(CONFIG_USER_ONLY)
2053
static GenOpFunc1 *gen_op_lswi[] = {
2054
    &gen_op_lswi_raw,
2055
    &gen_op_lswi_le_raw,
2056
    &gen_op_lswi_64_raw,
2057
    &gen_op_lswi_le_64_raw,
2058
};
2059
static GenOpFunc3 *gen_op_lswx[] = {
2060
    &gen_op_lswx_raw,
2061
    &gen_op_lswx_le_raw,
2062
    &gen_op_lswx_64_raw,
2063
    &gen_op_lswx_le_64_raw,
2064
};
2065
static GenOpFunc1 *gen_op_stsw[] = {
2066
    &gen_op_stsw_raw,
2067
    &gen_op_stsw_le_raw,
2068
    &gen_op_stsw_64_raw,
2069
    &gen_op_stsw_le_64_raw,
2070
};
2071
#else
2072
static GenOpFunc1 *gen_op_lswi[] = {
2073
    &gen_op_lswi_user,
2074
    &gen_op_lswi_le_user,
2075
    &gen_op_lswi_kernel,
2076
    &gen_op_lswi_le_kernel,
2077
    &gen_op_lswi_64_user,
2078
    &gen_op_lswi_le_64_user,
2079
    &gen_op_lswi_64_kernel,
2080
    &gen_op_lswi_le_64_kernel,
2081
};
2082
static GenOpFunc3 *gen_op_lswx[] = {
2083
    &gen_op_lswx_user,
2084
    &gen_op_lswx_le_user,
2085
    &gen_op_lswx_kernel,
2086
    &gen_op_lswx_le_kernel,
2087
    &gen_op_lswx_64_user,
2088
    &gen_op_lswx_le_64_user,
2089
    &gen_op_lswx_64_kernel,
2090
    &gen_op_lswx_le_64_kernel,
2091
};
2092
static GenOpFunc1 *gen_op_stsw[] = {
2093
    &gen_op_stsw_user,
2094
    &gen_op_stsw_le_user,
2095
    &gen_op_stsw_kernel,
2096
    &gen_op_stsw_le_kernel,
2097
    &gen_op_stsw_64_user,
2098
    &gen_op_stsw_le_64_user,
2099
    &gen_op_stsw_64_kernel,
2100
    &gen_op_stsw_le_64_kernel,
2101
};
2102
#endif
2103
#else
2104
#if defined(CONFIG_USER_ONLY)
2105
static GenOpFunc1 *gen_op_lswi[] = {
2106
    &gen_op_lswi_raw,
2107
    &gen_op_lswi_le_raw,
2108
};
2109
static GenOpFunc3 *gen_op_lswx[] = {
2110
    &gen_op_lswx_raw,
2111
    &gen_op_lswx_le_raw,
2112
};
2113
static GenOpFunc1 *gen_op_stsw[] = {
2114
    &gen_op_stsw_raw,
2115
    &gen_op_stsw_le_raw,
2116
};
2117
#else
2118
static GenOpFunc1 *gen_op_lswi[] = {
2119
    &gen_op_lswi_user,
2120
    &gen_op_lswi_le_user,
2121
    &gen_op_lswi_kernel,
2122
    &gen_op_lswi_le_kernel,
2123
};
2124
static GenOpFunc3 *gen_op_lswx[] = {
2125
    &gen_op_lswx_user,
2126
    &gen_op_lswx_le_user,
2127
    &gen_op_lswx_kernel,
2128
    &gen_op_lswx_le_kernel,
2129
};
2130
static GenOpFunc1 *gen_op_stsw[] = {
2131
    &gen_op_stsw_user,
2132
    &gen_op_stsw_le_user,
2133
    &gen_op_stsw_kernel,
2134
    &gen_op_stsw_le_kernel,
2135
};
2136
#endif
2137
#endif
2138

    
2139
/* lswi */
2140
/* PowerPC32 specification says we must generate an exception if
2141
 * rA is in the range of registers to be loaded.
2142
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2143
 * For now, I'll follow the spec...
2144
 */
2145
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
2146
{
2147
    int nb = NB(ctx->opcode);
2148
    int start = rD(ctx->opcode);
2149
    int ra = rA(ctx->opcode);
2150
    int nr;
2151

    
2152
    if (nb == 0)
2153
        nb = 32;
2154
    nr = nb / 4;
2155
    if (unlikely(((start + nr) > 32  &&
2156
                  start <= ra && (start + nr - 32) > ra) ||
2157
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2158
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
2159
        return;
2160
    }
2161
    /* NIP cannot be restored if the memory exception comes from an helper */
2162
    gen_update_nip(ctx, ctx->nip - 4);
2163
    gen_addr_register(ctx);
2164
    gen_op_set_T1(nb);
2165
    op_ldsts(lswi, start);
2166
}
2167

    
2168
/* lswx */
2169
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
2170
{
2171
    int ra = rA(ctx->opcode);
2172
    int rb = rB(ctx->opcode);
2173

    
2174
    /* NIP cannot be restored if the memory exception comes from an helper */
2175
    gen_update_nip(ctx, ctx->nip - 4);
2176
    gen_addr_reg_index(ctx);
2177
    if (ra == 0) {
2178
        ra = rb;
2179
    }
2180
    gen_op_load_xer_bc();
2181
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2182
}
2183

    
2184
/* stswi */
2185
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
2186
{
2187
    int nb = NB(ctx->opcode);
2188

    
2189
    /* NIP cannot be restored if the memory exception comes from an helper */
2190
    gen_update_nip(ctx, ctx->nip - 4);
2191
    gen_addr_register(ctx);
2192
    if (nb == 0)
2193
        nb = 32;
2194
    gen_op_set_T1(nb);
2195
    op_ldsts(stsw, rS(ctx->opcode));
2196
}
2197

    
2198
/* stswx */
2199
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
2200
{
2201
    /* NIP cannot be restored if the memory exception comes from an helper */
2202
    gen_update_nip(ctx, ctx->nip - 4); 
2203
    gen_addr_reg_index(ctx);
2204
    gen_op_load_xer_bc();
2205
    op_ldsts(stsw, rS(ctx->opcode));
2206
}
2207

    
2208
/***                        Memory synchronisation                         ***/
2209
/* eieio */
2210
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
2211
{
2212
}
2213

    
2214
/* isync */
2215
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
2216
{
2217
}
2218

    
2219
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2220
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2221
#if defined(TARGET_PPC64)
2222
#if defined(CONFIG_USER_ONLY)
2223
static GenOpFunc *gen_op_lwarx[] = {
2224
    &gen_op_lwarx_raw,
2225
    &gen_op_lwarx_le_raw,
2226
    &gen_op_lwarx_64_raw,
2227
    &gen_op_lwarx_le_64_raw,
2228
};
2229
static GenOpFunc *gen_op_stwcx[] = {
2230
    &gen_op_stwcx_raw,
2231
    &gen_op_stwcx_le_raw,
2232
    &gen_op_stwcx_64_raw,
2233
    &gen_op_stwcx_le_64_raw,
2234
};
2235
#else
2236
static GenOpFunc *gen_op_lwarx[] = {
2237
    &gen_op_lwarx_user,
2238
    &gen_op_lwarx_le_user,
2239
    &gen_op_lwarx_kernel,
2240
    &gen_op_lwarx_le_kernel,
2241
    &gen_op_lwarx_64_user,
2242
    &gen_op_lwarx_le_64_user,
2243
    &gen_op_lwarx_64_kernel,
2244
    &gen_op_lwarx_le_64_kernel,
2245
};
2246
static GenOpFunc *gen_op_stwcx[] = {
2247
    &gen_op_stwcx_user,
2248
    &gen_op_stwcx_le_user,
2249
    &gen_op_stwcx_kernel,
2250
    &gen_op_stwcx_le_kernel,
2251
    &gen_op_stwcx_64_user,
2252
    &gen_op_stwcx_le_64_user,
2253
    &gen_op_stwcx_64_kernel,
2254
    &gen_op_stwcx_le_64_kernel,
2255
};
2256
#endif
2257
#else
2258
#if defined(CONFIG_USER_ONLY)
2259
static GenOpFunc *gen_op_lwarx[] = {
2260
    &gen_op_lwarx_raw,
2261
    &gen_op_lwarx_le_raw,
2262
};
2263
static GenOpFunc *gen_op_stwcx[] = {
2264
    &gen_op_stwcx_raw,
2265
    &gen_op_stwcx_le_raw,
2266
};
2267
#else
2268
static GenOpFunc *gen_op_lwarx[] = {
2269
    &gen_op_lwarx_user,
2270
    &gen_op_lwarx_le_user,
2271
    &gen_op_lwarx_kernel,
2272
    &gen_op_lwarx_le_kernel,
2273
};
2274
static GenOpFunc *gen_op_stwcx[] = {
2275
    &gen_op_stwcx_user,
2276
    &gen_op_stwcx_le_user,
2277
    &gen_op_stwcx_kernel,
2278
    &gen_op_stwcx_le_kernel,
2279
};
2280
#endif
2281
#endif
2282

    
2283
/* lwarx */
2284
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2285
{
2286
    gen_addr_reg_index(ctx);
2287
    op_lwarx();
2288
    gen_op_store_T1_gpr(rD(ctx->opcode));
2289
}
2290

    
2291
/* stwcx. */
2292
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2293
{
2294
    gen_addr_reg_index(ctx);
2295
    gen_op_load_gpr_T1(rS(ctx->opcode));
2296
    op_stwcx();
2297
}
2298

    
2299
/* sync */
2300
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
2301
{
2302
}
2303

    
2304
/***                         Floating-point load                           ***/
2305
#define GEN_LDF(width, opc)                                                   \
2306
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                 \
2307
{                                                                             \
2308
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2309
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2310
        return;                                                               \
2311
    }                                                                         \
2312
    gen_addr_imm_index(ctx);                                                  \
2313
    op_ldst(l##width);                                                        \
2314
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2315
}
2316

    
2317
#define GEN_LDUF(width, opc)                                                  \
2318
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)              \
2319
{                                                                             \
2320
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2321
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2322
        return;                                                               \
2323
    }                                                                         \
2324
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2325
        RET_INVAL(ctx);                                                       \
2326
        return;                                                               \
2327
    }                                                                         \
2328
    gen_addr_imm_index(ctx);                                                  \
2329
    op_ldst(l##width);                                                        \
2330
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2331
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2332
}
2333

    
2334
#define GEN_LDUXF(width, opc)                                                 \
2335
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
2336
{                                                                             \
2337
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2338
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2339
        return;                                                               \
2340
    }                                                                         \
2341
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2342
        RET_INVAL(ctx);                                                       \
2343
        return;                                                               \
2344
    }                                                                         \
2345
    gen_addr_reg_index(ctx);                                                  \
2346
    op_ldst(l##width);                                                        \
2347
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2348
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2349
}
2350

    
2351
#define GEN_LDXF(width, opc2, opc3)                                           \
2352
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)             \
2353
{                                                                             \
2354
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2355
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2356
        return;                                                               \
2357
    }                                                                         \
2358
    gen_addr_reg_index(ctx);                                                  \
2359
    op_ldst(l##width);                                                        \
2360
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2361
}
2362

    
2363
#define GEN_LDFS(width, op)                                                   \
2364
OP_LD_TABLE(width);                                                           \
2365
GEN_LDF(width, op | 0x20);                                                    \
2366
GEN_LDUF(width, op | 0x21);                                                   \
2367
GEN_LDUXF(width, op | 0x01);                                                  \
2368
GEN_LDXF(width, 0x17, op | 0x00)
2369

    
2370
/* lfd lfdu lfdux lfdx */
2371
GEN_LDFS(fd, 0x12);
2372
/* lfs lfsu lfsux lfsx */
2373
GEN_LDFS(fs, 0x10);
2374

    
2375
/***                         Floating-point store                          ***/
2376
#define GEN_STF(width, opc)                                                   \
2377
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
2378
{                                                                             \
2379
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2380
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2381
        return;                                                               \
2382
    }                                                                         \
2383
    gen_addr_imm_index(ctx);                                                  \
2384
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2385
    op_ldst(st##width);                                                       \
2386
}
2387

    
2388
#define GEN_STUF(width, opc)                                                  \
2389
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
2390
{                                                                             \
2391
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2392
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2393
        return;                                                               \
2394
    }                                                                         \
2395
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2396
        RET_INVAL(ctx);                                                       \
2397
        return;                                                               \
2398
    }                                                                         \
2399
    gen_addr_imm_index(ctx);                                                  \
2400
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2401
    op_ldst(st##width);                                                       \
2402
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2403
}
2404

    
2405
#define GEN_STUXF(width, opc)                                                 \
2406
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
2407
{                                                                             \
2408
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2409
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2410
        return;                                                               \
2411
    }                                                                         \
2412
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2413
        RET_INVAL(ctx);                                                       \
2414
        return;                                                               \
2415
    }                                                                         \
2416
    gen_addr_reg_index(ctx);                                                  \
2417
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2418
    op_ldst(st##width);                                                       \
2419
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2420
}
2421

    
2422
#define GEN_STXF(width, opc2, opc3)                                           \
2423
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)            \
2424
{                                                                             \
2425
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2426
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2427
        return;                                                               \
2428
    }                                                                         \
2429
    gen_addr_reg_index(ctx);                                                  \
2430
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2431
    op_ldst(st##width);                                                       \
2432
}
2433

    
2434
#define GEN_STFS(width, op)                                                   \
2435
OP_ST_TABLE(width);                                                           \
2436
GEN_STF(width, op | 0x20);                                                    \
2437
GEN_STUF(width, op | 0x21);                                                   \
2438
GEN_STUXF(width, op | 0x01);                                                  \
2439
GEN_STXF(width, 0x17, op | 0x00)
2440

    
2441
/* stfd stfdu stfdux stfdx */
2442
GEN_STFS(fd, 0x16);
2443
/* stfs stfsu stfsux stfsx */
2444
GEN_STFS(fs, 0x14);
2445

    
2446
/* Optional: */
2447
/* stfiwx */
2448
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
2449
{
2450
    if (unlikely(!ctx->fpu_enabled)) {
2451
        RET_EXCP(ctx, EXCP_NO_FP, 0);
2452
        return;
2453
    }
2454
    gen_addr_reg_index(ctx);
2455
    /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2456
    RET_INVAL(ctx);
2457
}
2458

    
2459
/***                                Branch                                 ***/
2460

    
2461
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2462
{
2463
    TranslationBlock *tb;
2464
    tb = ctx->tb;
2465
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2466
        if (n == 0)
2467
            gen_op_goto_tb0(TBPARAM(tb));
2468
        else
2469
            gen_op_goto_tb1(TBPARAM(tb));
2470
        gen_set_T1(dest);
2471
#if defined(TARGET_PPC64)
2472
        if (ctx->sf_mode)
2473
            gen_op_b_T1_64();
2474
        else
2475
#endif
2476
            gen_op_b_T1();
2477
        gen_op_set_T0((long)tb + n);
2478
        if (ctx->singlestep_enabled)
2479
            gen_op_debug();
2480
        gen_op_exit_tb();
2481
    } else {
2482
        gen_set_T1(dest);
2483
#if defined(TARGET_PPC64)
2484
        if (ctx->sf_mode)
2485
            gen_op_b_T1_64();
2486
        else
2487
#endif
2488
            gen_op_b_T1();
2489
        gen_op_reset_T0();
2490
        if (ctx->singlestep_enabled)
2491
            gen_op_debug();
2492
        gen_op_exit_tb();
2493
    }
2494
}
2495

    
2496
/* b ba bl bla */
2497
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2498
{
2499
    target_ulong li, target;
2500

    
2501
    /* sign extend LI */
2502
#if defined(TARGET_PPC64)
2503
    if (ctx->sf_mode)
2504
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2505
    else
2506
#endif
2507
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2508
    if (likely(AA(ctx->opcode) == 0))
2509
        target = ctx->nip + li - 4;
2510
    else
2511
        target = li;
2512
    if (LK(ctx->opcode)) {
2513
#if defined(TARGET_PPC64)
2514
        if (ctx->sf_mode)
2515
            gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2516
        else
2517
#endif
2518
            gen_op_setlr(ctx->nip);
2519
    }
2520
    gen_goto_tb(ctx, 0, target);
2521
    ctx->exception = EXCP_BRANCH;
2522
}
2523

    
2524
#define BCOND_IM  0
2525
#define BCOND_LR  1
2526
#define BCOND_CTR 2
2527

    
2528
static inline void gen_bcond(DisasContext *ctx, int type)
2529
{
2530
    target_ulong target = 0;
2531
    target_ulong li;
2532
    uint32_t bo = BO(ctx->opcode);
2533
    uint32_t bi = BI(ctx->opcode);
2534
    uint32_t mask;
2535

    
2536
    if ((bo & 0x4) == 0)
2537
        gen_op_dec_ctr();
2538
    switch(type) {
2539
    case BCOND_IM:
2540
        li = (target_long)((int16_t)(BD(ctx->opcode)));
2541
        if (likely(AA(ctx->opcode) == 0)) {
2542
            target = ctx->nip + li - 4;
2543
        } else {
2544
            target = li;
2545
        }
2546
        break;
2547
    case BCOND_CTR:
2548
        gen_op_movl_T1_ctr();
2549
        break;
2550
    default:
2551
    case BCOND_LR:
2552
        gen_op_movl_T1_lr();
2553
        break;
2554
    }
2555
    if (LK(ctx->opcode)) {
2556
#if defined(TARGET_PPC64)
2557
        if (ctx->sf_mode)
2558
            gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2559
        else
2560
#endif
2561
            gen_op_setlr(ctx->nip);
2562
    }
2563
    if (bo & 0x10) {
2564
        /* No CR condition */
2565
        switch (bo & 0x6) {
2566
        case 0:
2567
#if defined(TARGET_PPC64)
2568
            if (ctx->sf_mode)
2569
                gen_op_test_ctr_64();
2570
            else
2571
#endif
2572
                gen_op_test_ctr();
2573
            break;
2574
        case 2:
2575
#if defined(TARGET_PPC64)
2576
            if (ctx->sf_mode)
2577
                gen_op_test_ctrz_64();
2578
            else
2579
#endif
2580
                gen_op_test_ctrz();
2581
            break;
2582
        default:
2583
        case 4:
2584
        case 6:
2585
            if (type == BCOND_IM) {
2586
                gen_goto_tb(ctx, 0, target);
2587
            } else {
2588
#if defined(TARGET_PPC64)
2589
                if (ctx->sf_mode)
2590
                    gen_op_b_T1_64();
2591
                else
2592
#endif
2593
                    gen_op_b_T1();
2594
                gen_op_reset_T0();
2595
            }
2596
            goto no_test;
2597
        }
2598
    } else {
2599
        mask = 1 << (3 - (bi & 0x03));
2600
        gen_op_load_crf_T0(bi >> 2);
2601
        if (bo & 0x8) {
2602
            switch (bo & 0x6) {
2603
            case 0:
2604
#if defined(TARGET_PPC64)
2605
                if (ctx->sf_mode)
2606
                    gen_op_test_ctr_true_64(mask);
2607
                else
2608
#endif
2609
                    gen_op_test_ctr_true(mask);
2610
                break;
2611
            case 2:
2612
#if defined(TARGET_PPC64)
2613
                if (ctx->sf_mode)
2614
                    gen_op_test_ctrz_true_64(mask);
2615
                else
2616
#endif
2617
                    gen_op_test_ctrz_true(mask);
2618
                break;
2619
            default:
2620
            case 4:
2621
            case 6:
2622
                gen_op_test_true(mask);
2623
                break;
2624
            }
2625
        } else {
2626
            switch (bo & 0x6) {
2627
            case 0:
2628
#if defined(TARGET_PPC64)
2629
                if (ctx->sf_mode)
2630
                    gen_op_test_ctr_false_64(mask);
2631
                else
2632
#endif
2633
                    gen_op_test_ctr_false(mask);
2634
                break;                           
2635
            case 2:
2636
#if defined(TARGET_PPC64)
2637
                if (ctx->sf_mode)
2638
                    gen_op_test_ctrz_false_64(mask);
2639
                else
2640
#endif
2641
                    gen_op_test_ctrz_false(mask);
2642
                break;
2643
            default:
2644
            case 4:
2645
            case 6:
2646
                gen_op_test_false(mask);
2647
                break;
2648
            }
2649
        }
2650
    }
2651
    if (type == BCOND_IM) {
2652
        int l1 = gen_new_label();
2653
        gen_op_jz_T0(l1);
2654
        gen_goto_tb(ctx, 0, target);
2655
        gen_set_label(l1);
2656
        gen_goto_tb(ctx, 1, ctx->nip);
2657
    } else {
2658
#if defined(TARGET_PPC64)
2659
        if (ctx->sf_mode)
2660
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
2661
        else
2662
#endif
2663
            gen_op_btest_T1(ctx->nip);
2664
        gen_op_reset_T0();
2665
    }
2666
 no_test:
2667
    if (ctx->singlestep_enabled)
2668
        gen_op_debug();
2669
    gen_op_exit_tb();
2670
    ctx->exception = EXCP_BRANCH;
2671
}
2672

    
2673
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2674
{                     
2675
    gen_bcond(ctx, BCOND_IM);
2676
}
2677

    
2678
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
2679
{                    
2680
    gen_bcond(ctx, BCOND_CTR);
2681
}
2682

    
2683
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
2684
{                     
2685
    gen_bcond(ctx, BCOND_LR);
2686
}
2687

    
2688
/***                      Condition register logical                       ***/
2689
#define GEN_CRLOGIC(op, opc)                                                  \
2690
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
2691
{                                                                             \
2692
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
2693
    gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
2694
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
2695
    gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
2696
    gen_op_##op();                                                            \
2697
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
2698
    gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
2699
                     3 - (crbD(ctx->opcode) & 0x03));                         \
2700
    gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
2701
}
2702

    
2703
/* crand */
2704
GEN_CRLOGIC(and, 0x08);
2705
/* crandc */
2706
GEN_CRLOGIC(andc, 0x04);
2707
/* creqv */
2708
GEN_CRLOGIC(eqv, 0x09);
2709
/* crnand */
2710
GEN_CRLOGIC(nand, 0x07);
2711
/* crnor */
2712
GEN_CRLOGIC(nor, 0x01);
2713
/* cror */
2714
GEN_CRLOGIC(or, 0x0E);
2715
/* crorc */
2716
GEN_CRLOGIC(orc, 0x0D);
2717
/* crxor */
2718
GEN_CRLOGIC(xor, 0x06);
2719
/* mcrf */
2720
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
2721
{
2722
    gen_op_load_crf_T0(crfS(ctx->opcode));
2723
    gen_op_store_T0_crf(crfD(ctx->opcode));
2724
}
2725

    
2726
/***                           System linkage                              ***/
2727
/* rfi (supervisor only) */
2728
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
2729
{
2730
#if defined(CONFIG_USER_ONLY)
2731
    RET_PRIVOPC(ctx);
2732
#else
2733
    /* Restore CPU state */
2734
    if (unlikely(!ctx->supervisor)) {
2735
        RET_PRIVOPC(ctx);
2736
        return;
2737
    }
2738
#if defined(TARGET_PPC64)
2739
    if (!ctx->sf_mode)
2740
        gen_op_rfi_32();
2741
    else
2742
#endif
2743
        gen_op_rfi();
2744
    RET_CHG_FLOW(ctx);
2745
#endif
2746
}
2747

    
2748
/* sc */
2749
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
2750
{
2751
#if defined(CONFIG_USER_ONLY)
2752
    RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
2753
#else
2754
    RET_EXCP(ctx, EXCP_SYSCALL, 0);
2755
#endif
2756
}
2757

    
2758
/***                                Trap                                   ***/
2759
/* tw */
2760
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
2761
{
2762
    gen_op_load_gpr_T0(rA(ctx->opcode));
2763
    gen_op_load_gpr_T1(rB(ctx->opcode));
2764
    /* Update the nip since this might generate a trap exception */
2765
    gen_update_nip(ctx, ctx->nip);
2766
    gen_op_tw(TO(ctx->opcode));
2767
}
2768

    
2769
/* twi */
2770
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2771
{
2772
    gen_op_load_gpr_T0(rA(ctx->opcode));
2773
    gen_set_T1(SIMM(ctx->opcode));
2774
    /* Update the nip since this might generate a trap exception */
2775
    gen_update_nip(ctx, ctx->nip);
2776
    gen_op_tw(TO(ctx->opcode));
2777
}
2778

    
2779
#if defined(TARGET_PPC64)
2780
/* td */
2781
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
2782
{
2783
    gen_op_load_gpr_T0(rA(ctx->opcode));
2784
    gen_op_load_gpr_T1(rB(ctx->opcode));
2785
    /* Update the nip since this might generate a trap exception */
2786
    gen_update_nip(ctx, ctx->nip);
2787
    gen_op_td(TO(ctx->opcode));
2788
}
2789

    
2790
/* tdi */
2791
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
2792
{
2793
    gen_op_load_gpr_T0(rA(ctx->opcode));
2794
    gen_set_T1(SIMM(ctx->opcode));
2795
    /* Update the nip since this might generate a trap exception */
2796
    gen_update_nip(ctx, ctx->nip);
2797
    gen_op_td(TO(ctx->opcode));
2798
}
2799
#endif
2800

    
2801
/***                          Processor control                            ***/
2802
/* mcrxr */
2803
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
2804
{
2805
    gen_op_load_xer_cr();
2806
    gen_op_store_T0_crf(crfD(ctx->opcode));
2807
    gen_op_clear_xer_cr();
2808
}
2809

    
2810
/* mfcr */
2811
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
2812
{
2813
    uint32_t crm, crn;
2814
    
2815
    if (likely(ctx->opcode & 0x00100000)) {
2816
        crm = CRM(ctx->opcode);
2817
        if (likely((crm ^ (crm - 1)) == 0)) {
2818
            crn = ffs(crm);
2819
            gen_op_load_cro(7 - crn);
2820
        }
2821
    } else {
2822
        gen_op_load_cr();
2823
    }
2824
    gen_op_store_T0_gpr(rD(ctx->opcode));
2825
}
2826

    
2827
/* mfmsr */
2828
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
2829
{
2830
#if defined(CONFIG_USER_ONLY)
2831
    RET_PRIVREG(ctx);
2832
#else
2833
    if (unlikely(!ctx->supervisor)) {
2834
        RET_PRIVREG(ctx);
2835
        return;
2836
    }
2837
    gen_op_load_msr();
2838
    gen_op_store_T0_gpr(rD(ctx->opcode));
2839
#endif
2840
}
2841

    
2842
#if 0
2843
#define SPR_NOACCESS ((void *)(-1))
2844
#else
2845
static void spr_noaccess (void *opaque, int sprn)
2846
{
2847
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
2848
    printf("ERROR: try to access SPR %d !\n", sprn);
2849
}
2850
#define SPR_NOACCESS (&spr_noaccess)
2851
#endif
2852

    
2853
/* mfspr */
2854
static inline void gen_op_mfspr (DisasContext *ctx)
2855
{
2856
    void (*read_cb)(void *opaque, int sprn);
2857
    uint32_t sprn = SPR(ctx->opcode);
2858

    
2859
#if !defined(CONFIG_USER_ONLY)
2860
    if (ctx->supervisor)
2861
        read_cb = ctx->spr_cb[sprn].oea_read;
2862
    else
2863
#endif
2864
        read_cb = ctx->spr_cb[sprn].uea_read;
2865
    if (likely(read_cb != NULL)) {
2866
        if (likely(read_cb != SPR_NOACCESS)) {
2867
            (*read_cb)(ctx, sprn);
2868
            gen_op_store_T0_gpr(rD(ctx->opcode));
2869
        } else {
2870
            /* Privilege exception */
2871
            if (loglevel) {
2872
                fprintf(logfile, "Trying to read priviledged spr %d %03x\n",
2873
                        sprn, sprn);
2874
            }
2875
            printf("Trying to read priviledged spr %d %03x\n", sprn, sprn);
2876
            RET_PRIVREG(ctx);
2877
        }
2878
    } else {
2879
        /* Not defined */
2880
        if (loglevel) {
2881
            fprintf(logfile, "Trying to read invalid spr %d %03x\n",
2882
                    sprn, sprn);
2883
        }
2884
        printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
2885
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2886
    }
2887
}
2888

    
2889
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
2890
{
2891
    gen_op_mfspr(ctx);
2892
}
2893

    
2894
/* mftb */
2895
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB)
2896
{
2897
    gen_op_mfspr(ctx);
2898
}
2899

    
2900
/* mtcrf */
2901
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
2902
{
2903
    uint32_t crm, crn;
2904
    
2905
    gen_op_load_gpr_T0(rS(ctx->opcode));
2906
    crm = CRM(ctx->opcode);
2907
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
2908
        crn = ffs(crm);
2909
        gen_op_srli_T0(crn * 4);
2910
        gen_op_andi_T0(0xF);
2911
        gen_op_store_cro(7 - crn);
2912
    } else {
2913
        gen_op_store_cr(crm);
2914
    }
2915
}
2916

    
2917
/* mtmsr */
2918
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
2919
{
2920
#if defined(CONFIG_USER_ONLY)
2921
    RET_PRIVREG(ctx);
2922
#else
2923
    if (unlikely(!ctx->supervisor)) {
2924
        RET_PRIVREG(ctx);
2925
        return;
2926
    }
2927
    gen_update_nip(ctx, ctx->nip);
2928
    gen_op_load_gpr_T0(rS(ctx->opcode));
2929
#if defined(TARGET_PPC64)
2930
    if (!ctx->sf_mode)
2931
        gen_op_store_msr_32();
2932
    else
2933
#endif
2934
        gen_op_store_msr();
2935
    /* Must stop the translation as machine state (may have) changed */
2936
    RET_CHG_FLOW(ctx);
2937
#endif
2938
}
2939

    
2940
/* mtspr */
2941
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
2942
{
2943
    void (*write_cb)(void *opaque, int sprn);
2944
    uint32_t sprn = SPR(ctx->opcode);
2945

    
2946
#if !defined(CONFIG_USER_ONLY)
2947
    if (ctx->supervisor)
2948
        write_cb = ctx->spr_cb[sprn].oea_write;
2949
    else
2950
#endif
2951
        write_cb = ctx->spr_cb[sprn].uea_write;
2952
    if (likely(write_cb != NULL)) {
2953
        if (likely(write_cb != SPR_NOACCESS)) {
2954
            gen_op_load_gpr_T0(rS(ctx->opcode));
2955
            (*write_cb)(ctx, sprn);
2956
        } else {
2957
            /* Privilege exception */
2958
            if (loglevel) {
2959
                fprintf(logfile, "Trying to write priviledged spr %d %03x\n",
2960
                        sprn, sprn);
2961
            }
2962
            printf("Trying to write priviledged spr %d %03x\n", sprn, sprn);
2963
            RET_PRIVREG(ctx);
2964
        }
2965
    } else {
2966
        /* Not defined */
2967
        if (loglevel) {
2968
            fprintf(logfile, "Trying to write invalid spr %d %03x\n",
2969
                    sprn, sprn);
2970
        }
2971
        printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
2972
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2973
    }
2974
}
2975

    
2976
/***                         Cache management                              ***/
2977
/* For now, all those will be implemented as nop:
2978
 * this is valid, regarding the PowerPC specs...
2979
 * We just have to flush tb while invalidating instruction cache lines...
2980
 */
2981
/* dcbf */
2982
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
2983
{
2984
    gen_addr_reg_index(ctx);
2985
    op_ldst(lbz);
2986
}
2987

    
2988
/* dcbi (Supervisor only) */
2989
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
2990
{
2991
#if defined(CONFIG_USER_ONLY)
2992
    RET_PRIVOPC(ctx);
2993
#else
2994
    if (unlikely(!ctx->supervisor)) {
2995
        RET_PRIVOPC(ctx);
2996
        return;
2997
    }
2998
    gen_addr_reg_index(ctx);
2999
    /* XXX: specification says this should be treated as a store by the MMU */
3000
    //op_ldst(lbz);
3001
    op_ldst(stb);
3002
#endif
3003
}
3004

    
3005
/* dcdst */
3006
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3007
{
3008
    /* XXX: specification say this is treated as a load by the MMU */
3009
    gen_addr_reg_index(ctx);
3010
    op_ldst(lbz);
3011
}
3012

    
3013
/* dcbt */
3014
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
3015
{
3016
    /* XXX: specification say this is treated as a load by the MMU
3017
     *      but does not generate any exception
3018
     */
3019
}
3020

    
3021
/* dcbtst */
3022
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
3023
{
3024
    /* XXX: specification say this is treated as a load by the MMU
3025
     *      but does not generate any exception
3026
     */
3027
}
3028

    
3029
/* dcbz */
3030
#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3031
#if defined(TARGET_PPC64)
3032
#if defined(CONFIG_USER_ONLY)
3033
static GenOpFunc *gen_op_dcbz[] = {
3034
    &gen_op_dcbz_raw,
3035
    &gen_op_dcbz_raw,
3036
    &gen_op_dcbz_64_raw,
3037
    &gen_op_dcbz_64_raw,
3038
};
3039
#else
3040
static GenOpFunc *gen_op_dcbz[] = {
3041
    &gen_op_dcbz_user,
3042
    &gen_op_dcbz_user,
3043
    &gen_op_dcbz_kernel,
3044
    &gen_op_dcbz_kernel,
3045
    &gen_op_dcbz_64_user,
3046
    &gen_op_dcbz_64_user,
3047
    &gen_op_dcbz_64_kernel,
3048
    &gen_op_dcbz_64_kernel,
3049
};
3050
#endif
3051
#else
3052
#if defined(CONFIG_USER_ONLY)
3053
static GenOpFunc *gen_op_dcbz[] = {
3054
    &gen_op_dcbz_raw,
3055
    &gen_op_dcbz_raw,
3056
};
3057
#else
3058
static GenOpFunc *gen_op_dcbz[] = {
3059
    &gen_op_dcbz_user,
3060
    &gen_op_dcbz_user,
3061
    &gen_op_dcbz_kernel,
3062
    &gen_op_dcbz_kernel,
3063
};
3064
#endif
3065
#endif
3066

    
3067
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3068
{
3069
    gen_addr_reg_index(ctx);
3070
    op_dcbz();
3071
    gen_op_check_reservation();
3072
}
3073

    
3074
/* icbi */
3075
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3076
#if defined(TARGET_PPC64)
3077
#if defined(CONFIG_USER_ONLY)
3078
static GenOpFunc *gen_op_icbi[] = {
3079
    &gen_op_icbi_raw,
3080
    &gen_op_icbi_raw,
3081
    &gen_op_icbi_64_raw,
3082
    &gen_op_icbi_64_raw,
3083
};
3084
#else
3085
static GenOpFunc *gen_op_icbi[] = {
3086
    &gen_op_icbi_user,
3087
    &gen_op_icbi_user,
3088
    &gen_op_icbi_kernel,
3089
    &gen_op_icbi_kernel,
3090
    &gen_op_icbi_64_user,
3091
    &gen_op_icbi_64_user,
3092
    &gen_op_icbi_64_kernel,
3093
    &gen_op_icbi_64_kernel,
3094
};
3095
#endif
3096
#else
3097
#if defined(CONFIG_USER_ONLY)
3098
static GenOpFunc *gen_op_icbi[] = {
3099
    &gen_op_icbi_raw,
3100
    &gen_op_icbi_raw,
3101
};
3102
#else
3103
static GenOpFunc *gen_op_icbi[] = {
3104
    &gen_op_icbi_user,
3105
    &gen_op_icbi_user,
3106
    &gen_op_icbi_kernel,
3107
    &gen_op_icbi_kernel,
3108
};
3109
#endif
3110
#endif
3111
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3112
{
3113
    /* NIP cannot be restored if the memory exception comes from an helper */
3114
    gen_update_nip(ctx, ctx->nip - 4);
3115
    gen_addr_reg_index(ctx);
3116
    op_icbi();
3117
    RET_STOP(ctx);
3118
}
3119

    
3120
/* Optional: */
3121
/* dcba */
3122
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT)
3123
{
3124
}
3125

    
3126
/***                    Segment register manipulation                      ***/
3127
/* Supervisor only: */
3128
/* mfsr */
3129
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3130
{
3131
#if defined(CONFIG_USER_ONLY)
3132
    RET_PRIVREG(ctx);
3133
#else
3134
    if (unlikely(!ctx->supervisor)) {
3135
        RET_PRIVREG(ctx);
3136
        return;
3137
    }
3138
    gen_op_set_T1(SR(ctx->opcode));
3139
    gen_op_load_sr();
3140
    gen_op_store_T0_gpr(rD(ctx->opcode));
3141
#endif
3142
}
3143

    
3144
/* mfsrin */
3145
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3146
{
3147
#if defined(CONFIG_USER_ONLY)
3148
    RET_PRIVREG(ctx);
3149
#else
3150
    if (unlikely(!ctx->supervisor)) {
3151
        RET_PRIVREG(ctx);
3152
        return;
3153
    }
3154
    gen_op_load_gpr_T1(rB(ctx->opcode));
3155
    gen_op_srli_T1(28);
3156
    gen_op_load_sr();
3157
    gen_op_store_T0_gpr(rD(ctx->opcode));
3158
#endif
3159
}
3160

    
3161
/* mtsr */
3162
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3163
{
3164
#if defined(CONFIG_USER_ONLY)
3165
    RET_PRIVREG(ctx);
3166
#else
3167
    if (unlikely(!ctx->supervisor)) {
3168
        RET_PRIVREG(ctx);
3169
        return;
3170
    }
3171
    gen_op_load_gpr_T0(rS(ctx->opcode));
3172
    gen_op_set_T1(SR(ctx->opcode));
3173
    gen_op_store_sr();
3174
    RET_STOP(ctx);
3175
#endif
3176
}
3177

    
3178
/* mtsrin */
3179
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3180
{
3181
#if defined(CONFIG_USER_ONLY)
3182
    RET_PRIVREG(ctx);
3183
#else
3184
    if (unlikely(!ctx->supervisor)) {
3185
        RET_PRIVREG(ctx);
3186
        return;
3187
    }
3188
    gen_op_load_gpr_T0(rS(ctx->opcode));
3189
    gen_op_load_gpr_T1(rB(ctx->opcode));
3190
    gen_op_srli_T1(28);
3191
    gen_op_store_sr();
3192
    RET_STOP(ctx);
3193
#endif
3194
}
3195

    
3196
/***                      Lookaside buffer management                      ***/
3197
/* Optional & supervisor only: */
3198
/* tlbia */
3199
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3200
{
3201
#if defined(CONFIG_USER_ONLY)
3202
    RET_PRIVOPC(ctx);
3203
#else
3204
    if (unlikely(!ctx->supervisor)) {
3205
        if (loglevel)
3206
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3207
        RET_PRIVOPC(ctx);
3208
        return;
3209
    }
3210
    gen_op_tlbia();
3211
    RET_STOP(ctx);
3212
#endif
3213
}
3214

    
3215
/* tlbie */
3216
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3217
{
3218
#if defined(CONFIG_USER_ONLY)
3219
    RET_PRIVOPC(ctx);
3220
#else
3221
    if (unlikely(!ctx->supervisor)) {
3222
        RET_PRIVOPC(ctx);
3223
        return;
3224
    }
3225
    gen_op_load_gpr_T0(rB(ctx->opcode));
3226
#if defined(TARGET_PPC64)
3227
    if (ctx->sf_mode)
3228
        gen_op_tlbie_64();
3229
    else
3230
#endif
3231
        gen_op_tlbie();
3232
    RET_STOP(ctx);
3233
#endif
3234
}
3235

    
3236
/* tlbsync */
3237
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3238
{
3239
#if defined(CONFIG_USER_ONLY)
3240
    RET_PRIVOPC(ctx);
3241
#else
3242
    if (unlikely(!ctx->supervisor)) {
3243
        RET_PRIVOPC(ctx);
3244
        return;
3245
    }
3246
    /* This has no effect: it should ensure that all previous
3247
     * tlbie have completed
3248
     */
3249
    RET_STOP(ctx);
3250
#endif
3251
}
3252

    
3253
/***                              External control                         ***/
3254
/* Optional: */
3255
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3256
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3257
#if defined(TARGET_PPC64)
3258
#if defined(CONFIG_USER_ONLY)
3259
static GenOpFunc *gen_op_eciwx[] = {
3260
    &gen_op_eciwx_raw,
3261
    &gen_op_eciwx_le_raw,
3262
    &gen_op_eciwx_64_raw,
3263
    &gen_op_eciwx_le_64_raw,
3264
};
3265
static GenOpFunc *gen_op_ecowx[] = {
3266
    &gen_op_ecowx_raw,
3267
    &gen_op_ecowx_le_raw,
3268
    &gen_op_ecowx_64_raw,
3269
    &gen_op_ecowx_le_64_raw,
3270
};
3271
#else
3272
static GenOpFunc *gen_op_eciwx[] = {
3273
    &gen_op_eciwx_user,
3274
    &gen_op_eciwx_le_user,
3275
    &gen_op_eciwx_kernel,
3276
    &gen_op_eciwx_le_kernel,
3277
    &gen_op_eciwx_64_user,
3278
    &gen_op_eciwx_le_64_user,
3279
    &gen_op_eciwx_64_kernel,
3280
    &gen_op_eciwx_le_64_kernel,
3281
};
3282
static GenOpFunc *gen_op_ecowx[] = {
3283
    &gen_op_ecowx_user,
3284
    &gen_op_ecowx_le_user,
3285
    &gen_op_ecowx_kernel,
3286
    &gen_op_ecowx_le_kernel,
3287
    &gen_op_ecowx_64_user,
3288
    &gen_op_ecowx_le_64_user,
3289
    &gen_op_ecowx_64_kernel,
3290
    &gen_op_ecowx_le_64_kernel,
3291
};
3292
#endif
3293
#else
3294
#if defined(CONFIG_USER_ONLY)
3295
static GenOpFunc *gen_op_eciwx[] = {
3296
    &gen_op_eciwx_raw,
3297
    &gen_op_eciwx_le_raw,
3298
};
3299
static GenOpFunc *gen_op_ecowx[] = {
3300
    &gen_op_ecowx_raw,
3301
    &gen_op_ecowx_le_raw,
3302
};
3303
#else
3304
static GenOpFunc *gen_op_eciwx[] = {
3305
    &gen_op_eciwx_user,
3306
    &gen_op_eciwx_le_user,
3307
    &gen_op_eciwx_kernel,
3308
    &gen_op_eciwx_le_kernel,
3309
};
3310
static GenOpFunc *gen_op_ecowx[] = {
3311
    &gen_op_ecowx_user,
3312
    &gen_op_ecowx_le_user,
3313
    &gen_op_ecowx_kernel,
3314
    &gen_op_ecowx_le_kernel,
3315
};
3316
#endif
3317
#endif
3318

    
3319
/* eciwx */
3320
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3321
{
3322
    /* Should check EAR[E] & alignment ! */
3323
    gen_addr_reg_index(ctx);
3324
    op_eciwx();
3325
    gen_op_store_T0_gpr(rD(ctx->opcode));
3326
}
3327

    
3328
/* ecowx */
3329
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3330
{
3331
    /* Should check EAR[E] & alignment ! */
3332
    gen_addr_reg_index(ctx);
3333
    gen_op_load_gpr_T1(rS(ctx->opcode));
3334
    op_ecowx();
3335
}
3336

    
3337
/* PowerPC 601 specific instructions */
3338
/* abs - abs. */
3339
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3340
{
3341
    gen_op_load_gpr_T0(rA(ctx->opcode));
3342
    gen_op_POWER_abs();
3343
    gen_op_store_T0_gpr(rD(ctx->opcode));
3344
    if (unlikely(Rc(ctx->opcode) != 0))
3345
        gen_set_Rc0(ctx);
3346
}
3347

    
3348
/* abso - abso. */
3349
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3350
{
3351
    gen_op_load_gpr_T0(rA(ctx->opcode));
3352
    gen_op_POWER_abso();
3353
    gen_op_store_T0_gpr(rD(ctx->opcode));
3354
    if (unlikely(Rc(ctx->opcode) != 0))
3355
        gen_set_Rc0(ctx);
3356
}
3357

    
3358
/* clcs */
3359
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR) /* 601 ? */
3360
{
3361
    gen_op_load_gpr_T0(rA(ctx->opcode));
3362
    gen_op_POWER_clcs();
3363
    gen_op_store_T0_gpr(rD(ctx->opcode));
3364
}
3365

    
3366
/* div - div. */
3367
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3368
{
3369
    gen_op_load_gpr_T0(rA(ctx->opcode));
3370
    gen_op_load_gpr_T1(rB(ctx->opcode));
3371
    gen_op_POWER_div();
3372
    gen_op_store_T0_gpr(rD(ctx->opcode));
3373
    if (unlikely(Rc(ctx->opcode) != 0))
3374
        gen_set_Rc0(ctx);
3375
}
3376

    
3377
/* divo - divo. */
3378
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3379
{
3380
    gen_op_load_gpr_T0(rA(ctx->opcode));
3381
    gen_op_load_gpr_T1(rB(ctx->opcode));
3382
    gen_op_POWER_divo();
3383
    gen_op_store_T0_gpr(rD(ctx->opcode));
3384
    if (unlikely(Rc(ctx->opcode) != 0))
3385
        gen_set_Rc0(ctx);
3386
}
3387

    
3388
/* divs - divs. */
3389
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3390
{
3391
    gen_op_load_gpr_T0(rA(ctx->opcode));
3392
    gen_op_load_gpr_T1(rB(ctx->opcode));
3393
    gen_op_POWER_divs();
3394
    gen_op_store_T0_gpr(rD(ctx->opcode));
3395
    if (unlikely(Rc(ctx->opcode) != 0))
3396
        gen_set_Rc0(ctx);
3397
}
3398

    
3399
/* divso - divso. */
3400
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3401
{
3402
    gen_op_load_gpr_T0(rA(ctx->opcode));
3403
    gen_op_load_gpr_T1(rB(ctx->opcode));
3404
    gen_op_POWER_divso();
3405
    gen_op_store_T0_gpr(rD(ctx->opcode));
3406
    if (unlikely(Rc(ctx->opcode) != 0))
3407
        gen_set_Rc0(ctx);
3408
}
3409

    
3410
/* doz - doz. */
3411
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3412
{
3413
    gen_op_load_gpr_T0(rA(ctx->opcode));
3414
    gen_op_load_gpr_T1(rB(ctx->opcode));
3415
    gen_op_POWER_doz();
3416
    gen_op_store_T0_gpr(rD(ctx->opcode));
3417
    if (unlikely(Rc(ctx->opcode) != 0))
3418
        gen_set_Rc0(ctx);
3419
}
3420

    
3421
/* dozo - dozo. */
3422
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3423
{
3424
    gen_op_load_gpr_T0(rA(ctx->opcode));
3425
    gen_op_load_gpr_T1(rB(ctx->opcode));
3426
    gen_op_POWER_dozo();
3427
    gen_op_store_T0_gpr(rD(ctx->opcode));
3428
    if (unlikely(Rc(ctx->opcode) != 0))
3429
        gen_set_Rc0(ctx);
3430
}
3431

    
3432
/* dozi */
3433
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3434
{
3435
    gen_op_load_gpr_T0(rA(ctx->opcode));
3436
    gen_op_set_T1(SIMM(ctx->opcode));
3437
    gen_op_POWER_doz();
3438
    gen_op_store_T0_gpr(rD(ctx->opcode));
3439
}
3440

    
3441
/* As lscbx load from memory byte after byte, it's always endian safe */
3442
#define op_POWER_lscbx(start, ra, rb) \
3443
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3444
#if defined(CONFIG_USER_ONLY)
3445
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3446
    &gen_op_POWER_lscbx_raw,
3447
    &gen_op_POWER_lscbx_raw,
3448
};
3449
#else
3450
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3451
    &gen_op_POWER_lscbx_user,
3452
    &gen_op_POWER_lscbx_user,
3453
    &gen_op_POWER_lscbx_kernel,
3454
    &gen_op_POWER_lscbx_kernel,
3455
};
3456
#endif
3457

    
3458
/* lscbx - lscbx. */
3459
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3460
{
3461
    int ra = rA(ctx->opcode);
3462
    int rb = rB(ctx->opcode);
3463

    
3464
    gen_addr_reg_index(ctx);
3465
    if (ra == 0) {
3466
        ra = rb;
3467
    }
3468
    /* NIP cannot be restored if the memory exception comes from an helper */
3469
    gen_update_nip(ctx, ctx->nip - 4);
3470
    gen_op_load_xer_bc();
3471
    gen_op_load_xer_cmp();
3472
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3473
    gen_op_store_xer_bc();
3474
    if (unlikely(Rc(ctx->opcode) != 0))
3475
        gen_set_Rc0(ctx);
3476
}
3477

    
3478
/* maskg - maskg. */
3479
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3480
{
3481
    gen_op_load_gpr_T0(rS(ctx->opcode));
3482
    gen_op_load_gpr_T1(rB(ctx->opcode));
3483
    gen_op_POWER_maskg();
3484
    gen_op_store_T0_gpr(rA(ctx->opcode));
3485
    if (unlikely(Rc(ctx->opcode) != 0))
3486
        gen_set_Rc0(ctx);
3487
}
3488

    
3489
/* maskir - maskir. */
3490
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3491
{
3492
    gen_op_load_gpr_T0(rA(ctx->opcode));
3493
    gen_op_load_gpr_T1(rS(ctx->opcode));
3494
    gen_op_load_gpr_T2(rB(ctx->opcode));
3495
    gen_op_POWER_maskir();
3496
    gen_op_store_T0_gpr(rA(ctx->opcode));
3497
    if (unlikely(Rc(ctx->opcode) != 0))
3498
        gen_set_Rc0(ctx);
3499
}
3500

    
3501
/* mul - mul. */
3502
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
3503
{
3504
    gen_op_load_gpr_T0(rA(ctx->opcode));
3505
    gen_op_load_gpr_T1(rB(ctx->opcode));
3506
    gen_op_POWER_mul();
3507
    gen_op_store_T0_gpr(rD(ctx->opcode));
3508
    if (unlikely(Rc(ctx->opcode) != 0))
3509
        gen_set_Rc0(ctx);
3510
}
3511

    
3512
/* mulo - mulo. */
3513
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
3514
{
3515
    gen_op_load_gpr_T0(rA(ctx->opcode));
3516
    gen_op_load_gpr_T1(rB(ctx->opcode));
3517
    gen_op_POWER_mulo();
3518
    gen_op_store_T0_gpr(rD(ctx->opcode));
3519
    if (unlikely(Rc(ctx->opcode) != 0))
3520
        gen_set_Rc0(ctx);
3521
}
3522

    
3523
/* nabs - nabs. */
3524
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
3525
{
3526
    gen_op_load_gpr_T0(rA(ctx->opcode));
3527
    gen_op_POWER_nabs();
3528
    gen_op_store_T0_gpr(rD(ctx->opcode));
3529
    if (unlikely(Rc(ctx->opcode) != 0))
3530
        gen_set_Rc0(ctx);
3531
}
3532

    
3533
/* nabso - nabso. */
3534
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
3535
{
3536
    gen_op_load_gpr_T0(rA(ctx->opcode));
3537
    gen_op_POWER_nabso();
3538
    gen_op_store_T0_gpr(rD(ctx->opcode));
3539
    if (unlikely(Rc(ctx->opcode) != 0))
3540
        gen_set_Rc0(ctx);
3541
}
3542

    
3543
/* rlmi - rlmi. */
3544
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3545
{
3546
    uint32_t mb, me;
3547

    
3548
    mb = MB(ctx->opcode);
3549
    me = ME(ctx->opcode);
3550
    gen_op_load_gpr_T0(rS(ctx->opcode));
3551
    gen_op_load_gpr_T1(rA(ctx->opcode));
3552
    gen_op_load_gpr_T2(rB(ctx->opcode));
3553
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
3554
    gen_op_store_T0_gpr(rA(ctx->opcode));
3555
    if (unlikely(Rc(ctx->opcode) != 0))
3556
        gen_set_Rc0(ctx);
3557
}
3558

    
3559
/* rrib - rrib. */
3560
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
3561
{
3562
    gen_op_load_gpr_T0(rS(ctx->opcode));
3563
    gen_op_load_gpr_T1(rA(ctx->opcode));
3564
    gen_op_load_gpr_T2(rB(ctx->opcode));
3565
    gen_op_POWER_rrib();
3566
    gen_op_store_T0_gpr(rA(ctx->opcode));
3567
    if (unlikely(Rc(ctx->opcode) != 0))
3568
        gen_set_Rc0(ctx);
3569
}
3570

    
3571
/* sle - sle. */
3572
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
3573
{
3574
    gen_op_load_gpr_T0(rS(ctx->opcode));
3575
    gen_op_load_gpr_T1(rB(ctx->opcode));
3576
    gen_op_POWER_sle();
3577
    gen_op_store_T0_gpr(rA(ctx->opcode));
3578
    if (unlikely(Rc(ctx->opcode) != 0))
3579
        gen_set_Rc0(ctx);
3580
}
3581

    
3582
/* sleq - sleq. */
3583
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
3584
{
3585
    gen_op_load_gpr_T0(rS(ctx->opcode));
3586
    gen_op_load_gpr_T1(rB(ctx->opcode));
3587
    gen_op_POWER_sleq();
3588
    gen_op_store_T0_gpr(rA(ctx->opcode));
3589
    if (unlikely(Rc(ctx->opcode) != 0))
3590
        gen_set_Rc0(ctx);
3591
}
3592

    
3593
/* sliq - sliq. */
3594
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
3595
{
3596
    gen_op_load_gpr_T0(rS(ctx->opcode));
3597
    gen_op_set_T1(SH(ctx->opcode));
3598
    gen_op_POWER_sle();
3599
    gen_op_store_T0_gpr(rA(ctx->opcode));
3600
    if (unlikely(Rc(ctx->opcode) != 0))
3601
        gen_set_Rc0(ctx);
3602
}
3603

    
3604
/* slliq - slliq. */
3605
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
3606
{
3607
    gen_op_load_gpr_T0(rS(ctx->opcode));
3608
    gen_op_set_T1(SH(ctx->opcode));
3609
    gen_op_POWER_sleq();
3610
    gen_op_store_T0_gpr(rA(ctx->opcode));
3611
    if (unlikely(Rc(ctx->opcode) != 0))
3612
        gen_set_Rc0(ctx);
3613
}
3614

    
3615
/* sllq - sllq. */
3616
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
3617
{
3618
    gen_op_load_gpr_T0(rS(ctx->opcode));
3619
    gen_op_load_gpr_T1(rB(ctx->opcode));
3620
    gen_op_POWER_sllq();
3621
    gen_op_store_T0_gpr(rA(ctx->opcode));
3622
    if (unlikely(Rc(ctx->opcode) != 0))
3623
        gen_set_Rc0(ctx);
3624
}
3625

    
3626
/* slq - slq. */
3627
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
3628
{
3629
    gen_op_load_gpr_T0(rS(ctx->opcode));
3630
    gen_op_load_gpr_T1(rB(ctx->opcode));
3631
    gen_op_POWER_slq();
3632
    gen_op_store_T0_gpr(rA(ctx->opcode));
3633
    if (unlikely(Rc(ctx->opcode) != 0))
3634
        gen_set_Rc0(ctx);
3635
}
3636

    
3637
/* sraiq - sraiq. */
3638
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
3639
{
3640
    gen_op_load_gpr_T0(rS(ctx->opcode));
3641
    gen_op_set_T1(SH(ctx->opcode));
3642
    gen_op_POWER_sraq();
3643
    gen_op_store_T0_gpr(rA(ctx->opcode));
3644
    if (unlikely(Rc(ctx->opcode) != 0))
3645
        gen_set_Rc0(ctx);
3646
}
3647

    
3648
/* sraq - sraq. */
3649
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
3650
{
3651
    gen_op_load_gpr_T0(rS(ctx->opcode));
3652
    gen_op_load_gpr_T1(rB(ctx->opcode));
3653
    gen_op_POWER_sraq();
3654
    gen_op_store_T0_gpr(rA(ctx->opcode));
3655
    if (unlikely(Rc(ctx->opcode) != 0))
3656
        gen_set_Rc0(ctx);
3657
}
3658

    
3659
/* sre - sre. */
3660
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
3661
{
3662
    gen_op_load_gpr_T0(rS(ctx->opcode));
3663
    gen_op_load_gpr_T1(rB(ctx->opcode));
3664
    gen_op_POWER_sre();
3665
    gen_op_store_T0_gpr(rA(ctx->opcode));
3666
    if (unlikely(Rc(ctx->opcode) != 0))
3667
        gen_set_Rc0(ctx);
3668
}
3669

    
3670
/* srea - srea. */
3671
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
3672
{
3673
    gen_op_load_gpr_T0(rS(ctx->opcode));
3674
    gen_op_load_gpr_T1(rB(ctx->opcode));
3675
    gen_op_POWER_srea();
3676
    gen_op_store_T0_gpr(rA(ctx->opcode));
3677
    if (unlikely(Rc(ctx->opcode) != 0))
3678
        gen_set_Rc0(ctx);
3679
}
3680

    
3681
/* sreq */
3682
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
3683
{
3684
    gen_op_load_gpr_T0(rS(ctx->opcode));
3685
    gen_op_load_gpr_T1(rB(ctx->opcode));
3686
    gen_op_POWER_sreq();
3687
    gen_op_store_T0_gpr(rA(ctx->opcode));
3688
    if (unlikely(Rc(ctx->opcode) != 0))
3689
        gen_set_Rc0(ctx);
3690
}
3691

    
3692
/* sriq */
3693
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
3694
{
3695
    gen_op_load_gpr_T0(rS(ctx->opcode));
3696
    gen_op_set_T1(SH(ctx->opcode));
3697
    gen_op_POWER_srq();
3698
    gen_op_store_T0_gpr(rA(ctx->opcode));
3699
    if (unlikely(Rc(ctx->opcode) != 0))
3700
        gen_set_Rc0(ctx);
3701
}
3702

    
3703
/* srliq */
3704
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
3705
{
3706
    gen_op_load_gpr_T0(rS(ctx->opcode));
3707
    gen_op_load_gpr_T1(rB(ctx->opcode));
3708
    gen_op_set_T1(SH(ctx->opcode));
3709
    gen_op_POWER_srlq();
3710
    gen_op_store_T0_gpr(rA(ctx->opcode));
3711
    if (unlikely(Rc(ctx->opcode) != 0))
3712
        gen_set_Rc0(ctx);
3713
}
3714

    
3715
/* srlq */
3716
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
3717
{
3718
    gen_op_load_gpr_T0(rS(ctx->opcode));
3719
    gen_op_load_gpr_T1(rB(ctx->opcode));
3720
    gen_op_POWER_srlq();
3721
    gen_op_store_T0_gpr(rA(ctx->opcode));
3722
    if (unlikely(Rc(ctx->opcode) != 0))
3723
        gen_set_Rc0(ctx);
3724
}
3725

    
3726
/* srq */
3727
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
3728
{
3729
    gen_op_load_gpr_T0(rS(ctx->opcode));
3730
    gen_op_load_gpr_T1(rB(ctx->opcode));
3731
    gen_op_POWER_srq();
3732
    gen_op_store_T0_gpr(rA(ctx->opcode));
3733
    if (unlikely(Rc(ctx->opcode) != 0))
3734
        gen_set_Rc0(ctx);
3735
}
3736

    
3737
/* PowerPC 602 specific instructions */
3738
/* dsa  */
3739
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
3740
{
3741
    /* XXX: TODO */
3742
    RET_INVAL(ctx);
3743
}
3744

    
3745
/* esa */
3746
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
3747
{
3748
    /* XXX: TODO */
3749
    RET_INVAL(ctx);
3750
}
3751

    
3752
/* mfrom */
3753
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
3754
{
3755
#if defined(CONFIG_USER_ONLY)
3756
    RET_PRIVOPC(ctx);
3757
#else
3758
    if (unlikely(!ctx->supervisor)) {
3759
        RET_PRIVOPC(ctx);
3760
        return;
3761
    }
3762
    gen_op_load_gpr_T0(rA(ctx->opcode));
3763
    gen_op_602_mfrom();
3764
    gen_op_store_T0_gpr(rD(ctx->opcode));
3765
#endif
3766
}
3767

    
3768
/* 602 - 603 - G2 TLB management */
3769
/* tlbld */
3770
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
3771
{
3772
#if defined(CONFIG_USER_ONLY)
3773
    RET_PRIVOPC(ctx);
3774
#else
3775
    if (unlikely(!ctx->supervisor)) {
3776
        RET_PRIVOPC(ctx);
3777
        return;
3778
    }
3779
    gen_op_load_gpr_T0(rB(ctx->opcode));
3780
    gen_op_6xx_tlbld();
3781
    RET_STOP(ctx);
3782
#endif
3783
}
3784

    
3785
/* tlbli */
3786
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
3787
{
3788
#if defined(CONFIG_USER_ONLY)
3789
    RET_PRIVOPC(ctx);
3790
#else
3791
    if (unlikely(!ctx->supervisor)) {
3792
        RET_PRIVOPC(ctx);
3793
        return;
3794
    }
3795
    gen_op_load_gpr_T0(rB(ctx->opcode));
3796
    gen_op_6xx_tlbli();
3797
    RET_STOP(ctx);
3798
#endif
3799
}
3800

    
3801
/* POWER instructions not in PowerPC 601 */
3802
/* clf */
3803
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
3804
{
3805
    /* Cache line flush: implemented as no-op */
3806
}
3807

    
3808
/* cli */
3809
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
3810
{
3811
    /* Cache line invalidate: priviledged and treated as no-op */
3812
#if defined(CONFIG_USER_ONLY)
3813
    RET_PRIVOPC(ctx);
3814
#else
3815
    if (unlikely(!ctx->supervisor)) {
3816
        RET_PRIVOPC(ctx);
3817
        return;
3818
    }
3819
#endif
3820
}
3821

    
3822
/* dclst */
3823
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
3824
{
3825
    /* Data cache line store: treated as no-op */
3826
}
3827

    
3828
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
3829
{
3830
#if defined(CONFIG_USER_ONLY)
3831
    RET_PRIVOPC(ctx);
3832
#else
3833
    if (unlikely(!ctx->supervisor)) {
3834
        RET_PRIVOPC(ctx);
3835
        return;
3836
    }
3837
    int ra = rA(ctx->opcode);
3838
    int rd = rD(ctx->opcode);
3839

    
3840
    gen_addr_reg_index(ctx);
3841
    gen_op_POWER_mfsri();
3842
    gen_op_store_T0_gpr(rd);
3843
    if (ra != 0 && ra != rd)
3844
        gen_op_store_T1_gpr(ra);
3845
#endif
3846
}
3847

    
3848
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
3849
{
3850
#if defined(CONFIG_USER_ONLY)
3851
    RET_PRIVOPC(ctx);
3852
#else
3853
    if (unlikely(!ctx->supervisor)) {
3854
        RET_PRIVOPC(ctx);
3855
        return;
3856
    }
3857
    gen_addr_reg_index(ctx);
3858
    gen_op_POWER_rac();
3859
    gen_op_store_T0_gpr(rD(ctx->opcode));
3860
#endif
3861
}
3862

    
3863
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
3864
{
3865
#if defined(CONFIG_USER_ONLY)
3866
    RET_PRIVOPC(ctx);
3867
#else
3868
    if (unlikely(!ctx->supervisor)) {
3869
        RET_PRIVOPC(ctx);
3870
        return;
3871
    }
3872
    gen_op_POWER_rfsvc();
3873
    RET_CHG_FLOW(ctx);
3874
#endif
3875
}
3876

    
3877
/* svc is not implemented for now */
3878

    
3879
/* POWER2 specific instructions */
3880
/* Quad manipulation (load/store two floats at a time) */
3881
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
3882
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
3883
#if defined(CONFIG_USER_ONLY)
3884
static GenOpFunc *gen_op_POWER2_lfq[] = {
3885
    &gen_op_POWER2_lfq_le_raw,
3886
    &gen_op_POWER2_lfq_raw,
3887
};
3888
static GenOpFunc *gen_op_POWER2_stfq[] = {
3889
    &gen_op_POWER2_stfq_le_raw,
3890
    &gen_op_POWER2_stfq_raw,
3891
};
3892
#else
3893
static GenOpFunc *gen_op_POWER2_lfq[] = {
3894
    &gen_op_POWER2_lfq_le_user,
3895
    &gen_op_POWER2_lfq_user,
3896
    &gen_op_POWER2_lfq_le_kernel,
3897
    &gen_op_POWER2_lfq_kernel,
3898
};
3899
static GenOpFunc *gen_op_POWER2_stfq[] = {
3900
    &gen_op_POWER2_stfq_le_user,
3901
    &gen_op_POWER2_stfq_user,
3902
    &gen_op_POWER2_stfq_le_kernel,
3903
    &gen_op_POWER2_stfq_kernel,
3904
};
3905
#endif
3906

    
3907
/* lfq */
3908
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3909
{
3910
    /* NIP cannot be restored if the memory exception comes from an helper */
3911
    gen_update_nip(ctx, ctx->nip - 4);
3912
    gen_addr_imm_index(ctx);
3913
    op_POWER2_lfq();
3914
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3915
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3916
}
3917

    
3918
/* lfqu */
3919
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3920
{
3921
    int ra = rA(ctx->opcode);
3922

    
3923
    /* NIP cannot be restored if the memory exception comes from an helper */
3924
    gen_update_nip(ctx, ctx->nip - 4);
3925
    gen_addr_imm_index(ctx);
3926
    op_POWER2_lfq();
3927
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3928
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3929
    if (ra != 0)
3930
        gen_op_store_T0_gpr(ra);
3931
}
3932

    
3933
/* lfqux */
3934
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
3935
{
3936
    int ra = rA(ctx->opcode);
3937

    
3938
    /* NIP cannot be restored if the memory exception comes from an helper */
3939
    gen_update_nip(ctx, ctx->nip - 4);
3940
    gen_addr_reg_index(ctx);
3941
    op_POWER2_lfq();
3942
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3943
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3944
    if (ra != 0)
3945
        gen_op_store_T0_gpr(ra);
3946
}
3947

    
3948
/* lfqx */
3949
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
3950
{
3951
    /* NIP cannot be restored if the memory exception comes from an helper */
3952
    gen_update_nip(ctx, ctx->nip - 4);
3953
    gen_addr_reg_index(ctx);
3954
    op_POWER2_lfq();
3955
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3956
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3957
}
3958

    
3959
/* stfq */
3960
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3961
{
3962
    /* NIP cannot be restored if the memory exception comes from an helper */
3963
    gen_update_nip(ctx, ctx->nip - 4);
3964
    gen_addr_imm_index(ctx);
3965
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3966
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3967
    op_POWER2_stfq();
3968
}
3969

    
3970
/* stfqu */
3971
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3972
{
3973
    int ra = rA(ctx->opcode);
3974

    
3975
    /* NIP cannot be restored if the memory exception comes from an helper */
3976
    gen_update_nip(ctx, ctx->nip - 4);
3977
    gen_addr_imm_index(ctx);
3978
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3979
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3980
    op_POWER2_stfq();
3981
    if (ra != 0)
3982
        gen_op_store_T0_gpr(ra);
3983
}
3984

    
3985
/* stfqux */
3986
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
3987
{
3988
    int ra = rA(ctx->opcode);
3989

    
3990
    /* NIP cannot be restored if the memory exception comes from an helper */
3991
    gen_update_nip(ctx, ctx->nip - 4);
3992
    gen_addr_reg_index(ctx);
3993
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3994
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3995
    op_POWER2_stfq();
3996
    if (ra != 0)
3997
        gen_op_store_T0_gpr(ra);
3998
}
3999

    
4000
/* stfqx */
4001
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4002
{
4003
    /* NIP cannot be restored if the memory exception comes from an helper */
4004
    gen_update_nip(ctx, ctx->nip - 4);
4005
    gen_addr_reg_index(ctx);
4006
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4007
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4008
    op_POWER2_stfq();
4009
}
4010

    
4011
/* BookE specific instructions */
4012
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE)
4013
{
4014
    /* XXX: TODO */
4015
    RET_INVAL(ctx);
4016
}
4017

    
4018
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE)
4019
{
4020
#if defined(CONFIG_USER_ONLY)
4021
    RET_PRIVOPC(ctx);
4022
#else
4023
    if (unlikely(!ctx->supervisor)) {
4024
        RET_PRIVOPC(ctx);
4025
        return;
4026
    }
4027
    gen_addr_reg_index(ctx);
4028
    /* Use the same micro-ops as for tlbie */
4029
#if defined(TARGET_PPC64)
4030
    if (ctx->sf_mode)
4031
        gen_op_tlbie_64();
4032
    else
4033
#endif
4034
        gen_op_tlbie();
4035
    RET_STOP(ctx);
4036
#endif
4037
}
4038

    
4039
/* All 405 MAC instructions are translated here */
4040
static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
4041
                                         int ra, int rb, int rt, int Rc)
4042
{
4043
    gen_op_load_gpr_T0(ra);
4044
    gen_op_load_gpr_T1(rb);
4045
    switch (opc3 & 0x0D) {
4046
    case 0x05:
4047
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4048
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4049
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4050
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4051
        /* mulchw - mulchw. */
4052
        gen_op_405_mulchw();
4053
        break;
4054
    case 0x04:
4055
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4056
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4057
        /* mulchwu - mulchwu. */
4058
        gen_op_405_mulchwu();
4059
        break;
4060
    case 0x01:
4061
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4062
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4063
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4064
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4065
        /* mulhhw - mulhhw. */
4066
        gen_op_405_mulhhw();
4067
        break;
4068
    case 0x00:
4069
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4070
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4071
        /* mulhhwu - mulhhwu. */
4072
        gen_op_405_mulhhwu();
4073
        break;
4074
    case 0x0D:
4075
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4076
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4077
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4078
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4079
        /* mullhw - mullhw. */
4080
        gen_op_405_mullhw();
4081
        break;
4082
    case 0x0C:
4083
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4084
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4085
        /* mullhwu - mullhwu. */
4086
        gen_op_405_mullhwu();
4087
        break;
4088
    }
4089
    if (opc2 & 0x02) {
4090
        /* nmultiply-and-accumulate (0x0E) */
4091
        gen_op_neg();
4092
    }
4093
    if (opc2 & 0x04) {
4094
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4095
        gen_op_load_gpr_T2(rt);
4096
        gen_op_move_T1_T0();
4097
        gen_op_405_add_T0_T2();
4098
    }
4099
    if (opc3 & 0x10) {
4100
        /* Check overflow */
4101
        if (opc3 & 0x01)
4102
            gen_op_405_check_ov();
4103
        else
4104
            gen_op_405_check_ovu();
4105
    }
4106
    if (opc3 & 0x02) {
4107
        /* Saturate */
4108
        if (opc3 & 0x01)
4109
            gen_op_405_check_sat();
4110
        else
4111
            gen_op_405_check_satu();
4112
    }
4113
    gen_op_store_T0_gpr(rt);
4114
    if (unlikely(Rc) != 0) {
4115
        /* Update Rc0 */
4116
        gen_set_Rc0(ctx);
4117
    }
4118
}
4119

    
4120
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4121
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4122
{                                                                             \
4123
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4124
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4125
}
4126

    
4127
/* macchw    - macchw.    */
4128
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4129
/* macchwo   - macchwo.   */
4130
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4131
/* macchws   - macchws.   */
4132
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4133
/* macchwso  - macchwso.  */
4134
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4135
/* macchwsu  - macchwsu.  */
4136
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4137
/* macchwsuo - macchwsuo. */
4138
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4139
/* macchwu   - macchwu.   */
4140
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4141
/* macchwuo  - macchwuo.  */
4142
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4143
/* machhw    - machhw.    */
4144
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4145
/* machhwo   - machhwo.   */
4146
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4147
/* machhws   - machhws.   */
4148
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4149
/* machhwso  - machhwso.  */
4150
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4151
/* machhwsu  - machhwsu.  */
4152
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4153
/* machhwsuo - machhwsuo. */
4154
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4155
/* machhwu   - machhwu.   */
4156
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4157
/* machhwuo  - machhwuo.  */
4158
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4159
/* maclhw    - maclhw.    */
4160
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4161
/* maclhwo   - maclhwo.   */
4162
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4163
/* maclhws   - maclhws.   */
4164
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4165
/* maclhwso  - maclhwso.  */
4166
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4167
/* maclhwu   - maclhwu.   */
4168
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4169
/* maclhwuo  - maclhwuo.  */
4170
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4171
/* maclhwsu  - maclhwsu.  */
4172
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4173
/* maclhwsuo - maclhwsuo. */
4174
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4175
/* nmacchw   - nmacchw.   */
4176
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4177
/* nmacchwo  - nmacchwo.  */
4178
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4179
/* nmacchws  - nmacchws.  */
4180
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4181
/* nmacchwso - nmacchwso. */
4182
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4183
/* nmachhw   - nmachhw.   */
4184
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4185
/* nmachhwo  - nmachhwo.  */
4186
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4187
/* nmachhws  - nmachhws.  */
4188
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4189
/* nmachhwso - nmachhwso. */
4190
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4191
/* nmaclhw   - nmaclhw.   */
4192
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4193
/* nmaclhwo  - nmaclhwo.  */
4194
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4195
/* nmaclhws  - nmaclhws.  */
4196
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4197
/* nmaclhwso - nmaclhwso. */
4198
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4199

    
4200
/* mulchw  - mulchw.  */
4201
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4202
/* mulchwu - mulchwu. */
4203
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4204
/* mulhhw  - mulhhw.  */
4205
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4206
/* mulhhwu - mulhhwu. */
4207
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4208
/* mullhw  - mullhw.  */
4209
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4210
/* mullhwu - mullhwu. */
4211
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4212

    
4213
/* mfdcr */
4214
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4215
{
4216
#if defined(CONFIG_USER_ONLY)
4217
    RET_PRIVREG(ctx);
4218
#else
4219
    uint32_t dcrn = SPR(ctx->opcode);
4220

    
4221
    if (unlikely(!ctx->supervisor)) {
4222
        RET_PRIVREG(ctx);
4223
        return;
4224
    }
4225
    gen_op_4xx_load_dcr(dcrn);
4226
    gen_op_store_T0_gpr(rD(ctx->opcode));
4227
#endif
4228
}
4229

    
4230
/* mtdcr */
4231
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4232
{
4233
#if defined(CONFIG_USER_ONLY)
4234
    RET_PRIVREG(ctx);
4235
#else
4236
    uint32_t dcrn = SPR(ctx->opcode);
4237

    
4238
    if (unlikely(!ctx->supervisor)) {
4239
        RET_PRIVREG(ctx);
4240
        return;
4241
    }
4242
    gen_op_load_gpr_T0(rS(ctx->opcode));
4243
    gen_op_4xx_store_dcr(dcrn);
4244
#endif
4245
}
4246

    
4247
/* dccci */
4248
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4249
{
4250
#if defined(CONFIG_USER_ONLY)
4251
    RET_PRIVOPC(ctx);
4252
#else
4253
    if (unlikely(!ctx->supervisor)) {
4254
        RET_PRIVOPC(ctx);
4255
        return;
4256
    }
4257
    /* interpreted as no-op */
4258
#endif
4259
}
4260

    
4261
/* dcread */
4262
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4263
{
4264
#if defined(CONFIG_USER_ONLY)
4265
    RET_PRIVOPC(ctx);
4266
#else
4267
    if (unlikely(!ctx->supervisor)) {
4268
        RET_PRIVOPC(ctx);
4269
        return;
4270
    }
4271
    gen_addr_reg_index(ctx);
4272
    op_ldst(lwz);
4273
    gen_op_store_T0_gpr(rD(ctx->opcode));
4274
#endif
4275
}
4276

    
4277
/* icbt */
4278
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC)
4279
{
4280
    /* interpreted as no-op */
4281
    /* XXX: specification say this is treated as a load by the MMU
4282
     *      but does not generate any exception
4283
     */
4284
}
4285

    
4286
/* iccci */
4287
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4288
{
4289
#if defined(CONFIG_USER_ONLY)
4290
    RET_PRIVOPC(ctx);
4291
#else
4292
    if (unlikely(!ctx->supervisor)) {
4293
        RET_PRIVOPC(ctx);
4294
        return;
4295
    }
4296
    /* interpreted as no-op */
4297
#endif
4298
}
4299

    
4300
/* icread */
4301
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4302
{
4303
#if defined(CONFIG_USER_ONLY)
4304
    RET_PRIVOPC(ctx);
4305
#else
4306
    if (unlikely(!ctx->supervisor)) {
4307
        RET_PRIVOPC(ctx);
4308
        return;
4309
    }
4310
    /* interpreted as no-op */
4311
#endif
4312
}
4313

    
4314
/* rfci (supervisor only) */
4315
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_EMB_COMMON)
4316
{
4317
#if defined(CONFIG_USER_ONLY)
4318
    RET_PRIVOPC(ctx);
4319
#else
4320
    if (unlikely(!ctx->supervisor)) {
4321
        RET_PRIVOPC(ctx);
4322
        return;
4323
    }
4324
    /* Restore CPU state */
4325
    gen_op_4xx_rfci();
4326
    RET_CHG_FLOW(ctx);
4327
#endif
4328
}
4329

    
4330
/* TLB management - PowerPC 405 implementation */
4331
/* tlbre */
4332
GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_EMB_COMMON)
4333
{
4334
#if defined(CONFIG_USER_ONLY)
4335
    RET_PRIVOPC(ctx);
4336
#else
4337
    if (unlikely(!ctx->supervisor)) {
4338
        RET_PRIVOPC(ctx);
4339
        return;
4340
    }
4341
    switch (rB(ctx->opcode)) {
4342
    case 0:
4343
        gen_op_load_gpr_T0(rA(ctx->opcode));
4344
        gen_op_4xx_tlbre_hi();
4345
        gen_op_store_T0_gpr(rD(ctx->opcode));
4346
        break;
4347
    case 1:
4348
        gen_op_load_gpr_T0(rA(ctx->opcode));
4349
        gen_op_4xx_tlbre_lo();
4350
        gen_op_store_T0_gpr(rD(ctx->opcode));
4351
        break;
4352
    default:
4353
        RET_INVAL(ctx);
4354
        break;
4355
    }
4356
#endif
4357
}
4358

    
4359
/* tlbsx - tlbsx. */
4360
GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_EMB_COMMON)
4361
{
4362
#if defined(CONFIG_USER_ONLY)
4363
    RET_PRIVOPC(ctx);
4364
#else
4365
    if (unlikely(!ctx->supervisor)) {
4366
        RET_PRIVOPC(ctx);
4367
        return;
4368
    }
4369
    gen_addr_reg_index(ctx);
4370
    if (Rc(ctx->opcode))
4371
        gen_op_4xx_tlbsx_();
4372
    else
4373
        gen_op_4xx_tlbsx();
4374
    gen_op_store_T0_gpr(rD(ctx->opcode));
4375
#endif
4376
}
4377

    
4378
/* tlbwe */
4379
GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC)
4380
{
4381
#if defined(CONFIG_USER_ONLY)
4382
    RET_PRIVOPC(ctx);
4383
#else
4384
    if (unlikely(!ctx->supervisor)) {
4385
        RET_PRIVOPC(ctx);
4386
        return;
4387
    }
4388
    switch (rB(ctx->opcode)) {
4389
    case 0:
4390
        gen_op_load_gpr_T0(rA(ctx->opcode));
4391
        gen_op_load_gpr_T1(rS(ctx->opcode));
4392
        gen_op_4xx_tlbwe_hi();
4393
        break;
4394
    case 1:
4395
        gen_op_load_gpr_T0(rA(ctx->opcode));
4396
        gen_op_load_gpr_T1(rS(ctx->opcode));
4397
        gen_op_4xx_tlbwe_lo();
4398
        break;
4399
    default:
4400
        RET_INVAL(ctx);
4401
        break;
4402
    }
4403
#endif
4404
}
4405

    
4406
/* wrtee */
4407
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4408
{
4409
#if defined(CONFIG_USER_ONLY)
4410
    RET_PRIVOPC(ctx);
4411
#else
4412
    if (unlikely(!ctx->supervisor)) {
4413
        RET_PRIVOPC(ctx);
4414
        return;
4415
    }
4416
    gen_op_load_gpr_T0(rD(ctx->opcode));
4417
    gen_op_4xx_wrte();
4418
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4419
#endif
4420
}
4421

    
4422
/* wrteei */
4423
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4424
{
4425
#if defined(CONFIG_USER_ONLY)
4426
    RET_PRIVOPC(ctx);
4427
#else
4428
    if (unlikely(!ctx->supervisor)) {
4429
        RET_PRIVOPC(ctx);
4430
        return;
4431
    }
4432
    gen_op_set_T0(ctx->opcode & 0x00010000);
4433
    gen_op_4xx_wrte();
4434
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4435
#endif
4436
}
4437

    
4438
/* PPC 440 specific instructions */
4439
/* dlmzb */
4440
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
4441
{
4442
    gen_op_load_gpr_T0(rS(ctx->opcode));
4443
    gen_op_load_gpr_T1(rB(ctx->opcode));
4444
    gen_op_440_dlmzb();
4445
    gen_op_store_T0_gpr(rA(ctx->opcode));
4446
    gen_op_store_xer_bc();
4447
    if (Rc(ctx->opcode)) {
4448
        gen_op_440_dlmzb_update_Rc();
4449
        gen_op_store_T0_crf(0);
4450
    }
4451
}
4452

    
4453
/* mbar replaces eieio on 440 */
4454
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
4455
{
4456
    /* interpreted as no-op */
4457
}
4458

    
4459
/* msync replaces sync on 440 */
4460
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
4461
{
4462
    /* interpreted as no-op */
4463
}
4464

    
4465
/* icbt */
4466
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
4467
{
4468
    /* interpreted as no-op */
4469
    /* XXX: specification say this is treated as a load by the MMU
4470
     *      but does not generate any exception
4471
     */
4472
}
4473

    
4474
#if defined(TARGET_PPCSPE)
4475
/***                           SPE extension                               ***/
4476

    
4477
/* Register moves */
4478
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
4479
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
4480
#if 0 // unused
4481
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
4482
#endif
4483

    
4484
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
4485
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
4486
#if 0 // unused
4487
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
4488
#endif
4489

    
4490
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
4491
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
4492
{                                                                             \
4493
    if (Rc(ctx->opcode))                                                      \
4494
        gen_##name1(ctx);                                                     \
4495
    else                                                                      \
4496
        gen_##name0(ctx);                                                     \
4497
}
4498

    
4499
/* Handler for undefined SPE opcodes */
4500
static inline void gen_speundef (DisasContext *ctx)
4501
{
4502
    RET_INVAL(ctx);
4503
}
4504

    
4505
/* SPE load and stores */
4506
static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
4507
{
4508
    target_long simm = rB(ctx->opcode);
4509

    
4510
    if (rA(ctx->opcode) == 0) {
4511
        gen_set_T0(simm << sh);
4512
    } else {
4513
        gen_op_load_gpr_T0(rA(ctx->opcode));
4514
        if (likely(simm != 0))
4515
            gen_op_addi(simm << sh);
4516
    }
4517
}
4518

    
4519
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
4520
#if defined(CONFIG_USER_ONLY)
4521
#if defined(TARGET_PPC64)
4522
#define OP_SPE_LD_TABLE(name)                                                 \
4523
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4524
    &gen_op_spe_l##name##_raw,                                                \
4525
    &gen_op_spe_l##name##_le_raw,                                             \
4526
    &gen_op_spe_l##name##_64_raw,                                             \
4527
    &gen_op_spe_l##name##_le_64_raw,                                          \
4528
};
4529
#define OP_SPE_ST_TABLE(name)                                                 \
4530
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4531
    &gen_op_spe_st##name##_raw,                                               \
4532
    &gen_op_spe_st##name##_le_raw,                                            \
4533
    &gen_op_spe_st##name##_64_raw,                                            \
4534
    &gen_op_spe_st##name##_le_64_raw,                                         \
4535
};
4536
#else /* defined(TARGET_PPC64) */
4537
#define OP_SPE_LD_TABLE(name)                                                 \
4538
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4539
    &gen_op_spe_l##name##_raw,                                                \
4540
    &gen_op_spe_l##name##_le_raw,                                             \
4541
};
4542
#define OP_SPE_ST_TABLE(name)                                                 \
4543
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4544
    &gen_op_spe_st##name##_raw,                                               \
4545
    &gen_op_spe_st##name##_le_raw,                                            \
4546
};
4547
#endif /* defined(TARGET_PPC64) */
4548
#else /* defined(CONFIG_USER_ONLY) */
4549
#if defined(TARGET_PPC64)
4550
#define OP_SPE_LD_TABLE(name)                                                 \
4551
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4552
    &gen_op_spe_l##name##_user,                                               \
4553
    &gen_op_spe_l##name##_le_user,                                            \
4554
    &gen_op_spe_l##name##_kernel,                                             \
4555
    &gen_op_spe_l##name##_le_kernel,                                          \
4556
    &gen_op_spe_l##name##_64_user,                                            \
4557
    &gen_op_spe_l##name##_le_64_user,                                         \
4558
    &gen_op_spe_l##name##_64_kernel,                                          \
4559
    &gen_op_spe_l##name##_le_64_kernel,                                       \
4560
};
4561
#define OP_SPE_ST_TABLE(name)                                                 \
4562
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4563
    &gen_op_spe_st##name##_user,                                              \
4564
    &gen_op_spe_st##name##_le_user,                                           \
4565
    &gen_op_spe_st##name##_kernel,                                            \
4566
    &gen_op_spe_st##name##_le_kernel,                                         \
4567
    &gen_op_spe_st##name##_64_user,                                           \
4568
    &gen_op_spe_st##name##_le_64_user,                                        \
4569
    &gen_op_spe_st##name##_64_kernel,                                         \
4570
    &gen_op_spe_st##name##_le_64_kernel,                                      \
4571
};
4572
#else /* defined(TARGET_PPC64) */
4573
#define OP_SPE_LD_TABLE(name)                                                 \
4574
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4575
    &gen_op_spe_l##name##_user,                                               \
4576
    &gen_op_spe_l##name##_le_user,                                            \
4577
    &gen_op_spe_l##name##_kernel,                                             \
4578
    &gen_op_spe_l##name##_le_kernel,                                          \
4579
};
4580
#define OP_SPE_ST_TABLE(name)                                                 \
4581
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4582
    &gen_op_spe_st##name##_user,                                              \
4583
    &gen_op_spe_st##name##_le_user,                                           \
4584
    &gen_op_spe_st##name##_kernel,                                            \
4585
    &gen_op_spe_st##name##_le_kernel,                                         \
4586
};
4587
#endif /* defined(TARGET_PPC64) */
4588
#endif /* defined(CONFIG_USER_ONLY) */
4589

    
4590
#define GEN_SPE_LD(name, sh)                                                  \
4591
static inline void gen_evl##name (DisasContext *ctx)                          \
4592
{                                                                             \
4593
    if (unlikely(!ctx->spe_enabled)) {                                        \
4594
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4595
        return;                                                               \
4596
    }                                                                         \
4597
    gen_addr_spe_imm_index(ctx, sh);                                          \
4598
    op_spe_ldst(spe_l##name);                                                 \
4599
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
4600
}
4601

    
4602
#define GEN_SPE_LDX(name)                                                     \
4603
static inline void gen_evl##name##x (DisasContext *ctx)                       \
4604
{                                                                             \
4605
    if (unlikely(!ctx->spe_enabled)) {                                        \
4606
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4607
        return;                                                               \
4608
    }                                                                         \
4609
    gen_addr_reg_index(ctx);                                                  \
4610
    op_spe_ldst(spe_l##name);                                                 \
4611
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
4612
}
4613

    
4614
#define GEN_SPEOP_LD(name, sh)                                                \
4615
OP_SPE_LD_TABLE(name);                                                        \
4616
GEN_SPE_LD(name, sh);                                                         \
4617
GEN_SPE_LDX(name)
4618

    
4619
#define GEN_SPE_ST(name, sh)                                                  \
4620
static inline void gen_evst##name (DisasContext *ctx)                         \
4621
{                                                                             \
4622
    if (unlikely(!ctx->spe_enabled)) {                                        \
4623
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4624
        return;                                                               \
4625
    }                                                                         \
4626
    gen_addr_spe_imm_index(ctx, sh);                                          \
4627
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
4628
    op_spe_ldst(spe_st##name);                                                \
4629
}
4630

    
4631
#define GEN_SPE_STX(name)                                                     \
4632
static inline void gen_evst##name##x (DisasContext *ctx)                      \
4633
{                                                                             \
4634
    if (unlikely(!ctx->spe_enabled)) {                                        \
4635
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4636
        return;                                                               \
4637
    }                                                                         \
4638
    gen_addr_reg_index(ctx);                                                  \
4639
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
4640
    op_spe_ldst(spe_st##name);                                                \
4641
}
4642

    
4643
#define GEN_SPEOP_ST(name, sh)                                                \
4644
OP_SPE_ST_TABLE(name);                                                        \
4645
GEN_SPE_ST(name, sh);                                                         \
4646
GEN_SPE_STX(name)
4647

    
4648
#define GEN_SPEOP_LDST(name, sh)                                              \
4649
GEN_SPEOP_LD(name, sh);                                                       \
4650
GEN_SPEOP_ST(name, sh)
4651

    
4652
/* SPE arithmetic and logic */
4653
#define GEN_SPEOP_ARITH2(name)                                                \
4654
static inline void gen_##name (DisasContext *ctx)                             \
4655
{                                                                             \
4656
    if (unlikely(!ctx->spe_enabled)) {                                        \
4657
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4658
        return;                                                               \
4659
    }                                                                         \
4660
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
4661
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
4662
    gen_op_##name();                                                          \
4663
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
4664
}
4665

    
4666
#define GEN_SPEOP_ARITH1(name)                                                \
4667
static inline void gen_##name (DisasContext *ctx)                             \
4668
{                                                                             \
4669
    if (unlikely(!ctx->spe_enabled)) {                                        \
4670
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4671
        return;                                                               \
4672
    }                                                                         \
4673
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
4674
    gen_op_##name();                                                          \
4675
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
4676
}
4677

    
4678
#define GEN_SPEOP_COMP(name)                                                  \
4679
static inline void gen_##name (DisasContext *ctx)                             \
4680
{                                                                             \
4681
    if (unlikely(!ctx->spe_enabled)) {                                        \
4682
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4683
        return;                                                               \
4684
    }                                                                         \
4685
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
4686
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
4687
    gen_op_##name();                                                          \
4688
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
4689
}
4690

    
4691
/* Logical */
4692
GEN_SPEOP_ARITH2(evand);
4693
GEN_SPEOP_ARITH2(evandc);
4694
GEN_SPEOP_ARITH2(evxor);
4695
GEN_SPEOP_ARITH2(evor);
4696
GEN_SPEOP_ARITH2(evnor);
4697
GEN_SPEOP_ARITH2(eveqv);
4698
GEN_SPEOP_ARITH2(evorc);
4699
GEN_SPEOP_ARITH2(evnand);
4700
GEN_SPEOP_ARITH2(evsrwu);
4701
GEN_SPEOP_ARITH2(evsrws);
4702
GEN_SPEOP_ARITH2(evslw);
4703
GEN_SPEOP_ARITH2(evrlw);
4704
GEN_SPEOP_ARITH2(evmergehi);
4705
GEN_SPEOP_ARITH2(evmergelo);
4706
GEN_SPEOP_ARITH2(evmergehilo);
4707
GEN_SPEOP_ARITH2(evmergelohi);
4708

    
4709
/* Arithmetic */
4710
GEN_SPEOP_ARITH2(evaddw);
4711
GEN_SPEOP_ARITH2(evsubfw);
4712
GEN_SPEOP_ARITH1(evabs);
4713
GEN_SPEOP_ARITH1(evneg);
4714
GEN_SPEOP_ARITH1(evextsb);
4715
GEN_SPEOP_ARITH1(evextsh);
4716
GEN_SPEOP_ARITH1(evrndw);
4717
GEN_SPEOP_ARITH1(evcntlzw);
4718
GEN_SPEOP_ARITH1(evcntlsw);
4719
static inline void gen_brinc (DisasContext *ctx)
4720
{
4721
    /* Note: brinc is usable even if SPE is disabled */
4722
    gen_op_load_gpr64_T0(rA(ctx->opcode));
4723
    gen_op_load_gpr64_T1(rB(ctx->opcode));
4724
    gen_op_brinc();
4725
    gen_op_store_T0_gpr64(rD(ctx->opcode));
4726
}
4727

    
4728
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
4729
static inline void gen_##name##i (DisasContext *ctx)                          \
4730
{                                                                             \
4731
    if (unlikely(!ctx->spe_enabled)) {                                        \
4732
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4733
        return;                                                               \
4734
    }                                                                         \
4735
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
4736
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
4737
    gen_op_##name();                                                          \
4738
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
4739
}
4740

    
4741
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
4742
static inline void gen_##name##i (DisasContext *ctx)                          \
4743
{                                                                             \
4744
    if (unlikely(!ctx->spe_enabled)) {                                        \
4745
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4746
        return;                                                               \
4747
    }                                                                         \
4748
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
4749
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
4750
    gen_op_##name();                                                          \
4751
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
4752
}
4753

    
4754
GEN_SPEOP_ARITH_IMM2(evaddw);
4755
#define gen_evaddiw gen_evaddwi
4756
GEN_SPEOP_ARITH_IMM2(evsubfw);
4757
#define gen_evsubifw gen_evsubfwi
4758
GEN_SPEOP_LOGIC_IMM2(evslw);
4759
GEN_SPEOP_LOGIC_IMM2(evsrwu);
4760
#define gen_evsrwis gen_evsrwsi
4761
GEN_SPEOP_LOGIC_IMM2(evsrws);
4762
#define gen_evsrwiu gen_evsrwui
4763
GEN_SPEOP_LOGIC_IMM2(evrlw);
4764

    
4765
static inline void gen_evsplati (DisasContext *ctx)
4766
{
4767
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
4768

    
4769
    gen_op_splatwi_T0_64(imm);
4770
    gen_op_store_T0_gpr64(rD(ctx->opcode));
4771
}
4772

    
4773
static inline void gen_evsplatfi (DisasContext *ctx)
4774
{
4775
    uint32_t imm = rA(ctx->opcode) << 27;
4776

    
4777
    gen_op_splatwi_T0_64(imm);
4778
    gen_op_store_T0_gpr64(rD(ctx->opcode));
4779
}
4780

    
4781
/* Comparison */
4782
GEN_SPEOP_COMP(evcmpgtu);
4783
GEN_SPEOP_COMP(evcmpgts);
4784
GEN_SPEOP_COMP(evcmpltu);
4785
GEN_SPEOP_COMP(evcmplts);
4786
GEN_SPEOP_COMP(evcmpeq);
4787

    
4788
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
4789
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
4790
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
4791
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
4792
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
4793
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
4794
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
4795
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
4796
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
4797
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
4798
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
4799
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
4800
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
4801
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
4802
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
4803
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
4804
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
4805
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
4806
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
4807
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
4808
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
4809
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
4810
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
4811
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
4812
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
4813

    
4814
static inline void gen_evsel (DisasContext *ctx)
4815
{
4816
    if (unlikely(!ctx->spe_enabled)) {
4817
        RET_EXCP(ctx, EXCP_NO_SPE, 0);
4818
        return;
4819
    }
4820
    gen_op_load_crf_T0(ctx->opcode & 0x7);
4821
    gen_op_load_gpr64_T0(rA(ctx->opcode));
4822
    gen_op_load_gpr64_T1(rB(ctx->opcode));
4823
    gen_op_evsel();
4824
    gen_op_store_T0_gpr64(rD(ctx->opcode));
4825
}
4826

    
4827
GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
4828
{
4829
    gen_evsel(ctx);
4830
}
4831
GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
4832
{
4833
    gen_evsel(ctx);
4834
}
4835
GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
4836
{
4837
    gen_evsel(ctx);
4838
}
4839
GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
4840
{
4841
    gen_evsel(ctx);
4842
}
4843

    
4844
/* Load and stores */
4845
#if defined(TARGET_PPC64)
4846
/* In that case, we already have 64 bits load & stores
4847
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
4848
 */
4849
#if defined(CONFIG_USER_ONLY)
4850
#define gen_op_spe_ldd_raw gen_op_ld_raw
4851
#define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
4852
#define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
4853
#define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
4854
#define gen_op_spe_stdd_raw gen_op_ld_raw
4855
#define gen_op_spe_stdd_64_raw gen_op_std_64_raw
4856
#define gen_op_spe_stdd_le_raw gen_op_std_le_raw
4857
#define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
4858
#else /* defined(CONFIG_USER_ONLY) */
4859
#define gen_op_spe_ldd_kernel gen_op_ld_kernel
4860
#define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
4861
#define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
4862
#define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
4863
#define gen_op_spe_ldd_user gen_op_ld_user
4864
#define gen_op_spe_ldd_64_user gen_op_ld_64_user
4865
#define gen_op_spe_ldd_le_user gen_op_ld_le_user
4866
#define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
4867
#define gen_op_spe_stdd_kernel gen_op_std_kernel
4868
#define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
4869
#define gen_op_spe_stdd_le_kernel gen_op_std_kernel
4870
#define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
4871
#define gen_op_spe_stdd_user gen_op_std_user
4872
#define gen_op_spe_stdd_64_user gen_op_std_64_user
4873
#define gen_op_spe_stdd_le_user gen_op_std_le_user
4874
#define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
4875
#endif /* defined(CONFIG_USER_ONLY) */
4876
#endif /* defined(TARGET_PPC64) */
4877
GEN_SPEOP_LDST(dd, 3);
4878
GEN_SPEOP_LDST(dw, 3);
4879
GEN_SPEOP_LDST(dh, 3);
4880
GEN_SPEOP_LDST(whe, 2);
4881
GEN_SPEOP_LD(whou, 2);
4882
GEN_SPEOP_LD(whos, 2);
4883
GEN_SPEOP_ST(who, 2);
4884

    
4885
#if defined(TARGET_PPC64)
4886
/* In that case, spe_stwwo is equivalent to stw */
4887
#if defined(CONFIG_USER_ONLY)
4888
#define gen_op_spe_stwwo_raw gen_op_stw_raw
4889
#define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
4890
#define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
4891
#define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
4892
#else
4893
#define gen_op_spe_stwwo_user gen_op_stw_user
4894
#define gen_op_spe_stwwo_le_user gen_op_stw_le_user
4895
#define gen_op_spe_stwwo_64_user gen_op_stw_64_user
4896
#define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
4897
#define gen_op_spe_stwwo_kernel gen_op_stw_kernel
4898
#define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
4899
#define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
4900
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
4901
#endif
4902
#endif
4903
#define _GEN_OP_SPE_STWWE(suffix)                                             \
4904
static inline void gen_op_spe_stwwe_##suffix (void)                           \
4905
{                                                                             \
4906
    gen_op_srli32_T1_64();                                                    \
4907
    gen_op_spe_stwwo_##suffix();                                              \
4908
}
4909
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
4910
static inline void gen_op_spe_stwwe_le_##suffix (void)                        \
4911
{                                                                             \
4912
    gen_op_srli32_T1_64();                                                    \
4913
    gen_op_spe_stwwo_le_##suffix();                                           \
4914
}
4915
#if defined(TARGET_PPC64)
4916
#define GEN_OP_SPE_STWWE(suffix)                                              \
4917
_GEN_OP_SPE_STWWE(suffix);                                                    \
4918
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
4919
static inline void gen_op_spe_stwwe_64_##suffix (void)                        \
4920
{                                                                             \
4921
    gen_op_srli32_T1_64();                                                    \
4922
    gen_op_spe_stwwo_64_##suffix();                                           \
4923
}                                                                             \
4924
static inline void gen_op_spe_stwwe_le_64_##suffix (void)                     \
4925
{                                                                             \
4926
    gen_op_srli32_T1_64();                                                    \
4927
    gen_op_spe_stwwo_le_64_##suffix();                                        \
4928
}
4929
#else
4930
#define GEN_OP_SPE_STWWE(suffix)                                              \
4931
_GEN_OP_SPE_STWWE(suffix);                                                    \
4932
_GEN_OP_SPE_STWWE_LE(suffix)
4933
#endif
4934
#if defined(CONFIG_USER_ONLY)
4935
GEN_OP_SPE_STWWE(raw);
4936
#else /* defined(CONFIG_USER_ONLY) */
4937
GEN_OP_SPE_STWWE(kernel);
4938
GEN_OP_SPE_STWWE(user);
4939
#endif /* defined(CONFIG_USER_ONLY) */
4940
GEN_SPEOP_ST(wwe, 2);
4941
GEN_SPEOP_ST(wwo, 2);
4942

    
4943
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
4944
static inline void gen_op_spe_l##name##_##suffix (void)                       \
4945
{                                                                             \
4946
    gen_op_##op##_##suffix();                                                 \
4947
    gen_op_splatw_T1_64();                                                    \
4948
}
4949

    
4950
#define GEN_OP_SPE_LHE(suffix)                                                \
4951
static inline void gen_op_spe_lhe_##suffix (void)                             \
4952
{                                                                             \
4953
    gen_op_spe_lh_##suffix();                                                 \
4954
    gen_op_sli16_T1_64();                                                     \
4955
}
4956

    
4957
#define GEN_OP_SPE_LHX(suffix)                                                \
4958
static inline void gen_op_spe_lhx_##suffix (void)                             \
4959
{                                                                             \
4960
    gen_op_spe_lh_##suffix();                                                 \
4961
    gen_op_extsh_T1_64();                                                     \
4962
}
4963

    
4964
#if defined(CONFIG_USER_ONLY)
4965
GEN_OP_SPE_LHE(raw);
4966
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
4967
GEN_OP_SPE_LHE(le_raw);
4968
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
4969
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
4970
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
4971
GEN_OP_SPE_LHX(raw);
4972
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
4973
GEN_OP_SPE_LHX(le_raw);
4974
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
4975
#if defined(TARGET_PPC64)
4976
GEN_OP_SPE_LHE(64_raw);
4977
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
4978
GEN_OP_SPE_LHE(le_64_raw);
4979
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
4980
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
4981
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
4982
GEN_OP_SPE_LHX(64_raw);
4983
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
4984
GEN_OP_SPE_LHX(le_64_raw);
4985
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
4986
#endif
4987
#else
4988
GEN_OP_SPE_LHE(kernel);
4989
GEN_OP_SPE_LHE(user);
4990
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
4991
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
4992
GEN_OP_SPE_LHE(le_kernel);
4993
GEN_OP_SPE_LHE(le_user);
4994
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
4995
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
4996
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
4997
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
4998
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
4999
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5000
GEN_OP_SPE_LHX(kernel);
5001
GEN_OP_SPE_LHX(user);
5002
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5003
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5004
GEN_OP_SPE_LHX(le_kernel);
5005
GEN_OP_SPE_LHX(le_user);
5006
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5007
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5008
#if defined(TARGET_PPC64)
5009
GEN_OP_SPE_LHE(64_kernel);
5010
GEN_OP_SPE_LHE(64_user);
5011
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5012
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5013
GEN_OP_SPE_LHE(le_64_kernel);
5014
GEN_OP_SPE_LHE(le_64_user);
5015
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5016
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5017
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5018
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5019
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5020
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5021
GEN_OP_SPE_LHX(64_kernel);
5022
GEN_OP_SPE_LHX(64_user);
5023
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5024
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5025
GEN_OP_SPE_LHX(le_64_kernel);
5026
GEN_OP_SPE_LHX(le_64_user);
5027
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5028
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5029
#endif
5030
#endif
5031
GEN_SPEOP_LD(hhesplat, 1);
5032
GEN_SPEOP_LD(hhousplat, 1);
5033
GEN_SPEOP_LD(hhossplat, 1);
5034
GEN_SPEOP_LD(wwsplat, 2);
5035
GEN_SPEOP_LD(whsplat, 2);
5036

    
5037
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5038
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5039
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5040
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5041
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5042
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5043
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5044
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5045
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5046
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5047
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5048
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5049
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5050
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5051
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5052
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5053
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5054
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5055

    
5056
/* Multiply and add - TODO */
5057
#if 0
5058
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5059
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5060
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5061
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5062
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5063
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5064
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5065
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5066
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5067
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5068
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5069
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5070

5071
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5072
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5073
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5074
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5075
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5076
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5077
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5078
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5079
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5080
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5081
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5082
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5083
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5084
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5085

5086
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5087
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5088
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5089
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5090
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5091
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5092

5093
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5094
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5095
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5096
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5097
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5098
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5099
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5100
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5101
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5102
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5103
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5104
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5105

5106
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5107
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5108
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5109
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5110
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5111

5112
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5113
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5114
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5115
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5116
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5117
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5118
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5119
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5120
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5121
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5122
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5123
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5124

5125
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5126
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5127
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5128
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5129
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5130
#endif
5131

    
5132
/***                      SPE floating-point extension                     ***/
5133
#define GEN_SPEFPUOP_CONV(name)                                               \
5134
static inline void gen_##name (DisasContext *ctx)                             \
5135
{                                                                             \
5136
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5137
    gen_op_##name();                                                          \
5138
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5139
}
5140

    
5141
/* Single precision floating-point vectors operations */
5142
/* Arithmetic */
5143
GEN_SPEOP_ARITH2(evfsadd);
5144
GEN_SPEOP_ARITH2(evfssub);
5145
GEN_SPEOP_ARITH2(evfsmul);
5146
GEN_SPEOP_ARITH2(evfsdiv);
5147
GEN_SPEOP_ARITH1(evfsabs);
5148
GEN_SPEOP_ARITH1(evfsnabs);
5149
GEN_SPEOP_ARITH1(evfsneg);
5150
/* Conversion */
5151
GEN_SPEFPUOP_CONV(evfscfui);
5152
GEN_SPEFPUOP_CONV(evfscfsi);
5153
GEN_SPEFPUOP_CONV(evfscfuf);
5154
GEN_SPEFPUOP_CONV(evfscfsf);
5155
GEN_SPEFPUOP_CONV(evfsctui);
5156
GEN_SPEFPUOP_CONV(evfsctsi);
5157
GEN_SPEFPUOP_CONV(evfsctuf);
5158
GEN_SPEFPUOP_CONV(evfsctsf);
5159
GEN_SPEFPUOP_CONV(evfsctuiz);
5160
GEN_SPEFPUOP_CONV(evfsctsiz);
5161
/* Comparison */
5162
GEN_SPEOP_COMP(evfscmpgt);
5163
GEN_SPEOP_COMP(evfscmplt);
5164
GEN_SPEOP_COMP(evfscmpeq);
5165
GEN_SPEOP_COMP(evfststgt);
5166
GEN_SPEOP_COMP(evfststlt);
5167
GEN_SPEOP_COMP(evfststeq);
5168

    
5169
/* Opcodes definitions */
5170
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5171
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5172
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5173
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5174
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5175
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5176
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5177
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5178
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5179
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5180
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5181
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5182
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5183
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5184

    
5185
/* Single precision floating-point operations */
5186
/* Arithmetic */
5187
GEN_SPEOP_ARITH2(efsadd);
5188
GEN_SPEOP_ARITH2(efssub);
5189
GEN_SPEOP_ARITH2(efsmul);
5190
GEN_SPEOP_ARITH2(efsdiv);
5191
GEN_SPEOP_ARITH1(efsabs);
5192
GEN_SPEOP_ARITH1(efsnabs);
5193
GEN_SPEOP_ARITH1(efsneg);
5194
/* Conversion */
5195
GEN_SPEFPUOP_CONV(efscfui);
5196
GEN_SPEFPUOP_CONV(efscfsi);
5197
GEN_SPEFPUOP_CONV(efscfuf);
5198
GEN_SPEFPUOP_CONV(efscfsf);
5199
GEN_SPEFPUOP_CONV(efsctui);
5200
GEN_SPEFPUOP_CONV(efsctsi);
5201
GEN_SPEFPUOP_CONV(efsctuf);
5202
GEN_SPEFPUOP_CONV(efsctsf);
5203
GEN_SPEFPUOP_CONV(efsctuiz);
5204
GEN_SPEFPUOP_CONV(efsctsiz);
5205
GEN_SPEFPUOP_CONV(efscfd);
5206
/* Comparison */
5207
GEN_SPEOP_COMP(efscmpgt);
5208
GEN_SPEOP_COMP(efscmplt);
5209
GEN_SPEOP_COMP(efscmpeq);
5210
GEN_SPEOP_COMP(efststgt);
5211
GEN_SPEOP_COMP(efststlt);
5212
GEN_SPEOP_COMP(efststeq);
5213

    
5214
/* Opcodes definitions */
5215
GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5216
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5217
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5218
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5219
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5220
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5221
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5222
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5223
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5224
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5225
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5226
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5227
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5228

    
5229
/* Double precision floating-point operations */
5230
/* Arithmetic */
5231
GEN_SPEOP_ARITH2(efdadd);
5232
GEN_SPEOP_ARITH2(efdsub);
5233
GEN_SPEOP_ARITH2(efdmul);
5234
GEN_SPEOP_ARITH2(efddiv);
5235
GEN_SPEOP_ARITH1(efdabs);
5236
GEN_SPEOP_ARITH1(efdnabs);
5237
GEN_SPEOP_ARITH1(efdneg);
5238
/* Conversion */
5239

    
5240
GEN_SPEFPUOP_CONV(efdcfui);
5241
GEN_SPEFPUOP_CONV(efdcfsi);
5242
GEN_SPEFPUOP_CONV(efdcfuf);
5243
GEN_SPEFPUOP_CONV(efdcfsf);
5244
GEN_SPEFPUOP_CONV(efdctui);
5245
GEN_SPEFPUOP_CONV(efdctsi);
5246
GEN_SPEFPUOP_CONV(efdctuf);
5247
GEN_SPEFPUOP_CONV(efdctsf);
5248
GEN_SPEFPUOP_CONV(efdctuiz);
5249
GEN_SPEFPUOP_CONV(efdctsiz);
5250
GEN_SPEFPUOP_CONV(efdcfs);
5251
GEN_SPEFPUOP_CONV(efdcfuid);
5252
GEN_SPEFPUOP_CONV(efdcfsid);
5253
GEN_SPEFPUOP_CONV(efdctuidz);
5254
GEN_SPEFPUOP_CONV(efdctsidz);
5255
/* Comparison */
5256
GEN_SPEOP_COMP(efdcmpgt);
5257
GEN_SPEOP_COMP(efdcmplt);
5258
GEN_SPEOP_COMP(efdcmpeq);
5259
GEN_SPEOP_COMP(efdtstgt);
5260
GEN_SPEOP_COMP(efdtstlt);
5261
GEN_SPEOP_COMP(efdtsteq);
5262

    
5263
/* Opcodes definitions */
5264
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
5265
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
5266
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
5267
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
5268
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
5269
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
5270
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
5271
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
5272
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
5273
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
5274
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
5275
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
5276
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
5277
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
5278
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
5279
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
5280
#endif
5281

    
5282
/* End opcode list */
5283
GEN_OPCODE_MARK(end);
5284

    
5285
#include "translate_init.c"
5286

    
5287
/*****************************************************************************/
5288
/* Misc PowerPC helpers */
5289
static inline uint32_t load_xer (CPUState *env)
5290
{
5291
    return (xer_so << XER_SO) |
5292
        (xer_ov << XER_OV) |
5293
        (xer_ca << XER_CA) |
5294
        (xer_bc << XER_BC) |
5295
        (xer_cmp << XER_CMP);
5296
}
5297

    
5298
void cpu_dump_state(CPUState *env, FILE *f, 
5299
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5300
                    int flags)
5301
{
5302
#if defined(TARGET_PPC64) || 1
5303
#define FILL ""
5304
#define RGPL  4
5305
#define RFPL  4
5306
#else
5307
#define FILL "        "
5308
#define RGPL  8
5309
#define RFPL  4
5310
#endif
5311

    
5312
    int i;
5313

    
5314
    cpu_fprintf(f, "NIP " REGX " LR " REGX " CTR " REGX "\n",
5315
                env->nip, env->lr, env->ctr);
5316
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
5317
#if !defined(NO_TIMER_DUMP)
5318
                "TB %08x %08x "
5319
#if !defined(CONFIG_USER_ONLY)
5320
                "DECR %08x"
5321
#endif
5322
#endif
5323
                "\n",
5324
                do_load_msr(env), load_xer(env)
5325
#if !defined(NO_TIMER_DUMP)
5326
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
5327
#if !defined(CONFIG_USER_ONLY)
5328
                , cpu_ppc_load_decr(env)
5329
#endif
5330
#endif
5331
                );
5332
    for (i = 0; i < 32; i++) {
5333
        if ((i & (RGPL - 1)) == 0)
5334
            cpu_fprintf(f, "GPR%02d", i);
5335
        cpu_fprintf(f, " " REGX, env->gpr[i]);
5336
        if ((i & (RGPL - 1)) == (RGPL - 1))
5337
            cpu_fprintf(f, "\n");
5338
    }
5339
    cpu_fprintf(f, "CR ");
5340
    for (i = 0; i < 8; i++)
5341
        cpu_fprintf(f, "%01x", env->crf[i]);
5342
    cpu_fprintf(f, "  [");
5343
    for (i = 0; i < 8; i++) {
5344
        char a = '-';
5345
        if (env->crf[i] & 0x08)
5346
            a = 'L';
5347
        else if (env->crf[i] & 0x04)
5348
            a = 'G';
5349
        else if (env->crf[i] & 0x02)
5350
            a = 'E';
5351
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
5352
    }
5353
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
5354
    for (i = 0; i < 32; i++) {
5355
        if ((i & (RFPL - 1)) == 0)
5356
            cpu_fprintf(f, "FPR%02d", i);
5357
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
5358
        if ((i & (RFPL - 1)) == (RFPL - 1))
5359
            cpu_fprintf(f, "\n");
5360
    }
5361
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
5362
                "SDR1 " REGX "\n",
5363
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
5364

    
5365
#undef RGPL
5366
#undef RFPL
5367
#undef FILL
5368
}
5369

    
5370
void cpu_dump_statistics (CPUState *env, FILE*f,
5371
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5372
                          int flags)
5373
{
5374
#if defined(DO_PPC_STATISTICS)
5375
    opc_handler_t **t1, **t2, **t3, *handler;
5376
    int op1, op2, op3;
5377

    
5378
    t1 = env->opcodes;
5379
    for (op1 = 0; op1 < 64; op1++) {
5380
        handler = t1[op1];
5381
        if (is_indirect_opcode(handler)) {
5382
            t2 = ind_table(handler);
5383
            for (op2 = 0; op2 < 32; op2++) {
5384
                handler = t2[op2];
5385
                if (is_indirect_opcode(handler)) {
5386
                    t3 = ind_table(handler);
5387
                    for (op3 = 0; op3 < 32; op3++) {
5388
                        handler = t3[op3];
5389
                        if (handler->count == 0)
5390
                            continue;
5391
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
5392
                                    "%016llx %lld\n",
5393
                                    op1, op2, op3, op1, (op3 << 5) | op2,
5394
                                    handler->oname,
5395
                                    handler->count, handler->count);
5396
                    }
5397
                } else {
5398
                    if (handler->count == 0)
5399
                        continue;
5400
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
5401
                                "%016llx %lld\n",
5402
                                op1, op2, op1, op2, handler->oname,
5403
                                handler->count, handler->count);
5404
                }
5405
            }
5406
        } else {
5407
            if (handler->count == 0)
5408
                continue;
5409
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
5410
                        op1, op1, handler->oname,
5411
                        handler->count, handler->count);
5412
        }
5413
    }
5414
#endif
5415
}
5416

    
5417
/*****************************************************************************/
5418
static inline int gen_intermediate_code_internal (CPUState *env,
5419
                                                  TranslationBlock *tb,
5420
                                                  int search_pc)
5421
{
5422
    DisasContext ctx, *ctxp = &ctx;
5423
    opc_handler_t **table, *handler;
5424
    target_ulong pc_start;
5425
    uint16_t *gen_opc_end;
5426
    int j, lj = -1;
5427

    
5428
    pc_start = tb->pc;
5429
    gen_opc_ptr = gen_opc_buf;
5430
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5431
    gen_opparam_ptr = gen_opparam_buf;
5432
    nb_gen_labels = 0;
5433
    ctx.nip = pc_start;
5434
    ctx.tb = tb;
5435
    ctx.exception = EXCP_NONE;
5436
    ctx.spr_cb = env->spr_cb;
5437
#if defined(CONFIG_USER_ONLY)
5438
    ctx.mem_idx = msr_le;
5439
#if defined(TARGET_PPC64)
5440
    ctx.mem_idx |= msr_sf << 1;
5441
#endif
5442
#else
5443
    ctx.supervisor = 1 - msr_pr;
5444
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
5445
#if defined(TARGET_PPC64)
5446
    ctx.mem_idx |= msr_sf << 2;
5447
#endif
5448
#endif
5449
#if defined(TARGET_PPC64)
5450
    ctx.sf_mode = msr_sf;
5451
#endif
5452
    ctx.fpu_enabled = msr_fp;
5453
#if defined(TARGET_PPCSPE)
5454
    ctx.spe_enabled = msr_spe;
5455
#endif
5456
    ctx.singlestep_enabled = env->singlestep_enabled;
5457
#if defined (DO_SINGLE_STEP) && 0
5458
    /* Single step trace mode */
5459
    msr_se = 1;
5460
#endif
5461
    /* Set env in case of segfault during code fetch */
5462
    while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
5463
        if (unlikely(env->nb_breakpoints > 0)) {
5464
            for (j = 0; j < env->nb_breakpoints; j++) {
5465
                if (env->breakpoints[j] == ctx.nip) {
5466
                    gen_update_nip(&ctx, ctx.nip); 
5467
                    gen_op_debug();
5468
                    break;
5469
                }
5470
            }
5471
        }
5472
        if (unlikely(search_pc)) {
5473
            j = gen_opc_ptr - gen_opc_buf;
5474
            if (lj < j) {
5475
                lj++;
5476
                while (lj < j)
5477
                    gen_opc_instr_start[lj++] = 0;
5478
                gen_opc_pc[lj] = ctx.nip;
5479
                gen_opc_instr_start[lj] = 1;
5480
            }
5481
        }
5482
#if defined PPC_DEBUG_DISAS
5483
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5484
            fprintf(logfile, "----------------\n");
5485
            fprintf(logfile, "nip=%08x super=%d ir=%d\n",
5486
                    ctx.nip, 1 - msr_pr, msr_ir);
5487
        }
5488
#endif
5489
        ctx.opcode = ldl_code(ctx.nip);
5490
        if (msr_le) {
5491
            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
5492
                ((ctx.opcode & 0x00FF0000) >> 8) |
5493
                ((ctx.opcode & 0x0000FF00) << 8) |
5494
                ((ctx.opcode & 0x000000FF) << 24);
5495
        }
5496
#if defined PPC_DEBUG_DISAS
5497
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5498
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
5499
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
5500
                    opc3(ctx.opcode), msr_le ? "little" : "big");
5501
        }
5502
#endif
5503
        ctx.nip += 4;
5504
        table = env->opcodes;
5505
        handler = table[opc1(ctx.opcode)];
5506
        if (is_indirect_opcode(handler)) {
5507
            table = ind_table(handler);
5508
            handler = table[opc2(ctx.opcode)];
5509
            if (is_indirect_opcode(handler)) {
5510
                table = ind_table(handler);
5511
                handler = table[opc3(ctx.opcode)];
5512
            }
5513
        }
5514
        /* Is opcode *REALLY* valid ? */
5515
        if (unlikely(handler->handler == &gen_invalid)) {
5516
            if (loglevel > 0) {
5517
                fprintf(logfile, "invalid/unsupported opcode: "
5518
                        "%02x - %02x - %02x (%08x) 0x" REGX " %d\n",
5519
                        opc1(ctx.opcode), opc2(ctx.opcode),
5520
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
5521
            } else {
5522
                printf("invalid/unsupported opcode: "
5523
                       "%02x - %02x - %02x (%08x) 0x" REGX " %d\n",
5524
                       opc1(ctx.opcode), opc2(ctx.opcode),
5525
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
5526
            }
5527
        } else {
5528
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
5529
                if (loglevel > 0) {
5530
                    fprintf(logfile, "invalid bits: %08x for opcode: "
5531
                            "%02x -%02x - %02x (%08x) " REGX "\n",
5532
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
5533
                            opc2(ctx.opcode), opc3(ctx.opcode),
5534
                            ctx.opcode, ctx.nip - 4);
5535
                } else {
5536
                    printf("invalid bits: %08x for opcode: "
5537
                           "%02x -%02x - %02x (%08x) " REGX "\n",
5538
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
5539
                           opc2(ctx.opcode), opc3(ctx.opcode),
5540
                           ctx.opcode, ctx.nip - 4);
5541
                }
5542
                RET_INVAL(ctxp);
5543
                break;
5544
            }
5545
        }
5546
        (*(handler->handler))(&ctx);
5547
#if defined(DO_PPC_STATISTICS)
5548
        handler->count++;
5549
#endif
5550
        /* Check trace mode exceptions */
5551
        if (unlikely((msr_be && ctx.exception == EXCP_BRANCH) ||
5552
                     /* Check in single step trace mode
5553
                      * we need to stop except if:
5554
                      * - rfi, trap or syscall
5555
                      * - first instruction of an exception handler
5556
                      */
5557
                     (msr_se && (ctx.nip < 0x100 ||
5558
                                 ctx.nip > 0xF00 ||
5559
                                 (ctx.nip & 0xFC) != 0x04) &&
5560
                      ctx.exception != EXCP_SYSCALL &&
5561
                      ctx.exception != EXCP_SYSCALL_USER &&
5562
                      ctx.exception != EXCP_TRAP))) {
5563
            RET_EXCP(ctxp, EXCP_TRACE, 0);
5564
        }
5565
        /* if we reach a page boundary or are single stepping, stop
5566
         * generation
5567
         */
5568
        if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
5569
                     (env->singlestep_enabled))) {
5570
            break;
5571
        }
5572
#if defined (DO_SINGLE_STEP)
5573
        break;
5574
#endif
5575
    }
5576
    if (ctx.exception == EXCP_NONE) {
5577
        gen_goto_tb(&ctx, 0, ctx.nip);
5578
    } else if (ctx.exception != EXCP_BRANCH) {
5579
        gen_op_reset_T0();
5580
        /* Generate the return instruction */
5581
        gen_op_exit_tb();
5582
    }
5583
    *gen_opc_ptr = INDEX_op_end;
5584
    if (unlikely(search_pc)) {
5585
        j = gen_opc_ptr - gen_opc_buf;
5586
        lj++;
5587
        while (lj <= j)
5588
            gen_opc_instr_start[lj++] = 0;
5589
        tb->size = 0;
5590
    } else {
5591
        tb->size = ctx.nip - pc_start;
5592
    }
5593
#if defined(DEBUG_DISAS)
5594
    if (loglevel & CPU_LOG_TB_CPU) {
5595
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
5596
        cpu_dump_state(env, logfile, fprintf, 0);
5597
    }
5598
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5599
        int flags;
5600
        flags = msr_le;
5601
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5602
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
5603
        fprintf(logfile, "\n");
5604
    }
5605
    if (loglevel & CPU_LOG_TB_OP) {
5606
        fprintf(logfile, "OP:\n");
5607
        dump_ops(gen_opc_buf, gen_opparam_buf);
5608
        fprintf(logfile, "\n");
5609
    }
5610
#endif
5611
    return 0;
5612
}
5613

    
5614
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5615
{
5616
    return gen_intermediate_code_internal(env, tb, 0);
5617
}
5618

    
5619
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5620
{
5621
    return gen_intermediate_code_internal(env, tb, 1);
5622
}