Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ d9bce9d9

History | View | Annotate | Download (150.3 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
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
164
    int singlestep_enabled;
165
} DisasContext;
166

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

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

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

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

    
210
#define RET_INVAL(ctx)                                                        \
211
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
212

    
213
#define RET_PRIVOPC(ctx)                                                      \
214
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
215

    
216
#define RET_PRIVREG(ctx)                                                      \
217
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
218

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

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

    
232
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
233
static void gen_##name (DisasContext *ctx);                                   \
234
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
235
static void gen_##name (DisasContext *ctx)
236

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

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

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

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

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

    
310
EXTRACT_HELPER(CRM, 12, 8);
311
EXTRACT_HELPER(FM, 17, 8);
312
EXTRACT_HELPER(SR, 16, 4);
313
EXTRACT_HELPER(FPIMM, 20, 4);
314

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

    
324
static inline uint32_t BD (uint32_t opcode)
325
{
326
    return (opcode >> 0) & 0xFFFC;
327
}
328

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

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

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

    
361
    return ret;
362
}
363

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

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

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

    
422
/* Start opcode list */
423
GEN_OPCODE_MARK(start);
424

    
425
/* Invalid instruction */
426
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
427
{
428
    RET_INVAL(ctx);
429
}
430

    
431
static opc_handler_t invalid_handler = {
432
    .inval   = 0xFFFFFFFF,
433
    .type    = PPC_NONE,
434
    .handler = gen_invalid,
435
};
436

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
981
/* or & or. */
982
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
983
{
984
    int rs, ra, rb;
985

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1379
#define GEN_FLOAT_ACB(name, op2)                                              \
1380
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0);                                     \
1381
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
1382

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

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

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

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

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

    
1464
/* fres */ /* XXX: not in 601 */
1465
GEN_FLOAT_BS(res, 0x3B, 0x18);
1466

    
1467
/* frsqrte */ /* XXX: not in 601 */
1468
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
1469

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

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

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

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

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

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

    
1552
/***                         Floating-point move                           ***/
1553
/* fabs */
1554
GEN_FLOAT_B(abs, 0x08, 0x08);
1555

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

    
1570
/* fnabs */
1571
GEN_FLOAT_B(nabs, 0x08, 0x04);
1572
/* fneg */
1573
GEN_FLOAT_B(neg, 0x08, 0x01);
1574

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2205
/***                        Memory synchronisation                         ***/
2206
/* eieio */
2207
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
2208
{
2209
}
2210

    
2211
/* isync */
2212
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
2213
{
2214
}
2215

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

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

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

    
2296
/* sync */
2297
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
2298
{
2299
}
2300

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

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

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

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

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

    
2367
/* lfd lfdu lfdux lfdx */
2368
GEN_LDFS(fd, 0x12);
2369
/* lfs lfsu lfsux lfsx */
2370
GEN_LDFS(fs, 0x10);
2371

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

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

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

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

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

    
2438
/* stfd stfdu stfdux stfdx */
2439
GEN_STFS(fd, 0x16);
2440
/* stfs stfsu stfsux stfsx */
2441
GEN_STFS(fs, 0x14);
2442

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

    
2456
/***                                Branch                                 ***/
2457

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

    
2493
/* b ba bl bla */
2494
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2495
{
2496
    target_ulong li, target;
2497

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

    
2521
#define BCOND_IM  0
2522
#define BCOND_LR  1
2523
#define BCOND_CTR 2
2524

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

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

    
2670
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2671
{                     
2672
    gen_bcond(ctx, BCOND_IM);
2673
}
2674

    
2675
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
2676
{                    
2677
    gen_bcond(ctx, BCOND_CTR);
2678
}
2679

    
2680
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
2681
{                     
2682
    gen_bcond(ctx, BCOND_LR);
2683
}
2684

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2886
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
2887
{
2888
    gen_op_mfspr(ctx);
2889
}
2890

    
2891
/* mftb */
2892
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB)
2893
{
2894
    gen_op_mfspr(ctx);
2895
}
2896

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

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

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

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

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

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

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

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

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

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

    
3064
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3065
{
3066
    gen_addr_reg_index(ctx);
3067
    op_dcbz();
3068
    gen_op_check_reservation();
3069
}
3070

    
3071
/* icbi */
3072
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3073
{
3074
    /* NIP cannot be restored if the memory exception comes from an helper */
3075
    gen_update_nip(ctx, ctx->nip - 4);
3076
    gen_addr_reg_index(ctx);
3077
#if defined(TARGET_PPC64)
3078
    if (ctx->sf_mode)
3079
        gen_op_icbi_64();
3080
    else
3081
#endif
3082
        gen_op_icbi();
3083
    RET_STOP(ctx);
3084
}
3085

    
3086
/* Optional: */
3087
/* dcba */
3088
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT)
3089
{
3090
}
3091

    
3092
/***                    Segment register manipulation                      ***/
3093
/* Supervisor only: */
3094
/* mfsr */
3095
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3096
{
3097
#if defined(CONFIG_USER_ONLY)
3098
    RET_PRIVREG(ctx);
3099
#else
3100
    if (unlikely(!ctx->supervisor)) {
3101
        RET_PRIVREG(ctx);
3102
        return;
3103
    }
3104
    gen_op_set_T1(SR(ctx->opcode));
3105
    gen_op_load_sr();
3106
    gen_op_store_T0_gpr(rD(ctx->opcode));
3107
#endif
3108
}
3109

    
3110
/* mfsrin */
3111
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3112
{
3113
#if defined(CONFIG_USER_ONLY)
3114
    RET_PRIVREG(ctx);
3115
#else
3116
    if (unlikely(!ctx->supervisor)) {
3117
        RET_PRIVREG(ctx);
3118
        return;
3119
    }
3120
    gen_op_load_gpr_T1(rB(ctx->opcode));
3121
    gen_op_srli_T1(28);
3122
    gen_op_load_sr();
3123
    gen_op_store_T0_gpr(rD(ctx->opcode));
3124
#endif
3125
}
3126

    
3127
/* mtsr */
3128
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3129
{
3130
#if defined(CONFIG_USER_ONLY)
3131
    RET_PRIVREG(ctx);
3132
#else
3133
    if (unlikely(!ctx->supervisor)) {
3134
        RET_PRIVREG(ctx);
3135
        return;
3136
    }
3137
    gen_op_load_gpr_T0(rS(ctx->opcode));
3138
    gen_op_set_T1(SR(ctx->opcode));
3139
    gen_op_store_sr();
3140
    RET_STOP(ctx);
3141
#endif
3142
}
3143

    
3144
/* mtsrin */
3145
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 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_T0(rS(ctx->opcode));
3155
    gen_op_load_gpr_T1(rB(ctx->opcode));
3156
    gen_op_srli_T1(28);
3157
    gen_op_store_sr();
3158
    RET_STOP(ctx);
3159
#endif
3160
}
3161

    
3162
/***                      Lookaside buffer management                      ***/
3163
/* Optional & supervisor only: */
3164
/* tlbia */
3165
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3166
{
3167
#if defined(CONFIG_USER_ONLY)
3168
    RET_PRIVOPC(ctx);
3169
#else
3170
    if (unlikely(!ctx->supervisor)) {
3171
        if (loglevel)
3172
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3173
        RET_PRIVOPC(ctx);
3174
        return;
3175
    }
3176
    gen_op_tlbia();
3177
    RET_STOP(ctx);
3178
#endif
3179
}
3180

    
3181
/* tlbie */
3182
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3183
{
3184
#if defined(CONFIG_USER_ONLY)
3185
    RET_PRIVOPC(ctx);
3186
#else
3187
    if (unlikely(!ctx->supervisor)) {
3188
        RET_PRIVOPC(ctx);
3189
        return;
3190
    }
3191
    gen_op_load_gpr_T0(rB(ctx->opcode));
3192
#if defined(TARGET_PPC64)
3193
    if (ctx->sf_mode)
3194
        gen_op_tlbie_64();
3195
    else
3196
#endif
3197
        gen_op_tlbie();
3198
    RET_STOP(ctx);
3199
#endif
3200
}
3201

    
3202
/* tlbsync */
3203
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3204
{
3205
#if defined(CONFIG_USER_ONLY)
3206
    RET_PRIVOPC(ctx);
3207
#else
3208
    if (unlikely(!ctx->supervisor)) {
3209
        RET_PRIVOPC(ctx);
3210
        return;
3211
    }
3212
    /* This has no effect: it should ensure that all previous
3213
     * tlbie have completed
3214
     */
3215
    RET_STOP(ctx);
3216
#endif
3217
}
3218

    
3219
/***                              External control                         ***/
3220
/* Optional: */
3221
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3222
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3223
#if defined(TARGET_PPC64)
3224
#if defined(CONFIG_USER_ONLY)
3225
static GenOpFunc *gen_op_eciwx[] = {
3226
    &gen_op_eciwx_raw,
3227
    &gen_op_eciwx_le_raw,
3228
    &gen_op_eciwx_64_raw,
3229
    &gen_op_eciwx_le_64_raw,
3230
};
3231
static GenOpFunc *gen_op_ecowx[] = {
3232
    &gen_op_ecowx_raw,
3233
    &gen_op_ecowx_le_raw,
3234
    &gen_op_ecowx_64_raw,
3235
    &gen_op_ecowx_le_64_raw,
3236
};
3237
#else
3238
static GenOpFunc *gen_op_eciwx[] = {
3239
    &gen_op_eciwx_user,
3240
    &gen_op_eciwx_le_user,
3241
    &gen_op_eciwx_kernel,
3242
    &gen_op_eciwx_le_kernel,
3243
    &gen_op_eciwx_64_user,
3244
    &gen_op_eciwx_le_64_user,
3245
    &gen_op_eciwx_64_kernel,
3246
    &gen_op_eciwx_le_64_kernel,
3247
};
3248
static GenOpFunc *gen_op_ecowx[] = {
3249
    &gen_op_ecowx_user,
3250
    &gen_op_ecowx_le_user,
3251
    &gen_op_ecowx_kernel,
3252
    &gen_op_ecowx_le_kernel,
3253
    &gen_op_ecowx_64_user,
3254
    &gen_op_ecowx_le_64_user,
3255
    &gen_op_ecowx_64_kernel,
3256
    &gen_op_ecowx_le_64_kernel,
3257
};
3258
#endif
3259
#else
3260
#if defined(CONFIG_USER_ONLY)
3261
static GenOpFunc *gen_op_eciwx[] = {
3262
    &gen_op_eciwx_raw,
3263
    &gen_op_eciwx_le_raw,
3264
};
3265
static GenOpFunc *gen_op_ecowx[] = {
3266
    &gen_op_ecowx_raw,
3267
    &gen_op_ecowx_le_raw,
3268
};
3269
#else
3270
static GenOpFunc *gen_op_eciwx[] = {
3271
    &gen_op_eciwx_user,
3272
    &gen_op_eciwx_le_user,
3273
    &gen_op_eciwx_kernel,
3274
    &gen_op_eciwx_le_kernel,
3275
};
3276
static GenOpFunc *gen_op_ecowx[] = {
3277
    &gen_op_ecowx_user,
3278
    &gen_op_ecowx_le_user,
3279
    &gen_op_ecowx_kernel,
3280
    &gen_op_ecowx_le_kernel,
3281
};
3282
#endif
3283
#endif
3284

    
3285
/* eciwx */
3286
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3287
{
3288
    /* Should check EAR[E] & alignment ! */
3289
    gen_addr_reg_index(ctx);
3290
    op_eciwx();
3291
    gen_op_store_T0_gpr(rD(ctx->opcode));
3292
}
3293

    
3294
/* ecowx */
3295
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3296
{
3297
    /* Should check EAR[E] & alignment ! */
3298
    gen_addr_reg_index(ctx);
3299
    gen_op_load_gpr_T1(rS(ctx->opcode));
3300
    op_ecowx();
3301
}
3302

    
3303
/* PowerPC 601 specific instructions */
3304
/* abs - abs. */
3305
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3306
{
3307
    gen_op_load_gpr_T0(rA(ctx->opcode));
3308
    gen_op_POWER_abs();
3309
    gen_op_store_T0_gpr(rD(ctx->opcode));
3310
    if (unlikely(Rc(ctx->opcode) != 0))
3311
        gen_set_Rc0(ctx);
3312
}
3313

    
3314
/* abso - abso. */
3315
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3316
{
3317
    gen_op_load_gpr_T0(rA(ctx->opcode));
3318
    gen_op_POWER_abso();
3319
    gen_op_store_T0_gpr(rD(ctx->opcode));
3320
    if (unlikely(Rc(ctx->opcode) != 0))
3321
        gen_set_Rc0(ctx);
3322
}
3323

    
3324
/* clcs */
3325
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR) /* 601 ? */
3326
{
3327
    gen_op_load_gpr_T0(rA(ctx->opcode));
3328
    gen_op_POWER_clcs();
3329
    gen_op_store_T0_gpr(rD(ctx->opcode));
3330
}
3331

    
3332
/* div - div. */
3333
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3334
{
3335
    gen_op_load_gpr_T0(rA(ctx->opcode));
3336
    gen_op_load_gpr_T1(rB(ctx->opcode));
3337
    gen_op_POWER_div();
3338
    gen_op_store_T0_gpr(rD(ctx->opcode));
3339
    if (unlikely(Rc(ctx->opcode) != 0))
3340
        gen_set_Rc0(ctx);
3341
}
3342

    
3343
/* divo - divo. */
3344
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3345
{
3346
    gen_op_load_gpr_T0(rA(ctx->opcode));
3347
    gen_op_load_gpr_T1(rB(ctx->opcode));
3348
    gen_op_POWER_divo();
3349
    gen_op_store_T0_gpr(rD(ctx->opcode));
3350
    if (unlikely(Rc(ctx->opcode) != 0))
3351
        gen_set_Rc0(ctx);
3352
}
3353

    
3354
/* divs - divs. */
3355
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3356
{
3357
    gen_op_load_gpr_T0(rA(ctx->opcode));
3358
    gen_op_load_gpr_T1(rB(ctx->opcode));
3359
    gen_op_POWER_divs();
3360
    gen_op_store_T0_gpr(rD(ctx->opcode));
3361
    if (unlikely(Rc(ctx->opcode) != 0))
3362
        gen_set_Rc0(ctx);
3363
}
3364

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

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

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

    
3398
/* dozi */
3399
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3400
{
3401
    gen_op_load_gpr_T0(rA(ctx->opcode));
3402
    gen_op_set_T1(SIMM(ctx->opcode));
3403
    gen_op_POWER_doz();
3404
    gen_op_store_T0_gpr(rD(ctx->opcode));
3405
}
3406

    
3407
/* As lscbx load from memory byte after byte, it's always endian safe */
3408
#define op_POWER_lscbx(start, ra, rb) \
3409
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3410
#if defined(CONFIG_USER_ONLY)
3411
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3412
    &gen_op_POWER_lscbx_raw,
3413
    &gen_op_POWER_lscbx_raw,
3414
};
3415
#else
3416
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3417
    &gen_op_POWER_lscbx_user,
3418
    &gen_op_POWER_lscbx_user,
3419
    &gen_op_POWER_lscbx_kernel,
3420
    &gen_op_POWER_lscbx_kernel,
3421
};
3422
#endif
3423

    
3424
/* lscbx - lscbx. */
3425
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3426
{
3427
    int ra = rA(ctx->opcode);
3428
    int rb = rB(ctx->opcode);
3429

    
3430
    gen_addr_reg_index(ctx);
3431
    if (ra == 0) {
3432
        ra = rb;
3433
    }
3434
    /* NIP cannot be restored if the memory exception comes from an helper */
3435
    gen_update_nip(ctx, ctx->nip - 4);
3436
    gen_op_load_xer_bc();
3437
    gen_op_load_xer_cmp();
3438
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3439
    gen_op_store_xer_bc();
3440
    if (unlikely(Rc(ctx->opcode) != 0))
3441
        gen_set_Rc0(ctx);
3442
}
3443

    
3444
/* maskg - maskg. */
3445
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3446
{
3447
    gen_op_load_gpr_T0(rS(ctx->opcode));
3448
    gen_op_load_gpr_T1(rB(ctx->opcode));
3449
    gen_op_POWER_maskg();
3450
    gen_op_store_T0_gpr(rA(ctx->opcode));
3451
    if (unlikely(Rc(ctx->opcode) != 0))
3452
        gen_set_Rc0(ctx);
3453
}
3454

    
3455
/* maskir - maskir. */
3456
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3457
{
3458
    gen_op_load_gpr_T0(rA(ctx->opcode));
3459
    gen_op_load_gpr_T1(rS(ctx->opcode));
3460
    gen_op_load_gpr_T2(rB(ctx->opcode));
3461
    gen_op_POWER_maskir();
3462
    gen_op_store_T0_gpr(rA(ctx->opcode));
3463
    if (unlikely(Rc(ctx->opcode) != 0))
3464
        gen_set_Rc0(ctx);
3465
}
3466

    
3467
/* mul - mul. */
3468
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
3469
{
3470
    gen_op_load_gpr_T0(rA(ctx->opcode));
3471
    gen_op_load_gpr_T1(rB(ctx->opcode));
3472
    gen_op_POWER_mul();
3473
    gen_op_store_T0_gpr(rD(ctx->opcode));
3474
    if (unlikely(Rc(ctx->opcode) != 0))
3475
        gen_set_Rc0(ctx);
3476
}
3477

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

    
3489
/* nabs - nabs. */
3490
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
3491
{
3492
    gen_op_load_gpr_T0(rA(ctx->opcode));
3493
    gen_op_POWER_nabs();
3494
    gen_op_store_T0_gpr(rD(ctx->opcode));
3495
    if (unlikely(Rc(ctx->opcode) != 0))
3496
        gen_set_Rc0(ctx);
3497
}
3498

    
3499
/* nabso - nabso. */
3500
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
3501
{
3502
    gen_op_load_gpr_T0(rA(ctx->opcode));
3503
    gen_op_POWER_nabso();
3504
    gen_op_store_T0_gpr(rD(ctx->opcode));
3505
    if (unlikely(Rc(ctx->opcode) != 0))
3506
        gen_set_Rc0(ctx);
3507
}
3508

    
3509
/* rlmi - rlmi. */
3510
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3511
{
3512
    uint32_t mb, me;
3513

    
3514
    mb = MB(ctx->opcode);
3515
    me = ME(ctx->opcode);
3516
    gen_op_load_gpr_T0(rS(ctx->opcode));
3517
    gen_op_load_gpr_T1(rA(ctx->opcode));
3518
    gen_op_load_gpr_T2(rB(ctx->opcode));
3519
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
3520
    gen_op_store_T0_gpr(rA(ctx->opcode));
3521
    if (unlikely(Rc(ctx->opcode) != 0))
3522
        gen_set_Rc0(ctx);
3523
}
3524

    
3525
/* rrib - rrib. */
3526
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
3527
{
3528
    gen_op_load_gpr_T0(rS(ctx->opcode));
3529
    gen_op_load_gpr_T1(rA(ctx->opcode));
3530
    gen_op_load_gpr_T2(rB(ctx->opcode));
3531
    gen_op_POWER_rrib();
3532
    gen_op_store_T0_gpr(rA(ctx->opcode));
3533
    if (unlikely(Rc(ctx->opcode) != 0))
3534
        gen_set_Rc0(ctx);
3535
}
3536

    
3537
/* sle - sle. */
3538
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
3539
{
3540
    gen_op_load_gpr_T0(rS(ctx->opcode));
3541
    gen_op_load_gpr_T1(rB(ctx->opcode));
3542
    gen_op_POWER_sle();
3543
    gen_op_store_T0_gpr(rA(ctx->opcode));
3544
    if (unlikely(Rc(ctx->opcode) != 0))
3545
        gen_set_Rc0(ctx);
3546
}
3547

    
3548
/* sleq - sleq. */
3549
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
3550
{
3551
    gen_op_load_gpr_T0(rS(ctx->opcode));
3552
    gen_op_load_gpr_T1(rB(ctx->opcode));
3553
    gen_op_POWER_sleq();
3554
    gen_op_store_T0_gpr(rA(ctx->opcode));
3555
    if (unlikely(Rc(ctx->opcode) != 0))
3556
        gen_set_Rc0(ctx);
3557
}
3558

    
3559
/* sliq - sliq. */
3560
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
3561
{
3562
    gen_op_load_gpr_T0(rS(ctx->opcode));
3563
    gen_op_set_T1(SH(ctx->opcode));
3564
    gen_op_POWER_sle();
3565
    gen_op_store_T0_gpr(rA(ctx->opcode));
3566
    if (unlikely(Rc(ctx->opcode) != 0))
3567
        gen_set_Rc0(ctx);
3568
}
3569

    
3570
/* slliq - slliq. */
3571
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
3572
{
3573
    gen_op_load_gpr_T0(rS(ctx->opcode));
3574
    gen_op_set_T1(SH(ctx->opcode));
3575
    gen_op_POWER_sleq();
3576
    gen_op_store_T0_gpr(rA(ctx->opcode));
3577
    if (unlikely(Rc(ctx->opcode) != 0))
3578
        gen_set_Rc0(ctx);
3579
}
3580

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

    
3592
/* slq - slq. */
3593
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
3594
{
3595
    gen_op_load_gpr_T0(rS(ctx->opcode));
3596
    gen_op_load_gpr_T1(rB(ctx->opcode));
3597
    gen_op_POWER_slq();
3598
    gen_op_store_T0_gpr(rA(ctx->opcode));
3599
    if (unlikely(Rc(ctx->opcode) != 0))
3600
        gen_set_Rc0(ctx);
3601
}
3602

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

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

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

    
3636
/* srea - srea. */
3637
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
3638
{
3639
    gen_op_load_gpr_T0(rS(ctx->opcode));
3640
    gen_op_load_gpr_T1(rB(ctx->opcode));
3641
    gen_op_POWER_srea();
3642
    gen_op_store_T0_gpr(rA(ctx->opcode));
3643
    if (unlikely(Rc(ctx->opcode) != 0))
3644
        gen_set_Rc0(ctx);
3645
}
3646

    
3647
/* sreq */
3648
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
3649
{
3650
    gen_op_load_gpr_T0(rS(ctx->opcode));
3651
    gen_op_load_gpr_T1(rB(ctx->opcode));
3652
    gen_op_POWER_sreq();
3653
    gen_op_store_T0_gpr(rA(ctx->opcode));
3654
    if (unlikely(Rc(ctx->opcode) != 0))
3655
        gen_set_Rc0(ctx);
3656
}
3657

    
3658
/* sriq */
3659
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
3660
{
3661
    gen_op_load_gpr_T0(rS(ctx->opcode));
3662
    gen_op_set_T1(SH(ctx->opcode));
3663
    gen_op_POWER_srq();
3664
    gen_op_store_T0_gpr(rA(ctx->opcode));
3665
    if (unlikely(Rc(ctx->opcode) != 0))
3666
        gen_set_Rc0(ctx);
3667
}
3668

    
3669
/* srliq */
3670
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
3671
{
3672
    gen_op_load_gpr_T0(rS(ctx->opcode));
3673
    gen_op_load_gpr_T1(rB(ctx->opcode));
3674
    gen_op_set_T1(SH(ctx->opcode));
3675
    gen_op_POWER_srlq();
3676
    gen_op_store_T0_gpr(rA(ctx->opcode));
3677
    if (unlikely(Rc(ctx->opcode) != 0))
3678
        gen_set_Rc0(ctx);
3679
}
3680

    
3681
/* srlq */
3682
GEN_HANDLER(srlq, 0x1F, 0x18, 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_srlq();
3687
    gen_op_store_T0_gpr(rA(ctx->opcode));
3688
    if (unlikely(Rc(ctx->opcode) != 0))
3689
        gen_set_Rc0(ctx);
3690
}
3691

    
3692
/* srq */
3693
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
3694
{
3695
    gen_op_load_gpr_T0(rS(ctx->opcode));
3696
    gen_op_load_gpr_T1(rB(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
/* PowerPC 602 specific instructions */
3704
/* dsa  */
3705
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
3706
{
3707
    /* XXX: TODO */
3708
    RET_INVAL(ctx);
3709
}
3710

    
3711
/* esa */
3712
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
3713
{
3714
    /* XXX: TODO */
3715
    RET_INVAL(ctx);
3716
}
3717

    
3718
/* mfrom */
3719
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
3720
{
3721
#if defined(CONFIG_USER_ONLY)
3722
    RET_PRIVOPC(ctx);
3723
#else
3724
    if (unlikely(!ctx->supervisor)) {
3725
        RET_PRIVOPC(ctx);
3726
        return;
3727
    }
3728
    gen_op_load_gpr_T0(rA(ctx->opcode));
3729
    gen_op_602_mfrom();
3730
    gen_op_store_T0_gpr(rD(ctx->opcode));
3731
#endif
3732
}
3733

    
3734
/* 602 - 603 - G2 TLB management */
3735
/* tlbld */
3736
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
3737
{
3738
#if defined(CONFIG_USER_ONLY)
3739
    RET_PRIVOPC(ctx);
3740
#else
3741
    if (unlikely(!ctx->supervisor)) {
3742
        RET_PRIVOPC(ctx);
3743
        return;
3744
    }
3745
    gen_op_load_gpr_T0(rB(ctx->opcode));
3746
    gen_op_6xx_tlbld();
3747
    RET_STOP(ctx);
3748
#endif
3749
}
3750

    
3751
/* tlbli */
3752
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
3753
{
3754
#if defined(CONFIG_USER_ONLY)
3755
    RET_PRIVOPC(ctx);
3756
#else
3757
    if (unlikely(!ctx->supervisor)) {
3758
        RET_PRIVOPC(ctx);
3759
        return;
3760
    }
3761
    gen_op_load_gpr_T0(rB(ctx->opcode));
3762
    gen_op_6xx_tlbli();
3763
    RET_STOP(ctx);
3764
#endif
3765
}
3766

    
3767
/* POWER instructions not in PowerPC 601 */
3768
/* clf */
3769
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
3770
{
3771
    /* Cache line flush: implemented as no-op */
3772
}
3773

    
3774
/* cli */
3775
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
3776
{
3777
    /* Cache line invalidate: priviledged and treated as no-op */
3778
#if defined(CONFIG_USER_ONLY)
3779
    RET_PRIVOPC(ctx);
3780
#else
3781
    if (unlikely(!ctx->supervisor)) {
3782
        RET_PRIVOPC(ctx);
3783
        return;
3784
    }
3785
#endif
3786
}
3787

    
3788
/* dclst */
3789
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
3790
{
3791
    /* Data cache line store: treated as no-op */
3792
}
3793

    
3794
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
3795
{
3796
#if defined(CONFIG_USER_ONLY)
3797
    RET_PRIVOPC(ctx);
3798
#else
3799
    if (unlikely(!ctx->supervisor)) {
3800
        RET_PRIVOPC(ctx);
3801
        return;
3802
    }
3803
    int ra = rA(ctx->opcode);
3804
    int rd = rD(ctx->opcode);
3805

    
3806
    gen_addr_reg_index(ctx);
3807
    gen_op_POWER_mfsri();
3808
    gen_op_store_T0_gpr(rd);
3809
    if (ra != 0 && ra != rd)
3810
        gen_op_store_T1_gpr(ra);
3811
#endif
3812
}
3813

    
3814
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
3815
{
3816
#if defined(CONFIG_USER_ONLY)
3817
    RET_PRIVOPC(ctx);
3818
#else
3819
    if (unlikely(!ctx->supervisor)) {
3820
        RET_PRIVOPC(ctx);
3821
        return;
3822
    }
3823
    gen_addr_reg_index(ctx);
3824
    gen_op_POWER_rac();
3825
    gen_op_store_T0_gpr(rD(ctx->opcode));
3826
#endif
3827
}
3828

    
3829
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
3830
{
3831
#if defined(CONFIG_USER_ONLY)
3832
    RET_PRIVOPC(ctx);
3833
#else
3834
    if (unlikely(!ctx->supervisor)) {
3835
        RET_PRIVOPC(ctx);
3836
        return;
3837
    }
3838
    gen_op_POWER_rfsvc();
3839
    RET_CHG_FLOW(ctx);
3840
#endif
3841
}
3842

    
3843
/* svc is not implemented for now */
3844

    
3845
/* POWER2 specific instructions */
3846
/* Quad manipulation (load/store two floats at a time) */
3847
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
3848
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
3849
#if defined(CONFIG_USER_ONLY)
3850
static GenOpFunc *gen_op_POWER2_lfq[] = {
3851
    &gen_op_POWER2_lfq_le_raw,
3852
    &gen_op_POWER2_lfq_raw,
3853
};
3854
static GenOpFunc *gen_op_POWER2_stfq[] = {
3855
    &gen_op_POWER2_stfq_le_raw,
3856
    &gen_op_POWER2_stfq_raw,
3857
};
3858
#else
3859
static GenOpFunc *gen_op_POWER2_lfq[] = {
3860
    &gen_op_POWER2_lfq_le_user,
3861
    &gen_op_POWER2_lfq_user,
3862
    &gen_op_POWER2_lfq_le_kernel,
3863
    &gen_op_POWER2_lfq_kernel,
3864
};
3865
static GenOpFunc *gen_op_POWER2_stfq[] = {
3866
    &gen_op_POWER2_stfq_le_user,
3867
    &gen_op_POWER2_stfq_user,
3868
    &gen_op_POWER2_stfq_le_kernel,
3869
    &gen_op_POWER2_stfq_kernel,
3870
};
3871
#endif
3872

    
3873
/* lfq */
3874
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3875
{
3876
    /* NIP cannot be restored if the memory exception comes from an helper */
3877
    gen_update_nip(ctx, ctx->nip - 4);
3878
    gen_addr_imm_index(ctx);
3879
    op_POWER2_lfq();
3880
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3881
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3882
}
3883

    
3884
/* lfqu */
3885
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3886
{
3887
    int ra = rA(ctx->opcode);
3888

    
3889
    /* NIP cannot be restored if the memory exception comes from an helper */
3890
    gen_update_nip(ctx, ctx->nip - 4);
3891
    gen_addr_imm_index(ctx);
3892
    op_POWER2_lfq();
3893
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3894
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3895
    if (ra != 0)
3896
        gen_op_store_T0_gpr(ra);
3897
}
3898

    
3899
/* lfqux */
3900
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
3901
{
3902
    int ra = rA(ctx->opcode);
3903

    
3904
    /* NIP cannot be restored if the memory exception comes from an helper */
3905
    gen_update_nip(ctx, ctx->nip - 4);
3906
    gen_addr_reg_index(ctx);
3907
    op_POWER2_lfq();
3908
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3909
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3910
    if (ra != 0)
3911
        gen_op_store_T0_gpr(ra);
3912
}
3913

    
3914
/* lfqx */
3915
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
3916
{
3917
    /* NIP cannot be restored if the memory exception comes from an helper */
3918
    gen_update_nip(ctx, ctx->nip - 4);
3919
    gen_addr_reg_index(ctx);
3920
    op_POWER2_lfq();
3921
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3922
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3923
}
3924

    
3925
/* stfq */
3926
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3927
{
3928
    /* NIP cannot be restored if the memory exception comes from an helper */
3929
    gen_update_nip(ctx, ctx->nip - 4);
3930
    gen_addr_imm_index(ctx);
3931
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3932
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3933
    op_POWER2_stfq();
3934
}
3935

    
3936
/* stfqu */
3937
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3938
{
3939
    int ra = rA(ctx->opcode);
3940

    
3941
    /* NIP cannot be restored if the memory exception comes from an helper */
3942
    gen_update_nip(ctx, ctx->nip - 4);
3943
    gen_addr_imm_index(ctx);
3944
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3945
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3946
    op_POWER2_stfq();
3947
    if (ra != 0)
3948
        gen_op_store_T0_gpr(ra);
3949
}
3950

    
3951
/* stfqux */
3952
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
3953
{
3954
    int ra = rA(ctx->opcode);
3955

    
3956
    /* NIP cannot be restored if the memory exception comes from an helper */
3957
    gen_update_nip(ctx, ctx->nip - 4);
3958
    gen_addr_reg_index(ctx);
3959
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3960
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3961
    op_POWER2_stfq();
3962
    if (ra != 0)
3963
        gen_op_store_T0_gpr(ra);
3964
}
3965

    
3966
/* stfqx */
3967
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
3968
{
3969
    /* NIP cannot be restored if the memory exception comes from an helper */
3970
    gen_update_nip(ctx, ctx->nip - 4);
3971
    gen_addr_reg_index(ctx);
3972
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3973
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3974
    op_POWER2_stfq();
3975
}
3976

    
3977
/* BookE specific instructions */
3978
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE)
3979
{
3980
    /* XXX: TODO */
3981
    RET_INVAL(ctx);
3982
}
3983

    
3984
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE)
3985
{
3986
#if defined(CONFIG_USER_ONLY)
3987
    RET_PRIVOPC(ctx);
3988
#else
3989
    if (unlikely(!ctx->supervisor)) {
3990
        RET_PRIVOPC(ctx);
3991
        return;
3992
    }
3993
    gen_addr_reg_index(ctx);
3994
    /* Use the same micro-ops as for tlbie */
3995
#if defined(TARGET_PPC64)
3996
    if (ctx->sf_mode)
3997
        gen_op_tlbie_64();
3998
    else
3999
#endif
4000
        gen_op_tlbie();
4001
    RET_STOP(ctx);
4002
#endif
4003
}
4004

    
4005
/* All 405 MAC instructions are translated here */
4006
static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
4007
                                         int ra, int rb, int rt, int Rc)
4008
{
4009
    gen_op_load_gpr_T0(ra);
4010
    gen_op_load_gpr_T1(rb);
4011
    switch (opc3 & 0x0D) {
4012
    case 0x05:
4013
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4014
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4015
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4016
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4017
        /* mulchw - mulchw. */
4018
        gen_op_405_mulchw();
4019
        break;
4020
    case 0x04:
4021
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4022
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4023
        /* mulchwu - mulchwu. */
4024
        gen_op_405_mulchwu();
4025
        break;
4026
    case 0x01:
4027
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4028
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4029
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4030
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4031
        /* mulhhw - mulhhw. */
4032
        gen_op_405_mulhhw();
4033
        break;
4034
    case 0x00:
4035
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4036
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4037
        /* mulhhwu - mulhhwu. */
4038
        gen_op_405_mulhhwu();
4039
        break;
4040
    case 0x0D:
4041
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4042
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4043
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4044
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4045
        /* mullhw - mullhw. */
4046
        gen_op_405_mullhw();
4047
        break;
4048
    case 0x0C:
4049
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4050
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4051
        /* mullhwu - mullhwu. */
4052
        gen_op_405_mullhwu();
4053
        break;
4054
    }
4055
    if (opc2 & 0x02) {
4056
        /* nmultiply-and-accumulate (0x0E) */
4057
        gen_op_neg();
4058
    }
4059
    if (opc2 & 0x04) {
4060
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4061
        gen_op_load_gpr_T2(rt);
4062
        gen_op_move_T1_T0();
4063
        gen_op_405_add_T0_T2();
4064
    }
4065
    if (opc3 & 0x10) {
4066
        /* Check overflow */
4067
        if (opc3 & 0x01)
4068
            gen_op_405_check_ov();
4069
        else
4070
            gen_op_405_check_ovu();
4071
    }
4072
    if (opc3 & 0x02) {
4073
        /* Saturate */
4074
        if (opc3 & 0x01)
4075
            gen_op_405_check_sat();
4076
        else
4077
            gen_op_405_check_satu();
4078
    }
4079
    gen_op_store_T0_gpr(rt);
4080
    if (unlikely(Rc) != 0) {
4081
        /* Update Rc0 */
4082
        gen_set_Rc0(ctx);
4083
    }
4084
}
4085

    
4086
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4087
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4088
{                                                                             \
4089
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4090
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4091
}
4092

    
4093
/* macchw    - macchw.    */
4094
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4095
/* macchwo   - macchwo.   */
4096
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4097
/* macchws   - macchws.   */
4098
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4099
/* macchwso  - macchwso.  */
4100
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4101
/* macchwsu  - macchwsu.  */
4102
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4103
/* macchwsuo - macchwsuo. */
4104
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4105
/* macchwu   - macchwu.   */
4106
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4107
/* macchwuo  - macchwuo.  */
4108
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4109
/* machhw    - machhw.    */
4110
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4111
/* machhwo   - machhwo.   */
4112
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4113
/* machhws   - machhws.   */
4114
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4115
/* machhwso  - machhwso.  */
4116
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4117
/* machhwsu  - machhwsu.  */
4118
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4119
/* machhwsuo - machhwsuo. */
4120
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4121
/* machhwu   - machhwu.   */
4122
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4123
/* machhwuo  - machhwuo.  */
4124
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4125
/* maclhw    - maclhw.    */
4126
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4127
/* maclhwo   - maclhwo.   */
4128
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4129
/* maclhws   - maclhws.   */
4130
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4131
/* maclhwso  - maclhwso.  */
4132
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4133
/* maclhwu   - maclhwu.   */
4134
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4135
/* maclhwuo  - maclhwuo.  */
4136
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4137
/* maclhwsu  - maclhwsu.  */
4138
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4139
/* maclhwsuo - maclhwsuo. */
4140
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4141
/* nmacchw   - nmacchw.   */
4142
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4143
/* nmacchwo  - nmacchwo.  */
4144
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4145
/* nmacchws  - nmacchws.  */
4146
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4147
/* nmacchwso - nmacchwso. */
4148
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4149
/* nmachhw   - nmachhw.   */
4150
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4151
/* nmachhwo  - nmachhwo.  */
4152
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4153
/* nmachhws  - nmachhws.  */
4154
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4155
/* nmachhwso - nmachhwso. */
4156
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4157
/* nmaclhw   - nmaclhw.   */
4158
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4159
/* nmaclhwo  - nmaclhwo.  */
4160
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4161
/* nmaclhws  - nmaclhws.  */
4162
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4163
/* nmaclhwso - nmaclhwso. */
4164
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4165

    
4166
/* mulchw  - mulchw.  */
4167
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4168
/* mulchwu - mulchwu. */
4169
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4170
/* mulhhw  - mulhhw.  */
4171
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4172
/* mulhhwu - mulhhwu. */
4173
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4174
/* mullhw  - mullhw.  */
4175
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4176
/* mullhwu - mullhwu. */
4177
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4178

    
4179
/* mfdcr */
4180
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4181
{
4182
#if defined(CONFIG_USER_ONLY)
4183
    RET_PRIVREG(ctx);
4184
#else
4185
    uint32_t dcrn = SPR(ctx->opcode);
4186

    
4187
    if (unlikely(!ctx->supervisor)) {
4188
        RET_PRIVREG(ctx);
4189
        return;
4190
    }
4191
    gen_op_4xx_load_dcr(dcrn);
4192
    gen_op_store_T0_gpr(rD(ctx->opcode));
4193
#endif
4194
}
4195

    
4196
/* mtdcr */
4197
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4198
{
4199
#if defined(CONFIG_USER_ONLY)
4200
    RET_PRIVREG(ctx);
4201
#else
4202
    uint32_t dcrn = SPR(ctx->opcode);
4203

    
4204
    if (unlikely(!ctx->supervisor)) {
4205
        RET_PRIVREG(ctx);
4206
        return;
4207
    }
4208
    gen_op_load_gpr_T0(rS(ctx->opcode));
4209
    gen_op_4xx_store_dcr(dcrn);
4210
#endif
4211
}
4212

    
4213
/* dccci */
4214
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4215
{
4216
#if defined(CONFIG_USER_ONLY)
4217
    RET_PRIVOPC(ctx);
4218
#else
4219
    if (unlikely(!ctx->supervisor)) {
4220
        RET_PRIVOPC(ctx);
4221
        return;
4222
    }
4223
    /* interpreted as no-op */
4224
#endif
4225
}
4226

    
4227
/* dcread */
4228
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4229
{
4230
#if defined(CONFIG_USER_ONLY)
4231
    RET_PRIVOPC(ctx);
4232
#else
4233
    if (unlikely(!ctx->supervisor)) {
4234
        RET_PRIVOPC(ctx);
4235
        return;
4236
    }
4237
    gen_addr_reg_index(ctx);
4238
    op_ldst(lwz);
4239
    gen_op_store_T0_gpr(rD(ctx->opcode));
4240
#endif
4241
}
4242

    
4243
/* icbt */
4244
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC)
4245
{
4246
    /* interpreted as no-op */
4247
    /* XXX: specification say this is treated as a load by the MMU
4248
     *      but does not generate any exception
4249
     */
4250
}
4251

    
4252
/* iccci */
4253
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4254
{
4255
#if defined(CONFIG_USER_ONLY)
4256
    RET_PRIVOPC(ctx);
4257
#else
4258
    if (unlikely(!ctx->supervisor)) {
4259
        RET_PRIVOPC(ctx);
4260
        return;
4261
    }
4262
    /* interpreted as no-op */
4263
#endif
4264
}
4265

    
4266
/* icread */
4267
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4268
{
4269
#if defined(CONFIG_USER_ONLY)
4270
    RET_PRIVOPC(ctx);
4271
#else
4272
    if (unlikely(!ctx->supervisor)) {
4273
        RET_PRIVOPC(ctx);
4274
        return;
4275
    }
4276
    /* interpreted as no-op */
4277
#endif
4278
}
4279

    
4280
/* rfci (supervisor only) */
4281
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_EMB_COMMON)
4282
{
4283
#if defined(CONFIG_USER_ONLY)
4284
    RET_PRIVOPC(ctx);
4285
#else
4286
    if (unlikely(!ctx->supervisor)) {
4287
        RET_PRIVOPC(ctx);
4288
        return;
4289
    }
4290
    /* Restore CPU state */
4291
    gen_op_4xx_rfci();
4292
    RET_CHG_FLOW(ctx);
4293
#endif
4294
}
4295

    
4296
/* TLB management - PowerPC 405 implementation */
4297
/* tlbre */
4298
GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_EMB_COMMON)
4299
{
4300
#if defined(CONFIG_USER_ONLY)
4301
    RET_PRIVOPC(ctx);
4302
#else
4303
    if (unlikely(!ctx->supervisor)) {
4304
        RET_PRIVOPC(ctx);
4305
        return;
4306
    }
4307
    switch (rB(ctx->opcode)) {
4308
    case 0:
4309
        gen_op_load_gpr_T0(rA(ctx->opcode));
4310
        gen_op_4xx_tlbre_hi();
4311
        gen_op_store_T0_gpr(rD(ctx->opcode));
4312
        break;
4313
    case 1:
4314
        gen_op_load_gpr_T0(rA(ctx->opcode));
4315
        gen_op_4xx_tlbre_lo();
4316
        gen_op_store_T0_gpr(rD(ctx->opcode));
4317
        break;
4318
    default:
4319
        RET_INVAL(ctx);
4320
        break;
4321
    }
4322
#endif
4323
}
4324

    
4325
/* tlbsx - tlbsx. */
4326
GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_EMB_COMMON)
4327
{
4328
#if defined(CONFIG_USER_ONLY)
4329
    RET_PRIVOPC(ctx);
4330
#else
4331
    if (unlikely(!ctx->supervisor)) {
4332
        RET_PRIVOPC(ctx);
4333
        return;
4334
    }
4335
    gen_addr_reg_index(ctx);
4336
    if (Rc(ctx->opcode))
4337
        gen_op_4xx_tlbsx_();
4338
    else
4339
        gen_op_4xx_tlbsx();
4340
    gen_op_store_T0_gpr(rD(ctx->opcode));
4341
#endif
4342
}
4343

    
4344
/* tlbwe */
4345
GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC)
4346
{
4347
#if defined(CONFIG_USER_ONLY)
4348
    RET_PRIVOPC(ctx);
4349
#else
4350
    if (unlikely(!ctx->supervisor)) {
4351
        RET_PRIVOPC(ctx);
4352
        return;
4353
    }
4354
    switch (rB(ctx->opcode)) {
4355
    case 0:
4356
        gen_op_load_gpr_T0(rA(ctx->opcode));
4357
        gen_op_load_gpr_T1(rS(ctx->opcode));
4358
        gen_op_4xx_tlbwe_hi();
4359
        break;
4360
    case 1:
4361
        gen_op_load_gpr_T0(rA(ctx->opcode));
4362
        gen_op_load_gpr_T1(rS(ctx->opcode));
4363
        gen_op_4xx_tlbwe_lo();
4364
        break;
4365
    default:
4366
        RET_INVAL(ctx);
4367
        break;
4368
    }
4369
#endif
4370
}
4371

    
4372
/* wrtee */
4373
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4374
{
4375
#if defined(CONFIG_USER_ONLY)
4376
    RET_PRIVOPC(ctx);
4377
#else
4378
    if (unlikely(!ctx->supervisor)) {
4379
        RET_PRIVOPC(ctx);
4380
        return;
4381
    }
4382
    gen_op_load_gpr_T0(rD(ctx->opcode));
4383
    gen_op_4xx_wrte();
4384
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4385
#endif
4386
}
4387

    
4388
/* wrteei */
4389
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4390
{
4391
#if defined(CONFIG_USER_ONLY)
4392
    RET_PRIVOPC(ctx);
4393
#else
4394
    if (unlikely(!ctx->supervisor)) {
4395
        RET_PRIVOPC(ctx);
4396
        return;
4397
    }
4398
    gen_op_set_T0(ctx->opcode & 0x00010000);
4399
    gen_op_4xx_wrte();
4400
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4401
#endif
4402
}
4403

    
4404
/* PPC 440 specific instructions */
4405
/* dlmzb */
4406
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
4407
{
4408
    gen_op_load_gpr_T0(rS(ctx->opcode));
4409
    gen_op_load_gpr_T1(rB(ctx->opcode));
4410
    gen_op_440_dlmzb();
4411
    gen_op_store_T0_gpr(rA(ctx->opcode));
4412
    gen_op_store_xer_bc();
4413
    if (Rc(ctx->opcode)) {
4414
        gen_op_440_dlmzb_update_Rc();
4415
        gen_op_store_T0_crf(0);
4416
    }
4417
}
4418

    
4419
/* mbar replaces eieio on 440 */
4420
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
4421
{
4422
    /* interpreted as no-op */
4423
}
4424

    
4425
/* msync replaces sync on 440 */
4426
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
4427
{
4428
    /* interpreted as no-op */
4429
}
4430

    
4431
/* icbt */
4432
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
4433
{
4434
    /* interpreted as no-op */
4435
    /* XXX: specification say this is treated as a load by the MMU
4436
     *      but does not generate any exception
4437
     */
4438
}
4439

    
4440
/* End opcode list */
4441
GEN_OPCODE_MARK(end);
4442

    
4443
#include "translate_init.c"
4444

    
4445
/*****************************************************************************/
4446
/* Misc PowerPC helpers */
4447
static inline uint32_t load_xer (CPUState *env)
4448
{
4449
    return (xer_so << XER_SO) |
4450
        (xer_ov << XER_OV) |
4451
        (xer_ca << XER_CA) |
4452
        (xer_bc << XER_BC) |
4453
        (xer_cmp << XER_CMP);
4454
}
4455

    
4456
void cpu_dump_state(CPUState *env, FILE *f, 
4457
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4458
                    int flags)
4459
{
4460
#if defined(TARGET_PPC64) || 1
4461
#define FILL ""
4462
#define RGPL  4
4463
#define RFPL  4
4464
#else
4465
#define FILL "        "
4466
#define RGPL  8
4467
#define RFPL  4
4468
#endif
4469

    
4470
    int i;
4471

    
4472
    cpu_fprintf(f, "NIP " REGX " LR " REGX " CTR " REGX "\n",
4473
                env->nip, env->lr, env->ctr);
4474
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
4475
#if !defined(NO_TIMER_DUMP)
4476
                "TB %08x %08x "
4477
#if !defined(CONFIG_USER_ONLY)
4478
                "DECR %08x"
4479
#endif
4480
#endif
4481
                "\n",
4482
                do_load_msr(env), load_xer(env)
4483
#if !defined(NO_TIMER_DUMP)
4484
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
4485
#if !defined(CONFIG_USER_ONLY)
4486
                , cpu_ppc_load_decr(env)
4487
#endif
4488
#endif
4489
                );
4490
    for (i = 0; i < 32; i++) {
4491
        if ((i & (RGPL - 1)) == 0)
4492
            cpu_fprintf(f, "GPR%02d", i);
4493
        cpu_fprintf(f, " " REGX, env->gpr[i]);
4494
        if ((i & (RGPL - 1)) == (RGPL - 1))
4495
            cpu_fprintf(f, "\n");
4496
    }
4497
    cpu_fprintf(f, "CR ");
4498
    for (i = 0; i < 8; i++)
4499
        cpu_fprintf(f, "%01x", env->crf[i]);
4500
    cpu_fprintf(f, "  [");
4501
    for (i = 0; i < 8; i++) {
4502
        char a = '-';
4503
        if (env->crf[i] & 0x08)
4504
            a = 'L';
4505
        else if (env->crf[i] & 0x04)
4506
            a = 'G';
4507
        else if (env->crf[i] & 0x02)
4508
            a = 'E';
4509
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
4510
    }
4511
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
4512
    for (i = 0; i < 32; i++) {
4513
        if ((i & (RFPL - 1)) == 0)
4514
            cpu_fprintf(f, "FPR%02d", i);
4515
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
4516
        if ((i & (RFPL - 1)) == (RFPL - 1))
4517
            cpu_fprintf(f, "\n");
4518
    }
4519
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
4520
                "SDR1 " REGX "\n",
4521
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
4522

    
4523
#undef RGPL
4524
#undef RFPL
4525
#undef FILL
4526
}
4527

    
4528
void cpu_dump_statistics (CPUState *env, FILE*f,
4529
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4530
                          int flags)
4531
{
4532
#if defined(DO_PPC_STATISTICS)
4533
    opc_handler_t **t1, **t2, **t3, *handler;
4534
    int op1, op2, op3;
4535

    
4536
    t1 = env->opcodes;
4537
    for (op1 = 0; op1 < 64; op1++) {
4538
        handler = t1[op1];
4539
        if (is_indirect_opcode(handler)) {
4540
            t2 = ind_table(handler);
4541
            for (op2 = 0; op2 < 32; op2++) {
4542
                handler = t2[op2];
4543
                if (is_indirect_opcode(handler)) {
4544
                    t3 = ind_table(handler);
4545
                    for (op3 = 0; op3 < 32; op3++) {
4546
                        handler = t3[op3];
4547
                        if (handler->count == 0)
4548
                            continue;
4549
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
4550
                                    "%016llx %lld\n",
4551
                                    op1, op2, op3, op1, (op3 << 5) | op2,
4552
                                    handler->oname,
4553
                                    handler->count, handler->count);
4554
                    }
4555
                } else {
4556
                    if (handler->count == 0)
4557
                        continue;
4558
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
4559
                                "%016llx %lld\n",
4560
                                op1, op2, op1, op2, handler->oname,
4561
                                handler->count, handler->count);
4562
                }
4563
            }
4564
        } else {
4565
            if (handler->count == 0)
4566
                continue;
4567
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
4568
                        op1, op1, handler->oname,
4569
                        handler->count, handler->count);
4570
        }
4571
    }
4572
#endif
4573
}
4574

    
4575
/*****************************************************************************/
4576
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
4577
                                    int search_pc)
4578
{
4579
    DisasContext ctx, *ctxp = &ctx;
4580
    opc_handler_t **table, *handler;
4581
    target_ulong pc_start;
4582
    uint16_t *gen_opc_end;
4583
    int j, lj = -1;
4584

    
4585
    pc_start = tb->pc;
4586
    gen_opc_ptr = gen_opc_buf;
4587
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4588
    gen_opparam_ptr = gen_opparam_buf;
4589
    nb_gen_labels = 0;
4590
    ctx.nip = pc_start;
4591
    ctx.tb = tb;
4592
    ctx.exception = EXCP_NONE;
4593
    ctx.spr_cb = env->spr_cb;
4594
#if defined(CONFIG_USER_ONLY)
4595
    ctx.mem_idx = msr_le;
4596
#if defined(TARGET_PPC64)
4597
    ctx.mem_idx |= msr_sf << 1;
4598
#endif
4599
#else
4600
    ctx.supervisor = 1 - msr_pr;
4601
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
4602
#if defined(TARGET_PPC64)
4603
    ctx.mem_idx |= msr_sf << 2;
4604
#endif
4605
#endif
4606
#if defined(TARGET_PPC64)
4607
    ctx.sf_mode = msr_sf;
4608
#endif
4609
    ctx.fpu_enabled = msr_fp;
4610
    ctx.singlestep_enabled = env->singlestep_enabled;
4611
#if defined (DO_SINGLE_STEP) && 0
4612
    /* Single step trace mode */
4613
    msr_se = 1;
4614
#endif
4615
    /* Set env in case of segfault during code fetch */
4616
    while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
4617
        if (unlikely(env->nb_breakpoints > 0)) {
4618
            for (j = 0; j < env->nb_breakpoints; j++) {
4619
                if (env->breakpoints[j] == ctx.nip) {
4620
                    gen_update_nip(&ctx, ctx.nip); 
4621
                    gen_op_debug();
4622
                    break;
4623
                }
4624
            }
4625
        }
4626
        if (unlikely(search_pc)) {
4627
            j = gen_opc_ptr - gen_opc_buf;
4628
            if (lj < j) {
4629
                lj++;
4630
                while (lj < j)
4631
                    gen_opc_instr_start[lj++] = 0;
4632
                gen_opc_pc[lj] = ctx.nip;
4633
                gen_opc_instr_start[lj] = 1;
4634
            }
4635
        }
4636
#if defined PPC_DEBUG_DISAS
4637
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4638
            fprintf(logfile, "----------------\n");
4639
            fprintf(logfile, "nip=%08x super=%d ir=%d\n",
4640
                    ctx.nip, 1 - msr_pr, msr_ir);
4641
        }
4642
#endif
4643
        ctx.opcode = ldl_code(ctx.nip);
4644
        if (msr_le) {
4645
            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
4646
                ((ctx.opcode & 0x00FF0000) >> 8) |
4647
                ((ctx.opcode & 0x0000FF00) << 8) |
4648
                ((ctx.opcode & 0x000000FF) << 24);
4649
        }
4650
#if defined PPC_DEBUG_DISAS
4651
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4652
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
4653
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
4654
                    opc3(ctx.opcode), msr_le ? "little" : "big");
4655
        }
4656
#endif
4657
        ctx.nip += 4;
4658
        table = env->opcodes;
4659
        handler = table[opc1(ctx.opcode)];
4660
        if (is_indirect_opcode(handler)) {
4661
            table = ind_table(handler);
4662
            handler = table[opc2(ctx.opcode)];
4663
            if (is_indirect_opcode(handler)) {
4664
                table = ind_table(handler);
4665
                handler = table[opc3(ctx.opcode)];
4666
            }
4667
        }
4668
        /* Is opcode *REALLY* valid ? */
4669
        if (unlikely(handler->handler == &gen_invalid)) {
4670
            if (loglevel > 0) {
4671
                fprintf(logfile, "invalid/unsupported opcode: "
4672
                        "%02x - %02x - %02x (%08x) 0x" REGX " %d\n",
4673
                        opc1(ctx.opcode), opc2(ctx.opcode),
4674
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
4675
            } else {
4676
                printf("invalid/unsupported opcode: "
4677
                       "%02x - %02x - %02x (%08x) 0x" REGX " %d\n",
4678
                       opc1(ctx.opcode), opc2(ctx.opcode),
4679
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
4680
            }
4681
        } else {
4682
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
4683
                if (loglevel > 0) {
4684
                    fprintf(logfile, "invalid bits: %08x for opcode: "
4685
                            "%02x -%02x - %02x (%08x) " REGX "\n",
4686
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
4687
                            opc2(ctx.opcode), opc3(ctx.opcode),
4688
                            ctx.opcode, ctx.nip - 4);
4689
                } else {
4690
                    printf("invalid bits: %08x for opcode: "
4691
                           "%02x -%02x - %02x (%08x) " REGX "\n",
4692
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
4693
                           opc2(ctx.opcode), opc3(ctx.opcode),
4694
                           ctx.opcode, ctx.nip - 4);
4695
                }
4696
                RET_INVAL(ctxp);
4697
                break;
4698
            }
4699
        }
4700
        (*(handler->handler))(&ctx);
4701
#if defined(DO_PPC_STATISTICS)
4702
        handler->count++;
4703
#endif
4704
        /* Check trace mode exceptions */
4705
        if (unlikely((msr_be && ctx.exception == EXCP_BRANCH) ||
4706
                     /* Check in single step trace mode
4707
                      * we need to stop except if:
4708
                      * - rfi, trap or syscall
4709
                      * - first instruction of an exception handler
4710
                      */
4711
                     (msr_se && (ctx.nip < 0x100 ||
4712
                                 ctx.nip > 0xF00 ||
4713
                                 (ctx.nip & 0xFC) != 0x04) &&
4714
                      ctx.exception != EXCP_SYSCALL &&
4715
                      ctx.exception != EXCP_SYSCALL_USER &&
4716
                      ctx.exception != EXCP_TRAP))) {
4717
            RET_EXCP(ctxp, EXCP_TRACE, 0);
4718
        }
4719
        /* if we reach a page boundary or are single stepping, stop
4720
         * generation
4721
         */
4722
        if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
4723
                     (env->singlestep_enabled))) {
4724
            break;
4725
        }
4726
#if defined (DO_SINGLE_STEP)
4727
        break;
4728
#endif
4729
    }
4730
    if (ctx.exception == EXCP_NONE) {
4731
        gen_goto_tb(&ctx, 0, ctx.nip);
4732
    } else if (ctx.exception != EXCP_BRANCH) {
4733
        gen_op_reset_T0();
4734
        /* Generate the return instruction */
4735
        gen_op_exit_tb();
4736
    }
4737
    *gen_opc_ptr = INDEX_op_end;
4738
    if (unlikely(search_pc)) {
4739
        j = gen_opc_ptr - gen_opc_buf;
4740
        lj++;
4741
        while (lj <= j)
4742
            gen_opc_instr_start[lj++] = 0;
4743
        tb->size = 0;
4744
    } else {
4745
        tb->size = ctx.nip - pc_start;
4746
    }
4747
#if defined(DEBUG_DISAS)
4748
    if (loglevel & CPU_LOG_TB_CPU) {
4749
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
4750
        cpu_dump_state(env, logfile, fprintf, 0);
4751
    }
4752
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4753
        int flags;
4754
        flags = msr_le;
4755
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4756
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
4757
        fprintf(logfile, "\n");
4758
    }
4759
    if (loglevel & CPU_LOG_TB_OP) {
4760
        fprintf(logfile, "OP:\n");
4761
        dump_ops(gen_opc_buf, gen_opparam_buf);
4762
        fprintf(logfile, "\n");
4763
    }
4764
#endif
4765
    return 0;
4766
}
4767

    
4768
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
4769
{
4770
    return gen_intermediate_code_internal(env, tb, 0);
4771
}
4772

    
4773
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
4774
{
4775
    return gen_intermediate_code_internal(env, tb, 1);
4776
}