Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 76a66253

History | View | Annotate | Download (125.1 kB)

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

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

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

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

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

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

    
50
#include "gen-op.h"
51

    
52
#define GEN8(func, NAME) \
53
static GenOpFunc *NAME ## _table [8] = {                                      \
54
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
55
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
56
};                                                                            \
57
static inline void func(int n)                                                \
58
{                                                                             \
59
    NAME ## _table[n]();                                                      \
60
}
61

    
62
#define GEN16(func, NAME)                                                     \
63
static GenOpFunc *NAME ## _table [16] = {                                     \
64
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
65
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
66
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
67
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
68
};                                                                            \
69
static inline void func(int n)                                                \
70
{                                                                             \
71
    NAME ## _table[n]();                                                      \
72
}
73

    
74
#define GEN32(func, NAME) \
75
static GenOpFunc *NAME ## _table [32] = {                                     \
76
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
77
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
78
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
79
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
80
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
81
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
82
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
83
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
84
};                                                                            \
85
static inline void func(int n)                                                \
86
{                                                                             \
87
    NAME ## _table[n]();                                                      \
88
}
89

    
90
/* Condition register moves */
91
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
92
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
93
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
94
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
95

    
96
/* Floating point condition and status register moves */
97
GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
98
GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
99
GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
100
static inline void gen_op_store_T0_fpscri(int n, uint8_t param)
101
{
102
    gen_op_set_T0(param);
103
    gen_op_store_T0_fpscr(n);
104
}
105

    
106
/* General purpose registers moves */
107
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
108
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
109
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
110

    
111
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
112
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
113
#if 0 // unused
114
GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
115
#endif
116

    
117
/* floating point registers moves */
118
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
119
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
120
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
121
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
122
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
123
#if 0 // unused
124
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
125
#endif
126

    
127
/* internal defines */
128
typedef struct DisasContext {
129
    struct TranslationBlock *tb;
130
    target_ulong nip;
131
    uint32_t opcode;
132
    uint32_t exception;
133
    /* Routine used to access memory */
134
    int mem_idx;
135
    /* Translation flags */
136
#if !defined(CONFIG_USER_ONLY)
137
    int supervisor;
138
#endif
139
    int fpu_enabled;
140
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
141
    int singlestep_enabled;
142
} DisasContext;
143

    
144
struct opc_handler_t {
145
    /* invalid bits */
146
    uint32_t inval;
147
    /* instruction type */
148
    uint32_t type;
149
    /* handler */
150
    void (*handler)(DisasContext *ctx);
151
#if defined(DO_PPC_STATISTICS)
152
    const unsigned char *oname;
153
    uint64_t count;
154
#endif
155
};
156

    
157
static inline void gen_set_Rc0 (DisasContext *ctx)
158
{
159
    gen_op_cmpi(0);
160
    gen_op_set_Rc0();
161
}
162

    
163
#define RET_EXCP(ctx, excp, error)                                            \
164
do {                                                                          \
165
    if ((ctx)->exception == EXCP_NONE) {                                      \
166
        gen_op_update_nip((ctx)->nip);                                        \
167
    }                                                                         \
168
    gen_op_raise_exception_err((excp), (error));                              \
169
    ctx->exception = (excp);                                                  \
170
} while (0)
171

    
172
#define RET_INVAL(ctx)                                                        \
173
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
174

    
175
#define RET_PRIVOPC(ctx)                                                      \
176
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
177

    
178
#define RET_PRIVREG(ctx)                                                      \
179
RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
180

    
181
/* Stop translation */
182
static inline void RET_STOP (DisasContext *ctx)
183
{
184
    gen_op_update_nip((ctx)->nip);
185
    ctx->exception = EXCP_MTMSR;
186
}
187

    
188
/* No need to update nip here, as execution flow will change */
189
static inline void RET_CHG_FLOW (DisasContext *ctx)
190
{
191
    ctx->exception = EXCP_MTMSR;
192
}
193

    
194
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
195
static void gen_##name (DisasContext *ctx);                                   \
196
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
197
static void gen_##name (DisasContext *ctx)
198

    
199
typedef struct opcode_t {
200
    unsigned char opc1, opc2, opc3;
201
#if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
202
    unsigned char pad[5];
203
#else
204
    unsigned char pad[1];
205
#endif
206
    opc_handler_t handler;
207
    const unsigned char *oname;
208
} opcode_t;
209

    
210
/***                           Instruction decoding                        ***/
211
#define EXTRACT_HELPER(name, shift, nb)                                       \
212
static inline target_ulong name (uint32_t opcode)                             \
213
{                                                                             \
214
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
215
}
216

    
217
#define EXTRACT_SHELPER(name, shift, nb)                                      \
218
static inline target_long name (uint32_t opcode)                              \
219
{                                                                             \
220
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
221
}
222

    
223
/* Opcode part 1 */
224
EXTRACT_HELPER(opc1, 26, 6);
225
/* Opcode part 2 */
226
EXTRACT_HELPER(opc2, 1, 5);
227
/* Opcode part 3 */
228
EXTRACT_HELPER(opc3, 6, 5);
229
/* Update Cr0 flags */
230
EXTRACT_HELPER(Rc, 0, 1);
231
/* Destination */
232
EXTRACT_HELPER(rD, 21, 5);
233
/* Source */
234
EXTRACT_HELPER(rS, 21, 5);
235
/* First operand */
236
EXTRACT_HELPER(rA, 16, 5);
237
/* Second operand */
238
EXTRACT_HELPER(rB, 11, 5);
239
/* Third operand */
240
EXTRACT_HELPER(rC, 6, 5);
241
/***                               Get CRn                                 ***/
242
EXTRACT_HELPER(crfD, 23, 3);
243
EXTRACT_HELPER(crfS, 18, 3);
244
EXTRACT_HELPER(crbD, 21, 5);
245
EXTRACT_HELPER(crbA, 16, 5);
246
EXTRACT_HELPER(crbB, 11, 5);
247
/* SPR / TBL */
248
EXTRACT_HELPER(_SPR, 11, 10);
249
static inline uint32_t SPR (uint32_t opcode)
250
{
251
    uint32_t sprn = _SPR(opcode);
252

    
253
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
254
}
255
/***                              Get constants                            ***/
256
EXTRACT_HELPER(IMM, 12, 8);
257
/* 16 bits signed immediate value */
258
EXTRACT_SHELPER(SIMM, 0, 16);
259
/* 16 bits unsigned immediate value */
260
EXTRACT_HELPER(UIMM, 0, 16);
261
/* Bit count */
262
EXTRACT_HELPER(NB, 11, 5);
263
/* Shift count */
264
EXTRACT_HELPER(SH, 11, 5);
265
/* Mask start */
266
EXTRACT_HELPER(MB, 6, 5);
267
/* Mask end */
268
EXTRACT_HELPER(ME, 1, 5);
269
/* Trap operand */
270
EXTRACT_HELPER(TO, 21, 5);
271

    
272
EXTRACT_HELPER(CRM, 12, 8);
273
EXTRACT_HELPER(FM, 17, 8);
274
EXTRACT_HELPER(SR, 16, 4);
275
EXTRACT_HELPER(FPIMM, 20, 4);
276

    
277
/***                            Jump target decoding                       ***/
278
/* Displacement */
279
EXTRACT_SHELPER(d, 0, 16);
280
/* Immediate address */
281
static inline target_ulong LI (uint32_t opcode)
282
{
283
    return (opcode >> 0) & 0x03FFFFFC;
284
}
285

    
286
static inline uint32_t BD (uint32_t opcode)
287
{
288
    return (opcode >> 0) & 0xFFFC;
289
}
290

    
291
EXTRACT_HELPER(BO, 21, 5);
292
EXTRACT_HELPER(BI, 16, 5);
293
/* Absolute/relative address */
294
EXTRACT_HELPER(AA, 1, 1);
295
/* Link */
296
EXTRACT_HELPER(LK, 0, 1);
297

    
298
/* Create a mask between <start> and <end> bits */
299
static inline target_ulong MASK (uint32_t start, uint32_t end)
300
{
301
    target_ulong ret;
302

    
303
#if defined(TARGET_PPC64)
304
    if (likely(start == 0)) {
305
        ret = (uint64_t)(-1ULL) << (63 - end);
306
    } else if (likely(end == 63)) {
307
        ret = (uint64_t)(-1ULL) >> start;
308
    }
309
#else
310
    if (likely(start == 0)) {
311
        ret = (uint32_t)(-1ULL) << (31  - end);
312
    } else if (likely(end == 31)) {
313
        ret = (uint32_t)(-1ULL) >> start;
314
    }
315
#endif
316
    else {
317
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
318
            (((target_ulong)(-1ULL) >> (end)) >> 1);
319
        if (unlikely(start > end))
320
            return ~ret;
321
    }
322

    
323
    return ret;
324
}
325

    
326
#if HOST_LONG_BITS == 64
327
#define OPC_ALIGN 8
328
#else
329
#define OPC_ALIGN 4
330
#endif
331
#if defined(__APPLE__)
332
#define OPCODES_SECTION \
333
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
334
#else
335
#define OPCODES_SECTION \
336
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
337
#endif
338

    
339
#if defined(DO_PPC_STATISTICS)
340
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
341
OPCODES_SECTION opcode_t opc_##name = {                                       \
342
    .opc1 = op1,                                                              \
343
    .opc2 = op2,                                                              \
344
    .opc3 = op3,                                                              \
345
    .pad  = { 0, },                                                           \
346
    .handler = {                                                              \
347
        .inval   = invl,                                                      \
348
        .type = _typ,                                                         \
349
        .handler = &gen_##name,                                               \
350
        .oname = stringify(name),                                             \
351
    },                                                                        \
352
    .oname = stringify(name),                                                 \
353
}
354
#else
355
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
356
OPCODES_SECTION opcode_t opc_##name = {                                       \
357
    .opc1 = op1,                                                              \
358
    .opc2 = op2,                                                              \
359
    .opc3 = op3,                                                              \
360
    .pad  = { 0, },                                                           \
361
    .handler = {                                                              \
362
        .inval   = invl,                                                      \
363
        .type = _typ,                                                         \
364
        .handler = &gen_##name,                                               \
365
    },                                                                        \
366
    .oname = stringify(name),                                                 \
367
}
368
#endif
369

    
370
#define GEN_OPCODE_MARK(name)                                                 \
371
OPCODES_SECTION opcode_t opc_##name = {                                       \
372
    .opc1 = 0xFF,                                                             \
373
    .opc2 = 0xFF,                                                             \
374
    .opc3 = 0xFF,                                                             \
375
    .pad  = { 0, },                                                           \
376
    .handler = {                                                              \
377
        .inval   = 0x00000000,                                                \
378
        .type = 0x00,                                                         \
379
        .handler = NULL,                                                      \
380
    },                                                                        \
381
    .oname = stringify(name),                                                 \
382
}
383

    
384
/* Start opcode list */
385
GEN_OPCODE_MARK(start);
386

    
387
/* Invalid instruction */
388
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
389
{
390
    RET_INVAL(ctx);
391
}
392

    
393
static opc_handler_t invalid_handler = {
394
    .inval   = 0xFFFFFFFF,
395
    .type    = PPC_NONE,
396
    .handler = gen_invalid,
397
};
398

    
399
/***                           Integer arithmetic                          ***/
400
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval)                       \
401
GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER)                       \
402
{                                                                             \
403
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
404
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
405
    gen_op_##name();                                                          \
406
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
407
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
408
        gen_set_Rc0(ctx);                                                     \
409
}
410

    
411
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval)                     \
412
GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER)                       \
413
{                                                                             \
414
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
415
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
416
    gen_op_##name();                                                          \
417
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
418
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
419
        gen_set_Rc0(ctx);                                                     \
420
}
421

    
422
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3)                              \
423
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER)                  \
424
{                                                                             \
425
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
426
    gen_op_##name();                                                          \
427
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
428
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
429
        gen_set_Rc0(ctx);                                                     \
430
}
431
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3)                            \
432
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER)                  \
433
{                                                                             \
434
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
435
    gen_op_##name();                                                          \
436
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
437
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
438
        gen_set_Rc0(ctx);                                                     \
439
}
440

    
441
/* Two operands arithmetic functions */
442
#define GEN_INT_ARITH2(name, opc1, opc2, opc3)                                \
443
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000)                          \
444
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000)
445

    
446
/* Two operands arithmetic functions with no overflow allowed */
447
#define GEN_INT_ARITHN(name, opc1, opc2, opc3)                                \
448
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400)
449

    
450
/* One operand arithmetic functions */
451
#define GEN_INT_ARITH1(name, opc1, opc2, opc3)                                \
452
__GEN_INT_ARITH1(name, opc1, opc2, opc3)                                      \
453
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10)
454

    
455
/* add    add.    addo    addo.    */
456
GEN_INT_ARITH2 (add,    0x1F, 0x0A, 0x08);
457
/* addc   addc.   addco   addco.   */
458
GEN_INT_ARITH2 (addc,   0x1F, 0x0A, 0x00);
459
/* adde   adde.   addeo   addeo.   */
460
GEN_INT_ARITH2 (adde,   0x1F, 0x0A, 0x04);
461
/* addme  addme.  addmeo  addmeo.  */
462
GEN_INT_ARITH1 (addme,  0x1F, 0x0A, 0x07);
463
/* addze  addze.  addzeo  addzeo.  */
464
GEN_INT_ARITH1 (addze,  0x1F, 0x0A, 0x06);
465
/* divw   divw.   divwo   divwo.   */
466
GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F);
467
/* divwu  divwu.  divwuo  divwuo.  */
468
GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E);
469
/* mulhw  mulhw.                   */
470
GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02);
471
/* mulhwu mulhwu.                  */
472
GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00);
473
/* mullw  mullw.  mullwo  mullwo.  */
474
GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07);
475
/* neg    neg.    nego    nego.    */
476
GEN_INT_ARITH1 (neg,    0x1F, 0x08, 0x03);
477
/* subf   subf.   subfo   subfo.   */
478
GEN_INT_ARITH2 (subf,   0x1F, 0x08, 0x01);
479
/* subfc  subfc.  subfco  subfco.  */
480
GEN_INT_ARITH2 (subfc,  0x1F, 0x08, 0x00);
481
/* subfe  subfe.  subfeo  subfeo.  */
482
GEN_INT_ARITH2 (subfe,  0x1F, 0x08, 0x04);
483
/* subfme subfme. subfmeo subfmeo. */
484
GEN_INT_ARITH1 (subfme, 0x1F, 0x08, 0x07);
485
/* subfze subfze. subfzeo subfzeo. */
486
GEN_INT_ARITH1 (subfze, 0x1F, 0x08, 0x06);
487
/* addi */
488
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
489
{
490
    target_long simm = SIMM(ctx->opcode);
491

    
492
    if (rA(ctx->opcode) == 0) {
493
        /* li case */
494
        gen_op_set_T0(simm);
495
    } else {
496
        gen_op_load_gpr_T0(rA(ctx->opcode));
497
        if (likely(simm != 0))
498
            gen_op_addi(simm);
499
    }
500
    gen_op_store_T0_gpr(rD(ctx->opcode));
501
}
502
/* addic */
503
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
504
{
505
    target_long simm = SIMM(ctx->opcode);
506

    
507
    gen_op_load_gpr_T0(rA(ctx->opcode));
508
    if (likely(simm != 0))
509
        gen_op_addic(SIMM(ctx->opcode));
510
    gen_op_store_T0_gpr(rD(ctx->opcode));
511
}
512
/* addic. */
513
GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
514
{
515
    target_long simm = SIMM(ctx->opcode);
516

    
517
    gen_op_load_gpr_T0(rA(ctx->opcode));
518
    if (likely(simm != 0))
519
        gen_op_addic(SIMM(ctx->opcode));
520
    gen_op_store_T0_gpr(rD(ctx->opcode));
521
    gen_set_Rc0(ctx);
522
}
523
/* addis */
524
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
525
{
526
    target_long simm = SIMM(ctx->opcode);
527

    
528
    if (rA(ctx->opcode) == 0) {
529
        /* lis case */
530
        gen_op_set_T0(simm << 16);
531
    } else {
532
        gen_op_load_gpr_T0(rA(ctx->opcode));
533
        if (likely(simm != 0))
534
            gen_op_addi(simm << 16);
535
    }
536
    gen_op_store_T0_gpr(rD(ctx->opcode));
537
}
538
/* mulli */
539
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
540
{
541
    gen_op_load_gpr_T0(rA(ctx->opcode));
542
    gen_op_mulli(SIMM(ctx->opcode));
543
    gen_op_store_T0_gpr(rD(ctx->opcode));
544
}
545
/* subfic */
546
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
547
{
548
    gen_op_load_gpr_T0(rA(ctx->opcode));
549
    gen_op_subfic(SIMM(ctx->opcode));
550
    gen_op_store_T0_gpr(rD(ctx->opcode));
551
}
552

    
553
/***                           Integer comparison                          ***/
554
#define GEN_CMP(name, opc)                                                    \
555
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, PPC_INTEGER)                   \
556
{                                                                             \
557
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
558
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
559
    gen_op_##name();                                                          \
560
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
561
}
562

    
563
/* cmp */
564
GEN_CMP(cmp, 0x00);
565
/* cmpi */
566
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
567
{
568
    gen_op_load_gpr_T0(rA(ctx->opcode));
569
    gen_op_cmpi(SIMM(ctx->opcode));
570
    gen_op_store_T0_crf(crfD(ctx->opcode));
571
}
572
/* cmpl */
573
GEN_CMP(cmpl, 0x01);
574
/* cmpli */
575
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
576
{
577
    gen_op_load_gpr_T0(rA(ctx->opcode));
578
    gen_op_cmpli(UIMM(ctx->opcode));
579
    gen_op_store_T0_crf(crfD(ctx->opcode));
580
}
581

    
582
/***                            Integer logical                            ***/
583
#define __GEN_LOGICAL2(name, opc2, opc3)                                      \
584
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, PPC_INTEGER)                  \
585
{                                                                             \
586
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
587
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
588
    gen_op_##name();                                                          \
589
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
590
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
591
        gen_set_Rc0(ctx);                                                     \
592
}
593
#define GEN_LOGICAL2(name, opc)                                               \
594
__GEN_LOGICAL2(name, 0x1C, opc)
595

    
596
#define GEN_LOGICAL1(name, opc)                                               \
597
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, PPC_INTEGER)                   \
598
{                                                                             \
599
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
600
    gen_op_##name();                                                          \
601
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
602
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
603
        gen_set_Rc0(ctx);                                                     \
604
}
605

    
606
/* and & and. */
607
GEN_LOGICAL2(and, 0x00);
608
/* andc & andc. */
609
GEN_LOGICAL2(andc, 0x01);
610
/* andi. */
611
GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
612
{
613
    gen_op_load_gpr_T0(rS(ctx->opcode));
614
    gen_op_andi_T0(UIMM(ctx->opcode));
615
    gen_op_store_T0_gpr(rA(ctx->opcode));
616
    gen_set_Rc0(ctx);
617
}
618
/* andis. */
619
GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
620
{
621
    gen_op_load_gpr_T0(rS(ctx->opcode));
622
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
623
    gen_op_store_T0_gpr(rA(ctx->opcode));
624
    gen_set_Rc0(ctx);
625
}
626

    
627
/* cntlzw */
628
GEN_LOGICAL1(cntlzw, 0x00);
629
/* eqv & eqv. */
630
GEN_LOGICAL2(eqv, 0x08);
631
/* extsb & extsb. */
632
GEN_LOGICAL1(extsb, 0x1D);
633
/* extsh & extsh. */
634
GEN_LOGICAL1(extsh, 0x1C);
635
/* nand & nand. */
636
GEN_LOGICAL2(nand, 0x0E);
637
/* nor & nor. */
638
GEN_LOGICAL2(nor, 0x03);
639

    
640
/* or & or. */
641
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
642
{
643
    int rs, ra, rb;
644

    
645
    rs = rS(ctx->opcode);
646
    ra = rA(ctx->opcode);
647
    rb = rB(ctx->opcode);
648
    /* Optimisation for mr. ri case */
649
    if (rs != ra || rs != rb) {
650
        gen_op_load_gpr_T0(rs);
651
        if (rs != rb) {
652
            gen_op_load_gpr_T1(rb);
653
            gen_op_or();
654
        }
655
        gen_op_store_T0_gpr(ra);
656
        if (unlikely(Rc(ctx->opcode) != 0))
657
            gen_set_Rc0(ctx);
658
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
659
        gen_op_load_gpr_T0(rs);
660
        gen_set_Rc0(ctx);
661
    }
662
}
663

    
664
/* orc & orc. */
665
GEN_LOGICAL2(orc, 0x0C);
666
/* xor & xor. */
667
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
668
{
669
    gen_op_load_gpr_T0(rS(ctx->opcode));
670
    /* Optimisation for "set to zero" case */
671
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
672
        gen_op_load_gpr_T1(rB(ctx->opcode));
673
        gen_op_xor();
674
    } else {
675
        gen_op_reset_T0();
676
    }
677
    gen_op_store_T0_gpr(rA(ctx->opcode));
678
    if (unlikely(Rc(ctx->opcode) != 0))
679
        gen_set_Rc0(ctx);
680
}
681
/* ori */
682
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
683
{
684
    target_ulong uimm = UIMM(ctx->opcode);
685

    
686
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
687
        /* NOP */
688
        /* XXX: should handle special NOPs for POWER series */
689
        return;
690
    }
691
    gen_op_load_gpr_T0(rS(ctx->opcode));
692
    if (likely(uimm != 0))
693
        gen_op_ori(uimm);
694
    gen_op_store_T0_gpr(rA(ctx->opcode));
695
}
696
/* oris */
697
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
698
{
699
    target_ulong uimm = UIMM(ctx->opcode);
700

    
701
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
702
        /* NOP */
703
        return;
704
    }
705
    gen_op_load_gpr_T0(rS(ctx->opcode));
706
    if (likely(uimm != 0))
707
        gen_op_ori(uimm << 16);
708
    gen_op_store_T0_gpr(rA(ctx->opcode));
709
}
710
/* xori */
711
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
712
{
713
    target_ulong uimm = UIMM(ctx->opcode);
714

    
715
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
716
        /* NOP */
717
        return;
718
    }
719
    gen_op_load_gpr_T0(rS(ctx->opcode));
720
    if (likely(uimm != 0))
721
        gen_op_xori(uimm);
722
    gen_op_store_T0_gpr(rA(ctx->opcode));
723
}
724

    
725
/* xoris */
726
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
727
{
728
    target_ulong uimm = UIMM(ctx->opcode);
729

    
730
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
731
        /* NOP */
732
        return;
733
    }
734
    gen_op_load_gpr_T0(rS(ctx->opcode));
735
    if (likely(uimm != 0))
736
        gen_op_xori(uimm << 16);
737
    gen_op_store_T0_gpr(rA(ctx->opcode));
738
}
739

    
740
/***                             Integer rotate                            ***/
741
/* rlwimi & rlwimi. */
742
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
743
{
744
    target_ulong mask;
745
    uint32_t mb, me, sh;
746
    int n;
747

    
748
    mb = MB(ctx->opcode);
749
    me = ME(ctx->opcode);
750
    sh = SH(ctx->opcode);
751
    n = me + 1 - mb;
752
    if (likely(sh == 0)) {
753
        if (likely(mb == 0 && me == 31)) {
754
            gen_op_load_gpr_T0(rS(ctx->opcode));
755
            goto do_store;
756
        } else if (likely(mb == 31 && me == 0)) {
757
            gen_op_load_gpr_T0(rA(ctx->opcode));
758
            goto do_store;
759
        }
760
        gen_op_load_gpr_T0(rS(ctx->opcode));
761
        gen_op_load_gpr_T1(rA(ctx->opcode));
762
        goto do_mask;
763
    }
764
    gen_op_load_gpr_T0(rS(ctx->opcode));
765
    gen_op_load_gpr_T1(rA(ctx->opcode));
766
    gen_op_rotli32_T0(SH(ctx->opcode));
767
 do_mask:
768
#if defined(TARGET_PPC64)
769
    mb += 32;
770
    me += 32;
771
#endif
772
    mask = MASK(mb, me);
773
    gen_op_andi_T0(mask);
774
    gen_op_andi_T1(~mask);
775
    gen_op_or();
776
 do_store:
777
    gen_op_store_T0_gpr(rA(ctx->opcode));
778
    if (unlikely(Rc(ctx->opcode) != 0))
779
        gen_set_Rc0(ctx);
780
}
781
/* rlwinm & rlwinm. */
782
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
783
{
784
    uint32_t mb, me, sh;
785
    
786
    sh = SH(ctx->opcode);
787
    mb = MB(ctx->opcode);
788
    me = ME(ctx->opcode);
789
    gen_op_load_gpr_T0(rS(ctx->opcode));
790
    if (likely(sh == 0)) {
791
        goto do_mask;
792
    }
793
    if (likely(mb == 0)) {
794
        if (likely(me == 31)) {
795
            gen_op_rotli32_T0(sh);
796
            goto do_store;
797
        } else if (likely(me == (31 - sh))) {
798
            gen_op_sli_T0(sh);
799
            goto do_store;
800
        }
801
    } else if (likely(me == 31)) {
802
        if (likely(sh == (32 - mb))) {
803
            gen_op_srli_T0(mb);
804
            goto do_store;
805
        }
806
    }
807
    gen_op_rotli32_T0(sh);
808
 do_mask:
809
#if defined(TARGET_PPC64)
810
    mb += 32;
811
    me += 32;
812
#endif
813
    gen_op_andi_T0(MASK(mb, me));
814
 do_store:
815
    gen_op_store_T0_gpr(rA(ctx->opcode));
816
    if (unlikely(Rc(ctx->opcode) != 0))
817
        gen_set_Rc0(ctx);
818
}
819
/* rlwnm & rlwnm. */
820
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
821
{
822
    uint32_t mb, me;
823

    
824
    mb = MB(ctx->opcode);
825
    me = ME(ctx->opcode);
826
    gen_op_load_gpr_T0(rS(ctx->opcode));
827
    gen_op_load_gpr_T1(rB(ctx->opcode));
828
    gen_op_rotl32_T0_T1();
829
    if (unlikely(mb != 0 || me != 31)) {
830
#if defined(TARGET_PPC64)
831
        mb += 32;
832
        me += 32;
833
#endif
834
        gen_op_andi_T0(MASK(mb, me));
835
    }
836
    gen_op_store_T0_gpr(rA(ctx->opcode));
837
    if (unlikely(Rc(ctx->opcode) != 0))
838
        gen_set_Rc0(ctx);
839
}
840

    
841
/***                             Integer shift                             ***/
842
/* slw & slw. */
843
__GEN_LOGICAL2(slw, 0x18, 0x00);
844
/* sraw & sraw. */
845
__GEN_LOGICAL2(sraw, 0x18, 0x18);
846
/* srawi & srawi. */
847
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
848
{
849
    gen_op_load_gpr_T0(rS(ctx->opcode));
850
    if (SH(ctx->opcode) != 0)
851
        gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
852
    gen_op_store_T0_gpr(rA(ctx->opcode));
853
    if (unlikely(Rc(ctx->opcode) != 0))
854
        gen_set_Rc0(ctx);
855
}
856
/* srw & srw. */
857
__GEN_LOGICAL2(srw, 0x18, 0x10);
858

    
859
/***                       Floating-Point arithmetic                       ***/
860
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat)                           \
861
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT)                   \
862
{                                                                             \
863
    if (unlikely(!ctx->fpu_enabled)) {                                        \
864
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
865
        return;                                                               \
866
    }                                                                         \
867
    gen_op_reset_scrfx();                                                     \
868
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
869
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
870
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
871
    gen_op_f##op();                                                           \
872
    if (isfloat) {                                                            \
873
        gen_op_frsp();                                                        \
874
    }                                                                         \
875
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
876
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
877
        gen_op_set_Rc1();                                                     \
878
}
879

    
880
#define GEN_FLOAT_ACB(name, op2)                                              \
881
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0);                                     \
882
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
883

    
884
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
885
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
886
{                                                                             \
887
    if (unlikely(!ctx->fpu_enabled)) {                                        \
888
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
889
        return;                                                               \
890
    }                                                                         \
891
    gen_op_reset_scrfx();                                                     \
892
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
893
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
894
    gen_op_f##op();                                                           \
895
    if (isfloat) {                                                            \
896
        gen_op_frsp();                                                        \
897
    }                                                                         \
898
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
899
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
900
        gen_op_set_Rc1();                                                     \
901
}
902
#define GEN_FLOAT_AB(name, op2, inval)                                        \
903
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
904
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
905

    
906
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
907
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
908
{                                                                             \
909
    if (unlikely(!ctx->fpu_enabled)) {                                        \
910
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
911
        return;                                                               \
912
    }                                                                         \
913
    gen_op_reset_scrfx();                                                     \
914
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
915
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
916
    gen_op_f##op();                                                           \
917
    if (isfloat) {                                                            \
918
        gen_op_frsp();                                                        \
919
    }                                                                         \
920
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
921
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
922
        gen_op_set_Rc1();                                                     \
923
}
924
#define GEN_FLOAT_AC(name, op2, inval)                                        \
925
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
926
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
927

    
928
#define GEN_FLOAT_B(name, op2, op3)                                           \
929
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT)                   \
930
{                                                                             \
931
    if (unlikely(!ctx->fpu_enabled)) {                                        \
932
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
933
        return;                                                               \
934
    }                                                                         \
935
    gen_op_reset_scrfx();                                                     \
936
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
937
    gen_op_f##name();                                                         \
938
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
939
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
940
        gen_op_set_Rc1();                                                     \
941
}
942

    
943
#define GEN_FLOAT_BS(name, op1, op2)                                          \
944
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT)                   \
945
{                                                                             \
946
    if (unlikely(!ctx->fpu_enabled)) {                                        \
947
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
948
        return;                                                               \
949
    }                                                                         \
950
    gen_op_reset_scrfx();                                                     \
951
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
952
    gen_op_f##name();                                                         \
953
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
954
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
955
        gen_op_set_Rc1();                                                     \
956
}
957

    
958
/* fadd - fadds */
959
GEN_FLOAT_AB(add, 0x15, 0x000007C0);
960
/* fdiv - fdivs */
961
GEN_FLOAT_AB(div, 0x12, 0x000007C0);
962
/* fmul - fmuls */
963
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
964

    
965
/* fres */ /* XXX: not in 601 */
966
GEN_FLOAT_BS(res, 0x3B, 0x18);
967

    
968
/* frsqrte */ /* XXX: not in 601 */
969
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
970

    
971
/* fsel */ /* XXX: not in 601 */
972
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0);
973
/* fsub - fsubs */
974
GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
975
/* Optional: */
976
/* fsqrt */
977
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
978
{
979
    if (unlikely(!ctx->fpu_enabled)) {
980
        RET_EXCP(ctx, EXCP_NO_FP, 0);
981
        return;
982
    }
983
    gen_op_reset_scrfx();
984
    gen_op_load_fpr_FT0(rB(ctx->opcode));
985
    gen_op_fsqrt();
986
    gen_op_store_FT0_fpr(rD(ctx->opcode));
987
    if (unlikely(Rc(ctx->opcode) != 0))
988
        gen_op_set_Rc1();
989
}
990

    
991
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
992
{
993
    if (unlikely(!ctx->fpu_enabled)) {
994
        RET_EXCP(ctx, EXCP_NO_FP, 0);
995
        return;
996
    }
997
    gen_op_reset_scrfx();
998
    gen_op_load_fpr_FT0(rB(ctx->opcode));
999
    gen_op_fsqrt();
1000
    gen_op_frsp();
1001
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1002
    if (unlikely(Rc(ctx->opcode) != 0))
1003
        gen_op_set_Rc1();
1004
}
1005

    
1006
/***                     Floating-Point multiply-and-add                   ***/
1007
/* fmadd - fmadds */
1008
GEN_FLOAT_ACB(madd, 0x1D);
1009
/* fmsub - fmsubs */
1010
GEN_FLOAT_ACB(msub, 0x1C);
1011
/* fnmadd - fnmadds */
1012
GEN_FLOAT_ACB(nmadd, 0x1F);
1013
/* fnmsub - fnmsubs */
1014
GEN_FLOAT_ACB(nmsub, 0x1E);
1015

    
1016
/***                     Floating-Point round & convert                    ***/
1017
/* fctiw */
1018
GEN_FLOAT_B(ctiw, 0x0E, 0x00);
1019
/* fctiwz */
1020
GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
1021
/* frsp */
1022
GEN_FLOAT_B(rsp, 0x0C, 0x00);
1023

    
1024
/***                         Floating-Point compare                        ***/
1025
/* fcmpo */
1026
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1027
{
1028
    if (unlikely(!ctx->fpu_enabled)) {
1029
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1030
        return;
1031
    }
1032
    gen_op_reset_scrfx();
1033
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1034
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1035
    gen_op_fcmpo();
1036
    gen_op_store_T0_crf(crfD(ctx->opcode));
1037
}
1038

    
1039
/* fcmpu */
1040
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1041
{
1042
    if (unlikely(!ctx->fpu_enabled)) {
1043
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1044
        return;
1045
    }
1046
    gen_op_reset_scrfx();
1047
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1048
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1049
    gen_op_fcmpu();
1050
    gen_op_store_T0_crf(crfD(ctx->opcode));
1051
}
1052

    
1053
/***                         Floating-point move                           ***/
1054
/* fabs */
1055
GEN_FLOAT_B(abs, 0x08, 0x08);
1056

    
1057
/* fmr  - fmr. */
1058
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1059
{
1060
    if (unlikely(!ctx->fpu_enabled)) {
1061
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1062
        return;
1063
    }
1064
    gen_op_reset_scrfx();
1065
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1066
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1067
    if (unlikely(Rc(ctx->opcode) != 0))
1068
        gen_op_set_Rc1();
1069
}
1070

    
1071
/* fnabs */
1072
GEN_FLOAT_B(nabs, 0x08, 0x04);
1073
/* fneg */
1074
GEN_FLOAT_B(neg, 0x08, 0x01);
1075

    
1076
/***                  Floating-Point status & ctrl register                ***/
1077
/* mcrfs */
1078
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1079
{
1080
    if (unlikely(!ctx->fpu_enabled)) {
1081
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1082
        return;
1083
    }
1084
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
1085
    gen_op_store_T0_crf(crfD(ctx->opcode));
1086
    gen_op_clear_fpscr(crfS(ctx->opcode));
1087
}
1088

    
1089
/* mffs */
1090
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1091
{
1092
    if (unlikely(!ctx->fpu_enabled)) {
1093
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1094
        return;
1095
    }
1096
    gen_op_load_fpscr();
1097
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1098
    if (unlikely(Rc(ctx->opcode) != 0))
1099
        gen_op_set_Rc1();
1100
}
1101

    
1102
/* mtfsb0 */
1103
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1104
{
1105
    uint8_t crb;
1106
    
1107
    if (unlikely(!ctx->fpu_enabled)) {
1108
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1109
        return;
1110
    }
1111
    crb = crbD(ctx->opcode) >> 2;
1112
    gen_op_load_fpscr_T0(crb);
1113
    gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1114
    gen_op_store_T0_fpscr(crb);
1115
    if (unlikely(Rc(ctx->opcode) != 0))
1116
        gen_op_set_Rc1();
1117
}
1118

    
1119
/* mtfsb1 */
1120
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1121
{
1122
    uint8_t crb;
1123
    
1124
    if (unlikely(!ctx->fpu_enabled)) {
1125
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1126
        return;
1127
    }
1128
    crb = crbD(ctx->opcode) >> 2;
1129
    gen_op_load_fpscr_T0(crb);
1130
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1131
    gen_op_store_T0_fpscr(crb);
1132
    if (unlikely(Rc(ctx->opcode) != 0))
1133
        gen_op_set_Rc1();
1134
}
1135

    
1136
/* mtfsf */
1137
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1138
{
1139
    if (unlikely(!ctx->fpu_enabled)) {
1140
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1141
        return;
1142
    }
1143
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1144
    gen_op_store_fpscr(FM(ctx->opcode));
1145
    if (unlikely(Rc(ctx->opcode) != 0))
1146
        gen_op_set_Rc1();
1147
}
1148

    
1149
/* mtfsfi */
1150
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1151
{
1152
    if (unlikely(!ctx->fpu_enabled)) {
1153
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1154
        return;
1155
    }
1156
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1157
    if (unlikely(Rc(ctx->opcode) != 0))
1158
        gen_op_set_Rc1();
1159
}
1160

    
1161
/***                           Addressing modes                            ***/
1162
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1163
static inline void gen_addr_imm_index (DisasContext *ctx)
1164
{
1165
    target_long simm = SIMM(ctx->opcode);
1166

    
1167
    if (rA(ctx->opcode) == 0) {
1168
        gen_op_set_T0(simm);
1169
    } else {
1170
        gen_op_load_gpr_T0(rA(ctx->opcode));
1171
        if (likely(simm != 0))
1172
            gen_op_addi(simm);
1173
    }
1174
}
1175

    
1176
static inline void gen_addr_reg_index (DisasContext *ctx)
1177
{
1178
    if (rA(ctx->opcode) == 0) {
1179
        gen_op_load_gpr_T0(rB(ctx->opcode));
1180
    } else {
1181
        gen_op_load_gpr_T0(rA(ctx->opcode));
1182
        gen_op_load_gpr_T1(rB(ctx->opcode));
1183
        gen_op_add();
1184
    }
1185
}
1186

    
1187
static inline void gen_addr_register (DisasContext *ctx)
1188
{
1189
    if (rA(ctx->opcode) == 0) {
1190
        gen_op_reset_T0();
1191
    } else {
1192
        gen_op_load_gpr_T0(rA(ctx->opcode));
1193
    }
1194
}
1195

    
1196
/***                             Integer load                              ***/
1197
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1198
#if defined(CONFIG_USER_ONLY)
1199
#define OP_LD_TABLE(width)                                                    \
1200
static GenOpFunc *gen_op_l##width[] = {                                       \
1201
    &gen_op_l##width##_raw,                                                   \
1202
    &gen_op_l##width##_le_raw,                                                \
1203
};
1204
#define OP_ST_TABLE(width)                                                    \
1205
static GenOpFunc *gen_op_st##width[] = {                                      \
1206
    &gen_op_st##width##_raw,                                                  \
1207
    &gen_op_st##width##_le_raw,                                               \
1208
};
1209
/* Byte access routine are endian safe */
1210
#define gen_op_stb_le_raw gen_op_stb_raw
1211
#define gen_op_lbz_le_raw gen_op_lbz_raw
1212
#else
1213
#define OP_LD_TABLE(width)                                                    \
1214
static GenOpFunc *gen_op_l##width[] = {                                       \
1215
    &gen_op_l##width##_user,                                                  \
1216
    &gen_op_l##width##_le_user,                                               \
1217
    &gen_op_l##width##_kernel,                                                \
1218
    &gen_op_l##width##_le_kernel,                                             \
1219
};
1220
#define OP_ST_TABLE(width)                                                    \
1221
static GenOpFunc *gen_op_st##width[] = {                                      \
1222
    &gen_op_st##width##_user,                                                 \
1223
    &gen_op_st##width##_le_user,                                              \
1224
    &gen_op_st##width##_kernel,                                               \
1225
    &gen_op_st##width##_le_kernel,                                            \
1226
};
1227
/* Byte access routine are endian safe */
1228
#define gen_op_stb_le_user gen_op_stb_user
1229
#define gen_op_lbz_le_user gen_op_lbz_user
1230
#define gen_op_stb_le_kernel gen_op_stb_kernel
1231
#define gen_op_lbz_le_kernel gen_op_lbz_kernel
1232
#endif
1233

    
1234
#define GEN_LD(width, opc)                                                    \
1235
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)               \
1236
{                                                                             \
1237
    gen_addr_imm_index(ctx);                                                  \
1238
    op_ldst(l##width);                                                        \
1239
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1240
}
1241

    
1242
#define GEN_LDU(width, opc)                                                   \
1243
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)            \
1244
{                                                                             \
1245
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1246
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1247
        RET_INVAL(ctx);                                                       \
1248
        return;                                                               \
1249
    }                                                                         \
1250
    gen_addr_imm_index(ctx);                                                  \
1251
    op_ldst(l##width);                                                        \
1252
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1253
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1254
}
1255

    
1256
#define GEN_LDUX(width, opc)                                                  \
1257
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)           \
1258
{                                                                             \
1259
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
1260
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1261
        RET_INVAL(ctx);                                                       \
1262
        return;                                                               \
1263
    }                                                                         \
1264
    gen_addr_reg_index(ctx);                                                  \
1265
    op_ldst(l##width);                                                        \
1266
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1267
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1268
}
1269

    
1270
#define GEN_LDX(width, opc2, opc3)                                            \
1271
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)           \
1272
{                                                                             \
1273
    gen_addr_reg_index(ctx);                                                  \
1274
    op_ldst(l##width);                                                        \
1275
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1276
}
1277

    
1278
#define GEN_LDS(width, op)                                                    \
1279
OP_LD_TABLE(width);                                                           \
1280
GEN_LD(width, op | 0x20);                                                     \
1281
GEN_LDU(width, op | 0x21);                                                    \
1282
GEN_LDUX(width, op | 0x01);                                                   \
1283
GEN_LDX(width, 0x17, op | 0x00)
1284

    
1285
/* lbz lbzu lbzux lbzx */
1286
GEN_LDS(bz, 0x02);
1287
/* lha lhau lhaux lhax */
1288
GEN_LDS(ha, 0x0A);
1289
/* lhz lhzu lhzux lhzx */
1290
GEN_LDS(hz, 0x08);
1291
/* lwz lwzu lwzux lwzx */
1292
GEN_LDS(wz, 0x00);
1293

    
1294
/***                              Integer store                            ***/
1295
#define GEN_ST(width, opc)                                                    \
1296
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)              \
1297
{                                                                             \
1298
    gen_addr_imm_index(ctx);                                                  \
1299
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1300
    op_ldst(st##width);                                                       \
1301
}
1302

    
1303
#define GEN_STU(width, opc)                                                   \
1304
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)           \
1305
{                                                                             \
1306
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1307
        RET_INVAL(ctx);                                                       \
1308
        return;                                                               \
1309
    }                                                                         \
1310
    gen_addr_imm_index(ctx);                                                  \
1311
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1312
    op_ldst(st##width);                                                       \
1313
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1314
}
1315

    
1316
#define GEN_STUX(width, opc)                                                  \
1317
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
1318
{                                                                             \
1319
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1320
        RET_INVAL(ctx);                                                       \
1321
        return;                                                               \
1322
    }                                                                         \
1323
    gen_addr_reg_index(ctx);                                                  \
1324
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1325
    op_ldst(st##width);                                                       \
1326
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1327
}
1328

    
1329
#define GEN_STX(width, opc2, opc3)                                            \
1330
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)          \
1331
{                                                                             \
1332
    gen_addr_reg_index(ctx);                                                  \
1333
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1334
    op_ldst(st##width);                                                       \
1335
}
1336

    
1337
#define GEN_STS(width, op)                                                    \
1338
OP_ST_TABLE(width);                                                           \
1339
GEN_ST(width, op | 0x20);                                                     \
1340
GEN_STU(width, op | 0x21);                                                    \
1341
GEN_STUX(width, op | 0x01);                                                   \
1342
GEN_STX(width, 0x17, op | 0x00)
1343

    
1344
/* stb stbu stbux stbx */
1345
GEN_STS(b, 0x06);
1346
/* sth sthu sthux sthx */
1347
GEN_STS(h, 0x0C);
1348
/* stw stwu stwux stwx */
1349
GEN_STS(w, 0x04);
1350

    
1351
/***                Integer load and store with byte reverse               ***/
1352
/* lhbrx */
1353
OP_LD_TABLE(hbr);
1354
GEN_LDX(hbr, 0x16, 0x18);
1355
/* lwbrx */
1356
OP_LD_TABLE(wbr);
1357
GEN_LDX(wbr, 0x16, 0x10);
1358
/* sthbrx */
1359
OP_ST_TABLE(hbr);
1360
GEN_STX(hbr, 0x16, 0x1C);
1361
/* stwbrx */
1362
OP_ST_TABLE(wbr);
1363
GEN_STX(wbr, 0x16, 0x14);
1364

    
1365
/***                    Integer load and store multiple                    ***/
1366
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
1367
#if defined(CONFIG_USER_ONLY)
1368
static GenOpFunc1 *gen_op_lmw[] = {
1369
    &gen_op_lmw_raw,
1370
    &gen_op_lmw_le_raw,
1371
};
1372
static GenOpFunc1 *gen_op_stmw[] = {
1373
    &gen_op_stmw_raw,
1374
    &gen_op_stmw_le_raw,
1375
};
1376
#else
1377
static GenOpFunc1 *gen_op_lmw[] = {
1378
    &gen_op_lmw_user,
1379
    &gen_op_lmw_le_user,
1380
    &gen_op_lmw_kernel,
1381
    &gen_op_lmw_le_kernel,
1382
};
1383
static GenOpFunc1 *gen_op_stmw[] = {
1384
    &gen_op_stmw_user,
1385
    &gen_op_stmw_le_user,
1386
    &gen_op_stmw_kernel,
1387
    &gen_op_stmw_le_kernel,
1388
};
1389
#endif
1390

    
1391
/* lmw */
1392
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1393
{
1394
    /* NIP cannot be restored if the memory exception comes from an helper */
1395
    gen_op_update_nip(ctx->nip - 4);
1396
    gen_addr_imm_index(ctx);
1397
    op_ldstm(lmw, rD(ctx->opcode));
1398
}
1399

    
1400
/* stmw */
1401
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1402
{
1403
    /* NIP cannot be restored if the memory exception comes from an helper */
1404
    gen_op_update_nip(ctx->nip - 4);
1405
    gen_addr_imm_index(ctx);
1406
    op_ldstm(stmw, rS(ctx->opcode));
1407
}
1408

    
1409
/***                    Integer load and store strings                     ***/
1410
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
1411
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
1412
#if defined(CONFIG_USER_ONLY)
1413
static GenOpFunc1 *gen_op_lswi[] = {
1414
    &gen_op_lswi_raw,
1415
    &gen_op_lswi_le_raw,
1416
};
1417
static GenOpFunc3 *gen_op_lswx[] = {
1418
    &gen_op_lswx_raw,
1419
    &gen_op_lswx_le_raw,
1420
};
1421
static GenOpFunc1 *gen_op_stsw[] = {
1422
    &gen_op_stsw_raw,
1423
    &gen_op_stsw_le_raw,
1424
};
1425
#else
1426
static GenOpFunc1 *gen_op_lswi[] = {
1427
    &gen_op_lswi_user,
1428
    &gen_op_lswi_le_user,
1429
    &gen_op_lswi_kernel,
1430
    &gen_op_lswi_le_kernel,
1431
};
1432
static GenOpFunc3 *gen_op_lswx[] = {
1433
    &gen_op_lswx_user,
1434
    &gen_op_lswx_le_user,
1435
    &gen_op_lswx_kernel,
1436
    &gen_op_lswx_le_kernel,
1437
};
1438
static GenOpFunc1 *gen_op_stsw[] = {
1439
    &gen_op_stsw_user,
1440
    &gen_op_stsw_le_user,
1441
    &gen_op_stsw_kernel,
1442
    &gen_op_stsw_le_kernel,
1443
};
1444
#endif
1445

    
1446
/* lswi */
1447
/* PowerPC32 specification says we must generate an exception if
1448
 * rA is in the range of registers to be loaded.
1449
 * In an other hand, IBM says this is valid, but rA won't be loaded.
1450
 * For now, I'll follow the spec...
1451
 */
1452
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
1453
{
1454
    int nb = NB(ctx->opcode);
1455
    int start = rD(ctx->opcode);
1456
    int ra = rA(ctx->opcode);
1457
    int nr;
1458

    
1459
    if (nb == 0)
1460
        nb = 32;
1461
    nr = nb / 4;
1462
    if (unlikely(((start + nr) > 32  &&
1463
                  start <= ra && (start + nr - 32) > ra) ||
1464
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
1465
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
1466
        return;
1467
    }
1468
    /* NIP cannot be restored if the memory exception comes from an helper */
1469
    gen_op_update_nip(ctx->nip - 4);
1470
    gen_addr_register(ctx);
1471
    gen_op_set_T1(nb);
1472
    op_ldsts(lswi, start);
1473
}
1474

    
1475
/* lswx */
1476
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
1477
{
1478
    int ra = rA(ctx->opcode);
1479
    int rb = rB(ctx->opcode);
1480

    
1481
    /* NIP cannot be restored if the memory exception comes from an helper */
1482
    gen_op_update_nip(ctx->nip - 4);
1483
    gen_addr_reg_index(ctx);
1484
    if (ra == 0) {
1485
        ra = rb;
1486
    }
1487
    gen_op_load_xer_bc();
1488
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
1489
}
1490

    
1491
/* stswi */
1492
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
1493
{
1494
    int nb = NB(ctx->opcode);
1495

    
1496
    /* NIP cannot be restored if the memory exception comes from an helper */
1497
    gen_op_update_nip(ctx->nip - 4);
1498
    gen_addr_register(ctx);
1499
    if (nb == 0)
1500
        nb = 32;
1501
    gen_op_set_T1(nb);
1502
    op_ldsts(stsw, rS(ctx->opcode));
1503
}
1504

    
1505
/* stswx */
1506
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
1507
{
1508
    /* NIP cannot be restored if the memory exception comes from an helper */
1509
    gen_op_update_nip(ctx->nip - 4); 
1510
    gen_addr_reg_index(ctx);
1511
    gen_op_load_xer_bc();
1512
    op_ldsts(stsw, rS(ctx->opcode));
1513
}
1514

    
1515
/***                        Memory synchronisation                         ***/
1516
/* eieio */
1517
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
1518
{
1519
}
1520

    
1521
/* isync */
1522
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
1523
{
1524
}
1525

    
1526
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
1527
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
1528
#if defined(CONFIG_USER_ONLY)
1529
static GenOpFunc *gen_op_lwarx[] = {
1530
    &gen_op_lwarx_raw,
1531
    &gen_op_lwarx_le_raw,
1532
};
1533
static GenOpFunc *gen_op_stwcx[] = {
1534
    &gen_op_stwcx_raw,
1535
    &gen_op_stwcx_le_raw,
1536
};
1537
#else
1538
static GenOpFunc *gen_op_lwarx[] = {
1539
    &gen_op_lwarx_user,
1540
    &gen_op_lwarx_le_user,
1541
    &gen_op_lwarx_kernel,
1542
    &gen_op_lwarx_le_kernel,
1543
};
1544
static GenOpFunc *gen_op_stwcx[] = {
1545
    &gen_op_stwcx_user,
1546
    &gen_op_stwcx_le_user,
1547
    &gen_op_stwcx_kernel,
1548
    &gen_op_stwcx_le_kernel,
1549
};
1550
#endif
1551

    
1552
/* lwarx */
1553
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
1554
{
1555
    gen_addr_reg_index(ctx);
1556
    op_lwarx();
1557
    gen_op_store_T1_gpr(rD(ctx->opcode));
1558
}
1559

    
1560
/* stwcx. */
1561
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
1562
{
1563
    gen_addr_reg_index(ctx);
1564
    gen_op_load_gpr_T1(rS(ctx->opcode));
1565
    op_stwcx();
1566
}
1567

    
1568
/* sync */
1569
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
1570
{
1571
}
1572

    
1573
/***                         Floating-point load                           ***/
1574
#define GEN_LDF(width, opc)                                                   \
1575
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                 \
1576
{                                                                             \
1577
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1578
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1579
        return;                                                               \
1580
    }                                                                         \
1581
    gen_addr_imm_index(ctx);                                                  \
1582
    op_ldst(l##width);                                                        \
1583
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1584
}
1585

    
1586
#define GEN_LDUF(width, opc)                                                  \
1587
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)              \
1588
{                                                                             \
1589
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1590
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1591
        return;                                                               \
1592
    }                                                                         \
1593
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1594
        RET_INVAL(ctx);                                                       \
1595
        return;                                                               \
1596
    }                                                                         \
1597
    gen_addr_imm_index(ctx);                                                  \
1598
    op_ldst(l##width);                                                        \
1599
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1600
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1601
}
1602

    
1603
#define GEN_LDUXF(width, opc)                                                 \
1604
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
1605
{                                                                             \
1606
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1607
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1608
        return;                                                               \
1609
    }                                                                         \
1610
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1611
        RET_INVAL(ctx);                                                       \
1612
        return;                                                               \
1613
    }                                                                         \
1614
    gen_addr_reg_index(ctx);                                                  \
1615
    op_ldst(l##width);                                                        \
1616
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1617
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1618
}
1619

    
1620
#define GEN_LDXF(width, opc2, opc3)                                           \
1621
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)             \
1622
{                                                                             \
1623
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1624
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1625
        return;                                                               \
1626
    }                                                                         \
1627
    gen_addr_reg_index(ctx);                                                  \
1628
    op_ldst(l##width);                                                        \
1629
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1630
}
1631

    
1632
#define GEN_LDFS(width, op)                                                   \
1633
OP_LD_TABLE(width);                                                           \
1634
GEN_LDF(width, op | 0x20);                                                    \
1635
GEN_LDUF(width, op | 0x21);                                                   \
1636
GEN_LDUXF(width, op | 0x01);                                                  \
1637
GEN_LDXF(width, 0x17, op | 0x00)
1638

    
1639
/* lfd lfdu lfdux lfdx */
1640
GEN_LDFS(fd, 0x12);
1641
/* lfs lfsu lfsux lfsx */
1642
GEN_LDFS(fs, 0x10);
1643

    
1644
/***                         Floating-point store                          ***/
1645
#define GEN_STF(width, opc)                                                   \
1646
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
1647
{                                                                             \
1648
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1649
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1650
        return;                                                               \
1651
    }                                                                         \
1652
    gen_addr_imm_index(ctx);                                                  \
1653
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1654
    op_ldst(st##width);                                                       \
1655
}
1656

    
1657
#define GEN_STUF(width, opc)                                                  \
1658
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
1659
{                                                                             \
1660
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1661
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1662
        return;                                                               \
1663
    }                                                                         \
1664
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1665
        RET_INVAL(ctx);                                                       \
1666
        return;                                                               \
1667
    }                                                                         \
1668
    gen_addr_imm_index(ctx);                                                  \
1669
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1670
    op_ldst(st##width);                                                       \
1671
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1672
}
1673

    
1674
#define GEN_STUXF(width, opc)                                                 \
1675
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
1676
{                                                                             \
1677
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1678
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1679
        return;                                                               \
1680
    }                                                                         \
1681
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1682
        RET_INVAL(ctx);                                                       \
1683
        return;                                                               \
1684
    }                                                                         \
1685
    gen_addr_reg_index(ctx);                                                  \
1686
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1687
    op_ldst(st##width);                                                       \
1688
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1689
}
1690

    
1691
#define GEN_STXF(width, opc2, opc3)                                           \
1692
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT)            \
1693
{                                                                             \
1694
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1695
        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1696
        return;                                                               \
1697
    }                                                                         \
1698
    gen_addr_reg_index(ctx);                                                  \
1699
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1700
    op_ldst(st##width);                                                       \
1701
}
1702

    
1703
#define GEN_STFS(width, op)                                                   \
1704
OP_ST_TABLE(width);                                                           \
1705
GEN_STF(width, op | 0x20);                                                    \
1706
GEN_STUF(width, op | 0x21);                                                   \
1707
GEN_STUXF(width, op | 0x01);                                                  \
1708
GEN_STXF(width, 0x17, op | 0x00)
1709

    
1710
/* stfd stfdu stfdux stfdx */
1711
GEN_STFS(fd, 0x16);
1712
/* stfs stfsu stfsux stfsx */
1713
GEN_STFS(fs, 0x14);
1714

    
1715
/* Optional: */
1716
/* stfiwx */
1717
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1718
{
1719
    if (unlikely(!ctx->fpu_enabled)) {
1720
        RET_EXCP(ctx, EXCP_NO_FP, 0);
1721
        return;
1722
    }
1723
    gen_addr_reg_index(ctx);
1724
    /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
1725
    RET_INVAL(ctx);
1726
}
1727

    
1728
/***                                Branch                                 ***/
1729

    
1730
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1731
{
1732
    TranslationBlock *tb;
1733
    tb = ctx->tb;
1734
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1735
        if (n == 0)
1736
            gen_op_goto_tb0(TBPARAM(tb));
1737
        else
1738
            gen_op_goto_tb1(TBPARAM(tb));
1739
        gen_op_set_T1(dest);
1740
        gen_op_b_T1();
1741
        gen_op_set_T0((long)tb + n);
1742
        if (ctx->singlestep_enabled)
1743
            gen_op_debug();
1744
        gen_op_exit_tb();
1745
    } else {
1746
        gen_op_set_T1(dest);
1747
        gen_op_b_T1();
1748
        gen_op_reset_T0();
1749
        if (ctx->singlestep_enabled)
1750
            gen_op_debug();
1751
        gen_op_exit_tb();
1752
    }
1753
}
1754

    
1755
/* b ba bl bla */
1756
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1757
{
1758
    target_ulong li, target;
1759

    
1760
    /* sign extend LI */
1761
#if defined(TARGET_PPC64)
1762
    li = ((target_long)LI(ctx->opcode) << 38) >> 38;
1763
#else
1764
    li = ((target_long)LI(ctx->opcode) << 6) >> 6;
1765
#endif
1766
    if (likely(AA(ctx->opcode) == 0))
1767
        target = ctx->nip + li - 4;
1768
    else
1769
        target = li;
1770
    if (LK(ctx->opcode)) {
1771
        gen_op_setlr(ctx->nip);
1772
    }
1773
    gen_goto_tb(ctx, 0, target);
1774
    ctx->exception = EXCP_BRANCH;
1775
}
1776

    
1777
#define BCOND_IM  0
1778
#define BCOND_LR  1
1779
#define BCOND_CTR 2
1780

    
1781
static inline void gen_bcond(DisasContext *ctx, int type) 
1782
{                                                                             
1783
    target_ulong target = 0;
1784
    target_ulong li;
1785
    uint32_t bo = BO(ctx->opcode);                                            
1786
    uint32_t bi = BI(ctx->opcode);                                            
1787
    uint32_t mask;                                                            
1788

    
1789
    if ((bo & 0x4) == 0)
1790
        gen_op_dec_ctr();                                                     
1791
    switch(type) {
1792
    case BCOND_IM:
1793
        li = (target_long)((int16_t)(BD(ctx->opcode)));
1794
        if (likely(AA(ctx->opcode) == 0)) {
1795
            target = ctx->nip + li - 4;
1796
        } else {
1797
            target = li;
1798
        }
1799
        break;
1800
    case BCOND_CTR:
1801
        gen_op_movl_T1_ctr();
1802
        break;
1803
    default:
1804
    case BCOND_LR:
1805
        gen_op_movl_T1_lr();
1806
        break;
1807
    }
1808
    if (LK(ctx->opcode)) {                                        
1809
        gen_op_setlr(ctx->nip);
1810
    }
1811
    if (bo & 0x10) {
1812
        /* No CR condition */                                                 
1813
        switch (bo & 0x6) {                                                   
1814
        case 0:                                                               
1815
            gen_op_test_ctr();
1816
            break;
1817
        case 2:                                                               
1818
            gen_op_test_ctrz();
1819
            break;                                                            
1820
        default:
1821
        case 4:                                                               
1822
        case 6:                                                               
1823
            if (type == BCOND_IM) {
1824
                gen_goto_tb(ctx, 0, target);
1825
            } else {
1826
                gen_op_b_T1();
1827
                gen_op_reset_T0();
1828
            }
1829
            goto no_test;
1830
        }
1831
    } else {                                                                  
1832
        mask = 1 << (3 - (bi & 0x03));                                        
1833
        gen_op_load_crf_T0(bi >> 2);                                          
1834
        if (bo & 0x8) {                                                       
1835
            switch (bo & 0x6) {                                               
1836
            case 0:                                                           
1837
                gen_op_test_ctr_true(mask);
1838
                break;                                                        
1839
            case 2:                                                           
1840
                gen_op_test_ctrz_true(mask);
1841
                break;                                                        
1842
            default:                                                          
1843
            case 4:                                                           
1844
            case 6:                                                           
1845
                gen_op_test_true(mask);
1846
                break;                                                        
1847
            }                                                                 
1848
        } else {                                                              
1849
            switch (bo & 0x6) {                                               
1850
            case 0:                                                           
1851
                gen_op_test_ctr_false(mask);
1852
                break;                                                        
1853
            case 2:                                                           
1854
                gen_op_test_ctrz_false(mask);
1855
                break;                                                        
1856
            default:
1857
            case 4:                                                           
1858
            case 6:                                                           
1859
                gen_op_test_false(mask);
1860
                break;                                                        
1861
            }                                                                 
1862
        }                                                                     
1863
    }                                                                         
1864
    if (type == BCOND_IM) {
1865
        int l1 = gen_new_label();
1866
        gen_op_jz_T0(l1);
1867
        gen_goto_tb(ctx, 0, target);
1868
        gen_set_label(l1);
1869
        gen_goto_tb(ctx, 1, ctx->nip);
1870
    } else {
1871
        gen_op_btest_T1(ctx->nip);
1872
        gen_op_reset_T0();
1873
    }
1874
 no_test:
1875
    if (ctx->singlestep_enabled)
1876
        gen_op_debug();
1877
    gen_op_exit_tb();
1878
    ctx->exception = EXCP_BRANCH;                                             
1879
}
1880

    
1881
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1882
{                                                                             
1883
    gen_bcond(ctx, BCOND_IM);
1884
}
1885

    
1886
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
1887
{                                                                             
1888
    gen_bcond(ctx, BCOND_CTR);
1889
}
1890

    
1891
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
1892
{                                                                             
1893
    gen_bcond(ctx, BCOND_LR);
1894
}
1895

    
1896
/***                      Condition register logical                       ***/
1897
#define GEN_CRLOGIC(op, opc)                                                  \
1898
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
1899
{                                                                             \
1900
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
1901
    gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
1902
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
1903
    gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
1904
    gen_op_##op();                                                            \
1905
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
1906
    gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
1907
                     3 - (crbD(ctx->opcode) & 0x03));                         \
1908
    gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
1909
}
1910

    
1911
/* crand */
1912
GEN_CRLOGIC(and, 0x08);
1913
/* crandc */
1914
GEN_CRLOGIC(andc, 0x04);
1915
/* creqv */
1916
GEN_CRLOGIC(eqv, 0x09);
1917
/* crnand */
1918
GEN_CRLOGIC(nand, 0x07);
1919
/* crnor */
1920
GEN_CRLOGIC(nor, 0x01);
1921
/* cror */
1922
GEN_CRLOGIC(or, 0x0E);
1923
/* crorc */
1924
GEN_CRLOGIC(orc, 0x0D);
1925
/* crxor */
1926
GEN_CRLOGIC(xor, 0x06);
1927
/* mcrf */
1928
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
1929
{
1930
    gen_op_load_crf_T0(crfS(ctx->opcode));
1931
    gen_op_store_T0_crf(crfD(ctx->opcode));
1932
}
1933

    
1934
/***                           System linkage                              ***/
1935
/* rfi (supervisor only) */
1936
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
1937
{
1938
#if defined(CONFIG_USER_ONLY)
1939
    RET_PRIVOPC(ctx);
1940
#else
1941
    /* Restore CPU state */
1942
    if (unlikely(!ctx->supervisor)) {
1943
        RET_PRIVOPC(ctx);
1944
        return;
1945
    }
1946
    gen_op_rfi();
1947
    RET_CHG_FLOW(ctx);
1948
#endif
1949
}
1950

    
1951
/* sc */
1952
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
1953
{
1954
#if defined(CONFIG_USER_ONLY)
1955
    RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
1956
#else
1957
    RET_EXCP(ctx, EXCP_SYSCALL, 0);
1958
#endif
1959
}
1960

    
1961
/***                                Trap                                   ***/
1962
/* tw */
1963
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
1964
{
1965
    gen_op_load_gpr_T0(rA(ctx->opcode));
1966
    gen_op_load_gpr_T1(rB(ctx->opcode));
1967
    /* Update the nip since this might generate a trap exception */
1968
    gen_op_update_nip(ctx->nip);
1969
    gen_op_tw(TO(ctx->opcode));
1970
}
1971

    
1972
/* twi */
1973
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1974
{
1975
    gen_op_load_gpr_T0(rA(ctx->opcode));
1976
    gen_op_set_T1(SIMM(ctx->opcode));
1977
    gen_op_tw(TO(ctx->opcode));
1978
}
1979

    
1980
/***                          Processor control                            ***/
1981
/* mcrxr */
1982
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
1983
{
1984
    gen_op_load_xer_cr();
1985
    gen_op_store_T0_crf(crfD(ctx->opcode));
1986
    gen_op_clear_xer_cr();
1987
}
1988

    
1989
/* mfcr */
1990
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
1991
{
1992
#if 0 // XXX: to be tested
1993
    uint32_t crm, crn;
1994
    
1995
    if (likely(ctx->opcode & 0x00100000)) {
1996
        crm = CRM(ctx->opcode);
1997
        if (likely((crm ^ (crm - 1)) == 0)) {
1998
            crn = ffs(crm);
1999
            gen_op_load_cro(7 - crn);
2000
        }
2001
    } else
2002
#endif
2003
        {
2004
            gen_op_load_cr();
2005
        }
2006
    gen_op_store_T0_gpr(rD(ctx->opcode));
2007
}
2008

    
2009
/* mfmsr */
2010
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
2011
{
2012
#if defined(CONFIG_USER_ONLY)
2013
    RET_PRIVREG(ctx);
2014
#else
2015
    if (unlikely(!ctx->supervisor)) {
2016
        RET_PRIVREG(ctx);
2017
        return;
2018
    }
2019
    gen_op_load_msr();
2020
    gen_op_store_T0_gpr(rD(ctx->opcode));
2021
#endif
2022
}
2023

    
2024
#if 0
2025
#define SPR_NOACCESS ((void *)(-1))
2026
#else
2027
static void spr_noaccess (void *opaque, int sprn)
2028
{
2029
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
2030
    printf("ERROR: try to access SPR %d !\n", sprn);
2031
}
2032
#define SPR_NOACCESS (&spr_noaccess)
2033
#endif
2034

    
2035
/* mfspr */
2036
static inline void gen_op_mfspr (DisasContext *ctx)
2037
{
2038
    void (*read_cb)(void *opaque, int sprn);
2039
    uint32_t sprn = SPR(ctx->opcode);
2040

    
2041
#if !defined(CONFIG_USER_ONLY)
2042
    if (ctx->supervisor)
2043
        read_cb = ctx->spr_cb[sprn].oea_read;
2044
    else
2045
#endif
2046
        read_cb = ctx->spr_cb[sprn].uea_read;
2047
    if (likely(read_cb != NULL)) {
2048
        if (likely(read_cb != SPR_NOACCESS)) {
2049
            (*read_cb)(ctx, sprn);
2050
            gen_op_store_T0_gpr(rD(ctx->opcode));
2051
        } else {
2052
            /* Privilege exception */
2053
            if (loglevel) {
2054
                fprintf(logfile, "Trying to read priviledged spr %d %03x\n",
2055
                        sprn, sprn);
2056
            }
2057
            printf("Trying to read priviledged spr %d %03x\n", sprn, sprn);
2058
            RET_PRIVREG(ctx);
2059
        }
2060
    } else {
2061
        /* Not defined */
2062
        if (loglevel) {
2063
            fprintf(logfile, "Trying to read invalid spr %d %03x\n",
2064
                    sprn, sprn);
2065
        }
2066
        printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
2067
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2068
    }
2069
}
2070

    
2071
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
2072
{
2073
    gen_op_mfspr(ctx);
2074
}
2075

    
2076
/* mftb */
2077
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB)
2078
{
2079
    gen_op_mfspr(ctx);
2080
}
2081

    
2082
/* mtcrf */
2083
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
2084
{
2085
    uint32_t crm, crn;
2086
    
2087
    gen_op_load_gpr_T0(rS(ctx->opcode));
2088
    crm = CRM(ctx->opcode);
2089
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
2090
        crn = ffs(crm);
2091
        gen_op_srli_T0(crn * 4);
2092
        gen_op_andi_T0(0xF);
2093
        gen_op_store_cro(7 - crn);
2094
    } else {
2095
        gen_op_store_cr(crm);
2096
    }
2097
}
2098

    
2099
/* mtmsr */
2100
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
2101
{
2102
#if defined(CONFIG_USER_ONLY)
2103
    RET_PRIVREG(ctx);
2104
#else
2105
    if (unlikely(!ctx->supervisor)) {
2106
        RET_PRIVREG(ctx);
2107
        return;
2108
    }
2109
    gen_op_update_nip((ctx)->nip);
2110
    gen_op_load_gpr_T0(rS(ctx->opcode));
2111
    gen_op_store_msr();
2112
    /* Must stop the translation as machine state (may have) changed */
2113
    RET_CHG_FLOW(ctx);
2114
#endif
2115
}
2116

    
2117
/* mtspr */
2118
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
2119
{
2120
    void (*write_cb)(void *opaque, int sprn);
2121
    uint32_t sprn = SPR(ctx->opcode);
2122

    
2123
#if !defined(CONFIG_USER_ONLY)
2124
    if (ctx->supervisor)
2125
        write_cb = ctx->spr_cb[sprn].oea_write;
2126
    else
2127
#endif
2128
        write_cb = ctx->spr_cb[sprn].uea_write;
2129
    if (likely(write_cb != NULL)) {
2130
        if (likely(write_cb != SPR_NOACCESS)) {
2131
            gen_op_load_gpr_T0(rS(ctx->opcode));
2132
            (*write_cb)(ctx, sprn);
2133
        } else {
2134
            /* Privilege exception */
2135
            if (loglevel) {
2136
                fprintf(logfile, "Trying to write priviledged spr %d %03x\n",
2137
                        sprn, sprn);
2138
            }
2139
            printf("Trying to write priviledged spr %d %03x\n", sprn, sprn);
2140
            RET_PRIVREG(ctx);
2141
        }
2142
    } else {
2143
        /* Not defined */
2144
        if (loglevel) {
2145
            fprintf(logfile, "Trying to write invalid spr %d %03x\n",
2146
                    sprn, sprn);
2147
        }
2148
        printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
2149
        RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2150
    }
2151
}
2152

    
2153
/***                         Cache management                              ***/
2154
/* For now, all those will be implemented as nop:
2155
 * this is valid, regarding the PowerPC specs...
2156
 * We just have to flush tb while invalidating instruction cache lines...
2157
 */
2158
/* dcbf */
2159
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
2160
{
2161
    gen_addr_reg_index(ctx);
2162
    op_ldst(lbz);
2163
}
2164

    
2165
/* dcbi (Supervisor only) */
2166
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
2167
{
2168
#if defined(CONFIG_USER_ONLY)
2169
    RET_PRIVOPC(ctx);
2170
#else
2171
    if (unlikely(!ctx->supervisor)) {
2172
        RET_PRIVOPC(ctx);
2173
        return;
2174
    }
2175
    gen_addr_reg_index(ctx);
2176
    /* XXX: specification says this should be treated as a store by the MMU */
2177
    //op_ldst(lbz);
2178
    op_ldst(stb);
2179
#endif
2180
}
2181

    
2182
/* dcdst */
2183
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
2184
{
2185
    /* XXX: specification say this is treated as a load by the MMU */
2186
    gen_addr_reg_index(ctx);
2187
    op_ldst(lbz);
2188
}
2189

    
2190
/* dcbt */
2191
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
2192
{
2193
    /* XXX: specification say this is treated as a load by the MMU
2194
     *      but does not generate any exception
2195
     */
2196
}
2197

    
2198
/* dcbtst */
2199
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
2200
{
2201
    /* XXX: specification say this is treated as a load by the MMU
2202
     *      but does not generate any exception
2203
     */
2204
}
2205

    
2206
/* dcbz */
2207
#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
2208
#if defined(CONFIG_USER_ONLY)
2209
static GenOpFunc *gen_op_dcbz[] = {
2210
    &gen_op_dcbz_raw,
2211
    &gen_op_dcbz_raw,
2212
};
2213
#else
2214
static GenOpFunc *gen_op_dcbz[] = {
2215
    &gen_op_dcbz_user,
2216
    &gen_op_dcbz_user,
2217
    &gen_op_dcbz_kernel,
2218
    &gen_op_dcbz_kernel,
2219
};
2220
#endif
2221

    
2222
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
2223
{
2224
    gen_addr_reg_index(ctx);
2225
    op_dcbz();
2226
    gen_op_check_reservation();
2227
}
2228

    
2229
/* icbi */
2230
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
2231
{
2232
    /* NIP cannot be restored if the memory exception comes from an helper */
2233
    gen_op_update_nip(ctx->nip - 4);
2234
    gen_addr_reg_index(ctx);
2235
    gen_op_icbi();
2236
    RET_STOP(ctx);
2237
}
2238

    
2239
/* Optional: */
2240
/* dcba */
2241
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT)
2242
{
2243
}
2244

    
2245
/***                    Segment register manipulation                      ***/
2246
/* Supervisor only: */
2247
/* mfsr */
2248
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
2249
{
2250
#if defined(CONFIG_USER_ONLY)
2251
    RET_PRIVREG(ctx);
2252
#else
2253
    if (unlikely(!ctx->supervisor)) {
2254
        RET_PRIVREG(ctx);
2255
        return;
2256
    }
2257
    gen_op_set_T1(SR(ctx->opcode));
2258
    gen_op_load_sr();
2259
    gen_op_store_T0_gpr(rD(ctx->opcode));
2260
#endif
2261
}
2262

    
2263
/* mfsrin */
2264
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
2265
{
2266
#if defined(CONFIG_USER_ONLY)
2267
    RET_PRIVREG(ctx);
2268
#else
2269
    if (unlikely(!ctx->supervisor)) {
2270
        RET_PRIVREG(ctx);
2271
        return;
2272
    }
2273
    gen_op_load_gpr_T1(rB(ctx->opcode));
2274
    gen_op_srli_T1(28);
2275
    gen_op_load_sr();
2276
    gen_op_store_T0_gpr(rD(ctx->opcode));
2277
#endif
2278
}
2279

    
2280
/* mtsr */
2281
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
2282
{
2283
#if defined(CONFIG_USER_ONLY)
2284
    RET_PRIVREG(ctx);
2285
#else
2286
    if (unlikely(!ctx->supervisor)) {
2287
        RET_PRIVREG(ctx);
2288
        return;
2289
    }
2290
    gen_op_load_gpr_T0(rS(ctx->opcode));
2291
    gen_op_set_T1(SR(ctx->opcode));
2292
    gen_op_store_sr();
2293
    RET_STOP(ctx);
2294
#endif
2295
}
2296

    
2297
/* mtsrin */
2298
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
2299
{
2300
#if defined(CONFIG_USER_ONLY)
2301
    RET_PRIVREG(ctx);
2302
#else
2303
    if (unlikely(!ctx->supervisor)) {
2304
        RET_PRIVREG(ctx);
2305
        return;
2306
    }
2307
    gen_op_load_gpr_T0(rS(ctx->opcode));
2308
    gen_op_load_gpr_T1(rB(ctx->opcode));
2309
    gen_op_srli_T1(28);
2310
    gen_op_store_sr();
2311
    RET_STOP(ctx);
2312
#endif
2313
}
2314

    
2315
/***                      Lookaside buffer management                      ***/
2316
/* Optional & supervisor only: */
2317
/* tlbia */
2318
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
2319
{
2320
#if defined(CONFIG_USER_ONLY)
2321
    RET_PRIVOPC(ctx);
2322
#else
2323
    if (unlikely(!ctx->supervisor)) {
2324
        if (loglevel)
2325
            fprintf(logfile, "%s: ! supervisor\n", __func__);
2326
        RET_PRIVOPC(ctx);
2327
        return;
2328
    }
2329
    gen_op_tlbia();
2330
    RET_STOP(ctx);
2331
#endif
2332
}
2333

    
2334
/* tlbie */
2335
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
2336
{
2337
#if defined(CONFIG_USER_ONLY)
2338
    RET_PRIVOPC(ctx);
2339
#else
2340
    if (unlikely(!ctx->supervisor)) {
2341
        RET_PRIVOPC(ctx);
2342
        return;
2343
    }
2344
    gen_op_load_gpr_T0(rB(ctx->opcode));
2345
    gen_op_tlbie();
2346
    RET_STOP(ctx);
2347
#endif
2348
}
2349

    
2350
/* tlbsync */
2351
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
2352
{
2353
#if defined(CONFIG_USER_ONLY)
2354
    RET_PRIVOPC(ctx);
2355
#else
2356
    if (unlikely(!ctx->supervisor)) {
2357
        RET_PRIVOPC(ctx);
2358
        return;
2359
    }
2360
    /* This has no effect: it should ensure that all previous
2361
     * tlbie have completed
2362
     */
2363
    RET_STOP(ctx);
2364
#endif
2365
}
2366

    
2367
/***                              External control                         ***/
2368
/* Optional: */
2369
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
2370
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
2371
#if defined(CONFIG_USER_ONLY)
2372
static GenOpFunc *gen_op_eciwx[] = {
2373
    &gen_op_eciwx_raw,
2374
    &gen_op_eciwx_le_raw,
2375
};
2376
static GenOpFunc *gen_op_ecowx[] = {
2377
    &gen_op_ecowx_raw,
2378
    &gen_op_ecowx_le_raw,
2379
};
2380
#else
2381
static GenOpFunc *gen_op_eciwx[] = {
2382
    &gen_op_eciwx_user,
2383
    &gen_op_eciwx_le_user,
2384
    &gen_op_eciwx_kernel,
2385
    &gen_op_eciwx_le_kernel,
2386
};
2387
static GenOpFunc *gen_op_ecowx[] = {
2388
    &gen_op_ecowx_user,
2389
    &gen_op_ecowx_le_user,
2390
    &gen_op_ecowx_kernel,
2391
    &gen_op_ecowx_le_kernel,
2392
};
2393
#endif
2394

    
2395
/* eciwx */
2396
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
2397
{
2398
    /* Should check EAR[E] & alignment ! */
2399
    gen_addr_reg_index(ctx);
2400
    op_eciwx();
2401
    gen_op_store_T0_gpr(rD(ctx->opcode));
2402
}
2403

    
2404
/* ecowx */
2405
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
2406
{
2407
    /* Should check EAR[E] & alignment ! */
2408
    gen_addr_reg_index(ctx);
2409
    gen_op_load_gpr_T1(rS(ctx->opcode));
2410
    op_ecowx();
2411
}
2412

    
2413
/* PowerPC 601 specific instructions */
2414
/* abs - abs. */
2415
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
2416
{
2417
    gen_op_load_gpr_T0(rA(ctx->opcode));
2418
    gen_op_POWER_abs();
2419
    gen_op_store_T0_gpr(rD(ctx->opcode));
2420
    if (unlikely(Rc(ctx->opcode) != 0))
2421
        gen_set_Rc0(ctx);
2422
}
2423

    
2424
/* abso - abso. */
2425
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
2426
{
2427
    gen_op_load_gpr_T0(rA(ctx->opcode));
2428
    gen_op_POWER_abso();
2429
    gen_op_store_T0_gpr(rD(ctx->opcode));
2430
    if (unlikely(Rc(ctx->opcode) != 0))
2431
        gen_set_Rc0(ctx);
2432
}
2433

    
2434
/* clcs */
2435
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR) /* 601 ? */
2436
{
2437
    gen_op_load_gpr_T0(rA(ctx->opcode));
2438
    gen_op_POWER_clcs();
2439
    gen_op_store_T0_gpr(rD(ctx->opcode));
2440
}
2441

    
2442
/* div - div. */
2443
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
2444
{
2445
    gen_op_load_gpr_T0(rA(ctx->opcode));
2446
    gen_op_load_gpr_T1(rB(ctx->opcode));
2447
    gen_op_POWER_div();
2448
    gen_op_store_T0_gpr(rD(ctx->opcode));
2449
    if (unlikely(Rc(ctx->opcode) != 0))
2450
        gen_set_Rc0(ctx);
2451
}
2452

    
2453
/* divo - divo. */
2454
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
2455
{
2456
    gen_op_load_gpr_T0(rA(ctx->opcode));
2457
    gen_op_load_gpr_T1(rB(ctx->opcode));
2458
    gen_op_POWER_divo();
2459
    gen_op_store_T0_gpr(rD(ctx->opcode));
2460
    if (unlikely(Rc(ctx->opcode) != 0))
2461
        gen_set_Rc0(ctx);
2462
}
2463

    
2464
/* divs - divs. */
2465
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
2466
{
2467
    gen_op_load_gpr_T0(rA(ctx->opcode));
2468
    gen_op_load_gpr_T1(rB(ctx->opcode));
2469
    gen_op_POWER_divs();
2470
    gen_op_store_T0_gpr(rD(ctx->opcode));
2471
    if (unlikely(Rc(ctx->opcode) != 0))
2472
        gen_set_Rc0(ctx);
2473
}
2474

    
2475
/* divso - divso. */
2476
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
2477
{
2478
    gen_op_load_gpr_T0(rA(ctx->opcode));
2479
    gen_op_load_gpr_T1(rB(ctx->opcode));
2480
    gen_op_POWER_divso();
2481
    gen_op_store_T0_gpr(rD(ctx->opcode));
2482
    if (unlikely(Rc(ctx->opcode) != 0))
2483
        gen_set_Rc0(ctx);
2484
}
2485

    
2486
/* doz - doz. */
2487
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
2488
{
2489
    gen_op_load_gpr_T0(rA(ctx->opcode));
2490
    gen_op_load_gpr_T1(rB(ctx->opcode));
2491
    gen_op_POWER_doz();
2492
    gen_op_store_T0_gpr(rD(ctx->opcode));
2493
    if (unlikely(Rc(ctx->opcode) != 0))
2494
        gen_set_Rc0(ctx);
2495
}
2496

    
2497
/* dozo - dozo. */
2498
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
2499
{
2500
    gen_op_load_gpr_T0(rA(ctx->opcode));
2501
    gen_op_load_gpr_T1(rB(ctx->opcode));
2502
    gen_op_POWER_dozo();
2503
    gen_op_store_T0_gpr(rD(ctx->opcode));
2504
    if (unlikely(Rc(ctx->opcode) != 0))
2505
        gen_set_Rc0(ctx);
2506
}
2507

    
2508
/* dozi */
2509
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
2510
{
2511
    gen_op_load_gpr_T0(rA(ctx->opcode));
2512
    gen_op_set_T1(SIMM(ctx->opcode));
2513
    gen_op_POWER_doz();
2514
    gen_op_store_T0_gpr(rD(ctx->opcode));
2515
}
2516

    
2517
/* As lscbx load from memory byte after byte, it's always endian safe */
2518
#define op_POWER_lscbx(start, ra, rb) \
2519
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
2520
#if defined(CONFIG_USER_ONLY)
2521
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
2522
    &gen_op_POWER_lscbx_raw,
2523
    &gen_op_POWER_lscbx_raw,
2524
};
2525
#else
2526
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
2527
    &gen_op_POWER_lscbx_user,
2528
    &gen_op_POWER_lscbx_user,
2529
    &gen_op_POWER_lscbx_kernel,
2530
    &gen_op_POWER_lscbx_kernel,
2531
};
2532
#endif
2533

    
2534
/* lscbx - lscbx. */
2535
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
2536
{
2537
    int ra = rA(ctx->opcode);
2538
    int rb = rB(ctx->opcode);
2539

    
2540
    gen_addr_reg_index(ctx);
2541
    if (ra == 0) {
2542
        ra = rb;
2543
    }
2544
    /* NIP cannot be restored if the memory exception comes from an helper */
2545
    gen_op_update_nip(ctx->nip - 4);
2546
    gen_op_load_xer_bc();
2547
    gen_op_load_xer_cmp();
2548
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
2549
    gen_op_store_xer_bc();
2550
    if (unlikely(Rc(ctx->opcode) != 0))
2551
        gen_set_Rc0(ctx);
2552
}
2553

    
2554
/* maskg - maskg. */
2555
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
2556
{
2557
    gen_op_load_gpr_T0(rS(ctx->opcode));
2558
    gen_op_load_gpr_T1(rB(ctx->opcode));
2559
    gen_op_POWER_maskg();
2560
    gen_op_store_T0_gpr(rA(ctx->opcode));
2561
    if (unlikely(Rc(ctx->opcode) != 0))
2562
        gen_set_Rc0(ctx);
2563
}
2564

    
2565
/* maskir - maskir. */
2566
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
2567
{
2568
    gen_op_load_gpr_T0(rA(ctx->opcode));
2569
    gen_op_load_gpr_T1(rS(ctx->opcode));
2570
    gen_op_load_gpr_T2(rB(ctx->opcode));
2571
    gen_op_POWER_maskir();
2572
    gen_op_store_T0_gpr(rA(ctx->opcode));
2573
    if (unlikely(Rc(ctx->opcode) != 0))
2574
        gen_set_Rc0(ctx);
2575
}
2576

    
2577
/* mul - mul. */
2578
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
2579
{
2580
    gen_op_load_gpr_T0(rA(ctx->opcode));
2581
    gen_op_load_gpr_T1(rB(ctx->opcode));
2582
    gen_op_POWER_mul();
2583
    gen_op_store_T0_gpr(rD(ctx->opcode));
2584
    if (unlikely(Rc(ctx->opcode) != 0))
2585
        gen_set_Rc0(ctx);
2586
}
2587

    
2588
/* mulo - mulo. */
2589
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
2590
{
2591
    gen_op_load_gpr_T0(rA(ctx->opcode));
2592
    gen_op_load_gpr_T1(rB(ctx->opcode));
2593
    gen_op_POWER_mulo();
2594
    gen_op_store_T0_gpr(rD(ctx->opcode));
2595
    if (unlikely(Rc(ctx->opcode) != 0))
2596
        gen_set_Rc0(ctx);
2597
}
2598

    
2599
/* nabs - nabs. */
2600
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
2601
{
2602
    gen_op_load_gpr_T0(rA(ctx->opcode));
2603
    gen_op_POWER_nabs();
2604
    gen_op_store_T0_gpr(rD(ctx->opcode));
2605
    if (unlikely(Rc(ctx->opcode) != 0))
2606
        gen_set_Rc0(ctx);
2607
}
2608

    
2609
/* nabso - nabso. */
2610
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
2611
{
2612
    gen_op_load_gpr_T0(rA(ctx->opcode));
2613
    gen_op_POWER_nabso();
2614
    gen_op_store_T0_gpr(rD(ctx->opcode));
2615
    if (unlikely(Rc(ctx->opcode) != 0))
2616
        gen_set_Rc0(ctx);
2617
}
2618

    
2619
/* rlmi - rlmi. */
2620
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
2621
{
2622
    uint32_t mb, me;
2623

    
2624
    mb = MB(ctx->opcode);
2625
    me = ME(ctx->opcode);
2626
    gen_op_load_gpr_T0(rS(ctx->opcode));
2627
    gen_op_load_gpr_T1(rA(ctx->opcode));
2628
    gen_op_load_gpr_T2(rB(ctx->opcode));
2629
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
2630
    gen_op_store_T0_gpr(rA(ctx->opcode));
2631
    if (unlikely(Rc(ctx->opcode) != 0))
2632
        gen_set_Rc0(ctx);
2633
}
2634

    
2635
/* rrib - rrib. */
2636
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
2637
{
2638
    gen_op_load_gpr_T0(rS(ctx->opcode));
2639
    gen_op_load_gpr_T1(rA(ctx->opcode));
2640
    gen_op_load_gpr_T2(rB(ctx->opcode));
2641
    gen_op_POWER_rrib();
2642
    gen_op_store_T0_gpr(rA(ctx->opcode));
2643
    if (unlikely(Rc(ctx->opcode) != 0))
2644
        gen_set_Rc0(ctx);
2645
}
2646

    
2647
/* sle - sle. */
2648
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
2649
{
2650
    gen_op_load_gpr_T0(rS(ctx->opcode));
2651
    gen_op_load_gpr_T1(rB(ctx->opcode));
2652
    gen_op_POWER_sle();
2653
    gen_op_store_T0_gpr(rA(ctx->opcode));
2654
    if (unlikely(Rc(ctx->opcode) != 0))
2655
        gen_set_Rc0(ctx);
2656
}
2657

    
2658
/* sleq - sleq. */
2659
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
2660
{
2661
    gen_op_load_gpr_T0(rS(ctx->opcode));
2662
    gen_op_load_gpr_T1(rB(ctx->opcode));
2663
    gen_op_POWER_sleq();
2664
    gen_op_store_T0_gpr(rA(ctx->opcode));
2665
    if (unlikely(Rc(ctx->opcode) != 0))
2666
        gen_set_Rc0(ctx);
2667
}
2668

    
2669
/* sliq - sliq. */
2670
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
2671
{
2672
    gen_op_load_gpr_T0(rS(ctx->opcode));
2673
    gen_op_set_T1(SH(ctx->opcode));
2674
    gen_op_POWER_sle();
2675
    gen_op_store_T0_gpr(rA(ctx->opcode));
2676
    if (unlikely(Rc(ctx->opcode) != 0))
2677
        gen_set_Rc0(ctx);
2678
}
2679

    
2680
/* slliq - slliq. */
2681
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
2682
{
2683
    gen_op_load_gpr_T0(rS(ctx->opcode));
2684
    gen_op_set_T1(SH(ctx->opcode));
2685
    gen_op_POWER_sleq();
2686
    gen_op_store_T0_gpr(rA(ctx->opcode));
2687
    if (unlikely(Rc(ctx->opcode) != 0))
2688
        gen_set_Rc0(ctx);
2689
}
2690

    
2691
/* sllq - sllq. */
2692
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
2693
{
2694
    gen_op_load_gpr_T0(rS(ctx->opcode));
2695
    gen_op_load_gpr_T1(rB(ctx->opcode));
2696
    gen_op_POWER_sllq();
2697
    gen_op_store_T0_gpr(rA(ctx->opcode));
2698
    if (unlikely(Rc(ctx->opcode) != 0))
2699
        gen_set_Rc0(ctx);
2700
}
2701

    
2702
/* slq - slq. */
2703
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
2704
{
2705
    gen_op_load_gpr_T0(rS(ctx->opcode));
2706
    gen_op_load_gpr_T1(rB(ctx->opcode));
2707
    gen_op_POWER_slq();
2708
    gen_op_store_T0_gpr(rA(ctx->opcode));
2709
    if (unlikely(Rc(ctx->opcode) != 0))
2710
        gen_set_Rc0(ctx);
2711
}
2712

    
2713
/* sraiq -sraiq. */
2714
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
2715
{
2716
    gen_op_load_gpr_T0(rS(ctx->opcode));
2717
    gen_op_set_T1(SH(ctx->opcode));
2718
    gen_op_POWER_sraq();
2719
    gen_op_store_T0_gpr(rA(ctx->opcode));
2720
    if (unlikely(Rc(ctx->opcode) != 0))
2721
        gen_set_Rc0(ctx);
2722
}
2723

    
2724
/* sraq - sraq. */
2725
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
2726
{
2727
    gen_op_load_gpr_T0(rS(ctx->opcode));
2728
    gen_op_load_gpr_T1(rB(ctx->opcode));
2729
    gen_op_POWER_sraq();
2730
    gen_op_store_T0_gpr(rA(ctx->opcode));
2731
    if (unlikely(Rc(ctx->opcode) != 0))
2732
        gen_set_Rc0(ctx);
2733
}
2734

    
2735
/* sre - sre. */
2736
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
2737
{
2738
    gen_op_load_gpr_T0(rS(ctx->opcode));
2739
    gen_op_load_gpr_T1(rB(ctx->opcode));
2740
    gen_op_POWER_sre();
2741
    gen_op_store_T0_gpr(rA(ctx->opcode));
2742
    if (unlikely(Rc(ctx->opcode) != 0))
2743
        gen_set_Rc0(ctx);
2744
}
2745

    
2746
/* srea - srea. */
2747
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
2748
{
2749
    gen_op_load_gpr_T0(rS(ctx->opcode));
2750
    gen_op_load_gpr_T1(rB(ctx->opcode));
2751
    gen_op_POWER_srea();
2752
    gen_op_store_T0_gpr(rA(ctx->opcode));
2753
    if (unlikely(Rc(ctx->opcode) != 0))
2754
        gen_set_Rc0(ctx);
2755
}
2756

    
2757
/* sreq */
2758
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
2759
{
2760
    gen_op_load_gpr_T0(rS(ctx->opcode));
2761
    gen_op_load_gpr_T1(rB(ctx->opcode));
2762
    gen_op_POWER_sreq();
2763
    gen_op_store_T0_gpr(rA(ctx->opcode));
2764
    if (unlikely(Rc(ctx->opcode) != 0))
2765
        gen_set_Rc0(ctx);
2766
}
2767

    
2768
/* sriq */
2769
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
2770
{
2771
    gen_op_load_gpr_T0(rS(ctx->opcode));
2772
    gen_op_set_T1(SH(ctx->opcode));
2773
    gen_op_POWER_srq();
2774
    gen_op_store_T0_gpr(rA(ctx->opcode));
2775
    if (unlikely(Rc(ctx->opcode) != 0))
2776
        gen_set_Rc0(ctx);
2777
}
2778

    
2779
/* srliq */
2780
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
2781
{
2782
    gen_op_load_gpr_T0(rS(ctx->opcode));
2783
    gen_op_load_gpr_T1(rB(ctx->opcode));
2784
    gen_op_set_T1(SH(ctx->opcode));
2785
    gen_op_POWER_srlq();
2786
    gen_op_store_T0_gpr(rA(ctx->opcode));
2787
    if (unlikely(Rc(ctx->opcode) != 0))
2788
        gen_set_Rc0(ctx);
2789
}
2790

    
2791
/* srlq */
2792
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
2793
{
2794
    gen_op_load_gpr_T0(rS(ctx->opcode));
2795
    gen_op_load_gpr_T1(rB(ctx->opcode));
2796
    gen_op_POWER_srlq();
2797
    gen_op_store_T0_gpr(rA(ctx->opcode));
2798
    if (unlikely(Rc(ctx->opcode) != 0))
2799
        gen_set_Rc0(ctx);
2800
}
2801

    
2802
/* srq */
2803
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
2804
{
2805
    gen_op_load_gpr_T0(rS(ctx->opcode));
2806
    gen_op_load_gpr_T1(rB(ctx->opcode));
2807
    gen_op_POWER_srq();
2808
    gen_op_store_T0_gpr(rA(ctx->opcode));
2809
    if (unlikely(Rc(ctx->opcode) != 0))
2810
        gen_set_Rc0(ctx);
2811
}
2812

    
2813
/* PowerPC 602 specific instructions */
2814
/* dsa  */
2815
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
2816
{
2817
    /* XXX: TODO */
2818
    RET_INVAL(ctx);
2819
}
2820

    
2821
/* esa */
2822
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
2823
{
2824
    /* XXX: TODO */
2825
    RET_INVAL(ctx);
2826
}
2827

    
2828
/* mfrom */
2829
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
2830
{
2831
#if defined(CONFIG_USER_ONLY)
2832
    RET_PRIVOPC(ctx);
2833
#else
2834
    if (unlikely(!ctx->supervisor)) {
2835
        RET_PRIVOPC(ctx);
2836
        return;
2837
    }
2838
    gen_op_load_gpr_T0(rA(ctx->opcode));
2839
    gen_op_602_mfrom();
2840
    gen_op_store_T0_gpr(rD(ctx->opcode));
2841
#endif
2842
}
2843

    
2844
/* 602 - 603 - G2 TLB management */
2845
/* tlbld */
2846
GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
2847
{
2848
#if defined(CONFIG_USER_ONLY)
2849
    RET_PRIVOPC(ctx);
2850
#else
2851
    if (unlikely(!ctx->supervisor)) {
2852
        RET_PRIVOPC(ctx);
2853
        return;
2854
    }
2855
    gen_op_load_gpr_T0(rB(ctx->opcode));
2856
    gen_op_6xx_tlbld();
2857
    RET_STOP(ctx);
2858
#endif
2859
}
2860

    
2861
/* tlbli */
2862
GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
2863
{
2864
#if defined(CONFIG_USER_ONLY)
2865
    RET_PRIVOPC(ctx);
2866
#else
2867
    if (unlikely(!ctx->supervisor)) {
2868
        RET_PRIVOPC(ctx);
2869
        return;
2870
    }
2871
    gen_op_load_gpr_T0(rB(ctx->opcode));
2872
    gen_op_6xx_tlbli();
2873
    RET_STOP(ctx);
2874
#endif
2875
}
2876

    
2877
/* POWER instructions not in PowerPC 601 */
2878
/* clf */
2879
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
2880
{
2881
    /* Cache line flush: implemented as no-op */
2882
}
2883

    
2884
/* cli */
2885
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
2886
{
2887
    /* Cache line invalidate: priviledged and treated as no-op */
2888
#if defined(CONFIG_USER_ONLY)
2889
    RET_PRIVOPC(ctx);
2890
#else
2891
    if (unlikely(!ctx->supervisor)) {
2892
        RET_PRIVOPC(ctx);
2893
        return;
2894
    }
2895
#endif
2896
}
2897

    
2898
/* dclst */
2899
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
2900
{
2901
    /* Data cache line store: treated as no-op */
2902
}
2903

    
2904
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
2905
{
2906
#if defined(CONFIG_USER_ONLY)
2907
    RET_PRIVOPC(ctx);
2908
#else
2909
    if (unlikely(!ctx->supervisor)) {
2910
        RET_PRIVOPC(ctx);
2911
        return;
2912
    }
2913
    int ra = rA(ctx->opcode);
2914
    int rd = rD(ctx->opcode);
2915

    
2916
    gen_addr_reg_index(ctx);
2917
    gen_op_POWER_mfsri();
2918
    gen_op_store_T0_gpr(rd);
2919
    if (ra != 0 && ra != rd)
2920
        gen_op_store_T1_gpr(ra);
2921
#endif
2922
}
2923

    
2924
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
2925
{
2926
#if defined(CONFIG_USER_ONLY)
2927
    RET_PRIVOPC(ctx);
2928
#else
2929
    if (unlikely(!ctx->supervisor)) {
2930
        RET_PRIVOPC(ctx);
2931
        return;
2932
    }
2933
    gen_addr_reg_index(ctx);
2934
    gen_op_POWER_rac();
2935
    gen_op_store_T0_gpr(rD(ctx->opcode));
2936
#endif
2937
}
2938

    
2939
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
2940
{
2941
#if defined(CONFIG_USER_ONLY)
2942
    RET_PRIVOPC(ctx);
2943
#else
2944
    if (unlikely(!ctx->supervisor)) {
2945
        RET_PRIVOPC(ctx);
2946
        return;
2947
    }
2948
    gen_op_POWER_rfsvc();
2949
    RET_CHG_FLOW(ctx);
2950
#endif
2951
}
2952

    
2953
/* svc is not implemented for now */
2954

    
2955
/* POWER2 specific instructions */
2956
/* Quad manipulation (load/store two floats at a time) */
2957
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
2958
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
2959
#if defined(CONFIG_USER_ONLY)
2960
static GenOpFunc *gen_op_POWER2_lfq[] = {
2961
    &gen_op_POWER2_lfq_le_raw,
2962
    &gen_op_POWER2_lfq_raw,
2963
};
2964
static GenOpFunc *gen_op_POWER2_stfq[] = {
2965
    &gen_op_POWER2_stfq_le_raw,
2966
    &gen_op_POWER2_stfq_raw,
2967
};
2968
#else
2969
static GenOpFunc *gen_op_POWER2_lfq[] = {
2970
    &gen_op_POWER2_lfq_le_user,
2971
    &gen_op_POWER2_lfq_user,
2972
    &gen_op_POWER2_lfq_le_kernel,
2973
    &gen_op_POWER2_lfq_kernel,
2974
};
2975
static GenOpFunc *gen_op_POWER2_stfq[] = {
2976
    &gen_op_POWER2_stfq_le_user,
2977
    &gen_op_POWER2_stfq_user,
2978
    &gen_op_POWER2_stfq_le_kernel,
2979
    &gen_op_POWER2_stfq_kernel,
2980
};
2981
#endif
2982

    
2983
/* lfq */
2984
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
2985
{
2986
    /* NIP cannot be restored if the memory exception comes from an helper */
2987
    gen_op_update_nip(ctx->nip - 4);
2988
    gen_addr_imm_index(ctx);
2989
    op_POWER2_lfq();
2990
    gen_op_store_FT0_fpr(rD(ctx->opcode));
2991
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
2992
}
2993

    
2994
/* lfqu */
2995
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
2996
{
2997
    int ra = rA(ctx->opcode);
2998

    
2999
    /* NIP cannot be restored if the memory exception comes from an helper */
3000
    gen_op_update_nip(ctx->nip - 4);
3001
    gen_addr_imm_index(ctx);
3002
    op_POWER2_lfq();
3003
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3004
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3005
    if (ra != 0)
3006
        gen_op_store_T0_gpr(ra);
3007
}
3008

    
3009
/* lfqux */
3010
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
3011
{
3012
    int ra = rA(ctx->opcode);
3013

    
3014
    /* NIP cannot be restored if the memory exception comes from an helper */
3015
    gen_op_update_nip(ctx->nip - 4);
3016
    gen_addr_reg_index(ctx);
3017
    op_POWER2_lfq();
3018
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3019
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3020
    if (ra != 0)
3021
        gen_op_store_T0_gpr(ra);
3022
}
3023

    
3024
/* lfqx */
3025
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
3026
{
3027
    /* NIP cannot be restored if the memory exception comes from an helper */
3028
    gen_op_update_nip(ctx->nip - 4);
3029
    gen_addr_reg_index(ctx);
3030
    op_POWER2_lfq();
3031
    gen_op_store_FT0_fpr(rD(ctx->opcode));
3032
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3033
}
3034

    
3035
/* stfq */
3036
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3037
{
3038
    /* NIP cannot be restored if the memory exception comes from an helper */
3039
    gen_op_update_nip(ctx->nip - 4);
3040
    gen_addr_imm_index(ctx);
3041
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3042
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3043
    op_POWER2_stfq();
3044
}
3045

    
3046
/* stfqu */
3047
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3048
{
3049
    int ra = rA(ctx->opcode);
3050

    
3051
    /* NIP cannot be restored if the memory exception comes from an helper */
3052
    gen_op_update_nip(ctx->nip - 4);
3053
    gen_addr_imm_index(ctx);
3054
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3055
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3056
    op_POWER2_stfq();
3057
    if (ra != 0)
3058
        gen_op_store_T0_gpr(ra);
3059
}
3060

    
3061
/* stfqux */
3062
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
3063
{
3064
    int ra = rA(ctx->opcode);
3065

    
3066
    /* NIP cannot be restored if the memory exception comes from an helper */
3067
    gen_op_update_nip(ctx->nip - 4);
3068
    gen_addr_reg_index(ctx);
3069
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3070
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3071
    op_POWER2_stfq();
3072
    if (ra != 0)
3073
        gen_op_store_T0_gpr(ra);
3074
}
3075

    
3076
/* stfqx */
3077
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
3078
{
3079
    /* NIP cannot be restored if the memory exception comes from an helper */
3080
    gen_op_update_nip(ctx->nip - 4);
3081
    gen_addr_reg_index(ctx);
3082
    gen_op_load_fpr_FT0(rS(ctx->opcode));
3083
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3084
    op_POWER2_stfq();
3085
}
3086

    
3087
/* BookE specific instructions */
3088
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE)
3089
{
3090
    /* XXX: TODO */
3091
    RET_INVAL(ctx);
3092
}
3093

    
3094
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE)
3095
{
3096
#if defined(CONFIG_USER_ONLY)
3097
    RET_PRIVOPC(ctx);
3098
#else
3099
    if (unlikely(!ctx->supervisor)) {
3100
        RET_PRIVOPC(ctx);
3101
        return;
3102
    }
3103
    gen_addr_reg_index(ctx);
3104
    /* Use the same micro-ops as for tlbie */
3105
    gen_op_tlbie();
3106
    RET_STOP(ctx);
3107
#endif
3108
}
3109

    
3110
/* All 405 MAC instructions are translated here */
3111
static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
3112
                                         int ra, int rb, int rt, int Rc)
3113
{
3114
    gen_op_load_gpr_T0(ra);
3115
    gen_op_load_gpr_T1(rb);
3116
    switch (opc3 & 0x0D) {
3117
    case 0x05:
3118
        /* macchw    - macchw.    - macchwo   - macchwo.   */
3119
        /* macchws   - macchws.   - macchwso  - macchwso.  */
3120
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
3121
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
3122
        /* mulchw - mulchw. */
3123
        gen_op_405_mulchw();
3124
        break;
3125
    case 0x04:
3126
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
3127
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
3128
        /* mulchwu - mulchwu. */
3129
        gen_op_405_mulchwu();
3130
        break;
3131
    case 0x01:
3132
        /* machhw    - machhw.    - machhwo   - machhwo.   */
3133
        /* machhws   - machhws.   - machhwso  - machhwso.  */
3134
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
3135
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
3136
        /* mulhhw - mulhhw. */
3137
        gen_op_405_mulhhw();
3138
        break;
3139
    case 0x00:
3140
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
3141
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
3142
        /* mulhhwu - mulhhwu. */
3143
        gen_op_405_mulhhwu();
3144
        break;
3145
    case 0x0D:
3146
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
3147
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
3148
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
3149
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
3150
        /* mullhw - mullhw. */
3151
        gen_op_405_mullhw();
3152
        break;
3153
    case 0x0C:
3154
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
3155
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
3156
        /* mullhwu - mullhwu. */
3157
        gen_op_405_mullhwu();
3158
        break;
3159
    }
3160
    if (opc2 & 0x02) {
3161
        /* nmultiply-and-accumulate (0x0E) */
3162
        gen_op_neg();
3163
    }
3164
    if (opc2 & 0x04) {
3165
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
3166
        gen_op_load_gpr_T2(rt);
3167
        gen_op_move_T1_T0();
3168
        gen_op_405_add_T0_T2();
3169
    }
3170
    if (opc3 & 0x10) {
3171
        /* Check overflow */
3172
        if (opc3 & 0x01)
3173
            gen_op_405_check_ov();
3174
        else
3175
            gen_op_405_check_ovu();
3176
    }
3177
    if (opc3 & 0x02) {
3178
        /* Saturate */
3179
        if (opc3 & 0x01)
3180
            gen_op_405_check_sat();
3181
        else
3182
            gen_op_405_check_satu();
3183
    }
3184
    gen_op_store_T0_gpr(rt);
3185
    if (unlikely(Rc) != 0) {
3186
        /* Update Rc0 */
3187
        gen_set_Rc0(ctx);
3188
    }
3189
}
3190

    
3191
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
3192
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
3193
{                                                                             \
3194
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
3195
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
3196
}
3197

    
3198
/* macchw    - macchw.    */
3199
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
3200
/* macchwo   - macchwo.   */
3201
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
3202
/* macchws   - macchws.   */
3203
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
3204
/* macchwso  - macchwso.  */
3205
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
3206
/* macchwsu  - macchwsu.  */
3207
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
3208
/* macchwsuo - macchwsuo. */
3209
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
3210
/* macchwu   - macchwu.   */
3211
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
3212
/* macchwuo  - macchwuo.  */
3213
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
3214
/* machhw    - machhw.    */
3215
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
3216
/* machhwo   - machhwo.   */
3217
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
3218
/* machhws   - machhws.   */
3219
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
3220
/* machhwso  - machhwso.  */
3221
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
3222
/* machhwsu  - machhwsu.  */
3223
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
3224
/* machhwsuo - machhwsuo. */
3225
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
3226
/* machhwu   - machhwu.   */
3227
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
3228
/* machhwuo  - machhwuo.  */
3229
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
3230
/* maclhw    - maclhw.    */
3231
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
3232
/* maclhwo   - maclhwo.   */
3233
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
3234
/* maclhws   - maclhws.   */
3235
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
3236
/* maclhwso  - maclhwso.  */
3237
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
3238
/* maclhwu   - maclhwu.   */
3239
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
3240
/* maclhwuo  - maclhwuo.  */
3241
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
3242
/* maclhwsu  - maclhwsu.  */
3243
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
3244
/* maclhwsuo - maclhwsuo. */
3245
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
3246
/* nmacchw   - nmacchw.   */
3247
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
3248
/* nmacchwo  - nmacchwo.  */
3249
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
3250
/* nmacchws  - nmacchws.  */
3251
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
3252
/* nmacchwso - nmacchwso. */
3253
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
3254
/* nmachhw   - nmachhw.   */
3255
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
3256
/* nmachhwo  - nmachhwo.  */
3257
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
3258
/* nmachhws  - nmachhws.  */
3259
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
3260
/* nmachhwso - nmachhwso. */
3261
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
3262
/* nmaclhw   - nmaclhw.   */
3263
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
3264
/* nmaclhwo  - nmaclhwo.  */
3265
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
3266
/* nmaclhws  - nmaclhws.  */
3267
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
3268
/* nmaclhwso - nmaclhwso. */
3269
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
3270

    
3271
/* mulchw  - mulchw.  */
3272
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
3273
/* mulchwu - mulchwu. */
3274
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
3275
/* mulhhw  - mulhhw.  */
3276
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
3277
/* mulhhwu - mulhhwu. */
3278
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
3279
/* mullhw  - mullhw.  */
3280
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
3281
/* mullhwu - mullhwu. */
3282
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
3283

    
3284
/* mfdcr */
3285
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
3286
{
3287
#if defined(CONFIG_USER_ONLY)
3288
    RET_PRIVREG(ctx);
3289
#else
3290
    uint32_t dcrn = SPR(ctx->opcode);
3291

    
3292
    if (unlikely(!ctx->supervisor)) {
3293
        RET_PRIVREG(ctx);
3294
        return;
3295
    }
3296
    gen_op_4xx_load_dcr(dcrn);
3297
    gen_op_store_T0_gpr(rD(ctx->opcode));
3298
#endif
3299
}
3300

    
3301
/* mtdcr */
3302
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
3303
{
3304
#if defined(CONFIG_USER_ONLY)
3305
    RET_PRIVREG(ctx);
3306
#else
3307
    uint32_t dcrn = SPR(ctx->opcode);
3308

    
3309
    if (unlikely(!ctx->supervisor)) {
3310
        RET_PRIVREG(ctx);
3311
        return;
3312
    }
3313
    gen_op_load_gpr_T0(rS(ctx->opcode));
3314
    gen_op_4xx_store_dcr(dcrn);
3315
#endif
3316
}
3317

    
3318
/* dccci */
3319
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
3320
{
3321
#if defined(CONFIG_USER_ONLY)
3322
    RET_PRIVOPC(ctx);
3323
#else
3324
    if (unlikely(!ctx->supervisor)) {
3325
        RET_PRIVOPC(ctx);
3326
        return;
3327
    }
3328
    /* interpreted as no-op */
3329
#endif
3330
}
3331

    
3332
/* dcread */
3333
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
3334
{
3335
#if defined(CONFIG_USER_ONLY)
3336
    RET_PRIVOPC(ctx);
3337
#else
3338
    if (unlikely(!ctx->supervisor)) {
3339
        RET_PRIVOPC(ctx);
3340
        return;
3341
    }
3342
    gen_addr_reg_index(ctx);
3343
    op_ldst(lwz);
3344
    gen_op_store_T0_gpr(rD(ctx->opcode));
3345
#endif
3346
}
3347

    
3348
/* icbt */
3349
GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC)
3350
{
3351
    /* interpreted as no-op */
3352
    /* XXX: specification say this is treated as a load by the MMU
3353
     *      but does not generate any exception
3354
     */
3355
}
3356

    
3357
/* iccci */
3358
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
3359
{
3360
#if defined(CONFIG_USER_ONLY)
3361
    RET_PRIVOPC(ctx);
3362
#else
3363
    if (unlikely(!ctx->supervisor)) {
3364
        RET_PRIVOPC(ctx);
3365
        return;
3366
    }
3367
    /* interpreted as no-op */
3368
#endif
3369
}
3370

    
3371
/* icread */
3372
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
3373
{
3374
#if defined(CONFIG_USER_ONLY)
3375
    RET_PRIVOPC(ctx);
3376
#else
3377
    if (unlikely(!ctx->supervisor)) {
3378
        RET_PRIVOPC(ctx);
3379
        return;
3380
    }
3381
    /* interpreted as no-op */
3382
#endif
3383
}
3384

    
3385
/* rfci (supervisor only) */
3386
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_EMB_COMMON)
3387
{
3388
#if defined(CONFIG_USER_ONLY)
3389
    RET_PRIVOPC(ctx);
3390
#else
3391
    if (unlikely(!ctx->supervisor)) {
3392
        RET_PRIVOPC(ctx);
3393
        return;
3394
    }
3395
    /* Restore CPU state */
3396
    gen_op_4xx_rfci();
3397
    RET_CHG_FLOW(ctx);
3398
#endif
3399
}
3400

    
3401
/* tlbre */
3402
GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_EMB_COMMON)
3403
{
3404
#if defined(CONFIG_USER_ONLY)
3405
    RET_PRIVOPC(ctx);
3406
#else
3407
    if (unlikely(!ctx->supervisor)) {
3408
        RET_PRIVOPC(ctx);
3409
        return;
3410
    }
3411
    switch (rB(ctx->opcode)) {
3412
    case 0:
3413
        gen_op_load_gpr_T0(rA(ctx->opcode));
3414
        gen_op_4xx_tlbre_hi();
3415
        gen_op_store_T0_gpr(rD(ctx->opcode));
3416
        break;
3417
    case 1:
3418
        gen_op_load_gpr_T0(rA(ctx->opcode));
3419
        gen_op_4xx_tlbre_lo();
3420
        gen_op_store_T0_gpr(rD(ctx->opcode));
3421
        break;
3422
    default:
3423
        RET_INVAL(ctx);
3424
        break;
3425
    }
3426
#endif
3427
}
3428

    
3429
/* tlbsx - tlbsx. */ /* Named tlbs in BookE */
3430
GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_EMB_COMMON)
3431
{
3432
#if defined(CONFIG_USER_ONLY)
3433
    RET_PRIVOPC(ctx);
3434
#else
3435
    if (unlikely(!ctx->supervisor)) {
3436
        RET_PRIVOPC(ctx);
3437
        return;
3438
    }
3439
    gen_addr_reg_index(ctx);
3440
    if (Rc(ctx->opcode))
3441
        gen_op_4xx_tlbsx_();
3442
    else
3443
        gen_op_4xx_tlbsx();
3444
    gen_op_store_T0_gpr(rD(ctx->opcode));
3445
#endif
3446
}
3447

    
3448
/* tlbwe */
3449
GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_EMB_COMMON)
3450
{
3451
#if defined(CONFIG_USER_ONLY)
3452
    RET_PRIVOPC(ctx);
3453
#else
3454
    if (unlikely(!ctx->supervisor)) {
3455
        RET_PRIVOPC(ctx);
3456
        return;
3457
    }
3458
    switch (rB(ctx->opcode)) {
3459
    case 0:
3460
        gen_op_load_gpr_T0(rA(ctx->opcode));
3461
        gen_op_load_gpr_T1(rS(ctx->opcode));
3462
        gen_op_4xx_tlbwe_hi();
3463
        break;
3464
    case 1:
3465
        gen_op_load_gpr_T0(rA(ctx->opcode));
3466
        gen_op_load_gpr_T1(rS(ctx->opcode));
3467
        gen_op_4xx_tlbwe_lo();
3468
        break;
3469
    default:
3470
        RET_INVAL(ctx);
3471
        break;
3472
    }
3473
#endif
3474
}
3475

    
3476
/* wrtee */
3477
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
3478
{
3479
#if defined(CONFIG_USER_ONLY)
3480
    RET_PRIVOPC(ctx);
3481
#else
3482
    if (unlikely(!ctx->supervisor)) {
3483
        RET_PRIVOPC(ctx);
3484
        return;
3485
    }
3486
    gen_op_load_gpr_T0(rD(ctx->opcode));
3487
    gen_op_4xx_wrte();
3488
    RET_EXCP(ctx, EXCP_MTMSR, 0);
3489
#endif
3490
}
3491

    
3492
/* wrteei */
3493
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
3494
{
3495
#if defined(CONFIG_USER_ONLY)
3496
    RET_PRIVOPC(ctx);
3497
#else
3498
    if (unlikely(!ctx->supervisor)) {
3499
        RET_PRIVOPC(ctx);
3500
        return;
3501
    }
3502
    gen_op_set_T0(ctx->opcode & 0x00010000);
3503
    gen_op_4xx_wrte();
3504
    RET_EXCP(ctx, EXCP_MTMSR, 0);
3505
#endif
3506
}
3507

    
3508
/* PPC 440 specific instructions */
3509
/* dlmzb */
3510
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
3511
{
3512
    gen_op_load_gpr_T0(rS(ctx->opcode));
3513
    gen_op_load_gpr_T1(rB(ctx->opcode));
3514
    gen_op_440_dlmzb();
3515
    gen_op_store_T0_gpr(rA(ctx->opcode));
3516
    gen_op_store_xer_bc();
3517
    if (Rc(ctx->opcode)) {
3518
        gen_op_440_dlmzb_update_Rc();
3519
        gen_op_store_T0_crf(0);
3520
    }
3521
}
3522

    
3523
/* mbar replaces eieio on 440 */
3524
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
3525
{
3526
    /* interpreted as no-op */
3527
}
3528

    
3529
/* msync replaces sync on 440 */
3530
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
3531
{
3532
    /* interpreted as no-op */
3533
}
3534

    
3535
/* icbt */
3536
GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
3537
{
3538
    /* interpreted as no-op */
3539
    /* XXX: specification say this is treated as a load by the MMU
3540
     *      but does not generate any exception
3541
     */
3542
}
3543

    
3544
/* End opcode list */
3545
GEN_OPCODE_MARK(end);
3546

    
3547
#include "translate_init.c"
3548

    
3549
/*****************************************************************************/
3550
/* Misc PowerPC helpers */
3551
static inline uint32_t load_xer (CPUState *env)
3552
{
3553
    return (xer_so << XER_SO) |
3554
        (xer_ov << XER_OV) |
3555
        (xer_ca << XER_CA) |
3556
        (xer_bc << XER_BC) |
3557
        (xer_cmp << XER_CMP);
3558
}
3559

    
3560
void cpu_dump_state(CPUState *env, FILE *f, 
3561
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3562
                    int flags)
3563
{
3564
#if defined(TARGET_PPC64) || 1
3565
#define FILL ""
3566
#define RGPL  4
3567
#define RFPL  4
3568
#else
3569
#define FILL "        "
3570
#define RGPL  8
3571
#define RFPL  4
3572
#endif
3573

    
3574
    int i;
3575

    
3576
    cpu_fprintf(f, "NIP " REGX " LR " REGX " CTR " REGX "\n",
3577
                env->nip, env->lr, env->ctr);
3578
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      TB %08x %08x "
3579
#if !defined(CONFIG_USER_ONLY)
3580
                "DECR %08x"
3581
#endif
3582
                "\n",
3583
                do_load_msr(env), load_xer(env), cpu_ppc_load_tbu(env),
3584
                cpu_ppc_load_tbl(env)
3585
#if !defined(CONFIG_USER_ONLY)
3586
                , cpu_ppc_load_decr(env)
3587
#endif
3588
                );
3589
    for (i = 0; i < 32; i++) {
3590
        if ((i & (RGPL - 1)) == 0)
3591
            cpu_fprintf(f, "GPR%02d", i);
3592
        cpu_fprintf(f, " " REGX, env->gpr[i]);
3593
        if ((i & (RGPL - 1)) == (RGPL - 1))
3594
            cpu_fprintf(f, "\n");
3595
    }
3596
    cpu_fprintf(f, "CR ");
3597
    for (i = 0; i < 8; i++)
3598
        cpu_fprintf(f, "%01x", env->crf[i]);
3599
    cpu_fprintf(f, "  [");
3600
    for (i = 0; i < 8; i++) {
3601
        char a = '-';
3602
        if (env->crf[i] & 0x08)
3603
            a = 'L';
3604
        else if (env->crf[i] & 0x04)
3605
            a = 'G';
3606
        else if (env->crf[i] & 0x02)
3607
            a = 'E';
3608
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
3609
    }
3610
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
3611
    for (i = 0; i < 32; i++) {
3612
        if ((i & (RFPL - 1)) == 0)
3613
            cpu_fprintf(f, "FPR%02d", i);
3614
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
3615
        if ((i & (RFPL - 1)) == (RFPL - 1))
3616
            cpu_fprintf(f, "\n");
3617
    }
3618
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
3619
                "SDR1 " REGX "\n",
3620
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
3621

    
3622
#undef REGX
3623
#undef RGPL
3624
#undef RFPL
3625
#undef FILL
3626
}
3627

    
3628
void cpu_dump_statistics (CPUState *env, FILE*f,
3629
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3630
                          int flags)
3631
{
3632
#if defined(DO_PPC_STATISTICS)
3633
    opc_handler_t **t1, **t2, **t3, *handler;
3634
    int op1, op2, op3;
3635

    
3636
    t1 = env->opcodes;
3637
    for (op1 = 0; op1 < 64; op1++) {
3638
        handler = t1[op1];
3639
        if (is_indirect_opcode(handler)) {
3640
            t2 = ind_table(handler);
3641
            for (op2 = 0; op2 < 32; op2++) {
3642
                handler = t2[op2];
3643
                if (is_indirect_opcode(handler)) {
3644
                    t3 = ind_table(handler);
3645
                    for (op3 = 0; op3 < 32; op3++) {
3646
                        handler = t3[op3];
3647
                        if (handler->count == 0)
3648
                            continue;
3649
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
3650
                                    "%016llx %lld\n",
3651
                                    op1, op2, op3, op1, (op3 << 5) | op2,
3652
                                    handler->oname,
3653
                                    handler->count, handler->count);
3654
                    }
3655
                } else {
3656
                    if (handler->count == 0)
3657
                        continue;
3658
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
3659
                                "%016llx %lld\n",
3660
                                op1, op2, op1, op2, handler->oname,
3661
                                handler->count, handler->count);
3662
                }
3663
            }
3664
        } else {
3665
            if (handler->count == 0)
3666
                continue;
3667
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
3668
                        op1, op1, handler->oname,
3669
                        handler->count, handler->count);
3670
        }
3671
    }
3672
#endif
3673
}
3674

    
3675
/*****************************************************************************/
3676
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3677
                                    int search_pc)
3678
{
3679
    DisasContext ctx, *ctxp = &ctx;
3680
    opc_handler_t **table, *handler;
3681
    target_ulong pc_start;
3682
    uint16_t *gen_opc_end;
3683
    int j, lj = -1;
3684

    
3685
    pc_start = tb->pc;
3686
    gen_opc_ptr = gen_opc_buf;
3687
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3688
    gen_opparam_ptr = gen_opparam_buf;
3689
    nb_gen_labels = 0;
3690
    ctx.nip = pc_start;
3691
    ctx.tb = tb;
3692
    ctx.exception = EXCP_NONE;
3693
    ctx.spr_cb = env->spr_cb;
3694
#if defined(CONFIG_USER_ONLY)
3695
    ctx.mem_idx = msr_le;
3696
#else
3697
    ctx.supervisor = 1 - msr_pr;
3698
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
3699
#endif
3700
    ctx.fpu_enabled = msr_fp;
3701
    ctx.singlestep_enabled = env->singlestep_enabled;
3702
#if defined (DO_SINGLE_STEP) && 0
3703
    /* Single step trace mode */
3704
    msr_se = 1;
3705
#endif
3706
    /* Set env in case of segfault during code fetch */
3707
    while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
3708
        if (unlikely(env->nb_breakpoints > 0)) {
3709
            for (j = 0; j < env->nb_breakpoints; j++) {
3710
                if (env->breakpoints[j] == ctx.nip) {
3711
                    gen_op_update_nip(ctx.nip); 
3712
                    gen_op_debug();
3713
                    break;
3714
                }
3715
            }
3716
        }
3717
        if (unlikely(search_pc)) {
3718
            j = gen_opc_ptr - gen_opc_buf;
3719
            if (lj < j) {
3720
                lj++;
3721
                while (lj < j)
3722
                    gen_opc_instr_start[lj++] = 0;
3723
                gen_opc_pc[lj] = ctx.nip;
3724
                gen_opc_instr_start[lj] = 1;
3725
            }
3726
        }
3727
#if defined PPC_DEBUG_DISAS
3728
        if (loglevel & CPU_LOG_TB_IN_ASM) {
3729
            fprintf(logfile, "----------------\n");
3730
            fprintf(logfile, "nip=%08x super=%d ir=%d\n",
3731
                    ctx.nip, 1 - msr_pr, msr_ir);
3732
        }
3733
#endif
3734
        ctx.opcode = ldl_code(ctx.nip);
3735
        if (msr_le) {
3736
            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
3737
                ((ctx.opcode & 0x00FF0000) >> 8) |
3738
                ((ctx.opcode & 0x0000FF00) << 8) |
3739
                ((ctx.opcode & 0x000000FF) << 24);
3740
        }
3741
#if defined PPC_DEBUG_DISAS
3742
        if (loglevel & CPU_LOG_TB_IN_ASM) {
3743
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
3744
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
3745
                    opc3(ctx.opcode), msr_le ? "little" : "big");
3746
        }
3747
#endif
3748
        ctx.nip += 4;
3749
        table = env->opcodes;
3750
        handler = table[opc1(ctx.opcode)];
3751
        if (is_indirect_opcode(handler)) {
3752
            table = ind_table(handler);
3753
            handler = table[opc2(ctx.opcode)];
3754
            if (is_indirect_opcode(handler)) {
3755
                table = ind_table(handler);
3756
                handler = table[opc3(ctx.opcode)];
3757
            }
3758
        }
3759
        /* Is opcode *REALLY* valid ? */
3760
        if (unlikely(handler->handler == &gen_invalid)) {
3761
            if (loglevel > 0) {
3762
                fprintf(logfile, "invalid/unsupported opcode: "
3763
                        "%02x - %02x - %02x (%08x) 0x%08x %d\n",
3764
                        opc1(ctx.opcode), opc2(ctx.opcode),
3765
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
3766
            } else {
3767
                printf("invalid/unsupported opcode: "
3768
                       "%02x - %02x - %02x (%08x) 0x%08x %d\n",
3769
                       opc1(ctx.opcode), opc2(ctx.opcode),
3770
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
3771
            }
3772
        } else {
3773
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
3774
                if (loglevel > 0) {
3775
                    fprintf(logfile, "invalid bits: %08x for opcode: "
3776
                            "%02x -%02x - %02x (0x%08x) (0x%08x)\n",
3777
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
3778
                            opc2(ctx.opcode), opc3(ctx.opcode),
3779
                            ctx.opcode, ctx.nip - 4);
3780
                } else {
3781
                    printf("invalid bits: %08x for opcode: "
3782
                           "%02x -%02x - %02x (0x%08x) (0x%08x)\n",
3783
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
3784
                           opc2(ctx.opcode), opc3(ctx.opcode),
3785
                           ctx.opcode, ctx.nip - 4);
3786
                }
3787
                RET_INVAL(ctxp);
3788
                break;
3789
            }
3790
        }
3791
        (*(handler->handler))(&ctx);
3792
#if defined(DO_PPC_STATISTICS)
3793
        handler->count++;
3794
#endif
3795
        /* Check trace mode exceptions */
3796
        if (unlikely((msr_be && ctx.exception == EXCP_BRANCH) ||
3797
                     /* Check in single step trace mode
3798
                      * we need to stop except if:
3799
                      * - rfi, trap or syscall
3800
                      * - first instruction of an exception handler
3801
                      */
3802
                     (msr_se && (ctx.nip < 0x100 ||
3803
                                 ctx.nip > 0xF00 ||
3804
                                 (ctx.nip & 0xFC) != 0x04) &&
3805
                      ctx.exception != EXCP_SYSCALL &&
3806
                      ctx.exception != EXCP_SYSCALL_USER &&
3807
                      ctx.exception != EXCP_TRAP))) {
3808
            RET_EXCP(ctxp, EXCP_TRACE, 0);
3809
        }
3810
        /* if we reach a page boundary or are single stepping, stop
3811
         * generation
3812
         */
3813
        if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
3814
                     (env->singlestep_enabled))) {
3815
            break;
3816
        }
3817
#if defined (DO_SINGLE_STEP)
3818
        break;
3819
#endif
3820
    }
3821
    if (ctx.exception == EXCP_NONE) {
3822
        gen_goto_tb(&ctx, 0, ctx.nip);
3823
    } else if (ctx.exception != EXCP_BRANCH) {
3824
        gen_op_reset_T0();
3825
        /* Generate the return instruction */
3826
        gen_op_exit_tb();
3827
    }
3828
    *gen_opc_ptr = INDEX_op_end;
3829
    if (unlikely(search_pc)) {
3830
        j = gen_opc_ptr - gen_opc_buf;
3831
        lj++;
3832
        while (lj <= j)
3833
            gen_opc_instr_start[lj++] = 0;
3834
        tb->size = 0;
3835
    } else {
3836
        tb->size = ctx.nip - pc_start;
3837
    }
3838
#ifdef DEBUG_DISAS
3839
    if (loglevel & CPU_LOG_TB_CPU) {
3840
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
3841
        cpu_dump_state(env, logfile, fprintf, 0);
3842
    }
3843
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3844
        int flags;
3845
        flags = msr_le;
3846
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3847
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
3848
        fprintf(logfile, "\n");
3849
    }
3850
    if (loglevel & CPU_LOG_TB_OP) {
3851
        fprintf(logfile, "OP:\n");
3852
        dump_ops(gen_opc_buf, gen_opparam_buf);
3853
        fprintf(logfile, "\n");
3854
    }
3855
#endif
3856
    return 0;
3857
}
3858

    
3859
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3860
{
3861
    return gen_intermediate_code_internal(env, tb, 0);
3862
}
3863

    
3864
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3865
{
3866
    return gen_intermediate_code_internal(env, tb, 1);
3867
}