suppressed use of gen_multi - use intermediate FT0 register for floats - use T0 tempo...
[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
42 #define GEN8(func, NAME) \
43 static GenOpFunc *NAME ## _table [8] = {\
44 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\
45 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\
46 };\
47 static inline void func(int n)\
48 {\
49     NAME ## _table[n]();\
50 }
51
52 #define GEN32(func, NAME) \
53 static GenOpFunc *NAME ## _table [32] = {\
54 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\
55 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\
56 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,\
57 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,\
58 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,\
59 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,\
60 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,\
61 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,\
62 };\
63 static inline void func(int n)\
64 {\
65     NAME ## _table[n]();\
66 }
67
68 GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf)
69 GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf)
70 GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf)
71 GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf)
72
73 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr)
74 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr)
75 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr)
76
77 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr)
78 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr)
79 GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr)
80
81 GEN32(gen_op_load_FT0_fpr, gen_op_load_FT0_fpr)
82 GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr)
83
84 static uint8_t  spr_access[1024 / 2];
85
86 /* internal defines */
87 typedef struct DisasContext {
88     struct TranslationBlock *tb;
89     uint32_t *nip;
90     uint32_t opcode;
91     int exception;
92     int retcode;
93     /* Time base */
94     uint32_t tb_offset;
95     int supervisor;
96 } DisasContext;
97
98 typedef struct opc_handler_t {
99     /* invalid bits */
100     uint32_t inval;
101     /* handler */
102     void (*handler)(DisasContext *ctx);
103 } opc_handler_t;
104
105 #define SET_RETVAL(n)                                                         \
106 do {                                                                          \
107     if ((n) != 0) {                                                           \
108         ctx->exception = (n);                                                 \
109     }                                                                         \
110     return;                                                                   \
111 } while (0)
112
113 #define GET_RETVAL(func, __opcode)                                            \
114 ({                                                                            \
115     (func)(&ctx);                                                             \
116     ctx.exception;                                                            \
117 })
118
119 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
120 static void gen_##name (DisasContext *ctx);                                   \
121 GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
122 static void gen_##name (DisasContext *ctx)
123
124 /* Instruction types */
125 enum {
126     PPC_INTEGER  = 0x0001, /* CPU has integer operations instructions        */
127     PPC_FLOAT    = 0x0002, /* CPU has floating point operations instructions */
128     PPC_FLOW     = 0x0004, /* CPU has flow control instructions              */
129     PPC_MEM      = 0x0008, /* CPU has virtual memory instructions            */
130     PPC_MISC     = 0x0010, /* CPU has spr/msr access instructions            */
131     PPC_EXTERN   = 0x0020, /* CPU has external control instructions          */
132     PPC_SEGMENT  = 0x0040, /* CPU has memory segment instructions            */
133 };
134
135 typedef struct opcode_t {
136     unsigned char opc1, opc2, opc3;
137     uint32_t type;
138     opc_handler_t handler;
139 } opcode_t;
140
141 /* XXX: move that elsewhere */
142 extern FILE *logfile;
143 extern int loglevel;
144
145 /* XXX: shouldn't stay all alone here ! */
146 static int reserve = 0;
147
148 /***                           Instruction decoding                        ***/
149 #define EXTRACT_HELPER(name, shift, nb)                                       \
150 static inline uint32_t name (uint32_t opcode)                                 \
151 {                                                                             \
152     return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
153 }
154
155 #define EXTRACT_SHELPER(name, shift, nb)                                      \
156 static inline int32_t name (uint32_t opcode)                                  \
157 {                                                                             \
158     return s_ext16((opcode >> (shift)) & ((1 << (nb)) - 1));                  \
159 }
160
161 /* Opcode part 1 */
162 EXTRACT_HELPER(opc1, 26, 6);
163 /* Opcode part 2 */
164 EXTRACT_HELPER(opc2, 1, 5);
165 /* Opcode part 3 */
166 EXTRACT_HELPER(opc3, 6, 5);
167 /* Update Cr0 flags */
168 EXTRACT_HELPER(Rc, 0, 1);
169 /* Destination */
170 EXTRACT_HELPER(rD, 21, 5);
171 /* Source */
172 EXTRACT_HELPER(rS, 21, 5);
173 /* First operand */
174 EXTRACT_HELPER(rA, 16, 5);
175 /* Second operand */
176 EXTRACT_HELPER(rB, 11, 5);
177 /* Third operand */
178 EXTRACT_HELPER(rC, 6, 5);
179 /***                               Get CRn                                 ***/
180 EXTRACT_HELPER(crfD, 23, 3);
181 EXTRACT_HELPER(crfS, 18, 3);
182 EXTRACT_HELPER(crbD, 21, 5);
183 EXTRACT_HELPER(crbA, 16, 5);
184 EXTRACT_HELPER(crbB, 11, 5);
185 /* SPR / TBL */
186 EXTRACT_HELPER(SPR, 11, 10);
187 /***                              Get constants                            ***/
188 EXTRACT_HELPER(IMM, 12, 8);
189 /* 16 bits signed immediate value */
190 EXTRACT_SHELPER(SIMM, 0, 16);
191 /* 16 bits unsigned immediate value */
192 EXTRACT_HELPER(UIMM, 0, 16);
193 /* Bit count */
194 EXTRACT_HELPER(NB, 11, 5);
195 /* Shift count */
196 EXTRACT_HELPER(SH, 11, 5);
197 /* Mask start */
198 EXTRACT_HELPER(MB, 6, 5);
199 /* Mask end */
200 EXTRACT_HELPER(ME, 1, 5);
201
202 EXTRACT_HELPER(CRM, 12, 8);
203 EXTRACT_HELPER(FM, 17, 8);
204 EXTRACT_HELPER(SR, 16, 4);
205 /***                            Jump target decoding                       ***/
206 /* Displacement */
207 EXTRACT_SHELPER(d, 0, 16);
208 /* Immediate address */
209 static inline uint32_t LI (uint32_t opcode)
210 {
211     return (opcode >> 0) & 0x03FFFFFC;
212 }
213
214 static inline uint32_t BD (uint32_t opcode)
215 {
216     return (opcode >> 0) & 0xFFFC;
217 }
218
219 EXTRACT_HELPER(BO, 21, 5);
220 EXTRACT_HELPER(BI, 16, 5);
221 /* Absolute/relative address */
222 EXTRACT_HELPER(AA, 1, 1);
223 /* Link */
224 EXTRACT_HELPER(LK, 0, 1);
225
226 /* Create a mask between <start> and <end> bits */
227 static inline uint32_t MASK (uint32_t start, uint32_t end)
228 {
229     uint32_t ret;
230
231     ret = (((uint32_t)(-1)) >> (start)) ^ (((uint32_t)(-1) >> (end)) >> 1);
232     if (start > end)
233         return ~ret;
234
235     return ret;
236 }
237
238 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
239 __attribute__ ((section(".opcodes"), unused))                                 \
240 static opcode_t opc_##name = {                                                \
241     .opc1 = op1,                                                              \
242     .opc2 = op2,                                                              \
243     .opc3 = op3,                                                              \
244     .type = _typ,                                                             \
245     .handler = {                                                              \
246         .inval   = invl,                                                      \
247         .handler = &gen_##name,                                               \
248     },                                                                        \
249 }
250
251 #define GEN_OPCODE_MARK(name)                                                 \
252 __attribute__ ((section(".opcodes"), unused))                                 \
253 static opcode_t opc_##name = {                                                \
254     .opc1 = 0xFF,                                                             \
255     .opc2 = 0xFF,                                                             \
256     .opc3 = 0xFF,                                                             \
257     .type = 0x00,                                                             \
258     .handler = {                                                              \
259         .inval   = 0x00000000,                                                \
260         .handler = NULL,                                                      \
261     },                                                                        \
262 }
263
264 /* Start opcode list */
265 GEN_OPCODE_MARK(start);
266
267 /* Invalid instruction */
268 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, 0)
269 {
270     /* Branch to next instruction to force nip update */
271     gen_op_b((uint32_t)ctx->nip);
272     SET_RETVAL(EXCP_INVAL);
273 }
274
275 static opc_handler_t invalid_handler = {
276     .inval   = 0xFFFFFFFF,
277     .handler = gen_invalid,
278 };
279
280 /***                           Integer arithmetic                          ***/
281 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval)                       \
282 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER)                       \
283 {                                                                             \
284     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
285     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
286     gen_op_##name();                                                          \
287     if (Rc(ctx->opcode) != 0)                                                 \
288         gen_op_set_Rc0();                                                     \
289     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
290     SET_RETVAL(0);                                                            \
291 }
292
293 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval)                     \
294 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER)                       \
295 {                                                                             \
296     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
297     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
298     gen_op_##name();                                                          \
299     if (Rc(ctx->opcode) != 0)                                                 \
300         gen_op_set_Rc0_ov();                                                  \
301     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
302     SET_RETVAL(0);                                                            \
303 }
304
305 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3)                              \
306 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER)                  \
307 {                                                                             \
308     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
309     gen_op_##name();                                                          \
310     if (Rc(ctx->opcode) != 0)                                                 \
311         gen_op_set_Rc0();                                                     \
312     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
313     SET_RETVAL(0);                                                            \
314 }
315 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3)                            \
316 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER)                  \
317 {                                                                             \
318     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
319     gen_op_##name();                                                          \
320     if (Rc(ctx->opcode) != 0)                                                 \
321         gen_op_set_Rc0_ov();                                                  \
322     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
323     SET_RETVAL(0);                                                            \
324 }
325
326 /* Two operands arithmetic functions */
327 #define GEN_INT_ARITH2(name, opc1, opc2, opc3)                                \
328 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000)                          \
329 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000)
330
331 /* Two operands arithmetic functions with no overflow allowed */
332 #define GEN_INT_ARITHN(name, opc1, opc2, opc3)                                \
333 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400)
334
335 /* One operand arithmetic functions */
336 #define GEN_INT_ARITH1(name, opc1, opc2, opc3)                                \
337 __GEN_INT_ARITH1(name, opc1, opc2, opc3)                                      \
338 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10)
339
340 /* add    add.    addo    addo.    */
341 GEN_INT_ARITH2 (add,    0x1F, 0x0A, 0x08);
342 /* addc   addc.   addco   addco.   */
343 GEN_INT_ARITH2 (addc,   0x1F, 0x0A, 0x00);
344 /* adde   adde.   addeo   addeo.   */
345 GEN_INT_ARITH2 (adde,   0x1F, 0x0A, 0x04);
346 /* addme  addme.  addmeo  addmeo.  */
347 GEN_INT_ARITH1 (addme,  0x1F, 0x0A, 0x07);
348 /* addze  addze.  addzeo  addzeo.  */
349 GEN_INT_ARITH1 (addze,  0x1F, 0x0A, 0x06);
350 /* divw   divw.   divwo   divwo.   */
351 GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F);
352 /* divwu  divwu.  divwuo  divwuo.  */
353 GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E);
354 /* mulhw  mulhw.                   */
355 GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02);
356 /* mulhwu mulhwu.                  */
357 GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00);
358 /* mullw  mullw.  mullwo  mullwo.  */
359 GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07);
360 /* neg    neg.    nego    nego.    */
361 GEN_INT_ARITH1 (neg,    0x1F, 0x08, 0x03);
362 /* subf   subf.   subfo   subfo.   */
363 GEN_INT_ARITH2 (subf,   0x1F, 0x08, 0x01);
364 /* subfc  subfc.  subfco  subfco.  */
365 GEN_INT_ARITH2 (subfc,  0x1F, 0x08, 0x00);
366 /* subfe  subfe.  subfeo  subfeo.  */
367 GEN_INT_ARITH2 (subfe,  0x1F, 0x08, 0x04);
368 /* subfme subfme. subfmeo subfmeo. */
369 GEN_INT_ARITH1 (subfme, 0x1F, 0x08, 0x07);
370 /* subfze subfze. subfzeo subfzeo. */
371 GEN_INT_ARITH1 (subfze, 0x1F, 0x08, 0x06);
372 /* addi */
373 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
374 {
375     int32_t simm = SIMM(ctx->opcode);
376
377     if (rA(ctx->opcode) == 0) {
378         gen_op_set_T0(simm);
379     } else {
380         gen_op_load_gpr_T0(rA(ctx->opcode));
381         gen_op_addi(simm);
382     }
383     gen_op_store_T0_gpr(rD(ctx->opcode));
384     SET_RETVAL(0);
385 }
386 /* addic */
387 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
388 {
389     gen_op_load_gpr_T0(rA(ctx->opcode));
390     gen_op_addic(SIMM(ctx->opcode));
391     gen_op_store_T0_gpr(rD(ctx->opcode));
392     SET_RETVAL(0);
393 }
394 /* addic. */
395 GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
396 {
397     gen_op_load_gpr_T0(rA(ctx->opcode));
398     gen_op_addic(SIMM(ctx->opcode));
399     gen_op_set_Rc0();
400     gen_op_store_T0_gpr(rD(ctx->opcode));
401     SET_RETVAL(0);
402 }
403 /* addis */
404 GEN_HANDLER(addis, 0x0F, 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 << 16);
410     } else {
411         gen_op_load_gpr_T0(rA(ctx->opcode));
412         gen_op_addi(simm << 16);
413     }
414     gen_op_store_T0_gpr(rD(ctx->opcode));
415     SET_RETVAL(0);
416 }
417 /* mulli */
418 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
419 {
420     gen_op_load_gpr_T0(rA(ctx->opcode));
421     gen_op_mulli(SIMM(ctx->opcode));
422     gen_op_store_T0_gpr(rD(ctx->opcode));
423     SET_RETVAL(0);
424 }
425 /* subfic */
426 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
427 {
428     gen_op_load_gpr_T0(rA(ctx->opcode));
429     gen_op_subfic(SIMM(ctx->opcode));
430     gen_op_store_T0_gpr(rD(ctx->opcode));
431     SET_RETVAL(0);
432 }
433
434 /***                           Integer comparison                          ***/
435 #define GEN_CMP(name, opc)                                                    \
436 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, PPC_INTEGER)                   \
437 {                                                                             \
438     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
439     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
440     gen_op_##name();                                                          \
441     gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
442     SET_RETVAL(0);                                                            \
443 }
444
445 /* cmp */
446 GEN_CMP(cmp, 0x00);
447 /* cmpi */
448 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
449 {
450     gen_op_load_gpr_T0(rA(ctx->opcode));
451     gen_op_cmpi(SIMM(ctx->opcode));
452     gen_op_store_T0_crf(crfD(ctx->opcode));
453     SET_RETVAL(0);
454 }
455 /* cmpl */
456 GEN_CMP(cmpl, 0x01);
457 /* cmpli */
458 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
459 {
460     gen_op_load_gpr_T0(rA(ctx->opcode));
461     gen_op_cmpli(UIMM(ctx->opcode));
462     gen_op_store_T0_crf(crfD(ctx->opcode));
463     SET_RETVAL(0);
464 }
465
466 /***                            Integer logical                            ***/
467 #define __GEN_LOGICAL2(name, opc2, opc3)                                      \
468 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, PPC_INTEGER)                  \
469 {                                                                             \
470     gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
471     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
472     gen_op_##name();                                                          \
473     if (Rc(ctx->opcode) != 0)                                                 \
474         gen_op_set_Rc0();                                                     \
475     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
476     SET_RETVAL(0);                                                            \
477 }
478 #define GEN_LOGICAL2(name, opc)                                               \
479 __GEN_LOGICAL2(name, 0x1C, opc)
480
481 #define GEN_LOGICAL1(name, opc)                                               \
482 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, PPC_INTEGER)                   \
483 {                                                                             \
484     gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
485     gen_op_##name();                                                          \
486     if (Rc(ctx->opcode) != 0)                                                 \
487         gen_op_set_Rc0();                                                     \
488     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
489     SET_RETVAL(0);                                                            \
490 }
491
492 /* and & and. */
493 GEN_LOGICAL2(and, 0x00);
494 /* andc & andc. */
495 GEN_LOGICAL2(andc, 0x01);
496 /* andi. */
497 GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
498 {
499     gen_op_load_gpr_T0(rS(ctx->opcode));
500     gen_op_andi_(UIMM(ctx->opcode));
501     gen_op_set_Rc0();
502     gen_op_store_T0_gpr(rA(ctx->opcode));
503     SET_RETVAL(0);
504 }
505 /* andis. */
506 GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
507 {
508     gen_op_load_gpr_T0(rS(ctx->opcode));
509     gen_op_andi_(UIMM(ctx->opcode) << 16);
510     gen_op_set_Rc0();
511     gen_op_store_T0_gpr(rA(ctx->opcode));
512     SET_RETVAL(0);
513 }
514
515 /* cntlzw */
516 GEN_LOGICAL1(cntlzw, 0x00);
517 /* eqv & eqv. */
518 GEN_LOGICAL2(eqv, 0x08);
519 /* extsb & extsb. */
520 GEN_LOGICAL1(extsb, 0x1D);
521 /* extsh & extsh. */
522 GEN_LOGICAL1(extsh, 0x1C);
523 /* nand & nand. */
524 GEN_LOGICAL2(nand, 0x0E);
525 /* nor & nor. */
526 GEN_LOGICAL2(nor, 0x03);
527 /* or & or. */
528 GEN_LOGICAL2(or, 0x0D);
529 /* orc & orc. */
530 GEN_LOGICAL2(orc, 0x0C);
531 /* xor & xor. */
532 GEN_LOGICAL2(xor, 0x09);
533 /* ori */
534 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
535 {
536     uint32_t uimm = UIMM(ctx->opcode);
537
538 #if 0
539     if (uimm == 0) {
540         if (rA(ctx->opcode) != rS(ctx->opcode)) {
541             gen_op_load_gpr_T0(rS(ctx->opcode));
542             gen_op_store_T0_gpr(rA(ctx->opcode));
543         }
544     } else
545 #endif
546     {
547         gen_op_load_gpr_T0(rS(ctx->opcode));
548         gen_op_ori(uimm);
549         gen_op_store_T0_gpr(rA(ctx->opcode));
550     }
551     SET_RETVAL(0);
552 }
553 /* oris */
554 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
555 {
556     uint32_t uimm = UIMM(ctx->opcode);
557
558 #if 0
559     if (uimm == 0) {
560         if (rA(ctx->opcode) != rS(ctx->opcode)) {
561             gen_op_load_gpr_T0(rS(ctx->opcode));
562             gen_op_store_T0_gpr(rA(ctx->opcode));
563         }
564     } else
565 #endif
566     {
567         gen_op_load_gpr_T0(rS(ctx->opcode));
568         gen_op_ori(uimm << 16);
569         gen_op_store_T0_gpr(rA(ctx->opcode));
570     }
571     SET_RETVAL(0);
572 }
573 /* xori */
574 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
575 {
576     gen_op_load_gpr_T0(rS(ctx->opcode));
577     gen_op_xori(UIMM(ctx->opcode));
578     gen_op_store_T0_gpr(rA(ctx->opcode));
579     SET_RETVAL(0);
580 }
581
582 /* xoris */
583 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
584 {
585     gen_op_load_gpr_T0(rS(ctx->opcode));
586     gen_op_xori(UIMM(ctx->opcode) << 16);
587     gen_op_store_T0_gpr(rA(ctx->opcode));
588     SET_RETVAL(0);
589 }
590
591 /***                             Integer rotate                            ***/
592 /* rlwimi & rlwimi. */
593 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
594 {
595     uint32_t mb, me;
596
597     mb = MB(ctx->opcode);
598     me = ME(ctx->opcode);
599     gen_op_load_gpr_T0(rS(ctx->opcode));
600     gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me));
601     if (Rc(ctx->opcode) != 0)
602         gen_op_set_Rc0();
603     gen_op_store_T0_gpr(rA(ctx->opcode));
604     SET_RETVAL(0);
605 }
606 /* rlwinm & rlwinm. */
607 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
608 {
609     uint32_t mb, me, sh;
610     
611     sh = SH(ctx->opcode);
612     mb = MB(ctx->opcode);
613     me = ME(ctx->opcode);
614     gen_op_load_gpr_T0(rS(ctx->opcode));
615     if (loglevel > 0) {
616         fprintf(logfile, "%s sh=%u mb=%u me=%u MASK=0x%08x\n",
617                 __func__, sh, mb, me, MASK(mb, me));
618     }
619     if (mb == 0) {
620         if (me == 31) {
621             gen_op_rotlwi(sh);
622             goto store;
623         } else if (me == (31 - sh)) {
624             gen_op_slwi(sh);
625             goto store;
626         } else if (sh == 0) {
627             gen_op_andi_(MASK(0, me));
628             goto store;
629         }
630     } else if (me == 31) {
631         if (sh == (32 - mb)) {
632             gen_op_srwi(mb);
633             goto store;
634         } else if (sh == 0) {
635             gen_op_andi_(MASK(mb, 31));
636             goto store;
637         }
638     }
639     gen_op_rlwinm(sh, MASK(mb, me));
640 store:
641     if (Rc(ctx->opcode) != 0)
642         gen_op_set_Rc0();
643     gen_op_store_T0_gpr(rA(ctx->opcode));
644     SET_RETVAL(0);
645 }
646 /* rlwnm & rlwnm. */
647 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
648 {
649     uint32_t mb, me;
650
651     mb = MB(ctx->opcode);
652     me = ME(ctx->opcode);
653     gen_op_load_gpr_T0(rS(ctx->opcode));
654     gen_op_load_gpr_T1(rB(ctx->opcode));
655     if (mb == 0 && me == 31) {
656         gen_op_rotl();
657     } else
658     {
659         gen_op_rlwnm(MASK(mb, me));
660     }
661     if (Rc(ctx->opcode) != 0)
662         gen_op_set_Rc0();
663     gen_op_store_T0_gpr(rA(ctx->opcode));
664     SET_RETVAL(0);
665 }
666
667 /***                             Integer shift                             ***/
668 /* slw & slw. */
669 __GEN_LOGICAL2(slw, 0x18, 0x00);
670 /* sraw & sraw. */
671 __GEN_LOGICAL2(sraw, 0x18, 0x18);
672 /* srawi & srawi. */
673 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
674 {
675     gen_op_load_gpr_T0(rS(ctx->opcode));
676     gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
677     if (Rc(ctx->opcode) != 0)
678         gen_op_set_Rc0();
679     gen_op_store_T0_gpr(rA(ctx->opcode));
680     SET_RETVAL(0);
681 }
682 /* srw & srw. */
683 __GEN_LOGICAL2(srw, 0x18, 0x10);
684
685 /***                       Floating-Point arithmetic                       ***/
686 /* fadd */
687 GEN_HANDLER(fadd, 0x3F, 0x15, 0xFF, 0x000007C0, PPC_FLOAT)
688 {
689     SET_RETVAL(EXCP_INVAL);
690 }
691
692 /* fadds */
693 GEN_HANDLER(fadds, 0x3B, 0x15, 0xFF, 0x000007C0, PPC_FLOAT)
694 {
695     SET_RETVAL(EXCP_INVAL);
696 }
697
698 /* fdiv */
699 GEN_HANDLER(fdiv, 0x3F, 0x12, 0xFF, 0x000007C0, PPC_FLOAT)
700 {
701     SET_RETVAL(EXCP_INVAL);
702 }
703
704 /* fdivs */
705 GEN_HANDLER(fdivs, 0x3B, 0x12, 0xFF, 0x000007C0, PPC_FLOAT)
706 {
707     SET_RETVAL(EXCP_INVAL);
708 }
709
710 /* fmul */
711 GEN_HANDLER(fmul, 0x3F, 0x19, 0xFF, 0x0000F800, PPC_FLOAT)
712 {
713     SET_RETVAL(EXCP_INVAL);
714 }
715
716 /* fmuls */
717 GEN_HANDLER(fmuls, 0x3B, 0x19, 0xFF, 0x0000F800, PPC_FLOAT)
718 {
719     SET_RETVAL(EXCP_INVAL);
720 }
721
722 /* fres */
723 GEN_HANDLER(fres, 0x3B, 0x18, 0xFF, 0x001807C0, PPC_FLOAT)
724 {
725     SET_RETVAL(EXCP_INVAL);
726 }
727
728 /* frsqrte */
729 GEN_HANDLER(frsqrte, 0x3F, 0x1A, 0xFF, 0x001807C0, PPC_FLOAT)
730 {
731     SET_RETVAL(EXCP_INVAL);
732 }
733
734 /* fsel */
735 GEN_HANDLER(fsel, 0x3F, 0x17, 0xFF, 0x00000000, PPC_FLOAT)
736 {
737     SET_RETVAL(EXCP_INVAL);
738 }
739
740 /* fsub */
741 GEN_HANDLER(fsub, 0x3F, 0x14, 0xFF, 0x000007C0, PPC_FLOAT)
742 {
743     SET_RETVAL(EXCP_INVAL);
744 }
745
746 /* fsubs */
747 GEN_HANDLER(fsubs, 0x3B, 0x14, 0xFF, 0x000007C0, PPC_FLOAT)
748 {
749     SET_RETVAL(EXCP_INVAL);
750 }
751
752 /* Optional: */
753 /* fsqrt */
754 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001807C0, PPC_FLOAT)
755 {
756     SET_RETVAL(EXCP_INVAL);
757 }
758
759 /* fsqrts */
760 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001807C0, PPC_FLOAT)
761 {
762     SET_RETVAL(EXCP_INVAL);
763 }
764
765 /***                     Floating-Point multiply-and-add                   ***/
766 /* fmadd */
767 GEN_HANDLER(fmadd, 0x3F, 0x1D, 0xFF, 0x00000000, PPC_FLOAT)
768 {
769     SET_RETVAL(EXCP_INVAL);
770 }
771
772 /* fmadds */
773 GEN_HANDLER(fmadds, 0x3B, 0x1D, 0xFF, 0x00000000, PPC_FLOAT)
774 {
775     SET_RETVAL(EXCP_INVAL);
776 }
777
778 /* fmsub */
779 GEN_HANDLER(fmsub, 0x3F, 0x1C, 0xFF, 0x00000000, PPC_FLOAT)
780 {
781     SET_RETVAL(EXCP_INVAL);
782 }
783
784 /* fmsubs */
785 GEN_HANDLER(fmsubs, 0x3B, 0x1C, 0xFF, 0x00000000, PPC_FLOAT)
786 {
787     SET_RETVAL(EXCP_INVAL);
788 }
789
790 /* fnmadd */
791 GEN_HANDLER(fnmadd, 0x3F, 0x1F, 0xFF, 0x00000000, PPC_FLOAT)
792 {
793     SET_RETVAL(EXCP_INVAL);
794 }
795
796 /* fnmadds */
797 GEN_HANDLER(fnmadds, 0x3B, 0x1F, 0xFF, 0x00000000, PPC_FLOAT)
798 {
799     SET_RETVAL(EXCP_INVAL);
800 }
801
802 /* fnmsub */
803 GEN_HANDLER(fnmsub, 0x3F, 0x1E, 0xFF, 0x00000000, PPC_FLOAT)
804 {
805     SET_RETVAL(EXCP_INVAL);
806 }
807
808 /* fnmsubs */
809 GEN_HANDLER(fnmsubs, 0x3B, 0x1E, 0xFF, 0x00000000, PPC_FLOAT)
810 {
811     SET_RETVAL(EXCP_INVAL);
812 }
813
814 /***                     Floating-Point round & convert                    ***/
815 /* fctiw */
816 GEN_HANDLER(fctiw, 0x3F, 0x0E, 0xFF, 0x001F0000, PPC_FLOAT)
817 {
818     SET_RETVAL(EXCP_INVAL);
819 }
820
821 /* fctiwz */
822 GEN_HANDLER(fctiwz, 0x3F, 0x0F, 0xFF, 0x001F0000, PPC_FLOAT)
823 {
824     SET_RETVAL(EXCP_INVAL);
825 }
826
827 /* frsp */
828 GEN_HANDLER(frsp, 0x3F, 0x0C, 0xFF, 0x001F0000, PPC_FLOAT)
829 {
830     SET_RETVAL(EXCP_INVAL);
831 }
832
833 /***                         Floating-Point compare                        ***/
834 /* fcmpo */
835 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
836 {
837     SET_RETVAL(EXCP_INVAL);
838 }
839
840 /* fcmpu */
841 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
842 {
843     SET_RETVAL(EXCP_INVAL);
844 }
845
846 /***                  Floating-Point status & ctrl register                ***/
847 /* mcrfs */
848 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
849 {
850     SET_RETVAL(EXCP_INVAL);
851 }
852
853 /* mffs */
854 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
855 {
856     gen_op_load_fpscr();
857     gen_op_store_T0_gpr(rD(ctx->opcode));
858     if (Rc(ctx->opcode)) {
859         /* Update CR1 */
860     }
861     SET_RETVAL(0);
862 }
863
864 /* mtfsb0 */
865 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
866 {
867     SET_RETVAL(EXCP_INVAL);
868 }
869
870 /* mtfsb1 */
871 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
872 {
873     SET_RETVAL(EXCP_INVAL);
874 }
875
876 /* mtfsf */
877 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
878 {
879     gen_op_load_gpr_T0(rB(ctx->opcode));
880     gen_op_store_fpscr(FM(ctx->opcode));
881     if (Rc(ctx->opcode)) {
882         /* Update CR1 */
883     }
884     SET_RETVAL(0);
885 }
886
887 /* mtfsfi */
888 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
889 {
890     SET_RETVAL(EXCP_INVAL);
891 }
892
893 /***                             Integer load                              ***/
894 #define GEN_ILDZ(width, opc)                                                  \
895 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)               \
896 {                                                                             \
897     uint32_t simm = SIMM(ctx->opcode);                                        \
898     if (rA(ctx->opcode) == 0) {                                               \
899         gen_op_l##width##_z(simm);                                            \
900     } else {                                                                  \
901         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
902         gen_op_l##width (simm);                                               \
903     }                                                                         \
904     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
905     SET_RETVAL(0);                                                            \
906 }
907
908 #define GEN_ILDZU(width, opc)                                                 \
909 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)            \
910 {                                                                             \
911     if (rA(ctx->opcode) == 0 ||                                               \
912         rA(ctx->opcode) == rD(ctx->opcode))                                   \
913         SET_RETVAL(EXCP_INVAL);                                               \
914     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
915     gen_op_l##width(SIMM(ctx->opcode));                                       \
916     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
917     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
918     SET_RETVAL(0);                                                            \
919 }
920
921 #define GEN_ILDZUX(width, opc)                                                \
922 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)           \
923 {                                                                             \
924     if (rA(ctx->opcode) == 0 ||                                               \
925         rA(ctx->opcode) == rD(ctx->opcode))                                   \
926         SET_RETVAL(EXCP_INVAL);                                               \
927     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
928     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
929     gen_op_l##width##x();                                                     \
930     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
931     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
932     SET_RETVAL(0);                                                            \
933 }
934
935 #define GEN_ILDZX(width, opc2, opc3)                                          \
936 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)           \
937 {                                                                             \
938     if (rA(ctx->opcode) == 0) {                                               \
939         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
940         gen_op_l##width##x_z();                                               \
941     } else {                                                                  \
942         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
943         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
944         gen_op_l##width##x();                                                 \
945     }                                                                         \
946     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
947     SET_RETVAL(0);                                                            \
948 }
949
950 #define GEN_ILD(width, op)                                                    \
951 GEN_ILDZ(width, op | 0x20)                                                    \
952 GEN_ILDZU(width, op | 0x21)                                                   \
953 GEN_ILDZUX(width, op | 0x01)                                                  \
954 GEN_ILDZX(width, 0x17, op | 0x00)
955
956 /* lbz lbzu lbzux lbzx */
957 GEN_ILD(bz, 0x02);
958 /* lha lhau lhaux lhax */
959 GEN_ILD(ha, 0x0A);
960 /* lhz lhzu lhzux lhzx */
961 GEN_ILD(hz, 0x08);
962 /* lwz lwzu lwzux lwzx */
963 GEN_ILD(wz, 0x00);
964
965 /***                              Integer store                            ***/
966 #define GEN_IST(width, opc)                                                   \
967 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)              \
968 {                                                                             \
969     uint32_t simm = SIMM(ctx->opcode);                                        \
970     if (rA(ctx->opcode) == 0) {                                               \
971         gen_op_load_gpr_T0(rS(ctx->opcode));                                  \
972         gen_op_st##width##_z(simm);                                           \
973     } else {                                                                  \
974         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
975         gen_op_load_gpr_T1(rS(ctx->opcode));                                  \
976         gen_op_st##width(simm);                                               \
977     }                                                                         \
978     SET_RETVAL(0);                                                            \
979 }
980
981 #define GEN_ISTU(width, opc)                                                  \
982 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)           \
983 {                                                                             \
984     if (rA(ctx->opcode) == 0)                                                 \
985         SET_RETVAL(EXCP_INVAL);                                               \
986     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
987     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
988     gen_op_st##width(SIMM(ctx->opcode));                                      \
989     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
990     SET_RETVAL(0);                                                            \
991 }
992
993 #define GEN_ISTUX(width, opc)                                                 \
994 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
995 {                                                                             \
996     if (rA(ctx->opcode) == 0)                                                 \
997         SET_RETVAL(EXCP_INVAL);                                               \
998     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
999     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1000     gen_op_load_gpr_T2(rS(ctx->opcode));                                      \
1001     gen_op_st##width##x();                                                    \
1002     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1003     SET_RETVAL(0);                                                            \
1004 }
1005
1006 #define GEN_ISTX(width, opc2, opc3)                                           \
1007 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)          \
1008 {                                                                             \
1009     if (rA(ctx->opcode) == 0) {                                               \
1010         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1011         gen_op_load_gpr_T1(rS(ctx->opcode));                                  \
1012         gen_op_st##width##x_z();                                              \
1013     } else {                                                                  \
1014         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1015         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1016         gen_op_load_gpr_T2(rS(ctx->opcode));                                  \
1017         gen_op_st##width##x();                                                \
1018     }                                                                         \
1019     SET_RETVAL(0);                                                            \
1020 }
1021
1022 #define GEN_ISTO(width, opc)                                                  \
1023 GEN_IST(width, opc | 0x20)                                                    \
1024 GEN_ISTU(width, opc | 0x21)                                                   \
1025 GEN_ISTUX(width, opc | 0x01)                                                  \
1026 GEN_ISTX(width, 0x17, opc | 0x00)
1027
1028 /* stb stbu stbux stbx */
1029 GEN_ISTO(b, 0x06);
1030 /* sth sthu sthux sthx */
1031 GEN_ISTO(h, 0x0C);
1032 /* stw stwu stwux stwx */
1033 GEN_ISTO(w, 0x04);
1034
1035 /***                Integer load and store with byte reverse               ***/
1036 /* lhbrx */
1037 GEN_ILDZX(hbr, 0x16, 0x18);
1038 /* lwbrx */
1039 GEN_ILDZX(wbr, 0x16, 0x10);
1040 /* sthbrx */
1041 GEN_ISTX(hbr, 0x16, 0x1C);
1042 /* stwbrx */
1043 GEN_ISTX(wbr, 0x16, 0x14);
1044
1045 /***                    Integer load and store multiple                    ***/
1046 /* lmw */
1047 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1048 {
1049     if (rA(ctx->opcode) == 0) {
1050         gen_op_set_T0(0);
1051     } else {
1052         gen_op_load_gpr_T0(rA(ctx->opcode));
1053     }
1054     gen_op_lmw(rD(ctx->opcode), SIMM(ctx->opcode));
1055     SET_RETVAL(0);
1056 }
1057
1058 /* stmw */
1059 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1060 {
1061     if (rA(ctx->opcode) == 0) {
1062         gen_op_set_T0(0);
1063     } else {
1064         gen_op_load_gpr_T0(rA(ctx->opcode));
1065     }
1066     gen_op_stmw(rS(ctx->opcode), SIMM(ctx->opcode));
1067     SET_RETVAL(0);
1068 }
1069
1070 /***                    Integer load and store strings                     ***/
1071 /* lswi */
1072 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
1073 {
1074     int nb = NB(ctx->opcode);
1075     int start = rD(ctx->opcode);
1076     int nr;
1077
1078     if (nb == 0)
1079         nb = 32;
1080     nr = nb / 4;
1081     if ((start + nr) > 32) {
1082         /* handle wrap around r0 */
1083         if (rA(ctx->opcode) == 0) {
1084             gen_op_set_T0(0);
1085         } else {
1086             gen_op_load_gpr_T0(rA(ctx->opcode));
1087         }
1088         gen_op_lswi(start, 4 * (32 - start));
1089         nb -= 4 * (32 - start);
1090         start = 0;
1091     }
1092     if (rA(ctx->opcode) == 0) {
1093         gen_op_set_T0(0);
1094     } else {
1095         gen_op_load_gpr_T0(rA(ctx->opcode));
1096     }
1097     gen_op_lswi(start, nb);
1098     SET_RETVAL(0);
1099 }
1100
1101 /* lswx */
1102 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
1103 {
1104     gen_op_load_xer_bc();
1105     gen_op_load_gpr_T1(rB(ctx->opcode));
1106     if (rA(ctx->opcode) == 0) {
1107         gen_op_set_T2(0);
1108     } else {
1109         gen_op_load_gpr_T2(rA(ctx->opcode));
1110     }
1111     gen_op_lswx(rD(ctx->opcode));
1112     SET_RETVAL(0);
1113 }
1114
1115 /* stswi */
1116 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
1117 {
1118     int nb = NB(ctx->opcode);
1119     int start = rS(ctx->opcode);
1120     int nr;
1121
1122     if (nb == 0)
1123         nb = 32;
1124     nr = nb / 4;
1125     if ((start + nr) > 32) {
1126         /* handle wrap around r0 */
1127         if (rA(ctx->opcode) == 0) {
1128             gen_op_set_T0(0);
1129         } else {
1130             gen_op_load_gpr_T0(rA(ctx->opcode));
1131         }
1132         gen_op_stswi(start, 4 * (32 - start));
1133         nb -= 4 * (32 - start);
1134         start = 0;
1135     }
1136     if (rA(ctx->opcode) == 0) {
1137         gen_op_set_T0(0);
1138     } else {
1139         gen_op_load_gpr_T0(rA(ctx->opcode));
1140     }
1141     gen_op_stswi(start, nb);
1142     SET_RETVAL(0);
1143 }
1144
1145 /* stswx */
1146 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
1147 {
1148     gen_op_load_xer_bc();
1149     gen_op_load_gpr_T1(rB(ctx->opcode));
1150     if (rA(ctx->opcode) == 0) {
1151         gen_op_set_T2(0);
1152     } else {
1153         gen_op_load_gpr_T2(rA(ctx->opcode));
1154     }
1155     gen_op_stswx(rS(ctx->opcode));
1156     SET_RETVAL(0);
1157 }
1158
1159 /***                        Memory synchronisation                         ***/
1160 /* eieio */
1161 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM)
1162 {
1163     /* Do a branch to next instruction */
1164     gen_op_b((uint32_t)ctx->nip);
1165     SET_RETVAL(EXCP_BRANCH);
1166 }
1167
1168 /* isync */
1169 GEN_HANDLER(isync, 0x13, 0x16, 0xFF, 0x03FF0801, PPC_MEM)
1170 {
1171     /* Do a branch to next instruction */
1172     gen_op_b((uint32_t)ctx->nip);
1173     SET_RETVAL(EXCP_BRANCH);
1174 }
1175
1176 /* lwarx */
1177 GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_MEM)
1178 {
1179     reserve = 1;
1180     if (rA(ctx->opcode) == 0) {
1181         gen_op_load_gpr_T0(rB(ctx->opcode));
1182         gen_op_lwzx_z();
1183         gen_op_set_reservation();
1184     } else {
1185         gen_op_load_gpr_T0(rA(ctx->opcode));
1186         gen_op_load_gpr_T1(rB(ctx->opcode));
1187         gen_op_lwzx();
1188         gen_op_set_reservation();
1189     }
1190     gen_op_store_T1_gpr(rD(ctx->opcode));
1191     SET_RETVAL(0);
1192 }
1193
1194 /* stwcx. */
1195 GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_MEM)
1196 {
1197     if (reserve == 0) {
1198         gen_op_reset_Rc0();
1199     } else {
1200         if (rA(ctx->opcode) == 0) {
1201             gen_op_load_gpr_T0(rB(ctx->opcode));
1202             gen_op_load_gpr_T1(rS(ctx->opcode));
1203             gen_op_stwx_z();
1204         } else {
1205             gen_op_load_gpr_T0(rA(ctx->opcode));
1206             gen_op_load_gpr_T1(rB(ctx->opcode));
1207             gen_op_load_gpr_T2(rS(ctx->opcode));
1208             gen_op_stwx();
1209         }
1210         gen_op_set_Rc0_1();
1211         gen_op_reset_reservation();
1212     }
1213     SET_RETVAL(0);
1214 }
1215
1216 /* sync */
1217 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM)
1218 {
1219     /* Do a branch to next instruction */
1220     gen_op_b((uint32_t)ctx->nip);
1221     SET_RETVAL(EXCP_BRANCH);
1222 }
1223
1224 /***                         Floating-point load                           ***/
1225 #define GEN_LF(width, opc)                                                    \
1226 GEN_HANDLER(lf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
1227 {                                                                             \
1228     uint32_t simm = SIMM(ctx->opcode);                                        \
1229     if (rA(ctx->opcode) == 0) {                                               \
1230         gen_op_lf##width##_z_FT0(simm);                          \
1231     } else {                                                                  \
1232         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1233         gen_op_lf##width##_FT0(simm);                              \
1234     }                                                                         \
1235     gen_op_store_FT0_fpr(rD(ctx->opcode));\
1236     SET_RETVAL(0);                                                            \
1237 }
1238
1239 #define GEN_LFU(width, opc)                                                   \
1240 GEN_HANDLER(lf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
1241 {                                                                             \
1242     if (rA(ctx->opcode) == 0 ||                                               \
1243         rA(ctx->opcode) == rD(ctx->opcode))                                   \
1244         SET_RETVAL(EXCP_INVAL);                                               \
1245     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1246     gen_op_lf##width##_FT0(SIMM(ctx->opcode));                     \
1247     gen_op_store_FT0_fpr(rD(ctx->opcode));\
1248     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1249     SET_RETVAL(0);                                                            \
1250 }
1251
1252 #define GEN_LFUX(width, opc)                                                  \
1253 GEN_HANDLER(lf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
1254 {                                                                             \
1255     if (rA(ctx->opcode) == 0 ||                                               \
1256         rA(ctx->opcode) == rD(ctx->opcode))                                   \
1257         SET_RETVAL(EXCP_INVAL);                                               \
1258     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1259     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1260     gen_op_lf##width##x_FT0();                                     \
1261     gen_op_store_FT0_fpr(rD(ctx->opcode));\
1262     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1263     SET_RETVAL(0);                                                            \
1264 }
1265
1266 #define GEN_LFX(width, opc)                                                   \
1267 GEN_HANDLER(lf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
1268 {                                                                             \
1269     if (rA(ctx->opcode) == 0) {                                               \
1270         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1271         gen_op_lf##width##x_z_FT0();                               \
1272     } else {                                                                  \
1273         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1274         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1275         gen_op_lf##width##x_FT0();                                 \
1276     }                                                                         \
1277     gen_op_store_FT0_fpr(rD(ctx->opcode));\
1278     SET_RETVAL(0);                                                            \
1279 }
1280
1281 #define GEN_LDF(width, opc)                                                   \
1282 GEN_LF(width, opc | 0x20)                                                     \
1283 GEN_LFU(width, opc | 0x21)                                                    \
1284 GEN_LFUX(width, opc | 0x01)                                                   \
1285 GEN_LFX(width, opc | 0x00)
1286
1287 /* lfd lfdu lfdux lfdx */
1288 GEN_LDF(d, 0x12);
1289 /* lfs lfsu lfsux lfsx */
1290 GEN_LDF(s, 0x10);
1291
1292 /***                         Floating-point store                          ***/
1293 #define GEN_STF(width, opc)                                                   \
1294 GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)               \
1295 {                                                                             \
1296     uint32_t simm = SIMM(ctx->opcode);                                        \
1297     gen_op_load_FT0_fpr(rS(ctx->opcode));\
1298     if (rA(ctx->opcode) == 0) {                                               \
1299         gen_op_stf##width##_z_FT0(simm);                         \
1300     } else {                                                                  \
1301         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1302         gen_op_stf##width##_FT0(simm);                             \
1303     }                                                                         \
1304     SET_RETVAL(0);                                                            \
1305 }
1306
1307 #define GEN_STFU(width, opc)                                                  \
1308 GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)            \
1309 {                                                                             \
1310     if (rA(ctx->opcode) == 0)                                                 \
1311         SET_RETVAL(EXCP_INVAL);                                               \
1312     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1313     gen_op_load_FT0_fpr(rS(ctx->opcode));\
1314     gen_op_stf##width##_FT0(SIMM(ctx->opcode));                    \
1315     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1316     SET_RETVAL(0);                                                            \
1317 }
1318
1319 #define GEN_STFUX(width, opc)                                                 \
1320 GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)           \
1321 {                                                                             \
1322     if (rA(ctx->opcode) == 0)                                                 \
1323         SET_RETVAL(EXCP_INVAL);                                               \
1324     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1325     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1326     gen_op_load_FT0_fpr(rS(ctx->opcode));\
1327     gen_op_stf##width##x_FT0();                                    \
1328     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1329     SET_RETVAL(0);                                                            \
1330 }
1331
1332 #define GEN_STFX(width, opc)                                                  \
1333 GEN_HANDLER(stf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
1334 {                                                                             \
1335     gen_op_load_FT0_fpr(rS(ctx->opcode));\
1336     if (rA(ctx->opcode) == 0) {                                               \
1337         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1338         gen_op_stf##width##x_z_FT0();                              \
1339     } else {                                                                  \
1340         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1341         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1342         gen_op_stf##width##x_FT0();                                \
1343     }                                                                         \
1344     SET_RETVAL(0);                                                            \
1345 }
1346
1347 #define GEN_STOF(width, opc)                                                  \
1348 GEN_STF(width, opc | 0x20)                                                    \
1349 GEN_STFU(width, opc | 0x21)                                                   \
1350 GEN_STFUX(width, opc | 0x01)                                                  \
1351 GEN_STFX(width, opc | 0x00)
1352
1353 /* stfd stfdu stfdux stfdx */
1354 GEN_STOF(d, 0x16);
1355 /* stfs stfsu stfsux stfsx */
1356 GEN_STOF(s, 0x14);
1357
1358 /* Optional: */
1359 /* stfiwx */
1360 GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1361 {
1362     SET_RETVAL(EXCP_INVAL);
1363 }
1364
1365 /***                         Floating-point move                           ***/
1366 /* fabs */
1367 GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT)
1368 {
1369     SET_RETVAL(EXCP_INVAL);
1370 }
1371
1372 /* fmr */
1373 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1374 {
1375     SET_RETVAL(EXCP_INVAL);
1376 }
1377
1378 /* fnabs */
1379 GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT)
1380 {
1381     SET_RETVAL(EXCP_INVAL);
1382 }
1383
1384 /* fneg */
1385 GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT)
1386 {
1387     SET_RETVAL(EXCP_INVAL);
1388 }
1389
1390 /***                                Branch                                 ***/
1391 #define GEN_BCOND(name, opc1, opc2, opc3, prologue,                           \
1392    bl_ctr,       b_ctr,       bl_ctrz,       b_ctrz,       b,                 \
1393    bl_ctr_true,  b_ctr_true,  bl_ctrz_true,  b_ctrz_true,  bl_true,  b_true,  \
1394    bl_ctr_false, b_ctr_false, bl_ctrz_false, b_ctrz_false, bl_false, b_false) \
1395 GEN_HANDLER(name, opc1, opc2, opc3, 0x00000000, PPC_FLOW)                     \
1396 {                                                                             \
1397     __attribute__ ((unused)) uint32_t target;                                 \
1398     uint32_t bo = BO(ctx->opcode);                                            \
1399     uint32_t bi = BI(ctx->opcode);                                            \
1400     uint32_t mask;                                                            \
1401     prologue;                                                                 \
1402     if ((bo & 0x4) == 0)                                                      \
1403         gen_op_dec_ctr();                                                     \
1404     if (bo & 0x10) {                                                          \
1405         /* No CR condition */                                                 \
1406         switch (bo & 0x6) {                                                   \
1407         case 0:                                                               \
1408             if (LK(ctx->opcode)) {                                            \
1409                 bl_ctr;                                                       \
1410             } else {                                                          \
1411                 b_ctr;                                                        \
1412             }                                                                 \
1413             break;                                                            \
1414         case 2:                                                               \
1415             if (LK(ctx->opcode)) {                                            \
1416                 bl_ctrz;                                                      \
1417             } else {                                                          \
1418                 b_ctrz;                                                       \
1419             }                                                                 \
1420             break;                                                            \
1421         case 4:                                                               \
1422         case 6:                                                               \
1423             b;                                                                \
1424             if (LK(ctx->opcode))                                              \
1425                 gen_op_load_lr((uint32_t)ctx->nip);                           \
1426             break;                                                            \
1427         default:                                                              \
1428             printf("ERROR: %s: unhandled ba case (%d)\n", __func__, bo);      \
1429             SET_RETVAL(EXCP_INVAL);                                           \
1430             break;                                                            \
1431         }                                                                     \
1432     } else {                                                                  \
1433         mask = 1 << (3 - (bi & 0x03));                                        \
1434         gen_op_load_crf_T0(bi >> 2);                                          \
1435         if (bo & 0x8) {                                                       \
1436             switch (bo & 0x6) {                                               \
1437             case 0:                                                           \
1438                 if (LK(ctx->opcode)) {                                        \
1439                     bl_ctr_true;                                              \
1440                 } else {                                                      \
1441                     b_ctr_true;                                               \
1442                 }                                                             \
1443                 break;                                                        \
1444             case 2:                                                           \
1445                 if (LK(ctx->opcode)) {                                        \
1446                     bl_ctrz_true;                                             \
1447                 } else {                                                      \
1448                     b_ctrz_true;                                              \
1449                 }                                                             \
1450                 break;                                                        \
1451             case 4:                                                           \
1452             case 6:                                                           \
1453                 if (LK(ctx->opcode)) {                                        \
1454                     bl_true;                                                  \
1455                 } else {                                                      \
1456                     b_true;                                                   \
1457                 }                                                             \
1458                 break;                                                        \
1459             default:                                                          \
1460                 printf("ERROR: %s: unhandled b case (%d)\n", __func__, bo);   \
1461                 SET_RETVAL(EXCP_INVAL);                                       \
1462                 break;                                                        \
1463             }                                                                 \
1464         } else {                                                              \
1465             switch (bo & 0x6) {                                               \
1466             case 0:                                                           \
1467                 if (LK(ctx->opcode)) {                                        \
1468                     bl_ctr_false;                                             \
1469                 } else {                                                      \
1470                     b_ctr_false;                                              \
1471                 }                                                             \
1472                 break;                                                        \
1473             case 2:                                                           \
1474                 if (LK(ctx->opcode)) {                                        \
1475                     bl_ctrz_false;                                            \
1476                 } else {                                                      \
1477                     b_ctrz_false;                                             \
1478                 }                                                             \
1479                 break;                                                        \
1480             case 4:                                                           \
1481             case 6:                                                           \
1482                 if (LK(ctx->opcode)) {                                        \
1483                     bl_false;                                                 \
1484                 } else {                                                      \
1485                     b_false;                                                  \
1486                 }                                                             \
1487                 break;                                                        \
1488             default:                                                          \
1489                 printf("ERROR: %s: unhandled bn case (%d)\n", __func__, bo);  \
1490                 SET_RETVAL(EXCP_INVAL);                                       \
1491                 break;                                                        \
1492             }                                                                 \
1493         }                                                                     \
1494     }                                                                         \
1495     SET_RETVAL(EXCP_BRANCH);                                                  \
1496 }
1497
1498 /* b ba bl bla */
1499 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1500 {
1501     uint32_t li = s_ext24(LI(ctx->opcode)), target;
1502
1503     if (AA(ctx->opcode) == 0)
1504         target = (uint32_t)ctx->nip + li - 4;
1505     else
1506         target = s_ext24(LI(ctx->opcode));
1507     gen_op_b(target);
1508     if (LK(ctx->opcode))
1509         gen_op_load_lr((uint32_t)ctx->nip);
1510     SET_RETVAL(EXCP_BRANCH);
1511 }
1512
1513 /* bc bca bcl bcla */
1514 GEN_BCOND(bc, 0x10, 0xFF, 0xFF,
1515           do {
1516               uint32_t li = s_ext16(BD(ctx->opcode));
1517               if (AA(ctx->opcode) == 0) {
1518                   target = (uint32_t)ctx->nip + li - 4;
1519               } else {
1520                   target = li;
1521               }
1522           } while (0),
1523           gen_op_bl_ctr((uint32_t)ctx->nip, target),
1524           gen_op_b_ctr((uint32_t)ctx->nip, target),
1525           gen_op_bl_ctrz((uint32_t)ctx->nip, target),
1526           gen_op_b_ctrz((uint32_t)ctx->nip, target),
1527           gen_op_b(target),
1528           gen_op_bl_ctr_true((uint32_t)ctx->nip, target, mask),
1529           gen_op_b_ctr_true((uint32_t)ctx->nip, target, mask),
1530           gen_op_bl_ctrz_true((uint32_t)ctx->nip, target, mask),
1531           gen_op_b_ctrz_true((uint32_t)ctx->nip, target, mask),
1532           gen_op_bl_true((uint32_t)ctx->nip, target, mask),
1533           gen_op_b_true((uint32_t)ctx->nip, target, mask),
1534           gen_op_bl_ctr_false((uint32_t)ctx->nip, target, mask),
1535           gen_op_b_ctr_false((uint32_t)ctx->nip, target, mask),
1536           gen_op_bl_ctrz_false((uint32_t)ctx->nip, target, mask),
1537           gen_op_b_ctrz_false((uint32_t)ctx->nip, target, mask),
1538           gen_op_bl_false((uint32_t)ctx->nip, target, mask),
1539           gen_op_b_false((uint32_t)ctx->nip, target, mask));
1540
1541 /* bcctr bcctrl */
1542 GEN_BCOND(bcctr, 0x13, 0x10, 0x10, do { } while (0),
1543           gen_op_bctrl_ctr((uint32_t)ctx->nip),
1544           gen_op_bctr_ctr((uint32_t)ctx->nip),
1545           gen_op_bctrl_ctrz((uint32_t)ctx->nip),
1546           gen_op_bctr_ctrz((uint32_t)ctx->nip),
1547           gen_op_bctr(),
1548           gen_op_bctrl_ctr_true((uint32_t)ctx->nip, mask),
1549           gen_op_bctr_ctr_true((uint32_t)ctx->nip, mask),
1550           gen_op_bctrl_ctrz_true((uint32_t)ctx->nip, mask),
1551           gen_op_bctr_ctrz_true((uint32_t)ctx->nip, mask),
1552           gen_op_bctrl_true((uint32_t)ctx->nip, mask),
1553           gen_op_bctr_true((uint32_t)ctx->nip, mask),
1554           gen_op_bctrl_ctr_false((uint32_t)ctx->nip, mask),
1555           gen_op_bctr_ctr_false((uint32_t)ctx->nip, mask),
1556           gen_op_bctrl_ctrz_false((uint32_t)ctx->nip, mask),
1557           gen_op_bctr_ctrz_false((uint32_t)ctx->nip, mask),
1558           gen_op_bctrl_false((uint32_t)ctx->nip, mask),
1559           gen_op_bctr_false((uint32_t)ctx->nip, mask))
1560
1561 /* bclr bclrl */
1562 GEN_BCOND(bclr, 0x13, 0x10, 0x00, do { } while (0),
1563           gen_op_blrl_ctr((uint32_t)ctx->nip),
1564           gen_op_blr_ctr((uint32_t)ctx->nip),
1565           gen_op_blrl_ctrz((uint32_t)ctx->nip),
1566           gen_op_blr_ctrz((uint32_t)ctx->nip),
1567           gen_op_blr(),
1568           gen_op_blrl_ctr_true((uint32_t)ctx->nip, mask),
1569           gen_op_blr_ctr_true((uint32_t)ctx->nip, mask),
1570           gen_op_blrl_ctrz_true((uint32_t)ctx->nip, mask),
1571           gen_op_blr_ctrz_true((uint32_t)ctx->nip, mask),
1572           gen_op_blrl_true((uint32_t)ctx->nip, mask),
1573           gen_op_blr_true((uint32_t)ctx->nip, mask),
1574           gen_op_blrl_ctr_false((uint32_t)ctx->nip, mask),
1575           gen_op_blr_ctr_false((uint32_t)ctx->nip, mask),
1576           gen_op_blrl_ctrz_false((uint32_t)ctx->nip, mask),
1577           gen_op_blr_ctrz_false((uint32_t)ctx->nip, mask),
1578           gen_op_blrl_false((uint32_t)ctx->nip, mask),
1579           gen_op_blr_false((uint32_t)ctx->nip, mask))
1580
1581 /***                      Condition register logical                       ***/
1582 #define GEN_CRLOGIC(op, opc)                                                  \
1583 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
1584 {                                                                             \
1585     gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
1586     gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
1587     gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
1588     gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
1589     gen_op_##op();                                                            \
1590     gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
1591     gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
1592                      3 - (crbD(ctx->opcode) & 0x03));                         \
1593     gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
1594     SET_RETVAL(0);                                                            \
1595 }
1596
1597 /* crand */
1598 GEN_CRLOGIC(and, 0x08)
1599 /* crandc */
1600 GEN_CRLOGIC(andc, 0x04)
1601 /* creqv */
1602 GEN_CRLOGIC(eqv, 0x09)
1603 /* crnand */
1604 GEN_CRLOGIC(nand, 0x07)
1605 /* crnor */
1606 GEN_CRLOGIC(nor, 0x01)
1607 /* cror */
1608 GEN_CRLOGIC(or, 0x0E)
1609 /* crorc */
1610 GEN_CRLOGIC(orc, 0x0D)
1611 /* crxor */
1612 GEN_CRLOGIC(xor, 0x06)
1613 /* mcrf */
1614 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
1615 {
1616     gen_op_load_crf_T0(crfS(ctx->opcode));
1617     gen_op_store_T0_crf(crfD(ctx->opcode));
1618     SET_RETVAL(0);
1619 }
1620
1621 /***                           System linkage                              ***/
1622 /* rfi (supervisor only) */
1623 GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
1624 {
1625     SET_RETVAL(EXCP_INVAL);
1626 }
1627
1628 /* sc */
1629 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
1630 {
1631     gen_op_b((uint32_t)ctx->nip);
1632     SET_RETVAL(EXCP_SYSCALL);
1633 }
1634
1635 /***                                Trap                                   ***/
1636 /* tw */
1637 GEN_HANDLER(tw, 0x1F, 0x04, 0xFF, 0x00000001, PPC_FLOW)
1638 {
1639     SET_RETVAL(EXCP_INVAL);
1640 }
1641
1642 /* twi */
1643 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1644 {
1645     SET_RETVAL(EXCP_INVAL);
1646 }
1647
1648 /***                          Processor control                            ***/
1649 static inline int check_spr_access (int spr, int rw, int supervisor)
1650 {
1651     uint32_t rights = spr_access[spr >> 1] >> (4 * (spr & 1));
1652
1653     rights = rights >> (2 * supervisor);
1654     rights = rights >> rw;
1655
1656     return rights & 1;
1657 }
1658
1659 /* mcrxr */
1660 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
1661 {
1662     gen_op_load_xer_cr();
1663     gen_op_store_T0_crf(crfD(ctx->opcode));
1664     gen_op_clear_xer_cr();
1665     SET_RETVAL(0);
1666 }
1667
1668 /* mfcr */
1669 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x001FF801, PPC_MISC)
1670 {
1671     gen_op_load_cr();
1672     gen_op_store_T0_gpr(rD(ctx->opcode));
1673     SET_RETVAL(0);
1674 }
1675
1676 /* mfmsr */
1677 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1678 {
1679     if (!ctx->supervisor)
1680         SET_RETVAL(EXCP_PRIV);
1681     gen_op_load_msr();
1682     gen_op_store_T0_gpr(rD(ctx->opcode));
1683     SET_RETVAL(0);
1684 }
1685
1686 /* mfspr */
1687 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
1688 {
1689     uint32_t sprn = SPR(ctx->opcode);
1690
1691     if (check_spr_access(sprn, 0, ctx->supervisor) == 0)
1692         SET_RETVAL(EXCP_PRIV);
1693     /* XXX: make this more generic */
1694     switch (sprn) {
1695     case SPR_ENCODE(1):
1696         if (loglevel > 0) {
1697             fprintf(logfile, "LOAD XER at %p\n", ctx->nip - 1);
1698         }
1699         gen_op_load_xer();
1700         break;
1701     case SPR_ENCODE(268):
1702         /* We need to update the time base before reading it */
1703         gen_op_update_tb(ctx->tb_offset);
1704         ctx->tb_offset = 0;
1705         break;
1706     case SPR_ENCODE(269):
1707         gen_op_update_tb(ctx->tb_offset);
1708         ctx->tb_offset = 0;
1709         break;
1710     default:
1711         gen_op_load_spr(sprn);
1712         break;
1713     }
1714     gen_op_store_T0_gpr(rD(ctx->opcode)); //
1715     SET_RETVAL(0);
1716 }
1717
1718 /* mftb */
1719 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC)
1720 {
1721     uint32_t sprn = SPR(ctx->opcode);
1722
1723     if (check_spr_access(sprn, 0, ctx->supervisor) == 0)
1724         SET_RETVAL(EXCP_PRIV);
1725     switch (sprn) {
1726     case SPR_ENCODE(268):
1727         /* We need to update the time base before reading it */
1728         gen_op_update_tb(ctx->tb_offset);
1729         ctx->tb_offset = 0;
1730         break;
1731     case SPR_ENCODE(269):
1732         gen_op_update_tb(ctx->tb_offset);
1733         ctx->tb_offset = 0;
1734         break;
1735     default:
1736         SET_RETVAL(EXCP_INVAL);
1737         break;
1738     }
1739     SET_RETVAL(0);
1740 }
1741
1742 /* mtcrf */
1743 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00100801, PPC_MISC)
1744 {
1745     gen_op_load_gpr_T0(rS(ctx->opcode));
1746     gen_op_store_cr(CRM(ctx->opcode));
1747     SET_RETVAL(0);
1748 }
1749
1750 /* mtmsr */
1751 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
1752 {
1753     if (!ctx->supervisor)
1754         SET_RETVAL(EXCP_PRIV);
1755     gen_op_load_gpr_T0(rS(ctx->opcode));
1756     gen_op_store_msr();
1757     /* Must stop the translation as machine state (may have) changed */
1758     SET_RETVAL(EXCP_MTMSR);
1759 }
1760
1761 /* mtspr */
1762 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
1763 {
1764     uint32_t sprn = SPR(ctx->opcode);
1765
1766     if (check_spr_access(sprn, 1, ctx->supervisor) == 0)
1767         SET_RETVAL(EXCP_PRIV);
1768     gen_op_load_gpr_T0(rS(ctx->opcode));
1769     if (sprn == SPR_ENCODE(1)) {
1770         gen_op_store_xer();
1771     } else {
1772         gen_op_store_spr(sprn);
1773     }
1774     SET_RETVAL(0);
1775 }
1776
1777 /***                         Cache management                              ***/
1778 /* For now, all those will be implemented as nop:
1779  * this is valid, regarding the PowerPC specs...
1780  */
1781 /* dcbf */
1782 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x17, 0x03E00001, PPC_MEM)
1783 {
1784     SET_RETVAL(0);
1785 }
1786
1787 /* dcbi (Supervisor only) */
1788 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_MEM)
1789 {
1790     SET_RETVAL(0);
1791 }
1792
1793 /* dcdst */
1794 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_MEM)
1795 {
1796     SET_RETVAL(0);
1797 }
1798
1799 /* dcbt */
1800 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x01, 0x03E00001, PPC_MEM)
1801 {
1802     SET_RETVAL(0);
1803 }
1804
1805 /* dcbtst */
1806 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x02, 0x03E00001, PPC_MEM)
1807 {
1808     SET_RETVAL(0);
1809 }
1810
1811 /* dcbz */
1812 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x08, 0x03E00001, PPC_MEM)
1813 {
1814     SET_RETVAL(0);
1815 }
1816
1817 /* icbi */
1818 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_MEM)
1819 {
1820     SET_RETVAL(0);
1821 }
1822
1823 /* Optional: */
1824 /* dcba */
1825 GEN_HANDLER(dcba, 0x1F, 0x16, 0x07, 0x03E00001, PPC_MEM)
1826 {
1827     SET_RETVAL(0);
1828 }
1829
1830 /***                    Segment register manipulation                      ***/
1831 /* Supervisor only: */
1832 /* mfsr */
1833 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
1834 {
1835     SET_RETVAL(EXCP_INVAL);
1836 }
1837
1838 /* mfsrin */
1839 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x0010F001, PPC_SEGMENT)
1840 {
1841     SET_RETVAL(EXCP_INVAL);
1842 }
1843
1844 /* mtsr */
1845 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x02, 0x0010F801, PPC_SEGMENT)
1846 {
1847     SET_RETVAL(EXCP_INVAL);
1848 }
1849
1850 /* mtsrin */
1851 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x0010F001, PPC_SEGMENT)
1852 {
1853     SET_RETVAL(EXCP_INVAL);
1854 }
1855
1856 /***                      Lookaside buffer management                      ***/
1857 /* Optional & supervisor only: */
1858 /* tlbia */
1859 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM)
1860 {
1861     SET_RETVAL(EXCP_INVAL);
1862 }
1863
1864 /* tlbie */
1865 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF8001, PPC_MEM)
1866 {
1867     SET_RETVAL(EXCP_INVAL);
1868 }
1869
1870 /* tlbsync */
1871 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFFC01, PPC_MEM)
1872 {
1873     SET_RETVAL(EXCP_INVAL);
1874 }
1875
1876 /***                              External control                         ***/
1877 /* Optional: */
1878 /* eciwx */
1879 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
1880 {
1881     SET_RETVAL(EXCP_INVAL);
1882 }
1883
1884 /* ecowx */
1885 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
1886 {
1887     SET_RETVAL(EXCP_INVAL);
1888 }
1889
1890 /* End opcode list */
1891 GEN_OPCODE_MARK(end);
1892
1893 /*****************************************************************************/
1894
1895 #include <string.h>
1896 extern FILE *stderr;
1897 void free (void *p);
1898 int fflush (FILE *f);
1899
1900 /* Main ppc opcodes table:
1901  * at init, all opcodes are invalids
1902  */
1903 static opc_handler_t *ppc_opcodes[0x40];
1904
1905 /* Opcode types */
1906 enum {
1907     PPC_DIRECT   = 0, /* Opcode routine        */
1908     PPC_INDIRECT = 1, /* Indirect opcode table */
1909 };
1910
1911 static inline int is_indirect_opcode (void *handler)
1912 {
1913     return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
1914 }
1915
1916 static inline opc_handler_t **ind_table(void *handler)
1917 {
1918     return (opc_handler_t **)((unsigned long)handler & ~3);
1919 }
1920
1921 /* Opcodes tables creation */
1922 static void fill_new_table (opc_handler_t **table, int len)
1923 {
1924     int i;
1925
1926     for (i = 0; i < len; i++)
1927         table[i] = &invalid_handler;
1928 }
1929
1930 static int create_new_table (opc_handler_t **table, unsigned char idx)
1931 {
1932     opc_handler_t **tmp;
1933
1934     tmp = malloc(0x20 * sizeof(opc_handler_t));
1935     if (tmp == NULL)
1936         return -1;
1937     fill_new_table(tmp, 0x20);
1938     table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
1939
1940     return 0;
1941 }
1942
1943 static int insert_in_table (opc_handler_t **table, unsigned char idx,
1944                             opc_handler_t *handler)
1945 {
1946     if (table[idx] != &invalid_handler)
1947         return -1;
1948     table[idx] = handler;
1949
1950     return 0;
1951 }
1952
1953 static int register_direct_insn (unsigned char idx, opc_handler_t *handler)
1954 {
1955     if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
1956         fprintf(stderr, "*** ERROR: opcode %02x already assigned in main "
1957                 "opcode table\n", idx);
1958         return -1;
1959     }
1960
1961     return 0;
1962 }
1963
1964 static int register_ind_in_table (opc_handler_t **table,
1965                                   unsigned char idx1, unsigned char idx2,
1966                                   opc_handler_t *handler)
1967 {
1968     if (table[idx1] == &invalid_handler) {
1969         if (create_new_table(table, idx1) < 0) {
1970             fprintf(stderr, "*** ERROR: unable to create indirect table "
1971                     "idx=%02x\n", idx1);
1972             return -1;
1973         }
1974     } else {
1975         if (!is_indirect_opcode(table[idx1])) {
1976             fprintf(stderr, "*** ERROR: idx %02x already assigned to a direct "
1977                     "opcode\n", idx1);
1978             return -1;
1979         }
1980     }
1981     if (handler != NULL &&
1982         insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
1983         fprintf(stderr, "*** ERROR: opcode %02x already assigned in "
1984                 "opcode table %02x\n", idx2, idx1);
1985         return -1;
1986     }
1987
1988     return 0;
1989 }
1990
1991 static int register_ind_insn (unsigned char idx1, unsigned char idx2,
1992                                opc_handler_t *handler)
1993 {
1994     int ret;
1995
1996     ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
1997
1998     return ret;
1999 }
2000
2001 static int register_dblind_insn (unsigned char idx1, unsigned char idx2,
2002                                   unsigned char idx3, opc_handler_t *handler)
2003 {
2004     if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
2005         fprintf(stderr, "*** ERROR: unable to join indirect table idx "
2006                 "[%02x-%02x]\n", idx1, idx2);
2007         return -1;
2008     }
2009     if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
2010                               handler) < 0) {
2011         fprintf(stderr, "*** ERROR: unable to insert opcode "
2012                 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
2013         return -1;
2014     }
2015
2016     return 0;
2017 }
2018
2019 static int register_insn (opcode_t *insn)
2020 {
2021     if (insn->opc2 != 0xFF) {
2022         if (insn->opc3 != 0xFF) {
2023             if (register_dblind_insn(insn->opc1, insn->opc2, insn->opc3,
2024                                      &insn->handler) < 0)
2025                 return -1;
2026         } else {
2027             if (register_ind_insn(insn->opc1, insn->opc2, &insn->handler) < 0)
2028                 return -1;
2029         }
2030     } else {
2031         if (register_direct_insn(insn->opc1, &insn->handler) < 0)
2032             return -1;
2033     }
2034
2035     return 0;
2036 }
2037
2038 static int test_opcode_table (opc_handler_t **table, int len)
2039 {
2040     int i, count, tmp;
2041
2042     for (i = 0, count = 0; i < len; i++) {
2043         /* Consistency fixup */
2044         if (table[i] == NULL)
2045             table[i] = &invalid_handler;
2046         if (table[i] != &invalid_handler) {
2047             if (is_indirect_opcode(table[i])) {
2048                 tmp = test_opcode_table(ind_table(table[i]), 0x20);
2049                 if (tmp == 0) {
2050                     free(table[i]);
2051                     table[i] = &invalid_handler;
2052                 } else {
2053                     count++;
2054                 }
2055             } else {
2056                 count++;
2057             }
2058         }
2059     }
2060
2061     return count;
2062 }
2063
2064 static void fix_opcode_tables (void)
2065 {
2066     if (test_opcode_table(ppc_opcodes, 0x40) == 0)
2067         fprintf(stderr, "*** WARNING: no opcode defined !\n");
2068 }
2069
2070 #define SPR_RIGHTS(rw, priv) ((2 * (priv)) + (rw))
2071 #define SPR_UR SPR_RIGHTS(0, 0)
2072 #define SPR_UW SPR_RIGHTS(1, 0)
2073 #define SPR_SR SPR_RIGHTS(0, 1)
2074 #define SPR_SW SPR_RIGHTS(1, 1)
2075
2076 #define spr_set_rights(spr, rights)                            \
2077 do {                                                           \
2078     spr_access[(spr) >> 1] |= ((rights) << (4 * ((spr) & 1))); \
2079 } while (0)
2080
2081 static void init_spr_rights (void)
2082 {
2083     /* XER    (SPR 1) */
2084     spr_set_rights(SPR_ENCODE(1), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2085     /* LR     (SPR 8) */
2086     spr_set_rights(SPR_ENCODE(8), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2087     /* CTR    (SPR 9) */
2088     spr_set_rights(SPR_ENCODE(9), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2089     /* TBL    (SPR 268) */
2090     spr_set_rights(SPR_ENCODE(268), SPR_UR | SPR_SR);
2091     /* TBU    (SPR 269) */
2092     spr_set_rights(SPR_ENCODE(269), SPR_UR | SPR_SR);
2093     /* DSISR  (SPR 18) */
2094     spr_set_rights(SPR_ENCODE(18), SPR_SR | SPR_SW);
2095     /* DAR    (SPR 19) */
2096     spr_set_rights(SPR_ENCODE(19), SPR_SR | SPR_SW);
2097     /* DEC    (SPR 22) */
2098     spr_set_rights(SPR_ENCODE(22), SPR_SR | SPR_SW);
2099     /* SDR1   (SPR 25) */
2100     spr_set_rights(SPR_ENCODE(25), SPR_SR | SPR_SW);
2101     /* SPRG0  (SPR 272) */
2102     spr_set_rights(SPR_ENCODE(272), SPR_SR | SPR_SW);
2103     /* SPRG1  (SPR 273) */
2104     spr_set_rights(SPR_ENCODE(273), SPR_SR | SPR_SW);
2105     /* SPRG2  (SPR 274) */
2106     spr_set_rights(SPR_ENCODE(274), SPR_SR | SPR_SW);
2107     /* SPRG3  (SPR 275) */
2108     spr_set_rights(SPR_ENCODE(275), SPR_SR | SPR_SW);
2109     /* ASR    (SPR 280) */
2110     spr_set_rights(SPR_ENCODE(281), SPR_SR | SPR_SW);
2111     /* EAR    (SPR 282) */
2112     spr_set_rights(SPR_ENCODE(282), SPR_SR | SPR_SW);
2113     /* IBAT0U (SPR 528) */
2114     spr_set_rights(SPR_ENCODE(528), SPR_SR | SPR_SW);
2115     /* IBAT0L (SPR 529) */
2116     spr_set_rights(SPR_ENCODE(529), SPR_SR | SPR_SW);
2117     /* IBAT1U (SPR 530) */
2118     spr_set_rights(SPR_ENCODE(530), SPR_SR | SPR_SW);
2119     /* IBAT1L (SPR 531) */
2120     spr_set_rights(SPR_ENCODE(531), SPR_SR | SPR_SW);
2121     /* IBAT2U (SPR 532) */
2122     spr_set_rights(SPR_ENCODE(532), SPR_SR | SPR_SW);
2123     /* IBAT2L (SPR 533) */
2124     spr_set_rights(SPR_ENCODE(533), SPR_SR | SPR_SW);
2125     /* IBAT3U (SPR 534) */
2126     spr_set_rights(SPR_ENCODE(534), SPR_SR | SPR_SW);
2127     /* IBAT3L (SPR 535) */
2128     spr_set_rights(SPR_ENCODE(535), SPR_SR | SPR_SW);
2129     /* DBAT0U (SPR 536) */
2130     spr_set_rights(SPR_ENCODE(536), SPR_SR | SPR_SW);
2131     /* DBAT0L (SPR 537) */
2132     spr_set_rights(SPR_ENCODE(537), SPR_SR | SPR_SW);
2133     /* DBAT1U (SPR 538) */
2134     spr_set_rights(SPR_ENCODE(538), SPR_SR | SPR_SW);
2135     /* DBAT1L (SPR 539) */
2136     spr_set_rights(SPR_ENCODE(539), SPR_SR | SPR_SW);
2137     /* DBAT2U (SPR 540) */
2138     spr_set_rights(SPR_ENCODE(540), SPR_SR | SPR_SW);
2139     /* DBAT2L (SPR 541) */
2140     spr_set_rights(SPR_ENCODE(541), SPR_SR | SPR_SW);
2141     /* DBAT3U (SPR 542) */
2142     spr_set_rights(SPR_ENCODE(542), SPR_SR | SPR_SW);
2143     /* DBAT3L (SPR 543) */
2144     spr_set_rights(SPR_ENCODE(543), SPR_SR | SPR_SW);
2145     /* DABR   (SPR 1013) */
2146     spr_set_rights(SPR_ENCODE(1013), SPR_SR | SPR_SW);
2147     /* FPECR  (SPR 1022) */
2148     spr_set_rights(SPR_ENCODE(1022), SPR_SR | SPR_SW);
2149     /* PIR    (SPR 1023) */
2150     spr_set_rights(SPR_ENCODE(1023), SPR_SR | SPR_SW);
2151     /* PVR    (SPR 287) */
2152     spr_set_rights(SPR_ENCODE(287), SPR_SR);
2153     /* TBL    (SPR 284) */
2154     spr_set_rights(SPR_ENCODE(284), SPR_SW);
2155     /* TBU    (SPR 285) */
2156     spr_set_rights(SPR_ENCODE(285), SPR_SW);
2157 }
2158
2159 /* PPC "main stream" common instructions */
2160 #define PPC_COMMON  (PPC_INTEGER | PPC_FLOAT | PPC_FLOW | PPC_MEM | \
2161                      PPC_MISC | PPC_EXTERN | PPC_SEGMENT)
2162
2163 typedef struct ppc_proc_t {
2164     int flags;
2165     void *specific;
2166 } ppc_proc_t;
2167
2168 typedef struct ppc_def_t {
2169     unsigned long pvr;
2170     unsigned long pvr_mask;
2171     ppc_proc_t *proc;
2172 } ppc_def_t;
2173
2174 static ppc_proc_t ppc_proc_common = {
2175     .flags    = PPC_COMMON,
2176     .specific = NULL,
2177 };
2178
2179 static ppc_def_t ppc_defs[] =
2180 {
2181     /* Fallback */
2182     {
2183         .pvr      = 0x00000000,
2184         .pvr_mask = 0x00000000,
2185         .proc     = &ppc_proc_common,
2186     },
2187 };
2188
2189 static int create_ppc_proc (unsigned long pvr)
2190 {
2191     opcode_t *opc;
2192     int i, flags;
2193
2194     fill_new_table(ppc_opcodes, 0x40);
2195     for (i = 0; ; i++) {
2196         if ((ppc_defs[i].pvr & ppc_defs[i].pvr_mask) ==
2197             (pvr & ppc_defs[i].pvr_mask)) {
2198             flags = ppc_defs[i].proc->flags;
2199             break;
2200         }
2201     }
2202     
2203     for (opc = &opc_start + 1; opc != &opc_end; opc++) {
2204         if ((opc->type & flags) != 0)
2205             if (register_insn(opc) < 0) {
2206                 fprintf(stderr, "*** ERROR initializing PPC instruction "
2207                         "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
2208                         opc->opc3);
2209                 return -1;
2210             }
2211     }
2212     fix_opcode_tables();
2213
2214     return 0;
2215 }
2216
2217 /*****************************************************************************/
2218 uint32_t do_load_xer (void);
2219
2220 void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
2221 {
2222     int i;
2223
2224     if (loglevel > 0) {
2225         fprintf(logfile, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x\n",
2226                 env->nip, env->LR, env->CTR, do_load_xer());
2227         for (i = 0; i < 32; i++) {
2228             if ((i & 7) == 0)
2229                 fprintf(logfile, "GPR%02d:", i);
2230             fprintf(logfile, " %08x", env->gpr[i]);
2231             if ((i & 7) == 7)
2232                 fprintf(logfile, "\n");
2233         }
2234         fprintf(logfile, "CR: 0x");
2235         for (i = 0; i < 8; i++)
2236             fprintf(logfile, "%01x", env->crf[i]);
2237         fprintf(logfile, "  [");
2238         for (i = 0; i < 8; i++) {
2239             char a = '-';
2240             
2241             if (env->crf[i] & 0x08)
2242                 a = 'L';
2243             else if (env->crf[i] & 0x04)
2244                 a = 'G';
2245             else if (env->crf[i] & 0x02)
2246                 a = 'E';
2247             fprintf(logfile, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
2248         }
2249         fprintf(logfile, " ] ");
2250         fprintf(logfile, "TB: 0x%08x %08x\n", env->spr[SPR_ENCODE(269)],
2251                 env->spr[SPR_ENCODE(268)]);
2252         for (i = 0; i < 16; i++) {
2253             if ((i & 3) == 0)
2254                 fprintf(logfile, "FPR%02d:", i);
2255             fprintf(logfile, " %016llx", env->fpr[i]);
2256             if ((i & 3) == 3)
2257                 fprintf(logfile, "\n");
2258         }
2259         fflush(logfile);
2260     }
2261 }
2262
2263 CPUPPCState *cpu_ppc_init(void)
2264 {
2265     CPUPPCState *env;
2266
2267     cpu_exec_init();
2268
2269     env = malloc(sizeof(CPUPPCState));
2270     if (!env)
2271         return NULL;
2272     memset(env, 0, sizeof(CPUPPCState));
2273     env->PVR = 0;
2274     if (create_ppc_proc(0) < 0)
2275         return NULL;
2276     init_spr_rights();
2277
2278     return env;
2279 }
2280
2281 void cpu_ppc_close(CPUPPCState *env)
2282 {
2283     /* Should also remove all opcode tables... */
2284     free(env);
2285 }
2286
2287 int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2288                                     int search_pc)
2289 {
2290     DisasContext ctx;
2291     opc_handler_t **table, *handler;
2292     uint32_t pc_start;
2293     uint16_t *gen_opc_end;
2294     int j, lj = -1;
2295     int ret = 0;
2296
2297     pc_start = tb->pc;
2298     gen_opc_ptr = gen_opc_buf;
2299     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2300     gen_opparam_ptr = gen_opparam_buf;
2301     ctx.nip = (uint32_t *)pc_start;
2302     ctx.tb_offset = 0;
2303     ctx.supervisor = msr_ip;
2304     ctx.tb = tb;
2305     ctx.exception = 0;
2306
2307     while (ret == 0 && gen_opc_ptr < gen_opc_end) {
2308         if (search_pc) {
2309             if (loglevel > 0)
2310                 fprintf(logfile, "Search PC...\n");
2311             j = gen_opc_ptr - gen_opc_buf;
2312             if (lj < j) {
2313                 lj++;
2314                 while (lj < j)
2315                     gen_opc_instr_start[lj++] = 0;
2316                 gen_opc_pc[lj] = (uint32_t)ctx.nip;
2317                 gen_opc_instr_start[lj] = 1;
2318             }
2319         }
2320         ctx.opcode = __be32_to_cpu(*ctx.nip);
2321 #ifdef DEBUG_DISAS
2322         if (loglevel > 0) {
2323             fprintf(logfile, "----------------\n");
2324             fprintf(logfile, "%p: translate opcode %08x\n",
2325                     ctx.nip, ctx.opcode);
2326         }
2327 #endif
2328         ctx.nip++;
2329         table = ppc_opcodes;
2330         handler = table[opc1(ctx.opcode)];
2331         if (is_indirect_opcode(handler)) {
2332             table = ind_table(handler);
2333             handler = table[opc2(ctx.opcode)];
2334             if (is_indirect_opcode(handler)) {
2335                 table = ind_table(handler);
2336                 handler = table[opc3(ctx.opcode)];
2337             }
2338         }
2339         /* Is opcode *REALLY* valid ? */
2340         if ((ctx.opcode & handler->inval) != 0) {
2341             if (loglevel > 0) {
2342                 if (handler->handler == &gen_invalid) {
2343                     fprintf(logfile, "invalid/unsupported opcode: "
2344                             "%02x -%02x - %02x (%08x)\n", opc1(ctx.opcode),
2345                             opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode);
2346                 } else {
2347                     fprintf(logfile, "invalid bits: %08x for opcode: "
2348                             "%02x -%02x - %02x (%p)\n",
2349                             ctx.opcode & handler->inval, opc1(ctx.opcode),
2350                             opc2(ctx.opcode), opc3(ctx.opcode),
2351                             handler->handler);
2352                 }
2353             }
2354             ret = GET_RETVAL(gen_invalid, ctx.opcode);
2355         } else {
2356             ret = GET_RETVAL(*(handler->handler), ctx.opcode);
2357         }
2358         ctx.tb_offset++;
2359 #if defined (DO_SINGLE_STEP)
2360         break;
2361 #endif
2362     }
2363 #if defined (DO_STEP_FLUSH)
2364         tb_flush();
2365 #endif
2366     /* We need to update the time base */
2367     if (!search_pc)
2368         gen_op_update_tb(ctx.tb_offset);
2369     /* If we are in step-by-step mode, do a branch to the next instruction
2370      * so the nip will be up-to-date
2371      */
2372 #if defined (DO_SINGLE_STEP)
2373     if (ret == 0) {
2374         gen_op_b((uint32_t)ctx.nip);
2375         ret = EXCP_BRANCH;
2376     }
2377 #endif
2378     /* If the exeption isn't a PPC one,
2379      * generate it now.
2380      */
2381     if (ret != EXCP_BRANCH) {
2382         gen_op_set_T0(0);
2383         if ((ret & 0x2000) == 0)
2384             gen_op_raise_exception(ret);
2385     }
2386     /* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
2387      *              do bad business and then qemu crashes !
2388      */
2389     gen_op_set_T0(0);
2390     /* Generate the return instruction */
2391     gen_op_exit_tb();
2392     *gen_opc_ptr = INDEX_op_end;
2393     if (!search_pc)
2394         tb->size = (uint32_t)ctx.nip - pc_start;
2395     else
2396         tb->size = 0;
2397 //    *gen_opc_ptr = INDEX_op_end;
2398 #ifdef DEBUG_DISAS
2399     if (loglevel > 0) {
2400         fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start));
2401         disas(logfile, (void *)pc_start, (uint32_t)ctx.nip - pc_start, 0, 0);
2402         fprintf(logfile, "\n");
2403
2404         fprintf(logfile, "OP:\n");
2405         dump_ops(gen_opc_buf, gen_opparam_buf);
2406         fprintf(logfile, "\n");
2407     }
2408 #endif
2409
2410     return 0;
2411 }
2412
2413 int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb)
2414 {
2415     return gen_intermediate_code_internal(env, tb, 0);
2416 }
2417
2418 int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb)
2419 {
2420     return gen_intermediate_code_internal(env, tb, 1);
2421 }