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