Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 51789c41

History | View | Annotate | Download (191.8 kB)

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

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

    
30
//#define DO_SINGLE_STEP
31
//#define PPC_DEBUG_DISAS
32
//#define DO_PPC_STATISTICS
33

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

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

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

    
50
#include "gen-op.h"
51

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
364
    return ret;
365
}
366

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1287
    sh = SH(ctx->opcode) | (1 << shn);
1288
    mb = (MB(ctx->opcode) << 1) | mbn;
1289
    gen_rldinm(ctx, mb, 63 - sh, sh);
1290
}
1291
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1292

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

    
1306
/* rldcl - rldcl. */
1307
static inline void gen_rldcl (DisasContext *ctx, int mbn)
1308
{
1309
    uint32_t mb;
1310

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

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

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

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

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

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

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

    
1444
#define GEN_FLOAT_ACB(name, op2)                                              \
1445
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0);                                     \
1446
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
1447

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

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

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

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

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

    
1529
/* fres */ /* XXX: not in 601 */
1530
GEN_FLOAT_BS(res, 0x3B, 0x18);
1531

    
1532
/* frsqrte */ /* XXX: not in 601 */
1533
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
1534

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

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

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

    
1580
/***                     Floating-Point round & convert                    ***/
1581
/* fctiw */
1582
GEN_FLOAT_B(ctiw, 0x0E, 0x00);
1583
/* fctiwz */
1584
GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
1585
/* frsp */
1586
GEN_FLOAT_B(rsp, 0x0C, 0x00);
1587

    
1588
/***                         Floating-Point compare                        ***/
1589
/* fcmpo */
1590
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1591
{
1592
    if (unlikely(!ctx->fpu_enabled)) {
1593
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1594
        return;
1595
    }
1596
    gen_op_reset_scrfx();
1597
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1598
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1599
    gen_op_fcmpo();
1600
    gen_op_store_T0_crf(crfD(ctx->opcode));
1601
}
1602

    
1603
/* fcmpu */
1604
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1605
{
1606
    if (unlikely(!ctx->fpu_enabled)) {
1607
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1608
        return;
1609
    }
1610
    gen_op_reset_scrfx();
1611
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1612
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1613
    gen_op_fcmpu();
1614
    gen_op_store_T0_crf(crfD(ctx->opcode));
1615
}
1616

    
1617
/***                         Floating-point move                           ***/
1618
/* fabs */
1619
GEN_FLOAT_B(abs, 0x08, 0x08);
1620

    
1621
/* fmr  - fmr. */
1622
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1623
{
1624
    if (unlikely(!ctx->fpu_enabled)) {
1625
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1626
        return;
1627
    }
1628
    gen_op_reset_scrfx();
1629
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1630
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1631
    if (unlikely(Rc(ctx->opcode) != 0))
1632
        gen_op_set_Rc1();
1633
}
1634

    
1635
/* fnabs */
1636
GEN_FLOAT_B(nabs, 0x08, 0x04);
1637
/* fneg */
1638
GEN_FLOAT_B(neg, 0x08, 0x01);
1639

    
1640
/***                  Floating-Point status & ctrl register                ***/
1641
/* mcrfs */
1642
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1643
{
1644
    if (unlikely(!ctx->fpu_enabled)) {
1645
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1646
        return;
1647
    }
1648
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
1649
    gen_op_store_T0_crf(crfD(ctx->opcode));
1650
    gen_op_clear_fpscr(crfS(ctx->opcode));
1651
}
1652

    
1653
/* mffs */
1654
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1655
{
1656
    if (unlikely(!ctx->fpu_enabled)) {
1657
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1658
        return;
1659
    }
1660
    gen_op_load_fpscr();
1661
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1662
    if (unlikely(Rc(ctx->opcode) != 0))
1663
        gen_op_set_Rc1();
1664
}
1665

    
1666
/* mtfsb0 */
1667
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1668
{
1669
    uint8_t crb;
1670
    
1671
    if (unlikely(!ctx->fpu_enabled)) {
1672
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1673
        return;
1674
    }
1675
    crb = crbD(ctx->opcode) >> 2;
1676
    gen_op_load_fpscr_T0(crb);
1677
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1678
    gen_op_store_T0_fpscr(crb);
1679
    if (unlikely(Rc(ctx->opcode) != 0))
1680
        gen_op_set_Rc1();
1681
}
1682

    
1683
/* mtfsb1 */
1684
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1685
{
1686
    uint8_t crb;
1687
    
1688
    if (unlikely(!ctx->fpu_enabled)) {
1689
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1690
        return;
1691
    }
1692
    crb = crbD(ctx->opcode) >> 2;
1693
    gen_op_load_fpscr_T0(crb);
1694
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1695
    gen_op_store_T0_fpscr(crb);
1696
    if (unlikely(Rc(ctx->opcode) != 0))
1697
        gen_op_set_Rc1();
1698
}
1699

    
1700
/* mtfsf */
1701
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1702
{
1703
    if (unlikely(!ctx->fpu_enabled)) {
1704
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1705
        return;
1706
    }
1707
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1708
    gen_op_store_fpscr(FM(ctx->opcode));
1709
    if (unlikely(Rc(ctx->opcode) != 0))
1710
        gen_op_set_Rc1();
1711
}
1712

    
1713
/* mtfsfi */
1714
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1715
{
1716
    if (unlikely(!ctx->fpu_enabled)) {
1717
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1718
        return;
1719
    }
1720
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1721
    if (unlikely(Rc(ctx->opcode) != 0))
1722
        gen_op_set_Rc1();
1723
}
1724

    
1725
/***                           Addressing modes                            ***/
1726
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1727
static inline void gen_addr_imm_index (DisasContext *ctx)
1728
{
1729
    target_long simm = SIMM(ctx->opcode);
1730

    
1731
    if (rA(ctx->opcode) == 0) {
1732
        gen_set_T0(simm);
1733
    } else {
1734
        gen_op_load_gpr_T0(rA(ctx->opcode));
1735
        if (likely(simm != 0))
1736
            gen_op_addi(simm);
1737
    }
1738
}
1739

    
1740
static inline void gen_addr_reg_index (DisasContext *ctx)
1741
{
1742
    if (rA(ctx->opcode) == 0) {
1743
        gen_op_load_gpr_T0(rB(ctx->opcode));
1744
    } else {
1745
        gen_op_load_gpr_T0(rA(ctx->opcode));
1746
        gen_op_load_gpr_T1(rB(ctx->opcode));
1747
        gen_op_add();
1748
    }
1749
}
1750

    
1751
static inline void gen_addr_register (DisasContext *ctx)
1752
{
1753
    if (rA(ctx->opcode) == 0) {
1754
        gen_op_reset_T0();
1755
    } else {
1756
        gen_op_load_gpr_T0(rA(ctx->opcode));
1757
    }
1758
}
1759

    
1760
/***                             Integer load                              ***/
1761
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1762
#if defined(CONFIG_USER_ONLY)
1763
#if defined(TARGET_PPC64)
1764
#define OP_LD_TABLE(width)                                                    \
1765
static GenOpFunc *gen_op_l##width[] = {                                       \
1766
    &gen_op_l##width##_raw,                                                   \
1767
    &gen_op_l##width##_le_raw,                                                \
1768
    &gen_op_l##width##_64_raw,                                                \
1769
    &gen_op_l##width##_le_64_raw,                                             \
1770
};
1771
#define OP_ST_TABLE(width)                                                    \
1772
static GenOpFunc *gen_op_st##width[] = {                                      \
1773
    &gen_op_st##width##_raw,                                                  \
1774
    &gen_op_st##width##_le_raw,                                               \
1775
    &gen_op_st##width##_64_raw,                                               \
1776
    &gen_op_st##width##_le_64_raw,                                            \
1777
};
1778
/* Byte access routine are endian safe */
1779
#define gen_op_stb_le_64_raw gen_op_stb_64_raw
1780
#define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1781
#else
1782
#define OP_LD_TABLE(width)                                                    \
1783
static GenOpFunc *gen_op_l##width[] = {                                       \
1784
    &gen_op_l##width##_raw,                                                   \
1785
    &gen_op_l##width##_le_raw,                                                \
1786
};
1787
#define OP_ST_TABLE(width)                                                    \
1788
static GenOpFunc *gen_op_st##width[] = {                                      \
1789
    &gen_op_st##width##_raw,                                                  \
1790
    &gen_op_st##width##_le_raw,                                               \
1791
};
1792
#endif
1793
/* Byte access routine are endian safe */
1794
#define gen_op_stb_le_raw gen_op_stb_raw
1795
#define gen_op_lbz_le_raw gen_op_lbz_raw
1796
#else
1797
#if defined(TARGET_PPC64)
1798
#define OP_LD_TABLE(width)                                                    \
1799
static GenOpFunc *gen_op_l##width[] = {                                       \
1800
    &gen_op_l##width##_user,                                                  \
1801
    &gen_op_l##width##_le_user,                                               \
1802
    &gen_op_l##width##_kernel,                                                \
1803
    &gen_op_l##width##_le_kernel,                                             \
1804
    &gen_op_l##width##_64_user,                                               \
1805
    &gen_op_l##width##_le_64_user,                                            \
1806
    &gen_op_l##width##_64_kernel,                                             \
1807
    &gen_op_l##width##_le_64_kernel,                                          \
1808
};
1809
#define OP_ST_TABLE(width)                                                    \
1810
static GenOpFunc *gen_op_st##width[] = {                                      \
1811
    &gen_op_st##width##_user,                                                 \
1812
    &gen_op_st##width##_le_user,                                              \
1813
    &gen_op_st##width##_kernel,                                               \
1814
    &gen_op_st##width##_le_kernel,                                            \
1815
    &gen_op_st##width##_64_user,                                              \
1816
    &gen_op_st##width##_le_64_user,                                           \
1817
    &gen_op_st##width##_64_kernel,                                            \
1818
    &gen_op_st##width##_le_64_kernel,                                         \
1819
};
1820
/* Byte access routine are endian safe */
1821
#define gen_op_stb_le_64_user gen_op_stb_64_user
1822
#define gen_op_lbz_le_64_user gen_op_lbz_64_user
1823
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
1824
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
1825
#else
1826
#define OP_LD_TABLE(width)                                                    \
1827
static GenOpFunc *gen_op_l##width[] = {                                       \
1828
    &gen_op_l##width##_user,                                                  \
1829
    &gen_op_l##width##_le_user,                                               \
1830
    &gen_op_l##width##_kernel,                                                \
1831
    &gen_op_l##width##_le_kernel,                                             \
1832
};
1833
#define OP_ST_TABLE(width)                                                    \
1834
static GenOpFunc *gen_op_st##width[] = {                                      \
1835
    &gen_op_st##width##_user,                                                 \
1836
    &gen_op_st##width##_le_user,                                              \
1837
    &gen_op_st##width##_kernel,                                               \
1838
    &gen_op_st##width##_le_kernel,                                            \
1839
};
1840
#endif
1841
/* Byte access routine are endian safe */
1842
#define gen_op_stb_le_user gen_op_stb_user
1843
#define gen_op_lbz_le_user gen_op_lbz_user
1844
#define gen_op_stb_le_kernel gen_op_stb_kernel
1845
#define gen_op_lbz_le_kernel gen_op_lbz_kernel
1846
#endif
1847

    
1848
#define GEN_LD(width, opc, type)                                              \
1849
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
1850
{                                                                             \
1851
    gen_addr_imm_index(ctx);                                                  \
1852
    op_ldst(l##width);                                                        \
1853
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1854
}
1855

    
1856
#define GEN_LDU(width, opc, type)                                             \
1857
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
1858
{                                                                             \
1859
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1860
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1861
        RET_INVAL(ctx);                                                       \
1862
        return;                                                               \
1863
    }                                                                         \
1864
    gen_addr_imm_index(ctx);                                                  \
1865
    op_ldst(l##width);                                                        \
1866
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1867
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1868
}
1869

    
1870
#define GEN_LDUX(width, opc2, opc3, type)                                     \
1871
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
1872
{                                                                             \
1873
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1874
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1875
        RET_INVAL(ctx);                                                       \
1876
        return;                                                               \
1877
    }                                                                         \
1878
    gen_addr_reg_index(ctx);                                                  \
1879
    op_ldst(l##width);                                                        \
1880
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1881
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1882
}
1883

    
1884
#define GEN_LDX(width, opc2, opc3, type)                                      \
1885
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
1886
{                                                                             \
1887
    gen_addr_reg_index(ctx);                                                  \
1888
    op_ldst(l##width);                                                        \
1889
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1890
}
1891

    
1892
#define GEN_LDS(width, op, type)                                              \
1893
OP_LD_TABLE(width);                                                           \
1894
GEN_LD(width, op | 0x20, type);                                               \
1895
GEN_LDU(width, op | 0x21, type);                                              \
1896
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
1897
GEN_LDX(width, 0x17, op | 0x00, type)
1898

    
1899
/* lbz lbzu lbzux lbzx */
1900
GEN_LDS(bz, 0x02, PPC_INTEGER);
1901
/* lha lhau lhaux lhax */
1902
GEN_LDS(ha, 0x0A, PPC_INTEGER);
1903
/* lhz lhzu lhzux lhzx */
1904
GEN_LDS(hz, 0x08, PPC_INTEGER);
1905
/* lwz lwzu lwzux lwzx */
1906
GEN_LDS(wz, 0x00, PPC_INTEGER);
1907
#if defined(TARGET_PPC64)
1908
OP_LD_TABLE(wa);
1909
OP_LD_TABLE(d);
1910
/* lwaux */
1911
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
1912
/* lwax */
1913
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
1914
/* ldux */
1915
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
1916
/* ldx */
1917
GEN_LDX(d, 0x15, 0x00, PPC_64B);
1918
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
1919
{
1920
    if (Rc(ctx->opcode)) {
1921
        if (unlikely(rA(ctx->opcode) == 0 ||
1922
                     rA(ctx->opcode) == rD(ctx->opcode))) {
1923
            RET_INVAL(ctx);
1924
            return;
1925
        }
1926
    }
1927
    gen_addr_imm_index(ctx);
1928
    if (ctx->opcode & 0x02) {
1929
        /* lwa (lwau is undefined) */
1930
        op_ldst(lwa);
1931
    } else {
1932
        /* ld - ldu */
1933
        op_ldst(ld);
1934
    }
1935
    gen_op_store_T1_gpr(rD(ctx->opcode));
1936
    if (Rc(ctx->opcode))
1937
        gen_op_store_T0_gpr(rA(ctx->opcode));
1938
}
1939
#endif
1940

    
1941
/***                              Integer store                            ***/
1942
#define GEN_ST(width, opc, type)                                              \
1943
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
1944
{                                                                             \
1945
    gen_addr_imm_index(ctx);                                                  \
1946
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1947
    op_ldst(st##width);                                                       \
1948
}
1949

    
1950
#define GEN_STU(width, opc, type)                                             \
1951
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
1952
{                                                                             \
1953
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1954
        RET_INVAL(ctx);                                                       \
1955
        return;                                                               \
1956
    }                                                                         \
1957
    gen_addr_imm_index(ctx);                                                  \
1958
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1959
    op_ldst(st##width);                                                       \
1960
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1961
}
1962

    
1963
#define GEN_STUX(width, opc2, opc3, type)                                     \
1964
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
1965
{                                                                             \
1966
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1967
        RET_INVAL(ctx);                                                       \
1968
        return;                                                               \
1969
    }                                                                         \
1970
    gen_addr_reg_index(ctx);                                                  \
1971
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1972
    op_ldst(st##width);                                                       \
1973
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1974
}
1975

    
1976
#define GEN_STX(width, opc2, opc3, type)                                      \
1977
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
1978
{                                                                             \
1979
    gen_addr_reg_index(ctx);                                                  \
1980
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1981
    op_ldst(st##width);                                                       \
1982
}
1983

    
1984
#define GEN_STS(width, op, type)                                              \
1985
OP_ST_TABLE(width);                                                           \
1986
GEN_ST(width, op | 0x20, type);                                               \
1987
GEN_STU(width, op | 0x21, type);                                              \
1988
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
1989
GEN_STX(width, 0x17, op | 0x00, type)
1990

    
1991
/* stb stbu stbux stbx */
1992
GEN_STS(b, 0x06, PPC_INTEGER);
1993
/* sth sthu sthux sthx */
1994
GEN_STS(h, 0x0C, PPC_INTEGER);
1995
/* stw stwu stwux stwx */
1996
GEN_STS(w, 0x04, PPC_INTEGER);
1997
#if defined(TARGET_PPC64)
1998
OP_ST_TABLE(d);
1999
GEN_STUX(d, 0x15, 0x01, PPC_64B);
2000
GEN_STX(d, 0x15, 0x00, PPC_64B);
2001
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
2002
{
2003
    if (Rc(ctx->opcode)) {
2004
        if (unlikely(rA(ctx->opcode) == 0)) {
2005
            RET_INVAL(ctx);
2006
            return;
2007
        }
2008
    }
2009
    gen_addr_imm_index(ctx);
2010
    gen_op_load_gpr_T1(rS(ctx->opcode));
2011
    op_ldst(std);
2012
    if (Rc(ctx->opcode))
2013
        gen_op_store_T0_gpr(rA(ctx->opcode));
2014
}
2015
#endif
2016
/***                Integer load and store with byte reverse               ***/
2017
/* lhbrx */
2018
OP_LD_TABLE(hbr);
2019
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2020
/* lwbrx */
2021
OP_LD_TABLE(wbr);
2022
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2023
/* sthbrx */
2024
OP_ST_TABLE(hbr);
2025
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2026
/* stwbrx */
2027
OP_ST_TABLE(wbr);
2028
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2029

    
2030
/***                    Integer load and store multiple                    ***/
2031
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2032
#if defined(TARGET_PPC64)
2033
#if defined(CONFIG_USER_ONLY)
2034
static GenOpFunc1 *gen_op_lmw[] = {
2035
    &gen_op_lmw_raw,
2036
    &gen_op_lmw_le_raw,
2037
    &gen_op_lmw_64_raw,
2038
    &gen_op_lmw_le_64_raw,
2039
};
2040
static GenOpFunc1 *gen_op_stmw[] = {
2041
    &gen_op_stmw_64_raw,
2042
    &gen_op_stmw_le_64_raw,
2043
};
2044
#else
2045
static GenOpFunc1 *gen_op_lmw[] = {
2046
    &gen_op_lmw_user,
2047
    &gen_op_lmw_le_user,
2048
    &gen_op_lmw_kernel,
2049
    &gen_op_lmw_le_kernel,
2050
    &gen_op_lmw_64_user,
2051
    &gen_op_lmw_le_64_user,
2052
    &gen_op_lmw_64_kernel,
2053
    &gen_op_lmw_le_64_kernel,
2054
};
2055
static GenOpFunc1 *gen_op_stmw[] = {
2056
    &gen_op_stmw_user,
2057
    &gen_op_stmw_le_user,
2058
    &gen_op_stmw_kernel,
2059
    &gen_op_stmw_le_kernel,
2060
    &gen_op_stmw_64_user,
2061
    &gen_op_stmw_le_64_user,
2062
    &gen_op_stmw_64_kernel,
2063
    &gen_op_stmw_le_64_kernel,
2064
};
2065
#endif
2066
#else
2067
#if defined(CONFIG_USER_ONLY)
2068
static GenOpFunc1 *gen_op_lmw[] = {
2069
    &gen_op_lmw_raw,
2070
    &gen_op_lmw_le_raw,
2071
};
2072
static GenOpFunc1 *gen_op_stmw[] = {
2073
    &gen_op_stmw_raw,
2074
    &gen_op_stmw_le_raw,
2075
};
2076
#else
2077
static GenOpFunc1 *gen_op_lmw[] = {
2078
    &gen_op_lmw_user,
2079
    &gen_op_lmw_le_user,
2080
    &gen_op_lmw_kernel,
2081
    &gen_op_lmw_le_kernel,
2082
};
2083
static GenOpFunc1 *gen_op_stmw[] = {
2084
    &gen_op_stmw_user,
2085
    &gen_op_stmw_le_user,
2086
    &gen_op_stmw_kernel,
2087
    &gen_op_stmw_le_kernel,
2088
};
2089
#endif
2090
#endif
2091

    
2092
/* lmw */
2093
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2094
{
2095
    /* NIP cannot be restored if the memory exception comes from an helper */
2096
    gen_update_nip(ctx, ctx->nip - 4);
2097
    gen_addr_imm_index(ctx);
2098
    op_ldstm(lmw, rD(ctx->opcode));
2099
}
2100

    
2101
/* stmw */
2102
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2103
{
2104
    /* NIP cannot be restored if the memory exception comes from an helper */
2105
    gen_update_nip(ctx, ctx->nip - 4);
2106
    gen_addr_imm_index(ctx);
2107
    op_ldstm(stmw, rS(ctx->opcode));
2108
}
2109

    
2110
/***                    Integer load and store strings                     ***/
2111
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2112
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2113
#if defined(TARGET_PPC64)
2114
#if defined(CONFIG_USER_ONLY)
2115
static GenOpFunc1 *gen_op_lswi[] = {
2116
    &gen_op_lswi_raw,
2117
    &gen_op_lswi_le_raw,
2118
    &gen_op_lswi_64_raw,
2119
    &gen_op_lswi_le_64_raw,
2120
};
2121
static GenOpFunc3 *gen_op_lswx[] = {
2122
    &gen_op_lswx_raw,
2123
    &gen_op_lswx_le_raw,
2124
    &gen_op_lswx_64_raw,
2125
    &gen_op_lswx_le_64_raw,
2126
};
2127
static GenOpFunc1 *gen_op_stsw[] = {
2128
    &gen_op_stsw_raw,
2129
    &gen_op_stsw_le_raw,
2130
    &gen_op_stsw_64_raw,
2131
    &gen_op_stsw_le_64_raw,
2132
};
2133
#else
2134
static GenOpFunc1 *gen_op_lswi[] = {
2135
    &gen_op_lswi_user,
2136
    &gen_op_lswi_le_user,
2137
    &gen_op_lswi_kernel,
2138
    &gen_op_lswi_le_kernel,
2139
    &gen_op_lswi_64_user,
2140
    &gen_op_lswi_le_64_user,
2141
    &gen_op_lswi_64_kernel,
2142
    &gen_op_lswi_le_64_kernel,
2143
};
2144
static GenOpFunc3 *gen_op_lswx[] = {
2145
    &gen_op_lswx_user,
2146
    &gen_op_lswx_le_user,
2147
    &gen_op_lswx_kernel,
2148
    &gen_op_lswx_le_kernel,
2149
    &gen_op_lswx_64_user,
2150
    &gen_op_lswx_le_64_user,
2151
    &gen_op_lswx_64_kernel,
2152
    &gen_op_lswx_le_64_kernel,
2153
};
2154
static GenOpFunc1 *gen_op_stsw[] = {
2155
    &gen_op_stsw_user,
2156
    &gen_op_stsw_le_user,
2157
    &gen_op_stsw_kernel,
2158
    &gen_op_stsw_le_kernel,
2159
    &gen_op_stsw_64_user,
2160
    &gen_op_stsw_le_64_user,
2161
    &gen_op_stsw_64_kernel,
2162
    &gen_op_stsw_le_64_kernel,
2163
};
2164
#endif
2165
#else
2166
#if defined(CONFIG_USER_ONLY)
2167
static GenOpFunc1 *gen_op_lswi[] = {
2168
    &gen_op_lswi_raw,
2169
    &gen_op_lswi_le_raw,
2170
};
2171
static GenOpFunc3 *gen_op_lswx[] = {
2172
    &gen_op_lswx_raw,
2173
    &gen_op_lswx_le_raw,
2174
};
2175
static GenOpFunc1 *gen_op_stsw[] = {
2176
    &gen_op_stsw_raw,
2177
    &gen_op_stsw_le_raw,
2178
};
2179
#else
2180
static GenOpFunc1 *gen_op_lswi[] = {
2181
    &gen_op_lswi_user,
2182
    &gen_op_lswi_le_user,
2183
    &gen_op_lswi_kernel,
2184
    &gen_op_lswi_le_kernel,
2185
};
2186
static GenOpFunc3 *gen_op_lswx[] = {
2187
    &gen_op_lswx_user,
2188
    &gen_op_lswx_le_user,
2189
    &gen_op_lswx_kernel,
2190
    &gen_op_lswx_le_kernel,
2191
};
2192
static GenOpFunc1 *gen_op_stsw[] = {
2193
    &gen_op_stsw_user,
2194
    &gen_op_stsw_le_user,
2195
    &gen_op_stsw_kernel,
2196
    &gen_op_stsw_le_kernel,
2197
};
2198
#endif
2199
#endif
2200

    
2201
/* lswi */
2202
/* PowerPC32 specification says we must generate an exception if
2203
 * rA is in the range of registers to be loaded.
2204
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2205
 * For now, I'll follow the spec...
2206
 */
2207
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
2208
{
2209
    int nb = NB(ctx->opcode);
2210
    int start = rD(ctx->opcode);
2211
    int ra = rA(ctx->opcode);
2212
    int nr;
2213

    
2214
    if (nb == 0)
2215
        nb = 32;
2216
    nr = nb / 4;
2217
    if (unlikely(((start + nr) > 32  &&
2218
                  start <= ra && (start + nr - 32) > ra) ||
2219
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2220
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
2221
        return;
2222
    }
2223
    /* NIP cannot be restored if the memory exception comes from an helper */
2224
    gen_update_nip(ctx, ctx->nip - 4);
2225
    gen_addr_register(ctx);
2226
    gen_op_set_T1(nb);
2227
    op_ldsts(lswi, start);
2228
}
2229

    
2230
/* lswx */
2231
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
2232
{
2233
    int ra = rA(ctx->opcode);
2234
    int rb = rB(ctx->opcode);
2235

    
2236
    /* NIP cannot be restored if the memory exception comes from an helper */
2237
    gen_update_nip(ctx, ctx->nip - 4);
2238
    gen_addr_reg_index(ctx);
2239
    if (ra == 0) {
2240
        ra = rb;
2241
    }
2242
    gen_op_load_xer_bc();
2243
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2244
}
2245

    
2246
/* stswi */
2247
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
2248
{
2249
    int nb = NB(ctx->opcode);
2250

    
2251
    /* NIP cannot be restored if the memory exception comes from an helper */
2252
    gen_update_nip(ctx, ctx->nip - 4);
2253
    gen_addr_register(ctx);
2254
    if (nb == 0)
2255
        nb = 32;
2256
    gen_op_set_T1(nb);
2257
    op_ldsts(stsw, rS(ctx->opcode));
2258
}
2259

    
2260
/* stswx */
2261
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
2262
{
2263
    /* NIP cannot be restored if the memory exception comes from an helper */
2264
    gen_update_nip(ctx, ctx->nip - 4); 
2265
    gen_addr_reg_index(ctx);
2266
    gen_op_load_xer_bc();
2267
    op_ldsts(stsw, rS(ctx->opcode));
2268
}
2269

    
2270
/***                        Memory synchronisation                         ***/
2271
/* eieio */
2272
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
2273
{
2274
}
2275

    
2276
/* isync */
2277
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
2278
{
2279
}
2280

    
2281
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2282
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2283
#if defined(TARGET_PPC64)
2284
#if defined(CONFIG_USER_ONLY)
2285
static GenOpFunc *gen_op_lwarx[] = {
2286
    &gen_op_lwarx_raw,
2287
    &gen_op_lwarx_le_raw,
2288
    &gen_op_lwarx_64_raw,
2289
    &gen_op_lwarx_le_64_raw,
2290
};
2291
static GenOpFunc *gen_op_stwcx[] = {
2292
    &gen_op_stwcx_raw,
2293
    &gen_op_stwcx_le_raw,
2294
    &gen_op_stwcx_64_raw,
2295
    &gen_op_stwcx_le_64_raw,
2296
};
2297
#else
2298
static GenOpFunc *gen_op_lwarx[] = {
2299
    &gen_op_lwarx_user,
2300
    &gen_op_lwarx_le_user,
2301
    &gen_op_lwarx_kernel,
2302
    &gen_op_lwarx_le_kernel,
2303
    &gen_op_lwarx_64_user,
2304
    &gen_op_lwarx_le_64_user,
2305
    &gen_op_lwarx_64_kernel,
2306
    &gen_op_lwarx_le_64_kernel,
2307
};
2308
static GenOpFunc *gen_op_stwcx[] = {
2309
    &gen_op_stwcx_user,
2310
    &gen_op_stwcx_le_user,
2311
    &gen_op_stwcx_kernel,
2312
    &gen_op_stwcx_le_kernel,
2313
    &gen_op_stwcx_64_user,
2314
    &gen_op_stwcx_le_64_user,
2315
    &gen_op_stwcx_64_kernel,
2316
    &gen_op_stwcx_le_64_kernel,
2317
};
2318
#endif
2319
#else
2320
#if defined(CONFIG_USER_ONLY)
2321
static GenOpFunc *gen_op_lwarx[] = {
2322
    &gen_op_lwarx_raw,
2323
    &gen_op_lwarx_le_raw,
2324
};
2325
static GenOpFunc *gen_op_stwcx[] = {
2326
    &gen_op_stwcx_raw,
2327
    &gen_op_stwcx_le_raw,
2328
};
2329
#else
2330
static GenOpFunc *gen_op_lwarx[] = {
2331
    &gen_op_lwarx_user,
2332
    &gen_op_lwarx_le_user,
2333
    &gen_op_lwarx_kernel,
2334
    &gen_op_lwarx_le_kernel,
2335
};
2336
static GenOpFunc *gen_op_stwcx[] = {
2337
    &gen_op_stwcx_user,
2338
    &gen_op_stwcx_le_user,
2339
    &gen_op_stwcx_kernel,
2340
    &gen_op_stwcx_le_kernel,
2341
};
2342
#endif
2343
#endif
2344

    
2345
/* lwarx */
2346
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2347
{
2348
    gen_addr_reg_index(ctx);
2349
    op_lwarx();
2350
    gen_op_store_T1_gpr(rD(ctx->opcode));
2351
}
2352

    
2353
/* stwcx. */
2354
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2355
{
2356
    gen_addr_reg_index(ctx);
2357
    gen_op_load_gpr_T1(rS(ctx->opcode));
2358
    op_stwcx();
2359
}
2360

    
2361
/* sync */
2362
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
2363
{
2364
}
2365

    
2366
/***                         Floating-point load                           ***/
2367
#define GEN_LDF(width, opc)                                                   \
2368
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                 \
2369
{                                                                             \
2370
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2371
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2372
        return;                                                               \
2373
    }                                                                         \
2374
    gen_addr_imm_index(ctx);                                                  \
2375
    op_ldst(l##width);                                                        \
2376
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2377
}
2378

    
2379
#define GEN_LDUF(width, opc)                                                  \
2380
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)              \
2381
{                                                                             \
2382
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2383
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2384
        return;                                                               \
2385
    }                                                                         \
2386
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2387
        RET_INVAL(ctx);                                                       \
2388
        return;                                                               \
2389
    }                                                                         \
2390
    gen_addr_imm_index(ctx);                                                  \
2391
    op_ldst(l##width);                                                        \
2392
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2393
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2394
}
2395

    
2396
#define GEN_LDUXF(width, opc)                                                 \
2397
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
2398
{                                                                             \
2399
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2400
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2401
        return;                                                               \
2402
    }                                                                         \
2403
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2404
        RET_INVAL(ctx);                                                       \
2405
        return;                                                               \
2406
    }                                                                         \
2407
    gen_addr_reg_index(ctx);                                                  \
2408
    op_ldst(l##width);                                                        \
2409
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2410
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2411
}
2412

    
2413
#define GEN_LDXF(width, opc2, opc3)                                           \
2414
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)             \
2415
{                                                                             \
2416
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2417
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2418
        return;                                                               \
2419
    }                                                                         \
2420
    gen_addr_reg_index(ctx);                                                  \
2421
    op_ldst(l##width);                                                        \
2422
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2423
}
2424

    
2425
#define GEN_LDFS(width, op)                                                   \
2426
OP_LD_TABLE(width);                                                           \
2427
GEN_LDF(width, op | 0x20);                                                    \
2428
GEN_LDUF(width, op | 0x21);                                                   \
2429
GEN_LDUXF(width, op | 0x01);                                                  \
2430
GEN_LDXF(width, 0x17, op | 0x00)
2431

    
2432
/* lfd lfdu lfdux lfdx */
2433
GEN_LDFS(fd, 0x12);
2434
/* lfs lfsu lfsux lfsx */
2435
GEN_LDFS(fs, 0x10);
2436

    
2437
/***                         Floating-point store                          ***/
2438
#define GEN_STF(width, opc)                                                   \
2439
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
2440
{                                                                             \
2441
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2442
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2443
        return;                                                               \
2444
    }                                                                         \
2445
    gen_addr_imm_index(ctx);                                                  \
2446
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2447
    op_ldst(st##width);                                                       \
2448
}
2449

    
2450
#define GEN_STUF(width, opc)                                                  \
2451
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
2452
{                                                                             \
2453
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2454
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2455
        return;                                                               \
2456
    }                                                                         \
2457
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2458
        RET_INVAL(ctx);                                                       \
2459
        return;                                                               \
2460
    }                                                                         \
2461
    gen_addr_imm_index(ctx);                                                  \
2462
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2463
    op_ldst(st##width);                                                       \
2464
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2465
}
2466

    
2467
#define GEN_STUXF(width, opc)                                                 \
2468
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
2469
{                                                                             \
2470
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2471
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2472
        return;                                                               \
2473
    }                                                                         \
2474
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2475
        RET_INVAL(ctx);                                                       \
2476
        return;                                                               \
2477
    }                                                                         \
2478
    gen_addr_reg_index(ctx);                                                  \
2479
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2480
    op_ldst(st##width);                                                       \
2481
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2482
}
2483

    
2484
#define GEN_STXF(width, opc2, opc3)                                           \
2485
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)            \
2486
{                                                                             \
2487
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2488
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
2489
        return;                                                               \
2490
    }                                                                         \
2491
    gen_addr_reg_index(ctx);                                                  \
2492
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2493
    op_ldst(st##width);                                                       \
2494
}
2495

    
2496
#define GEN_STFS(width, op)                                                   \
2497
OP_ST_TABLE(width);                                                           \
2498
GEN_STF(width, op | 0x20);                                                    \
2499
GEN_STUF(width, op | 0x21);                                                   \
2500
GEN_STUXF(width, op | 0x01);                                                  \
2501
GEN_STXF(width, 0x17, op | 0x00)
2502

    
2503
/* stfd stfdu stfdux stfdx */
2504
GEN_STFS(fd, 0x16);
2505
/* stfs stfsu stfsux stfsx */
2506
GEN_STFS(fs, 0x14);
2507

    
2508
/* Optional: */
2509
/* stfiwx */
2510
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
2511
{
2512
    if (unlikely(!ctx->fpu_enabled)) {
2513
        RET_EXCP(ctx, EXCP_NO_FP, 0);
2514
        return;
2515
    }
2516
    gen_addr_reg_index(ctx);
2517
    /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2518
    RET_INVAL(ctx);
2519
}
2520

    
2521
/***                                Branch                                 ***/
2522

    
2523
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2524
{
2525
    TranslationBlock *tb;
2526
    tb = ctx->tb;
2527
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2528
        if (n == 0)
2529
            gen_op_goto_tb0(TBPARAM(tb));
2530
        else
2531
            gen_op_goto_tb1(TBPARAM(tb));
2532
        gen_set_T1(dest);
2533
#if defined(TARGET_PPC64)
2534
        if (ctx->sf_mode)
2535
            gen_op_b_T1_64();
2536
        else
2537
#endif
2538
            gen_op_b_T1();
2539
        gen_op_set_T0((long)tb + n);
2540
        if (ctx->singlestep_enabled)
2541
            gen_op_debug();
2542
        gen_op_exit_tb();
2543
    } else {
2544
        gen_set_T1(dest);
2545
#if defined(TARGET_PPC64)
2546
        if (ctx->sf_mode)
2547
            gen_op_b_T1_64();
2548
        else
2549
#endif
2550
            gen_op_b_T1();
2551
        gen_op_reset_T0();
2552
        if (ctx->singlestep_enabled)
2553
            gen_op_debug();
2554
        gen_op_exit_tb();
2555
    }
2556
}
2557

    
2558
/* b ba bl bla */
2559
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2560
{
2561
    target_ulong li, target;
2562

    
2563
    /* sign extend LI */
2564
#if defined(TARGET_PPC64)
2565
    if (ctx->sf_mode)
2566
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2567
    else
2568
#endif
2569
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2570
    if (likely(AA(ctx->opcode) == 0))
2571
        target = ctx->nip + li - 4;
2572
    else
2573
        target = li;
2574
    if (LK(ctx->opcode)) {
2575
#if defined(TARGET_PPC64)
2576
        if (ctx->sf_mode)
2577
            gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2578
        else
2579
#endif
2580
            gen_op_setlr(ctx->nip);
2581
    }
2582
    gen_goto_tb(ctx, 0, target);
2583
    ctx->exception = EXCP_BRANCH;
2584
}
2585

    
2586
#define BCOND_IM  0
2587
#define BCOND_LR  1
2588
#define BCOND_CTR 2
2589

    
2590
static inline void gen_bcond(DisasContext *ctx, int type)
2591
{
2592
    target_ulong target = 0;
2593
    target_ulong li;
2594
    uint32_t bo = BO(ctx->opcode);
2595
    uint32_t bi = BI(ctx->opcode);
2596
    uint32_t mask;
2597

    
2598
    if ((bo & 0x4) == 0)
2599
        gen_op_dec_ctr();
2600
    switch(type) {
2601
    case BCOND_IM:
2602
        li = (target_long)((int16_t)(BD(ctx->opcode)));
2603
        if (likely(AA(ctx->opcode) == 0)) {
2604
            target = ctx->nip + li - 4;
2605
        } else {
2606
            target = li;
2607
        }
2608
        break;
2609
    case BCOND_CTR:
2610
        gen_op_movl_T1_ctr();
2611
        break;
2612
    default:
2613
    case BCOND_LR:
2614
        gen_op_movl_T1_lr();
2615
        break;
2616
    }
2617
    if (LK(ctx->opcode)) {
2618
#if defined(TARGET_PPC64)
2619
        if (ctx->sf_mode)
2620
            gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2621
        else
2622
#endif
2623
            gen_op_setlr(ctx->nip);
2624
    }
2625
    if (bo & 0x10) {
2626
        /* No CR condition */
2627
        switch (bo & 0x6) {
2628
        case 0:
2629
#if defined(TARGET_PPC64)
2630
            if (ctx->sf_mode)
2631
                gen_op_test_ctr_64();
2632
            else
2633
#endif
2634
                gen_op_test_ctr();
2635
            break;
2636
        case 2:
2637
#if defined(TARGET_PPC64)
2638
            if (ctx->sf_mode)
2639
                gen_op_test_ctrz_64();
2640
            else
2641
#endif
2642
                gen_op_test_ctrz();
2643
            break;
2644
        default:
2645
        case 4:
2646
        case 6:
2647
            if (type == BCOND_IM) {
2648
                gen_goto_tb(ctx, 0, target);
2649
            } else {
2650
#if defined(TARGET_PPC64)
2651
                if (ctx->sf_mode)
2652
                    gen_op_b_T1_64();
2653
                else
2654
#endif
2655
                    gen_op_b_T1();
2656
                gen_op_reset_T0();
2657
            }
2658
            goto no_test;
2659
        }
2660
    } else {
2661
        mask = 1 << (3 - (bi & 0x03));
2662
        gen_op_load_crf_T0(bi >> 2);
2663
        if (bo & 0x8) {
2664
            switch (bo & 0x6) {
2665
            case 0:
2666
#if defined(TARGET_PPC64)
2667
                if (ctx->sf_mode)
2668
                    gen_op_test_ctr_true_64(mask);
2669
                else
2670
#endif
2671
                    gen_op_test_ctr_true(mask);
2672
                break;
2673
            case 2:
2674
#if defined(TARGET_PPC64)
2675
                if (ctx->sf_mode)
2676
                    gen_op_test_ctrz_true_64(mask);
2677
                else
2678
#endif
2679
                    gen_op_test_ctrz_true(mask);
2680
                break;
2681
            default:
2682
            case 4:
2683
            case 6:
2684
                gen_op_test_true(mask);
2685
                break;
2686
            }
2687
        } else {
2688
            switch (bo & 0x6) {
2689
            case 0:
2690
#if defined(TARGET_PPC64)
2691
                if (ctx->sf_mode)
2692
                    gen_op_test_ctr_false_64(mask);
2693
                else
2694
#endif
2695
                    gen_op_test_ctr_false(mask);
2696
                break;                           
2697
            case 2:
2698
#if defined(TARGET_PPC64)
2699
                if (ctx->sf_mode)
2700
                    gen_op_test_ctrz_false_64(mask);
2701
                else
2702
#endif
2703
                    gen_op_test_ctrz_false(mask);
2704
                break;
2705
            default:
2706
            case 4:
2707
            case 6:
2708
                gen_op_test_false(mask);
2709
                break;
2710
            }
2711
        }
2712
    }
2713
    if (type == BCOND_IM) {
2714
        int l1 = gen_new_label();
2715
        gen_op_jz_T0(l1);
2716
        gen_goto_tb(ctx, 0, target);
2717
        gen_set_label(l1);
2718
        gen_goto_tb(ctx, 1, ctx->nip);
2719
    } else {
2720
#if defined(TARGET_PPC64)
2721
        if (ctx->sf_mode)
2722
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
2723
        else
2724
#endif
2725
            gen_op_btest_T1(ctx->nip);
2726
        gen_op_reset_T0();
2727
    }
2728
 no_test:
2729
    if (ctx->singlestep_enabled)
2730
        gen_op_debug();
2731
    gen_op_exit_tb();
2732
    ctx->exception = EXCP_BRANCH;
2733
}
2734

    
2735
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2736
{                     
2737
    gen_bcond(ctx, BCOND_IM);
2738
}
2739

    
2740
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
2741
{                    
2742
    gen_bcond(ctx, BCOND_CTR);
2743
}
2744

    
2745
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
2746
{                     
2747
    gen_bcond(ctx, BCOND_LR);
2748
}
2749

    
2750
/***                      Condition register logical                       ***/
2751
#define GEN_CRLOGIC(op, opc)                                                  \
2752
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
2753
{                                                                             \
2754
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
2755
    gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
2756
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
2757
    gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
2758
    gen_op_##op();                                                            \
2759
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
2760
    gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
2761
                     3 - (crbD(ctx->opcode) & 0x03));                         \
2762
    gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
2763
}
2764

    
2765
/* crand */
2766
GEN_CRLOGIC(and, 0x08);
2767
/* crandc */
2768
GEN_CRLOGIC(andc, 0x04);
2769
/* creqv */
2770
GEN_CRLOGIC(eqv, 0x09);
2771
/* crnand */
2772
GEN_CRLOGIC(nand, 0x07);
2773
/* crnor */
2774
GEN_CRLOGIC(nor, 0x01);
2775
/* cror */
2776
GEN_CRLOGIC(or, 0x0E);
2777
/* crorc */
2778
GEN_CRLOGIC(orc, 0x0D);
2779
/* crxor */
2780
GEN_CRLOGIC(xor, 0x06);
2781
/* mcrf */
2782
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
2783
{
2784
    gen_op_load_crf_T0(crfS(ctx->opcode));
2785
    gen_op_store_T0_crf(crfD(ctx->opcode));
2786
}
2787

    
2788
/***                           System linkage                              ***/
2789
/* rfi (supervisor only) */
2790
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
2791
{
2792
#if defined(CONFIG_USER_ONLY)
2793
    RET_PRIVOPC(ctx);
2794
#else
2795
    /* Restore CPU state */
2796
    if (unlikely(!ctx->supervisor)) {
2797
        RET_PRIVOPC(ctx);
2798
        return;
2799
    }
2800
#if defined(TARGET_PPC64)
2801
    if (!ctx->sf_mode)
2802
        gen_op_rfi_32();
2803
    else
2804
#endif
2805
        gen_op_rfi();
2806
    RET_CHG_FLOW(ctx);
2807
#endif
2808
}
2809

    
2810
/* sc */
2811
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
2812
{
2813
#if defined(CONFIG_USER_ONLY)
2814
    RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
2815
#else
2816
    RET_EXCP(ctx, EXCP_SYSCALL, 0);
2817
#endif
2818
}
2819

    
2820
/***                                Trap                                   ***/
2821
/* tw */
2822
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
2823
{
2824
    gen_op_load_gpr_T0(rA(ctx->opcode));
2825
    gen_op_load_gpr_T1(rB(ctx->opcode));
2826
    /* Update the nip since this might generate a trap exception */
2827
    gen_update_nip(ctx, ctx->nip);
2828
    gen_op_tw(TO(ctx->opcode));
2829
}
2830

    
2831
/* twi */
2832
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2833
{
2834
    gen_op_load_gpr_T0(rA(ctx->opcode));
2835
    gen_set_T1(SIMM(ctx->opcode));
2836
    /* Update the nip since this might generate a trap exception */
2837
    gen_update_nip(ctx, ctx->nip);
2838
    gen_op_tw(TO(ctx->opcode));
2839
}
2840

    
2841
#if defined(TARGET_PPC64)
2842
/* td */
2843
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
2844
{
2845
    gen_op_load_gpr_T0(rA(ctx->opcode));
2846
    gen_op_load_gpr_T1(rB(ctx->opcode));
2847
    /* Update the nip since this might generate a trap exception */
2848
    gen_update_nip(ctx, ctx->nip);
2849
    gen_op_td(TO(ctx->opcode));
2850
}
2851

    
2852
/* tdi */
2853
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
2854
{
2855
    gen_op_load_gpr_T0(rA(ctx->opcode));
2856
    gen_set_T1(SIMM(ctx->opcode));
2857
    /* Update the nip since this might generate a trap exception */
2858
    gen_update_nip(ctx, ctx->nip);
2859
    gen_op_td(TO(ctx->opcode));
2860
}
2861
#endif
2862

    
2863
/***                          Processor control                            ***/
2864
/* mcrxr */
2865
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
2866
{
2867
    gen_op_load_xer_cr();
2868
    gen_op_store_T0_crf(crfD(ctx->opcode));
2869
    gen_op_clear_xer_ov();
2870
    gen_op_clear_xer_ca();
2871
}
2872

    
2873
/* mfcr */
2874
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
2875
{
2876
    uint32_t crm, crn;
2877
    
2878
    if (likely(ctx->opcode & 0x00100000)) {
2879
        crm = CRM(ctx->opcode);
2880
        if (likely((crm ^ (crm - 1)) == 0)) {
2881
            crn = ffs(crm);
2882
            gen_op_load_cro(7 - crn);
2883
        }
2884
    } else {
2885
        gen_op_load_cr();
2886
    }
2887
    gen_op_store_T0_gpr(rD(ctx->opcode));
2888
}
2889

    
2890
/* mfmsr */
2891
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
2892
{
2893
#if defined(CONFIG_USER_ONLY)
2894
    RET_PRIVREG(ctx);
2895
#else
2896
    if (unlikely(!ctx->supervisor)) {
2897
        RET_PRIVREG(ctx);
2898
        return;
2899
    }
2900
    gen_op_load_msr();
2901
    gen_op_store_T0_gpr(rD(ctx->opcode));
2902
#endif
2903
}
2904

    
2905
#if 0
2906
#define SPR_NOACCESS ((void *)(-1))
2907
#else
2908
static void spr_noaccess (void *opaque, int sprn)
2909
{
2910
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
2911
    printf("ERROR: try to access SPR %d !\n", sprn);
2912
}
2913
#define SPR_NOACCESS (&spr_noaccess)
2914
#endif
2915

    
2916
/* mfspr */
2917
static inline void gen_op_mfspr (DisasContext *ctx)
2918
{
2919
    void (*read_cb)(void *opaque, int sprn);
2920
    uint32_t sprn = SPR(ctx->opcode);
2921

    
2922
#if !defined(CONFIG_USER_ONLY)
2923
    if (ctx->supervisor)
2924
        read_cb = ctx->spr_cb[sprn].oea_read;
2925
    else
2926
#endif
2927
        read_cb = ctx->spr_cb[sprn].uea_read;
2928
    if (likely(read_cb != NULL)) {
2929
        if (likely(read_cb != SPR_NOACCESS)) {
2930
            (*read_cb)(ctx, sprn);
2931
            gen_op_store_T0_gpr(rD(ctx->opcode));
2932
        } else {
2933
            /* Privilege exception */
2934
            if (loglevel) {
2935
                fprintf(logfile, "Trying to read priviledged spr %d %03x\n",
2936
                        sprn, sprn);
2937
            }
2938
            printf("Trying to read priviledged spr %d %03x\n", sprn, sprn);
2939
            RET_PRIVREG(ctx);
2940
        }
2941
    } else {
2942
        /* Not defined */
2943
        if (loglevel) {
2944
            fprintf(logfile, "Trying to read invalid spr %d %03x\n",
2945
                    sprn, sprn);
2946
        }
2947
        printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
2948
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2949
    }
2950
}
2951

    
2952
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
2953
{
2954
    gen_op_mfspr(ctx);
2955
}
2956

    
2957
/* mftb */
2958
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB)
2959
{
2960
    gen_op_mfspr(ctx);
2961
}
2962

    
2963
/* mtcrf */
2964
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
2965
{
2966
    uint32_t crm, crn;
2967
    
2968
    gen_op_load_gpr_T0(rS(ctx->opcode));
2969
    crm = CRM(ctx->opcode);
2970
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
2971
        crn = ffs(crm);
2972
        gen_op_srli_T0(crn * 4);
2973
        gen_op_andi_T0(0xF);
2974
        gen_op_store_cro(7 - crn);
2975
    } else {
2976
        gen_op_store_cr(crm);
2977
    }
2978
}
2979

    
2980
/* mtmsr */
2981
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
2982
{
2983
#if defined(CONFIG_USER_ONLY)
2984
    RET_PRIVREG(ctx);
2985
#else
2986
    if (unlikely(!ctx->supervisor)) {
2987
        RET_PRIVREG(ctx);
2988
        return;
2989
    }
2990
    gen_update_nip(ctx, ctx->nip);
2991
    gen_op_load_gpr_T0(rS(ctx->opcode));
2992
#if defined(TARGET_PPC64)
2993
    if (!ctx->sf_mode)
2994
        gen_op_store_msr_32();
2995
    else
2996
#endif
2997
        gen_op_store_msr();
2998
    /* Must stop the translation as machine state (may have) changed */
2999
    RET_CHG_FLOW(ctx);
3000
#endif
3001
}
3002

    
3003
/* mtspr */
3004
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3005
{
3006
    void (*write_cb)(void *opaque, int sprn);
3007
    uint32_t sprn = SPR(ctx->opcode);
3008

    
3009
#if !defined(CONFIG_USER_ONLY)
3010
    if (ctx->supervisor)
3011
        write_cb = ctx->spr_cb[sprn].oea_write;
3012
    else
3013
#endif
3014
        write_cb = ctx->spr_cb[sprn].uea_write;
3015
    if (likely(write_cb != NULL)) {
3016
        if (likely(write_cb != SPR_NOACCESS)) {
3017
            gen_op_load_gpr_T0(rS(ctx->opcode));
3018
            (*write_cb)(ctx, sprn);
3019
        } else {
3020
            /* Privilege exception */
3021
            if (loglevel) {
3022
                fprintf(logfile, "Trying to write priviledged spr %d %03x\n",
3023
                        sprn, sprn);
3024
            }
3025
            printf("Trying to write priviledged spr %d %03x\n", sprn, sprn);
3026
            RET_PRIVREG(ctx);
3027
        }
3028
    } else {
3029
        /* Not defined */
3030
        if (loglevel) {
3031
            fprintf(logfile, "Trying to write invalid spr %d %03x\n",
3032
                    sprn, sprn);
3033
        }
3034
        printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
3035
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
3036
    }
3037
}
3038

    
3039
/***                         Cache management                              ***/
3040
/* For now, all those will be implemented as nop:
3041
 * this is valid, regarding the PowerPC specs...
3042
 * We just have to flush tb while invalidating instruction cache lines...
3043
 */
3044
/* dcbf */
3045
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
3046
{
3047
    gen_addr_reg_index(ctx);
3048
    op_ldst(lbz);
3049
}
3050

    
3051
/* dcbi (Supervisor only) */
3052
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3053
{
3054
#if defined(CONFIG_USER_ONLY)
3055
    RET_PRIVOPC(ctx);
3056
#else
3057
    if (unlikely(!ctx->supervisor)) {
3058
        RET_PRIVOPC(ctx);
3059
        return;
3060
    }
3061
    gen_addr_reg_index(ctx);
3062
    /* XXX: specification says this should be treated as a store by the MMU */
3063
    //op_ldst(lbz);
3064
    op_ldst(stb);
3065
#endif
3066
}
3067

    
3068
/* dcdst */
3069
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3070
{
3071
    /* XXX: specification say this is treated as a load by the MMU */
3072
    gen_addr_reg_index(ctx);
3073
    op_ldst(lbz);
3074
}
3075

    
3076
/* dcbt */
3077
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
3078
{
3079
    /* XXX: specification say this is treated as a load by the MMU
3080
     *      but does not generate any exception
3081
     */
3082
}
3083

    
3084
/* dcbtst */
3085
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
3086
{
3087
    /* XXX: specification say this is treated as a load by the MMU
3088
     *      but does not generate any exception
3089
     */
3090
}
3091

    
3092
/* dcbz */
3093
#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3094
#if defined(TARGET_PPC64)
3095
#if defined(CONFIG_USER_ONLY)
3096
static GenOpFunc *gen_op_dcbz[] = {
3097
    &gen_op_dcbz_raw,
3098
    &gen_op_dcbz_raw,
3099
    &gen_op_dcbz_64_raw,
3100
    &gen_op_dcbz_64_raw,
3101
};
3102
#else
3103
static GenOpFunc *gen_op_dcbz[] = {
3104
    &gen_op_dcbz_user,
3105
    &gen_op_dcbz_user,
3106
    &gen_op_dcbz_kernel,
3107
    &gen_op_dcbz_kernel,
3108
    &gen_op_dcbz_64_user,
3109
    &gen_op_dcbz_64_user,
3110
    &gen_op_dcbz_64_kernel,
3111
    &gen_op_dcbz_64_kernel,
3112
};
3113
#endif
3114
#else
3115
#if defined(CONFIG_USER_ONLY)
3116
static GenOpFunc *gen_op_dcbz[] = {
3117
    &gen_op_dcbz_raw,
3118
    &gen_op_dcbz_raw,
3119
};
3120
#else
3121
static GenOpFunc *gen_op_dcbz[] = {
3122
    &gen_op_dcbz_user,
3123
    &gen_op_dcbz_user,
3124
    &gen_op_dcbz_kernel,
3125
    &gen_op_dcbz_kernel,
3126
};
3127
#endif
3128
#endif
3129

    
3130
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3131
{
3132
    gen_addr_reg_index(ctx);
3133
    op_dcbz();
3134
    gen_op_check_reservation();
3135
}
3136

    
3137
/* icbi */
3138
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3139
#if defined(TARGET_PPC64)
3140
#if defined(CONFIG_USER_ONLY)
3141
static GenOpFunc *gen_op_icbi[] = {
3142
    &gen_op_icbi_raw,
3143
    &gen_op_icbi_raw,
3144
    &gen_op_icbi_64_raw,
3145
    &gen_op_icbi_64_raw,
3146
};
3147
#else
3148
static GenOpFunc *gen_op_icbi[] = {
3149
    &gen_op_icbi_user,
3150
    &gen_op_icbi_user,
3151
    &gen_op_icbi_kernel,
3152
    &gen_op_icbi_kernel,
3153
    &gen_op_icbi_64_user,
3154
    &gen_op_icbi_64_user,
3155
    &gen_op_icbi_64_kernel,
3156
    &gen_op_icbi_64_kernel,
3157
};
3158
#endif
3159
#else
3160
#if defined(CONFIG_USER_ONLY)
3161
static GenOpFunc *gen_op_icbi[] = {
3162
    &gen_op_icbi_raw,
3163
    &gen_op_icbi_raw,
3164
};
3165
#else
3166
static GenOpFunc *gen_op_icbi[] = {
3167
    &gen_op_icbi_user,
3168
    &gen_op_icbi_user,
3169
    &gen_op_icbi_kernel,
3170
    &gen_op_icbi_kernel,
3171
};
3172
#endif
3173
#endif
3174
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3175
{
3176
    /* NIP cannot be restored if the memory exception comes from an helper */
3177
    gen_update_nip(ctx, ctx->nip - 4);
3178
    gen_addr_reg_index(ctx);
3179
    op_icbi();
3180
    RET_STOP(ctx);
3181
}
3182

    
3183
/* Optional: */
3184
/* dcba */
3185
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT)
3186
{
3187
}
3188

    
3189
/***                    Segment register manipulation                      ***/
3190
/* Supervisor only: */
3191
/* mfsr */
3192
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3193
{
3194
#if defined(CONFIG_USER_ONLY)
3195
    RET_PRIVREG(ctx);
3196
#else
3197
    if (unlikely(!ctx->supervisor)) {
3198
        RET_PRIVREG(ctx);
3199
        return;
3200
    }
3201
    gen_op_set_T1(SR(ctx->opcode));
3202
    gen_op_load_sr();
3203
    gen_op_store_T0_gpr(rD(ctx->opcode));
3204
#endif
3205
}
3206

    
3207
/* mfsrin */
3208
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3209
{
3210
#if defined(CONFIG_USER_ONLY)
3211
    RET_PRIVREG(ctx);
3212
#else
3213
    if (unlikely(!ctx->supervisor)) {
3214
        RET_PRIVREG(ctx);
3215
        return;
3216
    }
3217
    gen_op_load_gpr_T1(rB(ctx->opcode));
3218
    gen_op_srli_T1(28);
3219
    gen_op_load_sr();
3220
    gen_op_store_T0_gpr(rD(ctx->opcode));
3221
#endif
3222
}
3223

    
3224
/* mtsr */
3225
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3226
{
3227
#if defined(CONFIG_USER_ONLY)
3228
    RET_PRIVREG(ctx);
3229
#else
3230
    if (unlikely(!ctx->supervisor)) {
3231
        RET_PRIVREG(ctx);
3232
        return;
3233
    }
3234
    gen_op_load_gpr_T0(rS(ctx->opcode));
3235
    gen_op_set_T1(SR(ctx->opcode));
3236
    gen_op_store_sr();
3237
    RET_STOP(ctx);
3238
#endif
3239
}
3240

    
3241
/* mtsrin */
3242
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3243
{
3244
#if defined(CONFIG_USER_ONLY)
3245
    RET_PRIVREG(ctx);
3246
#else
3247
    if (unlikely(!ctx->supervisor)) {
3248
        RET_PRIVREG(ctx);
3249
        return;
3250
    }
3251
    gen_op_load_gpr_T0(rS(ctx->opcode));
3252
    gen_op_load_gpr_T1(rB(ctx->opcode));
3253
    gen_op_srli_T1(28);
3254
    gen_op_store_sr();
3255
    RET_STOP(ctx);
3256
#endif
3257
}
3258

    
3259
/***                      Lookaside buffer management                      ***/
3260
/* Optional & supervisor only: */
3261
/* tlbia */
3262
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3263
{
3264
#if defined(CONFIG_USER_ONLY)
3265
    RET_PRIVOPC(ctx);
3266
#else
3267
    if (unlikely(!ctx->supervisor)) {
3268
        if (loglevel)
3269
            fprintf(logfile, "%s: ! supervisor\n", __func__);
3270
        RET_PRIVOPC(ctx);
3271
        return;
3272
    }
3273
    gen_op_tlbia();
3274
    RET_STOP(ctx);
3275
#endif
3276
}
3277

    
3278
/* tlbie */
3279
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3280
{
3281
#if defined(CONFIG_USER_ONLY)
3282
    RET_PRIVOPC(ctx);
3283
#else
3284
    if (unlikely(!ctx->supervisor)) {
3285
        RET_PRIVOPC(ctx);
3286
        return;
3287
    }
3288
    gen_op_load_gpr_T0(rB(ctx->opcode));
3289
#if defined(TARGET_PPC64)
3290
    if (ctx->sf_mode)
3291
        gen_op_tlbie_64();
3292
    else
3293
#endif
3294
        gen_op_tlbie();
3295
    RET_STOP(ctx);
3296
#endif
3297
}
3298

    
3299
/* tlbsync */
3300
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3301
{
3302
#if defined(CONFIG_USER_ONLY)
3303
    RET_PRIVOPC(ctx);
3304
#else
3305
    if (unlikely(!ctx->supervisor)) {
3306
        RET_PRIVOPC(ctx);
3307
        return;
3308
    }
3309
    /* This has no effect: it should ensure that all previous
3310
     * tlbie have completed
3311
     */
3312
    RET_STOP(ctx);
3313
#endif
3314
}
3315

    
3316
/***                              External control                         ***/
3317
/* Optional: */
3318
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3319
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3320
#if defined(TARGET_PPC64)
3321
#if defined(CONFIG_USER_ONLY)
3322
static GenOpFunc *gen_op_eciwx[] = {
3323
    &gen_op_eciwx_raw,
3324
    &gen_op_eciwx_le_raw,
3325
    &gen_op_eciwx_64_raw,
3326
    &gen_op_eciwx_le_64_raw,
3327
};
3328
static GenOpFunc *gen_op_ecowx[] = {
3329
    &gen_op_ecowx_raw,
3330
    &gen_op_ecowx_le_raw,
3331
    &gen_op_ecowx_64_raw,
3332
    &gen_op_ecowx_le_64_raw,
3333
};
3334
#else
3335
static GenOpFunc *gen_op_eciwx[] = {
3336
    &gen_op_eciwx_user,
3337
    &gen_op_eciwx_le_user,
3338
    &gen_op_eciwx_kernel,
3339
    &gen_op_eciwx_le_kernel,
3340
    &gen_op_eciwx_64_user,
3341
    &gen_op_eciwx_le_64_user,
3342
    &gen_op_eciwx_64_kernel,
3343
    &gen_op_eciwx_le_64_kernel,
3344
};
3345
static GenOpFunc *gen_op_ecowx[] = {
3346
    &gen_op_ecowx_user,
3347
    &gen_op_ecowx_le_user,
3348
    &gen_op_ecowx_kernel,
3349
    &gen_op_ecowx_le_kernel,
3350
    &gen_op_ecowx_64_user,
3351
    &gen_op_ecowx_le_64_user,
3352
    &gen_op_ecowx_64_kernel,
3353
    &gen_op_ecowx_le_64_kernel,
3354
};
3355
#endif
3356
#else
3357
#if defined(CONFIG_USER_ONLY)
3358
static GenOpFunc *gen_op_eciwx[] = {
3359
    &gen_op_eciwx_raw,
3360
    &gen_op_eciwx_le_raw,
3361
};
3362
static GenOpFunc *gen_op_ecowx[] = {
3363
    &gen_op_ecowx_raw,
3364
    &gen_op_ecowx_le_raw,
3365
};
3366
#else
3367
static GenOpFunc *gen_op_eciwx[] = {
3368
    &gen_op_eciwx_user,
3369
    &gen_op_eciwx_le_user,
3370
    &gen_op_eciwx_kernel,
3371
    &gen_op_eciwx_le_kernel,
3372
};
3373
static GenOpFunc *gen_op_ecowx[] = {
3374
    &gen_op_ecowx_user,
3375
    &gen_op_ecowx_le_user,
3376
    &gen_op_ecowx_kernel,
3377
    &gen_op_ecowx_le_kernel,
3378
};
3379
#endif
3380
#endif
3381

    
3382
/* eciwx */
3383
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3384
{
3385
    /* Should check EAR[E] & alignment ! */
3386
    gen_addr_reg_index(ctx);
3387
    op_eciwx();
3388
    gen_op_store_T0_gpr(rD(ctx->opcode));
3389
}
3390

    
3391
/* ecowx */
3392
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3393
{
3394
    /* Should check EAR[E] & alignment ! */
3395
    gen_addr_reg_index(ctx);
3396
    gen_op_load_gpr_T1(rS(ctx->opcode));
3397
    op_ecowx();
3398
}
3399

    
3400
/* PowerPC 601 specific instructions */
3401
/* abs - abs. */
3402
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3403
{
3404
    gen_op_load_gpr_T0(rA(ctx->opcode));
3405
    gen_op_POWER_abs();
3406
    gen_op_store_T0_gpr(rD(ctx->opcode));
3407
    if (unlikely(Rc(ctx->opcode) != 0))
3408
        gen_set_Rc0(ctx);
3409
}
3410

    
3411
/* abso - abso. */
3412
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3413
{
3414
    gen_op_load_gpr_T0(rA(ctx->opcode));
3415
    gen_op_POWER_abso();
3416
    gen_op_store_T0_gpr(rD(ctx->opcode));
3417
    if (unlikely(Rc(ctx->opcode) != 0))
3418
        gen_set_Rc0(ctx);
3419
}
3420

    
3421
/* clcs */
3422
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR) /* 601 ? */
3423
{
3424
    gen_op_load_gpr_T0(rA(ctx->opcode));
3425
    gen_op_POWER_clcs();
3426
    gen_op_store_T0_gpr(rD(ctx->opcode));
3427
}
3428

    
3429
/* div - div. */
3430
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3431
{
3432
    gen_op_load_gpr_T0(rA(ctx->opcode));
3433
    gen_op_load_gpr_T1(rB(ctx->opcode));
3434
    gen_op_POWER_div();
3435
    gen_op_store_T0_gpr(rD(ctx->opcode));
3436
    if (unlikely(Rc(ctx->opcode) != 0))
3437
        gen_set_Rc0(ctx);
3438
}
3439

    
3440
/* divo - divo. */
3441
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3442
{
3443
    gen_op_load_gpr_T0(rA(ctx->opcode));
3444
    gen_op_load_gpr_T1(rB(ctx->opcode));
3445
    gen_op_POWER_divo();
3446
    gen_op_store_T0_gpr(rD(ctx->opcode));
3447
    if (unlikely(Rc(ctx->opcode) != 0))
3448
        gen_set_Rc0(ctx);
3449
}
3450

    
3451
/* divs - divs. */
3452
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3453
{
3454
    gen_op_load_gpr_T0(rA(ctx->opcode));
3455
    gen_op_load_gpr_T1(rB(ctx->opcode));
3456
    gen_op_POWER_divs();
3457
    gen_op_store_T0_gpr(rD(ctx->opcode));
3458
    if (unlikely(Rc(ctx->opcode) != 0))
3459
        gen_set_Rc0(ctx);
3460
}
3461

    
3462
/* divso - divso. */
3463
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3464
{
3465
    gen_op_load_gpr_T0(rA(ctx->opcode));
3466
    gen_op_load_gpr_T1(rB(ctx->opcode));
3467
    gen_op_POWER_divso();
3468
    gen_op_store_T0_gpr(rD(ctx->opcode));
3469
    if (unlikely(Rc(ctx->opcode) != 0))
3470
        gen_set_Rc0(ctx);
3471
}
3472

    
3473
/* doz - doz. */
3474
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3475
{
3476
    gen_op_load_gpr_T0(rA(ctx->opcode));
3477
    gen_op_load_gpr_T1(rB(ctx->opcode));
3478
    gen_op_POWER_doz();
3479
    gen_op_store_T0_gpr(rD(ctx->opcode));
3480
    if (unlikely(Rc(ctx->opcode) != 0))
3481
        gen_set_Rc0(ctx);
3482
}
3483

    
3484
/* dozo - dozo. */
3485
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3486
{
3487
    gen_op_load_gpr_T0(rA(ctx->opcode));
3488
    gen_op_load_gpr_T1(rB(ctx->opcode));
3489
    gen_op_POWER_dozo();
3490
    gen_op_store_T0_gpr(rD(ctx->opcode));
3491
    if (unlikely(Rc(ctx->opcode) != 0))
3492
        gen_set_Rc0(ctx);
3493
}
3494

    
3495
/* dozi */
3496
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3497
{
3498
    gen_op_load_gpr_T0(rA(ctx->opcode));
3499
    gen_op_set_T1(SIMM(ctx->opcode));
3500
    gen_op_POWER_doz();
3501
    gen_op_store_T0_gpr(rD(ctx->opcode));
3502
}
3503

    
3504
/* As lscbx load from memory byte after byte, it's always endian safe */
3505
#define op_POWER_lscbx(start, ra, rb) \
3506
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3507
#if defined(CONFIG_USER_ONLY)
3508
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3509
    &gen_op_POWER_lscbx_raw,
3510
    &gen_op_POWER_lscbx_raw,
3511
};
3512
#else
3513
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3514
    &gen_op_POWER_lscbx_user,
3515
    &gen_op_POWER_lscbx_user,
3516
    &gen_op_POWER_lscbx_kernel,
3517
    &gen_op_POWER_lscbx_kernel,
3518
};
3519
#endif
3520

    
3521
/* lscbx - lscbx. */
3522
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3523
{
3524
    int ra = rA(ctx->opcode);
3525
    int rb = rB(ctx->opcode);
3526

    
3527
    gen_addr_reg_index(ctx);
3528
    if (ra == 0) {
3529
        ra = rb;
3530
    }
3531
    /* NIP cannot be restored if the memory exception comes from an helper */
3532
    gen_update_nip(ctx, ctx->nip - 4);
3533
    gen_op_load_xer_bc();
3534
    gen_op_load_xer_cmp();
3535
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3536
    gen_op_store_xer_bc();
3537
    if (unlikely(Rc(ctx->opcode) != 0))
3538
        gen_set_Rc0(ctx);
3539
}
3540

    
3541
/* maskg - maskg. */
3542
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3543
{
3544
    gen_op_load_gpr_T0(rS(ctx->opcode));
3545
    gen_op_load_gpr_T1(rB(ctx->opcode));
3546
    gen_op_POWER_maskg();
3547
    gen_op_store_T0_gpr(rA(ctx->opcode));
3548
    if (unlikely(Rc(ctx->opcode) != 0))
3549
        gen_set_Rc0(ctx);
3550
}
3551

    
3552
/* maskir - maskir. */
3553
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3554
{
3555
    gen_op_load_gpr_T0(rA(ctx->opcode));
3556
    gen_op_load_gpr_T1(rS(ctx->opcode));
3557
    gen_op_load_gpr_T2(rB(ctx->opcode));
3558
    gen_op_POWER_maskir();
3559
    gen_op_store_T0_gpr(rA(ctx->opcode));
3560
    if (unlikely(Rc(ctx->opcode) != 0))
3561
        gen_set_Rc0(ctx);
3562
}
3563

    
3564
/* mul - mul. */
3565
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
3566
{
3567
    gen_op_load_gpr_T0(rA(ctx->opcode));
3568
    gen_op_load_gpr_T1(rB(ctx->opcode));
3569
    gen_op_POWER_mul();
3570
    gen_op_store_T0_gpr(rD(ctx->opcode));
3571
    if (unlikely(Rc(ctx->opcode) != 0))
3572
        gen_set_Rc0(ctx);
3573
}
3574

    
3575
/* mulo - mulo. */
3576
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
3577
{
3578
    gen_op_load_gpr_T0(rA(ctx->opcode));
3579
    gen_op_load_gpr_T1(rB(ctx->opcode));
3580
    gen_op_POWER_mulo();
3581
    gen_op_store_T0_gpr(rD(ctx->opcode));
3582
    if (unlikely(Rc(ctx->opcode) != 0))
3583
        gen_set_Rc0(ctx);
3584
}
3585

    
3586
/* nabs - nabs. */
3587
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
3588
{
3589
    gen_op_load_gpr_T0(rA(ctx->opcode));
3590
    gen_op_POWER_nabs();
3591
    gen_op_store_T0_gpr(rD(ctx->opcode));
3592
    if (unlikely(Rc(ctx->opcode) != 0))
3593
        gen_set_Rc0(ctx);
3594
}
3595

    
3596
/* nabso - nabso. */
3597
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
3598
{
3599
    gen_op_load_gpr_T0(rA(ctx->opcode));
3600
    gen_op_POWER_nabso();
3601
    gen_op_store_T0_gpr(rD(ctx->opcode));
3602
    if (unlikely(Rc(ctx->opcode) != 0))
3603
        gen_set_Rc0(ctx);
3604
}
3605

    
3606
/* rlmi - rlmi. */
3607
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3608
{
3609
    uint32_t mb, me;
3610

    
3611
    mb = MB(ctx->opcode);
3612
    me = ME(ctx->opcode);
3613
    gen_op_load_gpr_T0(rS(ctx->opcode));
3614
    gen_op_load_gpr_T1(rA(ctx->opcode));
3615
    gen_op_load_gpr_T2(rB(ctx->opcode));
3616
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
3617
    gen_op_store_T0_gpr(rA(ctx->opcode));
3618
    if (unlikely(Rc(ctx->opcode) != 0))
3619
        gen_set_Rc0(ctx);
3620
}
3621

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

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

    
3645
/* sleq - sleq. */
3646
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 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_sleq();
3651
    gen_op_store_T0_gpr(rA(ctx->opcode));
3652
    if (unlikely(Rc(ctx->opcode) != 0))
3653
        gen_set_Rc0(ctx);
3654
}
3655

    
3656
/* sliq - sliq. */
3657
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
3658
{
3659
    gen_op_load_gpr_T0(rS(ctx->opcode));
3660
    gen_op_set_T1(SH(ctx->opcode));
3661
    gen_op_POWER_sle();
3662
    gen_op_store_T0_gpr(rA(ctx->opcode));
3663
    if (unlikely(Rc(ctx->opcode) != 0))
3664
        gen_set_Rc0(ctx);
3665
}
3666

    
3667
/* slliq - slliq. */
3668
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
3669
{
3670
    gen_op_load_gpr_T0(rS(ctx->opcode));
3671
    gen_op_set_T1(SH(ctx->opcode));
3672
    gen_op_POWER_sleq();
3673
    gen_op_store_T0_gpr(rA(ctx->opcode));
3674
    if (unlikely(Rc(ctx->opcode) != 0))
3675
        gen_set_Rc0(ctx);
3676
}
3677

    
3678
/* sllq - sllq. */
3679
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 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_sllq();
3684
    gen_op_store_T0_gpr(rA(ctx->opcode));
3685
    if (unlikely(Rc(ctx->opcode) != 0))
3686
        gen_set_Rc0(ctx);
3687
}
3688

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

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

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

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

    
3733
/* srea - srea. */
3734
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
3735
{
3736
    gen_op_load_gpr_T0(rS(ctx->opcode));
3737
    gen_op_load_gpr_T1(rB(ctx->opcode));
3738
    gen_op_POWER_srea();
3739
    gen_op_store_T0_gpr(rA(ctx->opcode));
3740
    if (unlikely(Rc(ctx->opcode) != 0))
3741
        gen_set_Rc0(ctx);
3742
}
3743

    
3744
/* sreq */
3745
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
3746
{
3747
    gen_op_load_gpr_T0(rS(ctx->opcode));
3748
    gen_op_load_gpr_T1(rB(ctx->opcode));
3749
    gen_op_POWER_sreq();
3750
    gen_op_store_T0_gpr(rA(ctx->opcode));
3751
    if (unlikely(Rc(ctx->opcode) != 0))
3752
        gen_set_Rc0(ctx);
3753
}
3754

    
3755
/* sriq */
3756
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
3757
{
3758
    gen_op_load_gpr_T0(rS(ctx->opcode));
3759
    gen_op_set_T1(SH(ctx->opcode));
3760
    gen_op_POWER_srq();
3761
    gen_op_store_T0_gpr(rA(ctx->opcode));
3762
    if (unlikely(Rc(ctx->opcode) != 0))
3763
        gen_set_Rc0(ctx);
3764
}
3765

    
3766
/* srliq */
3767
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
3768
{
3769
    gen_op_load_gpr_T0(rS(ctx->opcode));
3770
    gen_op_load_gpr_T1(rB(ctx->opcode));
3771
    gen_op_set_T1(SH(ctx->opcode));
3772
    gen_op_POWER_srlq();
3773
    gen_op_store_T0_gpr(rA(ctx->opcode));
3774
    if (unlikely(Rc(ctx->opcode) != 0))
3775
        gen_set_Rc0(ctx);
3776
}
3777

    
3778
/* srlq */
3779
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
3780
{
3781
    gen_op_load_gpr_T0(rS(ctx->opcode));
3782
    gen_op_load_gpr_T1(rB(ctx->opcode));
3783
    gen_op_POWER_srlq();
3784
    gen_op_store_T0_gpr(rA(ctx->opcode));
3785
    if (unlikely(Rc(ctx->opcode) != 0))
3786
        gen_set_Rc0(ctx);
3787
}
3788

    
3789
/* srq */
3790
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
3791
{
3792
    gen_op_load_gpr_T0(rS(ctx->opcode));
3793
    gen_op_load_gpr_T1(rB(ctx->opcode));
3794
    gen_op_POWER_srq();
3795
    gen_op_store_T0_gpr(rA(ctx->opcode));
3796
    if (unlikely(Rc(ctx->opcode) != 0))
3797
        gen_set_Rc0(ctx);
3798
}
3799

    
3800
/* PowerPC 602 specific instructions */
3801
/* dsa  */
3802
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
3803
{
3804
    /* XXX: TODO */
3805
    RET_INVAL(ctx);
3806
}
3807

    
3808
/* esa */
3809
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
3810
{
3811
    /* XXX: TODO */
3812
    RET_INVAL(ctx);
3813
}
3814

    
3815
/* mfrom */
3816
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
3817
{
3818
#if defined(CONFIG_USER_ONLY)
3819
    RET_PRIVOPC(ctx);
3820
#else
3821
    if (unlikely(!ctx->supervisor)) {
3822
        RET_PRIVOPC(ctx);
3823
        return;
3824
    }
3825
    gen_op_load_gpr_T0(rA(ctx->opcode));
3826
    gen_op_602_mfrom();
3827
    gen_op_store_T0_gpr(rD(ctx->opcode));
3828
#endif
3829
}
3830

    
3831
/* 602 - 603 - G2 TLB management */
3832
/* tlbld */
3833
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
3834
{
3835
#if defined(CONFIG_USER_ONLY)
3836
    RET_PRIVOPC(ctx);
3837
#else
3838
    if (unlikely(!ctx->supervisor)) {
3839
        RET_PRIVOPC(ctx);
3840
        return;
3841
    }
3842
    gen_op_load_gpr_T0(rB(ctx->opcode));
3843
    gen_op_6xx_tlbld();
3844
    RET_STOP(ctx);
3845
#endif
3846
}
3847

    
3848
/* tlbli */
3849
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
3850
{
3851
#if defined(CONFIG_USER_ONLY)
3852
    RET_PRIVOPC(ctx);
3853
#else
3854
    if (unlikely(!ctx->supervisor)) {
3855
        RET_PRIVOPC(ctx);
3856
        return;
3857
    }
3858
    gen_op_load_gpr_T0(rB(ctx->opcode));
3859
    gen_op_6xx_tlbli();
3860
    RET_STOP(ctx);
3861
#endif
3862
}
3863

    
3864
/* POWER instructions not in PowerPC 601 */
3865
/* clf */
3866
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
3867
{
3868
    /* Cache line flush: implemented as no-op */
3869
}
3870

    
3871
/* cli */
3872
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
3873
{
3874
    /* Cache line invalidate: priviledged and treated as no-op */
3875
#if defined(CONFIG_USER_ONLY)
3876
    RET_PRIVOPC(ctx);
3877
#else
3878
    if (unlikely(!ctx->supervisor)) {
3879
        RET_PRIVOPC(ctx);
3880
        return;
3881
    }
3882
#endif
3883
}
3884

    
3885
/* dclst */
3886
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
3887
{
3888
    /* Data cache line store: treated as no-op */
3889
}
3890

    
3891
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
3892
{
3893
#if defined(CONFIG_USER_ONLY)
3894
    RET_PRIVOPC(ctx);
3895
#else
3896
    if (unlikely(!ctx->supervisor)) {
3897
        RET_PRIVOPC(ctx);
3898
        return;
3899
    }
3900
    int ra = rA(ctx->opcode);
3901
    int rd = rD(ctx->opcode);
3902

    
3903
    gen_addr_reg_index(ctx);
3904
    gen_op_POWER_mfsri();
3905
    gen_op_store_T0_gpr(rd);
3906
    if (ra != 0 && ra != rd)
3907
        gen_op_store_T1_gpr(ra);
3908
#endif
3909
}
3910

    
3911
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
3912
{
3913
#if defined(CONFIG_USER_ONLY)
3914
    RET_PRIVOPC(ctx);
3915
#else
3916
    if (unlikely(!ctx->supervisor)) {
3917
        RET_PRIVOPC(ctx);
3918
        return;
3919
    }
3920
    gen_addr_reg_index(ctx);
3921
    gen_op_POWER_rac();
3922
    gen_op_store_T0_gpr(rD(ctx->opcode));
3923
#endif
3924
}
3925

    
3926
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
3927
{
3928
#if defined(CONFIG_USER_ONLY)
3929
    RET_PRIVOPC(ctx);
3930
#else
3931
    if (unlikely(!ctx->supervisor)) {
3932
        RET_PRIVOPC(ctx);
3933
        return;
3934
    }
3935
    gen_op_POWER_rfsvc();
3936
    RET_CHG_FLOW(ctx);
3937
#endif
3938
}
3939

    
3940
/* svc is not implemented for now */
3941

    
3942
/* POWER2 specific instructions */
3943
/* Quad manipulation (load/store two floats at a time) */
3944
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
3945
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
3946
#if defined(CONFIG_USER_ONLY)
3947
static GenOpFunc *gen_op_POWER2_lfq[] = {
3948
    &gen_op_POWER2_lfq_le_raw,
3949
    &gen_op_POWER2_lfq_raw,
3950
};
3951
static GenOpFunc *gen_op_POWER2_stfq[] = {
3952
    &gen_op_POWER2_stfq_le_raw,
3953
    &gen_op_POWER2_stfq_raw,
3954
};
3955
#else
3956
static GenOpFunc *gen_op_POWER2_lfq[] = {
3957
    &gen_op_POWER2_lfq_le_user,
3958
    &gen_op_POWER2_lfq_user,
3959
    &gen_op_POWER2_lfq_le_kernel,
3960
    &gen_op_POWER2_lfq_kernel,
3961
};
3962
static GenOpFunc *gen_op_POWER2_stfq[] = {
3963
    &gen_op_POWER2_stfq_le_user,
3964
    &gen_op_POWER2_stfq_user,
3965
    &gen_op_POWER2_stfq_le_kernel,
3966
    &gen_op_POWER2_stfq_kernel,
3967
};
3968
#endif
3969

    
3970
/* lfq */
3971
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3972
{
3973
    /* NIP cannot be restored if the memory exception comes from an helper */
3974
    gen_update_nip(ctx, ctx->nip - 4);
3975
    gen_addr_imm_index(ctx);
3976
    op_POWER2_lfq();
3977
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3978
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3979
}
3980

    
3981
/* lfqu */
3982
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3983
{
3984
    int ra = rA(ctx->opcode);
3985

    
3986
    /* NIP cannot be restored if the memory exception comes from an helper */
3987
    gen_update_nip(ctx, ctx->nip - 4);
3988
    gen_addr_imm_index(ctx);
3989
    op_POWER2_lfq();
3990
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3991
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3992
    if (ra != 0)
3993
        gen_op_store_T0_gpr(ra);
3994
}
3995

    
3996
/* lfqux */
3997
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
3998
{
3999
    int ra = rA(ctx->opcode);
4000

    
4001
    /* NIP cannot be restored if the memory exception comes from an helper */
4002
    gen_update_nip(ctx, ctx->nip - 4);
4003
    gen_addr_reg_index(ctx);
4004
    op_POWER2_lfq();
4005
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4006
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4007
    if (ra != 0)
4008
        gen_op_store_T0_gpr(ra);
4009
}
4010

    
4011
/* lfqx */
4012
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4013
{
4014
    /* NIP cannot be restored if the memory exception comes from an helper */
4015
    gen_update_nip(ctx, ctx->nip - 4);
4016
    gen_addr_reg_index(ctx);
4017
    op_POWER2_lfq();
4018
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4019
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4020
}
4021

    
4022
/* stfq */
4023
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4024
{
4025
    /* NIP cannot be restored if the memory exception comes from an helper */
4026
    gen_update_nip(ctx, ctx->nip - 4);
4027
    gen_addr_imm_index(ctx);
4028
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4029
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4030
    op_POWER2_stfq();
4031
}
4032

    
4033
/* stfqu */
4034
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4035
{
4036
    int ra = rA(ctx->opcode);
4037

    
4038
    /* NIP cannot be restored if the memory exception comes from an helper */
4039
    gen_update_nip(ctx, ctx->nip - 4);
4040
    gen_addr_imm_index(ctx);
4041
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4042
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4043
    op_POWER2_stfq();
4044
    if (ra != 0)
4045
        gen_op_store_T0_gpr(ra);
4046
}
4047

    
4048
/* stfqux */
4049
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4050
{
4051
    int ra = rA(ctx->opcode);
4052

    
4053
    /* NIP cannot be restored if the memory exception comes from an helper */
4054
    gen_update_nip(ctx, ctx->nip - 4);
4055
    gen_addr_reg_index(ctx);
4056
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4057
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4058
    op_POWER2_stfq();
4059
    if (ra != 0)
4060
        gen_op_store_T0_gpr(ra);
4061
}
4062

    
4063
/* stfqx */
4064
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4065
{
4066
    /* NIP cannot be restored if the memory exception comes from an helper */
4067
    gen_update_nip(ctx, ctx->nip - 4);
4068
    gen_addr_reg_index(ctx);
4069
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4070
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4071
    op_POWER2_stfq();
4072
}
4073

    
4074
/* BookE specific instructions */
4075
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE)
4076
{
4077
    /* XXX: TODO */
4078
    RET_INVAL(ctx);
4079
}
4080

    
4081
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE)
4082
{
4083
#if defined(CONFIG_USER_ONLY)
4084
    RET_PRIVOPC(ctx);
4085
#else
4086
    if (unlikely(!ctx->supervisor)) {
4087
        RET_PRIVOPC(ctx);
4088
        return;
4089
    }
4090
    gen_addr_reg_index(ctx);
4091
    /* Use the same micro-ops as for tlbie */
4092
#if defined(TARGET_PPC64)
4093
    if (ctx->sf_mode)
4094
        gen_op_tlbie_64();
4095
    else
4096
#endif
4097
        gen_op_tlbie();
4098
    RET_STOP(ctx);
4099
#endif
4100
}
4101

    
4102
/* All 405 MAC instructions are translated here */
4103
static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
4104
                                         int ra, int rb, int rt, int Rc)
4105
{
4106
    gen_op_load_gpr_T0(ra);
4107
    gen_op_load_gpr_T1(rb);
4108
    switch (opc3 & 0x0D) {
4109
    case 0x05:
4110
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4111
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4112
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4113
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4114
        /* mulchw - mulchw. */
4115
        gen_op_405_mulchw();
4116
        break;
4117
    case 0x04:
4118
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4119
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4120
        /* mulchwu - mulchwu. */
4121
        gen_op_405_mulchwu();
4122
        break;
4123
    case 0x01:
4124
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4125
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4126
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4127
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4128
        /* mulhhw - mulhhw. */
4129
        gen_op_405_mulhhw();
4130
        break;
4131
    case 0x00:
4132
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4133
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4134
        /* mulhhwu - mulhhwu. */
4135
        gen_op_405_mulhhwu();
4136
        break;
4137
    case 0x0D:
4138
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4139
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4140
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4141
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4142
        /* mullhw - mullhw. */
4143
        gen_op_405_mullhw();
4144
        break;
4145
    case 0x0C:
4146
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4147
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4148
        /* mullhwu - mullhwu. */
4149
        gen_op_405_mullhwu();
4150
        break;
4151
    }
4152
    if (opc2 & 0x02) {
4153
        /* nmultiply-and-accumulate (0x0E) */
4154
        gen_op_neg();
4155
    }
4156
    if (opc2 & 0x04) {
4157
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4158
        gen_op_load_gpr_T2(rt);
4159
        gen_op_move_T1_T0();
4160
        gen_op_405_add_T0_T2();
4161
    }
4162
    if (opc3 & 0x10) {
4163
        /* Check overflow */
4164
        if (opc3 & 0x01)
4165
            gen_op_405_check_ov();
4166
        else
4167
            gen_op_405_check_ovu();
4168
    }
4169
    if (opc3 & 0x02) {
4170
        /* Saturate */
4171
        if (opc3 & 0x01)
4172
            gen_op_405_check_sat();
4173
        else
4174
            gen_op_405_check_satu();
4175
    }
4176
    gen_op_store_T0_gpr(rt);
4177
    if (unlikely(Rc) != 0) {
4178
        /* Update Rc0 */
4179
        gen_set_Rc0(ctx);
4180
    }
4181
}
4182

    
4183
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4184
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4185
{                                                                             \
4186
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4187
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4188
}
4189

    
4190
/* macchw    - macchw.    */
4191
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4192
/* macchwo   - macchwo.   */
4193
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4194
/* macchws   - macchws.   */
4195
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4196
/* macchwso  - macchwso.  */
4197
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4198
/* macchwsu  - macchwsu.  */
4199
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4200
/* macchwsuo - macchwsuo. */
4201
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4202
/* macchwu   - macchwu.   */
4203
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4204
/* macchwuo  - macchwuo.  */
4205
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4206
/* machhw    - machhw.    */
4207
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4208
/* machhwo   - machhwo.   */
4209
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4210
/* machhws   - machhws.   */
4211
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4212
/* machhwso  - machhwso.  */
4213
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4214
/* machhwsu  - machhwsu.  */
4215
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4216
/* machhwsuo - machhwsuo. */
4217
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4218
/* machhwu   - machhwu.   */
4219
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4220
/* machhwuo  - machhwuo.  */
4221
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4222
/* maclhw    - maclhw.    */
4223
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4224
/* maclhwo   - maclhwo.   */
4225
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4226
/* maclhws   - maclhws.   */
4227
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4228
/* maclhwso  - maclhwso.  */
4229
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4230
/* maclhwu   - maclhwu.   */
4231
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4232
/* maclhwuo  - maclhwuo.  */
4233
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4234
/* maclhwsu  - maclhwsu.  */
4235
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4236
/* maclhwsuo - maclhwsuo. */
4237
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4238
/* nmacchw   - nmacchw.   */
4239
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4240
/* nmacchwo  - nmacchwo.  */
4241
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4242
/* nmacchws  - nmacchws.  */
4243
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4244
/* nmacchwso - nmacchwso. */
4245
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4246
/* nmachhw   - nmachhw.   */
4247
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4248
/* nmachhwo  - nmachhwo.  */
4249
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4250
/* nmachhws  - nmachhws.  */
4251
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4252
/* nmachhwso - nmachhwso. */
4253
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4254
/* nmaclhw   - nmaclhw.   */
4255
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4256
/* nmaclhwo  - nmaclhwo.  */
4257
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4258
/* nmaclhws  - nmaclhws.  */
4259
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4260
/* nmaclhwso - nmaclhwso. */
4261
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4262

    
4263
/* mulchw  - mulchw.  */
4264
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4265
/* mulchwu - mulchwu. */
4266
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4267
/* mulhhw  - mulhhw.  */
4268
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4269
/* mulhhwu - mulhhwu. */
4270
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4271
/* mullhw  - mullhw.  */
4272
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4273
/* mullhwu - mullhwu. */
4274
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4275

    
4276
/* mfdcr */
4277
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4278
{
4279
#if defined(CONFIG_USER_ONLY)
4280
    RET_PRIVREG(ctx);
4281
#else
4282
    uint32_t dcrn = SPR(ctx->opcode);
4283

    
4284
    if (unlikely(!ctx->supervisor)) {
4285
        RET_PRIVREG(ctx);
4286
        return;
4287
    }
4288
    gen_op_4xx_load_dcr(dcrn);
4289
    gen_op_store_T0_gpr(rD(ctx->opcode));
4290
#endif
4291
}
4292

    
4293
/* mtdcr */
4294
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4295
{
4296
#if defined(CONFIG_USER_ONLY)
4297
    RET_PRIVREG(ctx);
4298
#else
4299
    uint32_t dcrn = SPR(ctx->opcode);
4300

    
4301
    if (unlikely(!ctx->supervisor)) {
4302
        RET_PRIVREG(ctx);
4303
        return;
4304
    }
4305
    gen_op_load_gpr_T0(rS(ctx->opcode));
4306
    gen_op_4xx_store_dcr(dcrn);
4307
#endif
4308
}
4309

    
4310
/* dccci */
4311
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4312
{
4313
#if defined(CONFIG_USER_ONLY)
4314
    RET_PRIVOPC(ctx);
4315
#else
4316
    if (unlikely(!ctx->supervisor)) {
4317
        RET_PRIVOPC(ctx);
4318
        return;
4319
    }
4320
    /* interpreted as no-op */
4321
#endif
4322
}
4323

    
4324
/* dcread */
4325
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4326
{
4327
#if defined(CONFIG_USER_ONLY)
4328
    RET_PRIVOPC(ctx);
4329
#else
4330
    if (unlikely(!ctx->supervisor)) {
4331
        RET_PRIVOPC(ctx);
4332
        return;
4333
    }
4334
    gen_addr_reg_index(ctx);
4335
    op_ldst(lwz);
4336
    gen_op_store_T0_gpr(rD(ctx->opcode));
4337
#endif
4338
}
4339

    
4340
/* icbt */
4341
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC)
4342
{
4343
    /* interpreted as no-op */
4344
    /* XXX: specification say this is treated as a load by the MMU
4345
     *      but does not generate any exception
4346
     */
4347
}
4348

    
4349
/* iccci */
4350
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4351
{
4352
#if defined(CONFIG_USER_ONLY)
4353
    RET_PRIVOPC(ctx);
4354
#else
4355
    if (unlikely(!ctx->supervisor)) {
4356
        RET_PRIVOPC(ctx);
4357
        return;
4358
    }
4359
    /* interpreted as no-op */
4360
#endif
4361
}
4362

    
4363
/* icread */
4364
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4365
{
4366
#if defined(CONFIG_USER_ONLY)
4367
    RET_PRIVOPC(ctx);
4368
#else
4369
    if (unlikely(!ctx->supervisor)) {
4370
        RET_PRIVOPC(ctx);
4371
        return;
4372
    }
4373
    /* interpreted as no-op */
4374
#endif
4375
}
4376

    
4377
/* rfci (supervisor only) */
4378
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_EMB_COMMON)
4379
{
4380
#if defined(CONFIG_USER_ONLY)
4381
    RET_PRIVOPC(ctx);
4382
#else
4383
    if (unlikely(!ctx->supervisor)) {
4384
        RET_PRIVOPC(ctx);
4385
        return;
4386
    }
4387
    /* Restore CPU state */
4388
    gen_op_4xx_rfci();
4389
    RET_CHG_FLOW(ctx);
4390
#endif
4391
}
4392

    
4393
/* TLB management - PowerPC 405 implementation */
4394
/* tlbre */
4395
GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_EMB_COMMON)
4396
{
4397
#if defined(CONFIG_USER_ONLY)
4398
    RET_PRIVOPC(ctx);
4399
#else
4400
    if (unlikely(!ctx->supervisor)) {
4401
        RET_PRIVOPC(ctx);
4402
        return;
4403
    }
4404
    switch (rB(ctx->opcode)) {
4405
    case 0:
4406
        gen_op_load_gpr_T0(rA(ctx->opcode));
4407
        gen_op_4xx_tlbre_hi();
4408
        gen_op_store_T0_gpr(rD(ctx->opcode));
4409
        break;
4410
    case 1:
4411
        gen_op_load_gpr_T0(rA(ctx->opcode));
4412
        gen_op_4xx_tlbre_lo();
4413
        gen_op_store_T0_gpr(rD(ctx->opcode));
4414
        break;
4415
    default:
4416
        RET_INVAL(ctx);
4417
        break;
4418
    }
4419
#endif
4420
}
4421

    
4422
/* tlbsx - tlbsx. */
4423
GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_EMB_COMMON)
4424
{
4425
#if defined(CONFIG_USER_ONLY)
4426
    RET_PRIVOPC(ctx);
4427
#else
4428
    if (unlikely(!ctx->supervisor)) {
4429
        RET_PRIVOPC(ctx);
4430
        return;
4431
    }
4432
    gen_addr_reg_index(ctx);
4433
    if (Rc(ctx->opcode))
4434
        gen_op_4xx_tlbsx_();
4435
    else
4436
        gen_op_4xx_tlbsx();
4437
    gen_op_store_T0_gpr(rD(ctx->opcode));
4438
#endif
4439
}
4440

    
4441
/* tlbwe */
4442
GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC)
4443
{
4444
#if defined(CONFIG_USER_ONLY)
4445
    RET_PRIVOPC(ctx);
4446
#else
4447
    if (unlikely(!ctx->supervisor)) {
4448
        RET_PRIVOPC(ctx);
4449
        return;
4450
    }
4451
    switch (rB(ctx->opcode)) {
4452
    case 0:
4453
        gen_op_load_gpr_T0(rA(ctx->opcode));
4454
        gen_op_load_gpr_T1(rS(ctx->opcode));
4455
        gen_op_4xx_tlbwe_hi();
4456
        break;
4457
    case 1:
4458
        gen_op_load_gpr_T0(rA(ctx->opcode));
4459
        gen_op_load_gpr_T1(rS(ctx->opcode));
4460
        gen_op_4xx_tlbwe_lo();
4461
        break;
4462
    default:
4463
        RET_INVAL(ctx);
4464
        break;
4465
    }
4466
#endif
4467
}
4468

    
4469
/* wrtee */
4470
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4471
{
4472
#if defined(CONFIG_USER_ONLY)
4473
    RET_PRIVOPC(ctx);
4474
#else
4475
    if (unlikely(!ctx->supervisor)) {
4476
        RET_PRIVOPC(ctx);
4477
        return;
4478
    }
4479
    gen_op_load_gpr_T0(rD(ctx->opcode));
4480
    gen_op_4xx_wrte();
4481
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4482
#endif
4483
}
4484

    
4485
/* wrteei */
4486
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4487
{
4488
#if defined(CONFIG_USER_ONLY)
4489
    RET_PRIVOPC(ctx);
4490
#else
4491
    if (unlikely(!ctx->supervisor)) {
4492
        RET_PRIVOPC(ctx);
4493
        return;
4494
    }
4495
    gen_op_set_T0(ctx->opcode & 0x00010000);
4496
    gen_op_4xx_wrte();
4497
    RET_EXCP(ctx, EXCP_MTMSR, 0);
4498
#endif
4499
}
4500

    
4501
/* PPC 440 specific instructions */
4502
/* dlmzb */
4503
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
4504
{
4505
    gen_op_load_gpr_T0(rS(ctx->opcode));
4506
    gen_op_load_gpr_T1(rB(ctx->opcode));
4507
    gen_op_440_dlmzb();
4508
    gen_op_store_T0_gpr(rA(ctx->opcode));
4509
    gen_op_store_xer_bc();
4510
    if (Rc(ctx->opcode)) {
4511
        gen_op_440_dlmzb_update_Rc();
4512
        gen_op_store_T0_crf(0);
4513
    }
4514
}
4515

    
4516
/* mbar replaces eieio on 440 */
4517
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
4518
{
4519
    /* interpreted as no-op */
4520
}
4521

    
4522
/* msync replaces sync on 440 */
4523
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
4524
{
4525
    /* interpreted as no-op */
4526
}
4527

    
4528
/* icbt */
4529
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
4530
{
4531
    /* interpreted as no-op */
4532
    /* XXX: specification say this is treated as a load by the MMU
4533
     *      but does not generate any exception
4534
     */
4535
}
4536

    
4537
#if defined(TARGET_PPCSPE)
4538
/***                           SPE extension                               ***/
4539

    
4540
/* Register moves */
4541
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
4542
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
4543
#if 0 // unused
4544
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
4545
#endif
4546

    
4547
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
4548
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
4549
#if 0 // unused
4550
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
4551
#endif
4552

    
4553
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
4554
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
4555
{                                                                             \
4556
    if (Rc(ctx->opcode))                                                      \
4557
        gen_##name1(ctx);                                                     \
4558
    else                                                                      \
4559
        gen_##name0(ctx);                                                     \
4560
}
4561

    
4562
/* Handler for undefined SPE opcodes */
4563
static inline void gen_speundef (DisasContext *ctx)
4564
{
4565
    RET_INVAL(ctx);
4566
}
4567

    
4568
/* SPE load and stores */
4569
static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
4570
{
4571
    target_long simm = rB(ctx->opcode);
4572

    
4573
    if (rA(ctx->opcode) == 0) {
4574
        gen_set_T0(simm << sh);
4575
    } else {
4576
        gen_op_load_gpr_T0(rA(ctx->opcode));
4577
        if (likely(simm != 0))
4578
            gen_op_addi(simm << sh);
4579
    }
4580
}
4581

    
4582
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
4583
#if defined(CONFIG_USER_ONLY)
4584
#if defined(TARGET_PPC64)
4585
#define OP_SPE_LD_TABLE(name)                                                 \
4586
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4587
    &gen_op_spe_l##name##_raw,                                                \
4588
    &gen_op_spe_l##name##_le_raw,                                             \
4589
    &gen_op_spe_l##name##_64_raw,                                             \
4590
    &gen_op_spe_l##name##_le_64_raw,                                          \
4591
};
4592
#define OP_SPE_ST_TABLE(name)                                                 \
4593
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4594
    &gen_op_spe_st##name##_raw,                                               \
4595
    &gen_op_spe_st##name##_le_raw,                                            \
4596
    &gen_op_spe_st##name##_64_raw,                                            \
4597
    &gen_op_spe_st##name##_le_64_raw,                                         \
4598
};
4599
#else /* defined(TARGET_PPC64) */
4600
#define OP_SPE_LD_TABLE(name)                                                 \
4601
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4602
    &gen_op_spe_l##name##_raw,                                                \
4603
    &gen_op_spe_l##name##_le_raw,                                             \
4604
};
4605
#define OP_SPE_ST_TABLE(name)                                                 \
4606
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4607
    &gen_op_spe_st##name##_raw,                                               \
4608
    &gen_op_spe_st##name##_le_raw,                                            \
4609
};
4610
#endif /* defined(TARGET_PPC64) */
4611
#else /* defined(CONFIG_USER_ONLY) */
4612
#if defined(TARGET_PPC64)
4613
#define OP_SPE_LD_TABLE(name)                                                 \
4614
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4615
    &gen_op_spe_l##name##_user,                                               \
4616
    &gen_op_spe_l##name##_le_user,                                            \
4617
    &gen_op_spe_l##name##_kernel,                                             \
4618
    &gen_op_spe_l##name##_le_kernel,                                          \
4619
    &gen_op_spe_l##name##_64_user,                                            \
4620
    &gen_op_spe_l##name##_le_64_user,                                         \
4621
    &gen_op_spe_l##name##_64_kernel,                                          \
4622
    &gen_op_spe_l##name##_le_64_kernel,                                       \
4623
};
4624
#define OP_SPE_ST_TABLE(name)                                                 \
4625
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4626
    &gen_op_spe_st##name##_user,                                              \
4627
    &gen_op_spe_st##name##_le_user,                                           \
4628
    &gen_op_spe_st##name##_kernel,                                            \
4629
    &gen_op_spe_st##name##_le_kernel,                                         \
4630
    &gen_op_spe_st##name##_64_user,                                           \
4631
    &gen_op_spe_st##name##_le_64_user,                                        \
4632
    &gen_op_spe_st##name##_64_kernel,                                         \
4633
    &gen_op_spe_st##name##_le_64_kernel,                                      \
4634
};
4635
#else /* defined(TARGET_PPC64) */
4636
#define OP_SPE_LD_TABLE(name)                                                 \
4637
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
4638
    &gen_op_spe_l##name##_user,                                               \
4639
    &gen_op_spe_l##name##_le_user,                                            \
4640
    &gen_op_spe_l##name##_kernel,                                             \
4641
    &gen_op_spe_l##name##_le_kernel,                                          \
4642
};
4643
#define OP_SPE_ST_TABLE(name)                                                 \
4644
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
4645
    &gen_op_spe_st##name##_user,                                              \
4646
    &gen_op_spe_st##name##_le_user,                                           \
4647
    &gen_op_spe_st##name##_kernel,                                            \
4648
    &gen_op_spe_st##name##_le_kernel,                                         \
4649
};
4650
#endif /* defined(TARGET_PPC64) */
4651
#endif /* defined(CONFIG_USER_ONLY) */
4652

    
4653
#define GEN_SPE_LD(name, sh)                                                  \
4654
static inline void gen_evl##name (DisasContext *ctx)                          \
4655
{                                                                             \
4656
    if (unlikely(!ctx->spe_enabled)) {                                        \
4657
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4658
        return;                                                               \
4659
    }                                                                         \
4660
    gen_addr_spe_imm_index(ctx, sh);                                          \
4661
    op_spe_ldst(spe_l##name);                                                 \
4662
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
4663
}
4664

    
4665
#define GEN_SPE_LDX(name)                                                     \
4666
static inline void gen_evl##name##x (DisasContext *ctx)                       \
4667
{                                                                             \
4668
    if (unlikely(!ctx->spe_enabled)) {                                        \
4669
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4670
        return;                                                               \
4671
    }                                                                         \
4672
    gen_addr_reg_index(ctx);                                                  \
4673
    op_spe_ldst(spe_l##name);                                                 \
4674
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
4675
}
4676

    
4677
#define GEN_SPEOP_LD(name, sh)                                                \
4678
OP_SPE_LD_TABLE(name);                                                        \
4679
GEN_SPE_LD(name, sh);                                                         \
4680
GEN_SPE_LDX(name)
4681

    
4682
#define GEN_SPE_ST(name, sh)                                                  \
4683
static inline void gen_evst##name (DisasContext *ctx)                         \
4684
{                                                                             \
4685
    if (unlikely(!ctx->spe_enabled)) {                                        \
4686
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4687
        return;                                                               \
4688
    }                                                                         \
4689
    gen_addr_spe_imm_index(ctx, sh);                                          \
4690
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
4691
    op_spe_ldst(spe_st##name);                                                \
4692
}
4693

    
4694
#define GEN_SPE_STX(name)                                                     \
4695
static inline void gen_evst##name##x (DisasContext *ctx)                      \
4696
{                                                                             \
4697
    if (unlikely(!ctx->spe_enabled)) {                                        \
4698
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4699
        return;                                                               \
4700
    }                                                                         \
4701
    gen_addr_reg_index(ctx);                                                  \
4702
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
4703
    op_spe_ldst(spe_st##name);                                                \
4704
}
4705

    
4706
#define GEN_SPEOP_ST(name, sh)                                                \
4707
OP_SPE_ST_TABLE(name);                                                        \
4708
GEN_SPE_ST(name, sh);                                                         \
4709
GEN_SPE_STX(name)
4710

    
4711
#define GEN_SPEOP_LDST(name, sh)                                              \
4712
GEN_SPEOP_LD(name, sh);                                                       \
4713
GEN_SPEOP_ST(name, sh)
4714

    
4715
/* SPE arithmetic and logic */
4716
#define GEN_SPEOP_ARITH2(name)                                                \
4717
static inline void gen_##name (DisasContext *ctx)                             \
4718
{                                                                             \
4719
    if (unlikely(!ctx->spe_enabled)) {                                        \
4720
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4721
        return;                                                               \
4722
    }                                                                         \
4723
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
4724
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
4725
    gen_op_##name();                                                          \
4726
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
4727
}
4728

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

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

    
4754
/* Logical */
4755
GEN_SPEOP_ARITH2(evand);
4756
GEN_SPEOP_ARITH2(evandc);
4757
GEN_SPEOP_ARITH2(evxor);
4758
GEN_SPEOP_ARITH2(evor);
4759
GEN_SPEOP_ARITH2(evnor);
4760
GEN_SPEOP_ARITH2(eveqv);
4761
GEN_SPEOP_ARITH2(evorc);
4762
GEN_SPEOP_ARITH2(evnand);
4763
GEN_SPEOP_ARITH2(evsrwu);
4764
GEN_SPEOP_ARITH2(evsrws);
4765
GEN_SPEOP_ARITH2(evslw);
4766
GEN_SPEOP_ARITH2(evrlw);
4767
GEN_SPEOP_ARITH2(evmergehi);
4768
GEN_SPEOP_ARITH2(evmergelo);
4769
GEN_SPEOP_ARITH2(evmergehilo);
4770
GEN_SPEOP_ARITH2(evmergelohi);
4771

    
4772
/* Arithmetic */
4773
GEN_SPEOP_ARITH2(evaddw);
4774
GEN_SPEOP_ARITH2(evsubfw);
4775
GEN_SPEOP_ARITH1(evabs);
4776
GEN_SPEOP_ARITH1(evneg);
4777
GEN_SPEOP_ARITH1(evextsb);
4778
GEN_SPEOP_ARITH1(evextsh);
4779
GEN_SPEOP_ARITH1(evrndw);
4780
GEN_SPEOP_ARITH1(evcntlzw);
4781
GEN_SPEOP_ARITH1(evcntlsw);
4782
static inline void gen_brinc (DisasContext *ctx)
4783
{
4784
    /* Note: brinc is usable even if SPE is disabled */
4785
    gen_op_load_gpr64_T0(rA(ctx->opcode));
4786
    gen_op_load_gpr64_T1(rB(ctx->opcode));
4787
    gen_op_brinc();
4788
    gen_op_store_T0_gpr64(rD(ctx->opcode));
4789
}
4790

    
4791
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
4792
static inline void gen_##name##i (DisasContext *ctx)                          \
4793
{                                                                             \
4794
    if (unlikely(!ctx->spe_enabled)) {                                        \
4795
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4796
        return;                                                               \
4797
    }                                                                         \
4798
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
4799
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
4800
    gen_op_##name();                                                          \
4801
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
4802
}
4803

    
4804
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
4805
static inline void gen_##name##i (DisasContext *ctx)                          \
4806
{                                                                             \
4807
    if (unlikely(!ctx->spe_enabled)) {                                        \
4808
        RET_EXCP(ctx, EXCP_NO_SPE, 0);                                        \
4809
        return;                                                               \
4810
    }                                                                         \
4811
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
4812
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
4813
    gen_op_##name();                                                          \
4814
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
4815
}
4816

    
4817
GEN_SPEOP_ARITH_IMM2(evaddw);
4818
#define gen_evaddiw gen_evaddwi
4819
GEN_SPEOP_ARITH_IMM2(evsubfw);
4820
#define gen_evsubifw gen_evsubfwi
4821
GEN_SPEOP_LOGIC_IMM2(evslw);
4822
GEN_SPEOP_LOGIC_IMM2(evsrwu);
4823
#define gen_evsrwis gen_evsrwsi
4824
GEN_SPEOP_LOGIC_IMM2(evsrws);
4825
#define gen_evsrwiu gen_evsrwui
4826
GEN_SPEOP_LOGIC_IMM2(evrlw);
4827

    
4828
static inline void gen_evsplati (DisasContext *ctx)
4829
{
4830
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
4831

    
4832
    gen_op_splatwi_T0_64(imm);
4833
    gen_op_store_T0_gpr64(rD(ctx->opcode));
4834
}
4835

    
4836
static inline void gen_evsplatfi (DisasContext *ctx)
4837
{
4838
    uint32_t imm = rA(ctx->opcode) << 27;
4839

    
4840
    gen_op_splatwi_T0_64(imm);
4841
    gen_op_store_T0_gpr64(rD(ctx->opcode));
4842
}
4843

    
4844
/* Comparison */
4845
GEN_SPEOP_COMP(evcmpgtu);
4846
GEN_SPEOP_COMP(evcmpgts);
4847
GEN_SPEOP_COMP(evcmpltu);
4848
GEN_SPEOP_COMP(evcmplts);
4849
GEN_SPEOP_COMP(evcmpeq);
4850

    
4851
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
4852
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
4853
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
4854
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
4855
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
4856
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
4857
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
4858
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
4859
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
4860
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
4861
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
4862
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
4863
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
4864
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
4865
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
4866
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
4867
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
4868
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
4869
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
4870
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
4871
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
4872
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
4873
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
4874
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
4875
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
4876

    
4877
static inline void gen_evsel (DisasContext *ctx)
4878
{
4879
    if (unlikely(!ctx->spe_enabled)) {
4880
        RET_EXCP(ctx, EXCP_NO_SPE, 0);
4881
        return;
4882
    }
4883
    gen_op_load_crf_T0(ctx->opcode & 0x7);
4884
    gen_op_load_gpr64_T0(rA(ctx->opcode));
4885
    gen_op_load_gpr64_T1(rB(ctx->opcode));
4886
    gen_op_evsel();
4887
    gen_op_store_T0_gpr64(rD(ctx->opcode));
4888
}
4889

    
4890
GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
4891
{
4892
    gen_evsel(ctx);
4893
}
4894
GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
4895
{
4896
    gen_evsel(ctx);
4897
}
4898
GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
4899
{
4900
    gen_evsel(ctx);
4901
}
4902
GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
4903
{
4904
    gen_evsel(ctx);
4905
}
4906

    
4907
/* Load and stores */
4908
#if defined(TARGET_PPC64)
4909
/* In that case, we already have 64 bits load & stores
4910
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
4911
 */
4912
#if defined(CONFIG_USER_ONLY)
4913
#define gen_op_spe_ldd_raw gen_op_ld_raw
4914
#define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
4915
#define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
4916
#define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
4917
#define gen_op_spe_stdd_raw gen_op_ld_raw
4918
#define gen_op_spe_stdd_64_raw gen_op_std_64_raw
4919
#define gen_op_spe_stdd_le_raw gen_op_std_le_raw
4920
#define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
4921
#else /* defined(CONFIG_USER_ONLY) */
4922
#define gen_op_spe_ldd_kernel gen_op_ld_kernel
4923
#define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
4924
#define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
4925
#define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
4926
#define gen_op_spe_ldd_user gen_op_ld_user
4927
#define gen_op_spe_ldd_64_user gen_op_ld_64_user
4928
#define gen_op_spe_ldd_le_user gen_op_ld_le_user
4929
#define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
4930
#define gen_op_spe_stdd_kernel gen_op_std_kernel
4931
#define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
4932
#define gen_op_spe_stdd_le_kernel gen_op_std_kernel
4933
#define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
4934
#define gen_op_spe_stdd_user gen_op_std_user
4935
#define gen_op_spe_stdd_64_user gen_op_std_64_user
4936
#define gen_op_spe_stdd_le_user gen_op_std_le_user
4937
#define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
4938
#endif /* defined(CONFIG_USER_ONLY) */
4939
#endif /* defined(TARGET_PPC64) */
4940
GEN_SPEOP_LDST(dd, 3);
4941
GEN_SPEOP_LDST(dw, 3);
4942
GEN_SPEOP_LDST(dh, 3);
4943
GEN_SPEOP_LDST(whe, 2);
4944
GEN_SPEOP_LD(whou, 2);
4945
GEN_SPEOP_LD(whos, 2);
4946
GEN_SPEOP_ST(who, 2);
4947

    
4948
#if defined(TARGET_PPC64)
4949
/* In that case, spe_stwwo is equivalent to stw */
4950
#if defined(CONFIG_USER_ONLY)
4951
#define gen_op_spe_stwwo_raw gen_op_stw_raw
4952
#define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
4953
#define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
4954
#define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
4955
#else
4956
#define gen_op_spe_stwwo_user gen_op_stw_user
4957
#define gen_op_spe_stwwo_le_user gen_op_stw_le_user
4958
#define gen_op_spe_stwwo_64_user gen_op_stw_64_user
4959
#define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
4960
#define gen_op_spe_stwwo_kernel gen_op_stw_kernel
4961
#define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
4962
#define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
4963
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
4964
#endif
4965
#endif
4966
#define _GEN_OP_SPE_STWWE(suffix)                                             \
4967
static inline void gen_op_spe_stwwe_##suffix (void)                           \
4968
{                                                                             \
4969
    gen_op_srli32_T1_64();                                                    \
4970
    gen_op_spe_stwwo_##suffix();                                              \
4971
}
4972
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
4973
static inline void gen_op_spe_stwwe_le_##suffix (void)                        \
4974
{                                                                             \
4975
    gen_op_srli32_T1_64();                                                    \
4976
    gen_op_spe_stwwo_le_##suffix();                                           \
4977
}
4978
#if defined(TARGET_PPC64)
4979
#define GEN_OP_SPE_STWWE(suffix)                                              \
4980
_GEN_OP_SPE_STWWE(suffix);                                                    \
4981
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
4982
static inline void gen_op_spe_stwwe_64_##suffix (void)                        \
4983
{                                                                             \
4984
    gen_op_srli32_T1_64();                                                    \
4985
    gen_op_spe_stwwo_64_##suffix();                                           \
4986
}                                                                             \
4987
static inline void gen_op_spe_stwwe_le_64_##suffix (void)                     \
4988
{                                                                             \
4989
    gen_op_srli32_T1_64();                                                    \
4990
    gen_op_spe_stwwo_le_64_##suffix();                                        \
4991
}
4992
#else
4993
#define GEN_OP_SPE_STWWE(suffix)                                              \
4994
_GEN_OP_SPE_STWWE(suffix);                                                    \
4995
_GEN_OP_SPE_STWWE_LE(suffix)
4996
#endif
4997
#if defined(CONFIG_USER_ONLY)
4998
GEN_OP_SPE_STWWE(raw);
4999
#else /* defined(CONFIG_USER_ONLY) */
5000
GEN_OP_SPE_STWWE(kernel);
5001
GEN_OP_SPE_STWWE(user);
5002
#endif /* defined(CONFIG_USER_ONLY) */
5003
GEN_SPEOP_ST(wwe, 2);
5004
GEN_SPEOP_ST(wwo, 2);
5005

    
5006
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5007
static inline void gen_op_spe_l##name##_##suffix (void)                       \
5008
{                                                                             \
5009
    gen_op_##op##_##suffix();                                                 \
5010
    gen_op_splatw_T1_64();                                                    \
5011
}
5012

    
5013
#define GEN_OP_SPE_LHE(suffix)                                                \
5014
static inline void gen_op_spe_lhe_##suffix (void)                             \
5015
{                                                                             \
5016
    gen_op_spe_lh_##suffix();                                                 \
5017
    gen_op_sli16_T1_64();                                                     \
5018
}
5019

    
5020
#define GEN_OP_SPE_LHX(suffix)                                                \
5021
static inline void gen_op_spe_lhx_##suffix (void)                             \
5022
{                                                                             \
5023
    gen_op_spe_lh_##suffix();                                                 \
5024
    gen_op_extsh_T1_64();                                                     \
5025
}
5026

    
5027
#if defined(CONFIG_USER_ONLY)
5028
GEN_OP_SPE_LHE(raw);
5029
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5030
GEN_OP_SPE_LHE(le_raw);
5031
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5032
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5033
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5034
GEN_OP_SPE_LHX(raw);
5035
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5036
GEN_OP_SPE_LHX(le_raw);
5037
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5038
#if defined(TARGET_PPC64)
5039
GEN_OP_SPE_LHE(64_raw);
5040
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5041
GEN_OP_SPE_LHE(le_64_raw);
5042
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5043
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5044
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5045
GEN_OP_SPE_LHX(64_raw);
5046
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5047
GEN_OP_SPE_LHX(le_64_raw);
5048
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5049
#endif
5050
#else
5051
GEN_OP_SPE_LHE(kernel);
5052
GEN_OP_SPE_LHE(user);
5053
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5054
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5055
GEN_OP_SPE_LHE(le_kernel);
5056
GEN_OP_SPE_LHE(le_user);
5057
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5058
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5059
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5060
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5061
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5062
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5063
GEN_OP_SPE_LHX(kernel);
5064
GEN_OP_SPE_LHX(user);
5065
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5066
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5067
GEN_OP_SPE_LHX(le_kernel);
5068
GEN_OP_SPE_LHX(le_user);
5069
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5070
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5071
#if defined(TARGET_PPC64)
5072
GEN_OP_SPE_LHE(64_kernel);
5073
GEN_OP_SPE_LHE(64_user);
5074
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5075
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5076
GEN_OP_SPE_LHE(le_64_kernel);
5077
GEN_OP_SPE_LHE(le_64_user);
5078
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5079
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5080
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5081
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5082
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5083
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5084
GEN_OP_SPE_LHX(64_kernel);
5085
GEN_OP_SPE_LHX(64_user);
5086
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5087
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5088
GEN_OP_SPE_LHX(le_64_kernel);
5089
GEN_OP_SPE_LHX(le_64_user);
5090
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5091
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5092
#endif
5093
#endif
5094
GEN_SPEOP_LD(hhesplat, 1);
5095
GEN_SPEOP_LD(hhousplat, 1);
5096
GEN_SPEOP_LD(hhossplat, 1);
5097
GEN_SPEOP_LD(wwsplat, 2);
5098
GEN_SPEOP_LD(whsplat, 2);
5099

    
5100
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5101
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5102
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5103
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5104
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5105
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5106
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5107
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5108
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5109
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5110
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5111
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5112
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5113
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5114
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5115
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5116
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5117
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5118

    
5119
/* Multiply and add - TODO */
5120
#if 0
5121
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5122
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5123
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5124
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5125
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5126
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5127
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5128
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5129
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5130
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5131
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5132
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5133

5134
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5135
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5136
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5137
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5138
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5139
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5140
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5141
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5142
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5143
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5144
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5145
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5146
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5147
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5148

5149
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5150
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5151
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5152
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5153
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5154
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5155

5156
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5157
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5158
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5159
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5160
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5161
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5162
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5163
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5164
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5165
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5166
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5167
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5168

5169
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5170
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5171
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5172
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5173
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5174

5175
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5176
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5177
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5178
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5179
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5180
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5181
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5182
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5183
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5184
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5185
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5186
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5187

5188
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5189
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5190
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5191
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5192
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5193
#endif
5194

    
5195
/***                      SPE floating-point extension                     ***/
5196
#define GEN_SPEFPUOP_CONV(name)                                               \
5197
static inline void gen_##name (DisasContext *ctx)                             \
5198
{                                                                             \
5199
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5200
    gen_op_##name();                                                          \
5201
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5202
}
5203

    
5204
/* Single precision floating-point vectors operations */
5205
/* Arithmetic */
5206
GEN_SPEOP_ARITH2(evfsadd);
5207
GEN_SPEOP_ARITH2(evfssub);
5208
GEN_SPEOP_ARITH2(evfsmul);
5209
GEN_SPEOP_ARITH2(evfsdiv);
5210
GEN_SPEOP_ARITH1(evfsabs);
5211
GEN_SPEOP_ARITH1(evfsnabs);
5212
GEN_SPEOP_ARITH1(evfsneg);
5213
/* Conversion */
5214
GEN_SPEFPUOP_CONV(evfscfui);
5215
GEN_SPEFPUOP_CONV(evfscfsi);
5216
GEN_SPEFPUOP_CONV(evfscfuf);
5217
GEN_SPEFPUOP_CONV(evfscfsf);
5218
GEN_SPEFPUOP_CONV(evfsctui);
5219
GEN_SPEFPUOP_CONV(evfsctsi);
5220
GEN_SPEFPUOP_CONV(evfsctuf);
5221
GEN_SPEFPUOP_CONV(evfsctsf);
5222
GEN_SPEFPUOP_CONV(evfsctuiz);
5223
GEN_SPEFPUOP_CONV(evfsctsiz);
5224
/* Comparison */
5225
GEN_SPEOP_COMP(evfscmpgt);
5226
GEN_SPEOP_COMP(evfscmplt);
5227
GEN_SPEOP_COMP(evfscmpeq);
5228
GEN_SPEOP_COMP(evfststgt);
5229
GEN_SPEOP_COMP(evfststlt);
5230
GEN_SPEOP_COMP(evfststeq);
5231

    
5232
/* Opcodes definitions */
5233
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5234
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5235
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5236
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5237
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5238
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5239
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5240
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5241
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5242
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5243
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5244
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5245
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5246
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5247

    
5248
/* Single precision floating-point operations */
5249
/* Arithmetic */
5250
GEN_SPEOP_ARITH2(efsadd);
5251
GEN_SPEOP_ARITH2(efssub);
5252
GEN_SPEOP_ARITH2(efsmul);
5253
GEN_SPEOP_ARITH2(efsdiv);
5254
GEN_SPEOP_ARITH1(efsabs);
5255
GEN_SPEOP_ARITH1(efsnabs);
5256
GEN_SPEOP_ARITH1(efsneg);
5257
/* Conversion */
5258
GEN_SPEFPUOP_CONV(efscfui);
5259
GEN_SPEFPUOP_CONV(efscfsi);
5260
GEN_SPEFPUOP_CONV(efscfuf);
5261
GEN_SPEFPUOP_CONV(efscfsf);
5262
GEN_SPEFPUOP_CONV(efsctui);
5263
GEN_SPEFPUOP_CONV(efsctsi);
5264
GEN_SPEFPUOP_CONV(efsctuf);
5265
GEN_SPEFPUOP_CONV(efsctsf);
5266
GEN_SPEFPUOP_CONV(efsctuiz);
5267
GEN_SPEFPUOP_CONV(efsctsiz);
5268
GEN_SPEFPUOP_CONV(efscfd);
5269
/* Comparison */
5270
GEN_SPEOP_COMP(efscmpgt);
5271
GEN_SPEOP_COMP(efscmplt);
5272
GEN_SPEOP_COMP(efscmpeq);
5273
GEN_SPEOP_COMP(efststgt);
5274
GEN_SPEOP_COMP(efststlt);
5275
GEN_SPEOP_COMP(efststeq);
5276

    
5277
/* Opcodes definitions */
5278
GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5279
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5280
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5281
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5282
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5283
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5284
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5285
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5286
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5287
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5288
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5289
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5290
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5291

    
5292
/* Double precision floating-point operations */
5293
/* Arithmetic */
5294
GEN_SPEOP_ARITH2(efdadd);
5295
GEN_SPEOP_ARITH2(efdsub);
5296
GEN_SPEOP_ARITH2(efdmul);
5297
GEN_SPEOP_ARITH2(efddiv);
5298
GEN_SPEOP_ARITH1(efdabs);
5299
GEN_SPEOP_ARITH1(efdnabs);
5300
GEN_SPEOP_ARITH1(efdneg);
5301
/* Conversion */
5302

    
5303
GEN_SPEFPUOP_CONV(efdcfui);
5304
GEN_SPEFPUOP_CONV(efdcfsi);
5305
GEN_SPEFPUOP_CONV(efdcfuf);
5306
GEN_SPEFPUOP_CONV(efdcfsf);
5307
GEN_SPEFPUOP_CONV(efdctui);
5308
GEN_SPEFPUOP_CONV(efdctsi);
5309
GEN_SPEFPUOP_CONV(efdctuf);
5310
GEN_SPEFPUOP_CONV(efdctsf);
5311
GEN_SPEFPUOP_CONV(efdctuiz);
5312
GEN_SPEFPUOP_CONV(efdctsiz);
5313
GEN_SPEFPUOP_CONV(efdcfs);
5314
GEN_SPEFPUOP_CONV(efdcfuid);
5315
GEN_SPEFPUOP_CONV(efdcfsid);
5316
GEN_SPEFPUOP_CONV(efdctuidz);
5317
GEN_SPEFPUOP_CONV(efdctsidz);
5318
/* Comparison */
5319
GEN_SPEOP_COMP(efdcmpgt);
5320
GEN_SPEOP_COMP(efdcmplt);
5321
GEN_SPEOP_COMP(efdcmpeq);
5322
GEN_SPEOP_COMP(efdtstgt);
5323
GEN_SPEOP_COMP(efdtstlt);
5324
GEN_SPEOP_COMP(efdtsteq);
5325

    
5326
/* Opcodes definitions */
5327
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
5328
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
5329
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
5330
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
5331
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
5332
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
5333
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
5334
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
5335
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
5336
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
5337
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
5338
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
5339
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
5340
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
5341
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
5342
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
5343
#endif
5344

    
5345
/* End opcode list */
5346
GEN_OPCODE_MARK(end);
5347

    
5348
#include "translate_init.c"
5349

    
5350
/*****************************************************************************/
5351
/* Misc PowerPC helpers */
5352
static inline uint32_t load_xer (CPUState *env)
5353
{
5354
    return (xer_so << XER_SO) |
5355
        (xer_ov << XER_OV) |
5356
        (xer_ca << XER_CA) |
5357
        (xer_bc << XER_BC) |
5358
        (xer_cmp << XER_CMP);
5359
}
5360

    
5361
void cpu_dump_state(CPUState *env, FILE *f, 
5362
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5363
                    int flags)
5364
{
5365
#if defined(TARGET_PPC64) || 1
5366
#define FILL ""
5367
#define RGPL  4
5368
#define RFPL  4
5369
#else
5370
#define FILL "        "
5371
#define RGPL  8
5372
#define RFPL  4
5373
#endif
5374

    
5375
    int i;
5376

    
5377
    cpu_fprintf(f, "NIP " REGX " LR " REGX " CTR " REGX "\n",
5378
                env->nip, env->lr, env->ctr);
5379
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
5380
#if !defined(NO_TIMER_DUMP)
5381
                "TB %08x %08x "
5382
#if !defined(CONFIG_USER_ONLY)
5383
                "DECR %08x"
5384
#endif
5385
#endif
5386
                "\n",
5387
                do_load_msr(env), load_xer(env)
5388
#if !defined(NO_TIMER_DUMP)
5389
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
5390
#if !defined(CONFIG_USER_ONLY)
5391
                , cpu_ppc_load_decr(env)
5392
#endif
5393
#endif
5394
                );
5395
    for (i = 0; i < 32; i++) {
5396
        if ((i & (RGPL - 1)) == 0)
5397
            cpu_fprintf(f, "GPR%02d", i);
5398
        cpu_fprintf(f, " " REGX, env->gpr[i]);
5399
        if ((i & (RGPL - 1)) == (RGPL - 1))
5400
            cpu_fprintf(f, "\n");
5401
    }
5402
    cpu_fprintf(f, "CR ");
5403
    for (i = 0; i < 8; i++)
5404
        cpu_fprintf(f, "%01x", env->crf[i]);
5405
    cpu_fprintf(f, "  [");
5406
    for (i = 0; i < 8; i++) {
5407
        char a = '-';
5408
        if (env->crf[i] & 0x08)
5409
            a = 'L';
5410
        else if (env->crf[i] & 0x04)
5411
            a = 'G';
5412
        else if (env->crf[i] & 0x02)
5413
            a = 'E';
5414
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
5415
    }
5416
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
5417
    for (i = 0; i < 32; i++) {
5418
        if ((i & (RFPL - 1)) == 0)
5419
            cpu_fprintf(f, "FPR%02d", i);
5420
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
5421
        if ((i & (RFPL - 1)) == (RFPL - 1))
5422
            cpu_fprintf(f, "\n");
5423
    }
5424
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
5425
                "SDR1 " REGX "\n",
5426
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
5427

    
5428
#undef RGPL
5429
#undef RFPL
5430
#undef FILL
5431
}
5432

    
5433
void cpu_dump_statistics (CPUState *env, FILE*f,
5434
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5435
                          int flags)
5436
{
5437
#if defined(DO_PPC_STATISTICS)
5438
    opc_handler_t **t1, **t2, **t3, *handler;
5439
    int op1, op2, op3;
5440

    
5441
    t1 = env->opcodes;
5442
    for (op1 = 0; op1 < 64; op1++) {
5443
        handler = t1[op1];
5444
        if (is_indirect_opcode(handler)) {
5445
            t2 = ind_table(handler);
5446
            for (op2 = 0; op2 < 32; op2++) {
5447
                handler = t2[op2];
5448
                if (is_indirect_opcode(handler)) {
5449
                    t3 = ind_table(handler);
5450
                    for (op3 = 0; op3 < 32; op3++) {
5451
                        handler = t3[op3];
5452
                        if (handler->count == 0)
5453
                            continue;
5454
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
5455
                                    "%016llx %lld\n",
5456
                                    op1, op2, op3, op1, (op3 << 5) | op2,
5457
                                    handler->oname,
5458
                                    handler->count, handler->count);
5459
                    }
5460
                } else {
5461
                    if (handler->count == 0)
5462
                        continue;
5463
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
5464
                                "%016llx %lld\n",
5465
                                op1, op2, op1, op2, handler->oname,
5466
                                handler->count, handler->count);
5467
                }
5468
            }
5469
        } else {
5470
            if (handler->count == 0)
5471
                continue;
5472
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
5473
                        op1, op1, handler->oname,
5474
                        handler->count, handler->count);
5475
        }
5476
    }
5477
#endif
5478
}
5479

    
5480
/*****************************************************************************/
5481
static inline int gen_intermediate_code_internal (CPUState *env,
5482
                                                  TranslationBlock *tb,
5483
                                                  int search_pc)
5484
{
5485
    DisasContext ctx, *ctxp = &ctx;
5486
    opc_handler_t **table, *handler;
5487
    target_ulong pc_start;
5488
    uint16_t *gen_opc_end;
5489
    int j, lj = -1;
5490

    
5491
    pc_start = tb->pc;
5492
    gen_opc_ptr = gen_opc_buf;
5493
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5494
    gen_opparam_ptr = gen_opparam_buf;
5495
    nb_gen_labels = 0;
5496
    ctx.nip = pc_start;
5497
    ctx.tb = tb;
5498
    ctx.exception = EXCP_NONE;
5499
    ctx.spr_cb = env->spr_cb;
5500
#if defined(CONFIG_USER_ONLY)
5501
    ctx.mem_idx = msr_le;
5502
#if defined(TARGET_PPC64)
5503
    ctx.mem_idx |= msr_sf << 1;
5504
#endif
5505
#else
5506
    ctx.supervisor = 1 - msr_pr;
5507
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
5508
#if defined(TARGET_PPC64)
5509
    ctx.mem_idx |= msr_sf << 2;
5510
#endif
5511
#endif
5512
#if defined(TARGET_PPC64)
5513
    ctx.sf_mode = msr_sf;
5514
#endif
5515
    ctx.fpu_enabled = msr_fp;
5516
#if defined(TARGET_PPCSPE)
5517
    ctx.spe_enabled = msr_spe;
5518
#endif
5519
    ctx.singlestep_enabled = env->singlestep_enabled;
5520
#if defined (DO_SINGLE_STEP) && 0
5521
    /* Single step trace mode */
5522
    msr_se = 1;
5523
#endif
5524
    /* Set env in case of segfault during code fetch */
5525
    while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
5526
        if (unlikely(env->nb_breakpoints > 0)) {
5527
            for (j = 0; j < env->nb_breakpoints; j++) {
5528
                if (env->breakpoints[j] == ctx.nip) {
5529
                    gen_update_nip(&ctx, ctx.nip); 
5530
                    gen_op_debug();
5531
                    break;
5532
                }
5533
            }
5534
        }
5535
        if (unlikely(search_pc)) {
5536
            j = gen_opc_ptr - gen_opc_buf;
5537
            if (lj < j) {
5538
                lj++;
5539
                while (lj < j)
5540
                    gen_opc_instr_start[lj++] = 0;
5541
                gen_opc_pc[lj] = ctx.nip;
5542
                gen_opc_instr_start[lj] = 1;
5543
            }
5544
        }
5545
#if defined PPC_DEBUG_DISAS
5546
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5547
            fprintf(logfile, "----------------\n");
5548
            fprintf(logfile, "nip=%08x super=%d ir=%d\n",
5549
                    ctx.nip, 1 - msr_pr, msr_ir);
5550
        }
5551
#endif
5552
        ctx.opcode = ldl_code(ctx.nip);
5553
        if (msr_le) {
5554
            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
5555
                ((ctx.opcode & 0x00FF0000) >> 8) |
5556
                ((ctx.opcode & 0x0000FF00) << 8) |
5557
                ((ctx.opcode & 0x000000FF) << 24);
5558
        }
5559
#if defined PPC_DEBUG_DISAS
5560
        if (loglevel & CPU_LOG_TB_IN_ASM) {
5561
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
5562
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
5563
                    opc3(ctx.opcode), msr_le ? "little" : "big");
5564
        }
5565
#endif
5566
        ctx.nip += 4;
5567
        table = env->opcodes;
5568
        handler = table[opc1(ctx.opcode)];
5569
        if (is_indirect_opcode(handler)) {
5570
            table = ind_table(handler);
5571
            handler = table[opc2(ctx.opcode)];
5572
            if (is_indirect_opcode(handler)) {
5573
                table = ind_table(handler);
5574
                handler = table[opc3(ctx.opcode)];
5575
            }
5576
        }
5577
        /* Is opcode *REALLY* valid ? */
5578
        if (unlikely(handler->handler == &gen_invalid)) {
5579
            if (loglevel > 0) {
5580
                fprintf(logfile, "invalid/unsupported opcode: "
5581
                        "%02x - %02x - %02x (%08x) 0x" REGX " %d\n",
5582
                        opc1(ctx.opcode), opc2(ctx.opcode),
5583
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
5584
            } else {
5585
                printf("invalid/unsupported opcode: "
5586
                       "%02x - %02x - %02x (%08x) 0x" REGX " %d\n",
5587
                       opc1(ctx.opcode), opc2(ctx.opcode),
5588
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
5589
            }
5590
        } else {
5591
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
5592
                if (loglevel > 0) {
5593
                    fprintf(logfile, "invalid bits: %08x for opcode: "
5594
                            "%02x -%02x - %02x (%08x) " REGX "\n",
5595
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
5596
                            opc2(ctx.opcode), opc3(ctx.opcode),
5597
                            ctx.opcode, ctx.nip - 4);
5598
                } else {
5599
                    printf("invalid bits: %08x for opcode: "
5600
                           "%02x -%02x - %02x (%08x) " REGX "\n",
5601
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
5602
                           opc2(ctx.opcode), opc3(ctx.opcode),
5603
                           ctx.opcode, ctx.nip - 4);
5604
                }
5605
                RET_INVAL(ctxp);
5606
                break;
5607
            }
5608
        }
5609
        (*(handler->handler))(&ctx);
5610
#if defined(DO_PPC_STATISTICS)
5611
        handler->count++;
5612
#endif
5613
        /* Check trace mode exceptions */
5614
        if (unlikely((msr_be && ctx.exception == EXCP_BRANCH) ||
5615
                     /* Check in single step trace mode
5616
                      * we need to stop except if:
5617
                      * - rfi, trap or syscall
5618
                      * - first instruction of an exception handler
5619
                      */
5620
                     (msr_se && (ctx.nip < 0x100 ||
5621
                                 ctx.nip > 0xF00 ||
5622
                                 (ctx.nip & 0xFC) != 0x04) &&
5623
                      ctx.exception != EXCP_SYSCALL &&
5624
                      ctx.exception != EXCP_SYSCALL_USER &&
5625
                      ctx.exception != EXCP_TRAP))) {
5626
            RET_EXCP(ctxp, EXCP_TRACE, 0);
5627
        }
5628
        /* if we reach a page boundary or are single stepping, stop
5629
         * generation
5630
         */
5631
        if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
5632
                     (env->singlestep_enabled))) {
5633
            break;
5634
        }
5635
#if defined (DO_SINGLE_STEP)
5636
        break;
5637
#endif
5638
    }
5639
    if (ctx.exception == EXCP_NONE) {
5640
        gen_goto_tb(&ctx, 0, ctx.nip);
5641
    } else if (ctx.exception != EXCP_BRANCH) {
5642
        gen_op_reset_T0();
5643
        /* Generate the return instruction */
5644
        gen_op_exit_tb();
5645
    }
5646
    *gen_opc_ptr = INDEX_op_end;
5647
    if (unlikely(search_pc)) {
5648
        j = gen_opc_ptr - gen_opc_buf;
5649
        lj++;
5650
        while (lj <= j)
5651
            gen_opc_instr_start[lj++] = 0;
5652
        tb->size = 0;
5653
    } else {
5654
        tb->size = ctx.nip - pc_start;
5655
    }
5656
#if defined(DEBUG_DISAS)
5657
    if (loglevel & CPU_LOG_TB_CPU) {
5658
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
5659
        cpu_dump_state(env, logfile, fprintf, 0);
5660
    }
5661
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5662
        int flags;
5663
        flags = msr_le;
5664
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5665
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
5666
        fprintf(logfile, "\n");
5667
    }
5668
    if (loglevel & CPU_LOG_TB_OP) {
5669
        fprintf(logfile, "OP:\n");
5670
        dump_ops(gen_opc_buf, gen_opparam_buf);
5671
        fprintf(logfile, "\n");
5672
    }
5673
#endif
5674
    return 0;
5675
}
5676

    
5677
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5678
{
5679
    return gen_intermediate_code_internal(env, tb, 0);
5680
}
5681

    
5682
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5683
{
5684
    return gen_intermediate_code_internal(env, tb, 1);
5685
}