fixed invalid includes
[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 <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <inttypes.h>
25
26 #include "cpu.h"
27 #include "exec-all.h"
28 #include "disas.h"
29
30 //#define DO_SINGLE_STEP
31 //#define DO_STEP_FLUSH
32 //#define DEBUG_DISAS
33
34 enum {
35 #define DEF(s, n, copy_size) INDEX_op_ ## s,
36 #include "opc.h"
37 #undef DEF
38     NB_OPS,
39 };
40
41 static uint16_t *gen_opc_ptr;
42 static uint32_t *gen_opparam_ptr;
43
44 #include "gen-op.h"
45
46 #define GEN8(func, NAME) \
47 static GenOpFunc *NAME ## _table [8] = {                                      \
48 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
49 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
50 };                                                                            \
51 static inline void func(int n)                                                \
52 {                                                                             \
53     NAME ## _table[n]();                                                      \
54 }
55
56 #define GEN16(func, NAME)                                                     \
57 static GenOpFunc *NAME ## _table [16] = {                                     \
58 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
59 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
60 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
61 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
62 };                                                                            \
63 static inline void func(int n)                                                \
64 {                                                                             \
65     NAME ## _table[n]();                                                      \
66 }
67
68 #define GEN32(func, NAME) \
69 static GenOpFunc *NAME ## _table [32] = {                                     \
70 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
71 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
72 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
73 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
74 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
75 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
76 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
77 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
78 };                                                                            \
79 static inline void func(int n)                                                \
80 {                                                                             \
81     NAME ## _table[n]();                                                      \
82 }
83
84 /* Condition register moves */
85 GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
86 GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
87 GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
88 GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
89
90 /* Floating point condition and status register moves */
91 GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
92 GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
93 GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
94 static GenOpFunc1 *gen_op_store_T0_fpscri_fpscr_table[8] = {
95     &gen_op_store_T0_fpscri_fpscr0,
96     &gen_op_store_T0_fpscri_fpscr1,
97     &gen_op_store_T0_fpscri_fpscr2,
98     &gen_op_store_T0_fpscri_fpscr3,
99     &gen_op_store_T0_fpscri_fpscr4,
100     &gen_op_store_T0_fpscri_fpscr5,
101     &gen_op_store_T0_fpscri_fpscr6,
102     &gen_op_store_T0_fpscri_fpscr7,
103 };
104 static inline void gen_op_store_T0_fpscri(int n, uint8_t param)
105 {
106     (*gen_op_store_T0_fpscri_fpscr_table[n])(param);
107 }
108
109 /* Segment register moves */
110 GEN16(gen_op_load_sr, gen_op_load_sr);
111 GEN16(gen_op_store_sr, gen_op_store_sr);
112
113 /* General purpose registers moves */
114 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
115 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
116 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
117
118 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
119 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
120 GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
121
122 /* floating point registers moves */
123 GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
124 GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
125 GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
126 GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
127 GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
128 GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
129
130 static uint8_t  spr_access[1024 / 2];
131
132 /* internal defines */
133 typedef struct DisasContext {
134     struct TranslationBlock *tb;
135     uint32_t nip;
136     uint32_t opcode;
137     uint32_t exception;
138     /* Time base offset */
139     uint32_t tb_offset;
140     /* Decrementer offset */
141     uint32_t decr_offset;
142     /* Execution mode */
143 #if !defined(CONFIG_USER_ONLY)
144     int supervisor;
145 #endif
146     /* Routine used to access memory */
147     int mem_idx;
148 } DisasContext;
149
150 typedef struct opc_handler_t {
151     /* invalid bits */
152     uint32_t inval;
153     /* instruction type */
154     uint32_t type;
155     /* handler */
156     void (*handler)(DisasContext *ctx);
157 } opc_handler_t;
158
159 #define RET_EXCP(excp, error)                                                 \
160 do {                                                                          \
161     gen_op_queue_exception_err(excp, error);                                  \
162     ctx->exception = excp;                                                    \
163     return;                                                                   \
164 } while (0)
165
166 #define RET_INVAL()                                                           \
167 RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
168
169 #define RET_PRIVOPC()                                                         \
170 RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
171
172 #define RET_PRIVREG()                                                         \
173 RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
174
175 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
176 static void gen_##name (DisasContext *ctx);                                   \
177 GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
178 static void gen_##name (DisasContext *ctx)
179
180 typedef struct opcode_t {
181     unsigned char opc1, opc2, opc3;
182     opc_handler_t handler;
183 } opcode_t;
184
185 /* XXX: move that elsewhere */
186 extern FILE *logfile;
187 extern int loglevel;
188
189 /***                           Instruction decoding                        ***/
190 #define EXTRACT_HELPER(name, shift, nb)                                       \
191 static inline uint32_t name (uint32_t opcode)                                 \
192 {                                                                             \
193     return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
194 }
195
196 #define EXTRACT_SHELPER(name, shift, nb)                                      \
197 static inline int32_t name (uint32_t opcode)                                  \
198 {                                                                             \
199     return s_ext16((opcode >> (shift)) & ((1 << (nb)) - 1));                  \
200 }
201
202 /* Opcode part 1 */
203 EXTRACT_HELPER(opc1, 26, 6);
204 /* Opcode part 2 */
205 EXTRACT_HELPER(opc2, 1, 5);
206 /* Opcode part 3 */
207 EXTRACT_HELPER(opc3, 6, 5);
208 /* Update Cr0 flags */
209 EXTRACT_HELPER(Rc, 0, 1);
210 /* Destination */
211 EXTRACT_HELPER(rD, 21, 5);
212 /* Source */
213 EXTRACT_HELPER(rS, 21, 5);
214 /* First operand */
215 EXTRACT_HELPER(rA, 16, 5);
216 /* Second operand */
217 EXTRACT_HELPER(rB, 11, 5);
218 /* Third operand */
219 EXTRACT_HELPER(rC, 6, 5);
220 /***                               Get CRn                                 ***/
221 EXTRACT_HELPER(crfD, 23, 3);
222 EXTRACT_HELPER(crfS, 18, 3);
223 EXTRACT_HELPER(crbD, 21, 5);
224 EXTRACT_HELPER(crbA, 16, 5);
225 EXTRACT_HELPER(crbB, 11, 5);
226 /* SPR / TBL */
227 EXTRACT_HELPER(SPR, 11, 10);
228 /***                              Get constants                            ***/
229 EXTRACT_HELPER(IMM, 12, 8);
230 /* 16 bits signed immediate value */
231 EXTRACT_SHELPER(SIMM, 0, 16);
232 /* 16 bits unsigned immediate value */
233 EXTRACT_HELPER(UIMM, 0, 16);
234 /* Bit count */
235 EXTRACT_HELPER(NB, 11, 5);
236 /* Shift count */
237 EXTRACT_HELPER(SH, 11, 5);
238 /* Mask start */
239 EXTRACT_HELPER(MB, 6, 5);
240 /* Mask end */
241 EXTRACT_HELPER(ME, 1, 5);
242 /* Trap operand */
243 EXTRACT_HELPER(TO, 21, 5);
244
245 EXTRACT_HELPER(CRM, 12, 8);
246 EXTRACT_HELPER(FM, 17, 8);
247 EXTRACT_HELPER(SR, 16, 4);
248 EXTRACT_HELPER(FPIMM, 20, 4);
249
250 /***                            Jump target decoding                       ***/
251 /* Displacement */
252 EXTRACT_SHELPER(d, 0, 16);
253 /* Immediate address */
254 static inline uint32_t LI (uint32_t opcode)
255 {
256     return (opcode >> 0) & 0x03FFFFFC;
257 }
258
259 static inline uint32_t BD (uint32_t opcode)
260 {
261     return (opcode >> 0) & 0xFFFC;
262 }
263
264 EXTRACT_HELPER(BO, 21, 5);
265 EXTRACT_HELPER(BI, 16, 5);
266 /* Absolute/relative address */
267 EXTRACT_HELPER(AA, 1, 1);
268 /* Link */
269 EXTRACT_HELPER(LK, 0, 1);
270
271 /* Create a mask between <start> and <end> bits */
272 static inline uint32_t MASK (uint32_t start, uint32_t end)
273 {
274     uint32_t ret;
275
276     ret = (((uint32_t)(-1)) >> (start)) ^ (((uint32_t)(-1) >> (end)) >> 1);
277     if (start > end)
278         return ~ret;
279
280     return ret;
281 }
282
283 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
284 __attribute__ ((section(".opcodes"), unused, aligned (8) ))                   \
285 static opcode_t opc_##name = {                                                \
286     .opc1 = op1,                                                              \
287     .opc2 = op2,                                                              \
288     .opc3 = op3,                                                              \
289     .handler = {                                                              \
290         .inval   = invl,                                                      \
291         .type = _typ,                                                         \
292         .handler = &gen_##name,                                               \
293     },                                                                        \
294 }
295
296 #define GEN_OPCODE_MARK(name)                                                 \
297 __attribute__ ((section(".opcodes"), unused, aligned (8) ))                   \
298 static opcode_t opc_##name = {                                                \
299     .opc1 = 0xFF,                                                             \
300     .opc2 = 0xFF,                                                             \
301     .opc3 = 0xFF,                                                             \
302     .handler = {                                                              \
303         .inval   = 0x00000000,                                                \
304         .type = 0x00,                                                         \
305         .handler = NULL,                                                      \
306     },                                                                        \
307 }
308
309 /* Start opcode list */
310 GEN_OPCODE_MARK(start);
311
312 /* Invalid instruction */
313 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
314 {
315     RET_INVAL();
316 }
317
318 /* Special opcode to stop emulation */
319 GEN_HANDLER(stop, 0x06, 0x00, 0xFF, 0x03FFFFC1, PPC_COMMON)
320 {
321     gen_op_queue_exception(EXCP_HLT);
322     ctx->exception = EXCP_HLT;
323 }
324
325 /* Special opcode to call open-firmware */
326 GEN_HANDLER(of_enter, 0x06, 0x01, 0xFF, 0x03FFFFC1, PPC_COMMON)
327 {
328     gen_op_queue_exception(EXCP_OFCALL);
329     ctx->exception = EXCP_OFCALL;
330 }
331
332 /* Special opcode to call RTAS */
333 GEN_HANDLER(rtas_enter, 0x06, 0x02, 0xFF, 0x03FFFFC1, PPC_COMMON)
334 {
335     printf("RTAS entry point !\n");
336     gen_op_queue_exception(EXCP_RTASCALL);
337     ctx->exception = EXCP_RTASCALL;
338 }
339
340 static opc_handler_t invalid_handler = {
341     .inval   = 0xFFFFFFFF,
342     .type    = PPC_NONE,
343     .handler = gen_invalid,
344 };
345
346 /***                           Integer arithmetic                          ***/
347 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval)                       \
348 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER)                       \
349 {                                                                             \
350     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
351     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
352     gen_op_##name();                                                          \
353     if (Rc(ctx->opcode) != 0)                                                 \
354         gen_op_set_Rc0();                                                     \
355     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
356 }
357
358 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval)                     \
359 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER)                       \
360 {                                                                             \
361     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
362     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
363     gen_op_##name();                                                          \
364     if (Rc(ctx->opcode) != 0)                                                 \
365         gen_op_set_Rc0_ov();                                                  \
366     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
367 }
368
369 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3)                              \
370 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER)                  \
371 {                                                                             \
372     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
373     gen_op_##name();                                                          \
374     if (Rc(ctx->opcode) != 0)                                                 \
375         gen_op_set_Rc0();                                                     \
376     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
377 }
378 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3)                            \
379 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER)                  \
380 {                                                                             \
381     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
382     gen_op_##name();                                                          \
383     if (Rc(ctx->opcode) != 0)                                                 \
384         gen_op_set_Rc0_ov();                                                  \
385     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
386 }
387
388 /* Two operands arithmetic functions */
389 #define GEN_INT_ARITH2(name, opc1, opc2, opc3)                                \
390 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000)                          \
391 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000)
392
393 /* Two operands arithmetic functions with no overflow allowed */
394 #define GEN_INT_ARITHN(name, opc1, opc2, opc3)                                \
395 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400)
396
397 /* One operand arithmetic functions */
398 #define GEN_INT_ARITH1(name, opc1, opc2, opc3)                                \
399 __GEN_INT_ARITH1(name, opc1, opc2, opc3)                                      \
400 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10)
401
402 /* add    add.    addo    addo.    */
403 GEN_INT_ARITH2 (add,    0x1F, 0x0A, 0x08);
404 /* addc   addc.   addco   addco.   */
405 GEN_INT_ARITH2 (addc,   0x1F, 0x0A, 0x00);
406 /* adde   adde.   addeo   addeo.   */
407 GEN_INT_ARITH2 (adde,   0x1F, 0x0A, 0x04);
408 /* addme  addme.  addmeo  addmeo.  */
409 GEN_INT_ARITH1 (addme,  0x1F, 0x0A, 0x07);
410 /* addze  addze.  addzeo  addzeo.  */
411 GEN_INT_ARITH1 (addze,  0x1F, 0x0A, 0x06);
412 /* divw   divw.   divwo   divwo.   */
413 GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F);
414 /* divwu  divwu.  divwuo  divwuo.  */
415 GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E);
416 /* mulhw  mulhw.                   */
417 GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02);
418 /* mulhwu mulhwu.                  */
419 GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00);
420 /* mullw  mullw.  mullwo  mullwo.  */
421 GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07);
422 /* neg    neg.    nego    nego.    */
423 GEN_INT_ARITH1 (neg,    0x1F, 0x08, 0x03);
424 /* subf   subf.   subfo   subfo.   */
425 GEN_INT_ARITH2 (subf,   0x1F, 0x08, 0x01);
426 /* subfc  subfc.  subfco  subfco.  */
427 GEN_INT_ARITH2 (subfc,  0x1F, 0x08, 0x00);
428 /* subfe  subfe.  subfeo  subfeo.  */
429 GEN_INT_ARITH2 (subfe,  0x1F, 0x08, 0x04);
430 /* subfme subfme. subfmeo subfmeo. */
431 GEN_INT_ARITH1 (subfme, 0x1F, 0x08, 0x07);
432 /* subfze subfze. subfzeo subfzeo. */
433 GEN_INT_ARITH1 (subfze, 0x1F, 0x08, 0x06);
434 /* addi */
435 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
436 {
437     int32_t simm = SIMM(ctx->opcode);
438
439     if (rA(ctx->opcode) == 0) {
440         gen_op_set_T0(simm);
441     } else {
442         gen_op_load_gpr_T0(rA(ctx->opcode));
443         gen_op_addi(simm);
444     }
445     gen_op_store_T0_gpr(rD(ctx->opcode));
446 }
447 /* addic */
448 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
449 {
450     gen_op_load_gpr_T0(rA(ctx->opcode));
451     gen_op_addic(SIMM(ctx->opcode));
452     gen_op_store_T0_gpr(rD(ctx->opcode));
453 }
454 /* addic. */
455 GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
456 {
457     gen_op_load_gpr_T0(rA(ctx->opcode));
458     gen_op_addic(SIMM(ctx->opcode));
459     gen_op_set_Rc0();
460     gen_op_store_T0_gpr(rD(ctx->opcode));
461 }
462 /* addis */
463 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
464 {
465     int32_t simm = SIMM(ctx->opcode);
466
467     if (rA(ctx->opcode) == 0) {
468         gen_op_set_T0(simm << 16);
469     } else {
470         gen_op_load_gpr_T0(rA(ctx->opcode));
471         gen_op_addi(simm << 16);
472     }
473     gen_op_store_T0_gpr(rD(ctx->opcode));
474 }
475 /* mulli */
476 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
477 {
478     gen_op_load_gpr_T0(rA(ctx->opcode));
479     gen_op_mulli(SIMM(ctx->opcode));
480     gen_op_store_T0_gpr(rD(ctx->opcode));
481 }
482 /* subfic */
483 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
484 {
485     gen_op_load_gpr_T0(rA(ctx->opcode));
486     gen_op_subfic(SIMM(ctx->opcode));
487     gen_op_store_T0_gpr(rD(ctx->opcode));
488 }
489
490 /***                           Integer comparison                          ***/
491 #define GEN_CMP(name, opc)                                                    \
492 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, PPC_INTEGER)                   \
493 {                                                                             \
494     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
495     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
496     gen_op_##name();                                                          \
497     gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
498 }
499
500 /* cmp */
501 GEN_CMP(cmp, 0x00);
502 /* cmpi */
503 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
504 {
505     gen_op_load_gpr_T0(rA(ctx->opcode));
506     gen_op_cmpi(SIMM(ctx->opcode));
507     gen_op_store_T0_crf(crfD(ctx->opcode));
508 }
509 /* cmpl */
510 GEN_CMP(cmpl, 0x01);
511 /* cmpli */
512 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
513 {
514     gen_op_load_gpr_T0(rA(ctx->opcode));
515     gen_op_cmpli(UIMM(ctx->opcode));
516     gen_op_store_T0_crf(crfD(ctx->opcode));
517 }
518
519 /***                            Integer logical                            ***/
520 #define __GEN_LOGICAL2(name, opc2, opc3)                                      \
521 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, PPC_INTEGER)                  \
522 {                                                                             \
523     gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
524     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
525     gen_op_##name();                                                          \
526     if (Rc(ctx->opcode) != 0)                                                 \
527         gen_op_set_Rc0();                                                     \
528     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
529 }
530 #define GEN_LOGICAL2(name, opc)                                               \
531 __GEN_LOGICAL2(name, 0x1C, opc)
532
533 #define GEN_LOGICAL1(name, opc)                                               \
534 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, PPC_INTEGER)                   \
535 {                                                                             \
536     gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
537     gen_op_##name();                                                          \
538     if (Rc(ctx->opcode) != 0)                                                 \
539         gen_op_set_Rc0();                                                     \
540     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
541 }
542
543 /* and & and. */
544 GEN_LOGICAL2(and, 0x00);
545 /* andc & andc. */
546 GEN_LOGICAL2(andc, 0x01);
547 /* andi. */
548 GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
549 {
550     gen_op_load_gpr_T0(rS(ctx->opcode));
551     gen_op_andi_(UIMM(ctx->opcode));
552     gen_op_set_Rc0();
553     gen_op_store_T0_gpr(rA(ctx->opcode));
554 }
555 /* andis. */
556 GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
557 {
558     gen_op_load_gpr_T0(rS(ctx->opcode));
559     gen_op_andi_(UIMM(ctx->opcode) << 16);
560     gen_op_set_Rc0();
561     gen_op_store_T0_gpr(rA(ctx->opcode));
562 }
563
564 /* cntlzw */
565 GEN_LOGICAL1(cntlzw, 0x00);
566 /* eqv & eqv. */
567 GEN_LOGICAL2(eqv, 0x08);
568 /* extsb & extsb. */
569 GEN_LOGICAL1(extsb, 0x1D);
570 /* extsh & extsh. */
571 GEN_LOGICAL1(extsh, 0x1C);
572 /* nand & nand. */
573 GEN_LOGICAL2(nand, 0x0E);
574 /* nor & nor. */
575 GEN_LOGICAL2(nor, 0x03);
576
577 /* or & or. */
578 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
579 {
580     gen_op_load_gpr_T0(rS(ctx->opcode));
581     /* Optimisation for mr case */
582     if (rS(ctx->opcode) != rB(ctx->opcode)) {
583         gen_op_load_gpr_T1(rB(ctx->opcode));
584         gen_op_or();
585     }
586     if (Rc(ctx->opcode) != 0)
587         gen_op_set_Rc0();
588     gen_op_store_T0_gpr(rA(ctx->opcode));
589 }
590
591 /* orc & orc. */
592 GEN_LOGICAL2(orc, 0x0C);
593 /* xor & xor. */
594 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
595 {
596     gen_op_load_gpr_T0(rS(ctx->opcode));
597     /* Optimisation for "set to zero" case */
598     if (rS(ctx->opcode) != rB(ctx->opcode)) {
599         gen_op_load_gpr_T1(rB(ctx->opcode));
600         gen_op_xor();
601     } else {
602         gen_op_set_T0(0);
603     }
604     if (Rc(ctx->opcode) != 0)
605         gen_op_set_Rc0();
606     gen_op_store_T0_gpr(rA(ctx->opcode));
607 }
608 /* ori */
609 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
610 {
611     uint32_t uimm = UIMM(ctx->opcode);
612
613     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
614         /* NOP */
615         return;
616         }
617         gen_op_load_gpr_T0(rS(ctx->opcode));
618     if (uimm != 0)
619         gen_op_ori(uimm);
620         gen_op_store_T0_gpr(rA(ctx->opcode));
621 }
622 /* oris */
623 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
624 {
625     uint32_t uimm = UIMM(ctx->opcode);
626
627     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
628         /* NOP */
629         return;
630         }
631         gen_op_load_gpr_T0(rS(ctx->opcode));
632     if (uimm != 0)
633         gen_op_ori(uimm << 16);
634         gen_op_store_T0_gpr(rA(ctx->opcode));
635 }
636 /* xori */
637 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
638 {
639     uint32_t uimm = UIMM(ctx->opcode);
640
641     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
642         /* NOP */
643         return;
644     }
645     gen_op_load_gpr_T0(rS(ctx->opcode));
646     if (uimm != 0)
647     gen_op_xori(UIMM(ctx->opcode));
648     gen_op_store_T0_gpr(rA(ctx->opcode));
649 }
650
651 /* xoris */
652 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
653 {
654     uint32_t uimm = UIMM(ctx->opcode);
655
656     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
657         /* NOP */
658         return;
659     }
660     gen_op_load_gpr_T0(rS(ctx->opcode));
661     if (uimm != 0)
662     gen_op_xori(UIMM(ctx->opcode) << 16);
663     gen_op_store_T0_gpr(rA(ctx->opcode));
664 }
665
666 /***                             Integer rotate                            ***/
667 /* rlwimi & rlwimi. */
668 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
669 {
670     uint32_t mb, me;
671
672     mb = MB(ctx->opcode);
673     me = ME(ctx->opcode);
674     gen_op_load_gpr_T0(rS(ctx->opcode));
675     gen_op_load_gpr_T1(rA(ctx->opcode));
676     gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me));
677     if (Rc(ctx->opcode) != 0)
678         gen_op_set_Rc0();
679     gen_op_store_T0_gpr(rA(ctx->opcode));
680 }
681 /* rlwinm & rlwinm. */
682 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
683 {
684     uint32_t mb, me, sh;
685     
686     sh = SH(ctx->opcode);
687     mb = MB(ctx->opcode);
688     me = ME(ctx->opcode);
689     gen_op_load_gpr_T0(rS(ctx->opcode));
690     if (mb == 0) {
691         if (me == 31) {
692             gen_op_rotlwi(sh);
693             goto store;
694         } else if (me == (31 - sh)) {
695             gen_op_slwi(sh);
696             goto store;
697         } else if (sh == 0) {
698             gen_op_andi_(MASK(0, me));
699             goto store;
700         }
701     } else if (me == 31) {
702         if (sh == (32 - mb)) {
703             gen_op_srwi(mb);
704             goto store;
705         } else if (sh == 0) {
706             gen_op_andi_(MASK(mb, 31));
707             goto store;
708         }
709     }
710     gen_op_rlwinm(sh, MASK(mb, me));
711 store:
712     if (Rc(ctx->opcode) != 0)
713         gen_op_set_Rc0();
714     gen_op_store_T0_gpr(rA(ctx->opcode));
715 }
716 /* rlwnm & rlwnm. */
717 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
718 {
719     uint32_t mb, me;
720
721     mb = MB(ctx->opcode);
722     me = ME(ctx->opcode);
723     gen_op_load_gpr_T0(rS(ctx->opcode));
724     gen_op_load_gpr_T1(rB(ctx->opcode));
725     if (mb == 0 && me == 31) {
726         gen_op_rotl();
727     } else
728     {
729         gen_op_rlwnm(MASK(mb, me));
730     }
731     if (Rc(ctx->opcode) != 0)
732         gen_op_set_Rc0();
733     gen_op_store_T0_gpr(rA(ctx->opcode));
734 }
735
736 /***                             Integer shift                             ***/
737 /* slw & slw. */
738 __GEN_LOGICAL2(slw, 0x18, 0x00);
739 /* sraw & sraw. */
740 __GEN_LOGICAL2(sraw, 0x18, 0x18);
741 /* srawi & srawi. */
742 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
743 {
744     gen_op_load_gpr_T0(rS(ctx->opcode));
745     gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
746     if (Rc(ctx->opcode) != 0)
747         gen_op_set_Rc0();
748     gen_op_store_T0_gpr(rA(ctx->opcode));
749 }
750 /* srw & srw. */
751 __GEN_LOGICAL2(srw, 0x18, 0x10);
752
753 /***                       Floating-Point arithmetic                       ***/
754 #define _GEN_FLOAT_ACB(name, op1, op2)                                        \
755 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT)                   \
756 {                                                                             \
757     gen_op_reset_scrfx();                                                     \
758     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
759     gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
760     gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
761     gen_op_f##name();                                                         \
762     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
763     if (Rc(ctx->opcode))                                                      \
764         gen_op_set_Rc1();                                                     \
765 }
766
767 #define GEN_FLOAT_ACB(name, op2)                                              \
768 _GEN_FLOAT_ACB(name, 0x3F, op2);                                              \
769 _GEN_FLOAT_ACB(name##s, 0x3B, op2);
770
771 #define _GEN_FLOAT_AB(name, op1, op2, inval)                                  \
772 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
773 {                                                                             \
774     gen_op_reset_scrfx();                                                     \
775     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
776     gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
777     gen_op_f##name();                                                         \
778     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
779     if (Rc(ctx->opcode))                                                      \
780         gen_op_set_Rc1();                                                     \
781 }
782 #define GEN_FLOAT_AB(name, op2, inval)                                        \
783 _GEN_FLOAT_AB(name, 0x3F, op2, inval);                                        \
784 _GEN_FLOAT_AB(name##s, 0x3B, op2, inval);
785
786 #define _GEN_FLOAT_AC(name, op1, op2, inval)                                  \
787 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
788 {                                                                             \
789     gen_op_reset_scrfx();                                                     \
790     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
791     gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
792     gen_op_f##name();                                                         \
793     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
794     if (Rc(ctx->opcode))                                                      \
795         gen_op_set_Rc1();                                                     \
796 }
797 #define GEN_FLOAT_AC(name, op2, inval)                                        \
798 _GEN_FLOAT_AC(name, 0x3F, op2, inval);                                        \
799 _GEN_FLOAT_AC(name##s, 0x3B, op2, inval);
800
801 #define GEN_FLOAT_B(name, op2, op3)                                           \
802 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT)                   \
803 {                                                                             \
804     gen_op_reset_scrfx();                                                     \
805     gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
806     gen_op_f##name();                                                         \
807     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
808     if (Rc(ctx->opcode))                                                      \
809         gen_op_set_Rc1();                                                     \
810 }
811
812 #define GEN_FLOAT_BS(name, op2)                                               \
813 GEN_HANDLER(f##name, 0x3F, op2, 0xFF, 0x001F07C0, PPC_FLOAT)                  \
814 {                                                                             \
815     gen_op_reset_scrfx();                                                     \
816     gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
817     gen_op_f##name();                                                         \
818     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
819     if (Rc(ctx->opcode))                                                      \
820         gen_op_set_Rc1();                                                     \
821 }
822
823 /* fadd - fadds */
824 GEN_FLOAT_AB(add, 0x15, 0x000007C0);
825 /* fdiv */
826 GEN_FLOAT_AB(div, 0x12, 0x000007C0);
827 /* fmul */
828 GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
829
830 /* fres */
831 GEN_FLOAT_BS(res, 0x18);
832
833 /* frsqrte */
834 GEN_FLOAT_BS(rsqrte, 0x1A);
835
836 /* fsel */
837 _GEN_FLOAT_ACB(sel, 0x3F, 0x17);
838 /* fsub */
839 GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
840 /* Optional: */
841 /* fsqrt */
842 GEN_FLOAT_BS(sqrt, 0x16);
843
844 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
845 {
846     gen_op_reset_scrfx();
847     gen_op_load_fpr_FT0(rB(ctx->opcode));
848     gen_op_fsqrts();
849     gen_op_store_FT0_fpr(rD(ctx->opcode));
850     if (Rc(ctx->opcode))
851         gen_op_set_Rc1();
852 }
853
854 /***                     Floating-Point multiply-and-add                   ***/
855 /* fmadd */
856 GEN_FLOAT_ACB(madd, 0x1D);
857 /* fmsub */
858 GEN_FLOAT_ACB(msub, 0x1C);
859 /* fnmadd */
860 GEN_FLOAT_ACB(nmadd, 0x1F);
861 /* fnmsub */
862 GEN_FLOAT_ACB(nmsub, 0x1E);
863
864 /***                     Floating-Point round & convert                    ***/
865 /* fctiw */
866 GEN_FLOAT_B(ctiw, 0x0E, 0x00);
867 /* fctiwz */
868 GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
869 /* frsp */
870 GEN_FLOAT_B(rsp, 0x0C, 0x00);
871
872 /***                         Floating-Point compare                        ***/
873 /* fcmpo */
874 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
875 {
876     gen_op_reset_scrfx();
877     gen_op_load_fpr_FT0(rA(ctx->opcode));
878     gen_op_load_fpr_FT1(rB(ctx->opcode));
879     gen_op_fcmpo();
880     gen_op_store_T0_crf(crfD(ctx->opcode));
881 }
882
883 /* fcmpu */
884 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
885 {
886     gen_op_reset_scrfx();
887     gen_op_load_fpr_FT0(rA(ctx->opcode));
888     gen_op_load_fpr_FT1(rB(ctx->opcode));
889     gen_op_fcmpu();
890     gen_op_store_T0_crf(crfD(ctx->opcode));
891 }
892
893 /***                         Floating-point move                           ***/
894 /* fabs */
895 GEN_FLOAT_B(abs, 0x08, 0x08);
896
897 /* fmr  - fmr. */
898 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
899 {
900     gen_op_reset_scrfx();
901     gen_op_load_fpr_FT0(rB(ctx->opcode));
902     gen_op_store_FT0_fpr(rD(ctx->opcode));
903     if (Rc(ctx->opcode))
904         gen_op_set_Rc1();
905 }
906
907 /* fnabs */
908 GEN_FLOAT_B(nabs, 0x08, 0x04);
909 /* fneg */
910 GEN_FLOAT_B(neg, 0x08, 0x01);
911
912 /***                  Floating-Point status & ctrl register                ***/
913 /* mcrfs */
914 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
915 {
916     gen_op_load_fpscr_T0(crfS(ctx->opcode));
917     gen_op_store_T0_crf(crfD(ctx->opcode));
918     gen_op_clear_fpscr(crfS(ctx->opcode));
919 }
920
921 /* mffs */
922 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
923 {
924     gen_op_load_fpscr();
925     gen_op_store_FT0_fpr(rD(ctx->opcode));
926     if (Rc(ctx->opcode))
927         gen_op_set_Rc1();
928 }
929
930 /* mtfsb0 */
931 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
932 {
933     uint8_t crb;
934     
935     crb = crbD(ctx->opcode) >> 2;
936     gen_op_load_fpscr_T0(crb);
937     gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03)));
938     gen_op_store_T0_fpscr(crb);
939     if (Rc(ctx->opcode))
940         gen_op_set_Rc1();
941 }
942
943 /* mtfsb1 */
944 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
945 {
946     uint8_t crb;
947     
948     crb = crbD(ctx->opcode) >> 2;
949     gen_op_load_fpscr_T0(crb);
950     gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
951     gen_op_store_T0_fpscr(crb);
952     if (Rc(ctx->opcode))
953         gen_op_set_Rc1();
954 }
955
956 /* mtfsf */
957 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
958 {
959     gen_op_load_fpr_FT0(rB(ctx->opcode));
960     gen_op_store_fpscr(FM(ctx->opcode));
961     if (Rc(ctx->opcode))
962         gen_op_set_Rc1();
963 }
964
965 /* mtfsfi */
966 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
967 {
968     gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
969     if (Rc(ctx->opcode))
970         gen_op_set_Rc1();
971 }
972
973 /***                             Integer load                              ***/
974 #if defined(CONFIG_USER_ONLY)
975 #define op_ldst(name)        gen_op_##name##_raw()
976 #define OP_LD_TABLE(width)
977 #define OP_ST_TABLE(width)
978 #else
979 #define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
980 #define OP_LD_TABLE(width)                                                    \
981 static GenOpFunc *gen_op_l##width[] = {                                       \
982     &gen_op_l##width##_user,                                                  \
983     &gen_op_l##width##_kernel,                                                \
984 }
985 #define OP_ST_TABLE(width)                                                    \
986 static GenOpFunc *gen_op_st##width[] = {                                      \
987     &gen_op_st##width##_user,                                                 \
988     &gen_op_st##width##_kernel,                                               \
989 }
990 #endif
991
992 #define GEN_LD(width, opc)                                                    \
993 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)               \
994 {                                                                             \
995     uint32_t simm = SIMM(ctx->opcode);                                        \
996     if (rA(ctx->opcode) == 0) {                                               \
997         gen_op_set_T0(simm);                                                  \
998     } else {                                                                  \
999         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1000         if (simm != 0)                                                        \
1001             gen_op_addi(simm);                                                \
1002     }                                                                         \
1003     op_ldst(l##width);                                                        \
1004     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1005 }
1006
1007 #define GEN_LDU(width, opc)                                                   \
1008 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)            \
1009 {                                                                             \
1010     uint32_t simm = SIMM(ctx->opcode);                                        \
1011     if (rA(ctx->opcode) == 0 ||                                               \
1012         rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1013         RET_INVAL();                                                          \
1014     }                                                                         \
1015     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1016     if (simm != 0)                                                            \
1017         gen_op_addi(simm);                                                    \
1018     op_ldst(l##width);                                                        \
1019     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1020     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1021 }
1022
1023 #define GEN_LDUX(width, opc)                                                  \
1024 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)           \
1025 {                                                                             \
1026     if (rA(ctx->opcode) == 0 ||                                               \
1027         rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1028         RET_INVAL();                                                          \
1029     }                                                                         \
1030     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1031     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1032     gen_op_add();                                                             \
1033     op_ldst(l##width);                                                        \
1034     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1035     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1036 }
1037
1038 #define GEN_LDX(width, opc2, opc3)                                            \
1039 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)           \
1040 {                                                                             \
1041     if (rA(ctx->opcode) == 0) {                                               \
1042         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1043     } else {                                                                  \
1044         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1045         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1046         gen_op_add();                                                         \
1047     }                                                                         \
1048     op_ldst(l##width);                                                        \
1049     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1050 }
1051
1052 #define GEN_LDS(width, op)                                                    \
1053 OP_LD_TABLE(width);                                                           \
1054 GEN_LD(width, op | 0x20);                                                     \
1055 GEN_LDU(width, op | 0x21);                                                    \
1056 GEN_LDUX(width, op | 0x01);                                                   \
1057 GEN_LDX(width, 0x17, op | 0x00)
1058
1059 /* lbz lbzu lbzux lbzx */
1060 GEN_LDS(bz, 0x02);
1061 /* lha lhau lhaux lhax */
1062 GEN_LDS(ha, 0x0A);
1063 /* lhz lhzu lhzux lhzx */
1064 GEN_LDS(hz, 0x08);
1065 /* lwz lwzu lwzux lwzx */
1066 GEN_LDS(wz, 0x00);
1067
1068 /***                              Integer store                            ***/
1069 #define GEN_ST(width, opc)                                                    \
1070 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)              \
1071 {                                                                             \
1072     uint32_t simm = SIMM(ctx->opcode);                                        \
1073     if (rA(ctx->opcode) == 0) {                                               \
1074         gen_op_set_T0(simm);                                                  \
1075     } else {                                                                  \
1076         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1077         if (simm != 0)                                                        \
1078             gen_op_addi(simm);                                                \
1079     }                                                                         \
1080     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1081     op_ldst(st##width);                                                       \
1082 }
1083
1084 #define GEN_STU(width, opc)                                                   \
1085 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)           \
1086 {                                                                             \
1087     uint32_t simm = SIMM(ctx->opcode);                                        \
1088     if (rA(ctx->opcode) == 0) {                                               \
1089         RET_INVAL();                                                          \
1090     }                                                                         \
1091     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1092     if (simm != 0)                                                            \
1093         gen_op_addi(simm);                                                    \
1094     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1095     op_ldst(st##width);                                                       \
1096     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1097 }
1098
1099 #define GEN_STUX(width, opc)                                                  \
1100 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
1101 {                                                                             \
1102     if (rA(ctx->opcode) == 0) {                                               \
1103         RET_INVAL();                                                          \
1104     }                                                                         \
1105     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1106     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1107     gen_op_add();                                                             \
1108     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1109     op_ldst(st##width);                                                       \
1110     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1111 }
1112
1113 #define GEN_STX(width, opc2, opc3)                                            \
1114 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)          \
1115 {                                                                             \
1116     if (rA(ctx->opcode) == 0) {                                               \
1117         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1118     } else {                                                                  \
1119         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1120         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1121         gen_op_add();                                                         \
1122     }                                                                         \
1123     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1124     op_ldst(st##width);                                                       \
1125 }
1126
1127 #define GEN_STS(width, op)                                                    \
1128 OP_ST_TABLE(width);                                                           \
1129 GEN_ST(width, op | 0x20);                                                     \
1130 GEN_STU(width, op | 0x21);                                                    \
1131 GEN_STUX(width, op | 0x01);                                                   \
1132 GEN_STX(width, 0x17, op | 0x00)
1133
1134 /* stb stbu stbux stbx */
1135 GEN_STS(b, 0x06);
1136 /* sth sthu sthux sthx */
1137 GEN_STS(h, 0x0C);
1138 /* stw stwu stwux stwx */
1139 GEN_STS(w, 0x04);
1140
1141 /***                Integer load and store with byte reverse               ***/
1142 /* lhbrx */
1143 OP_LD_TABLE(hbr);
1144 GEN_LDX(hbr, 0x16, 0x18);
1145 /* lwbrx */
1146 OP_LD_TABLE(wbr);
1147 GEN_LDX(wbr, 0x16, 0x10);
1148 /* sthbrx */
1149 OP_ST_TABLE(hbr);
1150 GEN_STX(hbr, 0x16, 0x1C);
1151 /* stwbrx */
1152 OP_ST_TABLE(wbr);
1153 GEN_STX(wbr, 0x16, 0x14);
1154
1155 /***                    Integer load and store multiple                    ***/
1156 #if defined(CONFIG_USER_ONLY)
1157 #define op_ldstm(name, reg) gen_op_##name##_raw(reg)
1158 #else
1159 #define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
1160 static GenOpFunc1 *gen_op_lmw[] = {
1161     &gen_op_lmw_user,
1162     &gen_op_lmw_kernel,
1163 };
1164 static GenOpFunc1 *gen_op_stmw[] = {
1165     &gen_op_stmw_user,
1166     &gen_op_stmw_kernel,
1167 };
1168 #endif
1169
1170 /* lmw */
1171 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1172 {
1173     int simm = SIMM(ctx->opcode);
1174
1175     if (rA(ctx->opcode) == 0) {
1176         gen_op_set_T0(simm);
1177     } else {
1178         gen_op_load_gpr_T0(rA(ctx->opcode));
1179         if (simm != 0)
1180             gen_op_addi(simm);
1181     }
1182     op_ldstm(lmw, rD(ctx->opcode));
1183 }
1184
1185 /* stmw */
1186 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1187 {
1188     int simm = SIMM(ctx->opcode);
1189
1190     if (rA(ctx->opcode) == 0) {
1191         gen_op_set_T0(simm);
1192     } else {
1193         gen_op_load_gpr_T0(rA(ctx->opcode));
1194         if (simm != 0)
1195             gen_op_addi(simm);
1196     }
1197     op_ldstm(stmw, rS(ctx->opcode));
1198 }
1199
1200 /***                    Integer load and store strings                     ***/
1201 #if defined(CONFIG_USER_ONLY)
1202 #define op_ldsts(name, start) gen_op_##name##_raw(start)
1203 #define op_ldstsx(name, rd, ra, rb) gen_op_##name##_raw(rd, ra, rb)
1204 #else
1205 #define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
1206 #define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
1207 static GenOpFunc1 *gen_op_lswi[] = {
1208     &gen_op_lswi_user,
1209     &gen_op_lswi_kernel,
1210 };
1211 static GenOpFunc3 *gen_op_lswx[] = {
1212     &gen_op_lswx_user,
1213     &gen_op_lswx_kernel,
1214 };
1215 static GenOpFunc1 *gen_op_stsw[] = {
1216     &gen_op_stsw_user,
1217     &gen_op_stsw_kernel,
1218 };
1219 #endif
1220
1221 /* lswi */
1222 /* PPC32 specification says we must generate an exception if
1223  * rA is in the range of registers to be loaded.
1224  * In an other hand, IBM says this is valid, but rA won't be loaded.
1225  * For now, I'll follow the spec...
1226  */
1227 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
1228 {
1229     int nb = NB(ctx->opcode);
1230     int start = rD(ctx->opcode);
1231     int ra = rA(ctx->opcode);
1232     int nr;
1233
1234     if (nb == 0)
1235         nb = 32;
1236     nr = nb / 4;
1237     if (((start + nr) > 32  && start <= ra && (start + nr - 32) > ra) ||
1238         ((start + nr) <= 32 && start <= ra && (start + nr) > ra)) {
1239         RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
1240     }
1241     if (ra == 0) {
1242         gen_op_set_T0(0);
1243     } else {
1244         gen_op_load_gpr_T0(ra);
1245     }
1246     gen_op_set_T1(nb);
1247     op_ldsts(lswi, start);
1248 }
1249
1250 /* lswx */
1251 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
1252 {
1253     int ra = rA(ctx->opcode);
1254     int rb = rB(ctx->opcode);
1255
1256     if (ra == 0) {
1257         gen_op_load_gpr_T0(rb);
1258         ra = rb;
1259     } else {
1260         gen_op_load_gpr_T0(ra);
1261         gen_op_load_gpr_T1(rb);
1262         gen_op_add();
1263     }
1264     gen_op_load_xer_bc();
1265     op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
1266 }
1267
1268 /* stswi */
1269 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
1270 {
1271     if (rA(ctx->opcode) == 0) {
1272         gen_op_set_T0(0);
1273     } else {
1274         gen_op_load_gpr_T0(rA(ctx->opcode));
1275     }
1276     gen_op_set_T1(NB(ctx->opcode));
1277     op_ldsts(stsw, rS(ctx->opcode));
1278 }
1279
1280 /* stswx */
1281 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
1282 {
1283     int ra = rA(ctx->opcode);
1284
1285     if (ra == 0) {
1286         gen_op_load_gpr_T0(rB(ctx->opcode));
1287         ra = rB(ctx->opcode);
1288     } else {
1289         gen_op_load_gpr_T0(ra);
1290         gen_op_load_gpr_T1(rB(ctx->opcode));
1291         gen_op_add();
1292     }
1293     gen_op_load_xer_bc();
1294     op_ldsts(stsw, rS(ctx->opcode));
1295 }
1296
1297 /***                        Memory synchronisation                         ***/
1298 /* eieio */
1299 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM)
1300 {
1301 }
1302
1303 /* isync */
1304 GEN_HANDLER(isync, 0x13, 0x16, 0xFF, 0x03FF0801, PPC_MEM)
1305 {
1306 }
1307
1308 /* lwarx */
1309 #if defined(CONFIG_USER_ONLY)
1310 #define op_lwarx() gen_op_lwarx_raw()
1311 #define op_stwcx() gen_op_stwcx_raw()
1312 #else
1313 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
1314 static GenOpFunc *gen_op_lwarx[] = {
1315     &gen_op_lwarx_user,
1316     &gen_op_lwarx_kernel,
1317 };
1318 #define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
1319 static GenOpFunc *gen_op_stwcx[] = {
1320     &gen_op_stwcx_user,
1321     &gen_op_stwcx_kernel,
1322 };
1323 #endif
1324
1325 GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_RES)
1326 {
1327     if (rA(ctx->opcode) == 0) {
1328         gen_op_load_gpr_T0(rB(ctx->opcode));
1329     } else {
1330         gen_op_load_gpr_T0(rA(ctx->opcode));
1331         gen_op_load_gpr_T1(rB(ctx->opcode));
1332         gen_op_add();
1333     }
1334     op_lwarx();
1335     gen_op_store_T1_gpr(rD(ctx->opcode));
1336 }
1337
1338 /* stwcx. */
1339 GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
1340 {
1341         if (rA(ctx->opcode) == 0) {
1342             gen_op_load_gpr_T0(rB(ctx->opcode));
1343         } else {
1344             gen_op_load_gpr_T0(rA(ctx->opcode));
1345             gen_op_load_gpr_T1(rB(ctx->opcode));
1346         gen_op_add();
1347         }
1348     gen_op_load_gpr_T1(rS(ctx->opcode));
1349     op_stwcx();
1350 }
1351
1352 /* sync */
1353 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM)
1354 {
1355 }
1356
1357 /***                         Floating-point load                           ***/
1358 #define GEN_LDF(width, opc)                                                   \
1359 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)               \
1360 {                                                                             \
1361     uint32_t simm = SIMM(ctx->opcode);                                        \
1362     if (rA(ctx->opcode) == 0) {                                               \
1363         gen_op_set_T0(simm);                                                  \
1364     } else {                                                                  \
1365         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1366         if (simm != 0)                                                        \
1367             gen_op_addi(simm);                                                \
1368     }                                                                         \
1369     op_ldst(l##width);                                                        \
1370     gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1371 }
1372
1373 #define GEN_LDUF(width, opc)                                                  \
1374 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)            \
1375 {                                                                             \
1376     uint32_t simm = SIMM(ctx->opcode);                                        \
1377     if (rA(ctx->opcode) == 0 ||                                               \
1378         rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1379         RET_INVAL();                                                          \
1380     }                                                                         \
1381     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1382     if (simm != 0)                                                            \
1383         gen_op_addi(simm);                                                    \
1384     op_ldst(l##width);                                                        \
1385     gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1386     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1387 }
1388
1389 #define GEN_LDUXF(width, opc)                                                 \
1390 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)           \
1391 {                                                                             \
1392     if (rA(ctx->opcode) == 0 ||                                               \
1393         rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1394         RET_INVAL();                                                          \
1395     }                                                                         \
1396     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1397     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1398     gen_op_add();                                                             \
1399     op_ldst(l##width);                                                        \
1400     gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1401     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1402 }
1403
1404 #define GEN_LDXF(width, opc2, opc3)                                           \
1405 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)           \
1406 {                                                                             \
1407     if (rA(ctx->opcode) == 0) {                                               \
1408         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1409     } else {                                                                  \
1410         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1411         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1412         gen_op_add();                                                         \
1413     }                                                                         \
1414     op_ldst(l##width);                                                        \
1415     gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1416 }
1417
1418 #define GEN_LDFS(width, op)                                                   \
1419 OP_LD_TABLE(width);                                                           \
1420 GEN_LDF(width, op | 0x20);                                                    \
1421 GEN_LDUF(width, op | 0x21);                                                   \
1422 GEN_LDUXF(width, op | 0x01);                                                  \
1423 GEN_LDXF(width, 0x17, op | 0x00)
1424
1425 /* lfd lfdu lfdux lfdx */
1426 GEN_LDFS(fd, 0x12);
1427 /* lfs lfsu lfsux lfsx */
1428 GEN_LDFS(fs, 0x10);
1429
1430 /***                         Floating-point store                          ***/
1431 #define GEN_STF(width, opc)                                                   \
1432 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)              \
1433 {                                                                             \
1434     uint32_t simm = SIMM(ctx->opcode);                                        \
1435     if (rA(ctx->opcode) == 0) {                                               \
1436         gen_op_set_T0(simm);                                                  \
1437     } else {                                                                  \
1438         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1439         if (simm != 0)                                                        \
1440             gen_op_addi(simm);                                                \
1441     }                                                                         \
1442     gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1443     op_ldst(st##width);                                                       \
1444 }
1445
1446 #define GEN_STUF(width, opc)                                                  \
1447 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)           \
1448 {                                                                             \
1449     uint32_t simm = SIMM(ctx->opcode);                                        \
1450     if (rA(ctx->opcode) == 0) {                                               \
1451         RET_INVAL();                                                          \
1452     }                                                                         \
1453     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1454     if (simm != 0)                                                            \
1455         gen_op_addi(simm);                                                    \
1456     gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1457     op_ldst(st##width);                                                       \
1458     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1459 }
1460
1461 #define GEN_STUXF(width, opc)                                                 \
1462 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
1463 {                                                                             \
1464     if (rA(ctx->opcode) == 0) {                                               \
1465         RET_INVAL();                                                          \
1466     }                                                                         \
1467     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1468     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1469     gen_op_add();                                                             \
1470     gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1471     op_ldst(st##width);                                                       \
1472     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1473 }
1474
1475 #define GEN_STXF(width, opc2, opc3)                                           \
1476 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)          \
1477 {                                                                             \
1478     if (rA(ctx->opcode) == 0) {                                               \
1479         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1480     } else {                                                                  \
1481         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1482         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1483         gen_op_add();                                                         \
1484     }                                                                         \
1485     gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1486     op_ldst(st##width);                                                       \
1487 }
1488
1489 #define GEN_STFS(width, op)                                                   \
1490 OP_ST_TABLE(width);                                                           \
1491 GEN_STF(width, op | 0x20);                                                    \
1492 GEN_STUF(width, op | 0x21);                                                   \
1493 GEN_STUXF(width, op | 0x01);                                                  \
1494 GEN_STXF(width, 0x17, op | 0x00)
1495
1496 /* stfd stfdu stfdux stfdx */
1497 GEN_STFS(fd, 0x16);
1498 /* stfs stfsu stfsux stfsx */
1499 GEN_STFS(fs, 0x14);
1500
1501 /* Optional: */
1502 /* stfiwx */
1503 GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1504 {
1505     RET_INVAL();
1506 }
1507
1508 /***                                Branch                                 ***/
1509
1510 /* b ba bl bla */
1511 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1512 {
1513     uint32_t li = s_ext24(LI(ctx->opcode)), target;
1514
1515     gen_op_update_tb(ctx->tb_offset);
1516     gen_op_update_decr(ctx->decr_offset);
1517     gen_op_process_exceptions(ctx->nip - 4);
1518     if (AA(ctx->opcode) == 0)
1519         target = ctx->nip + li - 4;
1520     else
1521         target = li;
1522     if (LK(ctx->opcode)) {
1523         gen_op_setlr(ctx->nip);
1524     }
1525     gen_op_b((long)ctx->tb, target);
1526     ctx->exception = EXCP_BRANCH;
1527 }
1528
1529 #define BCOND_IM  0
1530 #define BCOND_LR  1
1531 #define BCOND_CTR 2
1532
1533 static inline void gen_bcond(DisasContext *ctx, int type) 
1534 {                                                                             
1535     uint32_t target = 0;
1536     uint32_t bo = BO(ctx->opcode);                                            
1537     uint32_t bi = BI(ctx->opcode);                                            
1538     uint32_t mask;                                                            
1539     uint32_t li;
1540
1541     gen_op_update_tb(ctx->tb_offset);                                         
1542     gen_op_update_decr(ctx->decr_offset);                                     
1543     gen_op_process_exceptions(ctx->nip - 4);                        
1544
1545     if ((bo & 0x4) == 0)
1546         gen_op_dec_ctr();                                                     
1547     switch(type) {
1548     case BCOND_IM:
1549         li = s_ext16(BD(ctx->opcode));
1550         if (AA(ctx->opcode) == 0) {
1551             target = ctx->nip + li - 4;
1552         } else {
1553             target = li;
1554         }
1555         break;
1556     case BCOND_CTR:
1557         gen_op_movl_T1_ctr();
1558         break;
1559     default:
1560     case BCOND_LR:
1561         gen_op_movl_T1_lr();
1562         break;
1563     }
1564     if (LK(ctx->opcode)) {                                        
1565         gen_op_setlr(ctx->nip);
1566     }
1567     if (bo & 0x10) {
1568         /* No CR condition */                                                 
1569         switch (bo & 0x6) {                                                   
1570         case 0:                                                               
1571             gen_op_test_ctr();
1572             break;
1573         case 2:                                                               
1574             gen_op_test_ctrz();
1575             break;                                                            
1576         default:
1577         case 4:                                                               
1578         case 6:                                                               
1579             if (type == BCOND_IM) {
1580                 gen_op_b((long)ctx->tb, target);
1581             } else {
1582                 gen_op_b_T1();
1583             }
1584             goto no_test;
1585         }
1586     } else {                                                                  
1587         mask = 1 << (3 - (bi & 0x03));                                        
1588         gen_op_load_crf_T0(bi >> 2);                                          
1589         if (bo & 0x8) {                                                       
1590             switch (bo & 0x6) {                                               
1591             case 0:                                                           
1592                 gen_op_test_ctr_true(mask);
1593                 break;                                                        
1594             case 2:                                                           
1595                 gen_op_test_ctrz_true(mask);
1596                 break;                                                        
1597             default:                                                          
1598             case 4:                                                           
1599             case 6:                                                           
1600                 gen_op_test_true(mask);
1601                 break;                                                        
1602             }                                                                 
1603         } else {                                                              
1604             switch (bo & 0x6) {                                               
1605             case 0:                                                           
1606                 gen_op_test_ctr_false(mask);
1607                 break;                                                        
1608             case 2:                                                           
1609                 gen_op_test_ctrz_false(mask);
1610                 break;                                                        
1611             default:
1612             case 4:                                                           
1613             case 6:                                                           
1614                 gen_op_test_false(mask);
1615                 break;                                                        
1616             }                                                                 
1617         }                                                                     
1618     }                                                                         
1619     if (type == BCOND_IM) {
1620         gen_op_btest((long)ctx->tb, target, ctx->nip);
1621     } else {
1622         gen_op_btest_T1(ctx->nip);
1623     }
1624  no_test:
1625     ctx->exception = EXCP_BRANCH;                                             
1626 }
1627
1628 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1629 {                                                                             
1630     gen_bcond(ctx, BCOND_IM);
1631 }
1632
1633 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
1634 {                                                                             
1635     gen_bcond(ctx, BCOND_CTR);
1636 }
1637
1638 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
1639 {                                                                             
1640     gen_bcond(ctx, BCOND_LR);
1641 }
1642
1643 /***                      Condition register logical                       ***/
1644 #define GEN_CRLOGIC(op, opc)                                                  \
1645 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
1646 {                                                                             \
1647     gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
1648     gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
1649     gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
1650     gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
1651     gen_op_##op();                                                            \
1652     gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
1653     gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
1654                      3 - (crbD(ctx->opcode) & 0x03));                         \
1655     gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
1656 }
1657
1658 /* crand */
1659 GEN_CRLOGIC(and, 0x08)
1660 /* crandc */
1661 GEN_CRLOGIC(andc, 0x04)
1662 /* creqv */
1663 GEN_CRLOGIC(eqv, 0x09)
1664 /* crnand */
1665 GEN_CRLOGIC(nand, 0x07)
1666 /* crnor */
1667 GEN_CRLOGIC(nor, 0x01)
1668 /* cror */
1669 GEN_CRLOGIC(or, 0x0E)
1670 /* crorc */
1671 GEN_CRLOGIC(orc, 0x0D)
1672 /* crxor */
1673 GEN_CRLOGIC(xor, 0x06)
1674 /* mcrf */
1675 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
1676 {
1677     gen_op_load_crf_T0(crfS(ctx->opcode));
1678     gen_op_store_T0_crf(crfD(ctx->opcode));
1679 }
1680
1681 /***                           System linkage                              ***/
1682 /* rfi (supervisor only) */
1683 GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
1684 {
1685 #if defined(CONFIG_USER_ONLY)
1686     RET_PRIVOPC();
1687 #else
1688     /* Restore CPU state */
1689     if (!ctx->supervisor) {
1690         RET_PRIVOPC();
1691     }
1692     gen_op_rfi();
1693     ctx->exception = EXCP_RFI;
1694 #endif
1695 }
1696
1697 /* sc */
1698 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
1699 {
1700 #if defined(CONFIG_USER_ONLY)
1701     gen_op_queue_exception(EXCP_SYSCALL_USER);
1702 #else
1703     gen_op_queue_exception(EXCP_SYSCALL);
1704 #endif
1705     ctx->exception = EXCP_SYSCALL;
1706 }
1707
1708 /***                                Trap                                   ***/
1709 /* tw */
1710 GEN_HANDLER(tw, 0x1F, 0x04, 0xFF, 0x00000001, PPC_FLOW)
1711 {
1712     gen_op_load_gpr_T0(rA(ctx->opcode));
1713     gen_op_load_gpr_T1(rB(ctx->opcode));
1714     gen_op_tw(TO(ctx->opcode));
1715 }
1716
1717 /* twi */
1718 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1719 {
1720     gen_op_load_gpr_T0(rA(ctx->opcode));
1721 #if 0
1722     printf("%s: param=0x%04x T0=0x%04x\n", __func__,
1723            SIMM(ctx->opcode), TO(ctx->opcode));
1724 #endif
1725     gen_op_twi(SIMM(ctx->opcode), TO(ctx->opcode));
1726 }
1727
1728 /***                          Processor control                            ***/
1729 static inline int check_spr_access (int spr, int rw, int supervisor)
1730 {
1731     uint32_t rights = spr_access[spr >> 1] >> (4 * (spr & 1));
1732
1733 #if 0
1734     if (spr != LR && spr != CTR) {
1735     if (loglevel > 0) {
1736         fprintf(logfile, "%s reg=%d s=%d rw=%d r=0x%02x 0x%02x\n", __func__,
1737                 SPR_ENCODE(spr), supervisor, rw, rights,
1738                 (rights >> ((2 * supervisor) + rw)) & 1);
1739     } else {
1740         printf("%s reg=%d s=%d rw=%d r=0x%02x 0x%02x\n", __func__,
1741                SPR_ENCODE(spr), supervisor, rw, rights,
1742                (rights >> ((2 * supervisor) + rw)) & 1);
1743     }
1744     }
1745 #endif
1746     if (rights == 0)
1747         return -1;
1748     rights = rights >> (2 * supervisor);
1749     rights = rights >> rw;
1750
1751     return rights & 1;
1752 }
1753
1754 /* mcrxr */
1755 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
1756 {
1757     gen_op_load_xer_cr();
1758     gen_op_store_T0_crf(crfD(ctx->opcode));
1759     gen_op_clear_xer_cr();
1760 }
1761
1762 /* mfcr */
1763 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x001FF801, PPC_MISC)
1764 {
1765     gen_op_load_cr();
1766     gen_op_store_T0_gpr(rD(ctx->opcode));
1767 }
1768
1769 /* mfmsr */
1770 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1771 {
1772 #if defined(CONFIG_USER_ONLY)
1773     RET_PRIVREG();
1774 #else
1775     if (!ctx->supervisor) {
1776         RET_PRIVREG();
1777     }
1778     gen_op_load_msr();
1779     gen_op_store_T0_gpr(rD(ctx->opcode));
1780 #endif
1781 }
1782
1783 /* mfspr */
1784 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
1785 {
1786     uint32_t sprn = SPR(ctx->opcode);
1787
1788 #if defined(CONFIG_USER_ONLY)
1789     switch (check_spr_access(sprn, 0, 0))
1790 #else
1791     switch (check_spr_access(sprn, 0, ctx->supervisor))
1792 #endif
1793     {
1794     case -1:
1795         RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
1796         break;
1797     case 0:
1798         RET_PRIVREG();
1799         break;
1800     default:
1801         break;
1802         }
1803     switch (sprn) {
1804     case XER:
1805         gen_op_load_xer();
1806         break;
1807     case LR:
1808         gen_op_load_lr();
1809         break;
1810     case CTR:
1811         gen_op_load_ctr();
1812         break;
1813     case IBAT0U:
1814         gen_op_load_ibat(0, 0);
1815         break;
1816     case IBAT1U:
1817         gen_op_load_ibat(0, 1);
1818         break;
1819     case IBAT2U:
1820         gen_op_load_ibat(0, 2);
1821         break;
1822     case IBAT3U:
1823         gen_op_load_ibat(0, 3);
1824         break;
1825     case IBAT4U:
1826         gen_op_load_ibat(0, 4);
1827         break;
1828     case IBAT5U:
1829         gen_op_load_ibat(0, 5);
1830         break;
1831     case IBAT6U:
1832         gen_op_load_ibat(0, 6);
1833         break;
1834     case IBAT7U:
1835         gen_op_load_ibat(0, 7);
1836         break;
1837     case IBAT0L:
1838         gen_op_load_ibat(1, 0);
1839         break;
1840     case IBAT1L:
1841         gen_op_load_ibat(1, 1);
1842         break;
1843     case IBAT2L:
1844         gen_op_load_ibat(1, 2);
1845         break;
1846     case IBAT3L:
1847         gen_op_load_ibat(1, 3);
1848         break;
1849     case IBAT4L:
1850         gen_op_load_ibat(1, 4);
1851         break;
1852     case IBAT5L:
1853         gen_op_load_ibat(1, 5);
1854         break;
1855     case IBAT6L:
1856         gen_op_load_ibat(1, 6);
1857         break;
1858     case IBAT7L:
1859         gen_op_load_ibat(1, 7);
1860         break;
1861     case DBAT0U:
1862         gen_op_load_dbat(0, 0);
1863         break;
1864     case DBAT1U:
1865         gen_op_load_dbat(0, 1);
1866         break;
1867     case DBAT2U:
1868         gen_op_load_dbat(0, 2);
1869         break;
1870     case DBAT3U:
1871         gen_op_load_dbat(0, 3);
1872         break;
1873     case DBAT4U:
1874         gen_op_load_dbat(0, 4);
1875         break;
1876     case DBAT5U:
1877         gen_op_load_dbat(0, 5);
1878         break;
1879     case DBAT6U:
1880         gen_op_load_dbat(0, 6);
1881         break;
1882     case DBAT7U:
1883         gen_op_load_dbat(0, 7);
1884         break;
1885     case DBAT0L:
1886         gen_op_load_dbat(1, 0);
1887         break;
1888     case DBAT1L:
1889         gen_op_load_dbat(1, 1);
1890         break;
1891     case DBAT2L:
1892         gen_op_load_dbat(1, 2);
1893         break;
1894     case DBAT3L:
1895         gen_op_load_dbat(1, 3);
1896         break;
1897     case DBAT4L:
1898         gen_op_load_dbat(1, 4);
1899         break;
1900     case DBAT5L:
1901         gen_op_load_dbat(1, 5);
1902         break;
1903     case DBAT6L:
1904         gen_op_load_dbat(1, 6);
1905         break;
1906     case DBAT7L:
1907         gen_op_load_dbat(1, 7);
1908         break;
1909     case SDR1:
1910         gen_op_load_sdr1();
1911         break;
1912     case V_TBL:
1913         gen_op_update_tb(ctx->tb_offset);
1914         ctx->tb_offset = 0;
1915         /* TBL is still in T0 */
1916         break;
1917     case V_TBU:
1918         gen_op_update_tb(ctx->tb_offset);
1919         ctx->tb_offset = 0;
1920         gen_op_load_tb(1);
1921         break;
1922     case DECR:
1923         gen_op_update_decr(ctx->decr_offset);
1924         ctx->decr_offset = 0;
1925         /* decr is still in T0 */
1926         break;
1927     default:
1928         gen_op_load_spr(sprn);
1929         break;
1930     }
1931     gen_op_store_T0_gpr(rD(ctx->opcode));
1932 }
1933
1934 /* mftb */
1935 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC)
1936 {
1937     uint32_t sprn = SPR(ctx->opcode);
1938
1939         /* We need to update the time base before reading it */
1940     switch (sprn) {
1941     case V_TBL:
1942         gen_op_update_tb(ctx->tb_offset);
1943         /* TBL is still in T0 */
1944         break;
1945     case V_TBU:
1946         gen_op_update_tb(ctx->tb_offset);
1947         gen_op_load_tb(1);
1948         break;
1949     default:
1950         RET_INVAL();
1951         break;
1952     }
1953     ctx->tb_offset = 0;
1954     gen_op_store_T0_gpr(rD(ctx->opcode));
1955 }
1956
1957 /* mtcrf */
1958 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00100801, PPC_MISC)
1959 {
1960     gen_op_load_gpr_T0(rS(ctx->opcode));
1961     gen_op_store_cr(CRM(ctx->opcode));
1962 }
1963
1964 /* mtmsr */
1965 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
1966 {
1967 #if defined(CONFIG_USER_ONLY)
1968     RET_PRIVREG();
1969 #else
1970     if (!ctx->supervisor) {
1971         RET_PRIVREG();
1972     }
1973     gen_op_load_gpr_T0(rS(ctx->opcode));
1974     gen_op_store_msr();
1975     /* Must stop the translation as machine state (may have) changed */
1976     ctx->exception = EXCP_MTMSR;
1977 #endif
1978 }
1979
1980 /* mtspr */
1981 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
1982 {
1983     uint32_t sprn = SPR(ctx->opcode);
1984
1985 #if 0
1986     if (loglevel > 0) {
1987         fprintf(logfile, "MTSPR %d src=%d (%d)\n", SPR_ENCODE(sprn),
1988                 rS(ctx->opcode), sprn);
1989     }
1990 #endif
1991 #if defined(CONFIG_USER_ONLY)
1992     switch (check_spr_access(sprn, 1, 0))
1993 #else
1994     switch (check_spr_access(sprn, 1, ctx->supervisor))
1995 #endif
1996     {
1997     case -1:
1998         RET_EXCP(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
1999         break;
2000     case 0:
2001         RET_PRIVREG();
2002         break;
2003     default:
2004         break;
2005     }
2006     gen_op_load_gpr_T0(rS(ctx->opcode));
2007     switch (sprn) {
2008     case XER:
2009         gen_op_store_xer();
2010         break;
2011     case LR:
2012         gen_op_store_lr();
2013         break;
2014     case CTR:
2015         gen_op_store_ctr();
2016         break;
2017     case IBAT0U:
2018         gen_op_store_ibat(0, 0);
2019         gen_op_tlbia();
2020         break;
2021     case IBAT1U:
2022         gen_op_store_ibat(0, 1);
2023         gen_op_tlbia();
2024         break;
2025     case IBAT2U:
2026         gen_op_store_ibat(0, 2);
2027         gen_op_tlbia();
2028         break;
2029     case IBAT3U:
2030         gen_op_store_ibat(0, 3);
2031         gen_op_tlbia();
2032         break;
2033     case IBAT4U:
2034         gen_op_store_ibat(0, 4);
2035         gen_op_tlbia();
2036         break;
2037     case IBAT5U:
2038         gen_op_store_ibat(0, 5);
2039         gen_op_tlbia();
2040         break;
2041     case IBAT6U:
2042         gen_op_store_ibat(0, 6);
2043         gen_op_tlbia();
2044         break;
2045     case IBAT7U:
2046         gen_op_store_ibat(0, 7);
2047         gen_op_tlbia();
2048         break;
2049     case IBAT0L:
2050         gen_op_store_ibat(1, 0);
2051         gen_op_tlbia();
2052         break;
2053     case IBAT1L:
2054         gen_op_store_ibat(1, 1);
2055         gen_op_tlbia();
2056         break;
2057     case IBAT2L:
2058         gen_op_store_ibat(1, 2);
2059         gen_op_tlbia();
2060         break;
2061     case IBAT3L:
2062         gen_op_store_ibat(1, 3);
2063         gen_op_tlbia();
2064         break;
2065     case IBAT4L:
2066         gen_op_store_ibat(1, 4);
2067         gen_op_tlbia();
2068         break;
2069     case IBAT5L:
2070         gen_op_store_ibat(1, 5);
2071         gen_op_tlbia();
2072         break;
2073     case IBAT6L:
2074         gen_op_store_ibat(1, 6);
2075         gen_op_tlbia();
2076         break;
2077     case IBAT7L:
2078         gen_op_store_ibat(1, 7);
2079         gen_op_tlbia();
2080         break;
2081     case DBAT0U:
2082         gen_op_store_dbat(0, 0);
2083         gen_op_tlbia();
2084         break;
2085     case DBAT1U:
2086         gen_op_store_dbat(0, 1);
2087         gen_op_tlbia();
2088         break;
2089     case DBAT2U:
2090         gen_op_store_dbat(0, 2);
2091         gen_op_tlbia();
2092         break;
2093     case DBAT3U:
2094         gen_op_store_dbat(0, 3);
2095         gen_op_tlbia();
2096         break;
2097     case DBAT4U:
2098         gen_op_store_dbat(0, 4);
2099         gen_op_tlbia();
2100         break;
2101     case DBAT5U:
2102         gen_op_store_dbat(0, 5);
2103         gen_op_tlbia();
2104         break;
2105     case DBAT6U:
2106         gen_op_store_dbat(0, 6);
2107         gen_op_tlbia();
2108         break;
2109     case DBAT7U:
2110         gen_op_store_dbat(0, 7);
2111         gen_op_tlbia();
2112         break;
2113     case DBAT0L:
2114         gen_op_store_dbat(1, 0);
2115         gen_op_tlbia();
2116         break;
2117     case DBAT1L:
2118         gen_op_store_dbat(1, 1);
2119         gen_op_tlbia();
2120         break;
2121     case DBAT2L:
2122         gen_op_store_dbat(1, 2);
2123         gen_op_tlbia();
2124         break;
2125     case DBAT3L:
2126         gen_op_store_dbat(1, 3);
2127         gen_op_tlbia();
2128         break;
2129     case DBAT4L:
2130         gen_op_store_dbat(1, 4);
2131         gen_op_tlbia();
2132         break;
2133     case DBAT5L:
2134         gen_op_store_dbat(1, 5);
2135         gen_op_tlbia();
2136         break;
2137     case DBAT6L:
2138         gen_op_store_dbat(1, 6);
2139         gen_op_tlbia();
2140         break;
2141     case DBAT7L:
2142         gen_op_store_dbat(1, 7);
2143         gen_op_tlbia();
2144         break;
2145     case SDR1:
2146         gen_op_store_sdr1();
2147         gen_op_tlbia();
2148         break;
2149     case O_TBL:
2150         gen_op_store_tb(0);
2151         ctx->tb_offset = 0;
2152         break;
2153     case O_TBU:
2154         gen_op_store_tb(1);
2155         ctx->tb_offset = 0;
2156         break;
2157     case DECR:
2158         gen_op_store_decr();
2159         ctx->decr_offset = 0;
2160         break;
2161     default:
2162         gen_op_store_spr(sprn);
2163         break;
2164     }
2165 }
2166
2167 /***                         Cache management                              ***/
2168 /* For now, all those will be implemented as nop:
2169  * this is valid, regarding the PowerPC specs...
2170  * We just have to flush tb while invalidating instruction cache lines...
2171  */
2172 /* dcbf */
2173 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
2174 {
2175     if (rA(ctx->opcode) == 0) {
2176         gen_op_load_gpr_T0(rB(ctx->opcode));
2177     } else {
2178         gen_op_load_gpr_T0(rA(ctx->opcode));
2179         gen_op_load_gpr_T1(rB(ctx->opcode));
2180         gen_op_add();
2181     }
2182     op_ldst(lbz);
2183 }
2184
2185 /* dcbi (Supervisor only) */
2186 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
2187 {
2188 #if defined(CONFIG_USER_ONLY)
2189     RET_PRIVOPC();
2190 #else
2191     if (!ctx->supervisor) {
2192         RET_PRIVOPC();
2193     }
2194     if (rA(ctx->opcode) == 0) {
2195         gen_op_load_gpr_T0(rB(ctx->opcode));
2196     } else {
2197         gen_op_load_gpr_T0(rA(ctx->opcode));
2198         gen_op_load_gpr_T1(rB(ctx->opcode));
2199         gen_op_add();
2200     }
2201     op_ldst(lbz);
2202     op_ldst(stb);
2203 #endif
2204 }
2205
2206 /* dcdst */
2207 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
2208 {
2209     if (rA(ctx->opcode) == 0) {
2210         gen_op_load_gpr_T0(rB(ctx->opcode));
2211     } else {
2212         gen_op_load_gpr_T0(rA(ctx->opcode));
2213         gen_op_load_gpr_T1(rB(ctx->opcode));
2214         gen_op_add();
2215     }
2216     op_ldst(lbz);
2217 }
2218
2219 /* dcbt */
2220 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
2221 {
2222 }
2223
2224 /* dcbtst */
2225 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
2226 {
2227 }
2228
2229 /* dcbz */
2230 #if defined(CONFIG_USER_ONLY)
2231 #define op_dcbz() gen_op_dcbz_raw()
2232 #else
2233 #define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
2234 static GenOpFunc *gen_op_dcbz[] = {
2235     &gen_op_dcbz_user,
2236     &gen_op_dcbz_kernel,
2237 };
2238 #endif
2239
2240 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
2241 {
2242     if (rA(ctx->opcode) == 0) {
2243         gen_op_load_gpr_T0(rB(ctx->opcode));
2244     } else {
2245         gen_op_load_gpr_T0(rA(ctx->opcode));
2246         gen_op_load_gpr_T1(rB(ctx->opcode));
2247         gen_op_add();
2248     }
2249     op_dcbz();
2250 }
2251
2252 /* icbi */
2253 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
2254 {
2255     if (rA(ctx->opcode) == 0) {
2256         gen_op_load_gpr_T0(rB(ctx->opcode));
2257     } else {
2258         gen_op_load_gpr_T0(rA(ctx->opcode));
2259         gen_op_load_gpr_T1(rB(ctx->opcode));
2260         gen_op_add();
2261     }
2262     gen_op_icbi();
2263 }
2264
2265 /* Optional: */
2266 /* dcba */
2267 GEN_HANDLER(dcba, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE_OPT)
2268 {
2269 }
2270
2271 /***                    Segment register manipulation                      ***/
2272 /* Supervisor only: */
2273 /* mfsr */
2274 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
2275 {
2276 #if defined(CONFIG_USER_ONLY)
2277     RET_PRIVREG();
2278 #else
2279     if (!ctx->supervisor) {
2280         RET_PRIVREG();
2281     }
2282     gen_op_load_sr(SR(ctx->opcode));
2283     gen_op_store_T0_gpr(rD(ctx->opcode));
2284 #endif
2285 }
2286
2287 /* mfsrin */
2288 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
2289 {
2290 #if defined(CONFIG_USER_ONLY)
2291     RET_PRIVREG();
2292 #else
2293     if (!ctx->supervisor) {
2294         RET_PRIVREG();
2295     }
2296     gen_op_load_gpr_T1(rB(ctx->opcode));
2297     gen_op_load_srin();
2298     gen_op_store_T0_gpr(rD(ctx->opcode));
2299 #endif
2300 }
2301
2302 /* mtsr */
2303 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
2304 {
2305 #if defined(CONFIG_USER_ONLY)
2306     RET_PRIVREG();
2307 #else
2308     if (!ctx->supervisor) {
2309         RET_PRIVREG();
2310     }
2311     gen_op_load_gpr_T0(rS(ctx->opcode));
2312     gen_op_store_sr(SR(ctx->opcode));
2313     gen_op_tlbia();
2314 #endif
2315 }
2316
2317 /* mtsrin */
2318 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
2319 {
2320 #if defined(CONFIG_USER_ONLY)
2321     RET_PRIVREG();
2322 #else
2323     if (!ctx->supervisor) {
2324         RET_PRIVREG();
2325     }
2326     gen_op_load_gpr_T0(rS(ctx->opcode));
2327     gen_op_load_gpr_T1(rB(ctx->opcode));
2328     gen_op_store_srin();
2329     gen_op_tlbia();
2330 #endif
2331 }
2332
2333 /***                      Lookaside buffer management                      ***/
2334 /* Optional & supervisor only: */
2335 /* tlbia */
2336 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT)
2337 {
2338 #if defined(CONFIG_USER_ONLY)
2339     RET_PRIVOPC();
2340 #else
2341     if (!ctx->supervisor) {
2342         RET_PRIVOPC();
2343     }
2344     gen_op_tlbia();
2345 #endif
2346 }
2347
2348 /* tlbie */
2349 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM)
2350 {
2351 #if defined(CONFIG_USER_ONLY)
2352     RET_PRIVOPC();
2353 #else
2354     if (!ctx->supervisor) {
2355         RET_PRIVOPC();
2356     }
2357     gen_op_load_gpr_T0(rB(ctx->opcode));
2358     gen_op_tlbie();
2359 #endif
2360 }
2361
2362 /* tlbsync */
2363 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM)
2364 {
2365 #if defined(CONFIG_USER_ONLY)
2366     RET_PRIVOPC();
2367 #else
2368     if (!ctx->supervisor) {
2369         RET_PRIVOPC();
2370     }
2371     /* This has no effect: it should ensure that all previous
2372      * tlbie have completed
2373      */
2374 #endif
2375 }
2376
2377 /***                              External control                         ***/
2378 /* Optional: */
2379 /* eciwx */
2380 #if defined(CONFIG_USER_ONLY)
2381 #define op_eciwx() gen_op_eciwx_raw()
2382 #define op_ecowx() gen_op_ecowx_raw()
2383 #else
2384 #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
2385 #define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
2386 static GenOpFunc *gen_op_eciwx[] = {
2387     &gen_op_eciwx_user,
2388     &gen_op_eciwx_kernel,
2389 };
2390 static GenOpFunc *gen_op_ecowx[] = {
2391     &gen_op_ecowx_user,
2392     &gen_op_ecowx_kernel,
2393 };
2394 #endif
2395
2396 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
2397 {
2398     /* Should check EAR[E] & alignment ! */
2399     if (rA(ctx->opcode) == 0) {
2400         gen_op_load_gpr_T0(rB(ctx->opcode));
2401     } else {
2402         gen_op_load_gpr_T0(rA(ctx->opcode));
2403         gen_op_load_gpr_T1(rB(ctx->opcode));
2404         gen_op_add();
2405     }
2406     op_eciwx();
2407     gen_op_store_T0_gpr(rD(ctx->opcode));
2408 }
2409
2410 /* ecowx */
2411 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
2412 {
2413     /* Should check EAR[E] & alignment ! */
2414     if (rA(ctx->opcode) == 0) {
2415         gen_op_load_gpr_T0(rB(ctx->opcode));
2416     } else {
2417         gen_op_load_gpr_T0(rA(ctx->opcode));
2418         gen_op_load_gpr_T1(rB(ctx->opcode));
2419         gen_op_add();
2420     }
2421     gen_op_load_gpr_T2(rS(ctx->opcode));
2422     op_ecowx();
2423 }
2424
2425 /* End opcode list */
2426 GEN_OPCODE_MARK(end);
2427
2428 /*****************************************************************************/
2429 #include <stdlib.h>
2430 #include <string.h>
2431
2432 int fflush (FILE *stream);
2433
2434 /* Main ppc opcodes table:
2435  * at init, all opcodes are invalids
2436  */
2437 static opc_handler_t *ppc_opcodes[0x40];
2438
2439 /* Opcode types */
2440 enum {
2441     PPC_DIRECT   = 0, /* Opcode routine        */
2442     PPC_INDIRECT = 1, /* Indirect opcode table */
2443 };
2444
2445 static inline int is_indirect_opcode (void *handler)
2446 {
2447     return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
2448 }
2449
2450 static inline opc_handler_t **ind_table(void *handler)
2451 {
2452     return (opc_handler_t **)((unsigned long)handler & ~3);
2453 }
2454
2455 /* Instruction table creation */
2456 /* Opcodes tables creation */
2457 static void fill_new_table (opc_handler_t **table, int len)
2458 {
2459     int i;
2460
2461     for (i = 0; i < len; i++)
2462         table[i] = &invalid_handler;
2463 }
2464
2465 static int create_new_table (opc_handler_t **table, unsigned char idx)
2466 {
2467     opc_handler_t **tmp;
2468
2469     tmp = malloc(0x20 * sizeof(opc_handler_t));
2470     if (tmp == NULL)
2471         return -1;
2472     fill_new_table(tmp, 0x20);
2473     table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
2474
2475     return 0;
2476 }
2477
2478 static int insert_in_table (opc_handler_t **table, unsigned char idx,
2479                             opc_handler_t *handler)
2480 {
2481     if (table[idx] != &invalid_handler)
2482         return -1;
2483     table[idx] = handler;
2484
2485     return 0;
2486 }
2487
2488 static int register_direct_insn (opc_handler_t **ppc_opcodes,
2489                                  unsigned char idx, opc_handler_t *handler)
2490 {
2491     if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
2492         printf("*** ERROR: opcode %02x already assigned in main "
2493                 "opcode table\n", idx);
2494         return -1;
2495     }
2496
2497     return 0;
2498 }
2499
2500 static int register_ind_in_table (opc_handler_t **table,
2501                                   unsigned char idx1, unsigned char idx2,
2502                                   opc_handler_t *handler)
2503 {
2504     if (table[idx1] == &invalid_handler) {
2505         if (create_new_table(table, idx1) < 0) {
2506             printf("*** ERROR: unable to create indirect table "
2507                     "idx=%02x\n", idx1);
2508             return -1;
2509         }
2510     } else {
2511         if (!is_indirect_opcode(table[idx1])) {
2512             printf("*** ERROR: idx %02x already assigned to a direct "
2513                     "opcode\n", idx1);
2514             return -1;
2515         }
2516     }
2517     if (handler != NULL &&
2518         insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
2519         printf("*** ERROR: opcode %02x already assigned in "
2520                 "opcode table %02x\n", idx2, idx1);
2521         return -1;
2522     }
2523
2524     return 0;
2525 }
2526
2527 static int register_ind_insn (opc_handler_t **ppc_opcodes,
2528                               unsigned char idx1, unsigned char idx2,
2529                                opc_handler_t *handler)
2530 {
2531     int ret;
2532
2533     ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
2534
2535     return ret;
2536 }
2537
2538 static int register_dblind_insn (opc_handler_t **ppc_opcodes, 
2539                                  unsigned char idx1, unsigned char idx2,
2540                                   unsigned char idx3, opc_handler_t *handler)
2541 {
2542     if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
2543         printf("*** ERROR: unable to join indirect table idx "
2544                 "[%02x-%02x]\n", idx1, idx2);
2545         return -1;
2546     }
2547     if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
2548                               handler) < 0) {
2549         printf("*** ERROR: unable to insert opcode "
2550                 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
2551         return -1;
2552     }
2553
2554     return 0;
2555 }
2556
2557 static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
2558 {
2559     if (insn->opc2 != 0xFF) {
2560         if (insn->opc3 != 0xFF) {
2561             if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
2562                                      insn->opc3, &insn->handler) < 0)
2563                 return -1;
2564         } else {
2565             if (register_ind_insn(ppc_opcodes, insn->opc1,
2566                                   insn->opc2, &insn->handler) < 0)
2567                 return -1;
2568         }
2569     } else {
2570         if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
2571             return -1;
2572     }
2573
2574     return 0;
2575 }
2576
2577 static int test_opcode_table (opc_handler_t **table, int len)
2578 {
2579     int i, count, tmp;
2580
2581     for (i = 0, count = 0; i < len; i++) {
2582         /* Consistency fixup */
2583         if (table[i] == NULL)
2584             table[i] = &invalid_handler;
2585         if (table[i] != &invalid_handler) {
2586             if (is_indirect_opcode(table[i])) {
2587                 tmp = test_opcode_table(ind_table(table[i]), 0x20);
2588                 if (tmp == 0) {
2589                     free(table[i]);
2590                     table[i] = &invalid_handler;
2591                 } else {
2592                     count++;
2593                 }
2594             } else {
2595                 count++;
2596             }
2597         }
2598     }
2599
2600     return count;
2601 }
2602
2603 static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
2604 {
2605     if (test_opcode_table(ppc_opcodes, 0x40) == 0)
2606         printf("*** WARNING: no opcode defined !\n");
2607 }
2608
2609 #define SPR_RIGHTS(rw, priv) (1 << ((2 * (priv)) + (rw)))
2610 #define SPR_UR SPR_RIGHTS(0, 0)
2611 #define SPR_UW SPR_RIGHTS(1, 0)
2612 #define SPR_SR SPR_RIGHTS(0, 1)
2613 #define SPR_SW SPR_RIGHTS(1, 1)
2614
2615 #define spr_set_rights(spr, rights)                            \
2616 do {                                                           \
2617     spr_access[(spr) >> 1] |= ((rights) << (4 * ((spr) & 1))); \
2618 } while (0)
2619
2620 static void init_spr_rights (uint32_t pvr)
2621 {
2622     /* XER    (SPR 1) */
2623     spr_set_rights(XER,    SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2624     /* LR     (SPR 8) */
2625     spr_set_rights(LR,     SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2626     /* CTR    (SPR 9) */
2627     spr_set_rights(CTR,    SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2628     /* TBL    (SPR 268) */
2629     spr_set_rights(V_TBL,  SPR_UR | SPR_SR);
2630     /* TBU    (SPR 269) */
2631     spr_set_rights(V_TBU,  SPR_UR | SPR_SR);
2632     /* DSISR  (SPR 18) */
2633     spr_set_rights(DSISR,  SPR_SR | SPR_SW);
2634     /* DAR    (SPR 19) */
2635     spr_set_rights(DAR,    SPR_SR | SPR_SW);
2636     /* DEC    (SPR 22) */
2637     spr_set_rights(DECR,   SPR_SR | SPR_SW);
2638     /* SDR1   (SPR 25) */
2639     spr_set_rights(SDR1,   SPR_SR | SPR_SW);
2640     /* SRR0   (SPR 26) */
2641     spr_set_rights(SRR0,   SPR_SR | SPR_SW);
2642     /* SRR1   (SPR 27) */
2643     spr_set_rights(SRR1,   SPR_SR | SPR_SW);
2644     /* SPRG0  (SPR 272) */
2645     spr_set_rights(SPRG0,  SPR_SR | SPR_SW);
2646     /* SPRG1  (SPR 273) */
2647     spr_set_rights(SPRG1,  SPR_SR | SPR_SW);
2648     /* SPRG2  (SPR 274) */
2649     spr_set_rights(SPRG2,  SPR_SR | SPR_SW);
2650     /* SPRG3  (SPR 275) */
2651     spr_set_rights(SPRG3,  SPR_SR | SPR_SW);
2652     /* ASR    (SPR 280) */
2653     spr_set_rights(ASR,    SPR_SR | SPR_SW);
2654     /* EAR    (SPR 282) */
2655     spr_set_rights(EAR,    SPR_SR | SPR_SW);
2656     /* TBL    (SPR 284) */
2657     spr_set_rights(O_TBL,  SPR_SW);
2658     /* TBU    (SPR 285) */
2659     spr_set_rights(O_TBU,  SPR_SW);
2660     /* PVR    (SPR 287) */
2661     spr_set_rights(PVR,    SPR_SR);
2662     /* IBAT0U (SPR 528) */
2663     spr_set_rights(IBAT0U, SPR_SR | SPR_SW);
2664     /* IBAT0L (SPR 529) */
2665     spr_set_rights(IBAT0L, SPR_SR | SPR_SW);
2666     /* IBAT1U (SPR 530) */
2667     spr_set_rights(IBAT1U, SPR_SR | SPR_SW);
2668     /* IBAT1L (SPR 531) */
2669     spr_set_rights(IBAT1L, SPR_SR | SPR_SW);
2670     /* IBAT2U (SPR 532) */
2671     spr_set_rights(IBAT2U, SPR_SR | SPR_SW);
2672     /* IBAT2L (SPR 533) */
2673     spr_set_rights(IBAT2L, SPR_SR | SPR_SW);
2674     /* IBAT3U (SPR 534) */
2675     spr_set_rights(IBAT3U, SPR_SR | SPR_SW);
2676     /* IBAT3L (SPR 535) */
2677     spr_set_rights(IBAT3L, SPR_SR | SPR_SW);
2678     /* DBAT0U (SPR 536) */
2679     spr_set_rights(DBAT0U, SPR_SR | SPR_SW);
2680     /* DBAT0L (SPR 537) */
2681     spr_set_rights(DBAT0L, SPR_SR | SPR_SW);
2682     /* DBAT1U (SPR 538) */
2683     spr_set_rights(DBAT1U, SPR_SR | SPR_SW);
2684     /* DBAT1L (SPR 539) */
2685     spr_set_rights(DBAT1L, SPR_SR | SPR_SW);
2686     /* DBAT2U (SPR 540) */
2687     spr_set_rights(DBAT2U, SPR_SR | SPR_SW);
2688     /* DBAT2L (SPR 541) */
2689     spr_set_rights(DBAT2L, SPR_SR | SPR_SW);
2690     /* DBAT3U (SPR 542) */
2691     spr_set_rights(DBAT3U, SPR_SR | SPR_SW);
2692     /* DBAT3L (SPR 543) */
2693     spr_set_rights(DBAT3L, SPR_SR | SPR_SW);
2694     /* DABR   (SPR 1013) */
2695     spr_set_rights(DABR,   SPR_SR | SPR_SW);
2696     /* FPECR  (SPR 1022) */
2697     spr_set_rights(FPECR,  SPR_SR | SPR_SW);
2698     /* PIR    (SPR 1023) */
2699     spr_set_rights(PIR,    SPR_SR | SPR_SW);
2700     /* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */
2701     if ((pvr & 0xFFFF0000) == 0x00080000 ||
2702         (pvr & 0xFFFF0000) == 0x70000000) {
2703         /* HID0 */
2704         spr_set_rights(SPR_ENCODE(1008), SPR_SR | SPR_SW);
2705         /* HID1 */
2706         spr_set_rights(SPR_ENCODE(1009), SPR_SR | SPR_SW);
2707         /* IABR */
2708         spr_set_rights(SPR_ENCODE(1010), SPR_SR | SPR_SW);
2709         /* ICTC */
2710         spr_set_rights(SPR_ENCODE(1019), SPR_SR | SPR_SW);
2711         /* L2CR */
2712         spr_set_rights(SPR_ENCODE(1017), SPR_SR | SPR_SW);
2713         /* MMCR0 */
2714         spr_set_rights(SPR_ENCODE(952), SPR_SR | SPR_SW);
2715         /* MMCR1 */
2716         spr_set_rights(SPR_ENCODE(956), SPR_SR | SPR_SW);
2717         /* PMC1 */
2718         spr_set_rights(SPR_ENCODE(953), SPR_SR | SPR_SW);
2719         /* PMC2 */
2720         spr_set_rights(SPR_ENCODE(954), SPR_SR | SPR_SW);
2721         /* PMC3 */
2722         spr_set_rights(SPR_ENCODE(957), SPR_SR | SPR_SW);
2723         /* PMC4 */
2724         spr_set_rights(SPR_ENCODE(958), SPR_SR | SPR_SW);
2725         /* SIA */
2726         spr_set_rights(SPR_ENCODE(955), SPR_SR | SPR_SW);
2727         /* THRM1 */
2728         spr_set_rights(SPR_ENCODE(1020), SPR_SR | SPR_SW);
2729         /* THRM2 */
2730         spr_set_rights(SPR_ENCODE(1021), SPR_SR | SPR_SW);
2731         /* THRM3 */
2732         spr_set_rights(SPR_ENCODE(1022), SPR_SR | SPR_SW);
2733         /* UMMCR0 */
2734         spr_set_rights(SPR_ENCODE(936), SPR_UR | SPR_UW);
2735         /* UMMCR1 */
2736         spr_set_rights(SPR_ENCODE(940), SPR_UR | SPR_UW);
2737         /* UPMC1 */
2738         spr_set_rights(SPR_ENCODE(937), SPR_UR | SPR_UW);
2739         /* UPMC2 */
2740         spr_set_rights(SPR_ENCODE(938), SPR_UR | SPR_UW);
2741         /* UPMC3 */
2742         spr_set_rights(SPR_ENCODE(941), SPR_UR | SPR_UW);
2743         /* UPMC4 */
2744         spr_set_rights(SPR_ENCODE(942), SPR_UR | SPR_UW);
2745         /* USIA */
2746         spr_set_rights(SPR_ENCODE(939), SPR_UR | SPR_UW);
2747     }
2748     /* MPC755 has special registers */
2749     if (pvr == 0x00083100) {
2750         /* SPRG4 */
2751         spr_set_rights(SPRG4, SPR_SR | SPR_SW);
2752         /* SPRG5 */
2753         spr_set_rights(SPRG5, SPR_SR | SPR_SW);
2754         /* SPRG6 */
2755         spr_set_rights(SPRG6, SPR_SR | SPR_SW);
2756         /* SPRG7 */
2757         spr_set_rights(SPRG7, SPR_SR | SPR_SW);
2758         /* IBAT4U */
2759         spr_set_rights(IBAT4U, SPR_SR | SPR_SW);
2760         /* IBAT4L */
2761         spr_set_rights(IBAT4L, SPR_SR | SPR_SW);
2762         /* IBAT5U */
2763         spr_set_rights(IBAT5U, SPR_SR | SPR_SW);
2764         /* IBAT5L */
2765         spr_set_rights(IBAT5L, SPR_SR | SPR_SW);
2766         /* IBAT6U */
2767         spr_set_rights(IBAT6U, SPR_SR | SPR_SW);
2768         /* IBAT6L */
2769         spr_set_rights(IBAT6L, SPR_SR | SPR_SW);
2770         /* IBAT7U */
2771         spr_set_rights(IBAT7U, SPR_SR | SPR_SW);
2772         /* IBAT7L */
2773         spr_set_rights(IBAT7L, SPR_SR | SPR_SW);
2774         /* DBAT4U */
2775         spr_set_rights(DBAT4U, SPR_SR | SPR_SW);
2776         /* DBAT4L */
2777         spr_set_rights(DBAT4L, SPR_SR | SPR_SW);
2778         /* DBAT5U */
2779         spr_set_rights(DBAT5U, SPR_SR | SPR_SW);
2780         /* DBAT5L */
2781         spr_set_rights(DBAT5L, SPR_SR | SPR_SW);
2782         /* DBAT6U */
2783         spr_set_rights(DBAT6U, SPR_SR | SPR_SW);
2784         /* DBAT6L */
2785         spr_set_rights(DBAT6L, SPR_SR | SPR_SW);
2786         /* DBAT7U */
2787         spr_set_rights(DBAT7U, SPR_SR | SPR_SW);
2788         /* DBAT7L */
2789         spr_set_rights(DBAT7L, SPR_SR | SPR_SW);
2790         /* DMISS */
2791         spr_set_rights(SPR_ENCODE(976), SPR_SR | SPR_SW);
2792         /* DCMP */
2793         spr_set_rights(SPR_ENCODE(977), SPR_SR | SPR_SW);
2794         /* DHASH1 */
2795         spr_set_rights(SPR_ENCODE(978), SPR_SR | SPR_SW);
2796         /* DHASH2 */
2797         spr_set_rights(SPR_ENCODE(979), SPR_SR | SPR_SW);
2798         /* IMISS */
2799         spr_set_rights(SPR_ENCODE(980), SPR_SR | SPR_SW);
2800         /* ICMP */
2801         spr_set_rights(SPR_ENCODE(981), SPR_SR | SPR_SW);
2802         /* RPA */
2803         spr_set_rights(SPR_ENCODE(982), SPR_SR | SPR_SW);
2804         /* HID2 */
2805         spr_set_rights(SPR_ENCODE(1011), SPR_SR | SPR_SW);
2806         /* L2PM */
2807         spr_set_rights(SPR_ENCODE(1016), SPR_SR | SPR_SW);
2808     }
2809 }
2810
2811 /*****************************************************************************/
2812 /* PPC "main stream" common instructions (no optional ones) */
2813
2814 typedef struct ppc_proc_t {
2815     int flags;
2816     void *specific;
2817 } ppc_proc_t;
2818
2819 typedef struct ppc_def_t {
2820     unsigned long pvr;
2821     unsigned long pvr_mask;
2822     ppc_proc_t *proc;
2823 } ppc_def_t;
2824
2825 static ppc_proc_t ppc_proc_common = {
2826     .flags    = PPC_COMMON,
2827     .specific = NULL,
2828 };
2829
2830 static ppc_proc_t ppc_proc_G3 = {
2831     .flags    = PPC_750,
2832     .specific = NULL,
2833 };
2834
2835 static ppc_def_t ppc_defs[] =
2836 {
2837     /* MPC740/745/750/755 (G3) */
2838     {
2839         .pvr      = 0x00080000,
2840         .pvr_mask = 0xFFFF0000,
2841         .proc     = &ppc_proc_G3,
2842     },
2843     /* IBM 750FX (G3 embedded) */
2844     {
2845         .pvr      = 0x70000000,
2846         .pvr_mask = 0xFFFF0000,
2847         .proc     = &ppc_proc_G3,
2848     },
2849     /* Fallback (generic PPC) */
2850     {
2851         .pvr      = 0x00000000,
2852         .pvr_mask = 0x00000000,
2853         .proc     = &ppc_proc_common,
2854     },
2855 };
2856
2857 static int create_ppc_proc (opc_handler_t **ppc_opcodes, unsigned long pvr)
2858 {
2859     opcode_t *opc;
2860     int i, flags;
2861
2862     fill_new_table(ppc_opcodes, 0x40);
2863     for (i = 0; ; i++) {
2864         if ((ppc_defs[i].pvr & ppc_defs[i].pvr_mask) ==
2865             (pvr & ppc_defs[i].pvr_mask)) {
2866             flags = ppc_defs[i].proc->flags;
2867             break;
2868         }
2869     }
2870     
2871     for (opc = &opc_start + 1; opc != &opc_end; opc++) {
2872         if ((opc->handler.type & flags) != 0)
2873             if (register_insn(ppc_opcodes, opc) < 0) {
2874                 printf("*** ERROR initializing PPC instruction "
2875                         "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
2876                         opc->opc3);
2877                 return -1;
2878             }
2879     }
2880     fix_opcode_tables(ppc_opcodes);
2881
2882     return 0;
2883 }
2884
2885
2886 /*****************************************************************************/
2887 /* Misc PPC helpers */
2888 FILE *stdout;
2889
2890 void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
2891 {
2892     int i;
2893
2894     fprintf(f, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x "
2895             "MSR=0x%08x\n", env->nip, env->lr, env->ctr,
2896             _load_xer(env), _load_msr(env));
2897         for (i = 0; i < 32; i++) {
2898             if ((i & 7) == 0)
2899             fprintf(f, "GPR%02d:", i);
2900         fprintf(f, " %08x", env->gpr[i]);
2901             if ((i & 7) == 7)
2902             fprintf(f, "\n");
2903         }
2904     fprintf(f, "CR: 0x");
2905         for (i = 0; i < 8; i++)
2906         fprintf(f, "%01x", env->crf[i]);
2907     fprintf(f, "  [");
2908         for (i = 0; i < 8; i++) {
2909             char a = '-';
2910             if (env->crf[i] & 0x08)
2911                 a = 'L';
2912             else if (env->crf[i] & 0x04)
2913                 a = 'G';
2914             else if (env->crf[i] & 0x02)
2915                 a = 'E';
2916         fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
2917         }
2918     fprintf(f, " ] ");
2919     fprintf(f, "TB: 0x%08x %08x\n", env->tb[1], env->tb[0]);
2920         for (i = 0; i < 16; i++) {
2921             if ((i & 3) == 0)
2922             fprintf(f, "FPR%02d:", i);
2923         fprintf(f, " %016llx", *((uint64_t *)&env->fpr[i]));
2924             if ((i & 3) == 3)
2925             fprintf(f, "\n");
2926     }
2927     fprintf(f, "SRR0 0x%08x SRR1 0x%08x DECR=0x%08x excp:0x%08x\n",
2928             env->spr[SRR0], env->spr[SRR1], env->decr, env->exceptions);
2929     fprintf(f, "reservation 0x%08x\n", env->reserve);
2930     fflush(f);
2931 }
2932
2933 #if !defined(CONFIG_USER_ONLY) && defined (USE_OPENFIRMWARE)
2934 int setup_machine (CPUPPCState *env, uint32_t mid);
2935 #endif
2936
2937 CPUPPCState *cpu_ppc_init(void)
2938 {
2939     CPUPPCState *env;
2940
2941     cpu_exec_init();
2942
2943     env = malloc(sizeof(CPUPPCState));
2944     if (!env)
2945         return NULL;
2946     memset(env, 0, sizeof(CPUPPCState));
2947 #if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE)
2948     setup_machine(env, 0);
2949 #else
2950 //    env->spr[PVR] = 0; /* Basic PPC */
2951     env->spr[PVR] = 0x00080100; /* G3 CPU */
2952 //    env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */
2953 //    env->spr[PVR] = 0x00070100; /* IBM 750FX */
2954 #endif
2955     env->decr = 0xFFFFFFFF;
2956     if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0)
2957         return NULL;
2958     init_spr_rights(env->spr[PVR]);
2959     tlb_flush(env, 1);
2960 #if defined (DO_SINGLE_STEP)
2961     /* Single step trace mode */
2962     msr_se = 1;
2963 #endif
2964 #if defined(CONFIG_USER_ONLY)
2965     msr_pr = 1;
2966 #endif
2967     env->access_type = ACCESS_INT;
2968
2969     return env;
2970 }
2971
2972 void cpu_ppc_close(CPUPPCState *env)
2973 {
2974     /* Should also remove all opcode tables... */
2975     free(env);
2976 }
2977
2978 /*****************************************************************************/
2979 void raise_exception_err (int exception_index, int error_code);
2980 int print_insn_powerpc (FILE *out, unsigned long insn, unsigned memaddr,
2981                         int dialect);
2982
2983 int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2984                                     int search_pc)
2985 {
2986     DisasContext ctx;
2987     opc_handler_t **table, *handler;
2988     uint32_t pc_start;
2989     uint16_t *gen_opc_end;
2990     int j, lj = -1;
2991
2992     pc_start = tb->pc;
2993     gen_opc_ptr = gen_opc_buf;
2994     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2995     gen_opparam_ptr = gen_opparam_buf;
2996     ctx.nip = pc_start;
2997     ctx.tb_offset = 0;
2998     ctx.decr_offset = 0;
2999     ctx.tb = tb;
3000     ctx.exception = EXCP_NONE;
3001 #if defined(CONFIG_USER_ONLY)
3002     ctx.mem_idx = 0;
3003 #else
3004     ctx.supervisor = 1 - msr_pr;
3005     ctx.mem_idx = (1 - msr_pr);
3006 #endif
3007 #if defined (DO_SINGLE_STEP)
3008     /* Single step trace mode */
3009     msr_se = 1;
3010 #endif
3011     env->access_type = ACCESS_CODE;
3012     /* Set env in case of segfault during code fetch */
3013     while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
3014         if (search_pc) {
3015             if (loglevel > 0)
3016                 fprintf(logfile, "Search PC...\n");
3017             j = gen_opc_ptr - gen_opc_buf;
3018             if (lj < j) {
3019                 lj++;
3020                 while (lj < j)
3021                     gen_opc_instr_start[lj++] = 0;
3022                 gen_opc_pc[lj] = ctx.nip;
3023                 gen_opc_instr_start[lj] = 1;
3024             }
3025         }
3026 #if defined DEBUG_DISAS
3027         if (loglevel > 0) {
3028             fprintf(logfile, "----------------\n");
3029             fprintf(logfile, "nip=%08x super=%d ir=%d\n",
3030                     ctx.nip, 1 - msr_pr, msr_ir);
3031         }
3032 #endif
3033         ctx.opcode = ldl_code((void *)ctx.nip);
3034 #if defined DEBUG_DISAS
3035         if (loglevel > 0) {
3036             fprintf(logfile, "translate opcode %08x (%02x %02x %02x)\n",
3037                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
3038                     opc3(ctx.opcode));
3039         }
3040 #endif
3041         ctx.nip += 4;
3042         ctx.tb_offset++;
3043         /* Check decrementer exception */
3044         if (++ctx.decr_offset == env->decr + 1)
3045             ctx.exception = EXCP_DECR;
3046         table = ppc_opcodes;
3047         handler = table[opc1(ctx.opcode)];
3048         if (is_indirect_opcode(handler)) {
3049             table = ind_table(handler);
3050             handler = table[opc2(ctx.opcode)];
3051             if (is_indirect_opcode(handler)) {
3052                 table = ind_table(handler);
3053                 handler = table[opc3(ctx.opcode)];
3054             }
3055         }
3056         /* Is opcode *REALLY* valid ? */
3057         if ((ctx.opcode & handler->inval) != 0) {
3058             if (loglevel > 0) {
3059                 if (handler->handler == &gen_invalid) {
3060                     fprintf(logfile, "invalid/unsupported opcode: "
3061                             "%02x -%02x - %02x (%08x) 0x%08x\n",
3062                             opc1(ctx.opcode), opc2(ctx.opcode),
3063                             opc3(ctx.opcode), ctx.opcode, ctx.nip - 4);
3064                 } else {
3065                     fprintf(logfile, "invalid bits: %08x for opcode: "
3066                             "%02x -%02x - %02x (0x%08x) (0x%08x)\n",
3067                             ctx.opcode & handler->inval, opc1(ctx.opcode),
3068                             opc2(ctx.opcode), opc3(ctx.opcode),
3069                             ctx.opcode, ctx.nip - 4);
3070                 }
3071             } else {
3072                 if (handler->handler == &gen_invalid) {
3073                     printf("invalid/unsupported opcode: "
3074                            "%02x -%02x - %02x (%08x) 0x%08x\n",
3075                            opc1(ctx.opcode), opc2(ctx.opcode),
3076                            opc3(ctx.opcode), ctx.opcode, ctx.nip - 4);
3077                 } else {
3078                     printf("invalid bits: %08x for opcode: "
3079                            "%02x -%02x - %02x (0x%08x) (0x%08x)\n",
3080                             ctx.opcode & handler->inval, opc1(ctx.opcode),
3081                             opc2(ctx.opcode), opc3(ctx.opcode),
3082                            ctx.opcode, ctx.nip - 4);
3083             }
3084             }
3085             (*gen_invalid)(&ctx);
3086         } else {
3087             (*(handler->handler))(&ctx);
3088         }
3089         /* Check trace mode exceptions */
3090         if ((msr_be && ctx.exception == EXCP_BRANCH) ||
3091             /* Check in single step trace mode
3092              * we need to stop except if:
3093              * - rfi, trap or syscall
3094              * - first instruction of an exception handler
3095              */
3096             (msr_se && (ctx.nip < 0x100 ||
3097                         ctx.nip > 0xF00 ||
3098                         (ctx.nip & 0xFC) != 0x04) &&
3099              ctx.exception != EXCP_SYSCALL && ctx.exception != EXCP_RFI &&
3100              ctx.exception != EXCP_TRAP)) {
3101 #if !defined(CONFIG_USER_ONLY)
3102             gen_op_queue_exception(EXCP_TRACE);
3103 #endif
3104             if (ctx.exception == EXCP_NONE) {
3105                 ctx.exception = EXCP_TRACE;
3106     }
3107         }
3108         /* if we reach a page boundary, stop generation */
3109         if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
3110             if (ctx.exception == EXCP_NONE) {
3111         gen_op_b((long)ctx.tb, ctx.nip);
3112                 ctx.exception = EXCP_BRANCH;
3113     }
3114     }
3115     }
3116     /* In case of branch, this has already been done *BEFORE* the branch */
3117     if (ctx.exception != EXCP_BRANCH && ctx.exception != EXCP_RFI) {
3118         gen_op_update_tb(ctx.tb_offset);
3119         gen_op_update_decr(ctx.decr_offset);
3120         gen_op_process_exceptions(ctx.nip);
3121     }
3122 #if 1
3123     /* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
3124      *              do bad business and then qemu crashes !
3125      */
3126     gen_op_set_T0(0);
3127 #endif
3128     /* Generate the return instruction */
3129     gen_op_exit_tb();
3130     *gen_opc_ptr = INDEX_op_end;
3131     if (search_pc) {
3132         j = gen_opc_ptr - gen_opc_buf;
3133         lj++;
3134         while (lj <= j)
3135             gen_opc_instr_start[lj++] = 0;
3136         tb->size = 0;
3137 #if 0
3138         if (loglevel > 0) {
3139             page_dump(logfile);
3140         }
3141 #endif
3142     } else {
3143         tb->size = ctx.nip - pc_start;
3144     }
3145     env->access_type = ACCESS_INT;
3146 #ifdef DEBUG_DISAS
3147     if (loglevel > 0) {
3148         fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
3149         cpu_ppc_dump_state(env, logfile, 0);
3150         fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start));
3151 #if defined(CONFIG_USER_ONLY)
3152         disas(logfile, (void *)pc_start, ctx.nip - pc_start, 0, 0);
3153 #endif
3154         fprintf(logfile, "\n");
3155
3156         fprintf(logfile, "OP:\n");
3157         dump_ops(gen_opc_buf, gen_opparam_buf);
3158         fprintf(logfile, "\n");
3159     }
3160 #endif
3161
3162     return 0;
3163 }
3164
3165 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3166 {
3167     return gen_intermediate_code_internal(env, tb, 0);
3168 }
3169
3170 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3171 {
3172     return gen_intermediate_code_internal(env, tb, 1);
3173 }