Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 70bca53f

History | View | Annotate | Download (351.5 kB)

1
/*
2
 *  PowerPC emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2003-2007 Jocelyn Mayer
5
 *  Copyright (C) 2011 Freescale Semiconductor, Inc.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
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 "disas.h"
28
#include "tcg-op.h"
29
#include "qemu-common.h"
30
#include "host-utils.h"
31

    
32
#include "helper.h"
33
#define GEN_HELPER 1
34
#include "helper.h"
35

    
36
#define CPU_SINGLE_STEP 0x1
37
#define CPU_BRANCH_STEP 0x2
38
#define GDBSTUB_SINGLE_STEP 0x4
39

    
40
/* Include definitions for instructions classes and implementations flags */
41
//#define PPC_DEBUG_DISAS
42
//#define DO_PPC_STATISTICS
43

    
44
#ifdef PPC_DEBUG_DISAS
45
#  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
46
#else
47
#  define LOG_DISAS(...) do { } while (0)
48
#endif
49
/*****************************************************************************/
50
/* Code translation helpers                                                  */
51

    
52
/* global register indexes */
53
static TCGv_ptr cpu_env;
54
static char cpu_reg_names[10*3 + 22*4 /* GPR */
55
#if !defined(TARGET_PPC64)
56
    + 10*4 + 22*5 /* SPE GPRh */
57
#endif
58
    + 10*4 + 22*5 /* FPR */
59
    + 2*(10*6 + 22*7) /* AVRh, AVRl */
60
    + 8*5 /* CRF */];
61
static TCGv cpu_gpr[32];
62
#if !defined(TARGET_PPC64)
63
static TCGv cpu_gprh[32];
64
#endif
65
static TCGv_i64 cpu_fpr[32];
66
static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
67
static TCGv_i32 cpu_crf[8];
68
static TCGv cpu_nip;
69
static TCGv cpu_msr;
70
static TCGv cpu_ctr;
71
static TCGv cpu_lr;
72
#if defined(TARGET_PPC64)
73
static TCGv cpu_cfar;
74
#endif
75
static TCGv cpu_xer;
76
static TCGv cpu_reserve;
77
static TCGv_i32 cpu_fpscr;
78
static TCGv_i32 cpu_access_type;
79

    
80
#include "gen-icount.h"
81

    
82
void ppc_translate_init(void)
83
{
84
    int i;
85
    char* p;
86
    size_t cpu_reg_names_size;
87
    static int done_init = 0;
88

    
89
    if (done_init)
90
        return;
91

    
92
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
93

    
94
    p = cpu_reg_names;
95
    cpu_reg_names_size = sizeof(cpu_reg_names);
96

    
97
    for (i = 0; i < 8; i++) {
98
        snprintf(p, cpu_reg_names_size, "crf%d", i);
99
        cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
100
                                            offsetof(CPUState, crf[i]), p);
101
        p += 5;
102
        cpu_reg_names_size -= 5;
103
    }
104

    
105
    for (i = 0; i < 32; i++) {
106
        snprintf(p, cpu_reg_names_size, "r%d", i);
107
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
108
                                        offsetof(CPUState, gpr[i]), p);
109
        p += (i < 10) ? 3 : 4;
110
        cpu_reg_names_size -= (i < 10) ? 3 : 4;
111
#if !defined(TARGET_PPC64)
112
        snprintf(p, cpu_reg_names_size, "r%dH", i);
113
        cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
114
                                             offsetof(CPUState, gprh[i]), p);
115
        p += (i < 10) ? 4 : 5;
116
        cpu_reg_names_size -= (i < 10) ? 4 : 5;
117
#endif
118

    
119
        snprintf(p, cpu_reg_names_size, "fp%d", i);
120
        cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
121
                                            offsetof(CPUState, fpr[i]), p);
122
        p += (i < 10) ? 4 : 5;
123
        cpu_reg_names_size -= (i < 10) ? 4 : 5;
124

    
125
        snprintf(p, cpu_reg_names_size, "avr%dH", i);
126
#ifdef HOST_WORDS_BIGENDIAN
127
        cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
128
                                             offsetof(CPUState, avr[i].u64[0]), p);
129
#else
130
        cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
131
                                             offsetof(CPUState, avr[i].u64[1]), p);
132
#endif
133
        p += (i < 10) ? 6 : 7;
134
        cpu_reg_names_size -= (i < 10) ? 6 : 7;
135

    
136
        snprintf(p, cpu_reg_names_size, "avr%dL", i);
137
#ifdef HOST_WORDS_BIGENDIAN
138
        cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
139
                                             offsetof(CPUState, avr[i].u64[1]), p);
140
#else
141
        cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
142
                                             offsetof(CPUState, avr[i].u64[0]), p);
143
#endif
144
        p += (i < 10) ? 6 : 7;
145
        cpu_reg_names_size -= (i < 10) ? 6 : 7;
146
    }
147

    
148
    cpu_nip = tcg_global_mem_new(TCG_AREG0,
149
                                 offsetof(CPUState, nip), "nip");
150

    
151
    cpu_msr = tcg_global_mem_new(TCG_AREG0,
152
                                 offsetof(CPUState, msr), "msr");
153

    
154
    cpu_ctr = tcg_global_mem_new(TCG_AREG0,
155
                                 offsetof(CPUState, ctr), "ctr");
156

    
157
    cpu_lr = tcg_global_mem_new(TCG_AREG0,
158
                                offsetof(CPUState, lr), "lr");
159

    
160
#if defined(TARGET_PPC64)
161
    cpu_cfar = tcg_global_mem_new(TCG_AREG0,
162
                                  offsetof(CPUState, cfar), "cfar");
163
#endif
164

    
165
    cpu_xer = tcg_global_mem_new(TCG_AREG0,
166
                                 offsetof(CPUState, xer), "xer");
167

    
168
    cpu_reserve = tcg_global_mem_new(TCG_AREG0,
169
                                     offsetof(CPUState, reserve_addr),
170
                                     "reserve_addr");
171

    
172
    cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
173
                                       offsetof(CPUState, fpscr), "fpscr");
174

    
175
    cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
176
                                             offsetof(CPUState, access_type), "access_type");
177

    
178
    /* register helpers */
179
#define GEN_HELPER 2
180
#include "helper.h"
181

    
182
    done_init = 1;
183
}
184

    
185
/* internal defines */
186
typedef struct DisasContext {
187
    struct TranslationBlock *tb;
188
    target_ulong nip;
189
    uint32_t opcode;
190
    uint32_t exception;
191
    /* Routine used to access memory */
192
    int mem_idx;
193
    int access_type;
194
    /* Translation flags */
195
    int le_mode;
196
#if defined(TARGET_PPC64)
197
    int sf_mode;
198
    int has_cfar;
199
#endif
200
    int fpu_enabled;
201
    int altivec_enabled;
202
    int spe_enabled;
203
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
204
    int singlestep_enabled;
205
} DisasContext;
206

    
207
struct opc_handler_t {
208
    /* invalid bits for instruction 1 (Rc(opcode) == 0) */
209
    uint32_t inval1;
210
    /* invalid bits for instruction 2 (Rc(opcode) == 1) */
211
    uint32_t inval2;
212
    /* instruction type */
213
    uint64_t type;
214
    /* extended instruction type */
215
    uint64_t type2;
216
    /* handler */
217
    void (*handler)(DisasContext *ctx);
218
#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
219
    const char *oname;
220
#endif
221
#if defined(DO_PPC_STATISTICS)
222
    uint64_t count;
223
#endif
224
};
225

    
226
static inline void gen_reset_fpstatus(void)
227
{
228
    gen_helper_reset_fpstatus();
229
}
230

    
231
static inline void gen_compute_fprf(TCGv_i64 arg, int set_fprf, int set_rc)
232
{
233
    TCGv_i32 t0 = tcg_temp_new_i32();
234

    
235
    if (set_fprf != 0) {
236
        /* This case might be optimized later */
237
        tcg_gen_movi_i32(t0, 1);
238
        gen_helper_compute_fprf(t0, arg, t0);
239
        if (unlikely(set_rc)) {
240
            tcg_gen_mov_i32(cpu_crf[1], t0);
241
        }
242
        gen_helper_float_check_status();
243
    } else if (unlikely(set_rc)) {
244
        /* We always need to compute fpcc */
245
        tcg_gen_movi_i32(t0, 0);
246
        gen_helper_compute_fprf(t0, arg, t0);
247
        tcg_gen_mov_i32(cpu_crf[1], t0);
248
    }
249

    
250
    tcg_temp_free_i32(t0);
251
}
252

    
253
static inline void gen_set_access_type(DisasContext *ctx, int access_type)
254
{
255
    if (ctx->access_type != access_type) {
256
        tcg_gen_movi_i32(cpu_access_type, access_type);
257
        ctx->access_type = access_type;
258
    }
259
}
260

    
261
static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
262
{
263
#if defined(TARGET_PPC64)
264
    if (ctx->sf_mode)
265
        tcg_gen_movi_tl(cpu_nip, nip);
266
    else
267
#endif
268
        tcg_gen_movi_tl(cpu_nip, (uint32_t)nip);
269
}
270

    
271
static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
272
{
273
    TCGv_i32 t0, t1;
274
    if (ctx->exception == POWERPC_EXCP_NONE) {
275
        gen_update_nip(ctx, ctx->nip);
276
    }
277
    t0 = tcg_const_i32(excp);
278
    t1 = tcg_const_i32(error);
279
    gen_helper_raise_exception_err(t0, t1);
280
    tcg_temp_free_i32(t0);
281
    tcg_temp_free_i32(t1);
282
    ctx->exception = (excp);
283
}
284

    
285
static inline void gen_exception(DisasContext *ctx, uint32_t excp)
286
{
287
    TCGv_i32 t0;
288
    if (ctx->exception == POWERPC_EXCP_NONE) {
289
        gen_update_nip(ctx, ctx->nip);
290
    }
291
    t0 = tcg_const_i32(excp);
292
    gen_helper_raise_exception(t0);
293
    tcg_temp_free_i32(t0);
294
    ctx->exception = (excp);
295
}
296

    
297
static inline void gen_debug_exception(DisasContext *ctx)
298
{
299
    TCGv_i32 t0;
300

    
301
    if (ctx->exception != POWERPC_EXCP_BRANCH)
302
        gen_update_nip(ctx, ctx->nip);
303
    t0 = tcg_const_i32(EXCP_DEBUG);
304
    gen_helper_raise_exception(t0);
305
    tcg_temp_free_i32(t0);
306
}
307

    
308
static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
309
{
310
    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
311
}
312

    
313
/* Stop translation */
314
static inline void gen_stop_exception(DisasContext *ctx)
315
{
316
    gen_update_nip(ctx, ctx->nip);
317
    ctx->exception = POWERPC_EXCP_STOP;
318
}
319

    
320
/* No need to update nip here, as execution flow will change */
321
static inline void gen_sync_exception(DisasContext *ctx)
322
{
323
    ctx->exception = POWERPC_EXCP_SYNC;
324
}
325

    
326
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
327
GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
328

    
329
#define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2)             \
330
GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
331

    
332
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
333
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
334

    
335
#define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)      \
336
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
337

    
338
typedef struct opcode_t {
339
    unsigned char opc1, opc2, opc3;
340
#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
341
    unsigned char pad[5];
342
#else
343
    unsigned char pad[1];
344
#endif
345
    opc_handler_t handler;
346
    const char *oname;
347
} opcode_t;
348

    
349
/*****************************************************************************/
350
/***                           Instruction decoding                        ***/
351
#define EXTRACT_HELPER(name, shift, nb)                                       \
352
static inline uint32_t name(uint32_t opcode)                                  \
353
{                                                                             \
354
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
355
}
356

    
357
#define EXTRACT_SHELPER(name, shift, nb)                                      \
358
static inline int32_t name(uint32_t opcode)                                   \
359
{                                                                             \
360
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
361
}
362

    
363
/* Opcode part 1 */
364
EXTRACT_HELPER(opc1, 26, 6);
365
/* Opcode part 2 */
366
EXTRACT_HELPER(opc2, 1, 5);
367
/* Opcode part 3 */
368
EXTRACT_HELPER(opc3, 6, 5);
369
/* Update Cr0 flags */
370
EXTRACT_HELPER(Rc, 0, 1);
371
/* Destination */
372
EXTRACT_HELPER(rD, 21, 5);
373
/* Source */
374
EXTRACT_HELPER(rS, 21, 5);
375
/* First operand */
376
EXTRACT_HELPER(rA, 16, 5);
377
/* Second operand */
378
EXTRACT_HELPER(rB, 11, 5);
379
/* Third operand */
380
EXTRACT_HELPER(rC, 6, 5);
381
/***                               Get CRn                                 ***/
382
EXTRACT_HELPER(crfD, 23, 3);
383
EXTRACT_HELPER(crfS, 18, 3);
384
EXTRACT_HELPER(crbD, 21, 5);
385
EXTRACT_HELPER(crbA, 16, 5);
386
EXTRACT_HELPER(crbB, 11, 5);
387
/* SPR / TBL */
388
EXTRACT_HELPER(_SPR, 11, 10);
389
static inline uint32_t SPR(uint32_t opcode)
390
{
391
    uint32_t sprn = _SPR(opcode);
392

    
393
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
394
}
395
/***                              Get constants                            ***/
396
EXTRACT_HELPER(IMM, 12, 8);
397
/* 16 bits signed immediate value */
398
EXTRACT_SHELPER(SIMM, 0, 16);
399
/* 16 bits unsigned immediate value */
400
EXTRACT_HELPER(UIMM, 0, 16);
401
/* 5 bits signed immediate value */
402
EXTRACT_HELPER(SIMM5, 16, 5);
403
/* 5 bits signed immediate value */
404
EXTRACT_HELPER(UIMM5, 16, 5);
405
/* Bit count */
406
EXTRACT_HELPER(NB, 11, 5);
407
/* Shift count */
408
EXTRACT_HELPER(SH, 11, 5);
409
/* Vector shift count */
410
EXTRACT_HELPER(VSH, 6, 4);
411
/* Mask start */
412
EXTRACT_HELPER(MB, 6, 5);
413
/* Mask end */
414
EXTRACT_HELPER(ME, 1, 5);
415
/* Trap operand */
416
EXTRACT_HELPER(TO, 21, 5);
417

    
418
EXTRACT_HELPER(CRM, 12, 8);
419
EXTRACT_HELPER(FM, 17, 8);
420
EXTRACT_HELPER(SR, 16, 4);
421
EXTRACT_HELPER(FPIMM, 12, 4);
422

    
423
/***                            Jump target decoding                       ***/
424
/* Displacement */
425
EXTRACT_SHELPER(d, 0, 16);
426
/* Immediate address */
427
static inline target_ulong LI(uint32_t opcode)
428
{
429
    return (opcode >> 0) & 0x03FFFFFC;
430
}
431

    
432
static inline uint32_t BD(uint32_t opcode)
433
{
434
    return (opcode >> 0) & 0xFFFC;
435
}
436

    
437
EXTRACT_HELPER(BO, 21, 5);
438
EXTRACT_HELPER(BI, 16, 5);
439
/* Absolute/relative address */
440
EXTRACT_HELPER(AA, 1, 1);
441
/* Link */
442
EXTRACT_HELPER(LK, 0, 1);
443

    
444
/* Create a mask between <start> and <end> bits */
445
static inline target_ulong MASK(uint32_t start, uint32_t end)
446
{
447
    target_ulong ret;
448

    
449
#if defined(TARGET_PPC64)
450
    if (likely(start == 0)) {
451
        ret = UINT64_MAX << (63 - end);
452
    } else if (likely(end == 63)) {
453
        ret = UINT64_MAX >> start;
454
    }
455
#else
456
    if (likely(start == 0)) {
457
        ret = UINT32_MAX << (31  - end);
458
    } else if (likely(end == 31)) {
459
        ret = UINT32_MAX >> start;
460
    }
461
#endif
462
    else {
463
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
464
            (((target_ulong)(-1ULL) >> (end)) >> 1);
465
        if (unlikely(start > end))
466
            return ~ret;
467
    }
468

    
469
    return ret;
470
}
471

    
472
/*****************************************************************************/
473
/* PowerPC instructions table                                                */
474

    
475
#if defined(DO_PPC_STATISTICS)
476
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
477
{                                                                             \
478
    .opc1 = op1,                                                              \
479
    .opc2 = op2,                                                              \
480
    .opc3 = op3,                                                              \
481
    .pad  = { 0, },                                                           \
482
    .handler = {                                                              \
483
        .inval1  = invl,                                                      \
484
        .type = _typ,                                                         \
485
        .type2 = _typ2,                                                       \
486
        .handler = &gen_##name,                                               \
487
        .oname = stringify(name),                                             \
488
    },                                                                        \
489
    .oname = stringify(name),                                                 \
490
}
491
#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
492
{                                                                             \
493
    .opc1 = op1,                                                              \
494
    .opc2 = op2,                                                              \
495
    .opc3 = op3,                                                              \
496
    .pad  = { 0, },                                                           \
497
    .handler = {                                                              \
498
        .inval1  = invl1,                                                     \
499
        .inval2  = invl2,                                                     \
500
        .type = _typ,                                                         \
501
        .type2 = _typ2,                                                       \
502
        .handler = &gen_##name,                                               \
503
        .oname = stringify(name),                                             \
504
    },                                                                        \
505
    .oname = stringify(name),                                                 \
506
}
507
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
508
{                                                                             \
509
    .opc1 = op1,                                                              \
510
    .opc2 = op2,                                                              \
511
    .opc3 = op3,                                                              \
512
    .pad  = { 0, },                                                           \
513
    .handler = {                                                              \
514
        .inval1  = invl,                                                      \
515
        .type = _typ,                                                         \
516
        .type2 = _typ2,                                                       \
517
        .handler = &gen_##name,                                               \
518
        .oname = onam,                                                        \
519
    },                                                                        \
520
    .oname = onam,                                                            \
521
}
522
#else
523
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
524
{                                                                             \
525
    .opc1 = op1,                                                              \
526
    .opc2 = op2,                                                              \
527
    .opc3 = op3,                                                              \
528
    .pad  = { 0, },                                                           \
529
    .handler = {                                                              \
530
        .inval1  = invl,                                                      \
531
        .type = _typ,                                                         \
532
        .type2 = _typ2,                                                       \
533
        .handler = &gen_##name,                                               \
534
    },                                                                        \
535
    .oname = stringify(name),                                                 \
536
}
537
#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
538
{                                                                             \
539
    .opc1 = op1,                                                              \
540
    .opc2 = op2,                                                              \
541
    .opc3 = op3,                                                              \
542
    .pad  = { 0, },                                                           \
543
    .handler = {                                                              \
544
        .inval1  = invl1,                                                     \
545
        .inval2  = invl2,                                                     \
546
        .type = _typ,                                                         \
547
        .type2 = _typ2,                                                       \
548
        .handler = &gen_##name,                                               \
549
    },                                                                        \
550
    .oname = stringify(name),                                                 \
551
}
552
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
553
{                                                                             \
554
    .opc1 = op1,                                                              \
555
    .opc2 = op2,                                                              \
556
    .opc3 = op3,                                                              \
557
    .pad  = { 0, },                                                           \
558
    .handler = {                                                              \
559
        .inval1  = invl,                                                      \
560
        .type = _typ,                                                         \
561
        .type2 = _typ2,                                                       \
562
        .handler = &gen_##name,                                               \
563
    },                                                                        \
564
    .oname = onam,                                                            \
565
}
566
#endif
567

    
568
/* SPR load/store helpers */
569
static inline void gen_load_spr(TCGv t, int reg)
570
{
571
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, spr[reg]));
572
}
573

    
574
static inline void gen_store_spr(int reg, TCGv t)
575
{
576
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, spr[reg]));
577
}
578

    
579
/* Invalid instruction */
580
static void gen_invalid(DisasContext *ctx)
581
{
582
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
583
}
584

    
585
static opc_handler_t invalid_handler = {
586
    .inval1  = 0xFFFFFFFF,
587
    .inval2  = 0xFFFFFFFF,
588
    .type    = PPC_NONE,
589
    .type2   = PPC_NONE,
590
    .handler = gen_invalid,
591
};
592

    
593
/***                           Integer comparison                          ***/
594

    
595
static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
596
{
597
    int l1, l2, l3;
598

    
599
    tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_xer);
600
    tcg_gen_shri_i32(cpu_crf[crf], cpu_crf[crf], XER_SO);
601
    tcg_gen_andi_i32(cpu_crf[crf], cpu_crf[crf], 1);
602

    
603
    l1 = gen_new_label();
604
    l2 = gen_new_label();
605
    l3 = gen_new_label();
606
    if (s) {
607
        tcg_gen_brcond_tl(TCG_COND_LT, arg0, arg1, l1);
608
        tcg_gen_brcond_tl(TCG_COND_GT, arg0, arg1, l2);
609
    } else {
610
        tcg_gen_brcond_tl(TCG_COND_LTU, arg0, arg1, l1);
611
        tcg_gen_brcond_tl(TCG_COND_GTU, arg0, arg1, l2);
612
    }
613
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_EQ);
614
    tcg_gen_br(l3);
615
    gen_set_label(l1);
616
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_LT);
617
    tcg_gen_br(l3);
618
    gen_set_label(l2);
619
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_GT);
620
    gen_set_label(l3);
621
}
622

    
623
static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
624
{
625
    TCGv t0 = tcg_const_local_tl(arg1);
626
    gen_op_cmp(arg0, t0, s, crf);
627
    tcg_temp_free(t0);
628
}
629

    
630
#if defined(TARGET_PPC64)
631
static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
632
{
633
    TCGv t0, t1;
634
    t0 = tcg_temp_local_new();
635
    t1 = tcg_temp_local_new();
636
    if (s) {
637
        tcg_gen_ext32s_tl(t0, arg0);
638
        tcg_gen_ext32s_tl(t1, arg1);
639
    } else {
640
        tcg_gen_ext32u_tl(t0, arg0);
641
        tcg_gen_ext32u_tl(t1, arg1);
642
    }
643
    gen_op_cmp(t0, t1, s, crf);
644
    tcg_temp_free(t1);
645
    tcg_temp_free(t0);
646
}
647

    
648
static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
649
{
650
    TCGv t0 = tcg_const_local_tl(arg1);
651
    gen_op_cmp32(arg0, t0, s, crf);
652
    tcg_temp_free(t0);
653
}
654
#endif
655

    
656
static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
657
{
658
#if defined(TARGET_PPC64)
659
    if (!(ctx->sf_mode))
660
        gen_op_cmpi32(reg, 0, 1, 0);
661
    else
662
#endif
663
        gen_op_cmpi(reg, 0, 1, 0);
664
}
665

    
666
/* cmp */
667
static void gen_cmp(DisasContext *ctx)
668
{
669
#if defined(TARGET_PPC64)
670
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
671
        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
672
                     1, crfD(ctx->opcode));
673
    else
674
#endif
675
        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
676
                   1, crfD(ctx->opcode));
677
}
678

    
679
/* cmpi */
680
static void gen_cmpi(DisasContext *ctx)
681
{
682
#if defined(TARGET_PPC64)
683
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
684
        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
685
                      1, crfD(ctx->opcode));
686
    else
687
#endif
688
        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
689
                    1, crfD(ctx->opcode));
690
}
691

    
692
/* cmpl */
693
static void gen_cmpl(DisasContext *ctx)
694
{
695
#if defined(TARGET_PPC64)
696
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
697
        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
698
                     0, crfD(ctx->opcode));
699
    else
700
#endif
701
        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
702
                   0, crfD(ctx->opcode));
703
}
704

    
705
/* cmpli */
706
static void gen_cmpli(DisasContext *ctx)
707
{
708
#if defined(TARGET_PPC64)
709
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
710
        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
711
                      0, crfD(ctx->opcode));
712
    else
713
#endif
714
        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
715
                    0, crfD(ctx->opcode));
716
}
717

    
718
/* isel (PowerPC 2.03 specification) */
719
static void gen_isel(DisasContext *ctx)
720
{
721
    int l1, l2;
722
    uint32_t bi = rC(ctx->opcode);
723
    uint32_t mask;
724
    TCGv_i32 t0;
725

    
726
    l1 = gen_new_label();
727
    l2 = gen_new_label();
728

    
729
    mask = 1 << (3 - (bi & 0x03));
730
    t0 = tcg_temp_new_i32();
731
    tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
732
    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
733
    if (rA(ctx->opcode) == 0)
734
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
735
    else
736
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
737
    tcg_gen_br(l2);
738
    gen_set_label(l1);
739
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
740
    gen_set_label(l2);
741
    tcg_temp_free_i32(t0);
742
}
743

    
744
/***                           Integer arithmetic                          ***/
745

    
746
static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
747
                                           TCGv arg1, TCGv arg2, int sub)
748
{
749
    int l1;
750
    TCGv t0;
751

    
752
    l1 = gen_new_label();
753
    /* Start with XER OV disabled, the most likely case */
754
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
755
    t0 = tcg_temp_local_new();
756
    tcg_gen_xor_tl(t0, arg0, arg1);
757
#if defined(TARGET_PPC64)
758
    if (!ctx->sf_mode)
759
        tcg_gen_ext32s_tl(t0, t0);
760
#endif
761
    if (sub)
762
        tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
763
    else
764
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
765
    tcg_gen_xor_tl(t0, arg1, arg2);
766
#if defined(TARGET_PPC64)
767
    if (!ctx->sf_mode)
768
        tcg_gen_ext32s_tl(t0, t0);
769
#endif
770
    if (sub)
771
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
772
    else
773
        tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
774
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
775
    gen_set_label(l1);
776
    tcg_temp_free(t0);
777
}
778

    
779
static inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
780
                                           TCGv arg2, int sub)
781
{
782
    int l1 = gen_new_label();
783

    
784
#if defined(TARGET_PPC64)
785
    if (!(ctx->sf_mode)) {
786
        TCGv t0, t1;
787
        t0 = tcg_temp_new();
788
        t1 = tcg_temp_new();
789

    
790
        tcg_gen_ext32u_tl(t0, arg1);
791
        tcg_gen_ext32u_tl(t1, arg2);
792
        if (sub) {
793
            tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
794
        } else {
795
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
796
        }
797
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
798
        gen_set_label(l1);
799
        tcg_temp_free(t0);
800
        tcg_temp_free(t1);
801
    } else
802
#endif
803
    {
804
        if (sub) {
805
            tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
806
        } else {
807
            tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
808
        }
809
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
810
        gen_set_label(l1);
811
    }
812
}
813

    
814
/* Common add function */
815
static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
816
                                    TCGv arg2, int add_ca, int compute_ca,
817
                                    int compute_ov)
818
{
819
    TCGv t0, t1;
820

    
821
    if ((!compute_ca && !compute_ov) ||
822
        (!TCGV_EQUAL(ret,arg1) && !TCGV_EQUAL(ret, arg2)))  {
823
        t0 = ret;
824
    } else {
825
        t0 = tcg_temp_local_new();
826
    }
827

    
828
    if (add_ca) {
829
        t1 = tcg_temp_local_new();
830
        tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
831
        tcg_gen_shri_tl(t1, t1, XER_CA);
832
    } else {
833
        TCGV_UNUSED(t1);
834
    }
835

    
836
    if (compute_ca && compute_ov) {
837
        /* Start with XER CA and OV disabled, the most likely case */
838
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
839
    } else if (compute_ca) {
840
        /* Start with XER CA disabled, the most likely case */
841
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
842
    } else if (compute_ov) {
843
        /* Start with XER OV disabled, the most likely case */
844
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
845
    }
846

    
847
    tcg_gen_add_tl(t0, arg1, arg2);
848

    
849
    if (compute_ca) {
850
        gen_op_arith_compute_ca(ctx, t0, arg1, 0);
851
    }
852
    if (add_ca) {
853
        tcg_gen_add_tl(t0, t0, t1);
854
        gen_op_arith_compute_ca(ctx, t0, t1, 0);
855
        tcg_temp_free(t1);
856
    }
857
    if (compute_ov) {
858
        gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
859
    }
860

    
861
    if (unlikely(Rc(ctx->opcode) != 0))
862
        gen_set_Rc0(ctx, t0);
863

    
864
    if (!TCGV_EQUAL(t0, ret)) {
865
        tcg_gen_mov_tl(ret, t0);
866
        tcg_temp_free(t0);
867
    }
868
}
869
/* Add functions with two operands */
870
#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
871
static void glue(gen_, name)(DisasContext *ctx)                                       \
872
{                                                                             \
873
    gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
874
                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
875
                     add_ca, compute_ca, compute_ov);                         \
876
}
877
/* Add functions with one operand and one immediate */
878
#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
879
                                add_ca, compute_ca, compute_ov)               \
880
static void glue(gen_, name)(DisasContext *ctx)                                       \
881
{                                                                             \
882
    TCGv t0 = tcg_const_local_tl(const_val);                                  \
883
    gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
884
                     cpu_gpr[rA(ctx->opcode)], t0,                            \
885
                     add_ca, compute_ca, compute_ov);                         \
886
    tcg_temp_free(t0);                                                        \
887
}
888

    
889
/* add  add.  addo  addo. */
890
GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
891
GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
892
/* addc  addc.  addco  addco. */
893
GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
894
GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
895
/* adde  adde.  addeo  addeo. */
896
GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
897
GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
898
/* addme  addme.  addmeo  addmeo.  */
899
GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
900
GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
901
/* addze  addze.  addzeo  addzeo.*/
902
GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
903
GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
904
/* addi */
905
static void gen_addi(DisasContext *ctx)
906
{
907
    target_long simm = SIMM(ctx->opcode);
908

    
909
    if (rA(ctx->opcode) == 0) {
910
        /* li case */
911
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
912
    } else {
913
        tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm);
914
    }
915
}
916
/* addic  addic.*/
917
static inline void gen_op_addic(DisasContext *ctx, TCGv ret, TCGv arg1,
918
                                int compute_Rc0)
919
{
920
    target_long simm = SIMM(ctx->opcode);
921

    
922
    /* Start with XER CA and OV disabled, the most likely case */
923
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
924

    
925
    if (likely(simm != 0)) {
926
        TCGv t0 = tcg_temp_local_new();
927
        tcg_gen_addi_tl(t0, arg1, simm);
928
        gen_op_arith_compute_ca(ctx, t0, arg1, 0);
929
        tcg_gen_mov_tl(ret, t0);
930
        tcg_temp_free(t0);
931
    } else {
932
        tcg_gen_mov_tl(ret, arg1);
933
    }
934
    if (compute_Rc0) {
935
        gen_set_Rc0(ctx, ret);
936
    }
937
}
938

    
939
static void gen_addic(DisasContext *ctx)
940
{
941
    gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
942
}
943

    
944
static void gen_addic_(DisasContext *ctx)
945
{
946
    gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
947
}
948

    
949
/* addis */
950
static void gen_addis(DisasContext *ctx)
951
{
952
    target_long simm = SIMM(ctx->opcode);
953

    
954
    if (rA(ctx->opcode) == 0) {
955
        /* lis case */
956
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
957
    } else {
958
        tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm << 16);
959
    }
960
}
961

    
962
static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
963
                                     TCGv arg2, int sign, int compute_ov)
964
{
965
    int l1 = gen_new_label();
966
    int l2 = gen_new_label();
967
    TCGv_i32 t0 = tcg_temp_local_new_i32();
968
    TCGv_i32 t1 = tcg_temp_local_new_i32();
969

    
970
    tcg_gen_trunc_tl_i32(t0, arg1);
971
    tcg_gen_trunc_tl_i32(t1, arg2);
972
    tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
973
    if (sign) {
974
        int l3 = gen_new_label();
975
        tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
976
        tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
977
        gen_set_label(l3);
978
        tcg_gen_div_i32(t0, t0, t1);
979
    } else {
980
        tcg_gen_divu_i32(t0, t0, t1);
981
    }
982
    if (compute_ov) {
983
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
984
    }
985
    tcg_gen_br(l2);
986
    gen_set_label(l1);
987
    if (sign) {
988
        tcg_gen_sari_i32(t0, t0, 31);
989
    } else {
990
        tcg_gen_movi_i32(t0, 0);
991
    }
992
    if (compute_ov) {
993
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
994
    }
995
    gen_set_label(l2);
996
    tcg_gen_extu_i32_tl(ret, t0);
997
    tcg_temp_free_i32(t0);
998
    tcg_temp_free_i32(t1);
999
    if (unlikely(Rc(ctx->opcode) != 0))
1000
        gen_set_Rc0(ctx, ret);
1001
}
1002
/* Div functions */
1003
#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
1004
static void glue(gen_, name)(DisasContext *ctx)                                       \
1005
{                                                                             \
1006
    gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1007
                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
1008
                     sign, compute_ov);                                       \
1009
}
1010
/* divwu  divwu.  divwuo  divwuo.   */
1011
GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
1012
GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
1013
/* divw  divw.  divwo  divwo.   */
1014
GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
1015
GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
1016
#if defined(TARGET_PPC64)
1017
static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
1018
                                     TCGv arg2, int sign, int compute_ov)
1019
{
1020
    int l1 = gen_new_label();
1021
    int l2 = gen_new_label();
1022

    
1023
    tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
1024
    if (sign) {
1025
        int l3 = gen_new_label();
1026
        tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
1027
        tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
1028
        gen_set_label(l3);
1029
        tcg_gen_div_i64(ret, arg1, arg2);
1030
    } else {
1031
        tcg_gen_divu_i64(ret, arg1, arg2);
1032
    }
1033
    if (compute_ov) {
1034
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1035
    }
1036
    tcg_gen_br(l2);
1037
    gen_set_label(l1);
1038
    if (sign) {
1039
        tcg_gen_sari_i64(ret, arg1, 63);
1040
    } else {
1041
        tcg_gen_movi_i64(ret, 0);
1042
    }
1043
    if (compute_ov) {
1044
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
1045
    }
1046
    gen_set_label(l2);
1047
    if (unlikely(Rc(ctx->opcode) != 0))
1048
        gen_set_Rc0(ctx, ret);
1049
}
1050
#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
1051
static void glue(gen_, name)(DisasContext *ctx)                                       \
1052
{                                                                             \
1053
    gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1054
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1055
                      sign, compute_ov);                                      \
1056
}
1057
/* divwu  divwu.  divwuo  divwuo.   */
1058
GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
1059
GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
1060
/* divw  divw.  divwo  divwo.   */
1061
GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
1062
GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1063
#endif
1064

    
1065
/* mulhw  mulhw. */
1066
static void gen_mulhw(DisasContext *ctx)
1067
{
1068
    TCGv_i64 t0, t1;
1069

    
1070
    t0 = tcg_temp_new_i64();
1071
    t1 = tcg_temp_new_i64();
1072
#if defined(TARGET_PPC64)
1073
    tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
1074
    tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
1075
    tcg_gen_mul_i64(t0, t0, t1);
1076
    tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
1077
#else
1078
    tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1079
    tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1080
    tcg_gen_mul_i64(t0, t0, t1);
1081
    tcg_gen_shri_i64(t0, t0, 32);
1082
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1083
#endif
1084
    tcg_temp_free_i64(t0);
1085
    tcg_temp_free_i64(t1);
1086
    if (unlikely(Rc(ctx->opcode) != 0))
1087
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1088
}
1089

    
1090
/* mulhwu  mulhwu.  */
1091
static void gen_mulhwu(DisasContext *ctx)
1092
{
1093
    TCGv_i64 t0, t1;
1094

    
1095
    t0 = tcg_temp_new_i64();
1096
    t1 = tcg_temp_new_i64();
1097
#if defined(TARGET_PPC64)
1098
    tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1099
    tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1100
    tcg_gen_mul_i64(t0, t0, t1);
1101
    tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
1102
#else
1103
    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1104
    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1105
    tcg_gen_mul_i64(t0, t0, t1);
1106
    tcg_gen_shri_i64(t0, t0, 32);
1107
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1108
#endif
1109
    tcg_temp_free_i64(t0);
1110
    tcg_temp_free_i64(t1);
1111
    if (unlikely(Rc(ctx->opcode) != 0))
1112
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1113
}
1114

    
1115
/* mullw  mullw. */
1116
static void gen_mullw(DisasContext *ctx)
1117
{
1118
    tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1119
                   cpu_gpr[rB(ctx->opcode)]);
1120
    tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)]);
1121
    if (unlikely(Rc(ctx->opcode) != 0))
1122
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1123
}
1124

    
1125
/* mullwo  mullwo. */
1126
static void gen_mullwo(DisasContext *ctx)
1127
{
1128
    int l1;
1129
    TCGv_i64 t0, t1;
1130

    
1131
    t0 = tcg_temp_new_i64();
1132
    t1 = tcg_temp_new_i64();
1133
    l1 = gen_new_label();
1134
    /* Start with XER OV disabled, the most likely case */
1135
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1136
#if defined(TARGET_PPC64)
1137
    tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1138
    tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1139
#else
1140
    tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1141
    tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1142
#endif
1143
    tcg_gen_mul_i64(t0, t0, t1);
1144
#if defined(TARGET_PPC64)
1145
    tcg_gen_ext32s_i64(cpu_gpr[rD(ctx->opcode)], t0);
1146
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, cpu_gpr[rD(ctx->opcode)], l1);
1147
#else
1148
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1149
    tcg_gen_ext32s_i64(t1, t0);
1150
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
1151
#endif
1152
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
1153
    gen_set_label(l1);
1154
    tcg_temp_free_i64(t0);
1155
    tcg_temp_free_i64(t1);
1156
    if (unlikely(Rc(ctx->opcode) != 0))
1157
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1158
}
1159

    
1160
/* mulli */
1161
static void gen_mulli(DisasContext *ctx)
1162
{
1163
    tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1164
                    SIMM(ctx->opcode));
1165
}
1166
#if defined(TARGET_PPC64)
1167
#define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
1168
static void glue(gen_, name)(DisasContext *ctx)                                       \
1169
{                                                                             \
1170
    gen_helper_##name (cpu_gpr[rD(ctx->opcode)],                              \
1171
                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);   \
1172
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1173
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
1174
}
1175
/* mulhd  mulhd. */
1176
GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00);
1177
/* mulhdu  mulhdu. */
1178
GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02);
1179

    
1180
/* mulld  mulld. */
1181
static void gen_mulld(DisasContext *ctx)
1182
{
1183
    tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1184
                   cpu_gpr[rB(ctx->opcode)]);
1185
    if (unlikely(Rc(ctx->opcode) != 0))
1186
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1187
}
1188
/* mulldo  mulldo. */
1189
GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17);
1190
#endif
1191

    
1192
/* neg neg. nego nego. */
1193
static inline void gen_op_arith_neg(DisasContext *ctx, TCGv ret, TCGv arg1,
1194
                                    int ov_check)
1195
{
1196
    int l1 = gen_new_label();
1197
    int l2 = gen_new_label();
1198
    TCGv t0 = tcg_temp_local_new();
1199
#if defined(TARGET_PPC64)
1200
    if (ctx->sf_mode) {
1201
        tcg_gen_mov_tl(t0, arg1);
1202
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
1203
    } else
1204
#endif
1205
    {
1206
        tcg_gen_ext32s_tl(t0, arg1);
1207
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
1208
    }
1209
    tcg_gen_neg_tl(ret, arg1);
1210
    if (ov_check) {
1211
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1212
    }
1213
    tcg_gen_br(l2);
1214
    gen_set_label(l1);
1215
    tcg_gen_mov_tl(ret, t0);
1216
    if (ov_check) {
1217
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
1218
    }
1219
    gen_set_label(l2);
1220
    tcg_temp_free(t0);
1221
    if (unlikely(Rc(ctx->opcode) != 0))
1222
        gen_set_Rc0(ctx, ret);
1223
}
1224

    
1225
static void gen_neg(DisasContext *ctx)
1226
{
1227
    gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
1228
}
1229

    
1230
static void gen_nego(DisasContext *ctx)
1231
{
1232
    gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
1233
}
1234

    
1235
/* Common subf function */
1236
static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
1237
                                     TCGv arg2, int add_ca, int compute_ca,
1238
                                     int compute_ov)
1239
{
1240
    TCGv t0, t1;
1241

    
1242
    if ((!compute_ca && !compute_ov) ||
1243
        (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2)))  {
1244
        t0 = ret;
1245
    } else {
1246
        t0 = tcg_temp_local_new();
1247
    }
1248

    
1249
    if (add_ca) {
1250
        t1 = tcg_temp_local_new();
1251
        tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
1252
        tcg_gen_shri_tl(t1, t1, XER_CA);
1253
    } else {
1254
        TCGV_UNUSED(t1);
1255
    }
1256

    
1257
    if (compute_ca && compute_ov) {
1258
        /* Start with XER CA and OV disabled, the most likely case */
1259
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
1260
    } else if (compute_ca) {
1261
        /* Start with XER CA disabled, the most likely case */
1262
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1263
    } else if (compute_ov) {
1264
        /* Start with XER OV disabled, the most likely case */
1265
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1266
    }
1267

    
1268
    if (add_ca) {
1269
        tcg_gen_not_tl(t0, arg1);
1270
        tcg_gen_add_tl(t0, t0, arg2);
1271
        gen_op_arith_compute_ca(ctx, t0, arg2, 0);
1272
        tcg_gen_add_tl(t0, t0, t1);
1273
        gen_op_arith_compute_ca(ctx, t0, t1, 0);
1274
        tcg_temp_free(t1);
1275
    } else {
1276
        tcg_gen_sub_tl(t0, arg2, arg1);
1277
        if (compute_ca) {
1278
            gen_op_arith_compute_ca(ctx, t0, arg2, 1);
1279
        }
1280
    }
1281
    if (compute_ov) {
1282
        gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
1283
    }
1284

    
1285
    if (unlikely(Rc(ctx->opcode) != 0))
1286
        gen_set_Rc0(ctx, t0);
1287

    
1288
    if (!TCGV_EQUAL(t0, ret)) {
1289
        tcg_gen_mov_tl(ret, t0);
1290
        tcg_temp_free(t0);
1291
    }
1292
}
1293
/* Sub functions with Two operands functions */
1294
#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
1295
static void glue(gen_, name)(DisasContext *ctx)                                       \
1296
{                                                                             \
1297
    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1298
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1299
                      add_ca, compute_ca, compute_ov);                        \
1300
}
1301
/* Sub functions with one operand and one immediate */
1302
#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
1303
                                add_ca, compute_ca, compute_ov)               \
1304
static void glue(gen_, name)(DisasContext *ctx)                                       \
1305
{                                                                             \
1306
    TCGv t0 = tcg_const_local_tl(const_val);                                  \
1307
    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1308
                      cpu_gpr[rA(ctx->opcode)], t0,                           \
1309
                      add_ca, compute_ca, compute_ov);                        \
1310
    tcg_temp_free(t0);                                                        \
1311
}
1312
/* subf  subf.  subfo  subfo. */
1313
GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
1314
GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
1315
/* subfc  subfc.  subfco  subfco. */
1316
GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
1317
GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
1318
/* subfe  subfe.  subfeo  subfo. */
1319
GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
1320
GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
1321
/* subfme  subfme.  subfmeo  subfmeo.  */
1322
GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
1323
GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
1324
/* subfze  subfze.  subfzeo  subfzeo.*/
1325
GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
1326
GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1327

    
1328
/* subfic */
1329
static void gen_subfic(DisasContext *ctx)
1330
{
1331
    /* Start with XER CA and OV disabled, the most likely case */
1332
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1333
    TCGv t0 = tcg_temp_local_new();
1334
    TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
1335
    tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
1336
    gen_op_arith_compute_ca(ctx, t0, t1, 1);
1337
    tcg_temp_free(t1);
1338
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
1339
    tcg_temp_free(t0);
1340
}
1341

    
1342
/***                            Integer logical                            ***/
1343
#define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
1344
static void glue(gen_, name)(DisasContext *ctx)                                       \
1345
{                                                                             \
1346
    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
1347
       cpu_gpr[rB(ctx->opcode)]);                                             \
1348
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1349
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1350
}
1351

    
1352
#define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1353
static void glue(gen_, name)(DisasContext *ctx)                                       \
1354
{                                                                             \
1355
    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1356
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1357
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1358
}
1359

    
1360
/* and & and. */
1361
GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1362
/* andc & andc. */
1363
GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1364

    
1365
/* andi. */
1366
static void gen_andi_(DisasContext *ctx)
1367
{
1368
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
1369
    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1370
}
1371

    
1372
/* andis. */
1373
static void gen_andis_(DisasContext *ctx)
1374
{
1375
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
1376
    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1377
}
1378

    
1379
/* cntlzw */
1380
static void gen_cntlzw(DisasContext *ctx)
1381
{
1382
    gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1383
    if (unlikely(Rc(ctx->opcode) != 0))
1384
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1385
}
1386
/* eqv & eqv. */
1387
GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1388
/* extsb & extsb. */
1389
GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1390
/* extsh & extsh. */
1391
GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1392
/* nand & nand. */
1393
GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1394
/* nor & nor. */
1395
GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1396

    
1397
/* or & or. */
1398
static void gen_or(DisasContext *ctx)
1399
{
1400
    int rs, ra, rb;
1401

    
1402
    rs = rS(ctx->opcode);
1403
    ra = rA(ctx->opcode);
1404
    rb = rB(ctx->opcode);
1405
    /* Optimisation for mr. ri case */
1406
    if (rs != ra || rs != rb) {
1407
        if (rs != rb)
1408
            tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
1409
        else
1410
            tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1411
        if (unlikely(Rc(ctx->opcode) != 0))
1412
            gen_set_Rc0(ctx, cpu_gpr[ra]);
1413
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1414
        gen_set_Rc0(ctx, cpu_gpr[rs]);
1415
#if defined(TARGET_PPC64)
1416
    } else {
1417
        int prio = 0;
1418

    
1419
        switch (rs) {
1420
        case 1:
1421
            /* Set process priority to low */
1422
            prio = 2;
1423
            break;
1424
        case 6:
1425
            /* Set process priority to medium-low */
1426
            prio = 3;
1427
            break;
1428
        case 2:
1429
            /* Set process priority to normal */
1430
            prio = 4;
1431
            break;
1432
#if !defined(CONFIG_USER_ONLY)
1433
        case 31:
1434
            if (ctx->mem_idx > 0) {
1435
                /* Set process priority to very low */
1436
                prio = 1;
1437
            }
1438
            break;
1439
        case 5:
1440
            if (ctx->mem_idx > 0) {
1441
                /* Set process priority to medium-hight */
1442
                prio = 5;
1443
            }
1444
            break;
1445
        case 3:
1446
            if (ctx->mem_idx > 0) {
1447
                /* Set process priority to high */
1448
                prio = 6;
1449
            }
1450
            break;
1451
        case 7:
1452
            if (ctx->mem_idx > 1) {
1453
                /* Set process priority to very high */
1454
                prio = 7;
1455
            }
1456
            break;
1457
#endif
1458
        default:
1459
            /* nop */
1460
            break;
1461
        }
1462
        if (prio) {
1463
            TCGv t0 = tcg_temp_new();
1464
            gen_load_spr(t0, SPR_PPR);
1465
            tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
1466
            tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
1467
            gen_store_spr(SPR_PPR, t0);
1468
            tcg_temp_free(t0);
1469
        }
1470
#endif
1471
    }
1472
}
1473
/* orc & orc. */
1474
GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1475

    
1476
/* xor & xor. */
1477
static void gen_xor(DisasContext *ctx)
1478
{
1479
    /* Optimisation for "set to zero" case */
1480
    if (rS(ctx->opcode) != rB(ctx->opcode))
1481
        tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1482
    else
1483
        tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1484
    if (unlikely(Rc(ctx->opcode) != 0))
1485
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1486
}
1487

    
1488
/* ori */
1489
static void gen_ori(DisasContext *ctx)
1490
{
1491
    target_ulong uimm = UIMM(ctx->opcode);
1492

    
1493
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1494
        /* NOP */
1495
        /* XXX: should handle special NOPs for POWER series */
1496
        return;
1497
    }
1498
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1499
}
1500

    
1501
/* oris */
1502
static void gen_oris(DisasContext *ctx)
1503
{
1504
    target_ulong uimm = UIMM(ctx->opcode);
1505

    
1506
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1507
        /* NOP */
1508
        return;
1509
    }
1510
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1511
}
1512

    
1513
/* xori */
1514
static void gen_xori(DisasContext *ctx)
1515
{
1516
    target_ulong uimm = UIMM(ctx->opcode);
1517

    
1518
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1519
        /* NOP */
1520
        return;
1521
    }
1522
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1523
}
1524

    
1525
/* xoris */
1526
static void gen_xoris(DisasContext *ctx)
1527
{
1528
    target_ulong uimm = UIMM(ctx->opcode);
1529

    
1530
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1531
        /* NOP */
1532
        return;
1533
    }
1534
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1535
}
1536

    
1537
/* popcntb : PowerPC 2.03 specification */
1538
static void gen_popcntb(DisasContext *ctx)
1539
{
1540
    gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1541
}
1542

    
1543
static void gen_popcntw(DisasContext *ctx)
1544
{
1545
    gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1546
}
1547

    
1548
#if defined(TARGET_PPC64)
1549
/* popcntd: PowerPC 2.06 specification */
1550
static void gen_popcntd(DisasContext *ctx)
1551
{
1552
    gen_helper_popcntd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1553
}
1554
#endif
1555

    
1556
#if defined(TARGET_PPC64)
1557
/* extsw & extsw. */
1558
GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1559

    
1560
/* cntlzd */
1561
static void gen_cntlzd(DisasContext *ctx)
1562
{
1563
    gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1564
    if (unlikely(Rc(ctx->opcode) != 0))
1565
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1566
}
1567
#endif
1568

    
1569
/***                             Integer rotate                            ***/
1570

    
1571
/* rlwimi & rlwimi. */
1572
static void gen_rlwimi(DisasContext *ctx)
1573
{
1574
    uint32_t mb, me, sh;
1575

    
1576
    mb = MB(ctx->opcode);
1577
    me = ME(ctx->opcode);
1578
    sh = SH(ctx->opcode);
1579
    if (likely(sh == 0 && mb == 0 && me == 31)) {
1580
        tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1581
    } else {
1582
        target_ulong mask;
1583
        TCGv t1;
1584
        TCGv t0 = tcg_temp_new();
1585
#if defined(TARGET_PPC64)
1586
        TCGv_i32 t2 = tcg_temp_new_i32();
1587
        tcg_gen_trunc_i64_i32(t2, cpu_gpr[rS(ctx->opcode)]);
1588
        tcg_gen_rotli_i32(t2, t2, sh);
1589
        tcg_gen_extu_i32_i64(t0, t2);
1590
        tcg_temp_free_i32(t2);
1591
#else
1592
        tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1593
#endif
1594
#if defined(TARGET_PPC64)
1595
        mb += 32;
1596
        me += 32;
1597
#endif
1598
        mask = MASK(mb, me);
1599
        t1 = tcg_temp_new();
1600
        tcg_gen_andi_tl(t0, t0, mask);
1601
        tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1602
        tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1603
        tcg_temp_free(t0);
1604
        tcg_temp_free(t1);
1605
    }
1606
    if (unlikely(Rc(ctx->opcode) != 0))
1607
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1608
}
1609

    
1610
/* rlwinm & rlwinm. */
1611
static void gen_rlwinm(DisasContext *ctx)
1612
{
1613
    uint32_t mb, me, sh;
1614

    
1615
    sh = SH(ctx->opcode);
1616
    mb = MB(ctx->opcode);
1617
    me = ME(ctx->opcode);
1618

    
1619
    if (likely(mb == 0 && me == (31 - sh))) {
1620
        if (likely(sh == 0)) {
1621
            tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1622
        } else {
1623
            TCGv t0 = tcg_temp_new();
1624
            tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1625
            tcg_gen_shli_tl(t0, t0, sh);
1626
            tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1627
            tcg_temp_free(t0);
1628
        }
1629
    } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
1630
        TCGv t0 = tcg_temp_new();
1631
        tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1632
        tcg_gen_shri_tl(t0, t0, mb);
1633
        tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1634
        tcg_temp_free(t0);
1635
    } else {
1636
        TCGv t0 = tcg_temp_new();
1637
#if defined(TARGET_PPC64)
1638
        TCGv_i32 t1 = tcg_temp_new_i32();
1639
        tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1640
        tcg_gen_rotli_i32(t1, t1, sh);
1641
        tcg_gen_extu_i32_i64(t0, t1);
1642
        tcg_temp_free_i32(t1);
1643
#else
1644
        tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1645
#endif
1646
#if defined(TARGET_PPC64)
1647
        mb += 32;
1648
        me += 32;
1649
#endif
1650
        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1651
        tcg_temp_free(t0);
1652
    }
1653
    if (unlikely(Rc(ctx->opcode) != 0))
1654
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1655
}
1656

    
1657
/* rlwnm & rlwnm. */
1658
static void gen_rlwnm(DisasContext *ctx)
1659
{
1660
    uint32_t mb, me;
1661
    TCGv t0;
1662
#if defined(TARGET_PPC64)
1663
    TCGv_i32 t1, t2;
1664
#endif
1665

    
1666
    mb = MB(ctx->opcode);
1667
    me = ME(ctx->opcode);
1668
    t0 = tcg_temp_new();
1669
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
1670
#if defined(TARGET_PPC64)
1671
    t1 = tcg_temp_new_i32();
1672
    t2 = tcg_temp_new_i32();
1673
    tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1674
    tcg_gen_trunc_i64_i32(t2, t0);
1675
    tcg_gen_rotl_i32(t1, t1, t2);
1676
    tcg_gen_extu_i32_i64(t0, t1);
1677
    tcg_temp_free_i32(t1);
1678
    tcg_temp_free_i32(t2);
1679
#else
1680
    tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
1681
#endif
1682
    if (unlikely(mb != 0 || me != 31)) {
1683
#if defined(TARGET_PPC64)
1684
        mb += 32;
1685
        me += 32;
1686
#endif
1687
        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1688
    } else {
1689
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1690
    }
1691
    tcg_temp_free(t0);
1692
    if (unlikely(Rc(ctx->opcode) != 0))
1693
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1694
}
1695

    
1696
#if defined(TARGET_PPC64)
1697
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1698
static void glue(gen_, name##0)(DisasContext *ctx)                            \
1699
{                                                                             \
1700
    gen_##name(ctx, 0);                                                       \
1701
}                                                                             \
1702
                                                                              \
1703
static void glue(gen_, name##1)(DisasContext *ctx)                            \
1704
{                                                                             \
1705
    gen_##name(ctx, 1);                                                       \
1706
}
1707
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1708
static void glue(gen_, name##0)(DisasContext *ctx)                            \
1709
{                                                                             \
1710
    gen_##name(ctx, 0, 0);                                                    \
1711
}                                                                             \
1712
                                                                              \
1713
static void glue(gen_, name##1)(DisasContext *ctx)                            \
1714
{                                                                             \
1715
    gen_##name(ctx, 0, 1);                                                    \
1716
}                                                                             \
1717
                                                                              \
1718
static void glue(gen_, name##2)(DisasContext *ctx)                            \
1719
{                                                                             \
1720
    gen_##name(ctx, 1, 0);                                                    \
1721
}                                                                             \
1722
                                                                              \
1723
static void glue(gen_, name##3)(DisasContext *ctx)                            \
1724
{                                                                             \
1725
    gen_##name(ctx, 1, 1);                                                    \
1726
}
1727

    
1728
static inline void gen_rldinm(DisasContext *ctx, uint32_t mb, uint32_t me,
1729
                              uint32_t sh)
1730
{
1731
    if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
1732
        tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
1733
    } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
1734
        tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
1735
    } else {
1736
        TCGv t0 = tcg_temp_new();
1737
        tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1738
        if (likely(mb == 0 && me == 63)) {
1739
            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1740
        } else {
1741
            tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1742
        }
1743
        tcg_temp_free(t0);
1744
    }
1745
    if (unlikely(Rc(ctx->opcode) != 0))
1746
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1747
}
1748
/* rldicl - rldicl. */
1749
static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
1750
{
1751
    uint32_t sh, mb;
1752

    
1753
    sh = SH(ctx->opcode) | (shn << 5);
1754
    mb = MB(ctx->opcode) | (mbn << 5);
1755
    gen_rldinm(ctx, mb, 63, sh);
1756
}
1757
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1758
/* rldicr - rldicr. */
1759
static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
1760
{
1761
    uint32_t sh, me;
1762

    
1763
    sh = SH(ctx->opcode) | (shn << 5);
1764
    me = MB(ctx->opcode) | (men << 5);
1765
    gen_rldinm(ctx, 0, me, sh);
1766
}
1767
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1768
/* rldic - rldic. */
1769
static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
1770
{
1771
    uint32_t sh, mb;
1772

    
1773
    sh = SH(ctx->opcode) | (shn << 5);
1774
    mb = MB(ctx->opcode) | (mbn << 5);
1775
    gen_rldinm(ctx, mb, 63 - sh, sh);
1776
}
1777
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1778

    
1779
static inline void gen_rldnm(DisasContext *ctx, uint32_t mb, uint32_t me)
1780
{
1781
    TCGv t0;
1782

    
1783
    mb = MB(ctx->opcode);
1784
    me = ME(ctx->opcode);
1785
    t0 = tcg_temp_new();
1786
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
1787
    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1788
    if (unlikely(mb != 0 || me != 63)) {
1789
        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1790
    } else {
1791
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1792
    }
1793
    tcg_temp_free(t0);
1794
    if (unlikely(Rc(ctx->opcode) != 0))
1795
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1796
}
1797

    
1798
/* rldcl - rldcl. */
1799
static inline void gen_rldcl(DisasContext *ctx, int mbn)
1800
{
1801
    uint32_t mb;
1802

    
1803
    mb = MB(ctx->opcode) | (mbn << 5);
1804
    gen_rldnm(ctx, mb, 63);
1805
}
1806
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1807
/* rldcr - rldcr. */
1808
static inline void gen_rldcr(DisasContext *ctx, int men)
1809
{
1810
    uint32_t me;
1811

    
1812
    me = MB(ctx->opcode) | (men << 5);
1813
    gen_rldnm(ctx, 0, me);
1814
}
1815
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1816
/* rldimi - rldimi. */
1817
static inline void gen_rldimi(DisasContext *ctx, int mbn, int shn)
1818
{
1819
    uint32_t sh, mb, me;
1820

    
1821
    sh = SH(ctx->opcode) | (shn << 5);
1822
    mb = MB(ctx->opcode) | (mbn << 5);
1823
    me = 63 - sh;
1824
    if (unlikely(sh == 0 && mb == 0)) {
1825
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1826
    } else {
1827
        TCGv t0, t1;
1828
        target_ulong mask;
1829

    
1830
        t0 = tcg_temp_new();
1831
        tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1832
        t1 = tcg_temp_new();
1833
        mask = MASK(mb, me);
1834
        tcg_gen_andi_tl(t0, t0, mask);
1835
        tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1836
        tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1837
        tcg_temp_free(t0);
1838
        tcg_temp_free(t1);
1839
    }
1840
    if (unlikely(Rc(ctx->opcode) != 0))
1841
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1842
}
1843
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1844
#endif
1845

    
1846
/***                             Integer shift                             ***/
1847

    
1848
/* slw & slw. */
1849
static void gen_slw(DisasContext *ctx)
1850
{
1851
    TCGv t0, t1;
1852

    
1853
    t0 = tcg_temp_new();
1854
    /* AND rS with a mask that is 0 when rB >= 0x20 */
1855
#if defined(TARGET_PPC64)
1856
    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
1857
    tcg_gen_sari_tl(t0, t0, 0x3f);
1858
#else
1859
    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
1860
    tcg_gen_sari_tl(t0, t0, 0x1f);
1861
#endif
1862
    tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1863
    t1 = tcg_temp_new();
1864
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
1865
    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1866
    tcg_temp_free(t1);
1867
    tcg_temp_free(t0);
1868
    tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1869
    if (unlikely(Rc(ctx->opcode) != 0))
1870
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1871
}
1872

    
1873
/* sraw & sraw. */
1874
static void gen_sraw(DisasContext *ctx)
1875
{
1876
    gen_helper_sraw(cpu_gpr[rA(ctx->opcode)],
1877
                    cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1878
    if (unlikely(Rc(ctx->opcode) != 0))
1879
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1880
}
1881

    
1882
/* srawi & srawi. */
1883
static void gen_srawi(DisasContext *ctx)
1884
{
1885
    int sh = SH(ctx->opcode);
1886
    if (sh != 0) {
1887
        int l1, l2;
1888
        TCGv t0;
1889
        l1 = gen_new_label();
1890
        l2 = gen_new_label();
1891
        t0 = tcg_temp_local_new();
1892
        tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1893
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
1894
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
1895
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1896
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
1897
        tcg_gen_br(l2);
1898
        gen_set_label(l1);
1899
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1900
        gen_set_label(l2);
1901
        tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1902
        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], t0, sh);
1903
        tcg_temp_free(t0);
1904
    } else {
1905
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1906
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1907
    }
1908
    if (unlikely(Rc(ctx->opcode) != 0))
1909
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1910
}
1911

    
1912
/* srw & srw. */
1913
static void gen_srw(DisasContext *ctx)
1914
{
1915
    TCGv t0, t1;
1916

    
1917
    t0 = tcg_temp_new();
1918
    /* AND rS with a mask that is 0 when rB >= 0x20 */
1919
#if defined(TARGET_PPC64)
1920
    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
1921
    tcg_gen_sari_tl(t0, t0, 0x3f);
1922
#else
1923
    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
1924
    tcg_gen_sari_tl(t0, t0, 0x1f);
1925
#endif
1926
    tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1927
    tcg_gen_ext32u_tl(t0, t0);
1928
    t1 = tcg_temp_new();
1929
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
1930
    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1931
    tcg_temp_free(t1);
1932
    tcg_temp_free(t0);
1933
    if (unlikely(Rc(ctx->opcode) != 0))
1934
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1935
}
1936

    
1937
#if defined(TARGET_PPC64)
1938
/* sld & sld. */
1939
static void gen_sld(DisasContext *ctx)
1940
{
1941
    TCGv t0, t1;
1942

    
1943
    t0 = tcg_temp_new();
1944
    /* AND rS with a mask that is 0 when rB >= 0x40 */
1945
    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
1946
    tcg_gen_sari_tl(t0, t0, 0x3f);
1947
    tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1948
    t1 = tcg_temp_new();
1949
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
1950
    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1951
    tcg_temp_free(t1);
1952
    tcg_temp_free(t0);
1953
    if (unlikely(Rc(ctx->opcode) != 0))
1954
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1955
}
1956

    
1957
/* srad & srad. */
1958
static void gen_srad(DisasContext *ctx)
1959
{
1960
    gen_helper_srad(cpu_gpr[rA(ctx->opcode)],
1961
                    cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1962
    if (unlikely(Rc(ctx->opcode) != 0))
1963
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1964
}
1965
/* sradi & sradi. */
1966
static inline void gen_sradi(DisasContext *ctx, int n)
1967
{
1968
    int sh = SH(ctx->opcode) + (n << 5);
1969
    if (sh != 0) {
1970
        int l1, l2;
1971
        TCGv t0;
1972
        l1 = gen_new_label();
1973
        l2 = gen_new_label();
1974
        t0 = tcg_temp_local_new();
1975
        tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
1976
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
1977
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1978
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
1979
        tcg_gen_br(l2);
1980
        gen_set_label(l1);
1981
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1982
        gen_set_label(l2);
1983
        tcg_temp_free(t0);
1984
        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
1985
    } else {
1986
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1987
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1988
    }
1989
    if (unlikely(Rc(ctx->opcode) != 0))
1990
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1991
}
1992

    
1993
static void gen_sradi0(DisasContext *ctx)
1994
{
1995
    gen_sradi(ctx, 0);
1996
}
1997

    
1998
static void gen_sradi1(DisasContext *ctx)
1999
{
2000
    gen_sradi(ctx, 1);
2001
}
2002

    
2003
/* srd & srd. */
2004
static void gen_srd(DisasContext *ctx)
2005
{
2006
    TCGv t0, t1;
2007

    
2008
    t0 = tcg_temp_new();
2009
    /* AND rS with a mask that is 0 when rB >= 0x40 */
2010
    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2011
    tcg_gen_sari_tl(t0, t0, 0x3f);
2012
    tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2013
    t1 = tcg_temp_new();
2014
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2015
    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2016
    tcg_temp_free(t1);
2017
    tcg_temp_free(t0);
2018
    if (unlikely(Rc(ctx->opcode) != 0))
2019
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2020
}
2021
#endif
2022

    
2023
/***                       Floating-Point arithmetic                       ***/
2024
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
2025
static void gen_f##name(DisasContext *ctx)                                    \
2026
{                                                                             \
2027
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2028
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2029
        return;                                                               \
2030
    }                                                                         \
2031
    /* NIP cannot be restored if the memory exception comes from an helper */ \
2032
    gen_update_nip(ctx, ctx->nip - 4);                                        \
2033
    gen_reset_fpstatus();                                                     \
2034
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
2035
                     cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);     \
2036
    if (isfloat) {                                                            \
2037
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
2038
    }                                                                         \
2039
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], set_fprf,                      \
2040
                     Rc(ctx->opcode) != 0);                                   \
2041
}
2042

    
2043
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
2044
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
2045
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
2046

    
2047
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2048
static void gen_f##name(DisasContext *ctx)                                    \
2049
{                                                                             \
2050
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2051
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2052
        return;                                                               \
2053
    }                                                                         \
2054
    /* NIP cannot be restored if the memory exception comes from an helper */ \
2055
    gen_update_nip(ctx, ctx->nip - 4);                                        \
2056
    gen_reset_fpstatus();                                                     \
2057
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
2058
                     cpu_fpr[rB(ctx->opcode)]);                               \
2059
    if (isfloat) {                                                            \
2060
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
2061
    }                                                                         \
2062
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2063
                     set_fprf, Rc(ctx->opcode) != 0);                         \
2064
}
2065
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
2066
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2067
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2068

    
2069
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2070
static void gen_f##name(DisasContext *ctx)                                    \
2071
{                                                                             \
2072
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2073
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2074
        return;                                                               \
2075
    }                                                                         \
2076
    /* NIP cannot be restored if the memory exception comes from an helper */ \
2077
    gen_update_nip(ctx, ctx->nip - 4);                                        \
2078
    gen_reset_fpstatus();                                                     \
2079
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
2080
                       cpu_fpr[rC(ctx->opcode)]);                             \
2081
    if (isfloat) {                                                            \
2082
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
2083
    }                                                                         \
2084
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2085
                     set_fprf, Rc(ctx->opcode) != 0);                         \
2086
}
2087
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
2088
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2089
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2090

    
2091
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
2092
static void gen_f##name(DisasContext *ctx)                                    \
2093
{                                                                             \
2094
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2095
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2096
        return;                                                               \
2097
    }                                                                         \
2098
    /* NIP cannot be restored if the memory exception comes from an helper */ \
2099
    gen_update_nip(ctx, ctx->nip - 4);                                        \
2100
    gen_reset_fpstatus();                                                     \
2101
    gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
2102
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2103
                     set_fprf, Rc(ctx->opcode) != 0);                         \
2104
}
2105

    
2106
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
2107
static void gen_f##name(DisasContext *ctx)                                    \
2108
{                                                                             \
2109
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2110
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2111
        return;                                                               \
2112
    }                                                                         \
2113
    /* NIP cannot be restored if the memory exception comes from an helper */ \
2114
    gen_update_nip(ctx, ctx->nip - 4);                                        \
2115
    gen_reset_fpstatus();                                                     \
2116
    gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
2117
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2118
                     set_fprf, Rc(ctx->opcode) != 0);                         \
2119
}
2120

    
2121
/* fadd - fadds */
2122
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
2123
/* fdiv - fdivs */
2124
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
2125
/* fmul - fmuls */
2126
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
2127

    
2128
/* fre */
2129
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
2130

    
2131
/* fres */
2132
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
2133

    
2134
/* frsqrte */
2135
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
2136

    
2137
/* frsqrtes */
2138
static void gen_frsqrtes(DisasContext *ctx)
2139
{
2140
    if (unlikely(!ctx->fpu_enabled)) {
2141
        gen_exception(ctx, POWERPC_EXCP_FPU);
2142
        return;
2143
    }
2144
    /* NIP cannot be restored if the memory exception comes from an helper */
2145
    gen_update_nip(ctx, ctx->nip - 4);
2146
    gen_reset_fpstatus();
2147
    gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2148
    gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
2149
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2150
}
2151

    
2152
/* fsel */
2153
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
2154
/* fsub - fsubs */
2155
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
2156
/* Optional: */
2157

    
2158
/* fsqrt */
2159
static void gen_fsqrt(DisasContext *ctx)
2160
{
2161
    if (unlikely(!ctx->fpu_enabled)) {
2162
        gen_exception(ctx, POWERPC_EXCP_FPU);
2163
        return;
2164
    }
2165
    /* NIP cannot be restored if the memory exception comes from an helper */
2166
    gen_update_nip(ctx, ctx->nip - 4);
2167
    gen_reset_fpstatus();
2168
    gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2169
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2170
}
2171

    
2172
static void gen_fsqrts(DisasContext *ctx)
2173
{
2174
    if (unlikely(!ctx->fpu_enabled)) {
2175
        gen_exception(ctx, POWERPC_EXCP_FPU);
2176
        return;
2177
    }
2178
    /* NIP cannot be restored if the memory exception comes from an helper */
2179
    gen_update_nip(ctx, ctx->nip - 4);
2180
    gen_reset_fpstatus();
2181
    gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2182
    gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
2183
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2184
}
2185

    
2186
/***                     Floating-Point multiply-and-add                   ***/
2187
/* fmadd - fmadds */
2188
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
2189
/* fmsub - fmsubs */
2190
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
2191
/* fnmadd - fnmadds */
2192
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
2193
/* fnmsub - fnmsubs */
2194
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
2195

    
2196
/***                     Floating-Point round & convert                    ***/
2197
/* fctiw */
2198
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
2199
/* fctiwz */
2200
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
2201
/* frsp */
2202
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
2203
#if defined(TARGET_PPC64)
2204
/* fcfid */
2205
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
2206
/* fctid */
2207
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
2208
/* fctidz */
2209
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
2210
#endif
2211

    
2212
/* frin */
2213
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
2214
/* friz */
2215
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
2216
/* frip */
2217
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
2218
/* frim */
2219
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
2220

    
2221
/***                         Floating-Point compare                        ***/
2222

    
2223
/* fcmpo */
2224
static void gen_fcmpo(DisasContext *ctx)
2225
{
2226
    TCGv_i32 crf;
2227
    if (unlikely(!ctx->fpu_enabled)) {
2228
        gen_exception(ctx, POWERPC_EXCP_FPU);
2229
        return;
2230
    }
2231
    /* NIP cannot be restored if the memory exception comes from an helper */
2232
    gen_update_nip(ctx, ctx->nip - 4);
2233
    gen_reset_fpstatus();
2234
    crf = tcg_const_i32(crfD(ctx->opcode));
2235
    gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
2236
    tcg_temp_free_i32(crf);
2237
    gen_helper_float_check_status();
2238
}
2239

    
2240
/* fcmpu */
2241
static void gen_fcmpu(DisasContext *ctx)
2242
{
2243
    TCGv_i32 crf;
2244
    if (unlikely(!ctx->fpu_enabled)) {
2245
        gen_exception(ctx, POWERPC_EXCP_FPU);
2246
        return;
2247
    }
2248
    /* NIP cannot be restored if the memory exception comes from an helper */
2249
    gen_update_nip(ctx, ctx->nip - 4);
2250
    gen_reset_fpstatus();
2251
    crf = tcg_const_i32(crfD(ctx->opcode));
2252
    gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
2253
    tcg_temp_free_i32(crf);
2254
    gen_helper_float_check_status();
2255
}
2256

    
2257
/***                         Floating-point move                           ***/
2258
/* fabs */
2259
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
2260
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
2261

    
2262
/* fmr  - fmr. */
2263
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
2264
static void gen_fmr(DisasContext *ctx)
2265
{
2266
    if (unlikely(!ctx->fpu_enabled)) {
2267
        gen_exception(ctx, POWERPC_EXCP_FPU);
2268
        return;
2269
    }
2270
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2271
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2272
}
2273

    
2274
/* fnabs */
2275
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
2276
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
2277
/* fneg */
2278
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
2279
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
2280

    
2281
/***                  Floating-Point status & ctrl register                ***/
2282

    
2283
/* mcrfs */
2284
static void gen_mcrfs(DisasContext *ctx)
2285
{
2286
    int bfa;
2287

    
2288
    if (unlikely(!ctx->fpu_enabled)) {
2289
        gen_exception(ctx, POWERPC_EXCP_FPU);
2290
        return;
2291
    }
2292
    bfa = 4 * (7 - crfS(ctx->opcode));
2293
    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
2294
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
2295
    tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(0xF << bfa));
2296
}
2297

    
2298
/* mffs */
2299
static void gen_mffs(DisasContext *ctx)
2300
{
2301
    if (unlikely(!ctx->fpu_enabled)) {
2302
        gen_exception(ctx, POWERPC_EXCP_FPU);
2303
        return;
2304
    }
2305
    gen_reset_fpstatus();
2306
    tcg_gen_extu_i32_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
2307
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2308
}
2309

    
2310
/* mtfsb0 */
2311
static void gen_mtfsb0(DisasContext *ctx)
2312
{
2313
    uint8_t crb;
2314

    
2315
    if (unlikely(!ctx->fpu_enabled)) {
2316
        gen_exception(ctx, POWERPC_EXCP_FPU);
2317
        return;
2318
    }
2319
    crb = 31 - crbD(ctx->opcode);
2320
    gen_reset_fpstatus();
2321
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
2322
        TCGv_i32 t0;
2323
        /* NIP cannot be restored if the memory exception comes from an helper */
2324
        gen_update_nip(ctx, ctx->nip - 4);
2325
        t0 = tcg_const_i32(crb);
2326
        gen_helper_fpscr_clrbit(t0);
2327
        tcg_temp_free_i32(t0);
2328
    }
2329
    if (unlikely(Rc(ctx->opcode) != 0)) {
2330
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2331
    }
2332
}
2333

    
2334
/* mtfsb1 */
2335
static void gen_mtfsb1(DisasContext *ctx)
2336
{
2337
    uint8_t crb;
2338

    
2339
    if (unlikely(!ctx->fpu_enabled)) {
2340
        gen_exception(ctx, POWERPC_EXCP_FPU);
2341
        return;
2342
    }
2343
    crb = 31 - crbD(ctx->opcode);
2344
    gen_reset_fpstatus();
2345
    /* XXX: we pretend we can only do IEEE floating-point computations */
2346
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
2347
        TCGv_i32 t0;
2348
        /* NIP cannot be restored if the memory exception comes from an helper */
2349
        gen_update_nip(ctx, ctx->nip - 4);
2350
        t0 = tcg_const_i32(crb);
2351
        gen_helper_fpscr_setbit(t0);
2352
        tcg_temp_free_i32(t0);
2353
    }
2354
    if (unlikely(Rc(ctx->opcode) != 0)) {
2355
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2356
    }
2357
    /* We can raise a differed exception */
2358
    gen_helper_float_check_status();
2359
}
2360

    
2361
/* mtfsf */
2362
static void gen_mtfsf(DisasContext *ctx)
2363
{
2364
    TCGv_i32 t0;
2365
    int L = ctx->opcode & 0x02000000;
2366

    
2367
    if (unlikely(!ctx->fpu_enabled)) {
2368
        gen_exception(ctx, POWERPC_EXCP_FPU);
2369
        return;
2370
    }
2371
    /* NIP cannot be restored if the memory exception comes from an helper */
2372
    gen_update_nip(ctx, ctx->nip - 4);
2373
    gen_reset_fpstatus();
2374
    if (L)
2375
        t0 = tcg_const_i32(0xff);
2376
    else
2377
        t0 = tcg_const_i32(FM(ctx->opcode));
2378
    gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
2379
    tcg_temp_free_i32(t0);
2380
    if (unlikely(Rc(ctx->opcode) != 0)) {
2381
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2382
    }
2383
    /* We can raise a differed exception */
2384
    gen_helper_float_check_status();
2385
}
2386

    
2387
/* mtfsfi */
2388
static void gen_mtfsfi(DisasContext *ctx)
2389
{
2390
    int bf, sh;
2391
    TCGv_i64 t0;
2392
    TCGv_i32 t1;
2393

    
2394
    if (unlikely(!ctx->fpu_enabled)) {
2395
        gen_exception(ctx, POWERPC_EXCP_FPU);
2396
        return;
2397
    }
2398
    bf = crbD(ctx->opcode) >> 2;
2399
    sh = 7 - bf;
2400
    /* NIP cannot be restored if the memory exception comes from an helper */
2401
    gen_update_nip(ctx, ctx->nip - 4);
2402
    gen_reset_fpstatus();
2403
    t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
2404
    t1 = tcg_const_i32(1 << sh);
2405
    gen_helper_store_fpscr(t0, t1);
2406
    tcg_temp_free_i64(t0);
2407
    tcg_temp_free_i32(t1);
2408
    if (unlikely(Rc(ctx->opcode) != 0)) {
2409
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2410
    }
2411
    /* We can raise a differed exception */
2412
    gen_helper_float_check_status();
2413
}
2414

    
2415
/***                           Addressing modes                            ***/
2416
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2417
static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
2418
                                      target_long maskl)
2419
{
2420
    target_long simm = SIMM(ctx->opcode);
2421

    
2422
    simm &= ~maskl;
2423
    if (rA(ctx->opcode) == 0) {
2424
#if defined(TARGET_PPC64)
2425
        if (!ctx->sf_mode) {
2426
            tcg_gen_movi_tl(EA, (uint32_t)simm);
2427
        } else
2428
#endif
2429
        tcg_gen_movi_tl(EA, simm);
2430
    } else if (likely(simm != 0)) {
2431
        tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2432
#if defined(TARGET_PPC64)
2433
        if (!ctx->sf_mode) {
2434
            tcg_gen_ext32u_tl(EA, EA);
2435
        }
2436
#endif
2437
    } else {
2438
#if defined(TARGET_PPC64)
2439
        if (!ctx->sf_mode) {
2440
            tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2441
        } else
2442
#endif
2443
        tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2444
    }
2445
}
2446

    
2447
static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
2448
{
2449
    if (rA(ctx->opcode) == 0) {
2450
#if defined(TARGET_PPC64)
2451
        if (!ctx->sf_mode) {
2452
            tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2453
        } else
2454
#endif
2455
        tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2456
    } else {
2457
        tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2458
#if defined(TARGET_PPC64)
2459
        if (!ctx->sf_mode) {
2460
            tcg_gen_ext32u_tl(EA, EA);
2461
        }
2462
#endif
2463
    }
2464
}
2465

    
2466
static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
2467
{
2468
    if (rA(ctx->opcode) == 0) {
2469
        tcg_gen_movi_tl(EA, 0);
2470
    } else {
2471
#if defined(TARGET_PPC64)
2472
        if (!ctx->sf_mode) {
2473
            tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2474
        } else
2475
#endif
2476
            tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2477
    }
2478
}
2479

    
2480
static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
2481
                                target_long val)
2482
{
2483
    tcg_gen_addi_tl(ret, arg1, val);
2484
#if defined(TARGET_PPC64)
2485
    if (!ctx->sf_mode) {
2486
        tcg_gen_ext32u_tl(ret, ret);
2487
    }
2488
#endif
2489
}
2490

    
2491
static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
2492
{
2493
    int l1 = gen_new_label();
2494
    TCGv t0 = tcg_temp_new();
2495
    TCGv_i32 t1, t2;
2496
    /* NIP cannot be restored if the memory exception comes from an helper */
2497
    gen_update_nip(ctx, ctx->nip - 4);
2498
    tcg_gen_andi_tl(t0, EA, mask);
2499
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2500
    t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
2501
    t2 = tcg_const_i32(0);
2502
    gen_helper_raise_exception_err(t1, t2);
2503
    tcg_temp_free_i32(t1);
2504
    tcg_temp_free_i32(t2);
2505
    gen_set_label(l1);
2506
    tcg_temp_free(t0);
2507
}
2508

    
2509
/***                             Integer load                              ***/
2510
static inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2511
{
2512
    tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
2513
}
2514

    
2515
static inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2516
{
2517
    tcg_gen_qemu_ld8s(arg1, arg2, ctx->mem_idx);
2518
}
2519

    
2520
static inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2521
{
2522
    tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2523
    if (unlikely(ctx->le_mode)) {
2524
        tcg_gen_bswap16_tl(arg1, arg1);
2525
    }
2526
}
2527

    
2528
static inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2529
{
2530
    if (unlikely(ctx->le_mode)) {
2531
        tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2532
        tcg_gen_bswap16_tl(arg1, arg1);
2533
        tcg_gen_ext16s_tl(arg1, arg1);
2534
    } else {
2535
        tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
2536
    }
2537
}
2538

    
2539
static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2540
{
2541
    tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2542
    if (unlikely(ctx->le_mode)) {
2543
        tcg_gen_bswap32_tl(arg1, arg1);
2544
    }
2545
}
2546

    
2547
#if defined(TARGET_PPC64)
2548
static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2549
{
2550
    if (unlikely(ctx->le_mode)) {
2551
        tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2552
        tcg_gen_bswap32_tl(arg1, arg1);
2553
        tcg_gen_ext32s_tl(arg1, arg1);
2554
    } else
2555
        tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
2556
}
2557
#endif
2558

    
2559
static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2560
{
2561
    tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
2562
    if (unlikely(ctx->le_mode)) {
2563
        tcg_gen_bswap64_i64(arg1, arg1);
2564
    }
2565
}
2566

    
2567
static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
2568
{
2569
    tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
2570
}
2571

    
2572
static inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
2573
{
2574
    if (unlikely(ctx->le_mode)) {
2575
        TCGv t0 = tcg_temp_new();
2576
        tcg_gen_ext16u_tl(t0, arg1);
2577
        tcg_gen_bswap16_tl(t0, t0);
2578
        tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
2579
        tcg_temp_free(t0);
2580
    } else {
2581
        tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
2582
    }
2583
}
2584

    
2585
static inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
2586
{
2587
    if (unlikely(ctx->le_mode)) {
2588
        TCGv t0 = tcg_temp_new();
2589
        tcg_gen_ext32u_tl(t0, arg1);
2590
        tcg_gen_bswap32_tl(t0, t0);
2591
        tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
2592
        tcg_temp_free(t0);
2593
    } else {
2594
        tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
2595
    }
2596
}
2597

    
2598
static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2599
{
2600
    if (unlikely(ctx->le_mode)) {
2601
        TCGv_i64 t0 = tcg_temp_new_i64();
2602
        tcg_gen_bswap64_i64(t0, arg1);
2603
        tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
2604
        tcg_temp_free_i64(t0);
2605
    } else
2606
        tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
2607
}
2608

    
2609
#define GEN_LD(name, ldop, opc, type)                                         \
2610
static void glue(gen_, name)(DisasContext *ctx)                                       \
2611
{                                                                             \
2612
    TCGv EA;                                                                  \
2613
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2614
    EA = tcg_temp_new();                                                      \
2615
    gen_addr_imm_index(ctx, EA, 0);                                           \
2616
    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2617
    tcg_temp_free(EA);                                                        \
2618
}
2619

    
2620
#define GEN_LDU(name, ldop, opc, type)                                        \
2621
static void glue(gen_, name##u)(DisasContext *ctx)                                    \
2622
{                                                                             \
2623
    TCGv EA;                                                                  \
2624
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2625
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2626
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2627
        return;                                                               \
2628
    }                                                                         \
2629
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2630
    EA = tcg_temp_new();                                                      \
2631
    if (type == PPC_64B)                                                      \
2632
        gen_addr_imm_index(ctx, EA, 0x03);                                    \
2633
    else                                                                      \
2634
        gen_addr_imm_index(ctx, EA, 0);                                       \
2635
    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2636
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2637
    tcg_temp_free(EA);                                                        \
2638
}
2639

    
2640
#define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
2641
static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
2642
{                                                                             \
2643
    TCGv EA;                                                                  \
2644
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2645
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2646
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2647
        return;                                                               \
2648
    }                                                                         \
2649
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2650
    EA = tcg_temp_new();                                                      \
2651
    gen_addr_reg_index(ctx, EA);                                              \
2652
    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2653
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2654
    tcg_temp_free(EA);                                                        \
2655
}
2656

    
2657
#define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
2658
static void glue(gen_, name##x)(DisasContext *ctx)                            \
2659
{                                                                             \
2660
    TCGv EA;                                                                  \
2661
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2662
    EA = tcg_temp_new();                                                      \
2663
    gen_addr_reg_index(ctx, EA);                                              \
2664
    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2665
    tcg_temp_free(EA);                                                        \
2666
}
2667

    
2668
#define GEN_LDS(name, ldop, op, type)                                         \
2669
GEN_LD(name, ldop, op | 0x20, type);                                          \
2670
GEN_LDU(name, ldop, op | 0x21, type);                                         \
2671
GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
2672
GEN_LDX(name, ldop, 0x17, op | 0x00, type)
2673

    
2674
/* lbz lbzu lbzux lbzx */
2675
GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
2676
/* lha lhau lhaux lhax */
2677
GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
2678
/* lhz lhzu lhzux lhzx */
2679
GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
2680
/* lwz lwzu lwzux lwzx */
2681
GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
2682
#if defined(TARGET_PPC64)
2683
/* lwaux */
2684
GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
2685
/* lwax */
2686
GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
2687
/* ldux */
2688
GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
2689
/* ldx */
2690
GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
2691

    
2692
static void gen_ld(DisasContext *ctx)
2693
{
2694
    TCGv EA;
2695
    if (Rc(ctx->opcode)) {
2696
        if (unlikely(rA(ctx->opcode) == 0 ||
2697
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2698
            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2699
            return;
2700
        }
2701
    }
2702
    gen_set_access_type(ctx, ACCESS_INT);
2703
    EA = tcg_temp_new();
2704
    gen_addr_imm_index(ctx, EA, 0x03);
2705
    if (ctx->opcode & 0x02) {
2706
        /* lwa (lwau is undefined) */
2707
        gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2708
    } else {
2709
        /* ld - ldu */
2710
        gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2711
    }
2712
    if (Rc(ctx->opcode))
2713
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2714
    tcg_temp_free(EA);
2715
}
2716

    
2717
/* lq */
2718
static void gen_lq(DisasContext *ctx)
2719
{
2720
#if defined(CONFIG_USER_ONLY)
2721
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2722
#else
2723
    int ra, rd;
2724
    TCGv EA;
2725

    
2726
    /* Restore CPU state */
2727
    if (unlikely(ctx->mem_idx == 0)) {
2728
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2729
        return;
2730
    }
2731
    ra = rA(ctx->opcode);
2732
    rd = rD(ctx->opcode);
2733
    if (unlikely((rd & 1) || rd == ra)) {
2734
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2735
        return;
2736
    }
2737
    if (unlikely(ctx->le_mode)) {
2738
        /* Little-endian mode is not handled */
2739
        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2740
        return;
2741
    }
2742
    gen_set_access_type(ctx, ACCESS_INT);
2743
    EA = tcg_temp_new();
2744
    gen_addr_imm_index(ctx, EA, 0x0F);
2745
    gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
2746
    gen_addr_add(ctx, EA, EA, 8);
2747
    gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
2748
    tcg_temp_free(EA);
2749
#endif
2750
}
2751
#endif
2752

    
2753
/***                              Integer store                            ***/
2754
#define GEN_ST(name, stop, opc, type)                                         \
2755
static void glue(gen_, name)(DisasContext *ctx)                                       \
2756
{                                                                             \
2757
    TCGv EA;                                                                  \
2758
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2759
    EA = tcg_temp_new();                                                      \
2760
    gen_addr_imm_index(ctx, EA, 0);                                           \
2761
    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2762
    tcg_temp_free(EA);                                                        \
2763
}
2764

    
2765
#define GEN_STU(name, stop, opc, type)                                        \
2766
static void glue(gen_, stop##u)(DisasContext *ctx)                                    \
2767
{                                                                             \
2768
    TCGv EA;                                                                  \
2769
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2770
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2771
        return;                                                               \
2772
    }                                                                         \
2773
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2774
    EA = tcg_temp_new();                                                      \
2775
    if (type == PPC_64B)                                                      \
2776
        gen_addr_imm_index(ctx, EA, 0x03);                                    \
2777
    else                                                                      \
2778
        gen_addr_imm_index(ctx, EA, 0);                                       \
2779
    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2780
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2781
    tcg_temp_free(EA);                                                        \
2782
}
2783

    
2784
#define GEN_STUX(name, stop, opc2, opc3, type)                                \
2785
static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
2786
{                                                                             \
2787
    TCGv EA;                                                                  \
2788
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2789
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2790
        return;                                                               \
2791
    }                                                                         \
2792
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2793
    EA = tcg_temp_new();                                                      \
2794
    gen_addr_reg_index(ctx, EA);                                              \
2795
    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2796
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2797
    tcg_temp_free(EA);                                                        \
2798
}
2799

    
2800
#define GEN_STX(name, stop, opc2, opc3, type)                                 \
2801
static void glue(gen_, name##x)(DisasContext *ctx)                                    \
2802
{                                                                             \
2803
    TCGv EA;                                                                  \
2804
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2805
    EA = tcg_temp_new();                                                      \
2806
    gen_addr_reg_index(ctx, EA);                                              \
2807
    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2808
    tcg_temp_free(EA);                                                        \
2809
}
2810

    
2811
#define GEN_STS(name, stop, op, type)                                         \
2812
GEN_ST(name, stop, op | 0x20, type);                                          \
2813
GEN_STU(name, stop, op | 0x21, type);                                         \
2814
GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
2815
GEN_STX(name, stop, 0x17, op | 0x00, type)
2816

    
2817
/* stb stbu stbux stbx */
2818
GEN_STS(stb, st8, 0x06, PPC_INTEGER);
2819
/* sth sthu sthux sthx */
2820
GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
2821
/* stw stwu stwux stwx */
2822
GEN_STS(stw, st32, 0x04, PPC_INTEGER);
2823
#if defined(TARGET_PPC64)
2824
GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
2825
GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
2826

    
2827
static void gen_std(DisasContext *ctx)
2828
{
2829
    int rs;
2830
    TCGv EA;
2831

    
2832
    rs = rS(ctx->opcode);
2833
    if ((ctx->opcode & 0x3) == 0x2) {
2834
#if defined(CONFIG_USER_ONLY)
2835
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2836
#else
2837
        /* stq */
2838
        if (unlikely(ctx->mem_idx == 0)) {
2839
            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2840
            return;
2841
        }
2842
        if (unlikely(rs & 1)) {
2843
            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2844
            return;
2845
        }
2846
        if (unlikely(ctx->le_mode)) {
2847
            /* Little-endian mode is not handled */
2848
            gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2849
            return;
2850
        }
2851
        gen_set_access_type(ctx, ACCESS_INT);
2852
        EA = tcg_temp_new();
2853
        gen_addr_imm_index(ctx, EA, 0x03);
2854
        gen_qemu_st64(ctx, cpu_gpr[rs], EA);
2855
        gen_addr_add(ctx, EA, EA, 8);
2856
        gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
2857
        tcg_temp_free(EA);
2858
#endif
2859
    } else {
2860
        /* std / stdu */
2861
        if (Rc(ctx->opcode)) {
2862
            if (unlikely(rA(ctx->opcode) == 0)) {
2863
                gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2864
                return;
2865
            }
2866
        }
2867
        gen_set_access_type(ctx, ACCESS_INT);
2868
        EA = tcg_temp_new();
2869
        gen_addr_imm_index(ctx, EA, 0x03);
2870
        gen_qemu_st64(ctx, cpu_gpr[rs], EA);
2871
        if (Rc(ctx->opcode))
2872
            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2873
        tcg_temp_free(EA);
2874
    }
2875
}
2876
#endif
2877
/***                Integer load and store with byte reverse               ***/
2878
/* lhbrx */
2879
static inline void gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
2880
{
2881
    tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2882
    if (likely(!ctx->le_mode)) {
2883
        tcg_gen_bswap16_tl(arg1, arg1);
2884
    }
2885
}
2886
GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
2887

    
2888
/* lwbrx */
2889
static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
2890
{
2891
    tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2892
    if (likely(!ctx->le_mode)) {
2893
        tcg_gen_bswap32_tl(arg1, arg1);
2894
    }
2895
}
2896
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
2897

    
2898
/* sthbrx */
2899
static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
2900
{
2901
    if (likely(!ctx->le_mode)) {
2902
        TCGv t0 = tcg_temp_new();
2903
        tcg_gen_ext16u_tl(t0, arg1);
2904
        tcg_gen_bswap16_tl(t0, t0);
2905
        tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
2906
        tcg_temp_free(t0);
2907
    } else {
2908
        tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
2909
    }
2910
}
2911
GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
2912

    
2913
/* stwbrx */
2914
static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
2915
{
2916
    if (likely(!ctx->le_mode)) {
2917
        TCGv t0 = tcg_temp_new();
2918
        tcg_gen_ext32u_tl(t0, arg1);
2919
        tcg_gen_bswap32_tl(t0, t0);
2920
        tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
2921
        tcg_temp_free(t0);
2922
    } else {
2923
        tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
2924
    }
2925
}
2926
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
2927

    
2928
/***                    Integer load and store multiple                    ***/
2929

    
2930
/* lmw */
2931
static void gen_lmw(DisasContext *ctx)
2932
{
2933
    TCGv t0;
2934
    TCGv_i32 t1;
2935
    gen_set_access_type(ctx, ACCESS_INT);
2936
    /* NIP cannot be restored if the memory exception comes from an helper */
2937
    gen_update_nip(ctx, ctx->nip - 4);
2938
    t0 = tcg_temp_new();
2939
    t1 = tcg_const_i32(rD(ctx->opcode));
2940
    gen_addr_imm_index(ctx, t0, 0);
2941
    gen_helper_lmw(t0, t1);
2942
    tcg_temp_free(t0);
2943
    tcg_temp_free_i32(t1);
2944
}
2945

    
2946
/* stmw */
2947
static void gen_stmw(DisasContext *ctx)
2948
{
2949
    TCGv t0;
2950
    TCGv_i32 t1;
2951
    gen_set_access_type(ctx, ACCESS_INT);
2952
    /* NIP cannot be restored if the memory exception comes from an helper */
2953
    gen_update_nip(ctx, ctx->nip - 4);
2954
    t0 = tcg_temp_new();
2955
    t1 = tcg_const_i32(rS(ctx->opcode));
2956
    gen_addr_imm_index(ctx, t0, 0);
2957
    gen_helper_stmw(t0, t1);
2958
    tcg_temp_free(t0);
2959
    tcg_temp_free_i32(t1);
2960
}
2961

    
2962
/***                    Integer load and store strings                     ***/
2963

    
2964
/* lswi */
2965
/* PowerPC32 specification says we must generate an exception if
2966
 * rA is in the range of registers to be loaded.
2967
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2968
 * For now, I'll follow the spec...
2969
 */
2970
static void gen_lswi(DisasContext *ctx)
2971
{
2972
    TCGv t0;
2973
    TCGv_i32 t1, t2;
2974
    int nb = NB(ctx->opcode);
2975
    int start = rD(ctx->opcode);
2976
    int ra = rA(ctx->opcode);
2977
    int nr;
2978

    
2979
    if (nb == 0)
2980
        nb = 32;
2981
    nr = nb / 4;
2982
    if (unlikely(((start + nr) > 32  &&
2983
                  start <= ra && (start + nr - 32) > ra) ||
2984
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2985
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
2986
        return;
2987
    }
2988
    gen_set_access_type(ctx, ACCESS_INT);
2989
    /* NIP cannot be restored if the memory exception comes from an helper */
2990
    gen_update_nip(ctx, ctx->nip - 4);
2991
    t0 = tcg_temp_new();
2992
    gen_addr_register(ctx, t0);
2993
    t1 = tcg_const_i32(nb);
2994
    t2 = tcg_const_i32(start);
2995
    gen_helper_lsw(t0, t1, t2);
2996
    tcg_temp_free(t0);
2997
    tcg_temp_free_i32(t1);
2998
    tcg_temp_free_i32(t2);
2999
}
3000

    
3001
/* lswx */
3002
static void gen_lswx(DisasContext *ctx)
3003
{
3004
    TCGv t0;
3005
    TCGv_i32 t1, t2, t3;
3006
    gen_set_access_type(ctx, ACCESS_INT);
3007
    /* NIP cannot be restored if the memory exception comes from an helper */
3008
    gen_update_nip(ctx, ctx->nip - 4);
3009
    t0 = tcg_temp_new();
3010
    gen_addr_reg_index(ctx, t0);
3011
    t1 = tcg_const_i32(rD(ctx->opcode));
3012
    t2 = tcg_const_i32(rA(ctx->opcode));
3013
    t3 = tcg_const_i32(rB(ctx->opcode));
3014
    gen_helper_lswx(t0, t1, t2, t3);
3015
    tcg_temp_free(t0);
3016
    tcg_temp_free_i32(t1);
3017
    tcg_temp_free_i32(t2);
3018
    tcg_temp_free_i32(t3);
3019
}
3020

    
3021
/* stswi */
3022
static void gen_stswi(DisasContext *ctx)
3023
{
3024
    TCGv t0;
3025
    TCGv_i32 t1, t2;
3026
    int nb = NB(ctx->opcode);
3027
    gen_set_access_type(ctx, ACCESS_INT);
3028
    /* NIP cannot be restored if the memory exception comes from an helper */
3029
    gen_update_nip(ctx, ctx->nip - 4);
3030
    t0 = tcg_temp_new();
3031
    gen_addr_register(ctx, t0);
3032
    if (nb == 0)
3033
        nb = 32;
3034
    t1 = tcg_const_i32(nb);
3035
    t2 = tcg_const_i32(rS(ctx->opcode));
3036
    gen_helper_stsw(t0, t1, t2);
3037
    tcg_temp_free(t0);
3038
    tcg_temp_free_i32(t1);
3039
    tcg_temp_free_i32(t2);
3040
}
3041

    
3042
/* stswx */
3043
static void gen_stswx(DisasContext *ctx)
3044
{
3045
    TCGv t0;
3046
    TCGv_i32 t1, t2;
3047
    gen_set_access_type(ctx, ACCESS_INT);
3048
    /* NIP cannot be restored if the memory exception comes from an helper */
3049
    gen_update_nip(ctx, ctx->nip - 4);
3050
    t0 = tcg_temp_new();
3051
    gen_addr_reg_index(ctx, t0);
3052
    t1 = tcg_temp_new_i32();
3053
    tcg_gen_trunc_tl_i32(t1, cpu_xer);
3054
    tcg_gen_andi_i32(t1, t1, 0x7F);
3055
    t2 = tcg_const_i32(rS(ctx->opcode));
3056
    gen_helper_stsw(t0, t1, t2);
3057
    tcg_temp_free(t0);
3058
    tcg_temp_free_i32(t1);
3059
    tcg_temp_free_i32(t2);
3060
}
3061

    
3062
/***                        Memory synchronisation                         ***/
3063
/* eieio */
3064
static void gen_eieio(DisasContext *ctx)
3065
{
3066
}
3067

    
3068
/* isync */
3069
static void gen_isync(DisasContext *ctx)
3070
{
3071
    gen_stop_exception(ctx);
3072
}
3073

    
3074
/* lwarx */
3075
static void gen_lwarx(DisasContext *ctx)
3076
{
3077
    TCGv t0;
3078
    TCGv gpr = cpu_gpr[rD(ctx->opcode)];
3079
    gen_set_access_type(ctx, ACCESS_RES);
3080
    t0 = tcg_temp_local_new();
3081
    gen_addr_reg_index(ctx, t0);
3082
    gen_check_align(ctx, t0, 0x03);
3083
    gen_qemu_ld32u(ctx, gpr, t0);
3084
    tcg_gen_mov_tl(cpu_reserve, t0);
3085
    tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUState, reserve_val));
3086
    tcg_temp_free(t0);
3087
}
3088

    
3089
#if defined(CONFIG_USER_ONLY)
3090
static void gen_conditional_store (DisasContext *ctx, TCGv EA,
3091
                                   int reg, int size)
3092
{
3093
    TCGv t0 = tcg_temp_new();
3094
    uint32_t save_exception = ctx->exception;
3095

    
3096
    tcg_gen_st_tl(EA, cpu_env, offsetof(CPUState, reserve_ea));
3097
    tcg_gen_movi_tl(t0, (size << 5) | reg);
3098
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, reserve_info));
3099
    tcg_temp_free(t0);
3100
    gen_update_nip(ctx, ctx->nip-4);
3101
    ctx->exception = POWERPC_EXCP_BRANCH;
3102
    gen_exception(ctx, POWERPC_EXCP_STCX);
3103
    ctx->exception = save_exception;
3104
}
3105
#endif
3106

    
3107
/* stwcx. */
3108
static void gen_stwcx_(DisasContext *ctx)
3109
{
3110
    TCGv t0;
3111
    gen_set_access_type(ctx, ACCESS_RES);
3112
    t0 = tcg_temp_local_new();
3113
    gen_addr_reg_index(ctx, t0);
3114
    gen_check_align(ctx, t0, 0x03);
3115
#if defined(CONFIG_USER_ONLY)
3116
    gen_conditional_store(ctx, t0, rS(ctx->opcode), 4);
3117
#else
3118
    {
3119
        int l1;
3120

    
3121
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
3122
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
3123
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
3124
        l1 = gen_new_label();
3125
        tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
3126
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3127
        gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
3128
        gen_set_label(l1);
3129
        tcg_gen_movi_tl(cpu_reserve, -1);
3130
    }
3131
#endif
3132
    tcg_temp_free(t0);
3133
}
3134

    
3135
#if defined(TARGET_PPC64)
3136
/* ldarx */
3137
static void gen_ldarx(DisasContext *ctx)
3138
{
3139
    TCGv t0;
3140
    TCGv gpr = cpu_gpr[rD(ctx->opcode)];
3141
    gen_set_access_type(ctx, ACCESS_RES);
3142
    t0 = tcg_temp_local_new();
3143
    gen_addr_reg_index(ctx, t0);
3144
    gen_check_align(ctx, t0, 0x07);
3145
    gen_qemu_ld64(ctx, gpr, t0);
3146
    tcg_gen_mov_tl(cpu_reserve, t0);
3147
    tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUState, reserve_val));
3148
    tcg_temp_free(t0);
3149
}
3150

    
3151
/* stdcx. */
3152
static void gen_stdcx_(DisasContext *ctx)
3153
{
3154
    TCGv t0;
3155
    gen_set_access_type(ctx, ACCESS_RES);
3156
    t0 = tcg_temp_local_new();
3157
    gen_addr_reg_index(ctx, t0);
3158
    gen_check_align(ctx, t0, 0x07);
3159
#if defined(CONFIG_USER_ONLY)
3160
    gen_conditional_store(ctx, t0, rS(ctx->opcode), 8);
3161
#else
3162
    {
3163
        int l1;
3164
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
3165
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
3166
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
3167
        l1 = gen_new_label();
3168
        tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
3169
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3170
        gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
3171
        gen_set_label(l1);
3172
        tcg_gen_movi_tl(cpu_reserve, -1);
3173
    }
3174
#endif
3175
    tcg_temp_free(t0);
3176
}
3177
#endif /* defined(TARGET_PPC64) */
3178

    
3179
/* sync */
3180
static void gen_sync(DisasContext *ctx)
3181
{
3182
}
3183

    
3184
/* wait */
3185
static void gen_wait(DisasContext *ctx)
3186
{
3187
    TCGv_i32 t0 = tcg_temp_new_i32();
3188
    tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, halted));
3189
    tcg_temp_free_i32(t0);
3190
    /* Stop translation, as the CPU is supposed to sleep from now */
3191
    gen_exception_err(ctx, EXCP_HLT, 1);
3192
}
3193

    
3194
/***                         Floating-point load                           ***/
3195
#define GEN_LDF(name, ldop, opc, type)                                        \
3196
static void glue(gen_, name)(DisasContext *ctx)                                       \
3197
{                                                                             \
3198
    TCGv EA;                                                                  \
3199
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3200
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3201
        return;                                                               \
3202
    }                                                                         \
3203
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3204
    EA = tcg_temp_new();                                                      \
3205
    gen_addr_imm_index(ctx, EA, 0);                                           \
3206
    gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3207
    tcg_temp_free(EA);                                                        \
3208
}
3209

    
3210
#define GEN_LDUF(name, ldop, opc, type)                                       \
3211
static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3212
{                                                                             \
3213
    TCGv EA;                                                                  \
3214
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3215
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3216
        return;                                                               \
3217
    }                                                                         \
3218
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3219
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3220
        return;                                                               \
3221
    }                                                                         \
3222
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3223
    EA = tcg_temp_new();                                                      \
3224
    gen_addr_imm_index(ctx, EA, 0);                                           \
3225
    gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3226
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3227
    tcg_temp_free(EA);                                                        \
3228
}
3229

    
3230
#define GEN_LDUXF(name, ldop, opc, type)                                      \
3231
static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3232
{                                                                             \
3233
    TCGv EA;                                                                  \
3234
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3235
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3236
        return;                                                               \
3237
    }                                                                         \
3238
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3239
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3240
        return;                                                               \
3241
    }                                                                         \
3242
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3243
    EA = tcg_temp_new();                                                      \
3244
    gen_addr_reg_index(ctx, EA);                                              \
3245
    gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3246
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3247
    tcg_temp_free(EA);                                                        \
3248
}
3249

    
3250
#define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
3251
static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3252
{                                                                             \
3253
    TCGv EA;                                                                  \
3254
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3255
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3256
        return;                                                               \
3257
    }                                                                         \
3258
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3259
    EA = tcg_temp_new();                                                      \
3260
    gen_addr_reg_index(ctx, EA);                                              \
3261
    gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3262
    tcg_temp_free(EA);                                                        \
3263
}
3264

    
3265
#define GEN_LDFS(name, ldop, op, type)                                        \
3266
GEN_LDF(name, ldop, op | 0x20, type);                                         \
3267
GEN_LDUF(name, ldop, op | 0x21, type);                                        \
3268
GEN_LDUXF(name, ldop, op | 0x01, type);                                       \
3269
GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
3270

    
3271
static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3272
{
3273
    TCGv t0 = tcg_temp_new();
3274
    TCGv_i32 t1 = tcg_temp_new_i32();
3275
    gen_qemu_ld32u(ctx, t0, arg2);
3276
    tcg_gen_trunc_tl_i32(t1, t0);
3277
    tcg_temp_free(t0);
3278
    gen_helper_float32_to_float64(arg1, t1);
3279
    tcg_temp_free_i32(t1);
3280
}
3281

    
3282
 /* lfd lfdu lfdux lfdx */
3283
GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
3284
 /* lfs lfsu lfsux lfsx */
3285
GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
3286

    
3287
/***                         Floating-point store                          ***/
3288
#define GEN_STF(name, stop, opc, type)                                        \
3289
static void glue(gen_, name)(DisasContext *ctx)                                       \
3290
{                                                                             \
3291
    TCGv EA;                                                                  \
3292
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3293
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3294
        return;                                                               \
3295
    }                                                                         \
3296
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3297
    EA = tcg_temp_new();                                                      \
3298
    gen_addr_imm_index(ctx, EA, 0);                                           \
3299
    gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3300
    tcg_temp_free(EA);                                                        \
3301
}
3302

    
3303
#define GEN_STUF(name, stop, opc, type)                                       \
3304
static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3305
{                                                                             \
3306
    TCGv EA;                                                                  \
3307
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3308
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3309
        return;                                                               \
3310
    }                                                                         \
3311
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3312
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3313
        return;                                                               \
3314
    }                                                                         \
3315
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3316
    EA = tcg_temp_new();                                                      \
3317
    gen_addr_imm_index(ctx, EA, 0);                                           \
3318
    gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3319
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3320
    tcg_temp_free(EA);                                                        \
3321
}
3322

    
3323
#define GEN_STUXF(name, stop, opc, type)                                      \
3324
static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3325
{                                                                             \
3326
    TCGv EA;                                                                  \
3327
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3328
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3329
        return;                                                               \
3330
    }                                                                         \
3331
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3332
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3333
        return;                                                               \
3334
    }                                                                         \
3335
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3336
    EA = tcg_temp_new();                                                      \
3337
    gen_addr_reg_index(ctx, EA);                                              \
3338
    gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3339
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3340
    tcg_temp_free(EA);                                                        \
3341
}
3342

    
3343
#define GEN_STXF(name, stop, opc2, opc3, type)                                \
3344
static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3345
{                                                                             \
3346
    TCGv EA;                                                                  \
3347
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3348
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3349
        return;                                                               \
3350
    }                                                                         \
3351
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3352
    EA = tcg_temp_new();                                                      \
3353
    gen_addr_reg_index(ctx, EA);                                              \
3354
    gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3355
    tcg_temp_free(EA);                                                        \
3356
}
3357

    
3358
#define GEN_STFS(name, stop, op, type)                                        \
3359
GEN_STF(name, stop, op | 0x20, type);                                         \
3360
GEN_STUF(name, stop, op | 0x21, type);                                        \
3361
GEN_STUXF(name, stop, op | 0x01, type);                                       \
3362
GEN_STXF(name, stop, 0x17, op | 0x00, type)
3363

    
3364
static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3365
{
3366
    TCGv_i32 t0 = tcg_temp_new_i32();
3367
    TCGv t1 = tcg_temp_new();
3368
    gen_helper_float64_to_float32(t0, arg1);
3369
    tcg_gen_extu_i32_tl(t1, t0);
3370
    tcg_temp_free_i32(t0);
3371
    gen_qemu_st32(ctx, t1, arg2);
3372
    tcg_temp_free(t1);
3373
}
3374

    
3375
/* stfd stfdu stfdux stfdx */
3376
GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
3377
/* stfs stfsu stfsux stfsx */
3378
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
3379

    
3380
/* Optional: */
3381
static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3382
{
3383
    TCGv t0 = tcg_temp_new();
3384
    tcg_gen_trunc_i64_tl(t0, arg1),
3385
    gen_qemu_st32(ctx, t0, arg2);
3386
    tcg_temp_free(t0);
3387
}
3388
/* stfiwx */
3389
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
3390

    
3391
static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
3392
{
3393
#if defined(TARGET_PPC64)
3394
    if (ctx->has_cfar)
3395
        tcg_gen_movi_tl(cpu_cfar, nip);
3396
#endif
3397
}
3398

    
3399
/***                                Branch                                 ***/
3400
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3401
{
3402
    TranslationBlock *tb;
3403
    tb = ctx->tb;
3404
#if defined(TARGET_PPC64)
3405
    if (!ctx->sf_mode)
3406
        dest = (uint32_t) dest;
3407
#endif
3408
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3409
        likely(!ctx->singlestep_enabled)) {
3410
        tcg_gen_goto_tb(n);
3411
        tcg_gen_movi_tl(cpu_nip, dest & ~3);
3412
        tcg_gen_exit_tb((tcg_target_long)tb + n);
3413
    } else {
3414
        tcg_gen_movi_tl(cpu_nip, dest & ~3);
3415
        if (unlikely(ctx->singlestep_enabled)) {
3416
            if ((ctx->singlestep_enabled &
3417
                (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
3418
                ctx->exception == POWERPC_EXCP_BRANCH) {
3419
                target_ulong tmp = ctx->nip;
3420
                ctx->nip = dest;
3421
                gen_exception(ctx, POWERPC_EXCP_TRACE);
3422
                ctx->nip = tmp;
3423
            }
3424
            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3425
                gen_debug_exception(ctx);
3426
            }
3427
        }
3428
        tcg_gen_exit_tb(0);
3429
    }
3430
}
3431

    
3432
static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
3433
{
3434
#if defined(TARGET_PPC64)
3435
    if (ctx->sf_mode == 0)
3436
        tcg_gen_movi_tl(cpu_lr, (uint32_t)nip);
3437
    else
3438
#endif
3439
        tcg_gen_movi_tl(cpu_lr, nip);
3440
}
3441

    
3442
/* b ba bl bla */
3443
static void gen_b(DisasContext *ctx)
3444
{
3445
    target_ulong li, target;
3446

    
3447
    ctx->exception = POWERPC_EXCP_BRANCH;
3448
    /* sign extend LI */
3449
#if defined(TARGET_PPC64)
3450
    if (ctx->sf_mode)
3451
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
3452
    else
3453
#endif
3454
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
3455
    if (likely(AA(ctx->opcode) == 0))
3456
        target = ctx->nip + li - 4;
3457
    else
3458
        target = li;
3459
    if (LK(ctx->opcode))
3460
        gen_setlr(ctx, ctx->nip);
3461
    gen_update_cfar(ctx, ctx->nip);
3462
    gen_goto_tb(ctx, 0, target);
3463
}
3464

    
3465
#define BCOND_IM  0
3466
#define BCOND_LR  1
3467
#define BCOND_CTR 2
3468

    
3469
static inline void gen_bcond(DisasContext *ctx, int type)
3470
{
3471
    uint32_t bo = BO(ctx->opcode);
3472
    int l1;
3473
    TCGv target;
3474

    
3475
    ctx->exception = POWERPC_EXCP_BRANCH;
3476
    if (type == BCOND_LR || type == BCOND_CTR) {
3477
        target = tcg_temp_local_new();
3478
        if (type == BCOND_CTR)
3479
            tcg_gen_mov_tl(target, cpu_ctr);
3480
        else
3481
            tcg_gen_mov_tl(target, cpu_lr);
3482
    } else {
3483
        TCGV_UNUSED(target);
3484
    }
3485
    if (LK(ctx->opcode))
3486
        gen_setlr(ctx, ctx->nip);
3487
    l1 = gen_new_label();
3488
    if ((bo & 0x4) == 0) {
3489
        /* Decrement and test CTR */
3490
        TCGv temp = tcg_temp_new();
3491
        if (unlikely(type == BCOND_CTR)) {
3492
            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3493
            return;
3494
        }
3495
        tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3496
#if defined(TARGET_PPC64)
3497
        if (!ctx->sf_mode)
3498
            tcg_gen_ext32u_tl(temp, cpu_ctr);
3499
        else
3500
#endif
3501
            tcg_gen_mov_tl(temp, cpu_ctr);
3502
        if (bo & 0x2) {
3503
            tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3504
        } else {
3505
            tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3506
        }
3507
        tcg_temp_free(temp);
3508
    }
3509
    if ((bo & 0x10) == 0) {
3510
        /* Test CR */
3511
        uint32_t bi = BI(ctx->opcode);
3512
        uint32_t mask = 1 << (3 - (bi & 0x03));
3513
        TCGv_i32 temp = tcg_temp_new_i32();
3514

    
3515
        if (bo & 0x8) {
3516
            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3517
            tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
3518
        } else {
3519
            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3520
            tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
3521
        }
3522
        tcg_temp_free_i32(temp);
3523
    }
3524
    gen_update_cfar(ctx, ctx->nip);
3525
    if (type == BCOND_IM) {
3526
        target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
3527
        if (likely(AA(ctx->opcode) == 0)) {
3528
            gen_goto_tb(ctx, 0, ctx->nip + li - 4);
3529
        } else {
3530
            gen_goto_tb(ctx, 0, li);
3531
        }
3532
        gen_set_label(l1);
3533
        gen_goto_tb(ctx, 1, ctx->nip);
3534
    } else {
3535
#if defined(TARGET_PPC64)
3536
        if (!(ctx->sf_mode))
3537
            tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
3538
        else
3539
#endif
3540
            tcg_gen_andi_tl(cpu_nip, target, ~3);
3541
        tcg_gen_exit_tb(0);
3542
        gen_set_label(l1);
3543
#if defined(TARGET_PPC64)
3544
        if (!(ctx->sf_mode))
3545
            tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip);
3546
        else
3547
#endif
3548
            tcg_gen_movi_tl(cpu_nip, ctx->nip);
3549
        tcg_gen_exit_tb(0);
3550
    }
3551
}
3552

    
3553
static void gen_bc(DisasContext *ctx)
3554
{
3555
    gen_bcond(ctx, BCOND_IM);
3556
}
3557

    
3558
static void gen_bcctr(DisasContext *ctx)
3559
{
3560
    gen_bcond(ctx, BCOND_CTR);
3561
}
3562

    
3563
static void gen_bclr(DisasContext *ctx)
3564
{
3565
    gen_bcond(ctx, BCOND_LR);
3566
}
3567

    
3568
/***                      Condition register logical                       ***/
3569
#define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3570
static void glue(gen_, name)(DisasContext *ctx)                                       \
3571
{                                                                             \
3572
    uint8_t bitmask;                                                          \
3573
    int sh;                                                                   \
3574
    TCGv_i32 t0, t1;                                                          \
3575
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3576
    t0 = tcg_temp_new_i32();                                                  \
3577
    if (sh > 0)                                                               \
3578
        tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
3579
    else if (sh < 0)                                                          \
3580
        tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
3581
    else                                                                      \
3582
        tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
3583
    t1 = tcg_temp_new_i32();                                                  \
3584
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3585
    if (sh > 0)                                                               \
3586
        tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
3587
    else if (sh < 0)                                                          \
3588
        tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
3589
    else                                                                      \
3590
        tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
3591
    tcg_op(t0, t0, t1);                                                       \
3592
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3593
    tcg_gen_andi_i32(t0, t0, bitmask);                                        \
3594
    tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
3595
    tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
3596
    tcg_temp_free_i32(t0);                                                    \
3597
    tcg_temp_free_i32(t1);                                                    \
3598
}
3599

    
3600
/* crand */
3601
GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
3602
/* crandc */
3603
GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
3604
/* creqv */
3605
GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
3606
/* crnand */
3607
GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
3608
/* crnor */
3609
GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
3610
/* cror */
3611
GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
3612
/* crorc */
3613
GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
3614
/* crxor */
3615
GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
3616

    
3617
/* mcrf */
3618
static void gen_mcrf(DisasContext *ctx)
3619
{
3620
    tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
3621
}
3622

    
3623
/***                           System linkage                              ***/
3624

    
3625
/* rfi (mem_idx only) */
3626
static void gen_rfi(DisasContext *ctx)
3627
{
3628
#if defined(CONFIG_USER_ONLY)
3629
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3630
#else
3631
    /* Restore CPU state */
3632
    if (unlikely(!ctx->mem_idx)) {
3633
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3634
        return;
3635
    }
3636
    gen_update_cfar(ctx, ctx->nip);
3637
    gen_helper_rfi();
3638
    gen_sync_exception(ctx);
3639
#endif
3640
}
3641

    
3642
#if defined(TARGET_PPC64)
3643
static void gen_rfid(DisasContext *ctx)
3644
{
3645
#if defined(CONFIG_USER_ONLY)
3646
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3647
#else
3648
    /* Restore CPU state */
3649
    if (unlikely(!ctx->mem_idx)) {
3650
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3651
        return;
3652
    }
3653
    gen_update_cfar(ctx, ctx->nip);
3654
    gen_helper_rfid();
3655
    gen_sync_exception(ctx);
3656
#endif
3657
}
3658

    
3659
static void gen_hrfid(DisasContext *ctx)
3660
{
3661
#if defined(CONFIG_USER_ONLY)
3662
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3663
#else
3664
    /* Restore CPU state */
3665
    if (unlikely(ctx->mem_idx <= 1)) {
3666
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3667
        return;
3668
    }
3669
    gen_helper_hrfid();
3670
    gen_sync_exception(ctx);
3671
#endif
3672
}
3673
#endif
3674

    
3675
/* sc */
3676
#if defined(CONFIG_USER_ONLY)
3677
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3678
#else
3679
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3680
#endif
3681
static void gen_sc(DisasContext *ctx)
3682
{
3683
    uint32_t lev;
3684

    
3685
    lev = (ctx->opcode >> 5) & 0x7F;
3686
    gen_exception_err(ctx, POWERPC_SYSCALL, lev);
3687
}
3688

    
3689
/***                                Trap                                   ***/
3690

    
3691
/* tw */
3692
static void gen_tw(DisasContext *ctx)
3693
{
3694
    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
3695
    /* Update the nip since this might generate a trap exception */
3696
    gen_update_nip(ctx, ctx->nip);
3697
    gen_helper_tw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
3698
    tcg_temp_free_i32(t0);
3699
}
3700

    
3701
/* twi */
3702
static void gen_twi(DisasContext *ctx)
3703
{
3704
    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
3705
    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
3706
    /* Update the nip since this might generate a trap exception */
3707
    gen_update_nip(ctx, ctx->nip);
3708
    gen_helper_tw(cpu_gpr[rA(ctx->opcode)], t0, t1);
3709
    tcg_temp_free(t0);
3710
    tcg_temp_free_i32(t1);
3711
}
3712

    
3713
#if defined(TARGET_PPC64)
3714
/* td */
3715
static void gen_td(DisasContext *ctx)
3716
{
3717
    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
3718
    /* Update the nip since this might generate a trap exception */
3719
    gen_update_nip(ctx, ctx->nip);
3720
    gen_helper_td(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
3721
    tcg_temp_free_i32(t0);
3722
}
3723

    
3724
/* tdi */
3725
static void gen_tdi(DisasContext *ctx)
3726
{
3727
    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
3728
    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
3729
    /* Update the nip since this might generate a trap exception */
3730
    gen_update_nip(ctx, ctx->nip);
3731
    gen_helper_td(cpu_gpr[rA(ctx->opcode)], t0, t1);
3732
    tcg_temp_free(t0);
3733
    tcg_temp_free_i32(t1);
3734
}
3735
#endif
3736

    
3737
/***                          Processor control                            ***/
3738

    
3739
/* mcrxr */
3740
static void gen_mcrxr(DisasContext *ctx)
3741
{
3742
    tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
3743
    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
3744
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
3745
}
3746

    
3747
/* mfcr mfocrf */
3748
static void gen_mfcr(DisasContext *ctx)
3749
{
3750
    uint32_t crm, crn;
3751

    
3752
    if (likely(ctx->opcode & 0x00100000)) {
3753
        crm = CRM(ctx->opcode);
3754
        if (likely(crm && ((crm & (crm - 1)) == 0))) {
3755
            crn = ctz32 (crm);
3756
            tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
3757
            tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
3758
                            cpu_gpr[rD(ctx->opcode)], crn * 4);
3759
        }
3760
    } else {
3761
        TCGv_i32 t0 = tcg_temp_new_i32();
3762
        tcg_gen_mov_i32(t0, cpu_crf[0]);
3763
        tcg_gen_shli_i32(t0, t0, 4);
3764
        tcg_gen_or_i32(t0, t0, cpu_crf[1]);
3765
        tcg_gen_shli_i32(t0, t0, 4);
3766
        tcg_gen_or_i32(t0, t0, cpu_crf[2]);
3767
        tcg_gen_shli_i32(t0, t0, 4);
3768
        tcg_gen_or_i32(t0, t0, cpu_crf[3]);
3769
        tcg_gen_shli_i32(t0, t0, 4);
3770
        tcg_gen_or_i32(t0, t0, cpu_crf[4]);
3771
        tcg_gen_shli_i32(t0, t0, 4);
3772
        tcg_gen_or_i32(t0, t0, cpu_crf[5]);
3773
        tcg_gen_shli_i32(t0, t0, 4);
3774
        tcg_gen_or_i32(t0, t0, cpu_crf[6]);
3775
        tcg_gen_shli_i32(t0, t0, 4);
3776
        tcg_gen_or_i32(t0, t0, cpu_crf[7]);
3777
        tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
3778
        tcg_temp_free_i32(t0);
3779
    }
3780
}
3781

    
3782
/* mfmsr */
3783
static void gen_mfmsr(DisasContext *ctx)
3784
{
3785
#if defined(CONFIG_USER_ONLY)
3786
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3787
#else
3788
    if (unlikely(!ctx->mem_idx)) {
3789
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3790
        return;
3791
    }
3792
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
3793
#endif
3794
}
3795

    
3796
static void spr_noaccess(void *opaque, int gprn, int sprn)
3797
{
3798
#if 0
3799
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3800
    printf("ERROR: try to access SPR %d !\n", sprn);
3801
#endif
3802
}
3803
#define SPR_NOACCESS (&spr_noaccess)
3804

    
3805
/* mfspr */
3806
static inline void gen_op_mfspr(DisasContext *ctx)
3807
{
3808
    void (*read_cb)(void *opaque, int gprn, int sprn);
3809
    uint32_t sprn = SPR(ctx->opcode);
3810

    
3811
#if !defined(CONFIG_USER_ONLY)
3812
    if (ctx->mem_idx == 2)
3813
        read_cb = ctx->spr_cb[sprn].hea_read;
3814
    else if (ctx->mem_idx)
3815
        read_cb = ctx->spr_cb[sprn].oea_read;
3816
    else
3817
#endif
3818
        read_cb = ctx->spr_cb[sprn].uea_read;
3819
    if (likely(read_cb != NULL)) {
3820
        if (likely(read_cb != SPR_NOACCESS)) {
3821
            (*read_cb)(ctx, rD(ctx->opcode), sprn);
3822
        } else {
3823
            /* Privilege exception */
3824
            /* This is a hack to avoid warnings when running Linux:
3825
             * this OS breaks the PowerPC virtualisation model,
3826
             * allowing userland application to read the PVR
3827
             */
3828
            if (sprn != SPR_PVR) {
3829
                qemu_log("Trying to read privileged spr %d %03x at "
3830
                         TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3831
                printf("Trying to read privileged spr %d %03x at "
3832
                       TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3833
            }
3834
            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3835
        }
3836
    } else {
3837
        /* Not defined */
3838
        qemu_log("Trying to read invalid spr %d %03x at "
3839
                    TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3840
        printf("Trying to read invalid spr %d %03x at " TARGET_FMT_lx "\n",
3841
               sprn, sprn, ctx->nip);
3842
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
3843
    }
3844
}
3845

    
3846
static void gen_mfspr(DisasContext *ctx)
3847
{
3848
    gen_op_mfspr(ctx);
3849
}
3850

    
3851
/* mftb */
3852
static void gen_mftb(DisasContext *ctx)
3853
{
3854
    gen_op_mfspr(ctx);
3855
}
3856

    
3857
/* mtcrf mtocrf*/
3858
static void gen_mtcrf(DisasContext *ctx)
3859
{
3860
    uint32_t crm, crn;
3861

    
3862
    crm = CRM(ctx->opcode);
3863
    if (likely((ctx->opcode & 0x00100000))) {
3864
        if (crm && ((crm & (crm - 1)) == 0)) {
3865
            TCGv_i32 temp = tcg_temp_new_i32();
3866
            crn = ctz32 (crm);
3867
            tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
3868
            tcg_gen_shri_i32(temp, temp, crn * 4);
3869
            tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
3870
            tcg_temp_free_i32(temp);
3871
        }
3872
    } else {
3873
        TCGv_i32 temp = tcg_temp_new_i32();
3874
        tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
3875
        for (crn = 0 ; crn < 8 ; crn++) {
3876
            if (crm & (1 << crn)) {
3877
                    tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
3878
                    tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
3879
            }
3880
        }
3881
        tcg_temp_free_i32(temp);
3882
    }
3883
}
3884

    
3885
/* mtmsr */
3886
#if defined(TARGET_PPC64)
3887
static void gen_mtmsrd(DisasContext *ctx)
3888
{
3889
#if defined(CONFIG_USER_ONLY)
3890
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3891
#else
3892
    if (unlikely(!ctx->mem_idx)) {
3893
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3894
        return;
3895
    }
3896
    if (ctx->opcode & 0x00010000) {
3897
        /* Special form that does not need any synchronisation */
3898
        TCGv t0 = tcg_temp_new();
3899
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
3900
        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
3901
        tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
3902
        tcg_temp_free(t0);
3903
    } else {
3904
        /* XXX: we need to update nip before the store
3905
         *      if we enter power saving mode, we will exit the loop
3906
         *      directly from ppc_store_msr
3907
         */
3908
        gen_update_nip(ctx, ctx->nip);
3909
        gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
3910
        /* Must stop the translation as machine state (may have) changed */
3911
        /* Note that mtmsr is not always defined as context-synchronizing */
3912
        gen_stop_exception(ctx);
3913
    }
3914
#endif
3915
}
3916
#endif
3917

    
3918
static void gen_mtmsr(DisasContext *ctx)
3919
{
3920
#if defined(CONFIG_USER_ONLY)
3921
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3922
#else
3923
    if (unlikely(!ctx->mem_idx)) {
3924
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3925
        return;
3926
    }
3927
    if (ctx->opcode & 0x00010000) {
3928
        /* Special form that does not need any synchronisation */
3929
        TCGv t0 = tcg_temp_new();
3930
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
3931
        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
3932
        tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
3933
        tcg_temp_free(t0);
3934
    } else {
3935
        TCGv msr = tcg_temp_new();
3936

    
3937
        /* XXX: we need to update nip before the store
3938
         *      if we enter power saving mode, we will exit the loop
3939
         *      directly from ppc_store_msr
3940
         */
3941
        gen_update_nip(ctx, ctx->nip);
3942
#if defined(TARGET_PPC64)
3943
        tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
3944
#else
3945
        tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
3946
#endif
3947
        gen_helper_store_msr(msr);
3948
        /* Must stop the translation as machine state (may have) changed */
3949
        /* Note that mtmsr is not always defined as context-synchronizing */
3950
        gen_stop_exception(ctx);
3951
    }
3952
#endif
3953
}
3954

    
3955
/* mtspr */
3956
static void gen_mtspr(DisasContext *ctx)
3957
{
3958
    void (*write_cb)(void *opaque, int sprn, int gprn);
3959
    uint32_t sprn = SPR(ctx->opcode);
3960

    
3961
#if !defined(CONFIG_USER_ONLY)
3962
    if (ctx->mem_idx == 2)
3963
        write_cb = ctx->spr_cb[sprn].hea_write;
3964
    else if (ctx->mem_idx)
3965
        write_cb = ctx->spr_cb[sprn].oea_write;
3966
    else
3967
#endif
3968
        write_cb = ctx->spr_cb[sprn].uea_write;
3969
    if (likely(write_cb != NULL)) {
3970
        if (likely(write_cb != SPR_NOACCESS)) {
3971
            (*write_cb)(ctx, sprn, rS(ctx->opcode));
3972
        } else {
3973
            /* Privilege exception */
3974
            qemu_log("Trying to write privileged spr %d %03x at "
3975
                     TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3976
            printf("Trying to write privileged spr %d %03x at " TARGET_FMT_lx
3977
                   "\n", sprn, sprn, ctx->nip);
3978
            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3979
        }
3980
    } else {
3981
        /* Not defined */
3982
        qemu_log("Trying to write invalid spr %d %03x at "
3983
                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3984
        printf("Trying to write invalid spr %d %03x at " TARGET_FMT_lx "\n",
3985
               sprn, sprn, ctx->nip);
3986
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
3987
    }
3988
}
3989

    
3990
/***                         Cache management                              ***/
3991

    
3992
/* dcbf */
3993
static void gen_dcbf(DisasContext *ctx)
3994
{
3995
    /* XXX: specification says this is treated as a load by the MMU */
3996
    TCGv t0;
3997
    gen_set_access_type(ctx, ACCESS_CACHE);
3998
    t0 = tcg_temp_new();
3999
    gen_addr_reg_index(ctx, t0);
4000
    gen_qemu_ld8u(ctx, t0, t0);
4001
    tcg_temp_free(t0);
4002
}
4003

    
4004
/* dcbi (Supervisor only) */
4005
static void gen_dcbi(DisasContext *ctx)
4006
{
4007
#if defined(CONFIG_USER_ONLY)
4008
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4009
#else
4010
    TCGv EA, val;
4011
    if (unlikely(!ctx->mem_idx)) {
4012
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4013
        return;
4014
    }
4015
    EA = tcg_temp_new();
4016
    gen_set_access_type(ctx, ACCESS_CACHE);
4017
    gen_addr_reg_index(ctx, EA);
4018
    val = tcg_temp_new();
4019
    /* XXX: specification says this should be treated as a store by the MMU */
4020
    gen_qemu_ld8u(ctx, val, EA);
4021
    gen_qemu_st8(ctx, val, EA);
4022
    tcg_temp_free(val);
4023
    tcg_temp_free(EA);
4024
#endif
4025
}
4026

    
4027
/* dcdst */
4028
static void gen_dcbst(DisasContext *ctx)
4029
{
4030
    /* XXX: specification say this is treated as a load by the MMU */
4031
    TCGv t0;
4032
    gen_set_access_type(ctx, ACCESS_CACHE);
4033
    t0 = tcg_temp_new();
4034
    gen_addr_reg_index(ctx, t0);
4035
    gen_qemu_ld8u(ctx, t0, t0);
4036
    tcg_temp_free(t0);
4037
}
4038

    
4039
/* dcbt */
4040
static void gen_dcbt(DisasContext *ctx)
4041
{
4042
    /* interpreted as no-op */
4043
    /* XXX: specification say this is treated as a load by the MMU
4044
     *      but does not generate any exception
4045
     */
4046
}
4047

    
4048
/* dcbtst */
4049
static void gen_dcbtst(DisasContext *ctx)
4050
{
4051
    /* interpreted as no-op */
4052
    /* XXX: specification say this is treated as a load by the MMU
4053
     *      but does not generate any exception
4054
     */
4055
}
4056

    
4057
/* dcbz */
4058
static void gen_dcbz(DisasContext *ctx)
4059
{
4060
    TCGv t0;
4061
    gen_set_access_type(ctx, ACCESS_CACHE);
4062
    /* NIP cannot be restored if the memory exception comes from an helper */
4063
    gen_update_nip(ctx, ctx->nip - 4);
4064
    t0 = tcg_temp_new();
4065
    gen_addr_reg_index(ctx, t0);
4066
    gen_helper_dcbz(t0);
4067
    tcg_temp_free(t0);
4068
}
4069

    
4070
static void gen_dcbz_970(DisasContext *ctx)
4071
{
4072
    TCGv t0;
4073
    gen_set_access_type(ctx, ACCESS_CACHE);
4074
    /* NIP cannot be restored if the memory exception comes from an helper */
4075
    gen_update_nip(ctx, ctx->nip - 4);
4076
    t0 = tcg_temp_new();
4077
    gen_addr_reg_index(ctx, t0);
4078
    if (ctx->opcode & 0x00200000)
4079
        gen_helper_dcbz(t0);
4080
    else
4081
        gen_helper_dcbz_970(t0);
4082
    tcg_temp_free(t0);
4083
}
4084

    
4085
/* dst / dstt */
4086
static void gen_dst(DisasContext *ctx)
4087
{
4088
    if (rA(ctx->opcode) == 0) {
4089
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4090
    } else {
4091
        /* interpreted as no-op */
4092
    }
4093
}
4094

    
4095
/* dstst /dststt */
4096
static void gen_dstst(DisasContext *ctx)
4097
{
4098
    if (rA(ctx->opcode) == 0) {
4099
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4100
    } else {
4101
        /* interpreted as no-op */
4102
    }
4103

    
4104
}
4105

    
4106
/* dss / dssall */
4107
static void gen_dss(DisasContext *ctx)
4108
{
4109
    /* interpreted as no-op */
4110
}
4111

    
4112
/* icbi */
4113
static void gen_icbi(DisasContext *ctx)
4114
{
4115
    TCGv t0;
4116
    gen_set_access_type(ctx, ACCESS_CACHE);
4117
    /* NIP cannot be restored if the memory exception comes from an helper */
4118
    gen_update_nip(ctx, ctx->nip - 4);
4119
    t0 = tcg_temp_new();
4120
    gen_addr_reg_index(ctx, t0);
4121
    gen_helper_icbi(t0);
4122
    tcg_temp_free(t0);
4123
}
4124

    
4125
/* Optional: */
4126
/* dcba */
4127
static void gen_dcba(DisasContext *ctx)
4128
{
4129
    /* interpreted as no-op */
4130
    /* XXX: specification say this is treated as a store by the MMU
4131
     *      but does not generate any exception
4132
     */
4133
}
4134

    
4135
/***                    Segment register manipulation                      ***/
4136
/* Supervisor only: */
4137

    
4138
/* mfsr */
4139
static void gen_mfsr(DisasContext *ctx)
4140
{
4141
#if defined(CONFIG_USER_ONLY)
4142
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4143
#else
4144
    TCGv t0;
4145
    if (unlikely(!ctx->mem_idx)) {
4146
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4147
        return;
4148
    }
4149
    t0 = tcg_const_tl(SR(ctx->opcode));
4150
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4151
    tcg_temp_free(t0);
4152
#endif
4153
}
4154

    
4155
/* mfsrin */
4156
static void gen_mfsrin(DisasContext *ctx)
4157
{
4158
#if defined(CONFIG_USER_ONLY)
4159
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4160
#else
4161
    TCGv t0;
4162
    if (unlikely(!ctx->mem_idx)) {
4163
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4164
        return;
4165
    }
4166
    t0 = tcg_temp_new();
4167
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4168
    tcg_gen_andi_tl(t0, t0, 0xF);
4169
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4170
    tcg_temp_free(t0);
4171
#endif
4172
}
4173

    
4174
/* mtsr */
4175
static void gen_mtsr(DisasContext *ctx)
4176
{
4177
#if defined(CONFIG_USER_ONLY)
4178
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4179
#else
4180
    TCGv t0;
4181
    if (unlikely(!ctx->mem_idx)) {
4182
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4183
        return;
4184
    }
4185
    t0 = tcg_const_tl(SR(ctx->opcode));
4186
    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4187
    tcg_temp_free(t0);
4188
#endif
4189
}
4190

    
4191
/* mtsrin */
4192
static void gen_mtsrin(DisasContext *ctx)
4193
{
4194
#if defined(CONFIG_USER_ONLY)
4195
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4196
#else
4197
    TCGv t0;
4198
    if (unlikely(!ctx->mem_idx)) {
4199
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4200
        return;
4201
    }
4202
    t0 = tcg_temp_new();
4203
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4204
    tcg_gen_andi_tl(t0, t0, 0xF);
4205
    gen_helper_store_sr(t0, cpu_gpr[rD(ctx->opcode)]);
4206
    tcg_temp_free(t0);
4207
#endif
4208
}
4209

    
4210
#if defined(TARGET_PPC64)
4211
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4212

    
4213
/* mfsr */
4214
static void gen_mfsr_64b(DisasContext *ctx)
4215
{
4216
#if defined(CONFIG_USER_ONLY)
4217
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4218
#else
4219
    TCGv t0;
4220
    if (unlikely(!ctx->mem_idx)) {
4221
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4222
        return;
4223
    }
4224
    t0 = tcg_const_tl(SR(ctx->opcode));
4225
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4226
    tcg_temp_free(t0);
4227
#endif
4228
}
4229

    
4230
/* mfsrin */
4231
static void gen_mfsrin_64b(DisasContext *ctx)
4232
{
4233
#if defined(CONFIG_USER_ONLY)
4234
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4235
#else
4236
    TCGv t0;
4237
    if (unlikely(!ctx->mem_idx)) {
4238
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4239
        return;
4240
    }
4241
    t0 = tcg_temp_new();
4242
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4243
    tcg_gen_andi_tl(t0, t0, 0xF);
4244
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4245
    tcg_temp_free(t0);
4246
#endif
4247
}
4248

    
4249
/* mtsr */
4250
static void gen_mtsr_64b(DisasContext *ctx)
4251
{
4252
#if defined(CONFIG_USER_ONLY)
4253
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4254
#else
4255
    TCGv t0;
4256
    if (unlikely(!ctx->mem_idx)) {
4257
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4258
        return;
4259
    }
4260
    t0 = tcg_const_tl(SR(ctx->opcode));
4261
    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4262
    tcg_temp_free(t0);
4263
#endif
4264
}
4265

    
4266
/* mtsrin */
4267
static void gen_mtsrin_64b(DisasContext *ctx)
4268
{
4269
#if defined(CONFIG_USER_ONLY)
4270
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4271
#else
4272
    TCGv t0;
4273
    if (unlikely(!ctx->mem_idx)) {
4274
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4275
        return;
4276
    }
4277
    t0 = tcg_temp_new();
4278
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4279
    tcg_gen_andi_tl(t0, t0, 0xF);
4280
    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4281
    tcg_temp_free(t0);
4282
#endif
4283
}
4284

    
4285
/* slbmte */
4286
static void gen_slbmte(DisasContext *ctx)
4287
{
4288
#if defined(CONFIG_USER_ONLY)
4289
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4290
#else
4291
    if (unlikely(!ctx->mem_idx)) {
4292
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4293
        return;
4294
    }
4295
    gen_helper_store_slb(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
4296
#endif
4297
}
4298

    
4299
static void gen_slbmfee(DisasContext *ctx)
4300
{
4301
#if defined(CONFIG_USER_ONLY)
4302
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4303
#else
4304
    if (unlikely(!ctx->mem_idx)) {
4305
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4306
        return;
4307
    }
4308
    gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)],
4309
                             cpu_gpr[rB(ctx->opcode)]);
4310
#endif
4311
}
4312

    
4313
static void gen_slbmfev(DisasContext *ctx)
4314
{
4315
#if defined(CONFIG_USER_ONLY)
4316
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4317
#else
4318
    if (unlikely(!ctx->mem_idx)) {
4319
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4320
        return;
4321
    }
4322
    gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)],
4323
                             cpu_gpr[rB(ctx->opcode)]);
4324
#endif
4325
}
4326
#endif /* defined(TARGET_PPC64) */
4327

    
4328
/***                      Lookaside buffer management                      ***/
4329
/* Optional & mem_idx only: */
4330

    
4331
/* tlbia */
4332
static void gen_tlbia(DisasContext *ctx)
4333
{
4334
#if defined(CONFIG_USER_ONLY)
4335
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4336
#else
4337
    if (unlikely(!ctx->mem_idx)) {
4338
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4339
        return;
4340
    }
4341
    gen_helper_tlbia();
4342
#endif
4343
}
4344

    
4345
/* tlbiel */
4346
static void gen_tlbiel(DisasContext *ctx)
4347
{
4348
#if defined(CONFIG_USER_ONLY)
4349
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4350
#else
4351
    if (unlikely(!ctx->mem_idx)) {
4352
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4353
        return;
4354
    }
4355
    gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
4356
#endif
4357
}
4358

    
4359
/* tlbie */
4360
static void gen_tlbie(DisasContext *ctx)
4361
{
4362
#if defined(CONFIG_USER_ONLY)
4363
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4364
#else
4365
    if (unlikely(!ctx->mem_idx)) {
4366
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4367
        return;
4368
    }
4369
#if defined(TARGET_PPC64)
4370
    if (!ctx->sf_mode) {
4371
        TCGv t0 = tcg_temp_new();
4372
        tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
4373
        gen_helper_tlbie(t0);
4374
        tcg_temp_free(t0);
4375
    } else
4376
#endif
4377
        gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
4378
#endif
4379
}
4380

    
4381
/* tlbsync */
4382
static void gen_tlbsync(DisasContext *ctx)
4383
{
4384
#if defined(CONFIG_USER_ONLY)
4385
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4386
#else
4387
    if (unlikely(!ctx->mem_idx)) {
4388
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4389
        return;
4390
    }
4391
    /* This has no effect: it should ensure that all previous
4392
     * tlbie have completed
4393
     */
4394
    gen_stop_exception(ctx);
4395
#endif
4396
}
4397

    
4398
#if defined(TARGET_PPC64)
4399
/* slbia */
4400
static void gen_slbia(DisasContext *ctx)
4401
{
4402
#if defined(CONFIG_USER_ONLY)
4403
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4404
#else
4405
    if (unlikely(!ctx->mem_idx)) {
4406
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4407
        return;
4408
    }
4409
    gen_helper_slbia();
4410
#endif
4411
}
4412

    
4413
/* slbie */
4414
static void gen_slbie(DisasContext *ctx)
4415
{
4416
#if defined(CONFIG_USER_ONLY)
4417
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4418
#else
4419
    if (unlikely(!ctx->mem_idx)) {
4420
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4421
        return;
4422
    }
4423
    gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]);
4424
#endif
4425
}
4426
#endif
4427

    
4428
/***                              External control                         ***/
4429
/* Optional: */
4430

    
4431
/* eciwx */
4432
static void gen_eciwx(DisasContext *ctx)
4433
{
4434
    TCGv t0;
4435
    /* Should check EAR[E] ! */
4436
    gen_set_access_type(ctx, ACCESS_EXT);
4437
    t0 = tcg_temp_new();
4438
    gen_addr_reg_index(ctx, t0);
4439
    gen_check_align(ctx, t0, 0x03);
4440
    gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4441
    tcg_temp_free(t0);
4442
}
4443

    
4444
/* ecowx */
4445
static void gen_ecowx(DisasContext *ctx)
4446
{
4447
    TCGv t0;
4448
    /* Should check EAR[E] ! */
4449
    gen_set_access_type(ctx, ACCESS_EXT);
4450
    t0 = tcg_temp_new();
4451
    gen_addr_reg_index(ctx, t0);
4452
    gen_check_align(ctx, t0, 0x03);
4453
    gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4454
    tcg_temp_free(t0);
4455
}
4456

    
4457
/* PowerPC 601 specific instructions */
4458

    
4459
/* abs - abs. */
4460
static void gen_abs(DisasContext *ctx)
4461
{
4462
    int l1 = gen_new_label();
4463
    int l2 = gen_new_label();
4464
    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
4465
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4466
    tcg_gen_br(l2);
4467
    gen_set_label(l1);
4468
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4469
    gen_set_label(l2);
4470
    if (unlikely(Rc(ctx->opcode) != 0))
4471
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4472
}
4473

    
4474
/* abso - abso. */
4475
static void gen_abso(DisasContext *ctx)
4476
{
4477
    int l1 = gen_new_label();
4478
    int l2 = gen_new_label();
4479
    int l3 = gen_new_label();
4480
    /* Start with XER OV disabled, the most likely case */
4481
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4482
    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
4483
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
4484
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4485
    tcg_gen_br(l2);
4486
    gen_set_label(l1);
4487
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4488
    tcg_gen_br(l3);
4489
    gen_set_label(l2);
4490
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4491
    gen_set_label(l3);
4492
    if (unlikely(Rc(ctx->opcode) != 0))
4493
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4494
}
4495

    
4496
/* clcs */
4497
static void gen_clcs(DisasContext *ctx)
4498
{
4499
    TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
4500
    gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], t0);
4501
    tcg_temp_free_i32(t0);
4502
    /* Rc=1 sets CR0 to an undefined state */
4503
}
4504

    
4505
/* div - div. */
4506
static void gen_div(DisasContext *ctx)
4507
{
4508
    gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4509
    if (unlikely(Rc(ctx->opcode) != 0))
4510
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4511
}
4512

    
4513
/* divo - divo. */
4514
static void gen_divo(DisasContext *ctx)
4515
{
4516
    gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4517
    if (unlikely(Rc(ctx->opcode) != 0))
4518
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4519
}
4520

    
4521
/* divs - divs. */
4522
static void gen_divs(DisasContext *ctx)
4523
{
4524
    gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4525
    if (unlikely(Rc(ctx->opcode) != 0))
4526
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4527
}
4528

    
4529
/* divso - divso. */
4530
static void gen_divso(DisasContext *ctx)
4531
{
4532
    gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4533
    if (unlikely(Rc(ctx->opcode) != 0))
4534
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4535
}
4536

    
4537
/* doz - doz. */
4538
static void gen_doz(DisasContext *ctx)
4539
{
4540
    int l1 = gen_new_label();
4541
    int l2 = gen_new_label();
4542
    tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4543
    tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4544
    tcg_gen_br(l2);
4545
    gen_set_label(l1);
4546
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4547
    gen_set_label(l2);
4548
    if (unlikely(Rc(ctx->opcode) != 0))
4549
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4550
}
4551

    
4552
/* dozo - dozo. */
4553
static void gen_dozo(DisasContext *ctx)
4554
{
4555
    int l1 = gen_new_label();
4556
    int l2 = gen_new_label();
4557
    TCGv t0 = tcg_temp_new();
4558
    TCGv t1 = tcg_temp_new();
4559
    TCGv t2 = tcg_temp_new();
4560
    /* Start with XER OV disabled, the most likely case */
4561
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4562
    tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4563
    tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4564
    tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4565
    tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
4566
    tcg_gen_andc_tl(t1, t1, t2);
4567
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
4568
    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4569
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4570
    tcg_gen_br(l2);
4571
    gen_set_label(l1);
4572
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4573
    gen_set_label(l2);
4574
    tcg_temp_free(t0);
4575
    tcg_temp_free(t1);
4576
    tcg_temp_free(t2);
4577
    if (unlikely(Rc(ctx->opcode) != 0))
4578
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4579
}
4580

    
4581
/* dozi */
4582
static void gen_dozi(DisasContext *ctx)
4583
{
4584
    target_long simm = SIMM(ctx->opcode);
4585
    int l1 = gen_new_label();
4586
    int l2 = gen_new_label();
4587
    tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
4588
    tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
4589
    tcg_gen_br(l2);
4590
    gen_set_label(l1);
4591
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4592
    gen_set_label(l2);
4593
    if (unlikely(Rc(ctx->opcode) != 0))
4594
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4595
}
4596

    
4597
/* lscbx - lscbx. */
4598
static void gen_lscbx(DisasContext *ctx)
4599
{
4600
    TCGv t0 = tcg_temp_new();
4601
    TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
4602
    TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
4603
    TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
4604

    
4605
    gen_addr_reg_index(ctx, t0);
4606
    /* NIP cannot be restored if the memory exception comes from an helper */
4607
    gen_update_nip(ctx, ctx->nip - 4);
4608
    gen_helper_lscbx(t0, t0, t1, t2, t3);
4609
    tcg_temp_free_i32(t1);
4610
    tcg_temp_free_i32(t2);
4611
    tcg_temp_free_i32(t3);
4612
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
4613
    tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
4614
    if (unlikely(Rc(ctx->opcode) != 0))
4615
        gen_set_Rc0(ctx, t0);
4616
    tcg_temp_free(t0);
4617
}
4618

    
4619
/* maskg - maskg. */
4620
static void gen_maskg(DisasContext *ctx)
4621
{
4622
    int l1 = gen_new_label();
4623
    TCGv t0 = tcg_temp_new();
4624
    TCGv t1 = tcg_temp_new();
4625
    TCGv t2 = tcg_temp_new();
4626
    TCGv t3 = tcg_temp_new();
4627
    tcg_gen_movi_tl(t3, 0xFFFFFFFF);
4628
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4629
    tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
4630
    tcg_gen_addi_tl(t2, t0, 1);
4631
    tcg_gen_shr_tl(t2, t3, t2);
4632
    tcg_gen_shr_tl(t3, t3, t1);
4633
    tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
4634
    tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4635
    tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4636
    gen_set_label(l1);
4637
    tcg_temp_free(t0);
4638
    tcg_temp_free(t1);
4639
    tcg_temp_free(t2);
4640
    tcg_temp_free(t3);
4641
    if (unlikely(Rc(ctx->opcode) != 0))
4642
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4643
}
4644

    
4645
/* maskir - maskir. */
4646
static void gen_maskir(DisasContext *ctx)
4647
{
4648
    TCGv t0 = tcg_temp_new();
4649
    TCGv t1 = tcg_temp_new();
4650
    tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4651
    tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4652
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4653
    tcg_temp_free(t0);
4654
    tcg_temp_free(t1);
4655
    if (unlikely(Rc(ctx->opcode) != 0))
4656
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4657
}
4658

    
4659
/* mul - mul. */
4660
static void gen_mul(DisasContext *ctx)
4661
{
4662
    TCGv_i64 t0 = tcg_temp_new_i64();
4663
    TCGv_i64 t1 = tcg_temp_new_i64();
4664
    TCGv t2 = tcg_temp_new();
4665
    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4666
    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4667
    tcg_gen_mul_i64(t0, t0, t1);
4668
    tcg_gen_trunc_i64_tl(t2, t0);
4669
    gen_store_spr(SPR_MQ, t2);
4670
    tcg_gen_shri_i64(t1, t0, 32);
4671
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4672
    tcg_temp_free_i64(t0);
4673
    tcg_temp_free_i64(t1);
4674
    tcg_temp_free(t2);
4675
    if (unlikely(Rc(ctx->opcode) != 0))
4676
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4677
}
4678

    
4679
/* mulo - mulo. */
4680
static void gen_mulo(DisasContext *ctx)
4681
{
4682
    int l1 = gen_new_label();
4683
    TCGv_i64 t0 = tcg_temp_new_i64();
4684
    TCGv_i64 t1 = tcg_temp_new_i64();
4685
    TCGv t2 = tcg_temp_new();
4686
    /* Start with XER OV disabled, the most likely case */
4687
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4688
    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4689
    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4690
    tcg_gen_mul_i64(t0, t0, t1);
4691
    tcg_gen_trunc_i64_tl(t2, t0);
4692
    gen_store_spr(SPR_MQ, t2);
4693
    tcg_gen_shri_i64(t1, t0, 32);
4694
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4695
    tcg_gen_ext32s_i64(t1, t0);
4696
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
4697
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4698
    gen_set_label(l1);
4699
    tcg_temp_free_i64(t0);
4700
    tcg_temp_free_i64(t1);
4701
    tcg_temp_free(t2);
4702
    if (unlikely(Rc(ctx->opcode) != 0))
4703
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4704
}
4705

    
4706
/* nabs - nabs. */
4707
static void gen_nabs(DisasContext *ctx)
4708
{
4709
    int l1 = gen_new_label();
4710
    int l2 = gen_new_label();
4711
    tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4712
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4713
    tcg_gen_br(l2);
4714
    gen_set_label(l1);
4715
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4716
    gen_set_label(l2);
4717
    if (unlikely(Rc(ctx->opcode) != 0))
4718
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4719
}
4720

    
4721
/* nabso - nabso. */
4722
static void gen_nabso(DisasContext *ctx)
4723
{
4724
    int l1 = gen_new_label();
4725
    int l2 = gen_new_label();
4726
    tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4727
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4728
    tcg_gen_br(l2);
4729
    gen_set_label(l1);
4730
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4731
    gen_set_label(l2);
4732
    /* nabs never overflows */
4733
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4734
    if (unlikely(Rc(ctx->opcode) != 0))
4735
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4736
}
4737

    
4738
/* rlmi - rlmi. */
4739
static void gen_rlmi(DisasContext *ctx)
4740
{
4741
    uint32_t mb = MB(ctx->opcode);
4742
    uint32_t me = ME(ctx->opcode);
4743
    TCGv t0 = tcg_temp_new();
4744
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4745
    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4746
    tcg_gen_andi_tl(t0, t0, MASK(mb, me));
4747
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
4748
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
4749
    tcg_temp_free(t0);
4750
    if (unlikely(Rc(ctx->opcode) != 0))
4751
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4752
}
4753

    
4754
/* rrib - rrib. */
4755
static void gen_rrib(DisasContext *ctx)
4756
{
4757
    TCGv t0 = tcg_temp_new();
4758
    TCGv t1 = tcg_temp_new();
4759
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4760
    tcg_gen_movi_tl(t1, 0x80000000);
4761
    tcg_gen_shr_tl(t1, t1, t0);
4762
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4763
    tcg_gen_and_tl(t0, t0, t1);
4764
    tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
4765
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4766
    tcg_temp_free(t0);
4767
    tcg_temp_free(t1);
4768
    if (unlikely(Rc(ctx->opcode) != 0))
4769
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4770
}
4771

    
4772
/* sle - sle. */
4773
static void gen_sle(DisasContext *ctx)
4774
{
4775
    TCGv t0 = tcg_temp_new();
4776
    TCGv t1 = tcg_temp_new();
4777
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4778
    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4779
    tcg_gen_subfi_tl(t1, 32, t1);
4780
    tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4781
    tcg_gen_or_tl(t1, t0, t1);
4782
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4783
    gen_store_spr(SPR_MQ, t1);
4784
    tcg_temp_free(t0);
4785
    tcg_temp_free(t1);
4786
    if (unlikely(Rc(ctx->opcode) != 0))
4787
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4788
}
4789

    
4790
/* sleq - sleq. */
4791
static void gen_sleq(DisasContext *ctx)
4792
{
4793
    TCGv t0 = tcg_temp_new();
4794
    TCGv t1 = tcg_temp_new();
4795
    TCGv t2 = tcg_temp_new();
4796
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4797
    tcg_gen_movi_tl(t2, 0xFFFFFFFF);
4798
    tcg_gen_shl_tl(t2, t2, t0);
4799
    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4800
    gen_load_spr(t1, SPR_MQ);
4801
    gen_store_spr(SPR_MQ, t0);
4802
    tcg_gen_and_tl(t0, t0, t2);
4803
    tcg_gen_andc_tl(t1, t1, t2);
4804
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4805
    tcg_temp_free(t0);
4806
    tcg_temp_free(t1);
4807
    tcg_temp_free(t2);
4808
    if (unlikely(Rc(ctx->opcode) != 0))
4809
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4810
}
4811

    
4812
/* sliq - sliq. */
4813
static void gen_sliq(DisasContext *ctx)
4814
{
4815
    int sh = SH(ctx->opcode);
4816
    TCGv t0 = tcg_temp_new();
4817
    TCGv t1 = tcg_temp_new();
4818
    tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4819
    tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4820
    tcg_gen_or_tl(t1, t0, t1);
4821
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4822
    gen_store_spr(SPR_MQ, t1);
4823
    tcg_temp_free(t0);
4824
    tcg_temp_free(t1);
4825
    if (unlikely(Rc(ctx->opcode) != 0))
4826
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4827
}
4828

    
4829
/* slliq - slliq. */
4830
static void gen_slliq(DisasContext *ctx)
4831
{
4832
    int sh = SH(ctx->opcode);
4833
    TCGv t0 = tcg_temp_new();
4834
    TCGv t1 = tcg_temp_new();
4835
    tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4836
    gen_load_spr(t1, SPR_MQ);
4837
    gen_store_spr(SPR_MQ, t0);
4838
    tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
4839
    tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
4840
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4841
    tcg_temp_free(t0);
4842
    tcg_temp_free(t1);
4843
    if (unlikely(Rc(ctx->opcode) != 0))
4844
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4845
}
4846

    
4847
/* sllq - sllq. */
4848
static void gen_sllq(DisasContext *ctx)
4849
{
4850
    int l1 = gen_new_label();
4851
    int l2 = gen_new_label();
4852
    TCGv t0 = tcg_temp_local_new();
4853
    TCGv t1 = tcg_temp_local_new();
4854
    TCGv t2 = tcg_temp_local_new();
4855
    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4856
    tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4857
    tcg_gen_shl_tl(t1, t1, t2);
4858
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4859
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
4860
    gen_load_spr(t0, SPR_MQ);
4861
    tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4862
    tcg_gen_br(l2);
4863
    gen_set_label(l1);
4864
    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4865
    gen_load_spr(t2, SPR_MQ);
4866
    tcg_gen_andc_tl(t1, t2, t1);
4867
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4868
    gen_set_label(l2);
4869
    tcg_temp_free(t0);
4870
    tcg_temp_free(t1);
4871
    tcg_temp_free(t2);
4872
    if (unlikely(Rc(ctx->opcode) != 0))
4873
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4874
}
4875

    
4876
/* slq - slq. */
4877
static void gen_slq(DisasContext *ctx)
4878
{
4879
    int l1 = gen_new_label();
4880
    TCGv t0 = tcg_temp_new();
4881
    TCGv t1 = tcg_temp_new();
4882
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4883
    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4884
    tcg_gen_subfi_tl(t1, 32, t1);
4885
    tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4886
    tcg_gen_or_tl(t1, t0, t1);
4887
    gen_store_spr(SPR_MQ, t1);
4888
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
4889
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4890
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4891
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
4892
    gen_set_label(l1);
4893
    tcg_temp_free(t0);
4894
    tcg_temp_free(t1);
4895
    if (unlikely(Rc(ctx->opcode) != 0))
4896
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4897
}
4898

    
4899
/* sraiq - sraiq. */
4900
static void gen_sraiq(DisasContext *ctx)
4901
{
4902
    int sh = SH(ctx->opcode);
4903
    int l1 = gen_new_label();
4904
    TCGv t0 = tcg_temp_new();
4905
    TCGv t1 = tcg_temp_new();
4906
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4907
    tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4908
    tcg_gen_or_tl(t0, t0, t1);
4909
    gen_store_spr(SPR_MQ, t0);
4910
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
4911
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4912
    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
4913
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
4914
    gen_set_label(l1);
4915
    tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
4916
    tcg_temp_free(t0);
4917
    tcg_temp_free(t1);
4918
    if (unlikely(Rc(ctx->opcode) != 0))
4919
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4920
}
4921

    
4922
/* sraq - sraq. */
4923
static void gen_sraq(DisasContext *ctx)
4924
{
4925
    int l1 = gen_new_label();
4926
    int l2 = gen_new_label();
4927
    TCGv t0 = tcg_temp_new();
4928
    TCGv t1 = tcg_temp_local_new();
4929
    TCGv t2 = tcg_temp_local_new();
4930
    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4931
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4932
    tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
4933
    tcg_gen_subfi_tl(t2, 32, t2);
4934
    tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
4935
    tcg_gen_or_tl(t0, t0, t2);
4936
    gen_store_spr(SPR_MQ, t0);
4937
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4938
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
4939
    tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
4940
    tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
4941
    gen_set_label(l1);
4942
    tcg_temp_free(t0);
4943
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
4944
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
4945
    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4946
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
4947
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
4948
    gen_set_label(l2);
4949
    tcg_temp_free(t1);
4950
    tcg_temp_free(t2);
4951
    if (unlikely(Rc(ctx->opcode) != 0))
4952
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4953
}
4954

    
4955
/* sre - sre. */
4956
static void gen_sre(DisasContext *ctx)
4957
{
4958
    TCGv t0 = tcg_temp_new();
4959
    TCGv t1 = tcg_temp_new();
4960
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4961
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4962
    tcg_gen_subfi_tl(t1, 32, t1);
4963
    tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4964
    tcg_gen_or_tl(t1, t0, t1);
4965
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4966
    gen_store_spr(SPR_MQ, t1);
4967
    tcg_temp_free(t0);
4968
    tcg_temp_free(t1);
4969
    if (unlikely(Rc(ctx->opcode) != 0))
4970
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4971
}
4972

    
4973
/* srea - srea. */
4974
static void gen_srea(DisasContext *ctx)
4975
{
4976
    TCGv t0 = tcg_temp_new();
4977
    TCGv t1 = tcg_temp_new();
4978
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4979
    tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4980
    gen_store_spr(SPR_MQ, t0);
4981
    tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
4982
    tcg_temp_free(t0);
4983
    tcg_temp_free(t1);
4984
    if (unlikely(Rc(ctx->opcode) != 0))
4985
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4986
}
4987

    
4988
/* sreq */
4989
static void gen_sreq(DisasContext *ctx)
4990
{
4991
    TCGv t0 = tcg_temp_new();
4992
    TCGv t1 = tcg_temp_new();
4993
    TCGv t2 = tcg_temp_new();
4994
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4995
    tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4996
    tcg_gen_shr_tl(t1, t1, t0);
4997
    tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4998
    gen_load_spr(t2, SPR_MQ);
4999
    gen_store_spr(SPR_MQ, t0);
5000
    tcg_gen_and_tl(t0, t0, t1);
5001
    tcg_gen_andc_tl(t2, t2, t1);
5002
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5003
    tcg_temp_free(t0);
5004
    tcg_temp_free(t1);
5005
    tcg_temp_free(t2);
5006
    if (unlikely(Rc(ctx->opcode) != 0))
5007
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5008
}
5009

    
5010
/* sriq */
5011
static void gen_sriq(DisasContext *ctx)
5012
{
5013
    int sh = SH(ctx->opcode);
5014
    TCGv t0 = tcg_temp_new();
5015
    TCGv t1 = tcg_temp_new();
5016
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5017
    tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5018
    tcg_gen_or_tl(t1, t0, t1);
5019
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5020
    gen_store_spr(SPR_MQ, t1);
5021
    tcg_temp_free(t0);
5022
    tcg_temp_free(t1);
5023
    if (unlikely(Rc(ctx->opcode) != 0))
5024
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5025
}
5026

    
5027
/* srliq */
5028
static void gen_srliq(DisasContext *ctx)
5029
{
5030
    int sh = SH(ctx->opcode);
5031
    TCGv t0 = tcg_temp_new();
5032
    TCGv t1 = tcg_temp_new();
5033
    tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5034
    gen_load_spr(t1, SPR_MQ);
5035
    gen_store_spr(SPR_MQ, t0);
5036
    tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
5037
    tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
5038
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5039
    tcg_temp_free(t0);
5040
    tcg_temp_free(t1);
5041
    if (unlikely(Rc(ctx->opcode) != 0))
5042
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5043
}
5044

    
5045
/* srlq */
5046
static void gen_srlq(DisasContext *ctx)
5047
{
5048
    int l1 = gen_new_label();
5049
    int l2 = gen_new_label();
5050
    TCGv t0 = tcg_temp_local_new();
5051
    TCGv t1 = tcg_temp_local_new();
5052
    TCGv t2 = tcg_temp_local_new();
5053
    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5054
    tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5055
    tcg_gen_shr_tl(t2, t1, t2);
5056
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5057
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5058
    gen_load_spr(t0, SPR_MQ);
5059
    tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5060
    tcg_gen_br(l2);
5061
    gen_set_label(l1);
5062
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5063
    tcg_gen_and_tl(t0, t0, t2);
5064
    gen_load_spr(t1, SPR_MQ);
5065
    tcg_gen_andc_tl(t1, t1, t2);
5066
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5067
    gen_set_label(l2);
5068
    tcg_temp_free(t0);
5069
    tcg_temp_free(t1);
5070
    tcg_temp_free(t2);
5071
    if (unlikely(Rc(ctx->opcode) != 0))
5072
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5073
}
5074

    
5075
/* srq */
5076
static void gen_srq(DisasContext *ctx)
5077
{
5078
    int l1 = gen_new_label();
5079
    TCGv t0 = tcg_temp_new();
5080
    TCGv t1 = tcg_temp_new();
5081
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5082
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5083
    tcg_gen_subfi_tl(t1, 32, t1);
5084
    tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5085
    tcg_gen_or_tl(t1, t0, t1);
5086
    gen_store_spr(SPR_MQ, t1);
5087
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5088
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5089
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5090
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5091
    gen_set_label(l1);
5092
    tcg_temp_free(t0);
5093
    tcg_temp_free(t1);
5094
    if (unlikely(Rc(ctx->opcode) != 0))
5095
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5096
}
5097

    
5098
/* PowerPC 602 specific instructions */
5099

    
5100
/* dsa  */
5101
static void gen_dsa(DisasContext *ctx)
5102
{
5103
    /* XXX: TODO */
5104
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5105
}
5106

    
5107
/* esa */
5108
static void gen_esa(DisasContext *ctx)
5109
{
5110
    /* XXX: TODO */
5111
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5112
}
5113

    
5114
/* mfrom */
5115
static void gen_mfrom(DisasContext *ctx)
5116
{
5117
#if defined(CONFIG_USER_ONLY)
5118
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5119
#else
5120
    if (unlikely(!ctx->mem_idx)) {
5121
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5122
        return;
5123
    }
5124
    gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5125
#endif
5126
}
5127

    
5128
/* 602 - 603 - G2 TLB management */
5129

    
5130
/* tlbld */
5131
static void gen_tlbld_6xx(DisasContext *ctx)
5132
{
5133
#if defined(CONFIG_USER_ONLY)
5134
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5135
#else
5136
    if (unlikely(!ctx->mem_idx)) {
5137
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5138
        return;
5139
    }
5140
    gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5141
#endif
5142
}
5143

    
5144
/* tlbli */
5145
static void gen_tlbli_6xx(DisasContext *ctx)
5146
{
5147
#if defined(CONFIG_USER_ONLY)
5148
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5149
#else
5150
    if (unlikely(!ctx->mem_idx)) {
5151
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5152
        return;
5153
    }
5154
    gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5155
#endif
5156
}
5157

    
5158
/* 74xx TLB management */
5159

    
5160
/* tlbld */
5161
static void gen_tlbld_74xx(DisasContext *ctx)
5162
{
5163
#if defined(CONFIG_USER_ONLY)
5164
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5165
#else
5166
    if (unlikely(!ctx->mem_idx)) {
5167
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5168
        return;
5169
    }
5170
    gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5171
#endif
5172
}
5173

    
5174
/* tlbli */
5175
static void gen_tlbli_74xx(DisasContext *ctx)
5176
{
5177
#if defined(CONFIG_USER_ONLY)
5178
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5179
#else
5180
    if (unlikely(!ctx->mem_idx)) {
5181
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5182
        return;
5183
    }
5184
    gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5185
#endif
5186
}
5187

    
5188
/* POWER instructions not in PowerPC 601 */
5189

    
5190
/* clf */
5191
static void gen_clf(DisasContext *ctx)
5192
{
5193
    /* Cache line flush: implemented as no-op */
5194
}
5195

    
5196
/* cli */
5197
static void gen_cli(DisasContext *ctx)
5198
{
5199
    /* Cache line invalidate: privileged and treated as no-op */
5200
#if defined(CONFIG_USER_ONLY)
5201
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5202
#else
5203
    if (unlikely(!ctx->mem_idx)) {
5204
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5205
        return;
5206
    }
5207
#endif
5208
}
5209

    
5210
/* dclst */
5211
static void gen_dclst(DisasContext *ctx)
5212
{
5213
    /* Data cache line store: treated as no-op */
5214
}
5215

    
5216
static void gen_mfsri(DisasContext *ctx)
5217
{
5218
#if defined(CONFIG_USER_ONLY)
5219
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5220
#else
5221
    int ra = rA(ctx->opcode);
5222
    int rd = rD(ctx->opcode);
5223
    TCGv t0;
5224
    if (unlikely(!ctx->mem_idx)) {
5225
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5226
        return;
5227
    }
5228
    t0 = tcg_temp_new();
5229
    gen_addr_reg_index(ctx, t0);
5230
    tcg_gen_shri_tl(t0, t0, 28);
5231
    tcg_gen_andi_tl(t0, t0, 0xF);
5232
    gen_helper_load_sr(cpu_gpr[rd], t0);
5233
    tcg_temp_free(t0);
5234
    if (ra != 0 && ra != rd)
5235
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5236
#endif
5237
}
5238

    
5239
static void gen_rac(DisasContext *ctx)
5240
{
5241
#if defined(CONFIG_USER_ONLY)
5242
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5243
#else
5244
    TCGv t0;
5245
    if (unlikely(!ctx->mem_idx)) {
5246
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5247
        return;
5248
    }
5249
    t0 = tcg_temp_new();
5250
    gen_addr_reg_index(ctx, t0);
5251
    gen_helper_rac(cpu_gpr[rD(ctx->opcode)], t0);
5252
    tcg_temp_free(t0);
5253
#endif
5254
}
5255

    
5256
static void gen_rfsvc(DisasContext *ctx)
5257
{
5258
#if defined(CONFIG_USER_ONLY)
5259
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5260
#else
5261
    if (unlikely(!ctx->mem_idx)) {
5262
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5263
        return;
5264
    }
5265
    gen_helper_rfsvc();
5266
    gen_sync_exception(ctx);
5267
#endif
5268
}
5269

    
5270
/* svc is not implemented for now */
5271

    
5272
/* POWER2 specific instructions */
5273
/* Quad manipulation (load/store two floats at a time) */
5274

    
5275
/* lfq */
5276
static void gen_lfq(DisasContext *ctx)
5277
{
5278
    int rd = rD(ctx->opcode);
5279
    TCGv t0;
5280
    gen_set_access_type(ctx, ACCESS_FLOAT);
5281
    t0 = tcg_temp_new();
5282
    gen_addr_imm_index(ctx, t0, 0);
5283
    gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5284
    gen_addr_add(ctx, t0, t0, 8);
5285
    gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5286
    tcg_temp_free(t0);
5287
}
5288

    
5289
/* lfqu */
5290
static void gen_lfqu(DisasContext *ctx)
5291
{
5292
    int ra = rA(ctx->opcode);
5293
    int rd = rD(ctx->opcode);
5294
    TCGv t0, t1;
5295
    gen_set_access_type(ctx, ACCESS_FLOAT);
5296
    t0 = tcg_temp_new();
5297
    t1 = tcg_temp_new();
5298
    gen_addr_imm_index(ctx, t0, 0);
5299
    gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5300
    gen_addr_add(ctx, t1, t0, 8);
5301
    gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5302
    if (ra != 0)
5303
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
5304
    tcg_temp_free(t0);
5305
    tcg_temp_free(t1);
5306
}
5307

    
5308
/* lfqux */
5309
static void gen_lfqux(DisasContext *ctx)
5310
{
5311
    int ra = rA(ctx->opcode);
5312
    int rd = rD(ctx->opcode);
5313
    gen_set_access_type(ctx, ACCESS_FLOAT);
5314
    TCGv t0, t1;
5315
    t0 = tcg_temp_new();
5316
    gen_addr_reg_index(ctx, t0);
5317
    gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5318
    t1 = tcg_temp_new();
5319
    gen_addr_add(ctx, t1, t0, 8);
5320
    gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5321
    tcg_temp_free(t1);
5322
    if (ra != 0)
5323
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
5324
    tcg_temp_free(t0);
5325
}
5326

    
5327
/* lfqx */
5328
static void gen_lfqx(DisasContext *ctx)
5329
{
5330
    int rd = rD(ctx->opcode);
5331
    TCGv t0;
5332
    gen_set_access_type(ctx, ACCESS_FLOAT);
5333
    t0 = tcg_temp_new();
5334
    gen_addr_reg_index(ctx, t0);
5335
    gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5336
    gen_addr_add(ctx, t0, t0, 8);
5337
    gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5338
    tcg_temp_free(t0);
5339
}
5340

    
5341
/* stfq */
5342
static void gen_stfq(DisasContext *ctx)
5343
{
5344
    int rd = rD(ctx->opcode);
5345
    TCGv t0;
5346
    gen_set_access_type(ctx, ACCESS_FLOAT);
5347
    t0 = tcg_temp_new();
5348
    gen_addr_imm_index(ctx, t0, 0);
5349
    gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5350
    gen_addr_add(ctx, t0, t0, 8);
5351
    gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5352
    tcg_temp_free(t0);
5353
}
5354

    
5355
/* stfqu */
5356
static void gen_stfqu(DisasContext *ctx)
5357
{
5358
    int ra = rA(ctx->opcode);
5359
    int rd = rD(ctx->opcode);
5360
    TCGv t0, t1;
5361
    gen_set_access_type(ctx, ACCESS_FLOAT);
5362
    t0 = tcg_temp_new();
5363
    gen_addr_imm_index(ctx, t0, 0);
5364
    gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5365
    t1 = tcg_temp_new();
5366
    gen_addr_add(ctx, t1, t0, 8);
5367
    gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5368
    tcg_temp_free(t1);
5369
    if (ra != 0)
5370
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
5371
    tcg_temp_free(t0);
5372
}
5373

    
5374
/* stfqux */
5375
static void gen_stfqux(DisasContext *ctx)
5376
{
5377
    int ra = rA(ctx->opcode);
5378
    int rd = rD(ctx->opcode);
5379
    TCGv t0, t1;
5380
    gen_set_access_type(ctx, ACCESS_FLOAT);
5381
    t0 = tcg_temp_new();
5382
    gen_addr_reg_index(ctx, t0);
5383
    gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5384
    t1 = tcg_temp_new();
5385
    gen_addr_add(ctx, t1, t0, 8);
5386
    gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5387
    tcg_temp_free(t1);
5388
    if (ra != 0)
5389
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
5390
    tcg_temp_free(t0);
5391
}
5392

    
5393
/* stfqx */
5394
static void gen_stfqx(DisasContext *ctx)
5395
{
5396
    int rd = rD(ctx->opcode);
5397
    TCGv t0;
5398
    gen_set_access_type(ctx, ACCESS_FLOAT);
5399
    t0 = tcg_temp_new();
5400
    gen_addr_reg_index(ctx, t0);
5401
    gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5402
    gen_addr_add(ctx, t0, t0, 8);
5403
    gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5404
    tcg_temp_free(t0);
5405
}
5406

    
5407
/* BookE specific instructions */
5408

    
5409
/* XXX: not implemented on 440 ? */
5410
static void gen_mfapidi(DisasContext *ctx)
5411
{
5412
    /* XXX: TODO */
5413
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5414
}
5415

    
5416
/* XXX: not implemented on 440 ? */
5417
static void gen_tlbiva(DisasContext *ctx)
5418
{
5419
#if defined(CONFIG_USER_ONLY)
5420
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5421
#else
5422
    TCGv t0;
5423
    if (unlikely(!ctx->mem_idx)) {
5424
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5425
        return;
5426
    }
5427
    t0 = tcg_temp_new();
5428
    gen_addr_reg_index(ctx, t0);
5429
    gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
5430
    tcg_temp_free(t0);
5431
#endif
5432
}
5433

    
5434
/* All 405 MAC instructions are translated here */
5435
static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
5436
                                        int ra, int rb, int rt, int Rc)
5437
{
5438
    TCGv t0, t1;
5439

    
5440
    t0 = tcg_temp_local_new();
5441
    t1 = tcg_temp_local_new();
5442

    
5443
    switch (opc3 & 0x0D) {
5444
    case 0x05:
5445
        /* macchw    - macchw.    - macchwo   - macchwo.   */
5446
        /* macchws   - macchws.   - macchwso  - macchwso.  */
5447
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5448
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5449
        /* mulchw - mulchw. */
5450
        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5451
        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5452
        tcg_gen_ext16s_tl(t1, t1);
5453
        break;
5454
    case 0x04:
5455
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5456
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5457
        /* mulchwu - mulchwu. */
5458
        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5459
        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5460
        tcg_gen_ext16u_tl(t1, t1);
5461
        break;
5462
    case 0x01:
5463
        /* machhw    - machhw.    - machhwo   - machhwo.   */
5464
        /* machhws   - machhws.   - machhwso  - machhwso.  */
5465
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5466
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5467
        /* mulhhw - mulhhw. */
5468
        tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
5469
        tcg_gen_ext16s_tl(t0, t0);
5470
        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5471
        tcg_gen_ext16s_tl(t1, t1);
5472
        break;
5473
    case 0x00:
5474
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5475
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5476
        /* mulhhwu - mulhhwu. */
5477
        tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
5478
        tcg_gen_ext16u_tl(t0, t0);
5479
        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5480
        tcg_gen_ext16u_tl(t1, t1);
5481
        break;
5482
    case 0x0D:
5483
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5484
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5485
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5486
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5487
        /* mullhw - mullhw. */
5488
        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5489
        tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
5490
        break;
5491
    case 0x0C:
5492
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5493
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5494
        /* mullhwu - mullhwu. */
5495
        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5496
        tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
5497
        break;
5498
    }
5499
    if (opc2 & 0x04) {
5500
        /* (n)multiply-and-accumulate (0x0C / 0x0E) */
5501
        tcg_gen_mul_tl(t1, t0, t1);
5502
        if (opc2 & 0x02) {
5503
            /* nmultiply-and-accumulate (0x0E) */
5504
            tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
5505
        } else {
5506
            /* multiply-and-accumulate (0x0C) */
5507
            tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
5508
        }
5509

    
5510
        if (opc3 & 0x12) {
5511
            /* Check overflow and/or saturate */
5512
            int l1 = gen_new_label();
5513

    
5514
            if (opc3 & 0x10) {
5515
                /* Start with XER OV disabled, the most likely case */
5516
                tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
5517
            }
5518
            if (opc3 & 0x01) {
5519
                /* Signed */
5520
                tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
5521
                tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
5522
                tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
5523
                tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
5524
                if (opc3 & 0x02) {
5525
                    /* Saturate */
5526
                    tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
5527
                    tcg_gen_xori_tl(t0, t0, 0x7fffffff);
5528
                }
5529
            } else {
5530
                /* Unsigned */
5531
                tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5532
                if (opc3 & 0x02) {
5533
                    /* Saturate */
5534
                    tcg_gen_movi_tl(t0, UINT32_MAX);
5535
                }
5536
            }
5537
            if (opc3 & 0x10) {
5538
                /* Check overflow */
5539
                tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
5540
            }
5541
            gen_set_label(l1);
5542
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
5543
        }
5544
    } else {
5545
        tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
5546
    }
5547
    tcg_temp_free(t0);
5548
    tcg_temp_free(t1);
5549
    if (unlikely(Rc) != 0) {
5550
        /* Update Rc0 */
5551
        gen_set_Rc0(ctx, cpu_gpr[rt]);
5552
    }
5553
}
5554

    
5555
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
5556
static void glue(gen_, name)(DisasContext *ctx)                               \
5557
{                                                                             \
5558
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
5559
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
5560
}
5561

    
5562
/* macchw    - macchw.    */
5563
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
5564
/* macchwo   - macchwo.   */
5565
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
5566
/* macchws   - macchws.   */
5567
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
5568
/* macchwso  - macchwso.  */
5569
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
5570
/* macchwsu  - macchwsu.  */
5571
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
5572
/* macchwsuo - macchwsuo. */
5573
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
5574
/* macchwu   - macchwu.   */
5575
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
5576
/* macchwuo  - macchwuo.  */
5577
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
5578
/* machhw    - machhw.    */
5579
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
5580
/* machhwo   - machhwo.   */
5581
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
5582
/* machhws   - machhws.   */
5583
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
5584
/* machhwso  - machhwso.  */
5585
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
5586
/* machhwsu  - machhwsu.  */
5587
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
5588
/* machhwsuo - machhwsuo. */
5589
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
5590
/* machhwu   - machhwu.   */
5591
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
5592
/* machhwuo  - machhwuo.  */
5593
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
5594
/* maclhw    - maclhw.    */
5595
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
5596
/* maclhwo   - maclhwo.   */
5597
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
5598
/* maclhws   - maclhws.   */
5599
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
5600
/* maclhwso  - maclhwso.  */
5601
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
5602
/* maclhwu   - maclhwu.   */
5603
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
5604
/* maclhwuo  - maclhwuo.  */
5605
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
5606
/* maclhwsu  - maclhwsu.  */
5607
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
5608
/* maclhwsuo - maclhwsuo. */
5609
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
5610
/* nmacchw   - nmacchw.   */
5611
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
5612
/* nmacchwo  - nmacchwo.  */
5613
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
5614
/* nmacchws  - nmacchws.  */
5615
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
5616
/* nmacchwso - nmacchwso. */
5617
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
5618
/* nmachhw   - nmachhw.   */
5619
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
5620
/* nmachhwo  - nmachhwo.  */
5621
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
5622
/* nmachhws  - nmachhws.  */
5623
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
5624
/* nmachhwso - nmachhwso. */
5625
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
5626
/* nmaclhw   - nmaclhw.   */
5627
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
5628
/* nmaclhwo  - nmaclhwo.  */
5629
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
5630
/* nmaclhws  - nmaclhws.  */
5631
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
5632
/* nmaclhwso - nmaclhwso. */
5633
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
5634

    
5635
/* mulchw  - mulchw.  */
5636
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
5637
/* mulchwu - mulchwu. */
5638
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
5639
/* mulhhw  - mulhhw.  */
5640
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
5641
/* mulhhwu - mulhhwu. */
5642
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
5643
/* mullhw  - mullhw.  */
5644
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
5645
/* mullhwu - mullhwu. */
5646
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
5647

    
5648
/* mfdcr */
5649
static void gen_mfdcr(DisasContext *ctx)
5650
{
5651
#if defined(CONFIG_USER_ONLY)
5652
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5653
#else
5654
    TCGv dcrn;
5655
    if (unlikely(!ctx->mem_idx)) {
5656
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5657
        return;
5658
    }
5659
    /* NIP cannot be restored if the memory exception comes from an helper */
5660
    gen_update_nip(ctx, ctx->nip - 4);
5661
    dcrn = tcg_const_tl(SPR(ctx->opcode));
5662
    gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], dcrn);
5663
    tcg_temp_free(dcrn);
5664
#endif
5665
}
5666

    
5667
/* mtdcr */
5668
static void gen_mtdcr(DisasContext *ctx)
5669
{
5670
#if defined(CONFIG_USER_ONLY)
5671
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5672
#else
5673
    TCGv dcrn;
5674
    if (unlikely(!ctx->mem_idx)) {
5675
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5676
        return;
5677
    }
5678
    /* NIP cannot be restored if the memory exception comes from an helper */
5679
    gen_update_nip(ctx, ctx->nip - 4);
5680
    dcrn = tcg_const_tl(SPR(ctx->opcode));
5681
    gen_helper_store_dcr(dcrn, cpu_gpr[rS(ctx->opcode)]);
5682
    tcg_temp_free(dcrn);
5683
#endif
5684
}
5685

    
5686
/* mfdcrx */
5687
/* XXX: not implemented on 440 ? */
5688
static void gen_mfdcrx(DisasContext *ctx)
5689
{
5690
#if defined(CONFIG_USER_ONLY)
5691
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5692
#else
5693
    if (unlikely(!ctx->mem_idx)) {
5694
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5695
        return;
5696
    }
5697
    /* NIP cannot be restored if the memory exception comes from an helper */
5698
    gen_update_nip(ctx, ctx->nip - 4);
5699
    gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5700
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5701
#endif
5702
}
5703

    
5704
/* mtdcrx */
5705
/* XXX: not implemented on 440 ? */
5706
static void gen_mtdcrx(DisasContext *ctx)
5707
{
5708
#if defined(CONFIG_USER_ONLY)
5709
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5710
#else
5711
    if (unlikely(!ctx->mem_idx)) {
5712
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5713
        return;
5714
    }
5715
    /* NIP cannot be restored if the memory exception comes from an helper */
5716
    gen_update_nip(ctx, ctx->nip - 4);
5717
    gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5718
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5719
#endif
5720
}
5721

    
5722
/* mfdcrux (PPC 460) : user-mode access to DCR */
5723
static void gen_mfdcrux(DisasContext *ctx)
5724
{
5725
    /* NIP cannot be restored if the memory exception comes from an helper */
5726
    gen_update_nip(ctx, ctx->nip - 4);
5727
    gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5728
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5729
}
5730

    
5731
/* mtdcrux (PPC 460) : user-mode access to DCR */
5732
static void gen_mtdcrux(DisasContext *ctx)
5733
{
5734
    /* NIP cannot be restored if the memory exception comes from an helper */
5735
    gen_update_nip(ctx, ctx->nip - 4);
5736
    gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5737
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5738
}
5739

    
5740
/* dccci */
5741
static void gen_dccci(DisasContext *ctx)
5742
{
5743
#if defined(CONFIG_USER_ONLY)
5744
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5745
#else
5746
    if (unlikely(!ctx->mem_idx)) {
5747
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5748
        return;
5749
    }
5750
    /* interpreted as no-op */
5751
#endif
5752
}
5753

    
5754
/* dcread */
5755
static void gen_dcread(DisasContext *ctx)
5756
{
5757
#if defined(CONFIG_USER_ONLY)
5758
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5759
#else
5760
    TCGv EA, val;
5761
    if (unlikely(!ctx->mem_idx)) {
5762
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5763
        return;
5764
    }
5765
    gen_set_access_type(ctx, ACCESS_CACHE);
5766
    EA = tcg_temp_new();
5767
    gen_addr_reg_index(ctx, EA);
5768
    val = tcg_temp_new();
5769
    gen_qemu_ld32u(ctx, val, EA);
5770
    tcg_temp_free(val);
5771
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
5772
    tcg_temp_free(EA);
5773
#endif
5774
}
5775

    
5776
/* icbt */
5777
static void gen_icbt_40x(DisasContext *ctx)
5778
{
5779
    /* interpreted as no-op */
5780
    /* XXX: specification say this is treated as a load by the MMU
5781
     *      but does not generate any exception
5782
     */
5783
}
5784

    
5785
/* iccci */
5786
static void gen_iccci(DisasContext *ctx)
5787
{
5788
#if defined(CONFIG_USER_ONLY)
5789
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5790
#else
5791
    if (unlikely(!ctx->mem_idx)) {
5792
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5793
        return;
5794
    }
5795
    /* interpreted as no-op */
5796
#endif
5797
}
5798

    
5799
/* icread */
5800
static void gen_icread(DisasContext *ctx)
5801
{
5802
#if defined(CONFIG_USER_ONLY)
5803
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5804
#else
5805
    if (unlikely(!ctx->mem_idx)) {
5806
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5807
        return;
5808
    }
5809
    /* interpreted as no-op */
5810
#endif
5811
}
5812

    
5813
/* rfci (mem_idx only) */
5814
static void gen_rfci_40x(DisasContext *ctx)
5815
{
5816
#if defined(CONFIG_USER_ONLY)
5817
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5818
#else
5819
    if (unlikely(!ctx->mem_idx)) {
5820
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5821
        return;
5822
    }
5823
    /* Restore CPU state */
5824
    gen_helper_40x_rfci();
5825
    gen_sync_exception(ctx);
5826
#endif
5827
}
5828

    
5829
static void gen_rfci(DisasContext *ctx)
5830
{
5831
#if defined(CONFIG_USER_ONLY)
5832
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5833
#else
5834
    if (unlikely(!ctx->mem_idx)) {
5835
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5836
        return;
5837
    }
5838
    /* Restore CPU state */
5839
    gen_helper_rfci();
5840
    gen_sync_exception(ctx);
5841
#endif
5842
}
5843

    
5844
/* BookE specific */
5845

    
5846
/* XXX: not implemented on 440 ? */
5847
static void gen_rfdi(DisasContext *ctx)
5848
{
5849
#if defined(CONFIG_USER_ONLY)
5850
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5851
#else
5852
    if (unlikely(!ctx->mem_idx)) {
5853
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5854
        return;
5855
    }
5856
    /* Restore CPU state */
5857
    gen_helper_rfdi();
5858
    gen_sync_exception(ctx);
5859
#endif
5860
}
5861

    
5862
/* XXX: not implemented on 440 ? */
5863
static void gen_rfmci(DisasContext *ctx)
5864
{
5865
#if defined(CONFIG_USER_ONLY)
5866
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5867
#else
5868
    if (unlikely(!ctx->mem_idx)) {
5869
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5870
        return;
5871
    }
5872
    /* Restore CPU state */
5873
    gen_helper_rfmci();
5874
    gen_sync_exception(ctx);
5875
#endif
5876
}
5877

    
5878
/* TLB management - PowerPC 405 implementation */
5879

    
5880
/* tlbre */
5881
static void gen_tlbre_40x(DisasContext *ctx)
5882
{
5883
#if defined(CONFIG_USER_ONLY)
5884
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5885
#else
5886
    if (unlikely(!ctx->mem_idx)) {
5887
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5888
        return;
5889
    }
5890
    switch (rB(ctx->opcode)) {
5891
    case 0:
5892
        gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5893
        break;
5894
    case 1:
5895
        gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5896
        break;
5897
    default:
5898
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5899
        break;
5900
    }
5901
#endif
5902
}
5903

    
5904
/* tlbsx - tlbsx. */
5905
static void gen_tlbsx_40x(DisasContext *ctx)
5906
{
5907
#if defined(CONFIG_USER_ONLY)
5908
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5909
#else
5910
    TCGv t0;
5911
    if (unlikely(!ctx->mem_idx)) {
5912
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5913
        return;
5914
    }
5915
    t0 = tcg_temp_new();
5916
    gen_addr_reg_index(ctx, t0);
5917
    gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5918
    tcg_temp_free(t0);
5919
    if (Rc(ctx->opcode)) {
5920
        int l1 = gen_new_label();
5921
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
5922
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
5923
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
5924
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5925
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5926
        gen_set_label(l1);
5927
    }
5928
#endif
5929
}
5930

    
5931
/* tlbwe */
5932
static void gen_tlbwe_40x(DisasContext *ctx)
5933
{
5934
#if defined(CONFIG_USER_ONLY)
5935
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5936
#else
5937
    if (unlikely(!ctx->mem_idx)) {
5938
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5939
        return;
5940
    }
5941
    switch (rB(ctx->opcode)) {
5942
    case 0:
5943
        gen_helper_4xx_tlbwe_hi(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5944
        break;
5945
    case 1:
5946
        gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5947
        break;
5948
    default:
5949
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5950
        break;
5951
    }
5952
#endif
5953
}
5954

    
5955
/* TLB management - PowerPC 440 implementation */
5956

    
5957
/* tlbre */
5958
static void gen_tlbre_440(DisasContext *ctx)
5959
{
5960
#if defined(CONFIG_USER_ONLY)
5961
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5962
#else
5963
    if (unlikely(!ctx->mem_idx)) {
5964
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5965
        return;
5966
    }
5967
    switch (rB(ctx->opcode)) {
5968
    case 0:
5969
    case 1:
5970
    case 2:
5971
        {
5972
            TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
5973
            gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], t0, cpu_gpr[rA(ctx->opcode)]);
5974
            tcg_temp_free_i32(t0);
5975
        }
5976
        break;
5977
    default:
5978
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5979
        break;
5980
    }
5981
#endif
5982
}
5983

    
5984
/* tlbsx - tlbsx. */
5985
static void gen_tlbsx_440(DisasContext *ctx)
5986
{
5987
#if defined(CONFIG_USER_ONLY)
5988
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5989
#else
5990
    TCGv t0;
5991
    if (unlikely(!ctx->mem_idx)) {
5992
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5993
        return;
5994
    }
5995
    t0 = tcg_temp_new();
5996
    gen_addr_reg_index(ctx, t0);
5997
    gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5998
    tcg_temp_free(t0);
5999
    if (Rc(ctx->opcode)) {
6000
        int l1 = gen_new_label();
6001
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
6002
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
6003
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
6004
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6005
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6006
        gen_set_label(l1);
6007
    }
6008
#endif
6009
}
6010

    
6011
/* tlbwe */
6012
static void gen_tlbwe_440(DisasContext *ctx)
6013
{
6014
#if defined(CONFIG_USER_ONLY)
6015
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6016
#else
6017
    if (unlikely(!ctx->mem_idx)) {
6018
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6019
        return;
6020
    }
6021
    switch (rB(ctx->opcode)) {
6022
    case 0:
6023
    case 1:
6024
    case 2:
6025
        {
6026
            TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6027
            gen_helper_440_tlbwe(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
6028
            tcg_temp_free_i32(t0);
6029
        }
6030
        break;
6031
    default:
6032
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6033
        break;
6034
    }
6035
#endif
6036
}
6037

    
6038
/* TLB management - PowerPC BookE 2.06 implementation */
6039

    
6040
/* tlbre */
6041
static void gen_tlbre_booke206(DisasContext *ctx)
6042
{
6043
#if defined(CONFIG_USER_ONLY)
6044
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6045
#else
6046
    if (unlikely(!ctx->mem_idx)) {
6047
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6048
        return;
6049
    }
6050

    
6051
    gen_helper_booke206_tlbre();
6052
#endif
6053
}
6054

    
6055
/* tlbsx - tlbsx. */
6056
static void gen_tlbsx_booke206(DisasContext *ctx)
6057
{
6058
#if defined(CONFIG_USER_ONLY)
6059
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6060
#else
6061
    TCGv t0;
6062
    if (unlikely(!ctx->mem_idx)) {
6063
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6064
        return;
6065
    }
6066

    
6067
    if (rA(ctx->opcode)) {
6068
        t0 = tcg_temp_new();
6069
        tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
6070
    } else {
6071
        t0 = tcg_const_tl(0);
6072
    }
6073

    
6074
    tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
6075
    gen_helper_booke206_tlbsx(t0);
6076
#endif
6077
}
6078

    
6079
/* tlbwe */
6080
static void gen_tlbwe_booke206(DisasContext *ctx)
6081
{
6082
#if defined(CONFIG_USER_ONLY)
6083
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6084
#else
6085
    if (unlikely(!ctx->mem_idx)) {
6086
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6087
        return;
6088
    }
6089
    gen_helper_booke206_tlbwe();
6090
#endif
6091
}
6092

    
6093
static void gen_tlbivax_booke206(DisasContext *ctx)
6094
{
6095
#if defined(CONFIG_USER_ONLY)
6096
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6097
#else
6098
    TCGv t0;
6099
    if (unlikely(!ctx->mem_idx)) {
6100
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6101
        return;
6102
    }
6103

    
6104
    t0 = tcg_temp_new();
6105
    gen_addr_reg_index(ctx, t0);
6106

    
6107
    gen_helper_booke206_tlbivax(t0);
6108
#endif
6109
}
6110

    
6111

    
6112
/* wrtee */
6113
static void gen_wrtee(DisasContext *ctx)
6114
{
6115
#if defined(CONFIG_USER_ONLY)
6116
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6117
#else
6118
    TCGv t0;
6119
    if (unlikely(!ctx->mem_idx)) {
6120
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6121
        return;
6122
    }
6123
    t0 = tcg_temp_new();
6124
    tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
6125
    tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6126
    tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
6127
    tcg_temp_free(t0);
6128
    /* Stop translation to have a chance to raise an exception
6129
     * if we just set msr_ee to 1
6130
     */
6131
    gen_stop_exception(ctx);
6132
#endif
6133
}
6134

    
6135
/* wrteei */
6136
static void gen_wrteei(DisasContext *ctx)
6137
{
6138
#if defined(CONFIG_USER_ONLY)
6139
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6140
#else
6141
    if (unlikely(!ctx->mem_idx)) {
6142
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6143
        return;
6144
    }
6145
    if (ctx->opcode & 0x00008000) {
6146
        tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
6147
        /* Stop translation to have a chance to raise an exception */
6148
        gen_stop_exception(ctx);
6149
    } else {
6150
        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6151
    }
6152
#endif
6153
}
6154

    
6155
/* PowerPC 440 specific instructions */
6156

    
6157
/* dlmzb */
6158
static void gen_dlmzb(DisasContext *ctx)
6159
{
6160
    TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
6161
    gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
6162
                     cpu_gpr[rB(ctx->opcode)], t0);
6163
    tcg_temp_free_i32(t0);
6164
}
6165

    
6166
/* mbar replaces eieio on 440 */
6167
static void gen_mbar(DisasContext *ctx)
6168
{
6169
    /* interpreted as no-op */
6170
}
6171

    
6172
/* msync replaces sync on 440 */
6173
static void gen_msync(DisasContext *ctx)
6174
{
6175
    /* interpreted as no-op */
6176
}
6177

    
6178
/* icbt */
6179
static void gen_icbt_440(DisasContext *ctx)
6180
{
6181
    /* interpreted as no-op */
6182
    /* XXX: specification say this is treated as a load by the MMU
6183
     *      but does not generate any exception
6184
     */
6185
}
6186

    
6187
/***                      Altivec vector extension                         ***/
6188
/* Altivec registers moves */
6189

    
6190
static inline TCGv_ptr gen_avr_ptr(int reg)
6191
{
6192
    TCGv_ptr r = tcg_temp_new_ptr();
6193
    tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
6194
    return r;
6195
}
6196

    
6197
#define GEN_VR_LDX(name, opc2, opc3)                                          \
6198
static void glue(gen_, name)(DisasContext *ctx)                                       \
6199
{                                                                             \
6200
    TCGv EA;                                                                  \
6201
    if (unlikely(!ctx->altivec_enabled)) {                                    \
6202
        gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6203
        return;                                                               \
6204
    }                                                                         \
6205
    gen_set_access_type(ctx, ACCESS_INT);                                     \
6206
    EA = tcg_temp_new();                                                      \
6207
    gen_addr_reg_index(ctx, EA);                                              \
6208
    tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6209
    if (ctx->le_mode) {                                                       \
6210
        gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6211
        tcg_gen_addi_tl(EA, EA, 8);                                           \
6212
        gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6213
    } else {                                                                  \
6214
        gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6215
        tcg_gen_addi_tl(EA, EA, 8);                                           \
6216
        gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6217
    }                                                                         \
6218
    tcg_temp_free(EA);                                                        \
6219
}
6220

    
6221
#define GEN_VR_STX(name, opc2, opc3)                                          \
6222
static void gen_st##name(DisasContext *ctx)                                   \
6223
{                                                                             \
6224
    TCGv EA;                                                                  \
6225
    if (unlikely(!ctx->altivec_enabled)) {                                    \
6226
        gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6227
        return;                                                               \
6228
    }                                                                         \
6229
    gen_set_access_type(ctx, ACCESS_INT);                                     \
6230
    EA = tcg_temp_new();                                                      \
6231
    gen_addr_reg_index(ctx, EA);                                              \
6232
    tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6233
    if (ctx->le_mode) {                                                       \
6234
        gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6235
        tcg_gen_addi_tl(EA, EA, 8);                                           \
6236
        gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6237
    } else {                                                                  \
6238
        gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6239
        tcg_gen_addi_tl(EA, EA, 8);                                           \
6240
        gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6241
    }                                                                         \
6242
    tcg_temp_free(EA);                                                        \
6243
}
6244

    
6245
#define GEN_VR_LVE(name, opc2, opc3)                                    \
6246
static void gen_lve##name(DisasContext *ctx)                            \
6247
    {                                                                   \
6248
        TCGv EA;                                                        \
6249
        TCGv_ptr rs;                                                    \
6250
        if (unlikely(!ctx->altivec_enabled)) {                          \
6251
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6252
            return;                                                     \
6253
        }                                                               \
6254
        gen_set_access_type(ctx, ACCESS_INT);                           \
6255
        EA = tcg_temp_new();                                            \
6256
        gen_addr_reg_index(ctx, EA);                                    \
6257
        rs = gen_avr_ptr(rS(ctx->opcode));                              \
6258
        gen_helper_lve##name (rs, EA);                                  \
6259
        tcg_temp_free(EA);                                              \
6260
        tcg_temp_free_ptr(rs);                                          \
6261
    }
6262

    
6263
#define GEN_VR_STVE(name, opc2, opc3)                                   \
6264
static void gen_stve##name(DisasContext *ctx)                           \
6265
    {                                                                   \
6266
        TCGv EA;                                                        \
6267
        TCGv_ptr rs;                                                    \
6268
        if (unlikely(!ctx->altivec_enabled)) {                          \
6269
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6270
            return;                                                     \
6271
        }                                                               \
6272
        gen_set_access_type(ctx, ACCESS_INT);                           \
6273
        EA = tcg_temp_new();                                            \
6274
        gen_addr_reg_index(ctx, EA);                                    \
6275
        rs = gen_avr_ptr(rS(ctx->opcode));                              \
6276
        gen_helper_stve##name (rs, EA);                                 \
6277
        tcg_temp_free(EA);                                              \
6278
        tcg_temp_free_ptr(rs);                                          \
6279
    }
6280

    
6281
GEN_VR_LDX(lvx, 0x07, 0x03);
6282
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
6283
GEN_VR_LDX(lvxl, 0x07, 0x0B);
6284

    
6285
GEN_VR_LVE(bx, 0x07, 0x00);
6286
GEN_VR_LVE(hx, 0x07, 0x01);
6287
GEN_VR_LVE(wx, 0x07, 0x02);
6288

    
6289
GEN_VR_STX(svx, 0x07, 0x07);
6290
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
6291
GEN_VR_STX(svxl, 0x07, 0x0F);
6292

    
6293
GEN_VR_STVE(bx, 0x07, 0x04);
6294
GEN_VR_STVE(hx, 0x07, 0x05);
6295
GEN_VR_STVE(wx, 0x07, 0x06);
6296

    
6297
static void gen_lvsl(DisasContext *ctx)
6298
{
6299
    TCGv_ptr rd;
6300
    TCGv EA;
6301
    if (unlikely(!ctx->altivec_enabled)) {
6302
        gen_exception(ctx, POWERPC_EXCP_VPU);
6303
        return;
6304
    }
6305
    EA = tcg_temp_new();
6306
    gen_addr_reg_index(ctx, EA);
6307
    rd = gen_avr_ptr(rD(ctx->opcode));
6308
    gen_helper_lvsl(rd, EA);
6309
    tcg_temp_free(EA);
6310
    tcg_temp_free_ptr(rd);
6311
}
6312

    
6313
static void gen_lvsr(DisasContext *ctx)
6314
{
6315
    TCGv_ptr rd;
6316
    TCGv EA;
6317
    if (unlikely(!ctx->altivec_enabled)) {
6318
        gen_exception(ctx, POWERPC_EXCP_VPU);
6319
        return;
6320
    }
6321
    EA = tcg_temp_new();
6322
    gen_addr_reg_index(ctx, EA);
6323
    rd = gen_avr_ptr(rD(ctx->opcode));
6324
    gen_helper_lvsr(rd, EA);
6325
    tcg_temp_free(EA);
6326
    tcg_temp_free_ptr(rd);
6327
}
6328

    
6329
static void gen_mfvscr(DisasContext *ctx)
6330
{
6331
    TCGv_i32 t;
6332
    if (unlikely(!ctx->altivec_enabled)) {
6333
        gen_exception(ctx, POWERPC_EXCP_VPU);
6334
        return;
6335
    }
6336
    tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
6337
    t = tcg_temp_new_i32();
6338
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, vscr));
6339
    tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
6340
    tcg_temp_free_i32(t);
6341
}
6342

    
6343
static void gen_mtvscr(DisasContext *ctx)
6344
{
6345
    TCGv_ptr p;
6346
    if (unlikely(!ctx->altivec_enabled)) {
6347
        gen_exception(ctx, POWERPC_EXCP_VPU);
6348
        return;
6349
    }
6350
    p = gen_avr_ptr(rD(ctx->opcode));
6351
    gen_helper_mtvscr(p);
6352
    tcg_temp_free_ptr(p);
6353
}
6354

    
6355
/* Logical operations */
6356
#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
6357
static void glue(gen_, name)(DisasContext *ctx)                                 \
6358
{                                                                       \
6359
    if (unlikely(!ctx->altivec_enabled)) {                              \
6360
        gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6361
        return;                                                         \
6362
    }                                                                   \
6363
    tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
6364
    tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
6365
}
6366

    
6367
GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
6368
GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
6369
GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
6370
GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
6371
GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
6372

    
6373
#define GEN_VXFORM(name, opc2, opc3)                                    \
6374
static void glue(gen_, name)(DisasContext *ctx)                                 \
6375
{                                                                       \
6376
    TCGv_ptr ra, rb, rd;                                                \
6377
    if (unlikely(!ctx->altivec_enabled)) {                              \
6378
        gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6379
        return;                                                         \
6380
    }                                                                   \
6381
    ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6382
    rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6383
    rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6384
    gen_helper_##name (rd, ra, rb);                                     \
6385
    tcg_temp_free_ptr(ra);                                              \
6386
    tcg_temp_free_ptr(rb);                                              \
6387
    tcg_temp_free_ptr(rd);                                              \
6388
}
6389

    
6390
GEN_VXFORM(vaddubm, 0, 0);
6391
GEN_VXFORM(vadduhm, 0, 1);
6392
GEN_VXFORM(vadduwm, 0, 2);
6393
GEN_VXFORM(vsububm, 0, 16);
6394
GEN_VXFORM(vsubuhm, 0, 17);
6395
GEN_VXFORM(vsubuwm, 0, 18);
6396
GEN_VXFORM(vmaxub, 1, 0);
6397
GEN_VXFORM(vmaxuh, 1, 1);
6398
GEN_VXFORM(vmaxuw, 1, 2);
6399
GEN_VXFORM(vmaxsb, 1, 4);
6400
GEN_VXFORM(vmaxsh, 1, 5);
6401
GEN_VXFORM(vmaxsw, 1, 6);
6402
GEN_VXFORM(vminub, 1, 8);
6403
GEN_VXFORM(vminuh, 1, 9);
6404
GEN_VXFORM(vminuw, 1, 10);
6405
GEN_VXFORM(vminsb, 1, 12);
6406
GEN_VXFORM(vminsh, 1, 13);
6407
GEN_VXFORM(vminsw, 1, 14);
6408
GEN_VXFORM(vavgub, 1, 16);
6409
GEN_VXFORM(vavguh, 1, 17);
6410
GEN_VXFORM(vavguw, 1, 18);
6411
GEN_VXFORM(vavgsb, 1, 20);
6412
GEN_VXFORM(vavgsh, 1, 21);
6413
GEN_VXFORM(vavgsw, 1, 22);
6414
GEN_VXFORM(vmrghb, 6, 0);
6415
GEN_VXFORM(vmrghh, 6, 1);
6416
GEN_VXFORM(vmrghw, 6, 2);
6417
GEN_VXFORM(vmrglb, 6, 4);
6418
GEN_VXFORM(vmrglh, 6, 5);
6419
GEN_VXFORM(vmrglw, 6, 6);
6420
GEN_VXFORM(vmuloub, 4, 0);
6421
GEN_VXFORM(vmulouh, 4, 1);
6422
GEN_VXFORM(vmulosb, 4, 4);
6423
GEN_VXFORM(vmulosh, 4, 5);
6424
GEN_VXFORM(vmuleub, 4, 8);
6425
GEN_VXFORM(vmuleuh, 4, 9);
6426
GEN_VXFORM(vmulesb, 4, 12);
6427
GEN_VXFORM(vmulesh, 4, 13);
6428
GEN_VXFORM(vslb, 2, 4);
6429
GEN_VXFORM(vslh, 2, 5);
6430
GEN_VXFORM(vslw, 2, 6);
6431
GEN_VXFORM(vsrb, 2, 8);
6432
GEN_VXFORM(vsrh, 2, 9);
6433
GEN_VXFORM(vsrw, 2, 10);
6434
GEN_VXFORM(vsrab, 2, 12);
6435
GEN_VXFORM(vsrah, 2, 13);
6436
GEN_VXFORM(vsraw, 2, 14);
6437
GEN_VXFORM(vslo, 6, 16);
6438
GEN_VXFORM(vsro, 6, 17);
6439
GEN_VXFORM(vaddcuw, 0, 6);
6440
GEN_VXFORM(vsubcuw, 0, 22);
6441
GEN_VXFORM(vaddubs, 0, 8);
6442
GEN_VXFORM(vadduhs, 0, 9);
6443
GEN_VXFORM(vadduws, 0, 10);
6444
GEN_VXFORM(vaddsbs, 0, 12);
6445
GEN_VXFORM(vaddshs, 0, 13);
6446
GEN_VXFORM(vaddsws, 0, 14);
6447
GEN_VXFORM(vsububs, 0, 24);
6448
GEN_VXFORM(vsubuhs, 0, 25);
6449
GEN_VXFORM(vsubuws, 0, 26);
6450
GEN_VXFORM(vsubsbs, 0, 28);
6451
GEN_VXFORM(vsubshs, 0, 29);
6452
GEN_VXFORM(vsubsws, 0, 30);
6453
GEN_VXFORM(vrlb, 2, 0);
6454
GEN_VXFORM(vrlh, 2, 1);
6455
GEN_VXFORM(vrlw, 2, 2);
6456
GEN_VXFORM(vsl, 2, 7);
6457
GEN_VXFORM(vsr, 2, 11);
6458
GEN_VXFORM(vpkuhum, 7, 0);
6459
GEN_VXFORM(vpkuwum, 7, 1);
6460
GEN_VXFORM(vpkuhus, 7, 2);
6461
GEN_VXFORM(vpkuwus, 7, 3);
6462
GEN_VXFORM(vpkshus, 7, 4);
6463
GEN_VXFORM(vpkswus, 7, 5);
6464
GEN_VXFORM(vpkshss, 7, 6);
6465
GEN_VXFORM(vpkswss, 7, 7);
6466
GEN_VXFORM(vpkpx, 7, 12);
6467
GEN_VXFORM(vsum4ubs, 4, 24);
6468
GEN_VXFORM(vsum4sbs, 4, 28);
6469
GEN_VXFORM(vsum4shs, 4, 25);
6470
GEN_VXFORM(vsum2sws, 4, 26);
6471
GEN_VXFORM(vsumsws, 4, 30);
6472
GEN_VXFORM(vaddfp, 5, 0);
6473
GEN_VXFORM(vsubfp, 5, 1);
6474
GEN_VXFORM(vmaxfp, 5, 16);
6475
GEN_VXFORM(vminfp, 5, 17);
6476

    
6477
#define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
6478
static void glue(gen_, name)(DisasContext *ctx)                         \
6479
    {                                                                   \
6480
        TCGv_ptr ra, rb, rd;                                            \
6481
        if (unlikely(!ctx->altivec_enabled)) {                          \
6482
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6483
            return;                                                     \
6484
        }                                                               \
6485
        ra = gen_avr_ptr(rA(ctx->opcode));                              \
6486
        rb = gen_avr_ptr(rB(ctx->opcode));                              \
6487
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6488
        gen_helper_##opname (rd, ra, rb);                               \
6489
        tcg_temp_free_ptr(ra);                                          \
6490
        tcg_temp_free_ptr(rb);                                          \
6491
        tcg_temp_free_ptr(rd);                                          \
6492
    }
6493

    
6494
#define GEN_VXRFORM(name, opc2, opc3)                                \
6495
    GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
6496
    GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
6497

    
6498
GEN_VXRFORM(vcmpequb, 3, 0)
6499
GEN_VXRFORM(vcmpequh, 3, 1)
6500
GEN_VXRFORM(vcmpequw, 3, 2)
6501
GEN_VXRFORM(vcmpgtsb, 3, 12)
6502
GEN_VXRFORM(vcmpgtsh, 3, 13)
6503
GEN_VXRFORM(vcmpgtsw, 3, 14)
6504
GEN_VXRFORM(vcmpgtub, 3, 8)
6505
GEN_VXRFORM(vcmpgtuh, 3, 9)
6506
GEN_VXRFORM(vcmpgtuw, 3, 10)
6507
GEN_VXRFORM(vcmpeqfp, 3, 3)
6508
GEN_VXRFORM(vcmpgefp, 3, 7)
6509
GEN_VXRFORM(vcmpgtfp, 3, 11)
6510
GEN_VXRFORM(vcmpbfp, 3, 15)
6511

    
6512
#define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
6513
static void glue(gen_, name)(DisasContext *ctx)                         \
6514
    {                                                                   \
6515
        TCGv_ptr rd;                                                    \
6516
        TCGv_i32 simm;                                                  \
6517
        if (unlikely(!ctx->altivec_enabled)) {                          \
6518
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6519
            return;                                                     \
6520
        }                                                               \
6521
        simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
6522
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6523
        gen_helper_##name (rd, simm);                                   \
6524
        tcg_temp_free_i32(simm);                                        \
6525
        tcg_temp_free_ptr(rd);                                          \
6526
    }
6527

    
6528
GEN_VXFORM_SIMM(vspltisb, 6, 12);
6529
GEN_VXFORM_SIMM(vspltish, 6, 13);
6530
GEN_VXFORM_SIMM(vspltisw, 6, 14);
6531

    
6532
#define GEN_VXFORM_NOA(name, opc2, opc3)                                \
6533
static void glue(gen_, name)(DisasContext *ctx)                                 \
6534
    {                                                                   \
6535
        TCGv_ptr rb, rd;                                                \
6536
        if (unlikely(!ctx->altivec_enabled)) {                          \
6537
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6538
            return;                                                     \
6539
        }                                                               \
6540
        rb = gen_avr_ptr(rB(ctx->opcode));                              \
6541
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6542
        gen_helper_##name (rd, rb);                                     \
6543
        tcg_temp_free_ptr(rb);                                          \
6544
        tcg_temp_free_ptr(rd);                                         \
6545
    }
6546

    
6547
GEN_VXFORM_NOA(vupkhsb, 7, 8);
6548
GEN_VXFORM_NOA(vupkhsh, 7, 9);
6549
GEN_VXFORM_NOA(vupklsb, 7, 10);
6550
GEN_VXFORM_NOA(vupklsh, 7, 11);
6551
GEN_VXFORM_NOA(vupkhpx, 7, 13);
6552
GEN_VXFORM_NOA(vupklpx, 7, 15);
6553
GEN_VXFORM_NOA(vrefp, 5, 4);
6554
GEN_VXFORM_NOA(vrsqrtefp, 5, 5);
6555
GEN_VXFORM_NOA(vexptefp, 5, 6);
6556
GEN_VXFORM_NOA(vlogefp, 5, 7);
6557
GEN_VXFORM_NOA(vrfim, 5, 8);
6558
GEN_VXFORM_NOA(vrfin, 5, 9);
6559
GEN_VXFORM_NOA(vrfip, 5, 10);
6560
GEN_VXFORM_NOA(vrfiz, 5, 11);
6561

    
6562
#define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
6563
static void glue(gen_, name)(DisasContext *ctx)                                 \
6564
    {                                                                   \
6565
        TCGv_ptr rd;                                                    \
6566
        TCGv_i32 simm;                                                  \
6567
        if (unlikely(!ctx->altivec_enabled)) {                          \
6568
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6569
            return;                                                     \
6570
        }                                                               \
6571
        simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
6572
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6573
        gen_helper_##name (rd, simm);                                   \
6574
        tcg_temp_free_i32(simm);                                        \
6575
        tcg_temp_free_ptr(rd);                                          \
6576
    }
6577

    
6578
#define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
6579
static void glue(gen_, name)(DisasContext *ctx)                                 \
6580
    {                                                                   \
6581
        TCGv_ptr rb, rd;                                                \
6582
        TCGv_i32 uimm;                                                  \
6583
        if (unlikely(!ctx->altivec_enabled)) {                          \
6584
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6585
            return;                                                     \
6586
        }                                                               \
6587
        uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
6588
        rb = gen_avr_ptr(rB(ctx->opcode));                              \
6589
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6590
        gen_helper_##name (rd, rb, uimm);                               \
6591
        tcg_temp_free_i32(uimm);                                        \
6592
        tcg_temp_free_ptr(rb);                                          \
6593
        tcg_temp_free_ptr(rd);                                          \
6594
    }
6595

    
6596
GEN_VXFORM_UIMM(vspltb, 6, 8);
6597
GEN_VXFORM_UIMM(vsplth, 6, 9);
6598
GEN_VXFORM_UIMM(vspltw, 6, 10);
6599
GEN_VXFORM_UIMM(vcfux, 5, 12);
6600
GEN_VXFORM_UIMM(vcfsx, 5, 13);
6601
GEN_VXFORM_UIMM(vctuxs, 5, 14);
6602
GEN_VXFORM_UIMM(vctsxs, 5, 15);
6603

    
6604
static void gen_vsldoi(DisasContext *ctx)
6605
{
6606
    TCGv_ptr ra, rb, rd;
6607
    TCGv_i32 sh;
6608
    if (unlikely(!ctx->altivec_enabled)) {
6609
        gen_exception(ctx, POWERPC_EXCP_VPU);
6610
        return;
6611
    }
6612
    ra = gen_avr_ptr(rA(ctx->opcode));
6613
    rb = gen_avr_ptr(rB(ctx->opcode));
6614
    rd = gen_avr_ptr(rD(ctx->opcode));
6615
    sh = tcg_const_i32(VSH(ctx->opcode));
6616
    gen_helper_vsldoi (rd, ra, rb, sh);
6617
    tcg_temp_free_ptr(ra);
6618
    tcg_temp_free_ptr(rb);
6619
    tcg_temp_free_ptr(rd);
6620
    tcg_temp_free_i32(sh);
6621
}
6622

    
6623
#define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
6624
static void glue(gen_, name0##_##name1)(DisasContext *ctx)                      \
6625
    {                                                                   \
6626
        TCGv_ptr ra, rb, rc, rd;                                        \
6627
        if (unlikely(!ctx->altivec_enabled)) {                          \
6628
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6629
            return;                                                     \
6630
        }                                                               \
6631
        ra = gen_avr_ptr(rA(ctx->opcode));                              \
6632
        rb = gen_avr_ptr(rB(ctx->opcode));                              \
6633
        rc = gen_avr_ptr(rC(ctx->opcode));                              \
6634
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6635
        if (Rc(ctx->opcode)) {                                          \
6636
            gen_helper_##name1 (rd, ra, rb, rc);                        \
6637
        } else {                                                        \
6638
            gen_helper_##name0 (rd, ra, rb, rc);                        \
6639
        }                                                               \
6640
        tcg_temp_free_ptr(ra);                                          \
6641
        tcg_temp_free_ptr(rb);                                          \
6642
        tcg_temp_free_ptr(rc);                                          \
6643
        tcg_temp_free_ptr(rd);                                          \
6644
    }
6645

    
6646
GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
6647

    
6648
static void gen_vmladduhm(DisasContext *ctx)
6649
{
6650
    TCGv_ptr ra, rb, rc, rd;
6651
    if (unlikely(!ctx->altivec_enabled)) {
6652
        gen_exception(ctx, POWERPC_EXCP_VPU);
6653
        return;
6654
    }
6655
    ra = gen_avr_ptr(rA(ctx->opcode));
6656
    rb = gen_avr_ptr(rB(ctx->opcode));
6657
    rc = gen_avr_ptr(rC(ctx->opcode));
6658
    rd = gen_avr_ptr(rD(ctx->opcode));
6659
    gen_helper_vmladduhm(rd, ra, rb, rc);
6660
    tcg_temp_free_ptr(ra);
6661
    tcg_temp_free_ptr(rb);
6662
    tcg_temp_free_ptr(rc);
6663
    tcg_temp_free_ptr(rd);
6664
}
6665

    
6666
GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
6667
GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
6668
GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
6669
GEN_VAFORM_PAIRED(vsel, vperm, 21)
6670
GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
6671

    
6672
/***                           SPE extension                               ***/
6673
/* Register moves */
6674

    
6675

    
6676
static inline void gen_evmra(DisasContext *ctx)
6677
{
6678

    
6679
    if (unlikely(!ctx->spe_enabled)) {
6680
        gen_exception(ctx, POWERPC_EXCP_SPEU);
6681
        return;
6682
    }
6683

    
6684
#if defined(TARGET_PPC64)
6685
    /* rD := rA */
6686
    tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6687

    
6688
    /* spe_acc := rA */
6689
    tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)],
6690
                   cpu_env,
6691
                   offsetof(CPUState, spe_acc));
6692
#else
6693
    TCGv_i64 tmp = tcg_temp_new_i64();
6694

    
6695
    /* tmp := rA_lo + rA_hi << 32 */
6696
    tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6697

    
6698
    /* spe_acc := tmp */
6699
    tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc));
6700
    tcg_temp_free_i64(tmp);
6701

    
6702
    /* rD := rA */
6703
    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6704
    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6705
#endif
6706
}
6707

    
6708
static inline void gen_load_gpr64(TCGv_i64 t, int reg)
6709
{
6710
#if defined(TARGET_PPC64)
6711
    tcg_gen_mov_i64(t, cpu_gpr[reg]);
6712
#else
6713
    tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
6714
#endif
6715
}
6716

    
6717
static inline void gen_store_gpr64(int reg, TCGv_i64 t)
6718
{
6719
#if defined(TARGET_PPC64)
6720
    tcg_gen_mov_i64(cpu_gpr[reg], t);
6721
#else
6722
    TCGv_i64 tmp = tcg_temp_new_i64();
6723
    tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
6724
    tcg_gen_shri_i64(tmp, t, 32);
6725
    tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
6726
    tcg_temp_free_i64(tmp);
6727
#endif
6728
}
6729

    
6730
#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type)         \
6731
static void glue(gen_, name0##_##name1)(DisasContext *ctx)                    \
6732
{                                                                             \
6733
    if (Rc(ctx->opcode))                                                      \
6734
        gen_##name1(ctx);                                                     \
6735
    else                                                                      \
6736
        gen_##name0(ctx);                                                     \
6737
}
6738

    
6739
/* Handler for undefined SPE opcodes */
6740
static inline void gen_speundef(DisasContext *ctx)
6741
{
6742
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6743
}
6744

    
6745
/* SPE logic */
6746
#if defined(TARGET_PPC64)
6747
#define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6748
static inline void gen_##name(DisasContext *ctx)                              \
6749
{                                                                             \
6750
    if (unlikely(!ctx->spe_enabled)) {                                        \
6751
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
6752
        return;                                                               \
6753
    }                                                                         \
6754
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6755
           cpu_gpr[rB(ctx->opcode)]);                                         \
6756
}
6757
#else
6758
#define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6759
static inline void gen_##name(DisasContext *ctx)                              \
6760
{                                                                             \
6761
    if (unlikely(!ctx->spe_enabled)) {                                        \
6762
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
6763
        return;                                                               \
6764
    }                                                                         \
6765
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6766
           cpu_gpr[rB(ctx->opcode)]);                                         \
6767
    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6768
           cpu_gprh[rB(ctx->opcode)]);                                        \
6769
}
6770
#endif
6771

    
6772
GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
6773
GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
6774
GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
6775
GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
6776
GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
6777
GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
6778
GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
6779
GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
6780

    
6781
/* SPE logic immediate */
6782
#if defined(TARGET_PPC64)
6783
#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6784
static inline void gen_##name(DisasContext *ctx)                              \
6785
{                                                                             \
6786
    if (unlikely(!ctx->spe_enabled)) {                                        \
6787
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
6788
        return;                                                               \
6789
    }                                                                         \
6790
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6791
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6792
    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6793
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6794
    tcg_opi(t0, t0, rB(ctx->opcode));                                         \
6795
    tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6796
    tcg_gen_trunc_i64_i32(t1, t2);                                            \
6797
    tcg_temp_free_i64(t2);                                                    \
6798
    tcg_opi(t1, t1, rB(ctx->opcode));                                         \
6799
    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6800
    tcg_temp_free_i32(t0);                                                    \
6801
    tcg_temp_free_i32(t1);                                                    \
6802
}
6803
#else
6804
#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6805
static inline void gen_##name(DisasContext *ctx)                              \
6806
{                                                                             \
6807
    if (unlikely(!ctx->spe_enabled)) {                                        \
6808
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
6809
        return;                                                               \
6810
    }                                                                         \
6811
    tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
6812
            rB(ctx->opcode));                                                 \
6813
    tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
6814
            rB(ctx->opcode));                                                 \
6815
}
6816
#endif
6817
GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
6818
GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
6819
GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
6820
GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
6821

    
6822
/* SPE arithmetic */
6823
#if defined(TARGET_PPC64)
6824
#define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6825
static inline void gen_##name(DisasContext *ctx)                              \
6826
{                                                                             \
6827
    if (unlikely(!ctx->spe_enabled)) {                                        \
6828
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
6829
        return;                                                               \
6830
    }                                                                         \
6831
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6832
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6833
    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6834
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6835
    tcg_op(t0, t0);                                                           \
6836
    tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6837
    tcg_gen_trunc_i64_i32(t1, t2);                                            \
6838
    tcg_temp_free_i64(t2);                                                    \
6839
    tcg_op(t1, t1);                                                           \
6840
    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6841
    tcg_temp_free_i32(t0);                                                    \
6842
    tcg_temp_free_i32(t1);                                                    \
6843
}
6844
#else
6845
#define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6846
static inline void gen_##name(DisasContext *ctx)                              \
6847
{                                                                             \
6848
    if (unlikely(!ctx->spe_enabled)) {                                        \
6849
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
6850
        return;                                                               \
6851
    }                                                                         \
6852
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
6853
    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
6854
}
6855
#endif
6856

    
6857
static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
6858
{
6859
    int l1 = gen_new_label();
6860
    int l2 = gen_new_label();
6861

    
6862
    tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
6863
    tcg_gen_neg_i32(ret, arg1);
6864
    tcg_gen_br(l2);
6865
    gen_set_label(l1);
6866
    tcg_gen_mov_i32(ret, arg1);
6867
    gen_set_label(l2);
6868
}
6869
GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
6870
GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
6871
GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
6872
GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
6873
static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
6874
{
6875
    tcg_gen_addi_i32(ret, arg1, 0x8000);
6876
    tcg_gen_ext16u_i32(ret, ret);
6877
}
6878
GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
6879
GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
6880
GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
6881

    
6882
#if defined(TARGET_PPC64)
6883
#define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6884
static inline void gen_##name(DisasContext *ctx)                              \
6885
{                                                                             \
6886
    if (unlikely(!ctx->spe_enabled)) {                                        \
6887
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
6888
        return;                                                               \
6889
    }                                                                         \
6890
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6891
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6892
    TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
6893
    TCGv_i64 t3 = tcg_temp_local_new_i64();                                   \
6894
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6895
    tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
6896
    tcg_op(t0, t0, t2);                                                       \
6897
    tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
6898
    tcg_gen_trunc_i64_i32(t1, t3);                                            \
6899
    tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
6900
    tcg_gen_trunc_i64_i32(t2, t3);                                            \
6901
    tcg_temp_free_i64(t3);                                                    \
6902
    tcg_op(t1, t1, t2);                                                       \
6903
    tcg_temp_free_i32(t2);                                                    \
6904
    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6905
    tcg_temp_free_i32(t0);                                                    \
6906
    tcg_temp_free_i32(t1);                                                    \
6907
}
6908
#else
6909
#define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6910
static inline void gen_##name(DisasContext *ctx)                              \
6911
{                                                                             \
6912
    if (unlikely(!ctx->spe_enabled)) {                                        \
6913
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
6914
        return;                                                               \
6915
    }                                                                         \
6916
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6917
           cpu_gpr[rB(ctx->opcode)]);                                         \
6918
    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6919
           cpu_gprh[rB(ctx->opcode)]);                                        \
6920
}
6921
#endif
6922

    
6923
static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6924
{
6925
    TCGv_i32 t0;
6926
    int l1, l2;
6927

    
6928
    l1 = gen_new_label();
6929
    l2 = gen_new_label();
6930
    t0 = tcg_temp_local_new_i32();
6931
    /* No error here: 6 bits are used */
6932
    tcg_gen_andi_i32(t0, arg2, 0x3F);
6933
    tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6934
    tcg_gen_shr_i32(ret, arg1, t0);
6935
    tcg_gen_br(l2);
6936
    gen_set_label(l1);
6937
    tcg_gen_movi_i32(ret, 0);
6938
    gen_set_label(l2);
6939
    tcg_temp_free_i32(t0);
6940
}
6941
GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
6942
static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6943
{
6944
    TCGv_i32 t0;
6945
    int l1, l2;
6946

    
6947
    l1 = gen_new_label();
6948
    l2 = gen_new_label();
6949
    t0 = tcg_temp_local_new_i32();
6950
    /* No error here: 6 bits are used */
6951
    tcg_gen_andi_i32(t0, arg2, 0x3F);
6952
    tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6953
    tcg_gen_sar_i32(ret, arg1, t0);
6954
    tcg_gen_br(l2);
6955
    gen_set_label(l1);
6956
    tcg_gen_movi_i32(ret, 0);
6957
    gen_set_label(l2);
6958
    tcg_temp_free_i32(t0);
6959
}
6960
GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
6961
static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6962
{
6963
    TCGv_i32 t0;
6964
    int l1, l2;
6965

    
6966
    l1 = gen_new_label();
6967
    l2 = gen_new_label();
6968
    t0 = tcg_temp_local_new_i32();
6969
    /* No error here: 6 bits are used */
6970
    tcg_gen_andi_i32(t0, arg2, 0x3F);
6971
    tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6972
    tcg_gen_shl_i32(ret, arg1, t0);
6973
    tcg_gen_br(l2);
6974
    gen_set_label(l1);
6975
    tcg_gen_movi_i32(ret, 0);
6976
    gen_set_label(l2);
6977
    tcg_temp_free_i32(t0);
6978
}
6979
GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
6980
static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6981
{
6982
    TCGv_i32 t0 = tcg_temp_new_i32();
6983
    tcg_gen_andi_i32(t0, arg2, 0x1F);
6984
    tcg_gen_rotl_i32(ret, arg1, t0);
6985
    tcg_temp_free_i32(t0);
6986
}
6987
GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
6988
static inline void gen_evmergehi(DisasContext *ctx)
6989
{
6990
    if (unlikely(!ctx->spe_enabled)) {
6991
        gen_exception(ctx, POWERPC_EXCP_SPEU);
6992
        return;
6993
    }
6994
#if defined(TARGET_PPC64)
6995
    TCGv t0 = tcg_temp_new();
6996
    TCGv t1 = tcg_temp_new();
6997
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
6998
    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
6999
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7000
    tcg_temp_free(t0);
7001
    tcg_temp_free(t1);
7002
#else
7003
    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7004
    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7005
#endif
7006
}
7007
GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
7008
static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7009
{
7010
    tcg_gen_sub_i32(ret, arg2, arg1);
7011
}
7012
GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
7013

    
7014
/* SPE arithmetic immediate */
7015
#if defined(TARGET_PPC64)
7016
#define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
7017
static inline void gen_##name(DisasContext *ctx)                              \
7018
{                                                                             \
7019
    if (unlikely(!ctx->spe_enabled)) {                                        \
7020
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7021
        return;                                                               \
7022
    }                                                                         \
7023
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
7024
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
7025
    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
7026
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
7027
    tcg_op(t0, t0, rA(ctx->opcode));                                          \
7028
    tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
7029
    tcg_gen_trunc_i64_i32(t1, t2);                                            \
7030
    tcg_temp_free_i64(t2);                                                    \
7031
    tcg_op(t1, t1, rA(ctx->opcode));                                          \
7032
    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
7033
    tcg_temp_free_i32(t0);                                                    \
7034
    tcg_temp_free_i32(t1);                                                    \
7035
}
7036
#else
7037
#define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
7038
static inline void gen_##name(DisasContext *ctx)                              \
7039
{                                                                             \
7040
    if (unlikely(!ctx->spe_enabled)) {                                        \
7041
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7042
        return;                                                               \
7043
    }                                                                         \
7044
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
7045
           rA(ctx->opcode));                                                  \
7046
    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
7047
           rA(ctx->opcode));                                                  \
7048
}
7049
#endif
7050
GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
7051
GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
7052

    
7053
/* SPE comparison */
7054
#if defined(TARGET_PPC64)
7055
#define GEN_SPEOP_COMP(name, tcg_cond)                                        \
7056
static inline void gen_##name(DisasContext *ctx)                              \
7057
{                                                                             \
7058
    if (unlikely(!ctx->spe_enabled)) {                                        \
7059
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7060
        return;                                                               \
7061
    }                                                                         \
7062
    int l1 = gen_new_label();                                                 \
7063
    int l2 = gen_new_label();                                                 \
7064
    int l3 = gen_new_label();                                                 \
7065
    int l4 = gen_new_label();                                                 \
7066
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
7067
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
7068
    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
7069
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
7070
    tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
7071
    tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
7072
    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
7073
    tcg_gen_br(l2);                                                           \
7074
    gen_set_label(l1);                                                        \
7075
    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
7076
                     CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
7077
    gen_set_label(l2);                                                        \
7078
    tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
7079
    tcg_gen_trunc_i64_i32(t0, t2);                                            \
7080
    tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
7081
    tcg_gen_trunc_i64_i32(t1, t2);                                            \
7082
    tcg_temp_free_i64(t2);                                                    \
7083
    tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
7084
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
7085
                     ~(CRF_CH | CRF_CH_AND_CL));                              \
7086
    tcg_gen_br(l4);                                                           \
7087
    gen_set_label(l3);                                                        \
7088
    tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
7089
                    CRF_CH | CRF_CH_OR_CL);                                   \
7090
    gen_set_label(l4);                                                        \
7091
    tcg_temp_free_i32(t0);                                                    \
7092
    tcg_temp_free_i32(t1);                                                    \
7093
}
7094
#else
7095
#define GEN_SPEOP_COMP(name, tcg_cond)                                        \
7096
static inline void gen_##name(DisasContext *ctx)                              \
7097
{                                                                             \
7098
    if (unlikely(!ctx->spe_enabled)) {                                        \
7099
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7100
        return;                                                               \
7101
    }                                                                         \
7102
    int l1 = gen_new_label();                                                 \
7103
    int l2 = gen_new_label();                                                 \
7104
    int l3 = gen_new_label();                                                 \
7105
    int l4 = gen_new_label();                                                 \
7106
                                                                              \
7107
    tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
7108
                       cpu_gpr[rB(ctx->opcode)], l1);                         \
7109
    tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
7110
    tcg_gen_br(l2);                                                           \
7111
    gen_set_label(l1);                                                        \
7112
    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
7113
                     CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
7114
    gen_set_label(l2);                                                        \
7115
    tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
7116
                       cpu_gprh[rB(ctx->opcode)], l3);                        \
7117
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
7118
                     ~(CRF_CH | CRF_CH_AND_CL));                              \
7119
    tcg_gen_br(l4);                                                           \
7120
    gen_set_label(l3);                                                        \
7121
    tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
7122
                    CRF_CH | CRF_CH_OR_CL);                                   \
7123
    gen_set_label(l4);                                                        \
7124
}
7125
#endif
7126
GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
7127
GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
7128
GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
7129
GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
7130
GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
7131

    
7132
/* SPE misc */
7133
static inline void gen_brinc(DisasContext *ctx)
7134
{
7135
    /* Note: brinc is usable even if SPE is disabled */
7136
    gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
7137
                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7138
}
7139
static inline void gen_evmergelo(DisasContext *ctx)
7140
{
7141
    if (unlikely(!ctx->spe_enabled)) {
7142
        gen_exception(ctx, POWERPC_EXCP_SPEU);
7143
        return;
7144
    }
7145
#if defined(TARGET_PPC64)
7146
    TCGv t0 = tcg_temp_new();
7147
    TCGv t1 = tcg_temp_new();
7148
    tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
7149
    tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
7150
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7151
    tcg_temp_free(t0);
7152
    tcg_temp_free(t1);
7153
#else
7154
    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7155
    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7156
#endif
7157
}
7158
static inline void gen_evmergehilo(DisasContext *ctx)
7159
{
7160
    if (unlikely(!ctx->spe_enabled)) {
7161
        gen_exception(ctx, POWERPC_EXCP_SPEU);
7162
        return;
7163
    }
7164
#if defined(TARGET_PPC64)
7165
    TCGv t0 = tcg_temp_new();
7166
    TCGv t1 = tcg_temp_new();
7167
    tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
7168
    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
7169
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7170
    tcg_temp_free(t0);
7171
    tcg_temp_free(t1);
7172
#else
7173
    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7174
    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7175
#endif
7176
}
7177
static inline void gen_evmergelohi(DisasContext *ctx)
7178
{
7179
    if (unlikely(!ctx->spe_enabled)) {
7180
        gen_exception(ctx, POWERPC_EXCP_SPEU);
7181
        return;
7182
    }
7183
#if defined(TARGET_PPC64)
7184
    TCGv t0 = tcg_temp_new();
7185
    TCGv t1 = tcg_temp_new();
7186
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
7187
    tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
7188
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7189
    tcg_temp_free(t0);
7190
    tcg_temp_free(t1);
7191
#else
7192
    if (rD(ctx->opcode) == rA(ctx->opcode)) {
7193
        TCGv_i32 tmp = tcg_temp_new_i32();
7194
        tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);
7195
        tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7196
        tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);
7197
        tcg_temp_free_i32(tmp);
7198
    } else {
7199
        tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7200
        tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7201
    }
7202
#endif
7203
}
7204
static inline void gen_evsplati(DisasContext *ctx)
7205
{
7206
    uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
7207

    
7208
#if defined(TARGET_PPC64)
7209
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
7210
#else
7211
    tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
7212
    tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
7213
#endif
7214
}
7215
static inline void gen_evsplatfi(DisasContext *ctx)
7216
{
7217
    uint64_t imm = rA(ctx->opcode) << 27;
7218

    
7219
#if defined(TARGET_PPC64)
7220
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
7221
#else
7222
    tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
7223
    tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
7224
#endif
7225
}
7226

    
7227
static inline void gen_evsel(DisasContext *ctx)
7228
{
7229
    int l1 = gen_new_label();
7230
    int l2 = gen_new_label();
7231
    int l3 = gen_new_label();
7232
    int l4 = gen_new_label();
7233
    TCGv_i32 t0 = tcg_temp_local_new_i32();
7234
#if defined(TARGET_PPC64)
7235
    TCGv t1 = tcg_temp_local_new();
7236
    TCGv t2 = tcg_temp_local_new();
7237
#endif
7238
    tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
7239
    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
7240
#if defined(TARGET_PPC64)
7241
    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
7242
#else
7243
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7244
#endif
7245
    tcg_gen_br(l2);
7246
    gen_set_label(l1);
7247
#if defined(TARGET_PPC64)
7248
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
7249
#else
7250
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7251
#endif
7252
    gen_set_label(l2);
7253
    tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
7254
    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
7255
#if defined(TARGET_PPC64)
7256
    tcg_gen_ext32u_tl(t2, cpu_gpr[rA(ctx->opcode)]);
7257
#else
7258
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7259
#endif
7260
    tcg_gen_br(l4);
7261
    gen_set_label(l3);
7262
#if defined(TARGET_PPC64)
7263
    tcg_gen_ext32u_tl(t2, cpu_gpr[rB(ctx->opcode)]);
7264
#else
7265
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7266
#endif
7267
    gen_set_label(l4);
7268
    tcg_temp_free_i32(t0);
7269
#if defined(TARGET_PPC64)
7270
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
7271
    tcg_temp_free(t1);
7272
    tcg_temp_free(t2);
7273
#endif
7274
}
7275

    
7276
static void gen_evsel0(DisasContext *ctx)
7277
{
7278
    gen_evsel(ctx);
7279
}
7280

    
7281
static void gen_evsel1(DisasContext *ctx)
7282
{
7283
    gen_evsel(ctx);
7284
}
7285

    
7286
static void gen_evsel2(DisasContext *ctx)
7287
{
7288
    gen_evsel(ctx);
7289
}
7290

    
7291
static void gen_evsel3(DisasContext *ctx)
7292
{
7293
    gen_evsel(ctx);
7294
}
7295

    
7296
/* Multiply */
7297

    
7298
static inline void gen_evmwumi(DisasContext *ctx)
7299
{
7300
    TCGv_i64 t0, t1;
7301

    
7302
    if (unlikely(!ctx->spe_enabled)) {
7303
        gen_exception(ctx, POWERPC_EXCP_SPEU);
7304
        return;
7305
    }
7306

    
7307
    t0 = tcg_temp_new_i64();
7308
    t1 = tcg_temp_new_i64();
7309

    
7310
    /* t0 := rA; t1 := rB */
7311
#if defined(TARGET_PPC64)
7312
    tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]);
7313
    tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]);
7314
#else
7315
    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
7316
    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
7317
#endif
7318

    
7319
    tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
7320

    
7321
    gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
7322

    
7323
    tcg_temp_free_i64(t0);
7324
    tcg_temp_free_i64(t1);
7325
}
7326

    
7327
static inline void gen_evmwumia(DisasContext *ctx)
7328
{
7329
    TCGv_i64 tmp;
7330

    
7331
    if (unlikely(!ctx->spe_enabled)) {
7332
        gen_exception(ctx, POWERPC_EXCP_SPEU);
7333
        return;
7334
    }
7335

    
7336
    gen_evmwumi(ctx);            /* rD := rA * rB */
7337

    
7338
    tmp = tcg_temp_new_i64();
7339

    
7340
    /* acc := rD */
7341
    gen_load_gpr64(tmp, rD(ctx->opcode));
7342
    tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc));
7343
    tcg_temp_free_i64(tmp);
7344
}
7345

    
7346
static inline void gen_evmwumiaa(DisasContext *ctx)
7347
{
7348
    TCGv_i64 acc;
7349
    TCGv_i64 tmp;
7350

    
7351
    if (unlikely(!ctx->spe_enabled)) {
7352
        gen_exception(ctx, POWERPC_EXCP_SPEU);
7353
        return;
7354
    }
7355

    
7356
    gen_evmwumi(ctx);           /* rD := rA * rB */
7357

    
7358
    acc = tcg_temp_new_i64();
7359
    tmp = tcg_temp_new_i64();
7360

    
7361
    /* tmp := rD */
7362
    gen_load_gpr64(tmp, rD(ctx->opcode));
7363

    
7364
    /* Load acc */
7365
    tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
7366

    
7367
    /* acc := tmp + acc */
7368
    tcg_gen_add_i64(acc, acc, tmp);
7369

    
7370
    /* Store acc */
7371
    tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
7372

    
7373
    /* rD := acc */
7374
    gen_store_gpr64(rD(ctx->opcode), acc);
7375

    
7376
    tcg_temp_free_i64(acc);
7377
    tcg_temp_free_i64(tmp);
7378
}
7379

    
7380
static inline void gen_evmwsmi(DisasContext *ctx)
7381
{
7382
    TCGv_i64 t0, t1;
7383

    
7384
    if (unlikely(!ctx->spe_enabled)) {
7385
        gen_exception(ctx, POWERPC_EXCP_SPEU);
7386
        return;
7387
    }
7388

    
7389
    t0 = tcg_temp_new_i64();
7390
    t1 = tcg_temp_new_i64();
7391

    
7392
    /* t0 := rA; t1 := rB */
7393
#if defined(TARGET_PPC64)
7394
    tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
7395
    tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
7396
#else
7397
    tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
7398
    tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
7399
#endif
7400

    
7401
    tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
7402

    
7403
    gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
7404

    
7405
    tcg_temp_free_i64(t0);
7406
    tcg_temp_free_i64(t1);
7407
}
7408

    
7409
static inline void gen_evmwsmia(DisasContext *ctx)
7410
{
7411
    TCGv_i64 tmp;
7412

    
7413
    gen_evmwsmi(ctx);            /* rD := rA * rB */
7414

    
7415
    tmp = tcg_temp_new_i64();
7416

    
7417
    /* acc := rD */
7418
    gen_load_gpr64(tmp, rD(ctx->opcode));
7419
    tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc));
7420

    
7421
    tcg_temp_free_i64(tmp);
7422
}
7423

    
7424
static inline void gen_evmwsmiaa(DisasContext *ctx)
7425
{
7426
    TCGv_i64 acc = tcg_temp_new_i64();
7427
    TCGv_i64 tmp = tcg_temp_new_i64();
7428

    
7429
    gen_evmwsmi(ctx);           /* rD := rA * rB */
7430

    
7431
    acc = tcg_temp_new_i64();
7432
    tmp = tcg_temp_new_i64();
7433

    
7434
    /* tmp := rD */
7435
    gen_load_gpr64(tmp, rD(ctx->opcode));
7436

    
7437
    /* Load acc */
7438
    tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
7439

    
7440
    /* acc := tmp + acc */
7441
    tcg_gen_add_i64(acc, acc, tmp);
7442

    
7443
    /* Store acc */
7444
    tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
7445

    
7446
    /* rD := acc */
7447
    gen_store_gpr64(rD(ctx->opcode), acc);
7448

    
7449
    tcg_temp_free_i64(acc);
7450
    tcg_temp_free_i64(tmp);
7451
}
7452

    
7453
GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7454
GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7455
GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7456
GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7457
GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
7458
GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
7459
GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
7460
GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE); //
7461
GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE);
7462
GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
7463
GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7464
GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7465
GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7466
GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
7467
GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
7468
GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE);
7469
GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
7470
GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7471
GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7472
GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE);
7473
GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7474
GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7475
GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE); //
7476
GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE);
7477
GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7478
GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7479
GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
7480
GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
7481
GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE); ////
7482

    
7483
/* SPE load and stores */
7484
static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
7485
{
7486
    target_ulong uimm = rB(ctx->opcode);
7487

    
7488
    if (rA(ctx->opcode) == 0) {
7489
        tcg_gen_movi_tl(EA, uimm << sh);
7490
    } else {
7491
        tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
7492
#if defined(TARGET_PPC64)
7493
        if (!ctx->sf_mode) {
7494
            tcg_gen_ext32u_tl(EA, EA);
7495
        }
7496
#endif
7497
    }
7498
}
7499

    
7500
static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
7501
{
7502
#if defined(TARGET_PPC64)
7503
    gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7504
#else
7505
    TCGv_i64 t0 = tcg_temp_new_i64();
7506
    gen_qemu_ld64(ctx, t0, addr);
7507
    tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
7508
    tcg_gen_shri_i64(t0, t0, 32);
7509
    tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
7510
    tcg_temp_free_i64(t0);
7511
#endif
7512
}
7513

    
7514
static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
7515
{
7516
#if defined(TARGET_PPC64)
7517
    TCGv t0 = tcg_temp_new();
7518
    gen_qemu_ld32u(ctx, t0, addr);
7519
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7520
    gen_addr_add(ctx, addr, addr, 4);
7521
    gen_qemu_ld32u(ctx, t0, addr);
7522
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7523
    tcg_temp_free(t0);
7524
#else
7525
    gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7526
    gen_addr_add(ctx, addr, addr, 4);
7527
    gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7528
#endif
7529
}
7530

    
7531
static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
7532
{
7533
    TCGv t0 = tcg_temp_new();
7534
#if defined(TARGET_PPC64)
7535
    gen_qemu_ld16u(ctx, t0, addr);
7536
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7537
    gen_addr_add(ctx, addr, addr, 2);
7538
    gen_qemu_ld16u(ctx, t0, addr);
7539
    tcg_gen_shli_tl(t0, t0, 32);
7540
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7541
    gen_addr_add(ctx, addr, addr, 2);
7542
    gen_qemu_ld16u(ctx, t0, addr);
7543
    tcg_gen_shli_tl(t0, t0, 16);
7544
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7545
    gen_addr_add(ctx, addr, addr, 2);
7546
    gen_qemu_ld16u(ctx, t0, addr);
7547
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7548
#else
7549
    gen_qemu_ld16u(ctx, t0, addr);
7550
    tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7551
    gen_addr_add(ctx, addr, addr, 2);
7552
    gen_qemu_ld16u(ctx, t0, addr);
7553
    tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7554
    gen_addr_add(ctx, addr, addr, 2);
7555
    gen_qemu_ld16u(ctx, t0, addr);
7556
    tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7557
    gen_addr_add(ctx, addr, addr, 2);
7558
    gen_qemu_ld16u(ctx, t0, addr);
7559
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7560
#endif
7561
    tcg_temp_free(t0);
7562
}
7563

    
7564
static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
7565
{
7566
    TCGv t0 = tcg_temp_new();
7567
    gen_qemu_ld16u(ctx, t0, addr);
7568
#if defined(TARGET_PPC64)
7569
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7570
    tcg_gen_shli_tl(t0, t0, 16);
7571
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7572
#else
7573
    tcg_gen_shli_tl(t0, t0, 16);
7574
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7575
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7576
#endif
7577
    tcg_temp_free(t0);
7578
}
7579

    
7580
static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
7581
{
7582
    TCGv t0 = tcg_temp_new();
7583
    gen_qemu_ld16u(ctx, t0, addr);
7584
#if defined(TARGET_PPC64)
7585
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7586
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7587
#else
7588
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7589
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7590
#endif
7591
    tcg_temp_free(t0);
7592
}
7593

    
7594
static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
7595
{
7596
    TCGv t0 = tcg_temp_new();
7597
    gen_qemu_ld16s(ctx, t0, addr);
7598
#if defined(TARGET_PPC64)
7599
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7600
    tcg_gen_ext32u_tl(t0, t0);
7601
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7602
#else
7603
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7604
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7605
#endif
7606
    tcg_temp_free(t0);
7607
}
7608

    
7609
static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
7610
{
7611
    TCGv t0 = tcg_temp_new();
7612
#if defined(TARGET_PPC64)
7613
    gen_qemu_ld16u(ctx, t0, addr);
7614
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7615
    gen_addr_add(ctx, addr, addr, 2);
7616
    gen_qemu_ld16u(ctx, t0, addr);
7617
    tcg_gen_shli_tl(t0, t0, 16);
7618
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7619
#else
7620
    gen_qemu_ld16u(ctx, t0, addr);
7621
    tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7622
    gen_addr_add(ctx, addr, addr, 2);
7623
    gen_qemu_ld16u(ctx, t0, addr);
7624
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
7625
#endif
7626
    tcg_temp_free(t0);
7627
}
7628

    
7629
static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
7630
{
7631
#if defined(TARGET_PPC64)
7632
    TCGv t0 = tcg_temp_new();
7633
    gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7634
    gen_addr_add(ctx, addr, addr, 2);
7635
    gen_qemu_ld16u(ctx, t0, addr);
7636
    tcg_gen_shli_tl(t0, t0, 32);
7637
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7638
    tcg_temp_free(t0);
7639
#else
7640
    gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7641
    gen_addr_add(ctx, addr, addr, 2);
7642
    gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7643
#endif
7644
}
7645

    
7646
static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
7647
{
7648
#if defined(TARGET_PPC64)
7649
    TCGv t0 = tcg_temp_new();
7650
    gen_qemu_ld16s(ctx, t0, addr);
7651
    tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
7652
    gen_addr_add(ctx, addr, addr, 2);
7653
    gen_qemu_ld16s(ctx, t0, addr);
7654
    tcg_gen_shli_tl(t0, t0, 32);
7655
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7656
    tcg_temp_free(t0);
7657
#else
7658
    gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7659
    gen_addr_add(ctx, addr, addr, 2);
7660
    gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7661
#endif
7662
}
7663

    
7664
static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
7665
{
7666
    TCGv t0 = tcg_temp_new();
7667
    gen_qemu_ld32u(ctx, t0, addr);
7668
#if defined(TARGET_PPC64)
7669
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7670
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7671
#else
7672
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7673
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7674
#endif
7675
    tcg_temp_free(t0);
7676
}
7677

    
7678
static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
7679
{
7680
    TCGv t0 = tcg_temp_new();
7681
#if defined(TARGET_PPC64)
7682
    gen_qemu_ld16u(ctx, t0, addr);
7683
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7684
    tcg_gen_shli_tl(t0, t0, 32);
7685
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7686
    gen_addr_add(ctx, addr, addr, 2);
7687
    gen_qemu_ld16u(ctx, t0, addr);
7688
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7689
    tcg_gen_shli_tl(t0, t0, 16);
7690
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7691
#else
7692
    gen_qemu_ld16u(ctx, t0, addr);
7693
    tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7694
    tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7695
    gen_addr_add(ctx, addr, addr, 2);
7696
    gen_qemu_ld16u(ctx, t0, addr);
7697
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
7698
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7699
#endif
7700
    tcg_temp_free(t0);
7701
}
7702

    
7703
static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
7704
{
7705
#if defined(TARGET_PPC64)
7706
    gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7707
#else
7708
    TCGv_i64 t0 = tcg_temp_new_i64();
7709
    tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
7710
    gen_qemu_st64(ctx, t0, addr);
7711
    tcg_temp_free_i64(t0);
7712
#endif
7713
}
7714

    
7715
static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
7716
{
7717
#if defined(TARGET_PPC64)
7718
    TCGv t0 = tcg_temp_new();
7719
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7720
    gen_qemu_st32(ctx, t0, addr);
7721
    tcg_temp_free(t0);
7722
#else
7723
    gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7724
#endif
7725
    gen_addr_add(ctx, addr, addr, 4);
7726
    gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7727
}
7728

    
7729
static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
7730
{
7731
    TCGv t0 = tcg_temp_new();
7732
#if defined(TARGET_PPC64)
7733
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
7734
#else
7735
    tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
7736
#endif
7737
    gen_qemu_st16(ctx, t0, addr);
7738
    gen_addr_add(ctx, addr, addr, 2);
7739
#if defined(TARGET_PPC64)
7740
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7741
    gen_qemu_st16(ctx, t0, addr);
7742
#else
7743
    gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7744
#endif
7745
    gen_addr_add(ctx, addr, addr, 2);
7746
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
7747
    gen_qemu_st16(ctx, t0, addr);
7748
    tcg_temp_free(t0);
7749
    gen_addr_add(ctx, addr, addr, 2);
7750
    gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7751
}
7752

    
7753
static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
7754
{
7755
    TCGv t0 = tcg_temp_new();
7756
#if defined(TARGET_PPC64)
7757
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
7758
#else
7759
    tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
7760
#endif
7761
    gen_qemu_st16(ctx, t0, addr);
7762
    gen_addr_add(ctx, addr, addr, 2);
7763
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
7764
    gen_qemu_st16(ctx, t0, addr);
7765
    tcg_temp_free(t0);
7766
}
7767

    
7768
static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
7769
{
7770
#if defined(TARGET_PPC64)
7771
    TCGv t0 = tcg_temp_new();
7772
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7773
    gen_qemu_st16(ctx, t0, addr);
7774
    tcg_temp_free(t0);
7775
#else
7776
    gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7777
#endif
7778
    gen_addr_add(ctx, addr, addr, 2);
7779
    gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7780
}
7781

    
7782
static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
7783
{
7784
#if defined(TARGET_PPC64)
7785
    TCGv t0 = tcg_temp_new();
7786
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7787
    gen_qemu_st32(ctx, t0, addr);
7788
    tcg_temp_free(t0);
7789
#else
7790
    gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7791
#endif
7792
}
7793

    
7794
static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
7795
{
7796
    gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7797
}
7798

    
7799
#define GEN_SPEOP_LDST(name, opc2, sh)                                        \
7800
static void glue(gen_, name)(DisasContext *ctx)                                       \
7801
{                                                                             \
7802
    TCGv t0;                                                                  \
7803
    if (unlikely(!ctx->spe_enabled)) {                                        \
7804
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7805
        return;                                                               \
7806
    }                                                                         \
7807
    gen_set_access_type(ctx, ACCESS_INT);                                     \
7808
    t0 = tcg_temp_new();                                                      \
7809
    if (Rc(ctx->opcode)) {                                                    \
7810
        gen_addr_spe_imm_index(ctx, t0, sh);                                  \
7811
    } else {                                                                  \
7812
        gen_addr_reg_index(ctx, t0);                                          \
7813
    }                                                                         \
7814
    gen_op_##name(ctx, t0);                                                   \
7815
    tcg_temp_free(t0);                                                        \
7816
}
7817

    
7818
GEN_SPEOP_LDST(evldd, 0x00, 3);
7819
GEN_SPEOP_LDST(evldw, 0x01, 3);
7820
GEN_SPEOP_LDST(evldh, 0x02, 3);
7821
GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
7822
GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
7823
GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
7824
GEN_SPEOP_LDST(evlwhe, 0x08, 2);
7825
GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
7826
GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
7827
GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
7828
GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
7829

    
7830
GEN_SPEOP_LDST(evstdd, 0x10, 3);
7831
GEN_SPEOP_LDST(evstdw, 0x11, 3);
7832
GEN_SPEOP_LDST(evstdh, 0x12, 3);
7833
GEN_SPEOP_LDST(evstwhe, 0x18, 2);
7834
GEN_SPEOP_LDST(evstwho, 0x1A, 2);
7835
GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
7836
GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
7837

    
7838
/* Multiply and add - TODO */
7839
#if 0
7840
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);//
7841
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7842
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE);
7843
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7844
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE);
7845
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7846
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7847
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7848
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE);
7849
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7850
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE);
7851
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7852

7853
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7854
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7855
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE);
7856
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7857
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7858
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7859
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7860
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7861
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE);
7862
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7863
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7864
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7865

7866
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
7867
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
7868
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
7869
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
7870
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE);
7871

7872
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7873
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7874
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7875
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7876
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7877
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7878
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7879
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7880
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7881
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7882
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7883
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7884

7885
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE);
7886
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE);
7887
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7888
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7889

7890
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7891
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7892
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7893
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7894
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7895
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7896
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7897
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7898
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7899
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7900
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7901
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7902

7903
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE);
7904
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE);
7905
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7906
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE);
7907
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7908
#endif
7909

    
7910
/***                      SPE floating-point extension                     ***/
7911
#if defined(TARGET_PPC64)
7912
#define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7913
static inline void gen_##name(DisasContext *ctx)                              \
7914
{                                                                             \
7915
    TCGv_i32 t0;                                                              \
7916
    TCGv t1;                                                                  \
7917
    t0 = tcg_temp_new_i32();                                                  \
7918
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7919
    gen_helper_##name(t0, t0);                                                \
7920
    t1 = tcg_temp_new();                                                      \
7921
    tcg_gen_extu_i32_tl(t1, t0);                                              \
7922
    tcg_temp_free_i32(t0);                                                    \
7923
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7924
                    0xFFFFFFFF00000000ULL);                                   \
7925
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7926
    tcg_temp_free(t1);                                                        \
7927
}
7928
#define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7929
static inline void gen_##name(DisasContext *ctx)                              \
7930
{                                                                             \
7931
    TCGv_i32 t0;                                                              \
7932
    TCGv t1;                                                                  \
7933
    t0 = tcg_temp_new_i32();                                                  \
7934
    gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7935
    t1 = tcg_temp_new();                                                      \
7936
    tcg_gen_extu_i32_tl(t1, t0);                                              \
7937
    tcg_temp_free_i32(t0);                                                    \
7938
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7939
                    0xFFFFFFFF00000000ULL);                                   \
7940
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7941
    tcg_temp_free(t1);                                                        \
7942
}
7943
#define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7944
static inline void gen_##name(DisasContext *ctx)                              \
7945
{                                                                             \
7946
    TCGv_i32 t0 = tcg_temp_new_i32();                                         \
7947
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7948
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7949
    tcg_temp_free_i32(t0);                                                    \
7950
}
7951
#define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7952
static inline void gen_##name(DisasContext *ctx)                              \
7953
{                                                                             \
7954
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7955
}
7956
#define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7957
static inline void gen_##name(DisasContext *ctx)                              \
7958
{                                                                             \
7959
    TCGv_i32 t0, t1;                                                          \
7960
    TCGv_i64 t2;                                                              \
7961
    if (unlikely(!ctx->spe_enabled)) {                                        \
7962
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7963
        return;                                                               \
7964
    }                                                                         \
7965
    t0 = tcg_temp_new_i32();                                                  \
7966
    t1 = tcg_temp_new_i32();                                                  \
7967
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7968
    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7969
    gen_helper_##name(t0, t0, t1);                                            \
7970
    tcg_temp_free_i32(t1);                                                    \
7971
    t2 = tcg_temp_new();                                                      \
7972
    tcg_gen_extu_i32_tl(t2, t0);                                              \
7973
    tcg_temp_free_i32(t0);                                                    \
7974
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7975
                    0xFFFFFFFF00000000ULL);                                   \
7976
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
7977
    tcg_temp_free(t2);                                                        \
7978
}
7979
#define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7980
static inline void gen_##name(DisasContext *ctx)                              \
7981
{                                                                             \
7982
    if (unlikely(!ctx->spe_enabled)) {                                        \
7983
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7984
        return;                                                               \
7985
    }                                                                         \
7986
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
7987
                      cpu_gpr[rB(ctx->opcode)]);                              \
7988
}
7989
#define GEN_SPEFPUOP_COMP_32(name)                                            \
7990
static inline void gen_##name(DisasContext *ctx)                              \
7991
{                                                                             \
7992
    TCGv_i32 t0, t1;                                                          \
7993
    if (unlikely(!ctx->spe_enabled)) {                                        \
7994
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7995
        return;                                                               \
7996
    }                                                                         \
7997
    t0 = tcg_temp_new_i32();                                                  \
7998
    t1 = tcg_temp_new_i32();                                                  \
7999
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8000
    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
8001
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
8002
    tcg_temp_free_i32(t0);                                                    \
8003
    tcg_temp_free_i32(t1);                                                    \
8004
}
8005
#define GEN_SPEFPUOP_COMP_64(name)                                            \
8006
static inline void gen_##name(DisasContext *ctx)                              \
8007
{                                                                             \
8008
    if (unlikely(!ctx->spe_enabled)) {                                        \
8009
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8010
        return;                                                               \
8011
    }                                                                         \
8012
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
8013
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8014
}
8015
#else
8016
#define GEN_SPEFPUOP_CONV_32_32(name)                                         \
8017
static inline void gen_##name(DisasContext *ctx)                              \
8018
{                                                                             \
8019
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8020
}
8021
#define GEN_SPEFPUOP_CONV_32_64(name)                                         \
8022
static inline void gen_##name(DisasContext *ctx)                              \
8023
{                                                                             \
8024
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
8025
    gen_load_gpr64(t0, rB(ctx->opcode));                                      \
8026
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
8027
    tcg_temp_free_i64(t0);                                                    \
8028
}
8029
#define GEN_SPEFPUOP_CONV_64_32(name)                                         \
8030
static inline void gen_##name(DisasContext *ctx)                              \
8031
{                                                                             \
8032
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
8033
    gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
8034
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
8035
    tcg_temp_free_i64(t0);                                                    \
8036
}
8037
#define GEN_SPEFPUOP_CONV_64_64(name)                                         \
8038
static inline void gen_##name(DisasContext *ctx)                              \
8039
{                                                                             \
8040
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
8041
    gen_load_gpr64(t0, rB(ctx->opcode));                                      \
8042
    gen_helper_##name(t0, t0);                                                \
8043
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
8044
    tcg_temp_free_i64(t0);                                                    \
8045
}
8046
#define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
8047
static inline void gen_##name(DisasContext *ctx)                              \
8048
{                                                                             \
8049
    if (unlikely(!ctx->spe_enabled)) {                                        \
8050
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8051
        return;                                                               \
8052
    }                                                                         \
8053
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
8054
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8055
}
8056
#define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
8057
static inline void gen_##name(DisasContext *ctx)                              \
8058
{                                                                             \
8059
    TCGv_i64 t0, t1;                                                          \
8060
    if (unlikely(!ctx->spe_enabled)) {                                        \
8061
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8062
        return;                                                               \
8063
    }                                                                         \
8064
    t0 = tcg_temp_new_i64();                                                  \
8065
    t1 = tcg_temp_new_i64();                                                  \
8066
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
8067
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
8068
    gen_helper_##name(t0, t0, t1);                                            \
8069
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
8070
    tcg_temp_free_i64(t0);                                                    \
8071
    tcg_temp_free_i64(t1);                                                    \
8072
}
8073
#define GEN_SPEFPUOP_COMP_32(name)                                            \
8074
static inline void gen_##name(DisasContext *ctx)                              \
8075
{                                                                             \
8076
    if (unlikely(!ctx->spe_enabled)) {                                        \
8077
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8078
        return;                                                               \
8079
    }                                                                         \
8080
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
8081
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8082
}
8083
#define GEN_SPEFPUOP_COMP_64(name)                                            \
8084
static inline void gen_##name(DisasContext *ctx)                              \
8085
{                                                                             \
8086
    TCGv_i64 t0, t1;                                                          \
8087
    if (unlikely(!ctx->spe_enabled)) {                                        \
8088
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8089
        return;                                                               \
8090
    }                                                                         \
8091
    t0 = tcg_temp_new_i64();                                                  \
8092
    t1 = tcg_temp_new_i64();                                                  \
8093
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
8094
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
8095
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
8096
    tcg_temp_free_i64(t0);                                                    \
8097
    tcg_temp_free_i64(t1);                                                    \
8098
}
8099
#endif
8100

    
8101
/* Single precision floating-point vectors operations */
8102
/* Arithmetic */
8103
GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
8104
GEN_SPEFPUOP_ARITH2_64_64(evfssub);
8105
GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
8106
GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
8107
static inline void gen_evfsabs(DisasContext *ctx)
8108
{
8109
    if (unlikely(!ctx->spe_enabled)) {
8110
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8111
        return;
8112
    }
8113
#if defined(TARGET_PPC64)
8114
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
8115
#else
8116
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
8117
    tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
8118
#endif
8119
}
8120
static inline void gen_evfsnabs(DisasContext *ctx)
8121
{
8122
    if (unlikely(!ctx->spe_enabled)) {
8123
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8124
        return;
8125
    }
8126
#if defined(TARGET_PPC64)
8127
    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
8128
#else
8129
    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8130
    tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8131
#endif
8132
}
8133
static inline void gen_evfsneg(DisasContext *ctx)
8134
{
8135
    if (unlikely(!ctx->spe_enabled)) {
8136
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8137
        return;
8138
    }
8139
#if defined(TARGET_PPC64)
8140
    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
8141
#else
8142
    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8143
    tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8144
#endif
8145
}
8146

    
8147
/* Conversion */
8148
GEN_SPEFPUOP_CONV_64_64(evfscfui);
8149
GEN_SPEFPUOP_CONV_64_64(evfscfsi);
8150
GEN_SPEFPUOP_CONV_64_64(evfscfuf);
8151
GEN_SPEFPUOP_CONV_64_64(evfscfsf);
8152
GEN_SPEFPUOP_CONV_64_64(evfsctui);
8153
GEN_SPEFPUOP_CONV_64_64(evfsctsi);
8154
GEN_SPEFPUOP_CONV_64_64(evfsctuf);
8155
GEN_SPEFPUOP_CONV_64_64(evfsctsf);
8156
GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
8157
GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
8158

    
8159
/* Comparison */
8160
GEN_SPEFPUOP_COMP_64(evfscmpgt);
8161
GEN_SPEFPUOP_COMP_64(evfscmplt);
8162
GEN_SPEFPUOP_COMP_64(evfscmpeq);
8163
GEN_SPEFPUOP_COMP_64(evfststgt);
8164
GEN_SPEFPUOP_COMP_64(evfststlt);
8165
GEN_SPEFPUOP_COMP_64(evfststeq);
8166

    
8167
/* Opcodes definitions */
8168
GEN_SPE(evfsadd,   evfssub,   0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8169
GEN_SPE(evfsabs,   evfsnabs,  0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
8170
GEN_SPE(evfsneg,   speundef,  0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8171
GEN_SPE(evfsmul,   evfsdiv,   0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8172
GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8173
GEN_SPE(evfscmpeq, speundef,  0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8174
GEN_SPE(evfscfui,  evfscfsi,  0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8175
GEN_SPE(evfscfuf,  evfscfsf,  0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8176
GEN_SPE(evfsctui,  evfsctsi,  0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8177
GEN_SPE(evfsctuf,  evfsctsf,  0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8178
GEN_SPE(evfsctuiz, speundef,  0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8179
GEN_SPE(evfsctsiz, speundef,  0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8180
GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8181
GEN_SPE(evfststeq, speundef,  0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8182

    
8183
/* Single precision floating-point operations */
8184
/* Arithmetic */
8185
GEN_SPEFPUOP_ARITH2_32_32(efsadd);
8186
GEN_SPEFPUOP_ARITH2_32_32(efssub);
8187
GEN_SPEFPUOP_ARITH2_32_32(efsmul);
8188
GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
8189
static inline void gen_efsabs(DisasContext *ctx)
8190
{
8191
    if (unlikely(!ctx->spe_enabled)) {
8192
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8193
        return;
8194
    }
8195
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
8196
}
8197
static inline void gen_efsnabs(DisasContext *ctx)
8198
{
8199
    if (unlikely(!ctx->spe_enabled)) {
8200
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8201
        return;
8202
    }
8203
    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8204
}
8205
static inline void gen_efsneg(DisasContext *ctx)
8206
{
8207
    if (unlikely(!ctx->spe_enabled)) {
8208
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8209
        return;
8210
    }
8211
    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8212
}
8213

    
8214
/* Conversion */
8215
GEN_SPEFPUOP_CONV_32_32(efscfui);
8216
GEN_SPEFPUOP_CONV_32_32(efscfsi);
8217
GEN_SPEFPUOP_CONV_32_32(efscfuf);
8218
GEN_SPEFPUOP_CONV_32_32(efscfsf);
8219
GEN_SPEFPUOP_CONV_32_32(efsctui);
8220
GEN_SPEFPUOP_CONV_32_32(efsctsi);
8221
GEN_SPEFPUOP_CONV_32_32(efsctuf);
8222
GEN_SPEFPUOP_CONV_32_32(efsctsf);
8223
GEN_SPEFPUOP_CONV_32_32(efsctuiz);
8224
GEN_SPEFPUOP_CONV_32_32(efsctsiz);
8225
GEN_SPEFPUOP_CONV_32_64(efscfd);
8226

    
8227
/* Comparison */
8228
GEN_SPEFPUOP_COMP_32(efscmpgt);
8229
GEN_SPEFPUOP_COMP_32(efscmplt);
8230
GEN_SPEFPUOP_COMP_32(efscmpeq);
8231
GEN_SPEFPUOP_COMP_32(efststgt);
8232
GEN_SPEFPUOP_COMP_32(efststlt);
8233
GEN_SPEFPUOP_COMP_32(efststeq);
8234

    
8235
/* Opcodes definitions */
8236
GEN_SPE(efsadd,   efssub,   0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8237
GEN_SPE(efsabs,   efsnabs,  0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
8238
GEN_SPE(efsneg,   speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8239
GEN_SPE(efsmul,   efsdiv,   0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8240
GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8241
GEN_SPE(efscmpeq, efscfd,   0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE); //
8242
GEN_SPE(efscfui,  efscfsi,  0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8243
GEN_SPE(efscfuf,  efscfsf,  0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8244
GEN_SPE(efsctui,  efsctsi,  0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8245
GEN_SPE(efsctuf,  efsctsf,  0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8246
GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8247
GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8248
GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8249
GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8250

    
8251
/* Double precision floating-point operations */
8252
/* Arithmetic */
8253
GEN_SPEFPUOP_ARITH2_64_64(efdadd);
8254
GEN_SPEFPUOP_ARITH2_64_64(efdsub);
8255
GEN_SPEFPUOP_ARITH2_64_64(efdmul);
8256
GEN_SPEFPUOP_ARITH2_64_64(efddiv);
8257
static inline void gen_efdabs(DisasContext *ctx)
8258
{
8259
    if (unlikely(!ctx->spe_enabled)) {
8260
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8261
        return;
8262
    }
8263
#if defined(TARGET_PPC64)
8264
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
8265
#else
8266
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8267
    tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
8268
#endif
8269
}
8270
static inline void gen_efdnabs(DisasContext *ctx)
8271
{
8272
    if (unlikely(!ctx->spe_enabled)) {
8273
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8274
        return;
8275
    }
8276
#if defined(TARGET_PPC64)
8277
    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
8278
#else
8279
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8280
    tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8281
#endif
8282
}
8283
static inline void gen_efdneg(DisasContext *ctx)
8284
{
8285
    if (unlikely(!ctx->spe_enabled)) {
8286
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8287
        return;
8288
    }
8289
#if defined(TARGET_PPC64)
8290
    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
8291
#else
8292
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8293
    tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8294
#endif
8295
}
8296

    
8297
/* Conversion */
8298
GEN_SPEFPUOP_CONV_64_32(efdcfui);
8299
GEN_SPEFPUOP_CONV_64_32(efdcfsi);
8300
GEN_SPEFPUOP_CONV_64_32(efdcfuf);
8301
GEN_SPEFPUOP_CONV_64_32(efdcfsf);
8302
GEN_SPEFPUOP_CONV_32_64(efdctui);
8303
GEN_SPEFPUOP_CONV_32_64(efdctsi);
8304
GEN_SPEFPUOP_CONV_32_64(efdctuf);
8305
GEN_SPEFPUOP_CONV_32_64(efdctsf);
8306
GEN_SPEFPUOP_CONV_32_64(efdctuiz);
8307
GEN_SPEFPUOP_CONV_32_64(efdctsiz);
8308
GEN_SPEFPUOP_CONV_64_32(efdcfs);
8309
GEN_SPEFPUOP_CONV_64_64(efdcfuid);
8310
GEN_SPEFPUOP_CONV_64_64(efdcfsid);
8311
GEN_SPEFPUOP_CONV_64_64(efdctuidz);
8312
GEN_SPEFPUOP_CONV_64_64(efdctsidz);
8313

    
8314
/* Comparison */
8315
GEN_SPEFPUOP_COMP_64(efdcmpgt);
8316
GEN_SPEFPUOP_COMP_64(efdcmplt);
8317
GEN_SPEFPUOP_COMP_64(efdcmpeq);
8318
GEN_SPEFPUOP_COMP_64(efdtstgt);
8319
GEN_SPEFPUOP_COMP_64(efdtstlt);
8320
GEN_SPEFPUOP_COMP_64(efdtsteq);
8321

    
8322
/* Opcodes definitions */
8323
GEN_SPE(efdadd,    efdsub,    0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
8324
GEN_SPE(efdcfuid,  efdcfsid,  0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8325
GEN_SPE(efdabs,    efdnabs,   0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE); //
8326
GEN_SPE(efdneg,    speundef,  0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8327
GEN_SPE(efdmul,    efddiv,    0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
8328
GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8329
GEN_SPE(efdcmpgt,  efdcmplt,  0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
8330
GEN_SPE(efdcmpeq,  efdcfs,    0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE); //
8331
GEN_SPE(efdcfui,   efdcfsi,   0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8332
GEN_SPE(efdcfuf,   efdcfsf,   0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8333
GEN_SPE(efdctui,   efdctsi,   0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8334
GEN_SPE(efdctuf,   efdctsf,   0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8335
GEN_SPE(efdctuiz,  speundef,  0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8336
GEN_SPE(efdctsiz,  speundef,  0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8337
GEN_SPE(efdtstgt,  efdtstlt,  0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
8338
GEN_SPE(efdtsteq,  speundef,  0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8339

    
8340
static opcode_t opcodes[] = {
8341
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
8342
GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
8343
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
8344
GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
8345
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
8346
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
8347
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8348
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8349
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8350
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8351
GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
8352
GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
8353
GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
8354
GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
8355
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8356
#if defined(TARGET_PPC64)
8357
GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
8358
#endif
8359
GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
8360
GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
8361
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8362
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8363
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8364
GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
8365
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
8366
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
8367
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8368
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8369
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8370
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8371
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
8372
GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
8373
#if defined(TARGET_PPC64)
8374
GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
8375
GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
8376
#endif
8377
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8378
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8379
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8380
GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
8381
GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
8382
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
8383
GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
8384
#if defined(TARGET_PPC64)
8385
GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
8386
GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
8387
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
8388
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
8389
GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
8390
#endif
8391
GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
8392
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8393
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8394
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
8395
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
8396
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
8397
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
8398
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
8399
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
8400
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
8401
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT),
8402
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT),
8403
#if defined(TARGET_PPC64)
8404
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
8405
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
8406
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
8407
#endif
8408
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8409
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8410
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
8411
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
8412
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
8413
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
8414
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
8415
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
8416
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
8417
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
8418
#if defined(TARGET_PPC64)
8419
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
8420
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
8421
#endif
8422
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
8423
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
8424
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8425
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8426
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
8427
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
8428
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
8429
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
8430
#if defined(TARGET_PPC64)
8431
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
8432
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
8433
#endif
8434
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
8435
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
8436
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8437
#if defined(TARGET_PPC64)
8438
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
8439
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
8440
#endif
8441
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
8442
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
8443
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
8444
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
8445
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
8446
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
8447
#if defined(TARGET_PPC64)
8448
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
8449
#endif
8450
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
8451
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
8452
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
8453
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
8454
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
8455
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
8456
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
8457
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ),
8458
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT),
8459
GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
8460
GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
8461
GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
8462
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
8463
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
8464
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
8465
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
8466
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
8467
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
8468
#if defined(TARGET_PPC64)
8469
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
8470
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
8471
             PPC_SEGMENT_64B),
8472
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
8473
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
8474
             PPC_SEGMENT_64B),
8475
GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
8476
GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
8477
GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
8478
#endif
8479
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
8480
GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
8481
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
8482
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
8483
#if defined(TARGET_PPC64)
8484
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
8485
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
8486
#endif
8487
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
8488
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
8489
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
8490
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
8491
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
8492
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
8493
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
8494
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
8495
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
8496
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
8497
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
8498
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8499
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
8500
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
8501
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
8502
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
8503
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
8504
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
8505
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
8506
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8507
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
8508
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
8509
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
8510
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
8511
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
8512
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
8513
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
8514
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
8515
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
8516
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
8517
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
8518
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
8519
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
8520
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
8521
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
8522
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
8523
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
8524
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
8525
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
8526
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
8527
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
8528
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
8529
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
8530
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
8531
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
8532
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
8533
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
8534
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
8535
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
8536
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8537
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8538
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
8539
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
8540
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8541
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8542
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
8543
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
8544
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
8545
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
8546
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
8547
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
8548
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
8549
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
8550
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
8551
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
8552
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
8553
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
8554
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
8555
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
8556
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
8557
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
8558
GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
8559
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
8560
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
8561
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
8562
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
8563
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
8564
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
8565
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
8566
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
8567
GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
8568
               PPC_NONE, PPC2_BOOKE206),
8569
GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
8570
               PPC_NONE, PPC2_BOOKE206),
8571
GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
8572
               PPC_NONE, PPC2_BOOKE206),
8573
GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
8574
               PPC_NONE, PPC2_BOOKE206),
8575
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
8576
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
8577
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
8578
GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
8579
              PPC_BOOKE, PPC2_BOOKE206),
8580
GEN_HANDLER_E(msync, 0x1F, 0x16, 0x12, 0x03FFF801,
8581
              PPC_BOOKE, PPC2_BOOKE206),
8582
GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
8583
               PPC_BOOKE, PPC2_BOOKE206),
8584
GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
8585
GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
8586
GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
8587
GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
8588
GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
8589
GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
8590
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
8591
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
8592
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
8593
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
8594

    
8595
#undef GEN_INT_ARITH_ADD
8596
#undef GEN_INT_ARITH_ADD_CONST
8597
#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
8598
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
8599
#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
8600
                                add_ca, compute_ca, compute_ov)               \
8601
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
8602
GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
8603
GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
8604
GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
8605
GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
8606
GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
8607
GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
8608
GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
8609
GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
8610
GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
8611
GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
8612

    
8613
#undef GEN_INT_ARITH_DIVW
8614
#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
8615
GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
8616
GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
8617
GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
8618
GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
8619
GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
8620

    
8621
#if defined(TARGET_PPC64)
8622
#undef GEN_INT_ARITH_DIVD
8623
#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
8624
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8625
GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
8626
GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
8627
GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
8628
GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
8629

    
8630
#undef GEN_INT_ARITH_MUL_HELPER
8631
#define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
8632
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8633
GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
8634
GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
8635
GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
8636
#endif
8637

    
8638
#undef GEN_INT_ARITH_SUBF
8639
#undef GEN_INT_ARITH_SUBF_CONST
8640
#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
8641
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
8642
#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
8643
                                add_ca, compute_ca, compute_ov)               \
8644
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
8645
GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
8646
GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
8647
GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
8648
GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
8649
GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
8650
GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
8651
GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
8652
GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
8653
GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
8654
GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
8655

    
8656
#undef GEN_LOGICAL1
8657
#undef GEN_LOGICAL2
8658
#define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
8659
GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
8660
#define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
8661
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
8662
GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
8663
GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
8664
GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
8665
GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
8666
GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
8667
GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
8668
GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
8669
GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
8670
#if defined(TARGET_PPC64)
8671
GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
8672
#endif
8673

    
8674
#if defined(TARGET_PPC64)
8675
#undef GEN_PPC64_R2
8676
#undef GEN_PPC64_R4
8677
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
8678
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8679
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8680
             PPC_64B)
8681
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
8682
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8683
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
8684
             PPC_64B),                                                        \
8685
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8686
             PPC_64B),                                                        \
8687
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
8688
             PPC_64B)
8689
GEN_PPC64_R4(rldicl, 0x1E, 0x00),
8690
GEN_PPC64_R4(rldicr, 0x1E, 0x02),
8691
GEN_PPC64_R4(rldic, 0x1E, 0x04),
8692
GEN_PPC64_R2(rldcl, 0x1E, 0x08),
8693
GEN_PPC64_R2(rldcr, 0x1E, 0x09),
8694
GEN_PPC64_R4(rldimi, 0x1E, 0x06),
8695
#endif
8696

    
8697
#undef _GEN_FLOAT_ACB
8698
#undef GEN_FLOAT_ACB
8699
#undef _GEN_FLOAT_AB
8700
#undef GEN_FLOAT_AB
8701
#undef _GEN_FLOAT_AC
8702
#undef GEN_FLOAT_AC
8703
#undef GEN_FLOAT_B
8704
#undef GEN_FLOAT_BS
8705
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
8706
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
8707
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
8708
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
8709
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
8710
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8711
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8712
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
8713
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8714
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8715
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8716
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8717
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
8718
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8719
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8720
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
8721
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
8722
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
8723
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
8724

    
8725
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
8726
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
8727
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
8728
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
8729
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
8730
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
8731
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
8732
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
8733
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
8734
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
8735
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
8736
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
8737
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
8738
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
8739
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
8740
#if defined(TARGET_PPC64)
8741
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
8742
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
8743
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
8744
#endif
8745
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
8746
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
8747
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
8748
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
8749
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT),
8750
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT),
8751
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT),
8752

    
8753
#undef GEN_LD
8754
#undef GEN_LDU
8755
#undef GEN_LDUX
8756
#undef GEN_LDX
8757
#undef GEN_LDS
8758
#define GEN_LD(name, ldop, opc, type)                                         \
8759
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8760
#define GEN_LDU(name, ldop, opc, type)                                        \
8761
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8762
#define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
8763
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8764
#define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
8765
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8766
#define GEN_LDS(name, ldop, op, type)                                         \
8767
GEN_LD(name, ldop, op | 0x20, type)                                           \
8768
GEN_LDU(name, ldop, op | 0x21, type)                                          \
8769
GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
8770
GEN_LDX(name, ldop, 0x17, op | 0x00, type)
8771

    
8772
GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
8773
GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
8774
GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
8775
GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
8776
#if defined(TARGET_PPC64)
8777
GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
8778
GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
8779
GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
8780
GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
8781
#endif
8782
GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
8783
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
8784

    
8785
#undef GEN_ST
8786
#undef GEN_STU
8787
#undef GEN_STUX
8788
#undef GEN_STX
8789
#undef GEN_STS
8790
#define GEN_ST(name, stop, opc, type)                                         \
8791
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8792
#define GEN_STU(name, stop, opc, type)                                        \
8793
GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
8794
#define GEN_STUX(name, stop, opc2, opc3, type)                                \
8795
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8796
#define GEN_STX(name, stop, opc2, opc3, type)                                 \
8797
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8798
#define GEN_STS(name, stop, op, type)                                         \
8799
GEN_ST(name, stop, op | 0x20, type)                                           \
8800
GEN_STU(name, stop, op | 0x21, type)                                          \
8801
GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
8802
GEN_STX(name, stop, 0x17, op | 0x00, type)
8803

    
8804
GEN_STS(stb, st8, 0x06, PPC_INTEGER)
8805
GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
8806
GEN_STS(stw, st32, 0x04, PPC_INTEGER)
8807
#if defined(TARGET_PPC64)
8808
GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
8809
GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
8810
#endif
8811
GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
8812
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
8813

    
8814
#undef GEN_LDF
8815
#undef GEN_LDUF
8816
#undef GEN_LDUXF
8817
#undef GEN_LDXF
8818
#undef GEN_LDFS
8819
#define GEN_LDF(name, ldop, opc, type)                                        \
8820
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8821
#define GEN_LDUF(name, ldop, opc, type)                                       \
8822
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8823
#define GEN_LDUXF(name, ldop, opc, type)                                      \
8824
GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8825
#define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
8826
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8827
#define GEN_LDFS(name, ldop, op, type)                                        \
8828
GEN_LDF(name, ldop, op | 0x20, type)                                          \
8829
GEN_LDUF(name, ldop, op | 0x21, type)                                         \
8830
GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
8831
GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
8832

    
8833
GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
8834
GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
8835

    
8836
#undef GEN_STF
8837
#undef GEN_STUF
8838
#undef GEN_STUXF
8839
#undef GEN_STXF
8840
#undef GEN_STFS
8841
#define GEN_STF(name, stop, opc, type)                                        \
8842
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8843
#define GEN_STUF(name, stop, opc, type)                                       \
8844
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8845
#define GEN_STUXF(name, stop, opc, type)                                      \
8846
GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8847
#define GEN_STXF(name, stop, opc2, opc3, type)                                \
8848
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8849
#define GEN_STFS(name, stop, op, type)                                        \
8850
GEN_STF(name, stop, op | 0x20, type)                                          \
8851
GEN_STUF(name, stop, op | 0x21, type)                                         \
8852
GEN_STUXF(name, stop, op | 0x01, type)                                        \
8853
GEN_STXF(name, stop, 0x17, op | 0x00, type)
8854

    
8855
GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
8856
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
8857
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
8858

    
8859
#undef GEN_CRLOGIC
8860
#define GEN_CRLOGIC(name, tcg_op, opc)                                        \
8861
GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
8862
GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
8863
GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
8864
GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
8865
GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
8866
GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
8867
GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
8868
GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
8869
GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
8870

    
8871
#undef GEN_MAC_HANDLER
8872
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
8873
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
8874
GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
8875
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
8876
GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
8877
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
8878
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
8879
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
8880
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
8881
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
8882
GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
8883
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
8884
GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
8885
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
8886
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
8887
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
8888
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
8889
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
8890
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
8891
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
8892
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
8893
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
8894
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
8895
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
8896
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
8897
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
8898
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
8899
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
8900
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
8901
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
8902
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
8903
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
8904
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
8905
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
8906
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
8907
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
8908
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
8909
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
8910
GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
8911
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
8912
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
8913
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
8914
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
8915
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
8916

    
8917
#undef GEN_VR_LDX
8918
#undef GEN_VR_STX
8919
#undef GEN_VR_LVE
8920
#undef GEN_VR_STVE
8921
#define GEN_VR_LDX(name, opc2, opc3)                                          \
8922
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8923
#define GEN_VR_STX(name, opc2, opc3)                                          \
8924
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8925
#define GEN_VR_LVE(name, opc2, opc3)                                    \
8926
    GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8927
#define GEN_VR_STVE(name, opc2, opc3)                                   \
8928
    GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8929
GEN_VR_LDX(lvx, 0x07, 0x03),
8930
GEN_VR_LDX(lvxl, 0x07, 0x0B),
8931
GEN_VR_LVE(bx, 0x07, 0x00),
8932
GEN_VR_LVE(hx, 0x07, 0x01),
8933
GEN_VR_LVE(wx, 0x07, 0x02),
8934
GEN_VR_STX(svx, 0x07, 0x07),
8935
GEN_VR_STX(svxl, 0x07, 0x0F),
8936
GEN_VR_STVE(bx, 0x07, 0x04),
8937
GEN_VR_STVE(hx, 0x07, 0x05),
8938
GEN_VR_STVE(wx, 0x07, 0x06),
8939

    
8940
#undef GEN_VX_LOGICAL
8941
#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
8942
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8943
GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
8944
GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
8945
GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
8946
GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
8947
GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
8948

    
8949
#undef GEN_VXFORM
8950
#define GEN_VXFORM(name, opc2, opc3)                                    \
8951
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8952
GEN_VXFORM(vaddubm, 0, 0),
8953
GEN_VXFORM(vadduhm, 0, 1),
8954
GEN_VXFORM(vadduwm, 0, 2),
8955
GEN_VXFORM(vsububm, 0, 16),
8956
GEN_VXFORM(vsubuhm, 0, 17),
8957
GEN_VXFORM(vsubuwm, 0, 18),
8958
GEN_VXFORM(vmaxub, 1, 0),
8959
GEN_VXFORM(vmaxuh, 1, 1),
8960
GEN_VXFORM(vmaxuw, 1, 2),
8961
GEN_VXFORM(vmaxsb, 1, 4),
8962
GEN_VXFORM(vmaxsh, 1, 5),
8963
GEN_VXFORM(vmaxsw, 1, 6),
8964
GEN_VXFORM(vminub, 1, 8),
8965
GEN_VXFORM(vminuh, 1, 9),
8966
GEN_VXFORM(vminuw, 1, 10),
8967
GEN_VXFORM(vminsb, 1, 12),
8968
GEN_VXFORM(vminsh, 1, 13),
8969
GEN_VXFORM(vminsw, 1, 14),
8970
GEN_VXFORM(vavgub, 1, 16),
8971
GEN_VXFORM(vavguh, 1, 17),
8972
GEN_VXFORM(vavguw, 1, 18),
8973
GEN_VXFORM(vavgsb, 1, 20),
8974
GEN_VXFORM(vavgsh, 1, 21),
8975
GEN_VXFORM(vavgsw, 1, 22),
8976
GEN_VXFORM(vmrghb, 6, 0),
8977
GEN_VXFORM(vmrghh, 6, 1),
8978
GEN_VXFORM(vmrghw, 6, 2),
8979
GEN_VXFORM(vmrglb, 6, 4),
8980
GEN_VXFORM(vmrglh, 6, 5),
8981
GEN_VXFORM(vmrglw, 6, 6),
8982
GEN_VXFORM(vmuloub, 4, 0),
8983
GEN_VXFORM(vmulouh, 4, 1),
8984
GEN_VXFORM(vmulosb, 4, 4),
8985
GEN_VXFORM(vmulosh, 4, 5),
8986
GEN_VXFORM(vmuleub, 4, 8),
8987
GEN_VXFORM(vmuleuh, 4, 9),
8988
GEN_VXFORM(vmulesb, 4, 12),
8989
GEN_VXFORM(vmulesh, 4, 13),
8990
GEN_VXFORM(vslb, 2, 4),
8991
GEN_VXFORM(vslh, 2, 5),
8992
GEN_VXFORM(vslw, 2, 6),
8993
GEN_VXFORM(vsrb, 2, 8),
8994
GEN_VXFORM(vsrh, 2, 9),
8995
GEN_VXFORM(vsrw, 2, 10),
8996
GEN_VXFORM(vsrab, 2, 12),
8997
GEN_VXFORM(vsrah, 2, 13),
8998
GEN_VXFORM(vsraw, 2, 14),
8999
GEN_VXFORM(vslo, 6, 16),
9000
GEN_VXFORM(vsro, 6, 17),
9001
GEN_VXFORM(vaddcuw, 0, 6),
9002
GEN_VXFORM(vsubcuw, 0, 22),
9003
GEN_VXFORM(vaddubs, 0, 8),
9004
GEN_VXFORM(vadduhs, 0, 9),
9005
GEN_VXFORM(vadduws, 0, 10),
9006
GEN_VXFORM(vaddsbs, 0, 12),
9007
GEN_VXFORM(vaddshs, 0, 13),
9008
GEN_VXFORM(vaddsws, 0, 14),
9009
GEN_VXFORM(vsububs, 0, 24),
9010
GEN_VXFORM(vsubuhs, 0, 25),
9011
GEN_VXFORM(vsubuws, 0, 26),
9012
GEN_VXFORM(vsubsbs, 0, 28),
9013
GEN_VXFORM(vsubshs, 0, 29),
9014
GEN_VXFORM(vsubsws, 0, 30),
9015
GEN_VXFORM(vrlb, 2, 0),
9016
GEN_VXFORM(vrlh, 2, 1),
9017
GEN_VXFORM(vrlw, 2, 2),
9018
GEN_VXFORM(vsl, 2, 7),
9019
GEN_VXFORM(vsr, 2, 11),
9020
GEN_VXFORM(vpkuhum, 7, 0),
9021
GEN_VXFORM(vpkuwum, 7, 1),
9022
GEN_VXFORM(vpkuhus, 7, 2),
9023
GEN_VXFORM(vpkuwus, 7, 3),
9024
GEN_VXFORM(vpkshus, 7, 4),
9025
GEN_VXFORM(vpkswus, 7, 5),
9026
GEN_VXFORM(vpkshss, 7, 6),
9027
GEN_VXFORM(vpkswss, 7, 7),
9028
GEN_VXFORM(vpkpx, 7, 12),
9029
GEN_VXFORM(vsum4ubs, 4, 24),
9030
GEN_VXFORM(vsum4sbs, 4, 28),
9031
GEN_VXFORM(vsum4shs, 4, 25),
9032
GEN_VXFORM(vsum2sws, 4, 26),
9033
GEN_VXFORM(vsumsws, 4, 30),
9034
GEN_VXFORM(vaddfp, 5, 0),
9035
GEN_VXFORM(vsubfp, 5, 1),
9036
GEN_VXFORM(vmaxfp, 5, 16),
9037
GEN_VXFORM(vminfp, 5, 17),
9038

    
9039
#undef GEN_VXRFORM1
9040
#undef GEN_VXRFORM
9041
#define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
9042
    GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
9043
#define GEN_VXRFORM(name, opc2, opc3)                                \
9044
    GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
9045
    GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
9046
GEN_VXRFORM(vcmpequb, 3, 0)
9047
GEN_VXRFORM(vcmpequh, 3, 1)
9048
GEN_VXRFORM(vcmpequw, 3, 2)
9049
GEN_VXRFORM(vcmpgtsb, 3, 12)
9050
GEN_VXRFORM(vcmpgtsh, 3, 13)
9051
GEN_VXRFORM(vcmpgtsw, 3, 14)
9052
GEN_VXRFORM(vcmpgtub, 3, 8)
9053
GEN_VXRFORM(vcmpgtuh, 3, 9)
9054
GEN_VXRFORM(vcmpgtuw, 3, 10)
9055
GEN_VXRFORM(vcmpeqfp, 3, 3)
9056
GEN_VXRFORM(vcmpgefp, 3, 7)
9057
GEN_VXRFORM(vcmpgtfp, 3, 11)
9058
GEN_VXRFORM(vcmpbfp, 3, 15)
9059

    
9060
#undef GEN_VXFORM_SIMM
9061
#define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
9062
    GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
9063
GEN_VXFORM_SIMM(vspltisb, 6, 12),
9064
GEN_VXFORM_SIMM(vspltish, 6, 13),
9065
GEN_VXFORM_SIMM(vspltisw, 6, 14),
9066

    
9067
#undef GEN_VXFORM_NOA
9068
#define GEN_VXFORM_NOA(name, opc2, opc3)                                \
9069
    GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
9070
GEN_VXFORM_NOA(vupkhsb, 7, 8),
9071
GEN_VXFORM_NOA(vupkhsh, 7, 9),
9072
GEN_VXFORM_NOA(vupklsb, 7, 10),
9073
GEN_VXFORM_NOA(vupklsh, 7, 11),
9074
GEN_VXFORM_NOA(vupkhpx, 7, 13),
9075
GEN_VXFORM_NOA(vupklpx, 7, 15),
9076
GEN_VXFORM_NOA(vrefp, 5, 4),
9077
GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
9078
GEN_VXFORM_NOA(vexptefp, 5, 6),
9079
GEN_VXFORM_NOA(vlogefp, 5, 7),
9080
GEN_VXFORM_NOA(vrfim, 5, 8),
9081
GEN_VXFORM_NOA(vrfin, 5, 9),
9082
GEN_VXFORM_NOA(vrfip, 5, 10),
9083
GEN_VXFORM_NOA(vrfiz, 5, 11),
9084

    
9085
#undef GEN_VXFORM_UIMM
9086
#define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
9087
    GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
9088
GEN_VXFORM_UIMM(vspltb, 6, 8),
9089
GEN_VXFORM_UIMM(vsplth, 6, 9),
9090
GEN_VXFORM_UIMM(vspltw, 6, 10),
9091
GEN_VXFORM_UIMM(vcfux, 5, 12),
9092
GEN_VXFORM_UIMM(vcfsx, 5, 13),
9093
GEN_VXFORM_UIMM(vctuxs, 5, 14),
9094
GEN_VXFORM_UIMM(vctsxs, 5, 15),
9095

    
9096
#undef GEN_VAFORM_PAIRED
9097
#define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
9098
    GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
9099
GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
9100
GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
9101
GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
9102
GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
9103
GEN_VAFORM_PAIRED(vsel, vperm, 21),
9104
GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
9105

    
9106
#undef GEN_SPE
9107
#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
9108
    GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
9109
GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9110
GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9111
GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9112
GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9113
GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
9114
GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
9115
GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
9116
GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE),
9117
GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE),
9118
GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
9119
GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9120
GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9121
GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9122
GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
9123
GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
9124
GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE),
9125
GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
9126
GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9127
GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9128
GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9129
GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9130
GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9131
GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
9132
GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
9133
GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9134
GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9135
GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE),
9136
GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE),
9137
GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE),
9138

    
9139
GEN_SPE(evfsadd,     evfssub,     0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9140
GEN_SPE(evfsabs,     evfsnabs,    0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
9141
GEN_SPE(evfsneg,     speundef,    0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
9142
GEN_SPE(evfsmul,     evfsdiv,     0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9143
GEN_SPE(evfscmpgt,   evfscmplt,   0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9144
GEN_SPE(evfscmpeq,   speundef,    0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9145
GEN_SPE(evfscfui,    evfscfsi,    0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9146
GEN_SPE(evfscfuf,    evfscfsf,    0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9147
GEN_SPE(evfsctui,    evfsctsi,    0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9148
GEN_SPE(evfsctuf,    evfsctsf,    0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9149
GEN_SPE(evfsctuiz,   speundef,    0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9150
GEN_SPE(evfsctsiz,   speundef,    0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9151
GEN_SPE(evfststgt,   evfststlt,   0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9152
GEN_SPE(evfststeq,   speundef,    0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9153

    
9154
GEN_SPE(efsadd,      efssub,      0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9155
GEN_SPE(efsabs,      efsnabs,     0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
9156
GEN_SPE(efsneg,      speundef,    0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
9157
GEN_SPE(efsmul,      efsdiv,      0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9158
GEN_SPE(efscmpgt,    efscmplt,    0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9159
GEN_SPE(efscmpeq,    efscfd,      0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE),
9160
GEN_SPE(efscfui,     efscfsi,     0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9161
GEN_SPE(efscfuf,     efscfsf,     0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9162
GEN_SPE(efsctui,     efsctsi,     0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9163
GEN_SPE(efsctuf,     efsctsf,     0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9164
GEN_SPE(efsctuiz,    speundef,    0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9165
GEN_SPE(efsctsiz,    speundef,    0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9166
GEN_SPE(efststgt,    efststlt,    0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9167
GEN_SPE(efststeq,    speundef,    0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9168

    
9169
GEN_SPE(efdadd,      efdsub,      0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
9170
GEN_SPE(efdcfuid,    efdcfsid,    0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9171
GEN_SPE(efdabs,      efdnabs,     0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE),
9172
GEN_SPE(efdneg,      speundef,    0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9173
GEN_SPE(efdmul,      efddiv,      0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
9174
GEN_SPE(efdctuidz,   efdctsidz,   0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9175
GEN_SPE(efdcmpgt,    efdcmplt,    0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
9176
GEN_SPE(efdcmpeq,    efdcfs,      0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE),
9177
GEN_SPE(efdcfui,     efdcfsi,     0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9178
GEN_SPE(efdcfuf,     efdcfsf,     0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9179
GEN_SPE(efdctui,     efdctsi,     0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9180
GEN_SPE(efdctuf,     efdctsf,     0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9181
GEN_SPE(efdctuiz,    speundef,    0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9182
GEN_SPE(efdctsiz,    speundef,    0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9183
GEN_SPE(efdtstgt,    efdtstlt,    0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
9184
GEN_SPE(efdtsteq,    speundef,    0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9185

    
9186
#undef GEN_SPEOP_LDST
9187
#define GEN_SPEOP_LDST(name, opc2, sh)                                        \
9188
GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
9189
GEN_SPEOP_LDST(evldd, 0x00, 3),
9190
GEN_SPEOP_LDST(evldw, 0x01, 3),
9191
GEN_SPEOP_LDST(evldh, 0x02, 3),
9192
GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
9193
GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
9194
GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
9195
GEN_SPEOP_LDST(evlwhe, 0x08, 2),
9196
GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
9197
GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
9198
GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
9199
GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
9200

    
9201
GEN_SPEOP_LDST(evstdd, 0x10, 3),
9202
GEN_SPEOP_LDST(evstdw, 0x11, 3),
9203
GEN_SPEOP_LDST(evstdh, 0x12, 3),
9204
GEN_SPEOP_LDST(evstwhe, 0x18, 2),
9205
GEN_SPEOP_LDST(evstwho, 0x1A, 2),
9206
GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
9207
GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
9208
};
9209

    
9210
#include "translate_init.c"
9211
#include "helper_regs.h"
9212

    
9213
/*****************************************************************************/
9214
/* Misc PowerPC helpers */
9215
void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
9216
                     int flags)
9217
{
9218
#define RGPL  4
9219
#define RFPL  4
9220

    
9221
    int i;
9222

    
9223
    cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
9224
                TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
9225
                env->nip, env->lr, env->ctr, env->xer);
9226
    cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
9227
                TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
9228
                env->hflags, env->mmu_idx);
9229
#if !defined(NO_TIMER_DUMP)
9230
    cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
9231
#if !defined(CONFIG_USER_ONLY)
9232
                " DECR %08" PRIu32
9233
#endif
9234
                "\n",
9235
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
9236
#if !defined(CONFIG_USER_ONLY)
9237
                , cpu_ppc_load_decr(env)
9238
#endif
9239
                );
9240
#endif
9241
    for (i = 0; i < 32; i++) {
9242
        if ((i & (RGPL - 1)) == 0)
9243
            cpu_fprintf(f, "GPR%02d", i);
9244
        cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
9245
        if ((i & (RGPL - 1)) == (RGPL - 1))
9246
            cpu_fprintf(f, "\n");
9247
    }
9248
    cpu_fprintf(f, "CR ");
9249
    for (i = 0; i < 8; i++)
9250
        cpu_fprintf(f, "%01x", env->crf[i]);
9251
    cpu_fprintf(f, "  [");
9252
    for (i = 0; i < 8; i++) {
9253
        char a = '-';
9254
        if (env->crf[i] & 0x08)
9255
            a = 'L';
9256
        else if (env->crf[i] & 0x04)
9257
            a = 'G';
9258
        else if (env->crf[i] & 0x02)
9259
            a = 'E';
9260
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
9261
    }
9262
    cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
9263
                env->reserve_addr);
9264
    for (i = 0; i < 32; i++) {
9265
        if ((i & (RFPL - 1)) == 0)
9266
            cpu_fprintf(f, "FPR%02d", i);
9267
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
9268
        if ((i & (RFPL - 1)) == (RFPL - 1))
9269
            cpu_fprintf(f, "\n");
9270
    }
9271
    cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
9272
#if !defined(CONFIG_USER_ONLY)
9273
    cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
9274
                   "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
9275
                env->spr[SPR_SRR0], env->spr[SPR_SRR1],
9276
                env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
9277

    
9278
    cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
9279
                   "  SPRG2 " TARGET_FMT_lx "  SPRG3 " TARGET_FMT_lx "\n",
9280
                env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
9281
                env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
9282

    
9283
    cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
9284
                   "  SPRG6 " TARGET_FMT_lx "  SPRG7 " TARGET_FMT_lx "\n",
9285
                env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
9286
                env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
9287

    
9288
    if (env->excp_model == POWERPC_EXCP_BOOKE) {
9289
        cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
9290
                       " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
9291
                    env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
9292
                    env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
9293

    
9294
        cpu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
9295
                       "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
9296
                    env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
9297
                    env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
9298

    
9299
        cpu_fprintf(f, "  PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
9300
                       "   IVPR " TARGET_FMT_lx "   EPCR " TARGET_FMT_lx "\n",
9301
                    env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
9302
                    env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
9303

    
9304
        cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
9305
                       "    EPR " TARGET_FMT_lx "\n",
9306
                    env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
9307
                    env->spr[SPR_BOOKE_EPR]);
9308

    
9309
        /* FSL-specific */
9310
        cpu_fprintf(f, " MCAR " TARGET_FMT_lx "  PID1 " TARGET_FMT_lx
9311
                       "   PID2 " TARGET_FMT_lx "    SVR " TARGET_FMT_lx "\n",
9312
                    env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
9313
                    env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
9314

    
9315
        /*
9316
         * IVORs are left out as they are large and do not change often --
9317
         * they can be read with "p $ivor0", "p $ivor1", etc.
9318
         */
9319
    }
9320

    
9321
#if defined(TARGET_PPC64)
9322
    if (env->flags & POWERPC_FLAG_CFAR) {
9323
        cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
9324
    }
9325
#endif
9326

    
9327
    switch (env->mmu_model) {
9328
    case POWERPC_MMU_32B:
9329
    case POWERPC_MMU_601:
9330
    case POWERPC_MMU_SOFT_6xx:
9331
    case POWERPC_MMU_SOFT_74xx:
9332
#if defined(TARGET_PPC64)
9333
    case POWERPC_MMU_620:
9334
    case POWERPC_MMU_64B:
9335
#endif
9336
        cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "\n", env->spr[SPR_SDR1]);
9337
        break;
9338
    case POWERPC_MMU_BOOKE206:
9339
        cpu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
9340
                       "   MAS2 " TARGET_FMT_lx "   MAS3 " TARGET_FMT_lx "\n",
9341
                    env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
9342
                    env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
9343

    
9344
        cpu_fprintf(f, " MAS4 " TARGET_FMT_lx "  MAS6 " TARGET_FMT_lx
9345
                       "   MAS7 " TARGET_FMT_lx "    PID " TARGET_FMT_lx "\n",
9346
                    env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
9347
                    env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
9348

    
9349
        cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
9350
                       " TLB1CFG " TARGET_FMT_lx "\n",
9351
                    env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
9352
                    env->spr[SPR_BOOKE_TLB1CFG]);
9353
        break;
9354
    default:
9355
        break;
9356
    }
9357
#endif
9358

    
9359
#undef RGPL
9360
#undef RFPL
9361
}
9362

    
9363
void cpu_dump_statistics (CPUState *env, FILE*f, fprintf_function cpu_fprintf,
9364
                          int flags)
9365
{
9366
#if defined(DO_PPC_STATISTICS)
9367
    opc_handler_t **t1, **t2, **t3, *handler;
9368
    int op1, op2, op3;
9369

    
9370
    t1 = env->opcodes;
9371
    for (op1 = 0; op1 < 64; op1++) {
9372
        handler = t1[op1];
9373
        if (is_indirect_opcode(handler)) {
9374
            t2 = ind_table(handler);
9375
            for (op2 = 0; op2 < 32; op2++) {
9376
                handler = t2[op2];
9377
                if (is_indirect_opcode(handler)) {
9378
                    t3 = ind_table(handler);
9379
                    for (op3 = 0; op3 < 32; op3++) {
9380
                        handler = t3[op3];
9381
                        if (handler->count == 0)
9382
                            continue;
9383
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
9384
                                    "%016" PRIx64 " %" PRId64 "\n",
9385
                                    op1, op2, op3, op1, (op3 << 5) | op2,
9386
                                    handler->oname,
9387
                                    handler->count, handler->count);
9388
                    }
9389
                } else {
9390
                    if (handler->count == 0)
9391
                        continue;
9392
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
9393
                                "%016" PRIx64 " %" PRId64 "\n",
9394
                                op1, op2, op1, op2, handler->oname,
9395
                                handler->count, handler->count);
9396
                }
9397
            }
9398
        } else {
9399
            if (handler->count == 0)
9400
                continue;
9401
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
9402
                        " %" PRId64 "\n",
9403
                        op1, op1, handler->oname,
9404
                        handler->count, handler->count);
9405
        }
9406
    }
9407
#endif
9408
}
9409

    
9410
/*****************************************************************************/
9411
static inline void gen_intermediate_code_internal(CPUState *env,
9412
                                                  TranslationBlock *tb,
9413
                                                  int search_pc)
9414
{
9415
    DisasContext ctx, *ctxp = &ctx;
9416
    opc_handler_t **table, *handler;
9417
    target_ulong pc_start;
9418
    uint16_t *gen_opc_end;
9419
    CPUBreakpoint *bp;
9420
    int j, lj = -1;
9421
    int num_insns;
9422
    int max_insns;
9423

    
9424
    pc_start = tb->pc;
9425
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9426
    ctx.nip = pc_start;
9427
    ctx.tb = tb;
9428
    ctx.exception = POWERPC_EXCP_NONE;
9429
    ctx.spr_cb = env->spr_cb;
9430
    ctx.mem_idx = env->mmu_idx;
9431
    ctx.access_type = -1;
9432
    ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
9433
#if defined(TARGET_PPC64)
9434
    ctx.sf_mode = msr_sf;
9435
    ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
9436
#endif
9437
    ctx.fpu_enabled = msr_fp;
9438
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
9439
        ctx.spe_enabled = msr_spe;
9440
    else
9441
        ctx.spe_enabled = 0;
9442
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
9443
        ctx.altivec_enabled = msr_vr;
9444
    else
9445
        ctx.altivec_enabled = 0;
9446
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
9447
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
9448
    else
9449
        ctx.singlestep_enabled = 0;
9450
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
9451
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
9452
    if (unlikely(env->singlestep_enabled))
9453
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
9454
#if defined (DO_SINGLE_STEP) && 0
9455
    /* Single step trace mode */
9456
    msr_se = 1;
9457
#endif
9458
    num_insns = 0;
9459
    max_insns = tb->cflags & CF_COUNT_MASK;
9460
    if (max_insns == 0)
9461
        max_insns = CF_COUNT_MASK;
9462

    
9463
    gen_icount_start();
9464
    /* Set env in case of segfault during code fetch */
9465
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
9466
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9467
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9468
                if (bp->pc == ctx.nip) {
9469
                    gen_debug_exception(ctxp);
9470
                    break;
9471
                }
9472
            }
9473
        }
9474
        if (unlikely(search_pc)) {
9475
            j = gen_opc_ptr - gen_opc_buf;
9476
            if (lj < j) {
9477
                lj++;
9478
                while (lj < j)
9479
                    gen_opc_instr_start[lj++] = 0;
9480
            }
9481
            gen_opc_pc[lj] = ctx.nip;
9482
            gen_opc_instr_start[lj] = 1;
9483
            gen_opc_icount[lj] = num_insns;
9484
        }
9485
        LOG_DISAS("----------------\n");
9486
        LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
9487
                  ctx.nip, ctx.mem_idx, (int)msr_ir);
9488
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9489
            gen_io_start();
9490
        if (unlikely(ctx.le_mode)) {
9491
            ctx.opcode = bswap32(ldl_code(ctx.nip));
9492
        } else {
9493
            ctx.opcode = ldl_code(ctx.nip);
9494
        }
9495
        LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
9496
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
9497
                    opc3(ctx.opcode), little_endian ? "little" : "big");
9498
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
9499
            tcg_gen_debug_insn_start(ctx.nip);
9500
        ctx.nip += 4;
9501
        table = env->opcodes;
9502
        num_insns++;
9503
        handler = table[opc1(ctx.opcode)];
9504
        if (is_indirect_opcode(handler)) {
9505
            table = ind_table(handler);
9506
            handler = table[opc2(ctx.opcode)];
9507
            if (is_indirect_opcode(handler)) {
9508
                table = ind_table(handler);
9509
                handler = table[opc3(ctx.opcode)];
9510
            }
9511
        }
9512
        /* Is opcode *REALLY* valid ? */
9513
        if (unlikely(handler->handler == &gen_invalid)) {
9514
            if (qemu_log_enabled()) {
9515
                qemu_log("invalid/unsupported opcode: "
9516
                         "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
9517
                         opc1(ctx.opcode), opc2(ctx.opcode),
9518
                         opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
9519
            }
9520
        } else {
9521
            uint32_t inval;
9522

    
9523
            if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
9524
                inval = handler->inval2;
9525
            } else {
9526
                inval = handler->inval1;
9527
            }
9528

    
9529
            if (unlikely((ctx.opcode & inval) != 0)) {
9530
                if (qemu_log_enabled()) {
9531
                    qemu_log("invalid bits: %08x for opcode: "
9532
                             "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
9533
                             ctx.opcode & inval, opc1(ctx.opcode),
9534
                             opc2(ctx.opcode), opc3(ctx.opcode),
9535
                             ctx.opcode, ctx.nip - 4);
9536
                }
9537
                gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
9538
                break;
9539
            }
9540
        }
9541
        (*(handler->handler))(&ctx);
9542
#if defined(DO_PPC_STATISTICS)
9543
        handler->count++;
9544
#endif
9545
        /* Check trace mode exceptions */
9546
        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
9547
                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
9548
                     ctx.exception != POWERPC_SYSCALL &&
9549
                     ctx.exception != POWERPC_EXCP_TRAP &&
9550
                     ctx.exception != POWERPC_EXCP_BRANCH)) {
9551
            gen_exception(ctxp, POWERPC_EXCP_TRACE);
9552
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
9553
                            (env->singlestep_enabled) ||
9554
                            singlestep ||
9555
                            num_insns >= max_insns)) {
9556
            /* if we reach a page boundary or are single stepping, stop
9557
             * generation
9558
             */
9559
            break;
9560
        }
9561
    }
9562
    if (tb->cflags & CF_LAST_IO)
9563
        gen_io_end();
9564
    if (ctx.exception == POWERPC_EXCP_NONE) {
9565
        gen_goto_tb(&ctx, 0, ctx.nip);
9566
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
9567
        if (unlikely(env->singlestep_enabled)) {
9568
            gen_debug_exception(ctxp);
9569
        }
9570
        /* Generate the return instruction */
9571
        tcg_gen_exit_tb(0);
9572
    }
9573
    gen_icount_end(tb, num_insns);
9574
    *gen_opc_ptr = INDEX_op_end;
9575
    if (unlikely(search_pc)) {
9576
        j = gen_opc_ptr - gen_opc_buf;
9577
        lj++;
9578
        while (lj <= j)
9579
            gen_opc_instr_start[lj++] = 0;
9580
    } else {
9581
        tb->size = ctx.nip - pc_start;
9582
        tb->icount = num_insns;
9583
    }
9584
#if defined(DEBUG_DISAS)
9585
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9586
        int flags;
9587
        flags = env->bfd_mach;
9588
        flags |= ctx.le_mode << 16;
9589
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9590
        log_target_disas(pc_start, ctx.nip - pc_start, flags);
9591
        qemu_log("\n");
9592
    }
9593
#endif
9594
}
9595

    
9596
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
9597
{
9598
    gen_intermediate_code_internal(env, tb, 0);
9599
}
9600

    
9601
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
9602
{
9603
    gen_intermediate_code_internal(env, tb, 1);
9604
}
9605

    
9606
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
9607
{
9608
    env->nip = gen_opc_pc[pc_pos];
9609
}