Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 36081602

History | View | Annotate | Download (196.9 kB)

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

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

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

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

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

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

    
51
#include "gen-op.h"
52

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
365
    return ret;
366
}
367

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1114
    mb = MB(ctx->opcode);
1115
    me = ME(ctx->opcode);
1116
    sh = SH(ctx->opcode);
1117
    if (likely(sh == 0)) {
1118
        if (likely(mb == 0 && me == 31)) {
1119
            gen_op_load_gpr_T0(rS(ctx->opcode));
1120
            goto do_store;
1121
        } else if (likely(mb == 31 && me == 0)) {
1122
            gen_op_load_gpr_T0(rA(ctx->opcode));
1123
            goto do_store;
1124
        }
1125
        gen_op_load_gpr_T0(rS(ctx->opcode));
1126
        gen_op_load_gpr_T1(rA(ctx->opcode));
1127
        goto do_mask;
1128
    }
1129
    gen_op_load_gpr_T0(rS(ctx->opcode));
1130
    gen_op_load_gpr_T1(rA(ctx->opcode));
1131
    gen_op_rotli32_T0(SH(ctx->opcode));
1132
 do_mask:
1133
#if defined(TARGET_PPC64)
1134
    mb += 32;
1135
    me += 32;
1136
#endif
1137
    mask = MASK(mb, me);
1138
    gen_op_andi_T0(mask);
1139
    gen_op_andi_T1(~mask);
1140
    gen_op_or();
1141
 do_store:
1142
    gen_op_store_T0_gpr(rA(ctx->opcode));
1143
    if (unlikely(Rc(ctx->opcode) != 0))
1144
        gen_set_Rc0(ctx);
1145
}
1146
/* rlwinm & rlwinm. */
1147
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1148
{
1149
    uint32_t mb, me, sh;
1150

    
1151
    sh = SH(ctx->opcode);
1152
    mb = MB(ctx->opcode);
1153
    me = ME(ctx->opcode);
1154
    gen_op_load_gpr_T0(rS(ctx->opcode));
1155
    if (likely(sh == 0)) {
1156
        goto do_mask;
1157
    }
1158
    if (likely(mb == 0)) {
1159
        if (likely(me == 31)) {
1160
            gen_op_rotli32_T0(sh);
1161
            goto do_store;
1162
        } else if (likely(me == (31 - sh))) {
1163
            gen_op_sli_T0(sh);
1164
            goto do_store;
1165
        }
1166
    } else if (likely(me == 31)) {
1167
        if (likely(sh == (32 - mb))) {
1168
            gen_op_srli_T0(mb);
1169
            goto do_store;
1170
        }
1171
    }
1172
    gen_op_rotli32_T0(sh);
1173
 do_mask:
1174
#if defined(TARGET_PPC64)
1175
    mb += 32;
1176
    me += 32;
1177
#endif
1178
    gen_op_andi_T0(MASK(mb, me));
1179
 do_store:
1180
    gen_op_store_T0_gpr(rA(ctx->opcode));
1181
    if (unlikely(Rc(ctx->opcode) != 0))
1182
        gen_set_Rc0(ctx);
1183
}
1184
/* rlwnm & rlwnm. */
1185
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1186
{
1187
    uint32_t mb, me;
1188

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1675
/* mtfsb0 */
1676
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1677
{
1678
    uint8_t crb;
1679

    
1680
    if (unlikely(!ctx->fpu_enabled)) {
1681
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1682
        return;
1683
    }
1684
    crb = crbD(ctx->opcode) >> 2;
1685
    gen_op_load_fpscr_T0(crb);
1686
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1687
    gen_op_store_T0_fpscr(crb);
1688
    if (unlikely(Rc(ctx->opcode) != 0))
1689
        gen_op_set_Rc1();
1690
}
1691

    
1692
/* mtfsb1 */
1693
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1694
{
1695
    uint8_t crb;
1696

    
1697
    if (unlikely(!ctx->fpu_enabled)) {
1698
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1699
        return;
1700
    }
1701
    crb = crbD(ctx->opcode) >> 2;
1702
    gen_op_load_fpscr_T0(crb);
1703
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1704
    gen_op_store_T0_fpscr(crb);
1705
    if (unlikely(Rc(ctx->opcode) != 0))
1706
        gen_op_set_Rc1();
1707
}
1708

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2966
/* mfcr */
2967
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
2968
{
2969
    uint32_t crm, crn;
2970

    
2971
    if (likely(ctx->opcode & 0x00100000)) {
2972
        crm = CRM(ctx->opcode);
2973
        if (likely((crm ^ (crm - 1)) == 0)) {
2974
            crn = ffs(crm);
2975
            gen_op_load_cro(7 - crn);
2976
        }
2977
    } else {
2978
        gen_op_load_cr();
2979
    }
2980
    gen_op_store_T0_gpr(rD(ctx->opcode));
2981
}
2982

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

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

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

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

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

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

    
3056
/* mtcrf */
3057
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3058
{
3059
    uint32_t crm, crn;
3060

    
3061
    gen_op_load_gpr_T0(rS(ctx->opcode));
3062
    crm = CRM(ctx->opcode);
3063
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3064
        crn = ffs(crm);
3065
        gen_op_srli_T0(crn * 4);
3066
        gen_op_andi_T0(0xF);
3067
        gen_op_store_cro(7 - crn);
3068
    } else {
3069
        gen_op_store_cr(crm);
3070
    }
3071
}
3072

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4937
#define GEN_SPEOP_LDST(name, sh)                                              \
4938
GEN_SPEOP_LD(name, sh);                                                       \