PowerPC fixes (Jocelyn Mayer)
[qemu] / target-ppc / translate.c
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 }