PCI irq in sync with new Bochs BIOS
[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     if (SH(ctx->opcode) != 0)
744     gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
745     if (Rc(ctx->opcode) != 0)
746         gen_op_set_Rc0();
747     gen_op_store_T0_gpr(rA(ctx->opcode));
748 }
749 /* srw & srw. */
750 __GEN_LOGICAL2(srw, 0x18, 0x10);
751
752 /***                       Floating-Point arithmetic                       ***/
753 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat)                           \
754 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT)                   \
755 {                                                                             \
756     if (!ctx->fpu_enabled) {                                                  \
757         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
758         return;                                                               \
759     }                                                                         \
760     gen_op_reset_scrfx();                                                     \
761     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
762     gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
763     gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
764     gen_op_f##op();                                                           \
765     if (isfloat) {                                                            \
766         gen_op_frsp();                                                        \
767     }                                                                         \
768     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
769     if (Rc(ctx->opcode))                                                      \
770         gen_op_set_Rc1();                                                     \
771 }
772
773 #define GEN_FLOAT_ACB(name, op2)                                              \
774 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0);                                     \
775 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
776
777 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
778 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
779 {                                                                             \
780     if (!ctx->fpu_enabled) {                                                  \
781         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
782         return;                                                               \
783     }                                                                         \
784     gen_op_reset_scrfx();                                                     \
785     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
786     gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
787     gen_op_f##op();                                                           \
788     if (isfloat) {                                                            \
789         gen_op_frsp();                                                        \
790     }                                                                         \
791     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
792     if (Rc(ctx->opcode))                                                      \
793         gen_op_set_Rc1();                                                     \
794 }
795 #define GEN_FLOAT_AB(name, op2, inval)                                        \
796 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
797 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
798
799 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
800 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
801 {                                                                             \
802     if (!ctx->fpu_enabled) {                                                  \
803         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
804         return;                                                               \
805     }                                                                         \
806     gen_op_reset_scrfx();                                                     \
807     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
808     gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
809     gen_op_f##op();                                                           \
810     if (isfloat) {                                                            \
811         gen_op_frsp();                                                        \
812     }                                                                         \
813     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
814     if (Rc(ctx->opcode))                                                      \
815         gen_op_set_Rc1();                                                     \
816 }
817 #define GEN_FLOAT_AC(name, op2, inval)                                        \
818 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
819 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
820
821 #define GEN_FLOAT_B(name, op2, op3)                                           \
822 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT)                   \
823 {                                                                             \
824     if (!ctx->fpu_enabled) {                                                  \
825         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
826         return;                                                               \
827     }                                                                         \
828     gen_op_reset_scrfx();                                                     \
829     gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
830     gen_op_f##name();                                                         \
831     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
832     if (Rc(ctx->opcode))                                                      \
833         gen_op_set_Rc1();                                                     \
834 }
835
836 #define GEN_FLOAT_BS(name, op1, op2)                                          \
837 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT)                   \
838 {                                                                             \
839     if (!ctx->fpu_enabled) {                                                  \
840         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
841         return;                                                               \
842     }                                                                         \
843     gen_op_reset_scrfx();                                                     \
844     gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
845     gen_op_f##name();                                                         \
846     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
847     if (Rc(ctx->opcode))                                                      \
848         gen_op_set_Rc1();                                                     \
849 }
850
851 /* fadd - fadds */
852 GEN_FLOAT_AB(add, 0x15, 0x000007C0);
853 /* fdiv - fdivs */
854 GEN_FLOAT_AB(div, 0x12, 0x000007C0);
855 /* fmul - fmuls */
856 GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
857
858 /* fres */
859 GEN_FLOAT_BS(res, 0x3B, 0x18);
860
861 /* frsqrte */
862 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
863
864 /* fsel */
865 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0);
866 /* fsub - fsubs */
867 GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
868 /* Optional: */
869 /* fsqrt */
870 GEN_FLOAT_BS(sqrt, 0x3F, 0x16);
871
872 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
873 {
874     if (!ctx->fpu_enabled) {
875         RET_EXCP(ctx, EXCP_NO_FP, 0);
876         return;
877     }
878     gen_op_reset_scrfx();
879     gen_op_load_fpr_FT0(rB(ctx->opcode));
880     gen_op_fsqrt();
881     gen_op_frsp();
882     gen_op_store_FT0_fpr(rD(ctx->opcode));
883     if (Rc(ctx->opcode))
884         gen_op_set_Rc1();
885 }
886
887 /***                     Floating-Point multiply-and-add                   ***/
888 /* fmadd - fmadds */
889 GEN_FLOAT_ACB(madd, 0x1D);
890 /* fmsub - fmsubs */
891 GEN_FLOAT_ACB(msub, 0x1C);
892 /* fnmadd - fnmadds */
893 GEN_FLOAT_ACB(nmadd, 0x1F);
894 /* fnmsub - fnmsubs */
895 GEN_FLOAT_ACB(nmsub, 0x1E);
896
897 /***                     Floating-Point round & convert                    ***/
898 /* fctiw */
899 GEN_FLOAT_B(ctiw, 0x0E, 0x00);
900 /* fctiwz */
901 GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
902 /* frsp */
903 GEN_FLOAT_B(rsp, 0x0C, 0x00);
904
905 /***                         Floating-Point compare                        ***/
906 /* fcmpo */
907 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
908 {
909     if (!ctx->fpu_enabled) {
910         RET_EXCP(ctx, EXCP_NO_FP, 0);
911         return;
912     }
913     gen_op_reset_scrfx();
914     gen_op_load_fpr_FT0(rA(ctx->opcode));
915     gen_op_load_fpr_FT1(rB(ctx->opcode));
916     gen_op_fcmpo();
917     gen_op_store_T0_crf(crfD(ctx->opcode));
918 }
919
920 /* fcmpu */
921 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
922 {
923     if (!ctx->fpu_enabled) {
924         RET_EXCP(ctx, EXCP_NO_FP, 0);
925         return;
926     }
927     gen_op_reset_scrfx();
928     gen_op_load_fpr_FT0(rA(ctx->opcode));
929     gen_op_load_fpr_FT1(rB(ctx->opcode));
930     gen_op_fcmpu();
931     gen_op_store_T0_crf(crfD(ctx->opcode));
932 }
933
934 /***                         Floating-point move                           ***/
935 /* fabs */
936 GEN_FLOAT_B(abs, 0x08, 0x08);
937
938 /* fmr  - fmr. */
939 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
940 {
941     if (!ctx->fpu_enabled) {
942         RET_EXCP(ctx, EXCP_NO_FP, 0);
943         return;
944     }
945     gen_op_reset_scrfx();
946     gen_op_load_fpr_FT0(rB(ctx->opcode));
947     gen_op_store_FT0_fpr(rD(ctx->opcode));
948     if (Rc(ctx->opcode))
949         gen_op_set_Rc1();
950 }
951
952 /* fnabs */
953 GEN_FLOAT_B(nabs, 0x08, 0x04);
954 /* fneg */
955 GEN_FLOAT_B(neg, 0x08, 0x01);
956
957 /***                  Floating-Point status & ctrl register                ***/
958 /* mcrfs */
959 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
960 {
961     if (!ctx->fpu_enabled) {
962         RET_EXCP(ctx, EXCP_NO_FP, 0);
963         return;
964     }
965     gen_op_load_fpscr_T0(crfS(ctx->opcode));
966     gen_op_store_T0_crf(crfD(ctx->opcode));
967     gen_op_clear_fpscr(crfS(ctx->opcode));
968 }
969
970 /* mffs */
971 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
972 {
973     if (!ctx->fpu_enabled) {
974         RET_EXCP(ctx, EXCP_NO_FP, 0);
975         return;
976     }
977     gen_op_load_fpscr();
978     gen_op_store_FT0_fpr(rD(ctx->opcode));
979     if (Rc(ctx->opcode))
980         gen_op_set_Rc1();
981 }
982
983 /* mtfsb0 */
984 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
985 {
986     uint8_t crb;
987     
988     if (!ctx->fpu_enabled) {
989         RET_EXCP(ctx, EXCP_NO_FP, 0);
990         return;
991     }
992     crb = crbD(ctx->opcode) >> 2;
993     gen_op_load_fpscr_T0(crb);
994     gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03)));
995     gen_op_store_T0_fpscr(crb);
996     if (Rc(ctx->opcode))
997         gen_op_set_Rc1();
998 }
999
1000 /* mtfsb1 */
1001 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1002 {
1003     uint8_t crb;
1004     
1005     if (!ctx->fpu_enabled) {
1006         RET_EXCP(ctx, EXCP_NO_FP, 0);
1007         return;
1008     }
1009     crb = crbD(ctx->opcode) >> 2;
1010     gen_op_load_fpscr_T0(crb);
1011     gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1012     gen_op_store_T0_fpscr(crb);
1013     if (Rc(ctx->opcode))
1014         gen_op_set_Rc1();
1015 }
1016
1017 /* mtfsf */
1018 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1019 {
1020     if (!ctx->fpu_enabled) {
1021         RET_EXCP(ctx, EXCP_NO_FP, 0);
1022         return;
1023     }
1024     gen_op_load_fpr_FT0(rB(ctx->opcode));
1025     gen_op_store_fpscr(FM(ctx->opcode));
1026     if (Rc(ctx->opcode))
1027         gen_op_set_Rc1();
1028 }
1029
1030 /* mtfsfi */
1031 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1032 {
1033     if (!ctx->fpu_enabled) {
1034         RET_EXCP(ctx, EXCP_NO_FP, 0);
1035         return;
1036     }
1037     gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1038     if (Rc(ctx->opcode))
1039         gen_op_set_Rc1();
1040 }
1041
1042 /***                             Integer load                              ***/
1043 #if defined(CONFIG_USER_ONLY)
1044 #define op_ldst(name)        gen_op_##name##_raw()
1045 #define OP_LD_TABLE(width)
1046 #define OP_ST_TABLE(width)
1047 #else
1048 #define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1049 #define OP_LD_TABLE(width)                                                    \
1050 static GenOpFunc *gen_op_l##width[] = {                                       \
1051     &gen_op_l##width##_user,                                                  \
1052     &gen_op_l##width##_kernel,                                                \
1053 }
1054 #define OP_ST_TABLE(width)                                                    \
1055 static GenOpFunc *gen_op_st##width[] = {                                      \
1056     &gen_op_st##width##_user,                                                 \
1057     &gen_op_st##width##_kernel,                                               \
1058 }
1059 #endif
1060
1061 #define GEN_LD(width, opc)                                                    \
1062 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)               \
1063 {                                                                             \
1064     uint32_t simm = SIMM(ctx->opcode);                                        \
1065     if (rA(ctx->opcode) == 0) {                                               \
1066         gen_op_set_T0(simm);                                                  \
1067     } else {                                                                  \
1068         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1069         if (simm != 0)                                                        \
1070             gen_op_addi(simm);                                                \
1071     }                                                                         \
1072     op_ldst(l##width);                                                        \
1073     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1074 }
1075
1076 #define GEN_LDU(width, opc)                                                   \
1077 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)            \
1078 {                                                                             \
1079     uint32_t simm = SIMM(ctx->opcode);                                        \
1080     if (rA(ctx->opcode) == 0 ||                                               \
1081         rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1082         RET_INVAL(ctx);                                                       \
1083         return;                                                               \
1084     }                                                                         \
1085     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1086     if (simm != 0)                                                            \
1087         gen_op_addi(simm);                                                    \
1088     op_ldst(l##width);                                                        \
1089     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1090     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1091 }
1092
1093 #define GEN_LDUX(width, opc)                                                  \
1094 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)           \
1095 {                                                                             \
1096     if (rA(ctx->opcode) == 0 ||                                               \
1097         rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1098         RET_INVAL(ctx);                                                       \
1099         return;                                                               \
1100     }                                                                         \
1101     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1102     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1103     gen_op_add();                                                             \
1104     op_ldst(l##width);                                                        \
1105     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1106     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1107 }
1108
1109 #define GEN_LDX(width, opc2, opc3)                                            \
1110 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)           \
1111 {                                                                             \
1112     if (rA(ctx->opcode) == 0) {                                               \
1113         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1114     } else {                                                                  \
1115         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1116         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1117         gen_op_add();                                                         \
1118     }                                                                         \
1119     op_ldst(l##width);                                                        \
1120     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
1121 }
1122
1123 #define GEN_LDS(width, op)                                                    \
1124 OP_LD_TABLE(width);                                                           \
1125 GEN_LD(width, op | 0x20);                                                     \
1126 GEN_LDU(width, op | 0x21);                                                    \
1127 GEN_LDUX(width, op | 0x01);                                                   \
1128 GEN_LDX(width, 0x17, op | 0x00)
1129
1130 /* lbz lbzu lbzux lbzx */
1131 GEN_LDS(bz, 0x02);
1132 /* lha lhau lhaux lhax */
1133 GEN_LDS(ha, 0x0A);
1134 /* lhz lhzu lhzux lhzx */
1135 GEN_LDS(hz, 0x08);
1136 /* lwz lwzu lwzux lwzx */
1137 GEN_LDS(wz, 0x00);
1138
1139 /***                              Integer store                            ***/
1140 #define GEN_ST(width, opc)                                                    \
1141 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)              \
1142 {                                                                             \
1143     uint32_t simm = SIMM(ctx->opcode);                                        \
1144     if (rA(ctx->opcode) == 0) {                                               \
1145         gen_op_set_T0(simm);                                                  \
1146     } else {                                                                  \
1147         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1148         if (simm != 0)                                                        \
1149             gen_op_addi(simm);                                                \
1150     }                                                                         \
1151     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1152     op_ldst(st##width);                                                       \
1153 }
1154
1155 #define GEN_STU(width, opc)                                                   \
1156 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)           \
1157 {                                                                             \
1158     uint32_t simm = SIMM(ctx->opcode);                                        \
1159     if (rA(ctx->opcode) == 0) {                                               \
1160         RET_INVAL(ctx);                                                       \
1161         return;                                                               \
1162     }                                                                         \
1163     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1164     if (simm != 0)                                                            \
1165         gen_op_addi(simm);                                                    \
1166     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1167     op_ldst(st##width);                                                       \
1168     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1169 }
1170
1171 #define GEN_STUX(width, opc)                                                  \
1172 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
1173 {                                                                             \
1174     if (rA(ctx->opcode) == 0) {                                               \
1175         RET_INVAL(ctx);                                                       \
1176         return;                                                               \
1177     }                                                                         \
1178     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1179     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1180     gen_op_add();                                                             \
1181     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1182     op_ldst(st##width);                                                       \
1183     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1184 }
1185
1186 #define GEN_STX(width, opc2, opc3)                                            \
1187 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)          \
1188 {                                                                             \
1189     if (rA(ctx->opcode) == 0) {                                               \
1190         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1191     } else {                                                                  \
1192         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1193         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1194         gen_op_add();                                                         \
1195     }                                                                         \
1196     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
1197     op_ldst(st##width);                                                       \
1198 }
1199
1200 #define GEN_STS(width, op)                                                    \
1201 OP_ST_TABLE(width);                                                           \
1202 GEN_ST(width, op | 0x20);                                                     \
1203 GEN_STU(width, op | 0x21);                                                    \
1204 GEN_STUX(width, op | 0x01);                                                   \
1205 GEN_STX(width, 0x17, op | 0x00)
1206
1207 /* stb stbu stbux stbx */
1208 GEN_STS(b, 0x06);
1209 /* sth sthu sthux sthx */
1210 GEN_STS(h, 0x0C);
1211 /* stw stwu stwux stwx */
1212 GEN_STS(w, 0x04);
1213
1214 /***                Integer load and store with byte reverse               ***/
1215 /* lhbrx */
1216 OP_LD_TABLE(hbr);
1217 GEN_LDX(hbr, 0x16, 0x18);
1218 /* lwbrx */
1219 OP_LD_TABLE(wbr);
1220 GEN_LDX(wbr, 0x16, 0x10);
1221 /* sthbrx */
1222 OP_ST_TABLE(hbr);
1223 GEN_STX(hbr, 0x16, 0x1C);
1224 /* stwbrx */
1225 OP_ST_TABLE(wbr);
1226 GEN_STX(wbr, 0x16, 0x14);
1227
1228 /***                    Integer load and store multiple                    ***/
1229 #if defined(CONFIG_USER_ONLY)
1230 #define op_ldstm(name, reg) gen_op_##name##_raw(reg)
1231 #else
1232 #define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
1233 static GenOpFunc1 *gen_op_lmw[] = {
1234     &gen_op_lmw_user,
1235     &gen_op_lmw_kernel,
1236 };
1237 static GenOpFunc1 *gen_op_stmw[] = {
1238     &gen_op_stmw_user,
1239     &gen_op_stmw_kernel,
1240 };
1241 #endif
1242
1243 /* lmw */
1244 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1245 {
1246     int simm = SIMM(ctx->opcode);
1247
1248     if (rA(ctx->opcode) == 0) {
1249         gen_op_set_T0(simm);
1250     } else {
1251         gen_op_load_gpr_T0(rA(ctx->opcode));
1252         if (simm != 0)
1253             gen_op_addi(simm);
1254     }
1255     op_ldstm(lmw, rD(ctx->opcode));
1256 }
1257
1258 /* stmw */
1259 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1260 {
1261     int simm = SIMM(ctx->opcode);
1262
1263     if (rA(ctx->opcode) == 0) {
1264         gen_op_set_T0(simm);
1265     } else {
1266         gen_op_load_gpr_T0(rA(ctx->opcode));
1267         if (simm != 0)
1268             gen_op_addi(simm);
1269     }
1270     op_ldstm(stmw, rS(ctx->opcode));
1271 }
1272
1273 /***                    Integer load and store strings                     ***/
1274 #if defined(CONFIG_USER_ONLY)
1275 #define op_ldsts(name, start) gen_op_##name##_raw(start)
1276 #define op_ldstsx(name, rd, ra, rb) gen_op_##name##_raw(rd, ra, rb)
1277 #else
1278 #define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
1279 #define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
1280 static GenOpFunc1 *gen_op_lswi[] = {
1281     &gen_op_lswi_user,
1282     &gen_op_lswi_kernel,
1283 };
1284 static GenOpFunc3 *gen_op_lswx[] = {
1285     &gen_op_lswx_user,
1286     &gen_op_lswx_kernel,
1287 };
1288 static GenOpFunc1 *gen_op_stsw[] = {
1289     &gen_op_stsw_user,
1290     &gen_op_stsw_kernel,
1291 };
1292 #endif
1293
1294 /* lswi */
1295 /* PPC32 specification says we must generate an exception if
1296  * rA is in the range of registers to be loaded.
1297  * In an other hand, IBM says this is valid, but rA won't be loaded.
1298  * For now, I'll follow the spec...
1299  */
1300 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
1301 {
1302     int nb = NB(ctx->opcode);
1303     int start = rD(ctx->opcode);
1304     int ra = rA(ctx->opcode);
1305     int nr;
1306
1307     if (nb == 0)
1308         nb = 32;
1309     nr = nb / 4;
1310     if (((start + nr) > 32  && start <= ra && (start + nr - 32) > ra) ||
1311         ((start + nr) <= 32 && start <= ra && (start + nr) > ra)) {
1312         RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
1313         return;
1314     }
1315     if (ra == 0) {
1316         gen_op_set_T0(0);
1317     } else {
1318         gen_op_load_gpr_T0(ra);
1319     }
1320     gen_op_set_T1(nb);
1321     op_ldsts(lswi, start);
1322 }
1323
1324 /* lswx */
1325 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
1326 {
1327     int ra = rA(ctx->opcode);
1328     int rb = rB(ctx->opcode);
1329
1330     if (ra == 0) {
1331         gen_op_load_gpr_T0(rb);
1332         ra = rb;
1333     } else {
1334         gen_op_load_gpr_T0(ra);
1335         gen_op_load_gpr_T1(rb);
1336         gen_op_add();
1337     }
1338     gen_op_load_xer_bc();
1339     op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
1340 }
1341
1342 /* stswi */
1343 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
1344 {
1345     int nb = NB(ctx->opcode);
1346
1347     if (rA(ctx->opcode) == 0) {
1348         gen_op_set_T0(0);
1349     } else {
1350         gen_op_load_gpr_T0(rA(ctx->opcode));
1351     }
1352     if (nb == 0)
1353         nb = 32;
1354     gen_op_set_T1(nb);
1355     op_ldsts(stsw, rS(ctx->opcode));
1356 }
1357
1358 /* stswx */
1359 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
1360 {
1361     int ra = rA(ctx->opcode);
1362
1363     if (ra == 0) {
1364         gen_op_load_gpr_T0(rB(ctx->opcode));
1365         ra = rB(ctx->opcode);
1366     } else {
1367         gen_op_load_gpr_T0(ra);
1368         gen_op_load_gpr_T1(rB(ctx->opcode));
1369         gen_op_add();
1370     }
1371     gen_op_load_xer_bc();
1372     op_ldsts(stsw, rS(ctx->opcode));
1373 }
1374
1375 /***                        Memory synchronisation                         ***/
1376 /* eieio */
1377 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM)
1378 {
1379 }
1380
1381 /* isync */
1382 GEN_HANDLER(isync, 0x13, 0x16, 0xFF, 0x03FF0801, PPC_MEM)
1383 {
1384 }
1385
1386 /* lwarx */
1387 #if defined(CONFIG_USER_ONLY)
1388 #define op_lwarx() gen_op_lwarx_raw()
1389 #define op_stwcx() gen_op_stwcx_raw()
1390 #else
1391 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
1392 static GenOpFunc *gen_op_lwarx[] = {
1393     &gen_op_lwarx_user,
1394     &gen_op_lwarx_kernel,
1395 };
1396 #define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
1397 static GenOpFunc *gen_op_stwcx[] = {
1398     &gen_op_stwcx_user,
1399     &gen_op_stwcx_kernel,
1400 };
1401 #endif
1402
1403 GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_RES)
1404 {
1405     if (rA(ctx->opcode) == 0) {
1406         gen_op_load_gpr_T0(rB(ctx->opcode));
1407     } else {
1408         gen_op_load_gpr_T0(rA(ctx->opcode));
1409         gen_op_load_gpr_T1(rB(ctx->opcode));
1410         gen_op_add();
1411     }
1412     op_lwarx();
1413     gen_op_store_T1_gpr(rD(ctx->opcode));
1414 }
1415
1416 /* stwcx. */
1417 GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
1418 {
1419         if (rA(ctx->opcode) == 0) {
1420             gen_op_load_gpr_T0(rB(ctx->opcode));
1421         } else {
1422             gen_op_load_gpr_T0(rA(ctx->opcode));
1423             gen_op_load_gpr_T1(rB(ctx->opcode));
1424         gen_op_add();
1425         }
1426     gen_op_load_gpr_T1(rS(ctx->opcode));
1427     op_stwcx();
1428 }
1429
1430 /* sync */
1431 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM)
1432 {
1433 }
1434
1435 /***                         Floating-point load                           ***/
1436 #define GEN_LDF(width, opc)                                                   \
1437 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)               \
1438 {                                                                             \
1439     uint32_t simm = SIMM(ctx->opcode);                                        \
1440     if (!ctx->fpu_enabled) {                                                  \
1441         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1442         return;                                                               \
1443     }                                                                         \
1444     if (rA(ctx->opcode) == 0) {                                               \
1445         gen_op_set_T0(simm);                                                  \
1446     } else {                                                                  \
1447         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1448         if (simm != 0)                                                        \
1449             gen_op_addi(simm);                                                \
1450     }                                                                         \
1451     op_ldst(l##width);                                                        \
1452     gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1453 }
1454
1455 #define GEN_LDUF(width, opc)                                                  \
1456 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)            \
1457 {                                                                             \
1458     uint32_t simm = SIMM(ctx->opcode);                                        \
1459     if (!ctx->fpu_enabled) {                                                  \
1460         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1461         return;                                                               \
1462     }                                                                         \
1463     if (rA(ctx->opcode) == 0 ||                                               \
1464         rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1465         RET_INVAL(ctx);                                                       \
1466         return;                                                               \
1467     }                                                                         \
1468     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1469     if (simm != 0)                                                            \
1470         gen_op_addi(simm);                                                    \
1471     op_ldst(l##width);                                                        \
1472     gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1473     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1474 }
1475
1476 #define GEN_LDUXF(width, opc)                                                 \
1477 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)           \
1478 {                                                                             \
1479     if (!ctx->fpu_enabled) {                                                  \
1480         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1481         return;                                                               \
1482     }                                                                         \
1483     if (rA(ctx->opcode) == 0 ||                                               \
1484         rA(ctx->opcode) == rD(ctx->opcode)) {                                 \
1485         RET_INVAL(ctx);                                                       \
1486         return;                                                               \
1487     }                                                                         \
1488     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1489     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1490     gen_op_add();                                                             \
1491     op_ldst(l##width);                                                        \
1492     gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1493     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1494 }
1495
1496 #define GEN_LDXF(width, opc2, opc3)                                           \
1497 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)           \
1498 {                                                                             \
1499     if (!ctx->fpu_enabled) {                                                  \
1500         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1501         return;                                                               \
1502     }                                                                         \
1503     if (rA(ctx->opcode) == 0) {                                               \
1504         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1505     } else {                                                                  \
1506         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1507         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1508         gen_op_add();                                                         \
1509     }                                                                         \
1510     op_ldst(l##width);                                                        \
1511     gen_op_store_FT1_fpr(rD(ctx->opcode));                                    \
1512 }
1513
1514 #define GEN_LDFS(width, op)                                                   \
1515 OP_LD_TABLE(width);                                                           \
1516 GEN_LDF(width, op | 0x20);                                                    \
1517 GEN_LDUF(width, op | 0x21);                                                   \
1518 GEN_LDUXF(width, op | 0x01);                                                  \
1519 GEN_LDXF(width, 0x17, op | 0x00)
1520
1521 /* lfd lfdu lfdux lfdx */
1522 GEN_LDFS(fd, 0x12);
1523 /* lfs lfsu lfsux lfsx */
1524 GEN_LDFS(fs, 0x10);
1525
1526 /***                         Floating-point store                          ***/
1527 #define GEN_STF(width, opc)                                                   \
1528 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)              \
1529 {                                                                             \
1530     uint32_t simm = SIMM(ctx->opcode);                                        \
1531     if (!ctx->fpu_enabled) {                                                  \
1532         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1533         return;                                                               \
1534     }                                                                         \
1535     if (rA(ctx->opcode) == 0) {                                               \
1536         gen_op_set_T0(simm);                                                  \
1537     } else {                                                                  \
1538         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1539         if (simm != 0)                                                        \
1540             gen_op_addi(simm);                                                \
1541     }                                                                         \
1542     gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1543     op_ldst(st##width);                                                       \
1544 }
1545
1546 #define GEN_STUF(width, opc)                                                  \
1547 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)           \
1548 {                                                                             \
1549     uint32_t simm = SIMM(ctx->opcode);                                        \
1550     if (!ctx->fpu_enabled) {                                                  \
1551         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1552         return;                                                               \
1553     }                                                                         \
1554     if (rA(ctx->opcode) == 0) {                                               \
1555         RET_INVAL(ctx);                                                       \
1556         return;                                                               \
1557     }                                                                         \
1558     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1559     if (simm != 0)                                                            \
1560         gen_op_addi(simm);                                                    \
1561     gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1562     op_ldst(st##width);                                                       \
1563     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1564 }
1565
1566 #define GEN_STUXF(width, opc)                                                 \
1567 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER)          \
1568 {                                                                             \
1569     if (!ctx->fpu_enabled) {                                                  \
1570         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1571         return;                                                               \
1572     }                                                                         \
1573     if (rA(ctx->opcode) == 0) {                                               \
1574         RET_INVAL(ctx);                                                       \
1575         return;                                                               \
1576     }                                                                         \
1577     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1578     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1579     gen_op_add();                                                             \
1580     gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1581     op_ldst(st##width);                                                       \
1582     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1583 }
1584
1585 #define GEN_STXF(width, opc2, opc3)                                           \
1586 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER)          \
1587 {                                                                             \
1588     if (!ctx->fpu_enabled) {                                                  \
1589         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
1590         return;                                                               \
1591     }                                                                         \
1592     if (rA(ctx->opcode) == 0) {                                               \
1593         gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
1594     } else {                                                                  \
1595         gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
1596         gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
1597         gen_op_add();                                                         \
1598     }                                                                         \
1599     gen_op_load_fpr_FT1(rS(ctx->opcode));                                     \
1600     op_ldst(st##width);                                                       \
1601 }
1602
1603 #define GEN_STFS(width, op)                                                   \
1604 OP_ST_TABLE(width);                                                           \
1605 GEN_STF(width, op | 0x20);                                                    \
1606 GEN_STUF(width, op | 0x21);                                                   \
1607 GEN_STUXF(width, op | 0x01);                                                  \
1608 GEN_STXF(width, 0x17, op | 0x00)
1609
1610 /* stfd stfdu stfdux stfdx */
1611 GEN_STFS(fd, 0x16);
1612 /* stfs stfsu stfsux stfsx */
1613 GEN_STFS(fs, 0x14);
1614
1615 /* Optional: */
1616 /* stfiwx */
1617 GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1618 {
1619     if (!ctx->fpu_enabled) {
1620         RET_EXCP(ctx, EXCP_NO_FP, 0);
1621         return;
1622     }
1623     RET_INVAL(ctx);
1624 }
1625
1626 /***                                Branch                                 ***/
1627
1628 /* b ba bl bla */
1629 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1630 {
1631     uint32_t li, target;
1632
1633     /* sign extend LI */
1634     li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
1635
1636     if (AA(ctx->opcode) == 0)
1637         target = ctx->nip + li - 4;
1638     else
1639         target = li;
1640     if (LK(ctx->opcode)) {
1641         gen_op_setlr(ctx->nip);
1642     }
1643     gen_op_b((long)ctx->tb, target);
1644     ctx->exception = EXCP_BRANCH;
1645 }
1646
1647 #define BCOND_IM  0
1648 #define BCOND_LR  1
1649 #define BCOND_CTR 2
1650
1651 static inline void gen_bcond(DisasContext *ctx, int type) 
1652 {                                                                             
1653     uint32_t target = 0;
1654     uint32_t bo = BO(ctx->opcode);                                            
1655     uint32_t bi = BI(ctx->opcode);                                            
1656     uint32_t mask;                                                            
1657     uint32_t li;
1658
1659     if ((bo & 0x4) == 0)
1660         gen_op_dec_ctr();                                                     
1661     switch(type) {
1662     case BCOND_IM:
1663         li = (int32_t)((int16_t)(BD(ctx->opcode)));
1664         if (AA(ctx->opcode) == 0) {
1665             target = ctx->nip + li - 4;
1666         } else {
1667             target = li;
1668         }
1669         break;
1670     case BCOND_CTR:
1671         gen_op_movl_T1_ctr();
1672         break;
1673     default:
1674     case BCOND_LR:
1675         gen_op_movl_T1_lr();
1676         break;
1677     }
1678     if (LK(ctx->opcode)) {                                        
1679         gen_op_setlr(ctx->nip);
1680     }
1681     if (bo & 0x10) {
1682         /* No CR condition */                                                 
1683         switch (bo & 0x6) {                                                   
1684         case 0:                                                               
1685             gen_op_test_ctr();
1686             break;
1687         case 2:                                                               
1688             gen_op_test_ctrz();
1689             break;                                                            
1690         default:
1691         case 4:                                                               
1692         case 6:                                                               
1693             if (type == BCOND_IM) {
1694                 gen_op_b((long)ctx->tb, target);
1695             } else {
1696                 gen_op_b_T1();
1697             }
1698             goto no_test;
1699         }
1700     } else {                                                                  
1701         mask = 1 << (3 - (bi & 0x03));                                        
1702         gen_op_load_crf_T0(bi >> 2);                                          
1703         if (bo & 0x8) {                                                       
1704             switch (bo & 0x6) {                                               
1705             case 0:                                                           
1706                 gen_op_test_ctr_true(mask);
1707                 break;                                                        
1708             case 2:                                                           
1709                 gen_op_test_ctrz_true(mask);
1710                 break;                                                        
1711             default:                                                          
1712             case 4:                                                           
1713             case 6:                                                           
1714                 gen_op_test_true(mask);
1715                 break;                                                        
1716             }                                                                 
1717         } else {                                                              
1718             switch (bo & 0x6) {                                               
1719             case 0:                                                           
1720                 gen_op_test_ctr_false(mask);
1721                 break;                                                        
1722             case 2:                                                           
1723                 gen_op_test_ctrz_false(mask);
1724                 break;                                                        
1725             default:
1726             case 4:                                                           
1727             case 6:                                                           
1728                 gen_op_test_false(mask);
1729                 break;                                                        
1730             }                                                                 
1731         }                                                                     
1732     }                                                                         
1733     if (type == BCOND_IM) {
1734         gen_op_btest((long)ctx->tb, target, ctx->nip);
1735     } else {
1736         gen_op_btest_T1(ctx->nip);
1737     }
1738  no_test:
1739     ctx->exception = EXCP_BRANCH;                                             
1740 }
1741
1742 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1743 {                                                                             
1744     gen_bcond(ctx, BCOND_IM);
1745 }
1746
1747 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
1748 {                                                                             
1749     gen_bcond(ctx, BCOND_CTR);
1750 }
1751
1752 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
1753 {                                                                             
1754     gen_bcond(ctx, BCOND_LR);
1755 }
1756
1757 /***                      Condition register logical                       ***/
1758 #define GEN_CRLOGIC(op, opc)                                                  \
1759 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
1760 {                                                                             \
1761     gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
1762     gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
1763     gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
1764     gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
1765     gen_op_##op();                                                            \
1766     gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
1767     gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
1768                      3 - (crbD(ctx->opcode) & 0x03));                         \
1769     gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
1770 }
1771
1772 /* crand */
1773 GEN_CRLOGIC(and, 0x08)
1774 /* crandc */
1775 GEN_CRLOGIC(andc, 0x04)
1776 /* creqv */
1777 GEN_CRLOGIC(eqv, 0x09)
1778 /* crnand */
1779 GEN_CRLOGIC(nand, 0x07)
1780 /* crnor */
1781 GEN_CRLOGIC(nor, 0x01)
1782 /* cror */
1783 GEN_CRLOGIC(or, 0x0E)
1784 /* crorc */
1785 GEN_CRLOGIC(orc, 0x0D)
1786 /* crxor */
1787 GEN_CRLOGIC(xor, 0x06)
1788 /* mcrf */
1789 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
1790 {
1791     gen_op_load_crf_T0(crfS(ctx->opcode));
1792     gen_op_store_T0_crf(crfD(ctx->opcode));
1793 }
1794
1795 /***                           System linkage                              ***/
1796 /* rfi (supervisor only) */
1797 GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
1798 {
1799 #if defined(CONFIG_USER_ONLY)
1800     RET_PRIVOPC(ctx);
1801 #else
1802     /* Restore CPU state */
1803     if (!ctx->supervisor) {
1804         RET_PRIVOPC(ctx);
1805         return;
1806     }
1807     gen_op_rfi();
1808     RET_EXCP(ctx, EXCP_RFI, 0);
1809 #endif
1810 }
1811
1812 /* sc */
1813 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
1814 {
1815 #if defined(CONFIG_USER_ONLY)
1816     RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
1817 #else
1818     RET_EXCP(ctx, EXCP_SYSCALL, 0);
1819 #endif
1820 }
1821
1822 /***                                Trap                                   ***/
1823 /* tw */
1824 GEN_HANDLER(tw, 0x1F, 0x04, 0xFF, 0x00000001, PPC_FLOW)
1825 {
1826     gen_op_load_gpr_T0(rA(ctx->opcode));
1827     gen_op_load_gpr_T1(rB(ctx->opcode));
1828     gen_op_tw(TO(ctx->opcode));
1829 }
1830
1831 /* twi */
1832 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1833 {
1834     gen_op_load_gpr_T0(rA(ctx->opcode));
1835 #if 0
1836     printf("%s: param=0x%04x T0=0x%04x\n", __func__,
1837            SIMM(ctx->opcode), TO(ctx->opcode));
1838 #endif
1839     gen_op_twi(SIMM(ctx->opcode), TO(ctx->opcode));
1840 }
1841
1842 /***                          Processor control                            ***/
1843 static inline int check_spr_access (int spr, int rw, int supervisor)
1844 {
1845     uint32_t rights = spr_access[spr >> 1] >> (4 * (spr & 1));
1846
1847 #if 0
1848     if (spr != LR && spr != CTR) {
1849     if (loglevel > 0) {
1850         fprintf(logfile, "%s reg=%d s=%d rw=%d r=0x%02x 0x%02x\n", __func__,
1851                 SPR_ENCODE(spr), supervisor, rw, rights,
1852                 (rights >> ((2 * supervisor) + rw)) & 1);
1853     } else {
1854         printf("%s reg=%d s=%d rw=%d r=0x%02x 0x%02x\n", __func__,
1855                SPR_ENCODE(spr), supervisor, rw, rights,
1856                (rights >> ((2 * supervisor) + rw)) & 1);
1857     }
1858     }
1859 #endif
1860     if (rights == 0)
1861         return -1;
1862     rights = rights >> (2 * supervisor);
1863     rights = rights >> rw;
1864
1865     return rights & 1;
1866 }
1867
1868 /* mcrxr */
1869 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
1870 {
1871     gen_op_load_xer_cr();
1872     gen_op_store_T0_crf(crfD(ctx->opcode));
1873     gen_op_clear_xer_cr();
1874 }
1875
1876 /* mfcr */
1877 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x001FF801, PPC_MISC)
1878 {
1879     gen_op_load_cr();
1880     gen_op_store_T0_gpr(rD(ctx->opcode));
1881 }
1882
1883 /* mfmsr */
1884 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1885 {
1886 #if defined(CONFIG_USER_ONLY)
1887     RET_PRIVREG(ctx);
1888 #else
1889     if (!ctx->supervisor) {
1890         RET_PRIVREG(ctx);
1891         return;
1892     }
1893     gen_op_load_msr();
1894     gen_op_store_T0_gpr(rD(ctx->opcode));
1895 #endif
1896 }
1897
1898 /* mfspr */
1899 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
1900 {
1901     uint32_t sprn = SPR(ctx->opcode);
1902
1903 #if defined(CONFIG_USER_ONLY)
1904     switch (check_spr_access(sprn, 0, 0))
1905 #else
1906     switch (check_spr_access(sprn, 0, ctx->supervisor))
1907 #endif
1908     {
1909     case -1:
1910         RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
1911         return;
1912     case 0:
1913         RET_PRIVREG(ctx);
1914         return;
1915     default:
1916         break;
1917         }
1918     switch (sprn) {
1919     case XER:
1920         gen_op_load_xer();
1921         break;
1922     case LR:
1923         gen_op_load_lr();
1924         break;
1925     case CTR:
1926         gen_op_load_ctr();
1927         break;
1928     case IBAT0U:
1929         gen_op_load_ibat(0, 0);
1930         break;
1931     case IBAT1U:
1932         gen_op_load_ibat(0, 1);
1933         break;
1934     case IBAT2U:
1935         gen_op_load_ibat(0, 2);
1936         break;
1937     case IBAT3U:
1938         gen_op_load_ibat(0, 3);
1939         break;
1940     case IBAT4U:
1941         gen_op_load_ibat(0, 4);
1942         break;
1943     case IBAT5U:
1944         gen_op_load_ibat(0, 5);
1945         break;
1946     case IBAT6U:
1947         gen_op_load_ibat(0, 6);
1948         break;
1949     case IBAT7U:
1950         gen_op_load_ibat(0, 7);
1951         break;
1952     case IBAT0L:
1953         gen_op_load_ibat(1, 0);
1954         break;
1955     case IBAT1L:
1956         gen_op_load_ibat(1, 1);
1957         break;
1958     case IBAT2L:
1959         gen_op_load_ibat(1, 2);
1960         break;
1961     case IBAT3L:
1962         gen_op_load_ibat(1, 3);
1963         break;
1964     case IBAT4L:
1965         gen_op_load_ibat(1, 4);
1966         break;
1967     case IBAT5L:
1968         gen_op_load_ibat(1, 5);
1969         break;
1970     case IBAT6L:
1971         gen_op_load_ibat(1, 6);
1972         break;
1973     case IBAT7L:
1974         gen_op_load_ibat(1, 7);
1975         break;
1976     case DBAT0U:
1977         gen_op_load_dbat(0, 0);
1978         break;
1979     case DBAT1U:
1980         gen_op_load_dbat(0, 1);
1981         break;
1982     case DBAT2U:
1983         gen_op_load_dbat(0, 2);
1984         break;
1985     case DBAT3U:
1986         gen_op_load_dbat(0, 3);
1987         break;
1988     case DBAT4U:
1989         gen_op_load_dbat(0, 4);
1990         break;
1991     case DBAT5U:
1992         gen_op_load_dbat(0, 5);
1993         break;
1994     case DBAT6U:
1995         gen_op_load_dbat(0, 6);
1996         break;
1997     case DBAT7U:
1998         gen_op_load_dbat(0, 7);
1999         break;
2000     case DBAT0L:
2001         gen_op_load_dbat(1, 0);
2002         break;
2003     case DBAT1L:
2004         gen_op_load_dbat(1, 1);
2005         break;
2006     case DBAT2L:
2007         gen_op_load_dbat(1, 2);
2008         break;
2009     case DBAT3L:
2010         gen_op_load_dbat(1, 3);
2011         break;
2012     case DBAT4L:
2013         gen_op_load_dbat(1, 4);
2014         break;
2015     case DBAT5L:
2016         gen_op_load_dbat(1, 5);
2017         break;
2018     case DBAT6L:
2019         gen_op_load_dbat(1, 6);
2020         break;
2021     case DBAT7L:
2022         gen_op_load_dbat(1, 7);
2023         break;
2024     case SDR1:
2025         gen_op_load_sdr1();
2026         break;
2027     case V_TBL:
2028         gen_op_load_tbl();
2029         break;
2030     case V_TBU:
2031         gen_op_load_tbu();
2032         break;
2033     case DECR:
2034         gen_op_load_decr();
2035         break;
2036     default:
2037         gen_op_load_spr(sprn);
2038         break;
2039     }
2040     gen_op_store_T0_gpr(rD(ctx->opcode));
2041 }
2042
2043 /* mftb */
2044 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC)
2045 {
2046     uint32_t sprn = SPR(ctx->opcode);
2047
2048         /* We need to update the time base before reading it */
2049     switch (sprn) {
2050     case V_TBL:
2051         gen_op_load_tbl();
2052         break;
2053     case V_TBU:
2054         gen_op_load_tbu();
2055         break;
2056     default:
2057         RET_INVAL(ctx);
2058         return;
2059     }
2060     gen_op_store_T0_gpr(rD(ctx->opcode));
2061 }
2062
2063 /* mtcrf */
2064 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00100801, PPC_MISC)
2065 {
2066     gen_op_load_gpr_T0(rS(ctx->opcode));
2067     gen_op_store_cr(CRM(ctx->opcode));
2068 }
2069
2070 /* mtmsr */
2071 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
2072 {
2073 #if defined(CONFIG_USER_ONLY)
2074     RET_PRIVREG(ctx);
2075 #else
2076     if (!ctx->supervisor) {
2077         RET_PRIVREG(ctx);
2078         return;
2079     }
2080     gen_op_load_gpr_T0(rS(ctx->opcode));
2081     gen_op_store_msr();
2082     /* Must stop the translation as machine state (may have) changed */
2083     RET_MTMSR(ctx);
2084 #endif
2085 }
2086
2087 /* mtspr */
2088 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
2089 {
2090     uint32_t sprn = SPR(ctx->opcode);
2091
2092 #if 0
2093     if (loglevel > 0) {
2094         fprintf(logfile, "MTSPR %d src=%d (%d)\n", SPR_ENCODE(sprn),
2095                 rS(ctx->opcode), sprn);
2096     }
2097 #endif
2098 #if defined(CONFIG_USER_ONLY)
2099     switch (check_spr_access(sprn, 1, 0))
2100 #else
2101     switch (check_spr_access(sprn, 1, ctx->supervisor))
2102 #endif
2103     {
2104     case -1:
2105         RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2106         break;
2107     case 0:
2108         RET_PRIVREG(ctx);
2109         break;
2110     default:
2111         break;
2112     }
2113     gen_op_load_gpr_T0(rS(ctx->opcode));
2114     switch (sprn) {
2115     case XER:
2116         gen_op_store_xer();
2117         break;
2118     case LR:
2119         gen_op_store_lr();
2120         break;
2121     case CTR:
2122         gen_op_store_ctr();
2123         break;
2124     case IBAT0U:
2125         gen_op_store_ibat(0, 0);
2126         RET_MTMSR(ctx);
2127         break;
2128     case IBAT1U:
2129         gen_op_store_ibat(0, 1);
2130         RET_MTMSR(ctx);
2131         break;
2132     case IBAT2U:
2133         gen_op_store_ibat(0, 2);
2134         RET_MTMSR(ctx);
2135         break;
2136     case IBAT3U:
2137         gen_op_store_ibat(0, 3);
2138         RET_MTMSR(ctx);
2139         break;
2140     case IBAT4U:
2141         gen_op_store_ibat(0, 4);
2142         RET_MTMSR(ctx);
2143         break;
2144     case IBAT5U:
2145         gen_op_store_ibat(0, 5);
2146         RET_MTMSR(ctx);
2147         break;
2148     case IBAT6U:
2149         gen_op_store_ibat(0, 6);
2150         RET_MTMSR(ctx);
2151         break;
2152     case IBAT7U:
2153         gen_op_store_ibat(0, 7);
2154         RET_MTMSR(ctx);
2155         break;
2156     case IBAT0L:
2157         gen_op_store_ibat(1, 0);
2158         RET_MTMSR(ctx);
2159         break;
2160     case IBAT1L:
2161         gen_op_store_ibat(1, 1);
2162         RET_MTMSR(ctx);
2163         break;
2164     case IBAT2L:
2165         gen_op_store_ibat(1, 2);
2166         RET_MTMSR(ctx);
2167         break;
2168     case IBAT3L:
2169         gen_op_store_ibat(1, 3);
2170         RET_MTMSR(ctx);
2171         break;
2172     case IBAT4L:
2173         gen_op_store_ibat(1, 4);
2174         RET_MTMSR(ctx);
2175         break;
2176     case IBAT5L:
2177         gen_op_store_ibat(1, 5);
2178         RET_MTMSR(ctx);
2179         break;
2180     case IBAT6L:
2181         gen_op_store_ibat(1, 6);
2182         RET_MTMSR(ctx);
2183         break;
2184     case IBAT7L:
2185         gen_op_store_ibat(1, 7);
2186         RET_MTMSR(ctx);
2187         break;
2188     case DBAT0U:
2189         gen_op_store_dbat(0, 0);
2190         RET_MTMSR(ctx);
2191         break;
2192     case DBAT1U:
2193         gen_op_store_dbat(0, 1);
2194         RET_MTMSR(ctx);
2195         break;
2196     case DBAT2U:
2197         gen_op_store_dbat(0, 2);
2198         RET_MTMSR(ctx);
2199         break;
2200     case DBAT3U:
2201         gen_op_store_dbat(0, 3);
2202         RET_MTMSR(ctx);
2203         break;
2204     case DBAT4U:
2205         gen_op_store_dbat(0, 4);
2206         RET_MTMSR(ctx);
2207         break;
2208     case DBAT5U:
2209         gen_op_store_dbat(0, 5);
2210         RET_MTMSR(ctx);
2211         break;
2212     case DBAT6U:
2213         gen_op_store_dbat(0, 6);
2214         RET_MTMSR(ctx);
2215         break;
2216     case DBAT7U:
2217         gen_op_store_dbat(0, 7);
2218         RET_MTMSR(ctx);
2219         break;
2220     case DBAT0L:
2221         gen_op_store_dbat(1, 0);
2222         RET_MTMSR(ctx);
2223         break;
2224     case DBAT1L:
2225         gen_op_store_dbat(1, 1);
2226         RET_MTMSR(ctx);
2227         break;
2228     case DBAT2L:
2229         gen_op_store_dbat(1, 2);
2230         RET_MTMSR(ctx);
2231         break;
2232     case DBAT3L:
2233         gen_op_store_dbat(1, 3);
2234         RET_MTMSR(ctx);
2235         break;
2236     case DBAT4L:
2237         gen_op_store_dbat(1, 4);
2238         RET_MTMSR(ctx);
2239         break;
2240     case DBAT5L:
2241         gen_op_store_dbat(1, 5);
2242         RET_MTMSR(ctx);
2243         break;
2244     case DBAT6L:
2245         gen_op_store_dbat(1, 6);
2246         RET_MTMSR(ctx);
2247         break;
2248     case DBAT7L:
2249         gen_op_store_dbat(1, 7);
2250         RET_MTMSR(ctx);
2251         break;
2252     case SDR1:
2253         gen_op_store_sdr1();
2254         RET_MTMSR(ctx);
2255         break;
2256     case O_TBL:
2257         gen_op_store_tbl();
2258         break;
2259     case O_TBU:
2260         gen_op_store_tbu();
2261         break;
2262     case DECR:
2263         gen_op_store_decr();
2264         break;
2265     default:
2266         gen_op_store_spr(sprn);
2267         break;
2268     }
2269 }
2270
2271 /***                         Cache management                              ***/
2272 /* For now, all those will be implemented as nop:
2273  * this is valid, regarding the PowerPC specs...
2274  * We just have to flush tb while invalidating instruction cache lines...
2275  */
2276 /* dcbf */
2277 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
2278 {
2279     if (rA(ctx->opcode) == 0) {
2280         gen_op_load_gpr_T0(rB(ctx->opcode));
2281     } else {
2282         gen_op_load_gpr_T0(rA(ctx->opcode));
2283         gen_op_load_gpr_T1(rB(ctx->opcode));
2284         gen_op_add();
2285     }
2286     op_ldst(lbz);
2287 }
2288
2289 /* dcbi (Supervisor only) */
2290 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
2291 {
2292 #if defined(CONFIG_USER_ONLY)
2293     RET_PRIVOPC(ctx);
2294 #else
2295     if (!ctx->supervisor) {
2296         RET_PRIVOPC(ctx);
2297         return;
2298     }
2299     if (rA(ctx->opcode) == 0) {
2300         gen_op_load_gpr_T0(rB(ctx->opcode));
2301     } else {
2302         gen_op_load_gpr_T0(rA(ctx->opcode));
2303         gen_op_load_gpr_T1(rB(ctx->opcode));
2304         gen_op_add();
2305     }
2306     op_ldst(lbz);
2307     op_ldst(stb);
2308 #endif
2309 }
2310
2311 /* dcdst */
2312 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
2313 {
2314     if (rA(ctx->opcode) == 0) {
2315         gen_op_load_gpr_T0(rB(ctx->opcode));
2316     } else {
2317         gen_op_load_gpr_T0(rA(ctx->opcode));
2318         gen_op_load_gpr_T1(rB(ctx->opcode));
2319         gen_op_add();
2320     }
2321     op_ldst(lbz);
2322 }
2323
2324 /* dcbt */
2325 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
2326 {
2327 }
2328
2329 /* dcbtst */
2330 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
2331 {
2332 }
2333
2334 /* dcbz */
2335 #if defined(CONFIG_USER_ONLY)
2336 #define op_dcbz() gen_op_dcbz_raw()
2337 #else
2338 #define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
2339 static GenOpFunc *gen_op_dcbz[] = {
2340     &gen_op_dcbz_user,
2341     &gen_op_dcbz_kernel,
2342 };
2343 #endif
2344
2345 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
2346 {
2347     if (rA(ctx->opcode) == 0) {
2348         gen_op_load_gpr_T0(rB(ctx->opcode));
2349     } else {
2350         gen_op_load_gpr_T0(rA(ctx->opcode));
2351         gen_op_load_gpr_T1(rB(ctx->opcode));
2352         gen_op_add();
2353     }
2354     op_dcbz();
2355     gen_op_check_reservation();
2356 }
2357
2358 /* icbi */
2359 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
2360 {
2361     if (rA(ctx->opcode) == 0) {
2362         gen_op_load_gpr_T0(rB(ctx->opcode));
2363     } else {
2364         gen_op_load_gpr_T0(rA(ctx->opcode));
2365         gen_op_load_gpr_T1(rB(ctx->opcode));
2366         gen_op_add();
2367     }
2368     gen_op_icbi();
2369 }
2370
2371 /* Optional: */
2372 /* dcba */
2373 GEN_HANDLER(dcba, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE_OPT)
2374 {
2375 }
2376
2377 /***                    Segment register manipulation                      ***/
2378 /* Supervisor only: */
2379 /* mfsr */
2380 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
2381 {
2382 #if defined(CONFIG_USER_ONLY)
2383     RET_PRIVREG(ctx);
2384 #else
2385     if (!ctx->supervisor) {
2386         RET_PRIVREG(ctx);
2387         return;
2388     }
2389     gen_op_load_sr(SR(ctx->opcode));
2390     gen_op_store_T0_gpr(rD(ctx->opcode));
2391 #endif
2392 }
2393
2394 /* mfsrin */
2395 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
2396 {
2397 #if defined(CONFIG_USER_ONLY)
2398     RET_PRIVREG(ctx);
2399 #else
2400     if (!ctx->supervisor) {
2401         RET_PRIVREG(ctx);
2402         return;
2403     }
2404     gen_op_load_gpr_T1(rB(ctx->opcode));
2405     gen_op_load_srin();
2406     gen_op_store_T0_gpr(rD(ctx->opcode));
2407 #endif
2408 }
2409
2410 /* mtsr */
2411 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
2412 {
2413 #if defined(CONFIG_USER_ONLY)
2414     RET_PRIVREG(ctx);
2415 #else
2416     if (!ctx->supervisor) {
2417         RET_PRIVREG(ctx);
2418         return;
2419     }
2420     gen_op_load_gpr_T0(rS(ctx->opcode));
2421     gen_op_store_sr(SR(ctx->opcode));
2422 #endif
2423 }
2424
2425 /* mtsrin */
2426 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
2427 {
2428 #if defined(CONFIG_USER_ONLY)
2429     RET_PRIVREG(ctx);
2430 #else
2431     if (!ctx->supervisor) {
2432         RET_PRIVREG(ctx);
2433         return;
2434     }
2435     gen_op_load_gpr_T0(rS(ctx->opcode));
2436     gen_op_load_gpr_T1(rB(ctx->opcode));
2437     gen_op_store_srin();
2438 #endif
2439 }
2440
2441 /***                      Lookaside buffer management                      ***/
2442 /* Optional & supervisor only: */
2443 /* tlbia */
2444 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT)
2445 {
2446 #if defined(CONFIG_USER_ONLY)
2447     RET_PRIVOPC(ctx);
2448 #else
2449     if (!ctx->supervisor) {
2450         if (loglevel)
2451             fprintf(logfile, "%s: ! supervisor\n", __func__);
2452         RET_PRIVOPC(ctx);
2453         return;
2454     }
2455     gen_op_tlbia();
2456     RET_MTMSR(ctx);
2457 #endif
2458 }
2459
2460 /* tlbie */
2461 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM)
2462 {
2463 #if defined(CONFIG_USER_ONLY)
2464     RET_PRIVOPC(ctx);
2465 #else
2466     if (!ctx->supervisor) {
2467         RET_PRIVOPC(ctx);
2468         return;
2469     }
2470     gen_op_load_gpr_T0(rB(ctx->opcode));
2471     gen_op_tlbie();
2472     RET_MTMSR(ctx);
2473 #endif
2474 }
2475
2476 /* tlbsync */
2477 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM)
2478 {
2479 #if defined(CONFIG_USER_ONLY)
2480     RET_PRIVOPC(ctx);
2481 #else
2482     if (!ctx->supervisor) {
2483         RET_PRIVOPC(ctx);
2484         return;
2485     }
2486     /* This has no effect: it should ensure that all previous
2487      * tlbie have completed
2488      */
2489     RET_MTMSR(ctx);
2490 #endif
2491 }
2492
2493 /***                              External control                         ***/
2494 /* Optional: */
2495 /* eciwx */
2496 #if defined(CONFIG_USER_ONLY)
2497 #define op_eciwx() gen_op_eciwx_raw()
2498 #define op_ecowx() gen_op_ecowx_raw()
2499 #else
2500 #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
2501 #define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
2502 static GenOpFunc *gen_op_eciwx[] = {
2503     &gen_op_eciwx_user,
2504     &gen_op_eciwx_kernel,
2505 };
2506 static GenOpFunc *gen_op_ecowx[] = {
2507     &gen_op_ecowx_user,
2508     &gen_op_ecowx_kernel,
2509 };
2510 #endif
2511
2512 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
2513 {
2514     /* Should check EAR[E] & alignment ! */
2515     if (rA(ctx->opcode) == 0) {
2516         gen_op_load_gpr_T0(rB(ctx->opcode));
2517     } else {
2518         gen_op_load_gpr_T0(rA(ctx->opcode));
2519         gen_op_load_gpr_T1(rB(ctx->opcode));
2520         gen_op_add();
2521     }
2522     op_eciwx();
2523     gen_op_store_T0_gpr(rD(ctx->opcode));
2524 }
2525
2526 /* ecowx */
2527 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
2528 {
2529     /* Should check EAR[E] & alignment ! */
2530     if (rA(ctx->opcode) == 0) {
2531         gen_op_load_gpr_T0(rB(ctx->opcode));
2532     } else {
2533         gen_op_load_gpr_T0(rA(ctx->opcode));
2534         gen_op_load_gpr_T1(rB(ctx->opcode));
2535         gen_op_add();
2536     }
2537     gen_op_load_gpr_T2(rS(ctx->opcode));
2538     op_ecowx();
2539 }
2540
2541 /* End opcode list */
2542 GEN_OPCODE_MARK(end);
2543
2544 /*****************************************************************************/
2545 #include <stdlib.h>
2546 #include <string.h>
2547
2548 int fflush (FILE *stream);
2549
2550 /* Main ppc opcodes table:
2551  * at init, all opcodes are invalids
2552  */
2553 static opc_handler_t *ppc_opcodes[0x40];
2554
2555 /* Opcode types */
2556 enum {
2557     PPC_DIRECT   = 0, /* Opcode routine        */
2558     PPC_INDIRECT = 1, /* Indirect opcode table */
2559 };
2560
2561 static inline int is_indirect_opcode (void *handler)
2562 {
2563     return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
2564 }
2565
2566 static inline opc_handler_t **ind_table(void *handler)
2567 {
2568     return (opc_handler_t **)((unsigned long)handler & ~3);
2569 }
2570
2571 /* Instruction table creation */
2572 /* Opcodes tables creation */
2573 static void fill_new_table (opc_handler_t **table, int len)
2574 {
2575     int i;
2576
2577     for (i = 0; i < len; i++)
2578         table[i] = &invalid_handler;
2579 }
2580
2581 static int create_new_table (opc_handler_t **table, unsigned char idx)
2582 {
2583     opc_handler_t **tmp;
2584
2585     tmp = malloc(0x20 * sizeof(opc_handler_t));
2586     if (tmp == NULL)
2587         return -1;
2588     fill_new_table(tmp, 0x20);
2589     table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
2590
2591     return 0;
2592 }
2593
2594 static int insert_in_table (opc_handler_t **table, unsigned char idx,
2595                             opc_handler_t *handler)
2596 {
2597     if (table[idx] != &invalid_handler)
2598         return -1;
2599     table[idx] = handler;
2600
2601     return 0;
2602 }
2603
2604 static int register_direct_insn (opc_handler_t **ppc_opcodes,
2605                                  unsigned char idx, opc_handler_t *handler)
2606 {
2607     if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
2608         printf("*** ERROR: opcode %02x already assigned in main "
2609                 "opcode table\n", idx);
2610         return -1;
2611     }
2612
2613     return 0;
2614 }
2615
2616 static int register_ind_in_table (opc_handler_t **table,
2617                                   unsigned char idx1, unsigned char idx2,
2618                                   opc_handler_t *handler)
2619 {
2620     if (table[idx1] == &invalid_handler) {
2621         if (create_new_table(table, idx1) < 0) {
2622             printf("*** ERROR: unable to create indirect table "
2623                     "idx=%02x\n", idx1);
2624             return -1;
2625         }
2626     } else {
2627         if (!is_indirect_opcode(table[idx1])) {
2628             printf("*** ERROR: idx %02x already assigned to a direct "
2629                     "opcode\n", idx1);
2630             return -1;
2631         }
2632     }
2633     if (handler != NULL &&
2634         insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
2635         printf("*** ERROR: opcode %02x already assigned in "
2636                 "opcode table %02x\n", idx2, idx1);
2637         return -1;
2638     }
2639
2640     return 0;
2641 }
2642
2643 static int register_ind_insn (opc_handler_t **ppc_opcodes,
2644                               unsigned char idx1, unsigned char idx2,
2645                                opc_handler_t *handler)
2646 {
2647     int ret;
2648
2649     ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
2650
2651     return ret;
2652 }
2653
2654 static int register_dblind_insn (opc_handler_t **ppc_opcodes, 
2655                                  unsigned char idx1, unsigned char idx2,
2656                                   unsigned char idx3, opc_handler_t *handler)
2657 {
2658     if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
2659         printf("*** ERROR: unable to join indirect table idx "
2660                 "[%02x-%02x]\n", idx1, idx2);
2661         return -1;
2662     }
2663     if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
2664                               handler) < 0) {
2665         printf("*** ERROR: unable to insert opcode "
2666                 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
2667         return -1;
2668     }
2669
2670     return 0;
2671 }
2672
2673 static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
2674 {
2675     if (insn->opc2 != 0xFF) {
2676         if (insn->opc3 != 0xFF) {
2677             if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
2678                                      insn->opc3, &insn->handler) < 0)
2679                 return -1;
2680         } else {
2681             if (register_ind_insn(ppc_opcodes, insn->opc1,
2682                                   insn->opc2, &insn->handler) < 0)
2683                 return -1;
2684         }
2685     } else {
2686         if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
2687             return -1;
2688     }
2689
2690     return 0;
2691 }
2692
2693 static int test_opcode_table (opc_handler_t **table, int len)
2694 {
2695     int i, count, tmp;
2696
2697     for (i = 0, count = 0; i < len; i++) {
2698         /* Consistency fixup */
2699         if (table[i] == NULL)
2700             table[i] = &invalid_handler;
2701         if (table[i] != &invalid_handler) {
2702             if (is_indirect_opcode(table[i])) {
2703                 tmp = test_opcode_table(ind_table(table[i]), 0x20);
2704                 if (tmp == 0) {
2705                     free(table[i]);
2706                     table[i] = &invalid_handler;
2707                 } else {
2708                     count++;
2709                 }
2710             } else {
2711                 count++;
2712             }
2713         }
2714     }
2715
2716     return count;
2717 }
2718
2719 static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
2720 {
2721     if (test_opcode_table(ppc_opcodes, 0x40) == 0)
2722         printf("*** WARNING: no opcode defined !\n");
2723 }
2724
2725 #define SPR_RIGHTS(rw, priv) (1 << ((2 * (priv)) + (rw)))
2726 #define SPR_UR SPR_RIGHTS(0, 0)
2727 #define SPR_UW SPR_RIGHTS(1, 0)
2728 #define SPR_SR SPR_RIGHTS(0, 1)
2729 #define SPR_SW SPR_RIGHTS(1, 1)
2730
2731 #define spr_set_rights(spr, rights)                            \
2732 do {                                                           \
2733     spr_access[(spr) >> 1] |= ((rights) << (4 * ((spr) & 1))); \
2734 } while (0)
2735
2736 static void init_spr_rights (uint32_t pvr)
2737 {
2738     /* XER    (SPR 1) */
2739     spr_set_rights(XER,    SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2740     /* LR     (SPR 8) */
2741     spr_set_rights(LR,     SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2742     /* CTR    (SPR 9) */
2743     spr_set_rights(CTR,    SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2744     /* TBL    (SPR 268) */
2745     spr_set_rights(V_TBL,  SPR_UR | SPR_SR);
2746     /* TBU    (SPR 269) */
2747     spr_set_rights(V_TBU,  SPR_UR | SPR_SR);
2748     /* DSISR  (SPR 18) */
2749     spr_set_rights(DSISR,  SPR_SR | SPR_SW);
2750     /* DAR    (SPR 19) */
2751     spr_set_rights(DAR,    SPR_SR | SPR_SW);
2752     /* DEC    (SPR 22) */
2753     spr_set_rights(DECR,   SPR_SR | SPR_SW);
2754     /* SDR1   (SPR 25) */
2755     spr_set_rights(SDR1,   SPR_SR | SPR_SW);
2756     /* SRR0   (SPR 26) */
2757     spr_set_rights(SRR0,   SPR_SR | SPR_SW);
2758     /* SRR1   (SPR 27) */
2759     spr_set_rights(SRR1,   SPR_SR | SPR_SW);
2760     /* SPRG0  (SPR 272) */
2761     spr_set_rights(SPRG0,  SPR_SR | SPR_SW);
2762     /* SPRG1  (SPR 273) */
2763     spr_set_rights(SPRG1,  SPR_SR | SPR_SW);
2764     /* SPRG2  (SPR 274) */
2765     spr_set_rights(SPRG2,  SPR_SR | SPR_SW);
2766     /* SPRG3  (SPR 275) */
2767     spr_set_rights(SPRG3,  SPR_SR | SPR_SW);
2768     /* ASR    (SPR 280) */
2769     spr_set_rights(ASR,    SPR_SR | SPR_SW);
2770     /* EAR    (SPR 282) */
2771     spr_set_rights(EAR,    SPR_SR | SPR_SW);
2772     /* TBL    (SPR 284) */
2773     spr_set_rights(O_TBL,  SPR_SW);
2774     /* TBU    (SPR 285) */
2775     spr_set_rights(O_TBU,  SPR_SW);
2776     /* PVR    (SPR 287) */
2777     spr_set_rights(PVR,    SPR_SR);
2778     /* IBAT0U (SPR 528) */
2779     spr_set_rights(IBAT0U, SPR_SR | SPR_SW);
2780     /* IBAT0L (SPR 529) */
2781     spr_set_rights(IBAT0L, SPR_SR | SPR_SW);
2782     /* IBAT1U (SPR 530) */
2783     spr_set_rights(IBAT1U, SPR_SR | SPR_SW);
2784     /* IBAT1L (SPR 531) */
2785     spr_set_rights(IBAT1L, SPR_SR | SPR_SW);
2786     /* IBAT2U (SPR 532) */
2787     spr_set_rights(IBAT2U, SPR_SR | SPR_SW);
2788     /* IBAT2L (SPR 533) */
2789     spr_set_rights(IBAT2L, SPR_SR | SPR_SW);
2790     /* IBAT3U (SPR 534) */
2791     spr_set_rights(IBAT3U, SPR_SR | SPR_SW);
2792     /* IBAT3L (SPR 535) */
2793     spr_set_rights(IBAT3L, SPR_SR | SPR_SW);
2794     /* DBAT0U (SPR 536) */
2795     spr_set_rights(DBAT0U, SPR_SR | SPR_SW);
2796     /* DBAT0L (SPR 537) */
2797     spr_set_rights(DBAT0L, SPR_SR | SPR_SW);
2798     /* DBAT1U (SPR 538) */
2799     spr_set_rights(DBAT1U, SPR_SR | SPR_SW);
2800     /* DBAT1L (SPR 539) */
2801     spr_set_rights(DBAT1L, SPR_SR | SPR_SW);
2802     /* DBAT2U (SPR 540) */
2803     spr_set_rights(DBAT2U, SPR_SR | SPR_SW);
2804     /* DBAT2L (SPR 541) */
2805     spr_set_rights(DBAT2L, SPR_SR | SPR_SW);
2806     /* DBAT3U (SPR 542) */
2807     spr_set_rights(DBAT3U, SPR_SR | SPR_SW);
2808     /* DBAT3L (SPR 543) */
2809     spr_set_rights(DBAT3L, SPR_SR | SPR_SW);
2810     /* FPECR  (SPR 1022) */
2811     spr_set_rights(FPECR,  SPR_SR | SPR_SW);
2812     /* Special registers for PPC 604 */
2813     if ((pvr & 0xFFFF0000) == 0x00040000) {
2814         /* IABR */
2815         spr_set_rights(IABR ,  SPR_SR | SPR_SW);
2816         /* DABR   (SPR 1013) */
2817         spr_set_rights(DABR,   SPR_SR | SPR_SW);
2818         /* HID0 */
2819         spr_set_rights(HID0,   SPR_SR | SPR_SW);
2820         /* PIR */
2821     spr_set_rights(PIR,    SPR_SR | SPR_SW);
2822         /* PMC1 */
2823         spr_set_rights(PMC1,   SPR_SR | SPR_SW);
2824         /* PMC2 */
2825         spr_set_rights(PMC2,   SPR_SR | SPR_SW);
2826         /* MMCR0 */
2827         spr_set_rights(MMCR0,  SPR_SR | SPR_SW);
2828         /* SIA */
2829         spr_set_rights(SIA,    SPR_SR | SPR_SW);
2830         /* SDA */
2831         spr_set_rights(SDA,    SPR_SR | SPR_SW);
2832     }
2833     /* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */
2834     if ((pvr & 0xFFFF0000) == 0x00080000 ||
2835         (pvr & 0xFFFF0000) == 0x70000000) {
2836         /* HID0 */
2837         spr_set_rights(HID0,   SPR_SR | SPR_SW);
2838         /* HID1 */
2839         spr_set_rights(HID1,   SPR_SR | SPR_SW);
2840         /* IABR */
2841         spr_set_rights(IABR,   SPR_SR | SPR_SW);
2842         /* ICTC */
2843         spr_set_rights(ICTC,   SPR_SR | SPR_SW);
2844         /* L2CR */
2845         spr_set_rights(L2CR,   SPR_SR | SPR_SW);
2846         /* MMCR0 */
2847         spr_set_rights(MMCR0,  SPR_SR | SPR_SW);
2848         /* MMCR1 */
2849         spr_set_rights(MMCR1,  SPR_SR | SPR_SW);
2850         /* PMC1 */
2851         spr_set_rights(PMC1,   SPR_SR | SPR_SW);
2852         /* PMC2 */
2853         spr_set_rights(PMC2,   SPR_SR | SPR_SW);
2854         /* PMC3 */
2855         spr_set_rights(PMC3,   SPR_SR | SPR_SW);
2856         /* PMC4 */
2857         spr_set_rights(PMC4,   SPR_SR | SPR_SW);
2858         /* SIA */
2859         spr_set_rights(SIA,    SPR_SR | SPR_SW);
2860         /* SDA */
2861         spr_set_rights(SDA,    SPR_SR | SPR_SW);
2862         /* THRM1 */
2863         spr_set_rights(THRM1,  SPR_SR | SPR_SW);
2864         /* THRM2 */
2865         spr_set_rights(THRM2,  SPR_SR | SPR_SW);
2866         /* THRM3 */
2867         spr_set_rights(THRM3,  SPR_SR | SPR_SW);
2868         /* UMMCR0 */
2869         spr_set_rights(UMMCR0, SPR_UR | SPR_UW);
2870         /* UMMCR1 */
2871         spr_set_rights(UMMCR1, SPR_UR | SPR_UW);
2872         /* UPMC1 */
2873         spr_set_rights(UPMC1,  SPR_UR | SPR_UW);
2874         /* UPMC2 */
2875         spr_set_rights(UPMC2,  SPR_UR | SPR_UW);
2876         /* UPMC3 */
2877         spr_set_rights(UPMC3,  SPR_UR | SPR_UW);
2878         /* UPMC4 */
2879         spr_set_rights(UPMC4,  SPR_UR | SPR_UW);
2880         /* USIA */
2881         spr_set_rights(USIA,   SPR_UR | SPR_UW);
2882     }
2883     /* MPC755 has special registers */
2884     if (pvr == 0x00083100) {
2885         /* SPRG4 */
2886         spr_set_rights(SPRG4, SPR_SR | SPR_SW);
2887         /* SPRG5 */
2888         spr_set_rights(SPRG5, SPR_SR | SPR_SW);
2889         /* SPRG6 */
2890         spr_set_rights(SPRG6, SPR_SR | SPR_SW);
2891         /* SPRG7 */
2892         spr_set_rights(SPRG7, SPR_SR | SPR_SW);
2893         /* IBAT4U */
2894         spr_set_rights(IBAT4U, SPR_SR | SPR_SW);
2895         /* IBAT4L */
2896         spr_set_rights(IBAT4L, SPR_SR | SPR_SW);
2897         /* IBAT5U */
2898         spr_set_rights(IBAT5U, SPR_SR | SPR_SW);
2899         /* IBAT5L */
2900         spr_set_rights(IBAT5L, SPR_SR | SPR_SW);
2901         /* IBAT6U */
2902         spr_set_rights(IBAT6U, SPR_SR | SPR_SW);
2903         /* IBAT6L */
2904         spr_set_rights(IBAT6L, SPR_SR | SPR_SW);
2905         /* IBAT7U */
2906         spr_set_rights(IBAT7U, SPR_SR | SPR_SW);
2907         /* IBAT7L */
2908         spr_set_rights(IBAT7L, SPR_SR | SPR_SW);
2909         /* DBAT4U */
2910         spr_set_rights(DBAT4U, SPR_SR | SPR_SW);
2911         /* DBAT4L */
2912         spr_set_rights(DBAT4L, SPR_SR | SPR_SW);
2913         /* DBAT5U */
2914         spr_set_rights(DBAT5U, SPR_SR | SPR_SW);
2915         /* DBAT5L */
2916         spr_set_rights(DBAT5L, SPR_SR | SPR_SW);
2917         /* DBAT6U */
2918         spr_set_rights(DBAT6U, SPR_SR | SPR_SW);
2919         /* DBAT6L */
2920         spr_set_rights(DBAT6L, SPR_SR | SPR_SW);
2921         /* DBAT7U */
2922         spr_set_rights(DBAT7U, SPR_SR | SPR_SW);
2923         /* DBAT7L */
2924         spr_set_rights(DBAT7L, SPR_SR | SPR_SW);
2925         /* DMISS */
2926         spr_set_rights(DMISS,  SPR_SR | SPR_SW);
2927         /* DCMP */
2928         spr_set_rights(DCMP,   SPR_SR | SPR_SW);
2929         /* DHASH1 */
2930         spr_set_rights(DHASH1, SPR_SR | SPR_SW);
2931         /* DHASH2 */
2932         spr_set_rights(DHASH2, SPR_SR | SPR_SW);
2933         /* IMISS */
2934         spr_set_rights(IMISS,  SPR_SR | SPR_SW);
2935         /* ICMP */
2936         spr_set_rights(ICMP,   SPR_SR | SPR_SW);
2937         /* RPA */
2938         spr_set_rights(RPA,    SPR_SR | SPR_SW);
2939         /* HID2 */
2940         spr_set_rights(HID2,   SPR_SR | SPR_SW);
2941         /* L2PM */
2942         spr_set_rights(L2PM,   SPR_SR | SPR_SW);
2943     }
2944 }
2945
2946 /*****************************************************************************/
2947 /* PPC "main stream" common instructions (no optional ones) */
2948
2949 typedef struct ppc_proc_t {
2950     int flags;
2951     void *specific;
2952 } ppc_proc_t;
2953
2954 typedef struct ppc_def_t {
2955     unsigned long pvr;
2956     unsigned long pvr_mask;
2957     ppc_proc_t *proc;
2958 } ppc_def_t;
2959
2960 static ppc_proc_t ppc_proc_common = {
2961     .flags    = PPC_COMMON,
2962     .specific = NULL,
2963 };
2964
2965 static ppc_proc_t ppc_proc_G3 = {
2966     .flags    = PPC_750,
2967     .specific = NULL,
2968 };
2969
2970 static ppc_def_t ppc_defs[] =
2971 {
2972     /* MPC740/745/750/755 (G3) */
2973     {
2974         .pvr      = 0x00080000,
2975         .pvr_mask = 0xFFFF0000,
2976         .proc     = &ppc_proc_G3,
2977     },
2978     /* IBM 750FX (G3 embedded) */
2979     {
2980         .pvr      = 0x70000000,
2981         .pvr_mask = 0xFFFF0000,
2982         .proc     = &ppc_proc_G3,
2983     },
2984     /* Fallback (generic PPC) */
2985     {
2986         .pvr      = 0x00000000,
2987         .pvr_mask = 0x00000000,
2988         .proc     = &ppc_proc_common,
2989     },
2990 };
2991
2992 static int create_ppc_proc (opc_handler_t **ppc_opcodes, unsigned long pvr)
2993 {
2994     opcode_t *opc, *start, *end;
2995     int i, flags;
2996
2997     fill_new_table(ppc_opcodes, 0x40);
2998     for (i = 0; ; i++) {
2999         if ((ppc_defs[i].pvr & ppc_defs[i].pvr_mask) ==
3000             (pvr & ppc_defs[i].pvr_mask)) {
3001             flags = ppc_defs[i].proc->flags;
3002             break;
3003         }
3004     }
3005     
3006     if (&opc_start < &opc_end) {
3007         start = &opc_start;
3008         end = &opc_end;
3009     } else {
3010         start = &opc_end;
3011         end = &opc_start;
3012     }
3013     for (opc = start + 1; opc != end; opc++) {
3014         if ((opc->handler.type & flags) != 0)
3015             if (register_insn(ppc_opcodes, opc) < 0) {
3016                 printf("*** ERROR initializing PPC instruction "
3017                         "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
3018                         opc->opc3);
3019                 return -1;
3020             }
3021     }
3022     fix_opcode_tables(ppc_opcodes);
3023
3024     return 0;
3025 }
3026
3027
3028 /*****************************************************************************/
3029 /* Misc PPC helpers */
3030
3031 void cpu_dump_state(CPUState *env, FILE *f, 
3032                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3033                     int flags)
3034 {
3035     int i;
3036
3037     cpu_fprintf(f, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x "
3038             "MSR=0x%08x\n", env->nip, env->lr, env->ctr,
3039             _load_xer(env), _load_msr(env));
3040         for (i = 0; i < 32; i++) {
3041             if ((i & 7) == 0)
3042             cpu_fprintf(f, "GPR%02d:", i);
3043         cpu_fprintf(f, " %08x", env->gpr[i]);
3044             if ((i & 7) == 7)
3045             cpu_fprintf(f, "\n");
3046         }
3047     cpu_fprintf(f, "CR: 0x");
3048         for (i = 0; i < 8; i++)
3049         cpu_fprintf(f, "%01x", env->crf[i]);
3050     cpu_fprintf(f, "  [");
3051         for (i = 0; i < 8; i++) {
3052             char a = '-';
3053             if (env->crf[i] & 0x08)
3054                 a = 'L';
3055             else if (env->crf[i] & 0x04)
3056                 a = 'G';
3057             else if (env->crf[i] & 0x02)
3058                 a = 'E';
3059         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
3060         }
3061     cpu_fprintf(f, " ] ");
3062     cpu_fprintf(f, "TB: 0x%08x %08x\n", cpu_ppc_load_tbu(env),
3063             cpu_ppc_load_tbl(env));
3064         for (i = 0; i < 16; i++) {
3065             if ((i & 3) == 0)
3066             cpu_fprintf(f, "FPR%02d:", i);
3067         cpu_fprintf(f, " %016llx", *((uint64_t *)&env->fpr[i]));
3068             if ((i & 3) == 3)
3069             cpu_fprintf(f, "\n");
3070     }
3071     cpu_fprintf(f, "SRR0 0x%08x SRR1 0x%08x DECR=0x%08x\n",
3072             env->spr[SRR0], env->spr[SRR1], cpu_ppc_load_decr(env));
3073     cpu_fprintf(f, "reservation 0x%08x\n", env->reserve);
3074 }
3075
3076 CPUPPCState *cpu_ppc_init(void)
3077 {
3078     CPUPPCState *env;
3079
3080     cpu_exec_init();
3081
3082     env = qemu_mallocz(sizeof(CPUPPCState));
3083     if (!env)
3084         return NULL;
3085 //    env->spr[PVR] = 0; /* Basic PPC */
3086     env->spr[PVR] = 0x00080100; /* G3 CPU */
3087 //    env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */
3088 //    env->spr[PVR] = 0x00070100; /* IBM 750FX */
3089     tlb_flush(env, 1);
3090 #if defined (DO_SINGLE_STEP)
3091     /* Single step trace mode */
3092     msr_se = 1;
3093 #endif
3094     msr_fp = 1; /* Allow floating point exceptions */
3095     msr_me = 1; /* Allow machine check exceptions  */
3096 #if defined(CONFIG_USER_ONLY)
3097     msr_pr = 1;
3098     cpu_ppc_register(env, 0x00080000);
3099 #else
3100     env->nip = 0xFFFFFFFC;
3101 #endif
3102     cpu_single_env = env;
3103     return env;
3104 }
3105
3106 int cpu_ppc_register (CPUPPCState *env, uint32_t pvr)
3107 {
3108     env->spr[PVR] = pvr;
3109     if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0)
3110         return -1;
3111     init_spr_rights(env->spr[PVR]);
3112
3113     return 0;
3114 }
3115
3116 void cpu_ppc_close(CPUPPCState *env)
3117 {
3118     /* Should also remove all opcode tables... */
3119     free(env);
3120 }
3121
3122 /*****************************************************************************/
3123 int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3124                                     int search_pc)
3125 {
3126     DisasContext ctx, *ctxp = &ctx;
3127     opc_handler_t **table, *handler;
3128     target_ulong pc_start;
3129     uint16_t *gen_opc_end;
3130     int j, lj = -1;
3131
3132     pc_start = tb->pc;
3133     gen_opc_ptr = gen_opc_buf;
3134     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3135     gen_opparam_ptr = gen_opparam_buf;
3136     ctx.nip = pc_start;
3137     ctx.tb = tb;
3138     ctx.exception = EXCP_NONE;
3139 #if defined(CONFIG_USER_ONLY)
3140     ctx.mem_idx = 0;
3141 #else
3142     ctx.supervisor = 1 - msr_pr;
3143     ctx.mem_idx = 1 - msr_pr;
3144 #endif
3145     ctx.fpu_enabled = msr_fp;
3146 #if defined (DO_SINGLE_STEP)
3147     /* Single step trace mode */
3148     msr_se = 1;
3149 #endif
3150     /* Set env in case of segfault during code fetch */
3151     while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
3152         if (search_pc) {
3153             j = gen_opc_ptr - gen_opc_buf;
3154             if (lj < j) {
3155                 lj++;
3156                 while (lj < j)
3157                     gen_opc_instr_start[lj++] = 0;
3158                 gen_opc_pc[lj] = ctx.nip;
3159                 gen_opc_instr_start[lj] = 1;
3160             }
3161         }
3162 #if defined PPC_DEBUG_DISAS
3163         if (loglevel & CPU_LOG_TB_IN_ASM) {
3164             fprintf(logfile, "----------------\n");
3165             fprintf(logfile, "nip=%08x super=%d ir=%d\n",
3166                     ctx.nip, 1 - msr_pr, msr_ir);
3167         }
3168 #endif
3169         ctx.opcode = ldl_code(ctx.nip);
3170 #if defined PPC_DEBUG_DISAS
3171         if (loglevel & CPU_LOG_TB_IN_ASM) {
3172             fprintf(logfile, "translate opcode %08x (%02x %02x %02x)\n",
3173                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
3174                     opc3(ctx.opcode));
3175         }
3176 #endif
3177         ctx.nip += 4;
3178         table = ppc_opcodes;
3179         handler = table[opc1(ctx.opcode)];
3180         if (is_indirect_opcode(handler)) {
3181             table = ind_table(handler);
3182             handler = table[opc2(ctx.opcode)];
3183             if (is_indirect_opcode(handler)) {
3184                 table = ind_table(handler);
3185                 handler = table[opc3(ctx.opcode)];
3186             }
3187         }
3188         /* Is opcode *REALLY* valid ? */
3189                 if (handler->handler == &gen_invalid) {
3190             if (loglevel > 0) {
3191                     fprintf(logfile, "invalid/unsupported opcode: "
3192                         "%02x - %02x - %02x (%08x) 0x%08x %d\n",
3193                             opc1(ctx.opcode), opc2(ctx.opcode),
3194                         opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
3195             } else {
3196                 printf("invalid/unsupported opcode: "
3197                        "%02x - %02x - %02x (%08x) 0x%08x %d\n",
3198                        opc1(ctx.opcode), opc2(ctx.opcode),
3199                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
3200             }
3201                 } else {
3202             if ((ctx.opcode & handler->inval) != 0) {
3203                 if (loglevel > 0) {
3204                     fprintf(logfile, "invalid bits: %08x for opcode: "
3205                             "%02x -%02x - %02x (0x%08x) (0x%08x)\n",
3206                             ctx.opcode & handler->inval, opc1(ctx.opcode),
3207                             opc2(ctx.opcode), opc3(ctx.opcode),
3208                             ctx.opcode, ctx.nip - 4);
3209                 } else {
3210                     printf("invalid bits: %08x for opcode: "
3211                            "%02x -%02x - %02x (0x%08x) (0x%08x)\n",
3212                             ctx.opcode & handler->inval, opc1(ctx.opcode),
3213                             opc2(ctx.opcode), opc3(ctx.opcode),
3214                            ctx.opcode, ctx.nip - 4);
3215             }
3216                 RET_INVAL(ctxp);
3217                 break;
3218             }
3219         }
3220         (*(handler->handler))(&ctx);
3221         /* Check trace mode exceptions */
3222         if ((msr_be && ctx.exception == EXCP_BRANCH) ||
3223             /* Check in single step trace mode
3224              * we need to stop except if:
3225              * - rfi, trap or syscall
3226              * - first instruction of an exception handler
3227              */
3228             (msr_se && (ctx.nip < 0x100 ||
3229                         ctx.nip > 0xF00 ||
3230                         (ctx.nip & 0xFC) != 0x04) &&
3231              ctx.exception != EXCP_SYSCALL && ctx.exception != EXCP_RFI &&
3232              ctx.exception != EXCP_TRAP)) {
3233             RET_EXCP(ctxp, EXCP_TRACE, 0);
3234         }
3235         /* if we reach a page boundary, stop generation */
3236         if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
3237             RET_EXCP(ctxp, EXCP_BRANCH, 0);
3238     }
3239     }
3240     if (ctx.exception == EXCP_NONE) {
3241         gen_op_b((unsigned long)ctx.tb, ctx.nip);
3242     } else if (ctx.exception != EXCP_BRANCH) {
3243         gen_op_set_T0(0);
3244     }
3245 #if 1
3246     /* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
3247      *              do bad business and then qemu crashes !
3248      */
3249     gen_op_set_T0(0);
3250 #endif
3251     /* Generate the return instruction */
3252     gen_op_exit_tb();
3253     *gen_opc_ptr = INDEX_op_end;
3254     if (search_pc) {
3255         j = gen_opc_ptr - gen_opc_buf;
3256         lj++;
3257         while (lj <= j)
3258             gen_opc_instr_start[lj++] = 0;
3259         tb->size = 0;
3260 #if 0
3261         if (loglevel > 0) {
3262             page_dump(logfile);
3263         }
3264 #endif
3265     } else {
3266         tb->size = ctx.nip - pc_start;
3267     }
3268 #ifdef DEBUG_DISAS
3269     if (loglevel & CPU_LOG_TB_CPU) {
3270         fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
3271         cpu_dump_state(env, logfile, fprintf, 0);
3272     }
3273     if (loglevel & CPU_LOG_TB_IN_ASM) {
3274         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3275         target_disas(logfile, pc_start, ctx.nip - pc_start, 0);
3276         fprintf(logfile, "\n");
3277     }
3278     if (loglevel & CPU_LOG_TB_OP) {
3279         fprintf(logfile, "OP:\n");
3280         dump_ops(gen_opc_buf, gen_opparam_buf);
3281         fprintf(logfile, "\n");
3282     }
3283 #endif
3284     return 0;
3285 }
3286
3287 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3288 {
3289     return gen_intermediate_code_internal(env, tb, 0);
3290 }
3291
3292 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3293 {
3294     return gen_intermediate_code_internal(env, tb, 1);
3295 }