Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 35cdaad6

History | View | Annotate | Download (197 kB)

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

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

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

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

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

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

    
51
#include "gen-op.h"
52

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
365
    return ret;
366
}
367

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1675
/* mtfsb0 */
1676
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1677
{
1678
    uint8_t crb;
1679
    
1680
    if (unlikely(!ctx->fpu_enabled)) {
1681
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1682
        return;
1683
    }
1684
    crb = crbD(ctx->opcode) >> 2;
1685
    gen_op_load_fpscr_T0(crb);
1686
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1687
    gen_op_store_T0_fpscr(crb);
1688
    if (unlikely(Rc(ctx->opcode) != 0))
1689
        gen_op_set_Rc1();
1690
}
1691

    
1692
/* mtfsb1 */
1693
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1694
{
1695
    uint8_t crb;
1696
    
1697
    if (unlikely(!ctx->fpu_enabled)) {
1698
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1699
        return;
1700
    }
1701
    crb = crbD(ctx->opcode) >> 2;
1702
    gen_op_load_fpscr_T0(crb);
1703
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1704
    gen_op_store_T0_fpscr(crb);
1705
    if (unlikely(Rc(ctx->opcode) != 0))
1706
        gen_op_set_Rc1();
1707
}
1708

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2603
/***                                Branch                                 ***/
2604

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2967
/* mfcr */
2968
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
2969
{
2970
    uint32_t crm, crn;
2971
    
2972
    if (likely(ctx->opcode & 0x00100000)) {
2973
        crm = CRM(ctx->opcode);
2974
        if (likely((crm ^ (crm - 1)) == 0)) {
2975
            crn = ffs(crm);
2976
            gen_op_load_cro(7 - crn);
2977
        }
2978
    } else {
2979
        gen_op_load_cr();
2980
    }
2981
    gen_op_store_T0_gpr(rD(ctx->opcode));
2982
}
2983

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

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

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

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

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

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

    
3057
/* mtcrf */
3058
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3059
{
3060
    uint32_t crm, crn;
3061
    
3062
    gen_op_load_gpr_T0(rS(ctx->opcode));
3063
    crm = CRM(ctx->opcode);
3064
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3065
        crn = ffs(crm);
3066
        gen_op_srli_T0(crn * 4);
3067
        gen_op_andi_T0(0xF);
3068
        gen_op_store_cro(7 - crn);
3069
    } else {
3070
        gen_op_store_cr(crm);
3071
    }
3072
}
3073

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3689
/* maskg - maskg. */
3690
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 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_maskg();
3695
    gen_op_store_T0_gpr(rA(ctx->opcode));
3696
    if (unlikely(Rc(ctx->opcode) != 0))
3697
        gen_set_Rc0(ctx);
3698
}
3699

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5575
#include "translate_init.c"
5576

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

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

    
5602
    int i;
5603

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

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

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

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

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

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

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

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