Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ fb0eaffc

History | View | Annotate | Download (86.3 kB)

1
/*
2
 *  PPC emulation for qemu: main translation routines.
3
 * 
4
 *  Copyright (c) 2003 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 "dyngen-exec.h"
21
#include "cpu.h"
22
#include "exec.h"
23
#include "disas.h"
24

    
25
//#define DO_SINGLE_STEP
26
//#define DO_STEP_FLUSH
27

    
28
enum {
29
#define DEF(s, n, copy_size) INDEX_op_ ## s,
30
#include "opc.h"
31
#undef DEF
32
    NB_OPS,
33
};
34

    
35
static uint16_t *gen_opc_ptr;
36
static uint32_t *gen_opparam_ptr;
37

    
38
#include "gen-op.h"
39

    
40
typedef void (GenOpFunc)(void);
41
typedef void (GenOpFunc1)(long);
42
typedef void (GenOpFunc2)(long, long);
43
typedef void (GenOpFunc3)(long, long, long);
44

    
45
#define GEN8(func, NAME) \
46
static GenOpFunc *NAME ## _table [8] = {\
47
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\
48
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\
49
};\
50
static inline void func(int n)\
51
{\
52
    NAME ## _table[n]();\
53
}
54

    
55
#define GEN32(func, NAME) \
56
static GenOpFunc *NAME ## _table [32] = {\
57
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\
58
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\
59
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,\
60
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,\
61
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,\
62
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,\
63
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,\
64
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,\
65
};\
66
static inline void func(int n)\
67
{\
68
    NAME ## _table[n]();\
69
}
70

    
71
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf)
72
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf)
73
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf)
74
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf)
75

    
76
/* Floating point condition and status register moves */
77
GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
78
GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
79
GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
80
static GenOpFunc1 *gen_op_store_T0_fpscri_fpscr_table[8] = {
81
    &gen_op_store_T0_fpscri_fpscr0,
82
    &gen_op_store_T0_fpscri_fpscr1,
83
    &gen_op_store_T0_fpscri_fpscr2,
84
    &gen_op_store_T0_fpscri_fpscr3,
85
    &gen_op_store_T0_fpscri_fpscr4,
86
    &gen_op_store_T0_fpscri_fpscr5,
87
    &gen_op_store_T0_fpscri_fpscr6,
88
    &gen_op_store_T0_fpscri_fpscr7,
89
};
90
static inline void gen_op_store_T0_fpscri(int n, uint8_t param)
91
{
92
    (*gen_op_store_T0_fpscri_fpscr_table[n])(param);
93
}
94

    
95
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr)
96
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr)
97
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr)
98

    
99
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr)
100
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr)
101
GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr)
102

    
103
/* floating point registers moves */
104
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
105
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
106
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
107
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
108
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
109
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
110

    
111
static uint8_t  spr_access[1024 / 2];
112

    
113
/* internal defines */
114
typedef struct DisasContext {
115
    struct TranslationBlock *tb;
116
    uint32_t *nip;
117
    uint32_t opcode;
118
    int exception;
119
    int retcode;
120
    /* Time base */
121
    uint32_t tb_offset;
122
    int supervisor;
123
} DisasContext;
124

    
125
typedef struct opc_handler_t {
126
    /* invalid bits */
127
    uint32_t inval;
128
    /* handler */
129
    void (*handler)(DisasContext *ctx);
130
} opc_handler_t;
131

    
132
#define SET_RETVAL(n)                                                         \
133
do {                                                                          \
134
    if ((n) != 0) {                                                           \
135
        ctx->exception = (n);                                                 \
136
    }                                                                         \
137
    return;                                                                   \
138
} while (0)
139

    
140
#define GET_RETVAL(func, __opcode)                                            \
141
({                                                                            \
142
    (func)(&ctx);                                                             \
143
    ctx.exception;                                                            \
144
})
145

    
146
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
147
static void gen_##name (DisasContext *ctx);                                   \
148
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
149
static void gen_##name (DisasContext *ctx)
150

    
151
/* Instruction types */
152
enum {
153
    PPC_INTEGER  = 0x0001, /* CPU has integer operations instructions        */
154
    PPC_FLOAT    = 0x0002, /* CPU has floating point operations instructions */
155
    PPC_FLOW     = 0x0004, /* CPU has flow control instructions              */
156
    PPC_MEM      = 0x0008, /* CPU has virtual memory instructions            */
157
    PPC_MISC     = 0x0010, /* CPU has spr/msr access instructions            */
158
    PPC_EXTERN   = 0x0020, /* CPU has external control instructions          */
159
    PPC_SEGMENT  = 0x0040, /* CPU has memory segment instructions            */
160
};
161

    
162
typedef struct opcode_t {
163
    unsigned char opc1, opc2, opc3;
164
    uint32_t type;
165
    opc_handler_t handler;
166
} opcode_t;
167

    
168
/* XXX: move that elsewhere */
169
extern FILE *logfile;
170
extern int loglevel;
171

    
172
/* XXX: shouldn't stay all alone here ! */
173
static int reserve = 0;
174

    
175
/***                           Instruction decoding                        ***/
176
#define EXTRACT_HELPER(name, shift, nb)                                       \
177
static inline uint32_t name (uint32_t opcode)                                 \
178
{                                                                             \
179
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
180
}
181

    
182
#define EXTRACT_SHELPER(name, shift, nb)                                      \
183
static inline int32_t name (uint32_t opcode)                                  \
184
{                                                                             \
185
    return s_ext16((opcode >> (shift)) & ((1 << (nb)) - 1));                  \
186
}
187

    
188
/* Opcode part 1 */
189
EXTRACT_HELPER(opc1, 26, 6);
190
/* Opcode part 2 */
191
EXTRACT_HELPER(opc2, 1, 5);
192
/* Opcode part 3 */
193
EXTRACT_HELPER(opc3, 6, 5);
194
/* Update Cr0 flags */
195
EXTRACT_HELPER(Rc, 0, 1);
196
/* Destination */
197
EXTRACT_HELPER(rD, 21, 5);
198
/* Source */
199
EXTRACT_HELPER(rS, 21, 5);
200
/* First operand */
201
EXTRACT_HELPER(rA, 16, 5);
202
/* Second operand */
203
EXTRACT_HELPER(rB, 11, 5);
204
/* Third operand */
205
EXTRACT_HELPER(rC, 6, 5);
206
/***                               Get CRn                                 ***/
207
EXTRACT_HELPER(crfD, 23, 3);
208
EXTRACT_HELPER(crfS, 18, 3);
209
EXTRACT_HELPER(crbD, 21, 5);
210
EXTRACT_HELPER(crbA, 16, 5);
211
EXTRACT_HELPER(crbB, 11, 5);
212
/* SPR / TBL */
213
EXTRACT_HELPER(SPR, 11, 10);
214
/***                              Get constants                            ***/
215
EXTRACT_HELPER(IMM, 12, 8);
216
/* 16 bits signed immediate value */
217
EXTRACT_SHELPER(SIMM, 0, 16);
218
/* 16 bits unsigned immediate value */
219
EXTRACT_HELPER(UIMM, 0, 16);
220
/* Bit count */
221
EXTRACT_HELPER(NB, 11, 5);
222
/* Shift count */
223
EXTRACT_HELPER(SH, 11, 5);
224
/* Mask start */
225
EXTRACT_HELPER(MB, 6, 5);
226
/* Mask end */
227
EXTRACT_HELPER(ME, 1, 5);
228
/* Trap operand */
229
EXTRACT_HELPER(TO, 21, 5);
230

    
231
EXTRACT_HELPER(CRM, 12, 8);
232
EXTRACT_HELPER(FM, 17, 8);
233
EXTRACT_HELPER(SR, 16, 4);
234
EXTRACT_HELPER(FPIMM, 20, 4);
235

    
236
/***                            Jump target decoding                       ***/
237
/* Displacement */
238
EXTRACT_SHELPER(d, 0, 16);
239
/* Immediate address */
240
static inline uint32_t LI (uint32_t opcode)
241
{
242
    return (opcode >> 0) & 0x03FFFFFC;
243
}
244

    
245
static inline uint32_t BD (uint32_t opcode)
246
{
247
    return (opcode >> 0) & 0xFFFC;
248
}
249

    
250
EXTRACT_HELPER(BO, 21, 5);
251
EXTRACT_HELPER(BI, 16, 5);
252
/* Absolute/relative address */
253
EXTRACT_HELPER(AA, 1, 1);
254
/* Link */
255
EXTRACT_HELPER(LK, 0, 1);
256

    
257
/* Create a mask between <start> and <end> bits */
258
static inline uint32_t MASK (uint32_t start, uint32_t end)
259
{
260
    uint32_t ret;
261

    
262
    ret = (((uint32_t)(-1)) >> (start)) ^ (((uint32_t)(-1) >> (end)) >> 1);
263
    if (start > end)
264
        return ~ret;
265

    
266
    return ret;
267
}
268

    
269
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
270
__attribute__ ((section(".opcodes"), unused))                                 \
271
static opcode_t opc_##name = {                                                \
272
    .opc1 = op1,                                                              \
273
    .opc2 = op2,                                                              \
274
    .opc3 = op3,                                                              \
275
    .type = _typ,                                                             \
276
    .handler = {                                                              \
277
        .inval   = invl,                                                      \
278
        .handler = &gen_##name,                                               \
279
    },                                                                        \
280
}
281

    
282
#define GEN_OPCODE_MARK(name)                                                 \
283
__attribute__ ((section(".opcodes"), unused))                                 \
284
static opcode_t opc_##name = {                                                \
285
    .opc1 = 0xFF,                                                             \
286
    .opc2 = 0xFF,                                                             \
287
    .opc3 = 0xFF,                                                             \
288
    .type = 0x00,                                                             \
289
    .handler = {                                                              \
290
        .inval   = 0x00000000,                                                \
291
        .handler = NULL,                                                      \
292
    },                                                                        \
293
}
294

    
295
/* Start opcode list */
296
GEN_OPCODE_MARK(start);
297

    
298
/* Invalid instruction */
299
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, 0)
300
{
301
    /* Branch to next instruction to force nip update */
302
    gen_op_b((uint32_t)ctx->nip);
303
    SET_RETVAL(EXCP_INVAL);
304
}
305

    
306
static opc_handler_t invalid_handler = {
307
    .inval   = 0xFFFFFFFF,
308
    .handler = gen_invalid,
309
};
310

    
311
/***                           Integer arithmetic                          ***/
312
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval)                       \
313
GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER)                       \
314
{                                                                             \
315
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
316
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
317
    gen_op_##name();                                                          \
318
    if (Rc(ctx->opcode) != 0)                                                 \
319
        gen_op_set_Rc0();                                                     \
320
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
321
    SET_RETVAL(0);                                                            \
322
}
323

    
324
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval)                     \
325
GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER)                       \
326
{                                                                             \
327
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
328
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
329
    gen_op_##name();                                                          \
330
    if (Rc(ctx->opcode) != 0)                                                 \
331
        gen_op_set_Rc0_ov();                                                  \
332
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
333
    SET_RETVAL(0);                                                            \
334
}
335

    
336
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3)                              \
337
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER)                  \
338
{                                                                             \
339
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
340
    gen_op_##name();                                                          \
341
    if (Rc(ctx->opcode) != 0)                                                 \
342
        gen_op_set_Rc0();                                                     \
343
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
344
    SET_RETVAL(0);                                                            \
345
}
346
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3)                            \
347
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER)                  \
348
{                                                                             \
349
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
350
    gen_op_##name();                                                          \
351
    if (Rc(ctx->opcode) != 0)                                                 \
352
        gen_op_set_Rc0_ov();                                                  \
353
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
354
    SET_RETVAL(0);                                                            \
355
}
356

    
357
/* Two operands arithmetic functions */
358
#define GEN_INT_ARITH2(name, opc1, opc2, opc3)                                \
359
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000)                          \
360
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000)
361

    
362
/* Two operands arithmetic functions with no overflow allowed */
363
#define GEN_INT_ARITHN(name, opc1, opc2, opc3)                                \
364
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400)
365

    
366
/* One operand arithmetic functions */
367
#define GEN_INT_ARITH1(name, opc1, opc2, opc3)                                \
368
__GEN_INT_ARITH1(name, opc1, opc2, opc3)                                      \
369
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10)
370

    
371
/* add    add.    addo    addo.    */
372
GEN_INT_ARITH2 (add,    0x1F, 0x0A, 0x08);
373
/* addc   addc.   addco   addco.   */
374
GEN_INT_ARITH2 (addc,   0x1F, 0x0A, 0x00);
375
/* adde   adde.   addeo   addeo.   */
376
GEN_INT_ARITH2 (adde,   0x1F, 0x0A, 0x04);
377
/* addme  addme.  addmeo  addmeo.  */
378
GEN_INT_ARITH1 (addme,  0x1F, 0x0A, 0x07);
379
/* addze  addze.  addzeo  addzeo.  */
380
GEN_INT_ARITH1 (addze,  0x1F, 0x0A, 0x06);
381
/* divw   divw.   divwo   divwo.   */
382
GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F);
383
/* divwu  divwu.  divwuo  divwuo.  */
384
GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E);
385
/* mulhw  mulhw.                   */
386
GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02);
387
/* mulhwu mulhwu.                  */
388
GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00);
389
/* mullw  mullw.  mullwo  mullwo.  */
390
GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07);
391
/* neg    neg.    nego    nego.    */
392
GEN_INT_ARITH1 (neg,    0x1F, 0x08, 0x03);
393
/* subf   subf.   subfo   subfo.   */
394
GEN_INT_ARITH2 (subf,   0x1F, 0x08, 0x01);
395
/* subfc  subfc.  subfco  subfco.  */
396
GEN_INT_ARITH2 (subfc,  0x1F, 0x08, 0x00);
397
/* subfe  subfe.  subfeo  subfeo.  */
398
GEN_INT_ARITH2 (subfe,  0x1F, 0x08, 0x04);
399
/* subfme subfme. subfmeo subfmeo. */
400
GEN_INT_ARITH1 (subfme, 0x1F, 0x08, 0x07);
401
/* subfze subfze. subfzeo subfzeo. */
402
GEN_INT_ARITH1 (subfze, 0x1F, 0x08, 0x06);
403
/* addi */
404
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
405
{
406
    int32_t simm = SIMM(ctx->opcode);
407

    
408
    if (rA(ctx->opcode) == 0) {
409
        gen_op_set_T0(simm);
410
    } else {
411
        gen_op_load_gpr_T0(rA(ctx->opcode));
412
        gen_op_addi(simm);
413
    }
414
    gen_op_store_T0_gpr(rD(ctx->opcode));
415
    SET_RETVAL(0);
416
}
417
/* addic */
418
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
419
{
420
    gen_op_load_gpr_T0(rA(ctx->opcode));
421
    gen_op_addic(SIMM(ctx->opcode));
422
    gen_op_store_T0_gpr(rD(ctx->opcode));
423
    SET_RETVAL(0);
424
}
425
/* addic. */
426
GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
427
{
428
    gen_op_load_gpr_T0(rA(ctx->opcode));
429
    gen_op_addic(SIMM(ctx->opcode));
430
    gen_op_set_Rc0();
431
    gen_op_store_T0_gpr(rD(ctx->opcode));
432
    SET_RETVAL(0);
433
}
434
/* addis */
435
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
436
{
437
    int32_t simm = SIMM(ctx->opcode);
438

    
439
    if (rA(ctx->opcode) == 0) {
440
        gen_op_set_T0(simm << 16);
441
    } else {
442
        gen_op_load_gpr_T0(rA(ctx->opcode));
443
        gen_op_addi(simm << 16);
444
    }
445
    gen_op_store_T0_gpr(rD(ctx->opcode));
446
    SET_RETVAL(0);
447
}
448
/* mulli */
449
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
450
{
451
    gen_op_load_gpr_T0(rA(ctx->opcode));
452
    gen_op_mulli(SIMM(ctx->opcode));
453
    gen_op_store_T0_gpr(rD(ctx->opcode));
454
    SET_RETVAL(0);
455
}
456
/* subfic */
457
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
458
{
459
    gen_op_load_gpr_T0(rA(ctx->opcode));
460
    gen_op_subfic(SIMM(ctx->opcode));
461
    gen_op_store_T0_gpr(rD(ctx->opcode));
462
    SET_RETVAL(0);
463
}
464

    
465
/***                           Integer comparison                          ***/
466
#define GEN_CMP(name, opc)                                                    \
467
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, PPC_INTEGER)                   \
468
{                                                                             \
469
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
470
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
471
    gen_op_##name();                                                          \
472
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
473
    SET_RETVAL(0);                                                            \
474
}
475

    
476
/* cmp */
477
GEN_CMP(cmp, 0x00);
478
/* cmpi */
479
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
480
{
481
    gen_op_load_gpr_T0(rA(ctx->opcode));
482
    gen_op_cmpi(SIMM(ctx->opcode));
483
    gen_op_store_T0_crf(crfD(ctx->opcode));
484
    SET_RETVAL(0);
485
}
486
/* cmpl */
487
GEN_CMP(cmpl, 0x01);
488
/* cmpli */
489
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
490
{
491
    gen_op_load_gpr_T0(rA(ctx->opcode));
492
    gen_op_cmpli(UIMM(ctx->opcode));
493
    gen_op_store_T0_crf(crfD(ctx->opcode));
494
    SET_RETVAL(0);
495
}
496

    
497
/***                            Integer logical                            ***/
498
#define __GEN_LOGICAL2(name, opc2, opc3)                                      \
499
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, PPC_INTEGER)                  \
500
{                                                                             \
501
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
502
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
503
    gen_op_##name();                                                          \
504
    if (Rc(ctx->opcode) != 0)                                                 \
505
        gen_op_set_Rc0();                                                     \
506
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
507
    SET_RETVAL(0);                                                            \
508
}
509
#define GEN_LOGICAL2(name, opc)                                               \
510
__GEN_LOGICAL2(name, 0x1C, opc)
511

    
512
#define GEN_LOGICAL1(name, opc)                                               \
513
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, PPC_INTEGER)                   \
514
{                                                                             \
515
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
516
    gen_op_##name();                                                          \
517
    if (Rc(ctx->opcode) != 0)                                                 \
518
        gen_op_set_Rc0();                                                     \
519
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
520
    SET_RETVAL(0);                                                            \
521
}
522

    
523
/* and & and. */
524
GEN_LOGICAL2(and, 0x00);
525
/* andc & andc. */
526
GEN_LOGICAL2(andc, 0x01);
527
/* andi. */
528
GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
529
{
530
    gen_op_load_gpr_T0(rS(ctx->opcode));
531
    gen_op_andi_(UIMM(ctx->opcode));
532
    gen_op_set_Rc0();
533
    gen_op_store_T0_gpr(rA(ctx->opcode));
534
    SET_RETVAL(0);
535
}
536
/* andis. */
537
GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
538
{
539
    gen_op_load_gpr_T0(rS(ctx->opcode));
540
    gen_op_andi_(UIMM(ctx->opcode) << 16);
541
    gen_op_set_Rc0();
542
    gen_op_store_T0_gpr(rA(ctx->opcode));
543
    SET_RETVAL(0);
544
}
545

    
546
/* cntlzw */
547
GEN_LOGICAL1(cntlzw, 0x00);
548
/* eqv & eqv. */
549
GEN_LOGICAL2(eqv, 0x08);
550
/* extsb & extsb. */
551
GEN_LOGICAL1(extsb, 0x1D);
552
/* extsh & extsh. */
553
GEN_LOGICAL1(extsh, 0x1C);
554
/* nand & nand. */
555
GEN_LOGICAL2(nand, 0x0E);
556
/* nor & nor. */
557
GEN_LOGICAL2(nor, 0x03);
558
/* or & or. */
559
GEN_LOGICAL2(or, 0x0D);
560
/* orc & orc. */
561
GEN_LOGICAL2(orc, 0x0C);
562
/* xor & xor. */
563
GEN_LOGICAL2(xor, 0x09);
564
/* ori */
565
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
566
{
567
    uint32_t uimm = UIMM(ctx->opcode);
568

    
569
#if 0
570
    if (uimm == 0) {
571
        if (rA(ctx->opcode) != rS(ctx->opcode)) {
572
            gen_op_load_gpr_T0(rS(ctx->opcode));
573
            gen_op_store_T0_gpr(rA(ctx->opcode));
574
        }
575
    } else
576
#endif
577
    {
578
        gen_op_load_gpr_T0(rS(ctx->opcode));
579
        gen_op_ori(uimm);
580
        gen_op_store_T0_gpr(rA(ctx->opcode));
581
    }
582
    SET_RETVAL(0);
583
}
584
/* oris */
585
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
586
{
587
    uint32_t uimm = UIMM(ctx->opcode);
588

    
589
#if 0
590
    if (uimm == 0) {
591
        if (rA(ctx->opcode) != rS(ctx->opcode)) {
592
            gen_op_load_gpr_T0(rS(ctx->opcode));
593
            gen_op_store_T0_gpr(rA(ctx->opcode));
594
        }
595
    } else
596
#endif
597
    {
598
        gen_op_load_gpr_T0(rS(ctx->opcode));
599
        gen_op_ori(uimm << 16);
600
        gen_op_store_T0_gpr(rA(ctx->opcode));
601
    }
602
    SET_RETVAL(0);
603
}
604
/* xori */
605
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
606
{
607
    gen_op_load_gpr_T0(rS(ctx->opcode));
608
    gen_op_xori(UIMM(ctx->opcode));
609
    gen_op_store_T0_gpr(rA(ctx->opcode));
610
    SET_RETVAL(0);
611
}
612

    
613
/* xoris */
614
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
615
{
616
    gen_op_load_gpr_T0(rS(ctx->opcode));
617
    gen_op_xori(UIMM(ctx->opcode) << 16);
618
    gen_op_store_T0_gpr(rA(ctx->opcode));
619
    SET_RETVAL(0);
620
}
621

    
622
/***                             Integer rotate                            ***/
623
/* rlwimi & rlwimi. */
624
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
625
{
626
    uint32_t mb, me;
627

    
628
    mb = MB(ctx->opcode);
629
    me = ME(ctx->opcode);
630
    gen_op_load_gpr_T0(rS(ctx->opcode));
631
    gen_op_load_gpr_T1(rA(ctx->opcode));
632
    gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me));
633
    if (Rc(ctx->opcode) != 0)
634
        gen_op_set_Rc0();
635
    gen_op_store_T0_gpr(rA(ctx->opcode));
636
    SET_RETVAL(0);
637
}
638
/* rlwinm & rlwinm. */
639
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
640
{
641
    uint32_t mb, me, sh;
642
    
643
    sh = SH(ctx->opcode);
644
    mb = MB(ctx->opcode);
645
    me = ME(ctx->opcode);
646
    gen_op_load_gpr_T0(rS(ctx->opcode));
647
    if (loglevel > 0) {
648
        fprintf(logfile, "%s sh=%u mb=%u me=%u MASK=0x%08x\n",
649
                __func__, sh, mb, me, MASK(mb, me));
650
    }
651
    if (mb == 0) {
652
        if (me == 31) {
653
            gen_op_rotlwi(sh);
654
            goto store;
655
        } else if (me == (31 - sh)) {
656
            gen_op_slwi(sh);
657
            goto store;
658
        } else if (sh == 0) {
659
            gen_op_andi_(MASK(0, me));
660
            goto store;
661
        }
662
    } else if (me == 31) {
663
        if (sh == (32 - mb)) {
664
            gen_op_srwi(mb);
665
            goto store;
666
        } else if (sh == 0) {
667
            gen_op_andi_(MASK(mb, 31));
668
            goto store;
669
        }
670
    }
671
    gen_op_rlwinm(sh, MASK(mb, me));
672
store:
673
    if (Rc(ctx->opcode) != 0)
674
        gen_op_set_Rc0();
675
    gen_op_store_T0_gpr(rA(ctx->opcode));
676
    SET_RETVAL(0);
677
}
678
/* rlwnm & rlwnm. */
679
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
680
{
681
    uint32_t mb, me;
682

    
683
    mb = MB(ctx->opcode);
684
    me = ME(ctx->opcode);
685
    gen_op_load_gpr_T0(rS(ctx->opcode));
686
    gen_op_load_gpr_T1(rB(ctx->opcode));
687
    if (mb == 0 && me == 31) {
688
        gen_op_rotl();
689
    } else
690
    {
691
        gen_op_rlwnm(MASK(mb, me));
692
    }
693
    if (Rc(ctx->opcode) != 0)
694
        gen_op_set_Rc0();
695
    gen_op_store_T0_gpr(rA(ctx->opcode));
696
    SET_RETVAL(0);
697
}
698

    
699
/***                             Integer shift                             ***/
700
/* slw & slw. */
701
__GEN_LOGICAL2(slw, 0x18, 0x00);
702
/* sraw & sraw. */
703
__GEN_LOGICAL2(sraw, 0x18, 0x18);
704
/* srawi & srawi. */
705
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
706
{
707
    gen_op_load_gpr_T0(rS(ctx->opcode));
708
    gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
709
    if (Rc(ctx->opcode) != 0)
710
        gen_op_set_Rc0();
711
    gen_op_store_T0_gpr(rA(ctx->opcode));
712
    SET_RETVAL(0);
713
}
714
/* srw & srw. */
715
__GEN_LOGICAL2(srw, 0x18, 0x10);
716

    
717
/***                       Floating-Point arithmetic                       ***/
718
/* fadd */
719
GEN_HANDLER(fadd, 0x3F, 0x15, 0xFF, 0x000007C0, PPC_FLOAT)
720
{
721
    SET_RETVAL(EXCP_INVAL);
722
}
723

    
724
/* fadds */
725
GEN_HANDLER(fadds, 0x3B, 0x15, 0xFF, 0x000007C0, PPC_FLOAT)
726
{
727
    SET_RETVAL(EXCP_INVAL);
728
}
729

    
730
/* fdiv */
731
GEN_HANDLER(fdiv, 0x3F, 0x12, 0xFF, 0x000007C0, PPC_FLOAT)
732
{
733
    SET_RETVAL(EXCP_INVAL);
734
}
735

    
736
/* fdivs */
737
GEN_HANDLER(fdivs, 0x3B, 0x12, 0xFF, 0x000007C0, PPC_FLOAT)
738
{
739
    SET_RETVAL(EXCP_INVAL);
740
}
741

    
742
/* fmul */
743
GEN_HANDLER(fmul, 0x3F, 0x19, 0xFF, 0x0000F800, PPC_FLOAT)
744
{
745
    SET_RETVAL(EXCP_INVAL);
746
}
747

    
748
/* fmuls */
749
GEN_HANDLER(fmuls, 0x3B, 0x19, 0xFF, 0x0000F800, PPC_FLOAT)
750
{
751
    SET_RETVAL(EXCP_INVAL);
752
}
753

    
754
/* fres */
755
GEN_HANDLER(fres, 0x3B, 0x18, 0xFF, 0x001807C0, PPC_FLOAT)
756
{
757
    SET_RETVAL(EXCP_INVAL);
758
}
759

    
760
/* frsqrte */
761
GEN_HANDLER(frsqrte, 0x3F, 0x1A, 0xFF, 0x001807C0, PPC_FLOAT)
762
{
763
    SET_RETVAL(EXCP_INVAL);
764
}
765

    
766
/* fsel */
767
GEN_HANDLER(fsel, 0x3F, 0x17, 0xFF, 0x00000000, PPC_FLOAT)
768
{
769
    SET_RETVAL(EXCP_INVAL);
770
}
771

    
772
/* fsub */
773
GEN_HANDLER(fsub, 0x3F, 0x14, 0xFF, 0x000007C0, PPC_FLOAT)
774
{
775
    SET_RETVAL(EXCP_INVAL);
776
}
777

    
778
/* fsubs */
779
GEN_HANDLER(fsubs, 0x3B, 0x14, 0xFF, 0x000007C0, PPC_FLOAT)
780
{
781
    SET_RETVAL(EXCP_INVAL);
782
}
783

    
784
/* Optional: */
785
/* fsqrt */
786
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001807C0, PPC_FLOAT)
787
{
788
    SET_RETVAL(EXCP_INVAL);
789
}
790

    
791
/* fsqrts */
792
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001807C0, PPC_FLOAT)
793
{
794
    SET_RETVAL(EXCP_INVAL);
795
}
796

    
797
/***                     Floating-Point multiply-and-add                   ***/
798
/* fmadd */
799
GEN_HANDLER(fmadd, 0x3F, 0x1D, 0xFF, 0x00000000, PPC_FLOAT)
800
{
801
    SET_RETVAL(EXCP_INVAL);
802
}
803

    
804
/* fmadds */
805
GEN_HANDLER(fmadds, 0x3B, 0x1D, 0xFF, 0x00000000, PPC_FLOAT)
806
{
807
    SET_RETVAL(EXCP_INVAL);
808
}
809

    
810
/* fmsub */
811
GEN_HANDLER(fmsub, 0x3F, 0x1C, 0xFF, 0x00000000, PPC_FLOAT)
812
{
813
    SET_RETVAL(EXCP_INVAL);
814
}
815

    
816
/* fmsubs */
817
GEN_HANDLER(fmsubs, 0x3B, 0x1C, 0xFF, 0x00000000, PPC_FLOAT)
818
{
819
    SET_RETVAL(EXCP_INVAL);
820
}
821

    
822
/* fnmadd */
823
GEN_HANDLER(fnmadd, 0x3F, 0x1F, 0xFF, 0x00000000, PPC_FLOAT)
824
{
825
    SET_RETVAL(EXCP_INVAL);
826
}
827

    
828
/* fnmadds */
829
GEN_HANDLER(fnmadds, 0x3B, 0x1F, 0xFF, 0x00000000, PPC_FLOAT)
830
{
831
    SET_RETVAL(EXCP_INVAL);
832
}
833

    
834
/* fnmsub */
835
GEN_HANDLER(fnmsub, 0x3F, 0x1E, 0xFF, 0x00000000, PPC_FLOAT)
836
{
837
    SET_RETVAL(EXCP_INVAL);
838
}
839

    
840
/* fnmsubs */
841
GEN_HANDLER(fnmsubs, 0x3B, 0x1E, 0xFF, 0x00000000, PPC_FLOAT)
842
{
843
    SET_RETVAL(EXCP_INVAL);
844
}
845

    
846
/***                     Floating-Point round & convert                    ***/
847
/* fctiw */
848
GEN_HANDLER(fctiw, 0x3F, 0x0E, 0xFF, 0x001F0000, PPC_FLOAT)
849
{
850
    SET_RETVAL(EXCP_INVAL);
851
}
852

    
853
/* fctiwz */
854
GEN_HANDLER(fctiwz, 0x3F, 0x0F, 0xFF, 0x001F0000, PPC_FLOAT)
855
{
856
    SET_RETVAL(EXCP_INVAL);
857
}
858

    
859
/* frsp */
860
GEN_HANDLER(frsp, 0x3F, 0x0C, 0xFF, 0x001F0000, PPC_FLOAT)
861
{
862
    SET_RETVAL(EXCP_INVAL);
863
}
864

    
865
/***                         Floating-Point compare                        ***/
866
/* fcmpo */
867
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
868
{
869
    SET_RETVAL(EXCP_INVAL);
870
}
871

    
872
/* fcmpu */
873
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
874
{
875
    SET_RETVAL(EXCP_INVAL);
876
}
877

    
878
/***                  Floating-Point status & ctrl register                ***/
879
/* mcrfs */
880
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
881
{
882
    gen_op_load_fpscr_T0(crfS(ctx->opcode));
883
    gen_op_store_T0_crf(crfD(ctx->opcode));
884
    gen_op_clear_fpscr(crfS(ctx->opcode));
885
    SET_RETVAL(0);
886
}
887

    
888
/* mffs */
889
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
890
{
891
    gen_op_load_fpscr();
892
    gen_op_store_FT0_fpr(rD(ctx->opcode));
893
    if (Rc(ctx->opcode))
894
        gen_op_set_Rc1();
895
    SET_RETVAL(0);
896
}
897

    
898
/* mtfsb0 */
899
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
900
{
901
    uint8_t crb;
902
    
903
    crb = crbD(ctx->opcode) >> 2;
904
    gen_op_load_fpscr_T0(crb);
905
    gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03)));
906
    gen_op_store_T0_fpscr(crb);
907
    if (Rc(ctx->opcode))
908
        gen_op_set_Rc1();
909
    SET_RETVAL(0);
910
}
911

    
912
/* mtfsb1 */
913
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
914
{
915
    uint8_t crb;
916
    
917
    crb = crbD(ctx->opcode) >> 2;
918
    gen_op_load_fpscr_T0(crb);
919
    gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
920
    gen_op_store_T0_fpscr(crb);
921
    if (Rc(ctx->opcode))
922
        gen_op_set_Rc1();
923
    SET_RETVAL(0);
924
}
925

    
926
/* mtfsf */
927
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
928
{
929
    gen_op_load_fpr_FT0(rB(ctx->opcode));
930
    gen_op_store_fpscr(FM(ctx->opcode));
931
    if (Rc(ctx->opcode))
932
        gen_op_set_Rc1();
933
    SET_RETVAL(0);
934
}
935

    
936
/* mtfsfi */
937
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
938
{
939
    gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
940
    if (Rc(ctx->opcode))
941
        gen_op_set_Rc1();
942
    SET_RETVAL(0);
943
}
944

    
945
/***                             Integer load                              ***/
946
#define GEN_ILDZ(width, opc)                                                  \
947
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)               \
948
{                                                                             \
949
    uint32_t simm = SIMM(ctx->opcode);                                        \
950
    if (rA(ctx->opcode) == 0) {                                               \
951
        gen_op_l##width##_z(simm);                                            \
952
    } else {                                                                  \
953
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
954
        gen_op_l##width (simm);                                               \
955
    }                                                                         \
956
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
957
    SET_RETVAL(0);                                                            \
958
}
959

    
960
#define GEN_ILDZU(width, opc)                                                 \
961
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)            \
962
{                                                                             \
963
    if (rA(ctx->opcode) == 0 ||                                               \
964
        rA(ctx->opcode) == rD(ctx->opcode))                                   \
965
        SET_RETVAL(EXCP_INVAL);                                               \
966
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
967
    gen_op_l##width(SIMM(ctx->opcode));                                       \
968
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
969
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
970
    SET_RETVAL(0);                                                            \
971
}
972

    
973
#define GEN_ILDZUX(width, opc)                                                \
974
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)           \
975
{                                                                             \
976
    if (rA(ctx->opcode) == 0 ||                                               \
977
        rA(ctx->opcode) == rD(ctx->opcode))                                   \
978
        SET_RETVAL(EXCP_INVAL);                                               \
979
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
980
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
981
    gen_op_l##width##x();                                                     \
982
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
983
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
984
    SET_RETVAL(0);                                                            \
985
}
986

    
987
#define GEN_ILDZX(width, opc2, opc3)                                          \
988
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)           \
989
{                                                                             \
990
    if (rA(ctx->opcode) == 0) {                                               \
991
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
992
        gen_op_l##width##x_z();                                               \
993
    } else {                                                                  \
994
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
995
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
996
        gen_op_l##width##x();                                                 \
997
    }                                                                         \
998
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
999
    SET_RETVAL(0);                                                            \
1000
}
1001

    
1002
#define GEN_ILD(width, op)                                                    \
1003
GEN_ILDZ(width, op | 0x20)                                                    \
1004
GEN_ILDZU(width, op | 0x21)                                                   \
1005
GEN_ILDZUX(width, op | 0x01)                                                  \
1006
GEN_ILDZX(width, 0x17, op | 0x00)
1007

    
1008
/* lbz lbzu lbzux lbzx */
1009
GEN_ILD(bz, 0x02);
1010
/* lha lhau lhaux lhax */
1011
GEN_ILD(ha, 0x0A);
1012
/* lhz lhzu lhzux lhzx */
1013
GEN_ILD(hz, 0x08);
1014
/* lwz lwzu lwzux lwzx */
1015
GEN_ILD(wz, 0x00);
1016

    
1017
/***                              Integer store                            ***/
1018
#define GEN_IST(width, opc)                                                   \
1019
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)              \
1020
{                                                                             \
1021
    uint32_t simm = SIMM(ctx->opcode);                                        \
1022
    if (rA(ctx->opcode) == 0) {                                               \
1023
        gen_op_load_gpr_T0(rS(ctx->opcode));                                  \
1024
        gen_op_st##width##_z(simm);                                           \
1025
    } else {                                                                  \
1026
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1027
        gen_op_load_gpr_T1(rS(ctx->opcode));                                  \
1028
        gen_op_st##width(simm);                                               \
1029
    }                                                                         \
1030
    SET_RETVAL(0);                                                            \
1031
}
1032

    
1033
#define GEN_ISTU(width, opc)                                                  \
1034
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)           \
1035
{                                                                             \
1036
    if (rA(ctx->opcode) == 0)                                                 \
1037
        SET_RETVAL(EXCP_INVAL);                                               \
1038
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1039
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1040
    gen_op_st##width(SIMM(ctx->opcode));                                      \
1041
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1042
    SET_RETVAL(0);                                                            \
1043
}
1044

    
1045
#define GEN_ISTUX(width, opc)                                                 \
1046
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
1047
{                                                                             \
1048
    if (rA(ctx->opcode) == 0)                                                 \
1049
        SET_RETVAL(EXCP_INVAL);                                               \
1050
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1051
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1052
    gen_op_load_gpr_T2(rS(ctx->opcode));                                      \
1053
    gen_op_st##width##x();                                                    \
1054
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1055
    SET_RETVAL(0);                                                            \
1056
}
1057

    
1058
#define GEN_ISTX(width, opc2, opc3)                                           \
1059
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)          \
1060
{                                                                             \
1061
    if (rA(ctx->opcode) == 0) {                                               \
1062
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1063
        gen_op_load_gpr_T1(rS(ctx->opcode));                                  \
1064
        gen_op_st##width##x_z();                                              \
1065
    } else {                                                                  \
1066
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1067
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1068
        gen_op_load_gpr_T2(rS(ctx->opcode));                                  \
1069
        gen_op_st##width##x();                                                \
1070
    }                                                                         \
1071
    SET_RETVAL(0);                                                            \
1072
}
1073

    
1074
#define GEN_ISTO(width, opc)                                                  \
1075
GEN_IST(width, opc | 0x20)                                                    \
1076
GEN_ISTU(width, opc | 0x21)                                                   \
1077
GEN_ISTUX(width, opc | 0x01)                                                  \
1078
GEN_ISTX(width, 0x17, opc | 0x00)
1079

    
1080
/* stb stbu stbux stbx */
1081
GEN_ISTO(b, 0x06);
1082
/* sth sthu sthux sthx */
1083
GEN_ISTO(h, 0x0C);
1084
/* stw stwu stwux stwx */
1085
GEN_ISTO(w, 0x04);
1086

    
1087
/***                Integer load and store with byte reverse               ***/
1088
/* lhbrx */
1089
GEN_ILDZX(hbr, 0x16, 0x18);
1090
/* lwbrx */
1091
GEN_ILDZX(wbr, 0x16, 0x10);
1092
/* sthbrx */
1093
GEN_ISTX(hbr, 0x16, 0x1C);
1094
/* stwbrx */
1095
GEN_ISTX(wbr, 0x16, 0x14);
1096

    
1097
/***                    Integer load and store multiple                    ***/
1098
/* lmw */
1099
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1100
{
1101
    if (rA(ctx->opcode) == 0) {
1102
        gen_op_set_T0(0);
1103
    } else {
1104
        gen_op_load_gpr_T0(rA(ctx->opcode));
1105
    }
1106
    gen_op_lmw(rD(ctx->opcode), SIMM(ctx->opcode));
1107
    SET_RETVAL(0);
1108
}
1109

    
1110
/* stmw */
1111
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1112
{
1113
    if (rA(ctx->opcode) == 0) {
1114
        gen_op_set_T0(0);
1115
    } else {
1116
        gen_op_load_gpr_T0(rA(ctx->opcode));
1117
    }
1118
    gen_op_stmw(rS(ctx->opcode), SIMM(ctx->opcode));
1119
    SET_RETVAL(0);
1120
}
1121

    
1122
/***                    Integer load and store strings                     ***/
1123
/* lswi */
1124
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
1125
{
1126
    int nb = NB(ctx->opcode);
1127
    int start = rD(ctx->opcode);
1128
    int nr;
1129

    
1130
    if (nb == 0)
1131
        nb = 32;
1132
    nr = nb / 4;
1133
    if ((start + nr) > 32) {
1134
        /* handle wrap around r0 */
1135
        if (rA(ctx->opcode) == 0) {
1136
            gen_op_set_T0(0);
1137
        } else {
1138
            gen_op_load_gpr_T0(rA(ctx->opcode));
1139
        }
1140
        gen_op_lswi(start, 4 * (32 - start));
1141
        nb -= 4 * (32 - start);
1142
        start = 0;
1143
    }
1144
    if (rA(ctx->opcode) == 0) {
1145
        gen_op_set_T0(0);
1146
    } else {
1147
        gen_op_load_gpr_T0(rA(ctx->opcode));
1148
    }
1149
    gen_op_lswi(start, nb);
1150
    SET_RETVAL(0);
1151
}
1152

    
1153
/* lswx */
1154
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
1155
{
1156
    gen_op_load_xer_bc();
1157
    gen_op_load_gpr_T1(rB(ctx->opcode));
1158
    if (rA(ctx->opcode) == 0) {
1159
        gen_op_set_T2(0);
1160
    } else {
1161
        gen_op_load_gpr_T2(rA(ctx->opcode));
1162
    }
1163
    gen_op_lswx(rD(ctx->opcode));
1164
    SET_RETVAL(0);
1165
}
1166

    
1167
/* stswi */
1168
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
1169
{
1170
    int nb = NB(ctx->opcode);
1171
    int start = rS(ctx->opcode);
1172
    int nr;
1173

    
1174
    if (nb == 0)
1175
        nb = 32;
1176
    nr = nb / 4;
1177
    if ((start + nr) > 32) {
1178
        /* handle wrap around r0 */
1179
        if (rA(ctx->opcode) == 0) {
1180
            gen_op_set_T0(0);
1181
        } else {
1182
            gen_op_load_gpr_T0(rA(ctx->opcode));
1183
        }
1184
        gen_op_stswi(start, 4 * (32 - start));
1185
        nb -= 4 * (32 - start);
1186
        start = 0;
1187
    }
1188
    if (rA(ctx->opcode) == 0) {
1189
        gen_op_set_T0(0);
1190
    } else {
1191
        gen_op_load_gpr_T0(rA(ctx->opcode));
1192
    }
1193
    gen_op_stswi(start, nb);
1194
    SET_RETVAL(0);
1195
}
1196

    
1197
/* stswx */
1198
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
1199
{
1200
    gen_op_load_xer_bc();
1201
    gen_op_load_gpr_T1(rB(ctx->opcode));
1202
    if (rA(ctx->opcode) == 0) {
1203
        gen_op_set_T2(0);
1204
    } else {
1205
        gen_op_load_gpr_T2(rA(ctx->opcode));
1206
    }
1207
    gen_op_stswx(rS(ctx->opcode));
1208
    SET_RETVAL(0);
1209
}
1210

    
1211
/***                        Memory synchronisation                         ***/
1212
/* eieio */
1213
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM)
1214
{
1215
    /* Do a branch to next instruction */
1216
    gen_op_b((uint32_t)ctx->nip);
1217
    SET_RETVAL(EXCP_BRANCH);
1218
}
1219

    
1220
/* isync */
1221
GEN_HANDLER(isync, 0x13, 0x16, 0xFF, 0x03FF0801, PPC_MEM)
1222
{
1223
    /* Do a branch to next instruction */
1224
    gen_op_b((uint32_t)ctx->nip);
1225
    SET_RETVAL(EXCP_BRANCH);
1226
}
1227

    
1228
/* lwarx */
1229
GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_MEM)
1230
{
1231
    reserve = 1;
1232
    if (rA(ctx->opcode) == 0) {
1233
        gen_op_load_gpr_T0(rB(ctx->opcode));
1234
        gen_op_lwarx_z();
1235
    } else {
1236
        gen_op_load_gpr_T0(rA(ctx->opcode));
1237
        gen_op_load_gpr_T1(rB(ctx->opcode));
1238
        gen_op_lwarx();
1239
    }
1240
    gen_op_store_T1_gpr(rD(ctx->opcode));
1241
    SET_RETVAL(0);
1242
}
1243

    
1244
/* stwcx. */
1245
GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_MEM)
1246
{
1247
    if (reserve == 0) {
1248
        gen_op_reset_Rc0();
1249
    } else {
1250
        if (rA(ctx->opcode) == 0) {
1251
            gen_op_load_gpr_T0(rB(ctx->opcode));
1252
            gen_op_load_gpr_T1(rS(ctx->opcode));
1253
            gen_op_stwx_z();
1254
        } else {
1255
            gen_op_load_gpr_T0(rA(ctx->opcode));
1256
            gen_op_load_gpr_T1(rB(ctx->opcode));
1257
            gen_op_load_gpr_T2(rS(ctx->opcode));
1258
            gen_op_stwx();
1259
        }
1260
    }
1261
    SET_RETVAL(0);
1262
}
1263

    
1264
/* sync */
1265
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM)
1266
{
1267
    /* Do a branch to next instruction */
1268
    gen_op_b((uint32_t)ctx->nip);
1269
    SET_RETVAL(EXCP_BRANCH);
1270
}
1271

    
1272
/***                         Floating-point load                           ***/
1273
#define GEN_LF(width, opc)                                                    \
1274
GEN_HANDLER(lf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
1275
{                                                                             \
1276
    uint32_t simm = SIMM(ctx->opcode);                                        \
1277
    if (rA(ctx->opcode) == 0) {                                               \
1278
        gen_op_lf##width##_z_FT0(simm);                          \
1279
    } else {                                                                  \
1280
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1281
        gen_op_lf##width##_FT0(simm);                              \
1282
    }                                                                         \
1283
    gen_op_store_FT0_fpr(rD(ctx->opcode));\
1284
    SET_RETVAL(0);                                                            \
1285
}
1286

    
1287
#define GEN_LFU(width, opc)                                                   \
1288
GEN_HANDLER(lf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
1289
{                                                                             \
1290
    if (rA(ctx->opcode) == 0 ||                                               \
1291
        rA(ctx->opcode) == rD(ctx->opcode))                                   \
1292
        SET_RETVAL(EXCP_INVAL);                                               \
1293
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1294
    gen_op_lf##width##_FT0(SIMM(ctx->opcode));                     \
1295
    gen_op_store_FT0_fpr(rD(ctx->opcode));\
1296
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1297
    SET_RETVAL(0);                                                            \
1298
}
1299

    
1300
#define GEN_LFUX(width, opc)                                                  \
1301
GEN_HANDLER(lf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
1302
{                                                                             \
1303
    if (rA(ctx->opcode) == 0 ||                                               \
1304
        rA(ctx->opcode) == rD(ctx->opcode))                                   \
1305
        SET_RETVAL(EXCP_INVAL);                                               \
1306
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1307
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1308
    gen_op_lf##width##x_FT0();                                     \
1309
    gen_op_store_FT0_fpr(rD(ctx->opcode));\
1310
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1311
    SET_RETVAL(0);                                                            \
1312
}
1313

    
1314
#define GEN_LFX(width, opc)                                                   \
1315
GEN_HANDLER(lf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
1316
{                                                                             \
1317
    if (rA(ctx->opcode) == 0) {                                               \
1318
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1319
        gen_op_lf##width##x_z_FT0();                               \
1320
    } else {                                                                  \
1321
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1322
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1323
        gen_op_lf##width##x_FT0();                                 \
1324
    }                                                                         \
1325
    gen_op_store_FT0_fpr(rD(ctx->opcode));\
1326
    SET_RETVAL(0);                                                            \
1327
}
1328

    
1329
#define GEN_LDF(width, opc)                                                   \
1330
GEN_LF(width, opc | 0x20)                                                     \
1331
GEN_LFU(width, opc | 0x21)                                                    \
1332
GEN_LFUX(width, opc | 0x01)                                                   \
1333
GEN_LFX(width, opc | 0x00)
1334

    
1335
/* lfd lfdu lfdux lfdx */
1336
GEN_LDF(d, 0x12);
1337
/* lfs lfsu lfsux lfsx */
1338
GEN_LDF(s, 0x10);
1339

    
1340
/***                         Floating-point store                          ***/
1341
#define GEN_STF(width, opc)                                                   \
1342
GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)               \
1343
{                                                                             \
1344
    uint32_t simm = SIMM(ctx->opcode);                                        \
1345
    gen_op_load_fpr_FT0(rS(ctx->opcode));\
1346
    if (rA(ctx->opcode) == 0) {                                               \
1347
        gen_op_stf##width##_z_FT0(simm);                         \
1348
    } else {                                                                  \
1349
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1350
        gen_op_stf##width##_FT0(simm);                             \
1351
    }                                                                         \
1352
    SET_RETVAL(0);                                                            \
1353
}
1354

    
1355
#define GEN_STFU(width, opc)                                                  \
1356
GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)            \
1357
{                                                                             \
1358
    if (rA(ctx->opcode) == 0)                                                 \
1359
        SET_RETVAL(EXCP_INVAL);                                               \
1360
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1361
    gen_op_load_fpr_FT0(rS(ctx->opcode));\
1362
    gen_op_stf##width##_FT0(SIMM(ctx->opcode));                    \
1363
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1364
    SET_RETVAL(0);                                                            \
1365
}
1366

    
1367
#define GEN_STFUX(width, opc)                                                 \
1368
GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)           \
1369
{                                                                             \
1370
    if (rA(ctx->opcode) == 0)                                                 \
1371
        SET_RETVAL(EXCP_INVAL);                                               \
1372
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1373
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1374
    gen_op_load_fpr_FT0(rS(ctx->opcode));\
1375
    gen_op_stf##width##x_FT0();                                    \
1376
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1377
    SET_RETVAL(0);                                                            \
1378
}
1379

    
1380
#define GEN_STFX(width, opc)                                                  \
1381
GEN_HANDLER(stf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
1382
{                                                                             \
1383
    gen_op_load_fpr_FT0(rS(ctx->opcode));\
1384
    if (rA(ctx->opcode) == 0) {                                               \
1385
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1386
        gen_op_stf##width##x_z_FT0();                              \
1387
    } else {                                                                  \
1388
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1389
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1390
        gen_op_stf##width##x_FT0();                                \
1391
    }                                                                         \
1392
    SET_RETVAL(0);                                                            \
1393
}
1394

    
1395
#define GEN_STOF(width, opc)                                                  \
1396
GEN_STF(width, opc | 0x20)                                                    \
1397
GEN_STFU(width, opc | 0x21)                                                   \
1398
GEN_STFUX(width, opc | 0x01)                                                  \
1399
GEN_STFX(width, opc | 0x00)
1400

    
1401
/* stfd stfdu stfdux stfdx */
1402
GEN_STOF(d, 0x16);
1403
/* stfs stfsu stfsux stfsx */
1404
GEN_STOF(s, 0x14);
1405

    
1406
/* Optional: */
1407
/* stfiwx */
1408
GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1409
{
1410
    SET_RETVAL(EXCP_INVAL);
1411
}
1412

    
1413
/***                         Floating-point move                           ***/
1414
/* fabs */
1415
GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT)
1416
{
1417
    SET_RETVAL(EXCP_INVAL);
1418
}
1419

    
1420
/* fmr */
1421
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1422
{
1423
    SET_RETVAL(EXCP_INVAL);
1424
}
1425

    
1426
/* fnabs */
1427
GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT)
1428
{
1429
    SET_RETVAL(EXCP_INVAL);
1430
}
1431

    
1432
/* fneg */
1433
GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT)
1434
{
1435
    SET_RETVAL(EXCP_INVAL);
1436
}
1437

    
1438
/***                                Branch                                 ***/
1439
#define GEN_BCOND(name, opc1, opc2, opc3, prologue,                           \
1440
   bl_ctr,       b_ctr,       bl_ctrz,       b_ctrz,       b,                 \
1441
   bl_ctr_true,  b_ctr_true,  bl_ctrz_true,  b_ctrz_true,  bl_true,  b_true,  \
1442
   bl_ctr_false, b_ctr_false, bl_ctrz_false, b_ctrz_false, bl_false, b_false) \
1443
GEN_HANDLER(name, opc1, opc2, opc3, 0x00000000, PPC_FLOW)                     \
1444
{                                                                             \
1445
    __attribute__ ((unused)) uint32_t target;                                 \
1446
    uint32_t bo = BO(ctx->opcode);                                            \
1447
    uint32_t bi = BI(ctx->opcode);                                            \
1448
    uint32_t mask;                                                            \
1449
    prologue;                                                                 \
1450
    if ((bo & 0x4) == 0)                                                      \
1451
        gen_op_dec_ctr();                                                     \
1452
    if (bo & 0x10) {                                                          \
1453
        /* No CR condition */                                                 \
1454
        switch (bo & 0x6) {                                                   \
1455
        case 0:                                                               \
1456
            if (LK(ctx->opcode)) {                                            \
1457
                bl_ctr;                                                       \
1458
            } else {                                                          \
1459
                b_ctr;                                                        \
1460
            }                                                                 \
1461
            break;                                                            \
1462
        case 2:                                                               \
1463
            if (LK(ctx->opcode)) {                                            \
1464
                bl_ctrz;                                                      \
1465
            } else {                                                          \
1466
                b_ctrz;                                                       \
1467
            }                                                                 \
1468
            break;                                                            \
1469
        case 4:                                                               \
1470
        case 6:                                                               \
1471
            b;                                                                \
1472
            if (LK(ctx->opcode))                                              \
1473
                gen_op_load_lr((uint32_t)ctx->nip);                           \
1474
            break;                                                            \
1475
        default:                                                              \
1476
            printf("ERROR: %s: unhandled ba case (%d)\n", __func__, bo);      \
1477
            SET_RETVAL(EXCP_INVAL);                                           \
1478
            break;                                                            \
1479
        }                                                                     \
1480
    } else {                                                                  \
1481
        mask = 1 << (3 - (bi & 0x03));                                        \
1482
        gen_op_load_crf_T0(bi >> 2);                                          \
1483
        if (bo & 0x8) {                                                       \
1484
            switch (bo & 0x6) {                                               \
1485
            case 0:                                                           \
1486
                if (LK(ctx->opcode)) {                                        \
1487
                    bl_ctr_true;                                              \
1488
                } else {                                                      \
1489
                    b_ctr_true;                                               \
1490
                }                                                             \
1491
                break;                                                        \
1492
            case 2:                                                           \
1493
                if (LK(ctx->opcode)) {                                        \
1494
                    bl_ctrz_true;                                             \
1495
                } else {                                                      \
1496
                    b_ctrz_true;                                              \
1497
                }                                                             \
1498
                break;                                                        \
1499
            case 4:                                                           \
1500
            case 6:                                                           \
1501
                if (LK(ctx->opcode)) {                                        \
1502
                    bl_true;                                                  \
1503
                } else {                                                      \
1504
                    b_true;                                                   \
1505
                }                                                             \
1506
                break;                                                        \
1507
            default:                                                          \
1508
                printf("ERROR: %s: unhandled b case (%d)\n", __func__, bo);   \
1509
                SET_RETVAL(EXCP_INVAL);                                       \
1510
                break;                                                        \
1511
            }                                                                 \
1512
        } else {                                                              \
1513
            switch (bo & 0x6) {                                               \
1514
            case 0:                                                           \
1515
                if (LK(ctx->opcode)) {                                        \
1516
                    bl_ctr_false;                                             \
1517
                } else {                                                      \
1518
                    b_ctr_false;                                              \
1519
                }                                                             \
1520
                break;                                                        \
1521
            case 2:                                                           \
1522
                if (LK(ctx->opcode)) {                                        \
1523
                    bl_ctrz_false;                                            \
1524
                } else {                                                      \
1525
                    b_ctrz_false;                                             \
1526
                }                                                             \
1527
                break;                                                        \
1528
            case 4:                                                           \
1529
            case 6:                                                           \
1530
                if (LK(ctx->opcode)) {                                        \
1531
                    bl_false;                                                 \
1532
                } else {                                                      \
1533
                    b_false;                                                  \
1534
                }                                                             \
1535
                break;                                                        \
1536
            default:                                                          \
1537
                printf("ERROR: %s: unhandled bn case (%d)\n", __func__, bo);  \
1538
                SET_RETVAL(EXCP_INVAL);                                       \
1539
                break;                                                        \
1540
            }                                                                 \
1541
        }                                                                     \
1542
    }                                                                         \
1543
    SET_RETVAL(EXCP_BRANCH);                                                  \
1544
}
1545

    
1546
/* b ba bl bla */
1547
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1548
{
1549
    uint32_t li = s_ext24(LI(ctx->opcode)), target;
1550

    
1551
    if (AA(ctx->opcode) == 0)
1552
        target = (uint32_t)ctx->nip + li - 4;
1553
    else
1554
        target = s_ext24(LI(ctx->opcode));
1555
    gen_op_b(target);
1556
    if (LK(ctx->opcode))
1557
        gen_op_load_lr((uint32_t)ctx->nip);
1558
    SET_RETVAL(EXCP_BRANCH);
1559
}
1560

    
1561
/* bc bca bcl bcla */
1562
GEN_BCOND(bc, 0x10, 0xFF, 0xFF,
1563
          do {
1564
              uint32_t li = s_ext16(BD(ctx->opcode));
1565
              if (AA(ctx->opcode) == 0) {
1566
                  target = (uint32_t)ctx->nip + li - 4;
1567
              } else {
1568
                  target = li;
1569
              }
1570
          } while (0),
1571
          gen_op_bl_ctr((uint32_t)ctx->nip, target),
1572
          gen_op_b_ctr((uint32_t)ctx->nip, target),
1573
          gen_op_bl_ctrz((uint32_t)ctx->nip, target),
1574
          gen_op_b_ctrz((uint32_t)ctx->nip, target),
1575
          gen_op_b(target),
1576
          gen_op_bl_ctr_true((uint32_t)ctx->nip, target, mask),
1577
          gen_op_b_ctr_true((uint32_t)ctx->nip, target, mask),
1578
          gen_op_bl_ctrz_true((uint32_t)ctx->nip, target, mask),
1579
          gen_op_b_ctrz_true((uint32_t)ctx->nip, target, mask),
1580
          gen_op_bl_true((uint32_t)ctx->nip, target, mask),
1581
          gen_op_b_true((uint32_t)ctx->nip, target, mask),
1582
          gen_op_bl_ctr_false((uint32_t)ctx->nip, target, mask),
1583
          gen_op_b_ctr_false((uint32_t)ctx->nip, target, mask),
1584
          gen_op_bl_ctrz_false((uint32_t)ctx->nip, target, mask),
1585
          gen_op_b_ctrz_false((uint32_t)ctx->nip, target, mask),
1586
          gen_op_bl_false((uint32_t)ctx->nip, target, mask),
1587
          gen_op_b_false((uint32_t)ctx->nip, target, mask));
1588

    
1589
/* bcctr bcctrl */
1590
GEN_BCOND(bcctr, 0x13, 0x10, 0x10, do { } while (0),
1591
          gen_op_bctrl_ctr((uint32_t)ctx->nip),
1592
          gen_op_bctr_ctr((uint32_t)ctx->nip),
1593
          gen_op_bctrl_ctrz((uint32_t)ctx->nip),
1594
          gen_op_bctr_ctrz((uint32_t)ctx->nip),
1595
          gen_op_bctr(),
1596
          gen_op_bctrl_ctr_true((uint32_t)ctx->nip, mask),
1597
          gen_op_bctr_ctr_true((uint32_t)ctx->nip, mask),
1598
          gen_op_bctrl_ctrz_true((uint32_t)ctx->nip, mask),
1599
          gen_op_bctr_ctrz_true((uint32_t)ctx->nip, mask),
1600
          gen_op_bctrl_true((uint32_t)ctx->nip, mask),
1601
          gen_op_bctr_true((uint32_t)ctx->nip, mask),
1602
          gen_op_bctrl_ctr_false((uint32_t)ctx->nip, mask),
1603
          gen_op_bctr_ctr_false((uint32_t)ctx->nip, mask),
1604
          gen_op_bctrl_ctrz_false((uint32_t)ctx->nip, mask),
1605
          gen_op_bctr_ctrz_false((uint32_t)ctx->nip, mask),
1606
          gen_op_bctrl_false((uint32_t)ctx->nip, mask),
1607
          gen_op_bctr_false((uint32_t)ctx->nip, mask))
1608

    
1609
/* bclr bclrl */
1610
GEN_BCOND(bclr, 0x13, 0x10, 0x00, do { } while (0),
1611
          gen_op_blrl_ctr((uint32_t)ctx->nip),
1612
          gen_op_blr_ctr((uint32_t)ctx->nip),
1613
          gen_op_blrl_ctrz((uint32_t)ctx->nip),
1614
          gen_op_blr_ctrz((uint32_t)ctx->nip),
1615
          gen_op_blr(),
1616
          gen_op_blrl_ctr_true((uint32_t)ctx->nip, mask),
1617
          gen_op_blr_ctr_true((uint32_t)ctx->nip, mask),
1618
          gen_op_blrl_ctrz_true((uint32_t)ctx->nip, mask),
1619
          gen_op_blr_ctrz_true((uint32_t)ctx->nip, mask),
1620
          gen_op_blrl_true((uint32_t)ctx->nip, mask),
1621
          gen_op_blr_true((uint32_t)ctx->nip, mask),
1622
          gen_op_blrl_ctr_false((uint32_t)ctx->nip, mask),
1623
          gen_op_blr_ctr_false((uint32_t)ctx->nip, mask),
1624
          gen_op_blrl_ctrz_false((uint32_t)ctx->nip, mask),
1625
          gen_op_blr_ctrz_false((uint32_t)ctx->nip, mask),
1626
          gen_op_blrl_false((uint32_t)ctx->nip, mask),
1627
          gen_op_blr_false((uint32_t)ctx->nip, mask))
1628

    
1629
/***                      Condition register logical                       ***/
1630
#define GEN_CRLOGIC(op, opc)                                                  \
1631
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
1632
{                                                                             \
1633
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
1634
    gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
1635
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
1636
    gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
1637
    gen_op_##op();                                                            \
1638
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
1639
    gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
1640
                     3 - (crbD(ctx->opcode) & 0x03));                         \
1641
    gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
1642
    SET_RETVAL(0);                                                            \
1643
}
1644

    
1645
/* crand */
1646
GEN_CRLOGIC(and, 0x08)
1647
/* crandc */
1648
GEN_CRLOGIC(andc, 0x04)
1649
/* creqv */
1650
GEN_CRLOGIC(eqv, 0x09)
1651
/* crnand */
1652
GEN_CRLOGIC(nand, 0x07)
1653
/* crnor */
1654
GEN_CRLOGIC(nor, 0x01)
1655
/* cror */
1656
GEN_CRLOGIC(or, 0x0E)
1657
/* crorc */
1658
GEN_CRLOGIC(orc, 0x0D)
1659
/* crxor */
1660
GEN_CRLOGIC(xor, 0x06)
1661
/* mcrf */
1662
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
1663
{
1664
    gen_op_load_crf_T0(crfS(ctx->opcode));
1665
    gen_op_store_T0_crf(crfD(ctx->opcode));
1666
    SET_RETVAL(0);
1667
}
1668

    
1669
/***                           System linkage                              ***/
1670
/* rfi (supervisor only) */
1671
GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
1672
{
1673
    SET_RETVAL(EXCP_INVAL);
1674
}
1675

    
1676
/* sc */
1677
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
1678
{
1679
    gen_op_b((uint32_t)ctx->nip);
1680
    SET_RETVAL(EXCP_SYSCALL);
1681
}
1682

    
1683
/***                                Trap                                   ***/
1684
/* tw */
1685
GEN_HANDLER(tw, 0x1F, 0x04, 0xFF, 0x00000001, PPC_FLOW)
1686
{
1687
    SET_RETVAL(EXCP_INVAL);
1688
}
1689

    
1690
/* twi */
1691
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1692
{
1693
    SET_RETVAL(EXCP_INVAL);
1694
}
1695

    
1696
/***                          Processor control                            ***/
1697
static inline int check_spr_access (int spr, int rw, int supervisor)
1698
{
1699
    uint32_t rights = spr_access[spr >> 1] >> (4 * (spr & 1));
1700

    
1701
    rights = rights >> (2 * supervisor);
1702
    rights = rights >> rw;
1703

    
1704
    return rights & 1;
1705
}
1706

    
1707
/* mcrxr */
1708
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
1709
{
1710
    gen_op_load_xer_cr();
1711
    gen_op_store_T0_crf(crfD(ctx->opcode));
1712
    gen_op_clear_xer_cr();
1713
    SET_RETVAL(0);
1714
}
1715

    
1716
/* mfcr */
1717
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x001FF801, PPC_MISC)
1718
{
1719
    gen_op_load_cr();
1720
    gen_op_store_T0_gpr(rD(ctx->opcode));
1721
    SET_RETVAL(0);
1722
}
1723

    
1724
/* mfmsr */
1725
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1726
{
1727
    if (!ctx->supervisor)
1728
        SET_RETVAL(EXCP_PRIV);
1729
    gen_op_load_msr();
1730
    gen_op_store_T0_gpr(rD(ctx->opcode));
1731
    SET_RETVAL(0);
1732
}
1733

    
1734
/* mfspr */
1735
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
1736
{
1737
    uint32_t sprn = SPR(ctx->opcode);
1738

    
1739
    if (check_spr_access(sprn, 0, ctx->supervisor) == 0)
1740
        SET_RETVAL(EXCP_PRIV);
1741
    /* XXX: make this more generic */
1742
    switch (sprn) {
1743
    case SPR_ENCODE(1):
1744
        if (loglevel > 0) {
1745
            fprintf(logfile, "LOAD XER at %p\n", ctx->nip - 1);
1746
        }
1747
        gen_op_load_xer();
1748
        break;
1749
    case SPR_ENCODE(268):
1750
        /* We need to update the time base before reading it */
1751
        gen_op_update_tb(ctx->tb_offset);
1752
        ctx->tb_offset = 0;
1753
        break;
1754
    case SPR_ENCODE(269):
1755
        gen_op_update_tb(ctx->tb_offset);
1756
        ctx->tb_offset = 0;
1757
        break;
1758
    default:
1759
        gen_op_load_spr(sprn);
1760
        break;
1761
    }
1762
    gen_op_store_T0_gpr(rD(ctx->opcode)); //
1763
    SET_RETVAL(0);
1764
}
1765

    
1766
/* mftb */
1767
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC)
1768
{
1769
    uint32_t sprn = SPR(ctx->opcode);
1770

    
1771
    if (check_spr_access(sprn, 0, ctx->supervisor) == 0)
1772
        SET_RETVAL(EXCP_PRIV);
1773
    switch (sprn) {
1774
    case SPR_ENCODE(268):
1775
        /* We need to update the time base before reading it */
1776
        gen_op_update_tb(ctx->tb_offset);
1777
        ctx->tb_offset = 0;
1778
        break;
1779
    case SPR_ENCODE(269):
1780
        gen_op_update_tb(ctx->tb_offset);
1781
        ctx->tb_offset = 0;
1782
        break;
1783
    default:
1784
        SET_RETVAL(EXCP_INVAL);
1785
        break;
1786
    }
1787
    SET_RETVAL(0);
1788
}
1789

    
1790
/* mtcrf */
1791
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00100801, PPC_MISC)
1792
{
1793
    gen_op_load_gpr_T0(rS(ctx->opcode));
1794
    gen_op_store_cr(CRM(ctx->opcode));
1795
    SET_RETVAL(0);
1796
}
1797

    
1798
/* mtmsr */
1799
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
1800
{
1801
    if (!ctx->supervisor)
1802
        SET_RETVAL(EXCP_PRIV);
1803
    gen_op_load_gpr_T0(rS(ctx->opcode));
1804
    gen_op_store_msr();
1805
    /* Must stop the translation as machine state (may have) changed */
1806
    SET_RETVAL(EXCP_MTMSR);
1807
}
1808

    
1809
/* mtspr */
1810
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
1811
{
1812
    uint32_t sprn = SPR(ctx->opcode);
1813

    
1814
    if (check_spr_access(sprn, 1, ctx->supervisor) == 0)
1815
        SET_RETVAL(EXCP_PRIV);
1816
    gen_op_load_gpr_T0(rS(ctx->opcode));
1817
    if (sprn == SPR_ENCODE(1)) {
1818
        gen_op_store_xer();
1819
    } else {
1820
        gen_op_store_spr(sprn);
1821
    }
1822
    SET_RETVAL(0);
1823
}
1824

    
1825
/***                         Cache management                              ***/
1826
/* For now, all those will be implemented as nop:
1827
 * this is valid, regarding the PowerPC specs...
1828
 */
1829
/* dcbf */
1830
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x17, 0x03E00001, PPC_MEM)
1831
{
1832
    SET_RETVAL(0);
1833
}
1834

    
1835
/* dcbi (Supervisor only) */
1836
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_MEM)
1837
{
1838
    SET_RETVAL(0);
1839
}
1840

    
1841
/* dcdst */
1842
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_MEM)
1843
{
1844
    SET_RETVAL(0);
1845
}
1846

    
1847
/* dcbt */
1848
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x01, 0x03E00001, PPC_MEM)
1849
{
1850
    SET_RETVAL(0);
1851
}
1852

    
1853
/* dcbtst */
1854
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x02, 0x03E00001, PPC_MEM)
1855
{
1856
    SET_RETVAL(0);
1857
}
1858

    
1859
/* dcbz */
1860
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x08, 0x03E00001, PPC_MEM)
1861
{
1862
    if (rA(ctx->opcode) == 0) {
1863
        gen_op_load_gpr_T0(rB(ctx->opcode));
1864
        gen_op_dcbz_z();
1865
    } else {
1866
        gen_op_load_gpr_T0(rA(ctx->opcode));
1867
        gen_op_load_gpr_T1(rB(ctx->opcode));
1868
        gen_op_dcbz();
1869
    }
1870
    SET_RETVAL(0);
1871
}
1872

    
1873
/* icbi */
1874
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_MEM)
1875
{
1876
    if (rA(ctx->opcode) == 0) {
1877
        gen_op_load_gpr_T0(rB(ctx->opcode));
1878
        gen_op_icbi_z();
1879
    } else {
1880
        gen_op_load_gpr_T0(rA(ctx->opcode));
1881
        gen_op_load_gpr_T1(rB(ctx->opcode));
1882
        gen_op_icbi();
1883
    }
1884
    SET_RETVAL(0);
1885
}
1886

    
1887
/* Optional: */
1888
/* dcba */
1889
GEN_HANDLER(dcba, 0x1F, 0x16, 0x07, 0x03E00001, PPC_MEM)
1890
{
1891
    SET_RETVAL(0);
1892
}
1893

    
1894
/***                    Segment register manipulation                      ***/
1895
/* Supervisor only: */
1896
/* mfsr */
1897
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
1898
{
1899
    SET_RETVAL(EXCP_INVAL);
1900
}
1901

    
1902
/* mfsrin */
1903
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x0010F001, PPC_SEGMENT)
1904
{
1905
    SET_RETVAL(EXCP_INVAL);
1906
}
1907

    
1908
/* mtsr */
1909
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x02, 0x0010F801, PPC_SEGMENT)
1910
{
1911
    SET_RETVAL(EXCP_INVAL);
1912
}
1913

    
1914
/* mtsrin */
1915
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x0010F001, PPC_SEGMENT)
1916
{
1917
    SET_RETVAL(EXCP_INVAL);
1918
}
1919

    
1920
/***                      Lookaside buffer management                      ***/
1921
/* Optional & supervisor only: */
1922
/* tlbia */
1923
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM)
1924
{
1925
    SET_RETVAL(EXCP_INVAL);
1926
}
1927

    
1928
/* tlbie */
1929
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF8001, PPC_MEM)
1930
{
1931
    SET_RETVAL(EXCP_INVAL);
1932
}
1933

    
1934
/* tlbsync */
1935
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFFC01, PPC_MEM)
1936
{
1937
    SET_RETVAL(EXCP_INVAL);
1938
}
1939

    
1940
/***                              External control                         ***/
1941
/* Optional: */
1942
/* eciwx */
1943
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
1944
{
1945
    SET_RETVAL(EXCP_INVAL);
1946
}
1947

    
1948
/* ecowx */
1949
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
1950
{
1951
    SET_RETVAL(EXCP_INVAL);
1952
}
1953

    
1954
/* End opcode list */
1955
GEN_OPCODE_MARK(end);
1956

    
1957
/*****************************************************************************/
1958

    
1959
#include <string.h>
1960
extern FILE *stderr;
1961
void free (void *p);
1962
int fflush (FILE *f);
1963

    
1964
/* Main ppc opcodes table:
1965
 * at init, all opcodes are invalids
1966
 */
1967
static opc_handler_t *ppc_opcodes[0x40];
1968

    
1969
/* Opcode types */
1970
enum {
1971
    PPC_DIRECT   = 0, /* Opcode routine        */
1972
    PPC_INDIRECT = 1, /* Indirect opcode table */
1973
};
1974

    
1975
static inline int is_indirect_opcode (void *handler)
1976
{
1977
    return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
1978
}
1979

    
1980
static inline opc_handler_t **ind_table(void *handler)
1981
{
1982
    return (opc_handler_t **)((unsigned long)handler & ~3);
1983
}
1984

    
1985
/* Opcodes tables creation */
1986
static void fill_new_table (opc_handler_t **table, int len)
1987
{
1988
    int i;
1989

    
1990
    for (i = 0; i < len; i++)
1991
        table[i] = &invalid_handler;
1992
}
1993

    
1994
static int create_new_table (opc_handler_t **table, unsigned char idx)
1995
{
1996
    opc_handler_t **tmp;
1997

    
1998
    tmp = malloc(0x20 * sizeof(opc_handler_t));
1999
    if (tmp == NULL)
2000
        return -1;
2001
    fill_new_table(tmp, 0x20);
2002
    table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
2003

    
2004
    return 0;
2005
}
2006

    
2007
static int insert_in_table (opc_handler_t **table, unsigned char idx,
2008
                            opc_handler_t *handler)
2009
{
2010
    if (table[idx] != &invalid_handler)
2011
        return -1;
2012
    table[idx] = handler;
2013

    
2014
    return 0;
2015
}
2016

    
2017
static int register_direct_insn (unsigned char idx, opc_handler_t *handler)
2018
{
2019
    if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
2020
        fprintf(stderr, "*** ERROR: opcode %02x already assigned in main "
2021
                "opcode table\n", idx);
2022
        return -1;
2023
    }
2024

    
2025
    return 0;
2026
}
2027

    
2028
static int register_ind_in_table (opc_handler_t **table,
2029
                                  unsigned char idx1, unsigned char idx2,
2030
                                  opc_handler_t *handler)
2031
{
2032
    if (table[idx1] == &invalid_handler) {
2033
        if (create_new_table(table, idx1) < 0) {
2034
            fprintf(stderr, "*** ERROR: unable to create indirect table "
2035
                    "idx=%02x\n", idx1);
2036
            return -1;
2037
        }
2038
    } else {
2039
        if (!is_indirect_opcode(table[idx1])) {
2040
            fprintf(stderr, "*** ERROR: idx %02x already assigned to a direct "
2041
                    "opcode\n", idx1);
2042
            return -1;
2043
        }
2044
    }
2045
    if (handler != NULL &&
2046
        insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
2047
        fprintf(stderr, "*** ERROR: opcode %02x already assigned in "
2048
                "opcode table %02x\n", idx2, idx1);
2049
        return -1;
2050
    }
2051

    
2052
    return 0;
2053
}
2054

    
2055
static int register_ind_insn (unsigned char idx1, unsigned char idx2,
2056
                               opc_handler_t *handler)
2057
{
2058
    int ret;
2059

    
2060
    ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
2061

    
2062
    return ret;
2063
}
2064

    
2065
static int register_dblind_insn (unsigned char idx1, unsigned char idx2,
2066
                                  unsigned char idx3, opc_handler_t *handler)
2067
{
2068
    if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
2069
        fprintf(stderr, "*** ERROR: unable to join indirect table idx "
2070
                "[%02x-%02x]\n", idx1, idx2);
2071
        return -1;
2072
    }
2073
    if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
2074
                              handler) < 0) {
2075
        fprintf(stderr, "*** ERROR: unable to insert opcode "
2076
                "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
2077
        return -1;
2078
    }
2079

    
2080
    return 0;
2081
}
2082

    
2083
static int register_insn (opcode_t *insn)
2084
{
2085
    if (insn->opc2 != 0xFF) {
2086
        if (insn->opc3 != 0xFF) {
2087
            if (register_dblind_insn(insn->opc1, insn->opc2, insn->opc3,
2088
                                     &insn->handler) < 0)
2089
                return -1;
2090
        } else {
2091
            if (register_ind_insn(insn->opc1, insn->opc2, &insn->handler) < 0)
2092
                return -1;
2093
        }
2094
    } else {
2095
        if (register_direct_insn(insn->opc1, &insn->handler) < 0)
2096
            return -1;
2097
    }
2098

    
2099
    return 0;
2100
}
2101

    
2102
static int test_opcode_table (opc_handler_t **table, int len)
2103
{
2104
    int i, count, tmp;
2105

    
2106
    for (i = 0, count = 0; i < len; i++) {
2107
        /* Consistency fixup */
2108
        if (table[i] == NULL)
2109
            table[i] = &invalid_handler;
2110
        if (table[i] != &invalid_handler) {
2111
            if (is_indirect_opcode(table[i])) {
2112
                tmp = test_opcode_table(ind_table(table[i]), 0x20);
2113
                if (tmp == 0) {
2114
                    free(table[i]);
2115
                    table[i] = &invalid_handler;
2116
                } else {
2117
                    count++;
2118
                }
2119
            } else {
2120
                count++;
2121
            }
2122
        }
2123
    }
2124

    
2125
    return count;
2126
}
2127

    
2128
static void fix_opcode_tables (void)
2129
{
2130
    if (test_opcode_table(ppc_opcodes, 0x40) == 0)
2131
        fprintf(stderr, "*** WARNING: no opcode defined !\n");
2132
}
2133

    
2134
#define SPR_RIGHTS(rw, priv) ((2 * (priv)) + (rw))
2135
#define SPR_UR SPR_RIGHTS(0, 0)
2136
#define SPR_UW SPR_RIGHTS(1, 0)
2137
#define SPR_SR SPR_RIGHTS(0, 1)
2138
#define SPR_SW SPR_RIGHTS(1, 1)
2139

    
2140
#define spr_set_rights(spr, rights)                            \
2141
do {                                                           \
2142
    spr_access[(spr) >> 1] |= ((rights) << (4 * ((spr) & 1))); \
2143
} while (0)
2144

    
2145
static void init_spr_rights (void)
2146
{
2147
    /* XER    (SPR 1) */
2148
    spr_set_rights(SPR_ENCODE(1), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2149
    /* LR     (SPR 8) */
2150
    spr_set_rights(SPR_ENCODE(8), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2151
    /* CTR    (SPR 9) */
2152
    spr_set_rights(SPR_ENCODE(9), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2153
    /* TBL    (SPR 268) */
2154
    spr_set_rights(SPR_ENCODE(268), SPR_UR | SPR_SR);
2155
    /* TBU    (SPR 269) */
2156
    spr_set_rights(SPR_ENCODE(269), SPR_UR | SPR_SR);
2157
    /* DSISR  (SPR 18) */
2158
    spr_set_rights(SPR_ENCODE(18), SPR_SR | SPR_SW);
2159
    /* DAR    (SPR 19) */
2160
    spr_set_rights(SPR_ENCODE(19), SPR_SR | SPR_SW);
2161
    /* DEC    (SPR 22) */
2162
    spr_set_rights(SPR_ENCODE(22), SPR_SR | SPR_SW);
2163
    /* SDR1   (SPR 25) */
2164
    spr_set_rights(SPR_ENCODE(25), SPR_SR | SPR_SW);
2165
    /* SPRG0  (SPR 272) */
2166
    spr_set_rights(SPR_ENCODE(272), SPR_SR | SPR_SW);
2167
    /* SPRG1  (SPR 273) */
2168
    spr_set_rights(SPR_ENCODE(273), SPR_SR | SPR_SW);
2169
    /* SPRG2  (SPR 274) */
2170
    spr_set_rights(SPR_ENCODE(274), SPR_SR | SPR_SW);
2171
    /* SPRG3  (SPR 275) */
2172
    spr_set_rights(SPR_ENCODE(275), SPR_SR | SPR_SW);
2173
    /* ASR    (SPR 280) */
2174
    spr_set_rights(SPR_ENCODE(281), SPR_SR | SPR_SW);
2175
    /* EAR    (SPR 282) */
2176
    spr_set_rights(SPR_ENCODE(282), SPR_SR | SPR_SW);
2177
    /* IBAT0U (SPR 528) */
2178
    spr_set_rights(SPR_ENCODE(528), SPR_SR | SPR_SW);
2179
    /* IBAT0L (SPR 529) */
2180
    spr_set_rights(SPR_ENCODE(529), SPR_SR | SPR_SW);
2181
    /* IBAT1U (SPR 530) */
2182
    spr_set_rights(SPR_ENCODE(530), SPR_SR | SPR_SW);
2183
    /* IBAT1L (SPR 531) */
2184
    spr_set_rights(SPR_ENCODE(531), SPR_SR | SPR_SW);
2185
    /* IBAT2U (SPR 532) */
2186
    spr_set_rights(SPR_ENCODE(532), SPR_SR | SPR_SW);
2187
    /* IBAT2L (SPR 533) */
2188
    spr_set_rights(SPR_ENCODE(533), SPR_SR | SPR_SW);
2189
    /* IBAT3U (SPR 534) */
2190
    spr_set_rights(SPR_ENCODE(534), SPR_SR | SPR_SW);
2191
    /* IBAT3L (SPR 535) */
2192
    spr_set_rights(SPR_ENCODE(535), SPR_SR | SPR_SW);
2193
    /* DBAT0U (SPR 536) */
2194
    spr_set_rights(SPR_ENCODE(536), SPR_SR | SPR_SW);
2195
    /* DBAT0L (SPR 537) */
2196
    spr_set_rights(SPR_ENCODE(537), SPR_SR | SPR_SW);
2197
    /* DBAT1U (SPR 538) */
2198
    spr_set_rights(SPR_ENCODE(538), SPR_SR | SPR_SW);
2199
    /* DBAT1L (SPR 539) */
2200
    spr_set_rights(SPR_ENCODE(539), SPR_SR | SPR_SW);
2201
    /* DBAT2U (SPR 540) */
2202
    spr_set_rights(SPR_ENCODE(540), SPR_SR | SPR_SW);
2203
    /* DBAT2L (SPR 541) */
2204
    spr_set_rights(SPR_ENCODE(541), SPR_SR | SPR_SW);
2205
    /* DBAT3U (SPR 542) */
2206
    spr_set_rights(SPR_ENCODE(542), SPR_SR | SPR_SW);
2207
    /* DBAT3L (SPR 543) */
2208
    spr_set_rights(SPR_ENCODE(543), SPR_SR | SPR_SW);
2209
    /* DABR   (SPR 1013) */
2210
    spr_set_rights(SPR_ENCODE(1013), SPR_SR | SPR_SW);
2211
    /* FPECR  (SPR 1022) */
2212
    spr_set_rights(SPR_ENCODE(1022), SPR_SR | SPR_SW);
2213
    /* PIR    (SPR 1023) */
2214
    spr_set_rights(SPR_ENCODE(1023), SPR_SR | SPR_SW);
2215
    /* PVR    (SPR 287) */
2216
    spr_set_rights(SPR_ENCODE(287), SPR_SR);
2217
    /* TBL    (SPR 284) */
2218
    spr_set_rights(SPR_ENCODE(284), SPR_SW);
2219
    /* TBU    (SPR 285) */
2220
    spr_set_rights(SPR_ENCODE(285), SPR_SW);
2221
}
2222

    
2223
/* PPC "main stream" common instructions */
2224
#define PPC_COMMON  (PPC_INTEGER | PPC_FLOAT | PPC_FLOW | PPC_MEM | \
2225
                     PPC_MISC | PPC_EXTERN | PPC_SEGMENT)
2226

    
2227
typedef struct ppc_proc_t {
2228
    int flags;
2229
    void *specific;
2230
} ppc_proc_t;
2231

    
2232
typedef struct ppc_def_t {
2233
    unsigned long pvr;
2234
    unsigned long pvr_mask;
2235
    ppc_proc_t *proc;
2236
} ppc_def_t;
2237

    
2238
static ppc_proc_t ppc_proc_common = {
2239
    .flags    = PPC_COMMON,
2240
    .specific = NULL,
2241
};
2242

    
2243
static ppc_def_t ppc_defs[] =
2244
{
2245
    /* Fallback */
2246
    {
2247
        .pvr      = 0x00000000,
2248
        .pvr_mask = 0x00000000,
2249
        .proc     = &ppc_proc_common,
2250
    },
2251
};
2252

    
2253
static int create_ppc_proc (unsigned long pvr)
2254
{
2255
    opcode_t *opc;
2256
    int i, flags;
2257

    
2258
    fill_new_table(ppc_opcodes, 0x40);
2259
    for (i = 0; ; i++) {
2260
        if ((ppc_defs[i].pvr & ppc_defs[i].pvr_mask) ==
2261
            (pvr & ppc_defs[i].pvr_mask)) {
2262
            flags = ppc_defs[i].proc->flags;
2263
            break;
2264
        }
2265
    }
2266
    
2267
    for (opc = &opc_start + 1; opc != &opc_end; opc++) {
2268
        if ((opc->type & flags) != 0)
2269
            if (register_insn(opc) < 0) {
2270
                fprintf(stderr, "*** ERROR initializing PPC instruction "
2271
                        "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
2272
                        opc->opc3);
2273
                return -1;
2274
            }
2275
    }
2276
    fix_opcode_tables();
2277

    
2278
    return 0;
2279
}
2280

    
2281
/*****************************************************************************/
2282
uint32_t do_load_xer (void);
2283

    
2284
void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
2285
{
2286
    int i;
2287

    
2288
    if (loglevel > 0) {
2289
        fprintf(logfile, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x\n",
2290
                env->nip, env->LR, env->CTR, do_load_xer());
2291
        for (i = 0; i < 32; i++) {
2292
            if ((i & 7) == 0)
2293
                fprintf(logfile, "GPR%02d:", i);
2294
            fprintf(logfile, " %08x", env->gpr[i]);
2295
            if ((i & 7) == 7)
2296
                fprintf(logfile, "\n");
2297
        }
2298
        fprintf(logfile, "CR: 0x");
2299
        for (i = 0; i < 8; i++)
2300
            fprintf(logfile, "%01x", env->crf[i]);
2301
        fprintf(logfile, "  [");
2302
        for (i = 0; i < 8; i++) {
2303
            char a = '-';
2304
            
2305
            if (env->crf[i] & 0x08)
2306
                a = 'L';
2307
            else if (env->crf[i] & 0x04)
2308
                a = 'G';
2309
            else if (env->crf[i] & 0x02)
2310
                a = 'E';
2311
            fprintf(logfile, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
2312
        }
2313
        fprintf(logfile, " ] ");
2314
        fprintf(logfile, "TB: 0x%08x %08x\n", env->spr[SPR_ENCODE(269)],
2315
                env->spr[SPR_ENCODE(268)]);
2316
        for (i = 0; i < 16; i++) {
2317
            if ((i & 3) == 0)
2318
                fprintf(logfile, "FPR%02d:", i);
2319
            fprintf(logfile, " %016llx", *((uint64_t *)(&env->fpr[i])));
2320
            if ((i & 3) == 3)
2321
                fprintf(logfile, "\n");
2322
        }
2323
        fflush(logfile);
2324
    }
2325
}
2326

    
2327
CPUPPCState *cpu_ppc_init(void)
2328
{
2329
    CPUPPCState *env;
2330

    
2331
    cpu_exec_init();
2332

    
2333
    env = malloc(sizeof(CPUPPCState));
2334
    if (!env)
2335
        return NULL;
2336
    memset(env, 0, sizeof(CPUPPCState));
2337
    env->PVR = 0;
2338
    if (create_ppc_proc(0) < 0)
2339
        return NULL;
2340
    init_spr_rights();
2341

    
2342
    return env;
2343
}
2344

    
2345
void cpu_ppc_close(CPUPPCState *env)
2346
{
2347
    /* Should also remove all opcode tables... */
2348
    free(env);
2349
}
2350

    
2351
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2352
                                    int search_pc)
2353
{
2354
    DisasContext ctx;
2355
    opc_handler_t **table, *handler;
2356
    uint32_t pc_start;
2357
    uint16_t *gen_opc_end;
2358
    int j, lj = -1;
2359
    int ret = 0;
2360

    
2361
    pc_start = tb->pc;
2362
    gen_opc_ptr = gen_opc_buf;
2363
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2364
    gen_opparam_ptr = gen_opparam_buf;
2365
    ctx.nip = (uint32_t *)pc_start;
2366
    ctx.tb_offset = 0;
2367
    ctx.supervisor = msr_ip;
2368
    ctx.tb = tb;
2369
    ctx.exception = 0;
2370

    
2371
    while (ret == 0 && gen_opc_ptr < gen_opc_end) {
2372
        if (search_pc) {
2373
            if (loglevel > 0)
2374
                fprintf(logfile, "Search PC...\n");
2375
            j = gen_opc_ptr - gen_opc_buf;
2376
            if (lj < j) {
2377
                lj++;
2378
                while (lj < j)
2379
                    gen_opc_instr_start[lj++] = 0;
2380
                gen_opc_pc[lj] = (uint32_t)ctx.nip;
2381
                gen_opc_instr_start[lj] = 1;
2382
            }
2383
        }
2384
        ctx.opcode = __be32_to_cpu(*ctx.nip);
2385
#ifdef DEBUG_DISAS
2386
        if (loglevel > 0) {
2387
            fprintf(logfile, "----------------\n");
2388
            fprintf(logfile, "%p: translate opcode %08x\n",
2389
                    ctx.nip, ctx.opcode);
2390
        }
2391
#endif
2392
        ctx.nip++;
2393
        table = ppc_opcodes;
2394
        handler = table[opc1(ctx.opcode)];
2395
        if (is_indirect_opcode(handler)) {
2396
            table = ind_table(handler);
2397
            handler = table[opc2(ctx.opcode)];
2398
            if (is_indirect_opcode(handler)) {
2399
                table = ind_table(handler);
2400
                handler = table[opc3(ctx.opcode)];
2401
            }
2402
        }
2403
        /* Is opcode *REALLY* valid ? */
2404
        if ((ctx.opcode & handler->inval) != 0) {
2405
            if (loglevel > 0) {
2406
                if (handler->handler == &gen_invalid) {
2407
                    fprintf(logfile, "invalid/unsupported opcode: "
2408
                            "%02x -%02x - %02x (%08x)\n", opc1(ctx.opcode),
2409
                            opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode);
2410
                } else {
2411
                    fprintf(logfile, "invalid bits: %08x for opcode: "
2412
                            "%02x -%02x - %02x (%p)\n",
2413
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
2414
                            opc2(ctx.opcode), opc3(ctx.opcode),
2415
                            handler->handler);
2416
                }
2417
            }
2418
            ret = GET_RETVAL(gen_invalid, ctx.opcode);
2419
        } else {
2420
            ret = GET_RETVAL(*(handler->handler), ctx.opcode);
2421
        }
2422
        ctx.tb_offset++;
2423
#if defined (DO_SINGLE_STEP)
2424
        break;
2425
#endif
2426
    }
2427
#if defined (DO_STEP_FLUSH)
2428
    tb_flush(env);
2429
#endif
2430
    /* We need to update the time base */
2431
    if (!search_pc)
2432
        gen_op_update_tb(ctx.tb_offset);
2433
    /* If we are in step-by-step mode, do a branch to the next instruction
2434
     * so the nip will be up-to-date
2435
     */
2436
#if defined (DO_SINGLE_STEP)
2437
    if (ret == 0) {
2438
        gen_op_b((uint32_t)ctx.nip);
2439
        ret = EXCP_BRANCH;
2440
    }
2441
#endif
2442
    /* If the exeption isn't a PPC one,
2443
     * generate it now.
2444
     */
2445
    if (ret != EXCP_BRANCH) {
2446
        gen_op_set_T0(0);
2447
        if ((ret & 0x2000) == 0)
2448
            gen_op_raise_exception(ret);
2449
    }
2450
    /* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
2451
     *              do bad business and then qemu crashes !
2452
     */
2453
    gen_op_set_T0(0);
2454
    /* Generate the return instruction */
2455
    gen_op_exit_tb();
2456
    *gen_opc_ptr = INDEX_op_end;
2457
    if (!search_pc)
2458
        tb->size = (uint32_t)ctx.nip - pc_start;
2459
    else
2460
        tb->size = 0;
2461
//    *gen_opc_ptr = INDEX_op_end;
2462
#ifdef DEBUG_DISAS
2463
    if (loglevel > 0) {
2464
        fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start));
2465
        disas(logfile, (void *)pc_start, (uint32_t)ctx.nip - pc_start, 0, 0);
2466
        fprintf(logfile, "\n");
2467

    
2468
        fprintf(logfile, "OP:\n");
2469
        dump_ops(gen_opc_buf, gen_opparam_buf);
2470
        fprintf(logfile, "\n");
2471
    }
2472
#endif
2473

    
2474
    return 0;
2475
}
2476

    
2477
int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb)
2478
{
2479
    return gen_intermediate_code_internal(env, tb, 0);
2480
}
2481

    
2482
int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb)
2483
{
2484
    return gen_intermediate_code_internal(env, tb, 1);
2485
}