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