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