Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 36f69651

History | View | Annotate | Download (150.9 kB)

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

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

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

    
3117
/* Optional: */
3118
/* dcba */
3119
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT)
3120
{
3121
}
3122

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3540
/* rlmi - rlmi. */
3541
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3542
{
3543
    uint32_t mb, me;
3544

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3837
    gen_addr_reg_index(ctx);
3838
    gen_op_POWER_mfsri();
3839
    gen_op_store_T0_gpr(rd);
3840
    if (ra != 0 && ra != rd)
3841
        gen_op_store_T1_gpr(ra);
3842
#endif
3843
}
3844

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

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

    
3874
/* svc is not implemented for now */
3875

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4297
/* icread */
4298
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_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
    /* interpreted as no-op */
4308
#endif
4309
}
4310

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

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

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

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

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

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

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

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

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

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

    
4471
/* End opcode list */
4472
GEN_OPCODE_MARK(end);
4473

    
4474
#include "translate_init.c"
4475

    
4476
/*****************************************************************************/
4477
/* Misc PowerPC helpers */
4478
static inline uint32_t load_xer (CPUState *env)
4479
{
4480
    return (xer_so << XER_SO) |
4481
        (xer_ov << XER_OV) |
4482
        (xer_ca << XER_CA) |
4483
        (xer_bc << XER_BC) |
4484
        (xer_cmp << XER_CMP);
4485
}
4486

    
4487
void cpu_dump_state(CPUState *env, FILE *f, 
4488
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4489
                    int flags)
4490
{
4491
#if defined(TARGET_PPC64) || 1
4492
#define FILL ""
4493
#define RGPL  4
4494
#define RFPL  4
4495
#else
4496
#define FILL "        "
4497
#define RGPL  8
4498
#define RFPL  4
4499
#endif
4500

    
4501
    int i;
4502

    
4503
    cpu_fprintf(f, "NIP " REGX " LR " REGX " CTR " REGX "\n",
4504
                env->nip, env->lr, env->ctr);
4505
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
4506
#if !defined(NO_TIMER_DUMP)
4507
                "TB %08x %08x "
4508
#if !defined(CONFIG_USER_ONLY)
4509
                "DECR %08x"
4510
#endif
4511
#endif
4512
                "\n",
4513
                do_load_msr(env), load_xer(env)
4514
#if !defined(NO_TIMER_DUMP)
4515
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
4516
#if !defined(CONFIG_USER_ONLY)
4517
                , cpu_ppc_load_decr(env)
4518
#endif
4519
#endif
4520
                );
4521
    for (i = 0; i < 32; i++) {
4522
        if ((i & (RGPL - 1)) == 0)
4523
            cpu_fprintf(f, "GPR%02d", i);
4524
        cpu_fprintf(f, " " REGX, env->gpr[i]);
4525
        if ((i & (RGPL - 1)) == (RGPL - 1))
4526
            cpu_fprintf(f, "\n");
4527
    }
4528
    cpu_fprintf(f, "CR ");
4529
    for (i = 0; i < 8; i++)
4530
        cpu_fprintf(f, "%01x", env->crf[i]);
4531
    cpu_fprintf(f, "  [");
4532
    for (i = 0; i < 8; i++) {
4533
        char a = '-';
4534
        if (env->crf[i] & 0x08)
4535
            a = 'L';
4536
        else if (env->crf[i] & 0x04)
4537
            a = 'G';
4538
        else if (env->crf[i] & 0x02)
4539
            a = 'E';
4540
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
4541
    }
4542
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
4543
    for (i = 0; i < 32; i++) {
4544
        if ((i & (RFPL - 1)) == 0)
4545
            cpu_fprintf(f, "FPR%02d", i);
4546
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
4547
        if ((i & (RFPL - 1)) == (RFPL - 1))
4548
            cpu_fprintf(f, "\n");
4549
    }
4550
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
4551
                "SDR1 " REGX "\n",
4552
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
4553

    
4554
#undef RGPL
4555
#undef RFPL
4556
#undef FILL
4557
}
4558

    
4559
void cpu_dump_statistics (CPUState *env, FILE*f,
4560
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4561
                          int flags)
4562
{
4563
#if defined(DO_PPC_STATISTICS)
4564
    opc_handler_t **t1, **t2, **t3, *handler;
4565
    int op1, op2, op3;
4566

    
4567
    t1 = env->opcodes;
4568
    for (op1 = 0; op1 < 64; op1++) {
4569
        handler = t1[op1];
4570
        if (is_indirect_opcode(handler)) {
4571
            t2 = ind_table(handler);
4572
            for (op2 = 0; op2 < 32; op2++) {
4573
                handler = t2[op2];
4574
                if (is_indirect_opcode(handler)) {
4575
                    t3 = ind_table(handler);
4576
                    for (op3 = 0; op3 < 32; op3++) {
4577
                        handler = t3[op3];
4578
                        if (handler->count == 0)
4579
                            continue;
4580
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
4581
                                    "%016llx %lld\n",
4582
                                    op1, op2, op3, op1, (op3 << 5) | op2,
4583
                                    handler->oname,
4584
                                    handler->count, handler->count);
4585
                    }
4586
                } else {
4587
                    if (handler->count == 0)
4588
                        continue;
4589
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
4590
                                "%016llx %lld\n",
4591
                                op1, op2, op1, op2, handler->oname,
4592
                                handler->count, handler->count);
4593
                }
4594
            }
4595
        } else {
4596
            if (handler->count == 0)
4597
                continue;
4598
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
4599
                        op1, op1, handler->oname,
4600
                        handler->count, handler->count);
4601
        }
4602
    }
4603
#endif
4604
}
4605

    
4606
/*****************************************************************************/
4607
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
4608
                                    int search_pc)
4609
{
4610
    DisasContext ctx, *ctxp = &ctx;
4611
    opc_handler_t **table, *handler;
4612
    target_ulong pc_start;
4613
    uint16_t *gen_opc_end;
4614
    int j, lj = -1;
4615

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

    
4799
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
4800
{
4801
    return gen_intermediate_code_internal(env, tb, 0);
4802
}
4803

    
4804
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
4805
{
4806
    return gen_intermediate_code_internal(env, tb, 1);
4807
}