/[dynamips]/trunk/ppc32_x86_trans.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/ppc32_x86_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/ppc32_x86_trans.c
File MIME type: text/plain
File size: 63543 byte(s)
dynamips-0.2.7-RC1

1 dpavlin 7 /*
2     * Cisco router simulation platform.
3     * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4     */
5    
6     #include <stdio.h>
7     #include <stdlib.h>
8     #include <unistd.h>
9     #include <string.h>
10     #include <sys/types.h>
11     #include <sys/stat.h>
12     #include <sys/mman.h>
13     #include <fcntl.h>
14    
15     #include "cpu.h"
16     #include "ppc32_jit.h"
17     #include "ppc32_x86_trans.h"
18     #include "memory.h"
19    
20     /* Macros for CPU structure access */
21     #define REG_OFFSET(reg) (OFFSET(cpu_ppc_t,gpr[(reg)]))
22     #define MEMOP_OFFSET(op) (OFFSET(cpu_ppc_t,mem_op_fn[(op)]))
23    
24     #define DECLARE_INSN(name) \
25     static int ppc32_emit_##name(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, \
26     ppc_insn_t insn)
27    
28     /* Dump regs */
29     static void ppc32_emit_dump_regs(ppc32_jit_tcb_t *b);
30    
31     /* Load a 32 bit immediate value */
32     static inline void ppc32_load_imm(ppc32_jit_tcb_t *b,u_int reg,m_uint32_t val)
33     {
34     if (val)
35     x86_mov_reg_imm(b->jit_ptr,reg,val);
36     else
37     x86_alu_reg_reg(b->jit_ptr,X86_XOR,reg,reg);
38     }
39    
40     /* Set the Instruction Address (IA) register */
41     void ppc32_set_ia(ppc32_jit_tcb_t *b,m_uint32_t new_ia)
42     {
43     x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),new_ia,4);
44     }
45    
46     /* Set the Link Register (LR) */
47     void ppc32_set_lr(ppc32_jit_tcb_t *b,m_uint32_t new_lr)
48     {
49     x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),new_lr,4);
50     }
51    
52     /* Set Jump */
53     static void ppc32_set_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
54     m_uint32_t new_ia,int local_jump)
55     {
56     int return_to_caller = FALSE;
57     u_char *jump_ptr;
58    
59     #if 0
60     if (cpu->sym_trace && !local_jump)
61     return_to_caller = TRUE;
62     #endif
63    
64     if (!return_to_caller && ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr)) {
65     if (jump_ptr) {
66     x86_jump_code(b->jit_ptr,jump_ptr);
67     } else {
68     ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia);
69     x86_jump32(b->jit_ptr,0);
70     }
71     } else {
72     /* save PC */
73     ppc32_set_ia(b,new_ia);
74    
75     /* address is in another block, for now, returns to caller */
76     ppc32_jit_tcb_push_epilog(b);
77     }
78     }
79    
80     /* Load the Condition Register (CR) into the specified host register */
81     static forced_inline void ppc32_load_cr(ppc32_jit_tcb_t *b,u_int host_reg)
82     {
83     x86_mov_reg_membase(b->jit_ptr,host_reg,X86_EDI,OFFSET(cpu_ppc_t,cr),4);
84     }
85    
86     /* Store the Condition Register (CR) from the specified host register */
87     static forced_inline void ppc32_store_cr(ppc32_jit_tcb_t *b,u_int host_reg)
88     {
89     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr),host_reg,4);
90     }
91    
92     /* Load a GPR into the specified host register */
93     static forced_inline void ppc32_load_gpr(ppc32_jit_tcb_t *b,u_int host_reg,
94     u_int ppc_reg)
95     {
96     x86_mov_reg_membase(b->jit_ptr,host_reg,X86_EDI,REG_OFFSET(ppc_reg),4);
97     }
98    
99     /* Store contents for a host register into a GPR register */
100     static forced_inline void ppc32_store_gpr(ppc32_jit_tcb_t *b,u_int ppc_reg,
101     u_int host_reg)
102     {
103     x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(ppc_reg),host_reg,4);
104     }
105    
106     /* Apply an ALU operation on a GPR register and a host register */
107     static forced_inline void ppc32_alu_gpr(ppc32_jit_tcb_t *b,u_int op,
108     u_int host_reg,u_int ppc_reg)
109     {
110     x86_alu_reg_membase(b->jit_ptr,op,host_reg,X86_EDI,REG_OFFSET(ppc_reg));
111     }
112    
113     /*
114     * Update CR from %eflags
115     * %eax, %ecx, %edx, %esi are modified.
116     */
117     #define PPC32_CR_LT_BIT 3
118     #define PPC32_CR_GT_BIT 2
119     #define PPC32_CR_EQ_BIT 1
120     #define PPC32_CR_SO_BIT 0
121    
122     static void ppc32_update_cr(ppc32_jit_tcb_t *b,int field,int is_signed)
123     {
124     m_uint32_t cr_mask;
125     u_int cfb;
126    
127     cr_mask = 0xF0000000 >> (field << 2);
128     cfb = 28 - (field << 2);
129    
130     x86_set_reg(b->jit_ptr,X86_CC_LT,X86_EAX,is_signed);
131     x86_set_reg(b->jit_ptr,X86_CC_GT,X86_ECX,is_signed);
132     x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EDX,is_signed);
133    
134     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,(cfb + PPC32_CR_LT_BIT));
135     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_ECX,(cfb + PPC32_CR_GT_BIT));
136     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EDX,(cfb + PPC32_CR_EQ_BIT));
137    
138     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
139     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_EDX);
140    
141     /* Load Condition Register */
142     x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,cr),4);
143     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EDX,~cr_mask);
144     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,cr_mask);
145     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EDX,X86_EAX);
146    
147     /* Check XER Summary of Overflow and report it */
148     x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,OFFSET(cpu_ppc_t,xer),4);
149     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,PPC32_XER_SO);
150     x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_ECX,(field << 2) + 3);
151     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EDX,X86_ECX);
152    
153     /* Store modified CR */
154     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr),X86_EDX,4);
155     }
156    
157     /*
158     * Update CR0 from %eflags
159     * %eax, %ecx, %edx, %esi are modified.
160     */
161     static void ppc32_update_cr0(ppc32_jit_tcb_t *b)
162     {
163     ppc32_update_cr(b,0,TRUE);
164     }
165    
166     /* Basic C call */
167     static forced_inline void ppc32_emit_basic_c_call(ppc32_jit_tcb_t *b,void *f)
168     {
169     x86_mov_reg_imm(b->jit_ptr,X86_EBX,f);
170     x86_call_reg(b->jit_ptr,X86_EBX);
171     }
172    
173     /* Emit a simple call to a C function without any parameter */
174     static void ppc32_emit_c_call(ppc32_jit_tcb_t *b,void *f)
175     {
176     ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
177     ppc32_emit_basic_c_call(b,f);
178     }
179    
180     /* Memory operation */
181     static void ppc32_emit_memop(ppc32_jit_tcb_t *b,int op,int base,int offset,
182     int target,int update)
183     {
184     m_uint32_t val = sign_extend(offset,16);
185     u_char *test1;
186    
187     /* Save PC for exception handling */
188     ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
189    
190     /* EDX = sign-extended offset */
191     ppc32_load_imm(b,X86_EDX,val);
192    
193     /* EDX = GPR[base] + sign-extended offset */
194     if (update || (base != 0))
195     ppc32_alu_gpr(b,X86_ADD,X86_EDX,base);
196    
197     if (update)
198     x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EDX,4);
199    
200     /* ECX = target register */
201     x86_mov_reg_imm(b->jit_ptr,X86_ECX,target);
202    
203     /* EAX = CPU instance pointer */
204     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
205    
206     /* Call memory function */
207     x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(op));
208    
209     /* Exception ? */
210     x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
211     test1 = b->jit_ptr;
212     x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
213     ppc32_jit_tcb_push_epilog(b);
214     x86_patch(test1,b->jit_ptr);
215    
216     if (update)
217     ppc32_store_gpr(b,base,X86_ESI);
218     }
219    
220     /* Memory operation (indexed) */
221     static void ppc32_emit_memop_idx(ppc32_jit_tcb_t *b,int op,int ra,int rb,
222     int target,int update)
223     {
224     u_char *test1;
225    
226     /* Save PC for exception handling */
227     ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
228    
229     /* EDX = $rb */
230     ppc32_load_gpr(b,X86_EDX,rb);
231    
232     /* EDX = $rb + $ra */
233     if (update || (ra != 0))
234     ppc32_alu_gpr(b,X86_ADD,X86_EDX,ra);
235    
236     if (update)
237     x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EDX,4);
238    
239     /* ECX = target register */
240     x86_mov_reg_imm(b->jit_ptr,X86_ECX,target);
241    
242     /* EAX = CPU instance pointer */
243     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
244    
245     /* Call memory function */
246     x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(op));
247    
248     /* Exception ? */
249     x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
250     test1 = b->jit_ptr;
251     x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
252     ppc32_jit_tcb_push_epilog(b);
253     x86_patch(test1,b->jit_ptr);
254    
255     if (update)
256     ppc32_store_gpr(b,ra,X86_ESI);
257     }
258    
259     typedef void (*memop_fast_access)(ppc32_jit_tcb_t *b,int target);
260    
261     /* Fast LBZ */
262     static void ppc32_memop_fast_lbz(ppc32_jit_tcb_t *b,int target)
263     {
264     x86_clear_reg(b->jit_ptr,X86_ECX);
265     x86_mov_reg_memindex(b->jit_ptr,X86_ECX,X86_EAX,0,X86_EBX,0,1);
266     ppc32_store_gpr(b,target,X86_ECX);
267     }
268    
269     /* Fast STB */
270     static void ppc32_memop_fast_stb(ppc32_jit_tcb_t *b,int target)
271     {
272     ppc32_load_gpr(b,X86_EDX,target);
273     x86_mov_memindex_reg(b->jit_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,1);
274     }
275    
276     /* Fast LWZ */
277     static void ppc32_memop_fast_lwz(ppc32_jit_tcb_t *b,int target)
278     {
279     x86_mov_reg_memindex(b->jit_ptr,X86_EAX,X86_EAX,0,X86_EBX,0,4);
280     x86_bswap(b->jit_ptr,X86_EAX);
281     ppc32_store_gpr(b,target,X86_EAX);
282     }
283    
284     /* Fast STW */
285     static void ppc32_memop_fast_stw(ppc32_jit_tcb_t *b,int target)
286     {
287     ppc32_load_gpr(b,X86_EDX,target);
288     x86_bswap(b->jit_ptr,X86_EDX);
289     x86_mov_memindex_reg(b->jit_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,4);
290     }
291    
292     /* Fast memory operation */
293     static void ppc32_emit_memop_fast(ppc32_jit_tcb_t *b,int write_op,int opcode,
294     int base,int offset,int target,
295     memop_fast_access op_handler)
296     {
297     m_uint32_t val = sign_extend(offset,16);
298     u_char *test1,*test2,*p_exception,*p_exit;
299    
300     test2 = NULL;
301    
302     /* EBX = sign-extended offset */
303     ppc32_load_imm(b,X86_EBX,val);
304    
305     /* EBX = GPR[base] + sign-extended offset */
306     if (base != 0)
307     ppc32_alu_gpr(b,X86_ADD,X86_EBX,base);
308    
309     /* EAX = mts32_entry index */
310     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EBX,4);
311     x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,MTS32_HASH_SHIFT);
312     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,MTS32_HASH_MASK);
313    
314     /* EDX = mts32_entry */
315     x86_mov_reg_membase(b->jit_ptr,X86_EDX,
316     X86_EDI,OFFSET(cpu_ppc_t,mts_cache[PPC32_MTS_DCACHE]),
317     4);
318     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,4);
319     x86_alu_reg_reg(b->jit_ptr,X86_ADD,X86_EDX,X86_EAX);
320    
321     /* Compare virtual page address (ESI = vpage) */
322     x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EBX,4);
323     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_MASK);
324    
325     x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_ESI,X86_EDX,
326     OFFSET(mts32_entry_t,gvpa));
327     test1 = b->jit_ptr;
328     x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
329    
330     /* Test if we are writing to a COW page */
331     if (write_op) {
332     x86_test_membase_imm(b->jit_ptr,X86_EDX,OFFSET(mts32_entry_t,flags),
333     MTS_FLAG_COW);
334     test2 = b->jit_ptr;
335     x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
336     }
337    
338     /* EBX = offset in page, EAX = Host Page Address */
339     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,PPC32_MIN_PAGE_IMASK);
340     x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDX,OFFSET(mts32_entry_t,hpa),4);
341    
342     /* Memory access */
343     op_handler(b,target);
344    
345     p_exit = b->jit_ptr;
346     x86_jump8(b->jit_ptr,0);
347    
348     /* === Slow lookup === */
349     x86_patch(test1,b->jit_ptr);
350     if (test2)
351     x86_patch(test2,b->jit_ptr);
352    
353     /* Update IA (EBX = vaddr) */
354     ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
355    
356     /* EDX = virtual address */
357     x86_mov_reg_reg(b->jit_ptr,X86_EDX,X86_EBX,4);
358    
359     /* ECX = target register */
360     x86_mov_reg_imm(b->jit_ptr,X86_ECX,target);
361    
362     /* EAX = CPU instance pointer */
363     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
364    
365     /* Call memory function */
366     x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(opcode));
367    
368     /* Check for exception */
369     x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
370     p_exception = b->jit_ptr;
371     x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
372     ppc32_jit_tcb_push_epilog(b);
373    
374     x86_patch(p_exit,b->jit_ptr);
375     x86_patch(p_exception,b->jit_ptr);
376     }
377    
378     /* Virtual Breakpoint */
379     void ppc32_emit_breakpoint(ppc32_jit_tcb_t *b)
380     {
381     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
382     ppc32_emit_c_call(b,ppc32_run_breakpoint);
383     }
384    
385     /* Unknown opcode handler */
386     static asmlinkage void ppc32_unknown_opcode(cpu_ppc_t *cpu,m_uint32_t opcode)
387     {
388     printf("PPC32: unhandled opcode 0x%8.8x at 0x%8.8x (lr=0x%8.8x)\n",
389     opcode,cpu->ia,cpu->lr);
390    
391     ppc32_dump_regs(cpu->gen);
392     exit(1);
393     }
394    
395     /* Emit unhandled instruction code */
396     static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
397     ppc_insn_t opcode)
398     {
399     u_char *test1;
400    
401     #if 0
402     x86_mov_reg_imm(b->jit_ptr,X86_EAX,opcode);
403     x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,4);
404     x86_push_reg(b->jit_ptr,X86_EAX);
405     x86_push_reg(b->jit_ptr,X86_EDI);
406     ppc32_emit_c_call(b,ppc32_unknown_opcode);
407     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
408     #endif
409    
410     /* Update IA */
411     ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
412    
413     /* Fallback to non-JIT mode */
414     x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
415     x86_mov_reg_imm(b->jit_ptr,X86_EDX,opcode);
416    
417     ppc32_emit_c_call(b,ppc32_exec_single_insn_ext);
418     x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
419     test1 = b->jit_ptr;
420     x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
421     ppc32_jit_tcb_push_epilog(b);
422    
423     x86_patch(test1,b->jit_ptr);
424     return(0);
425     }
426    
427     /* Dump regs */
428     static void ppc32_emit_dump_regs(ppc32_jit_tcb_t *b)
429     {
430     x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,OFFSET(cpu_ppc_t,gen),4);
431     x86_push_reg(b->jit_ptr,X86_EAX);
432     ppc32_emit_c_call(b,ppc32_dump_regs);
433     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,4);
434     }
435    
436     /* Increment the number of executed instructions (performance debugging) */
437     void ppc32_inc_perf_counter(ppc32_jit_tcb_t *b)
438     {
439     x86_alu_membase_imm(b->jit_ptr,X86_ADD,
440     X86_EDI,OFFSET(cpu_ppc_t,perf_counter),1);
441     x86_alu_membase_imm(b->jit_ptr,X86_ADC,
442     X86_EDI,OFFSET(cpu_ppc_t,perf_counter)+4,0);
443     }
444    
445     /* ======================================================================== */
446    
447     /* BLR - Branch to Link Register */
448     DECLARE_INSN(BLR)
449     {
450     x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
451     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),X86_EDX,4);
452    
453     /* set the return address */
454     if (insn & 1)
455     ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
456    
457     ppc32_jit_tcb_push_epilog(b);
458     return(0);
459     }
460    
461     /* BCTR - Branch to Count Register */
462     DECLARE_INSN(BCTR)
463     {
464     x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
465     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),X86_EDX,4);
466    
467     /* set the return address */
468     if (insn & 1)
469     ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
470    
471     ppc32_jit_tcb_push_epilog(b);
472     return(0);
473     }
474    
475     /* MFLR - Move From Link Register */
476     DECLARE_INSN(MFLR)
477     {
478     int rd = bits(insn,21,25);
479    
480     x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
481     ppc32_store_gpr(b,rd,X86_EDX);
482     return(0);
483     }
484    
485     /* MTLR - Move To Link Register */
486     DECLARE_INSN(MTLR)
487     {
488     int rs = bits(insn,21,25);
489    
490     ppc32_load_gpr(b,X86_EDX,rs);
491     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),X86_EDX,4);
492     return(0);
493     }
494    
495     /* MFCTR - Move From Counter Register */
496     DECLARE_INSN(MFCTR)
497     {
498     int rd = bits(insn,21,25);
499    
500     x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
501     ppc32_store_gpr(b,rd,X86_EDX);
502     return(0);
503     }
504    
505     /* MTCTR - Move To Counter Register */
506     DECLARE_INSN(MTCTR)
507     {
508     int rs = bits(insn,21,25);
509    
510     ppc32_load_gpr(b,X86_EDX,rs);
511     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr),X86_EDX,4);
512     return(0);
513     }
514    
515     /* MFTBU - Move from Time Base (Up) */
516     DECLARE_INSN(MFTBU)
517     {
518     int rd = bits(insn,21,25);
519    
520     x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
521     ppc32_store_gpr(b,rd,X86_EDX);
522     return(0);
523     }
524    
525     #define PPC32_TB_INCREMENT 50
526    
527     /* MFTBL - Move from Time Base (Lo) */
528     DECLARE_INSN(MFTBL)
529     {
530     int rd = bits(insn,21,25);
531    
532     /* Increment the time base register */
533     x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,tb),4);
534     x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
535     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_EDX,PPC32_TB_INCREMENT);
536     x86_alu_reg_imm(b->jit_ptr,X86_ADC,X86_EBX,0);
537     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb),X86_EDX,4);
538     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,X86_EBX,4);
539    
540     ppc32_store_gpr(b,rd,X86_EDX);
541     return(0);
542     }
543    
544     /* ADD */
545     DECLARE_INSN(ADD)
546     {
547     int rd = bits(insn,21,25);
548     int ra = bits(insn,16,20);
549     int rb = bits(insn,11,15);
550    
551     /* $rd = $ra + $rb */
552     ppc32_load_gpr(b,X86_EBX,ra);
553     ppc32_alu_gpr(b,X86_ADD,X86_EBX,rb);
554     ppc32_store_gpr(b,rd,X86_EBX);
555    
556     if (insn & 1)
557     ppc32_update_cr0(b);
558    
559     return(0);
560     }
561    
562     /* ADDC */
563     DECLARE_INSN(ADDC)
564     {
565     int rd = bits(insn,21,25);
566     int ra = bits(insn,16,20);
567     int rb = bits(insn,11,15);
568    
569     /* $rd = $ra + $rb */
570     ppc32_load_gpr(b,X86_EBX,ra);
571     ppc32_alu_gpr(b,X86_ADD,X86_EBX,rb);
572     ppc32_store_gpr(b,rd,X86_EBX);
573    
574     /* store the carry flag */
575     x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
576     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
577     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
578    
579     if (insn & 1) {
580     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
581     ppc32_update_cr0(b);
582     }
583    
584     return(0);
585     }
586    
587     /* ADDE - Add Extended */
588     DECLARE_INSN(ADDE)
589     {
590     int rd = bits(insn,21,25);
591     int ra = bits(insn,16,20);
592     int rb = bits(insn,11,15);
593    
594     /* $ra + carry */
595     ppc32_load_gpr(b,X86_ESI,ra);
596     x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_ESI,
597     X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
598     x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
599    
600     /* add $rb */
601     ppc32_alu_gpr(b,X86_ADD,X86_ESI,rb);
602     x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
603    
604     ppc32_store_gpr(b,rd,X86_ESI);
605    
606     /* store the carry flag */
607     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
608     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
609    
610     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
611    
612     /* update cr0 */
613     if (insn & 1) {
614     x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
615     ppc32_update_cr0(b);
616     }
617    
618     return(0);
619     }
620    
621     /* ADDI - ADD Immediate */
622     DECLARE_INSN(ADDI)
623     {
624     int rd = bits(insn,21,25);
625     int ra = bits(insn,16,20);
626     int imm = bits(insn,0,15);
627     m_uint32_t tmp = sign_extend_32(imm,16);
628    
629     ppc32_load_imm(b,X86_EBX,tmp);
630    
631     if (ra != 0)
632     x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EBX,X86_EDI,REG_OFFSET(ra));
633    
634     ppc32_store_gpr(b,rd,X86_EBX);
635     return(0);
636     }
637    
638     /* ADDIC - ADD Immediate with Carry */
639     DECLARE_INSN(ADDIC)
640     {
641     int rd = bits(insn,21,25);
642     int ra = bits(insn,16,20);
643     int imm = bits(insn,0,15);
644     m_uint32_t tmp = sign_extend_32(imm,16);
645    
646     ppc32_load_imm(b,X86_EAX,tmp);
647     ppc32_alu_gpr(b,X86_ADD,X86_EAX,ra);
648     ppc32_store_gpr(b,rd,X86_EAX);
649     x86_set_membase(b->jit_ptr,X86_CC_C,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
650     return(0);
651     }
652    
653     /* ADDIC. */
654     DECLARE_INSN(ADDIC_dot)
655     {
656     int rd = bits(insn,21,25);
657     int ra = bits(insn,16,20);
658     int imm = bits(insn,0,15);
659     m_uint32_t tmp = sign_extend_32(imm,16);
660    
661     ppc32_load_imm(b,X86_EAX,tmp);
662     ppc32_alu_gpr(b,X86_ADD,X86_EAX,ra);
663     ppc32_store_gpr(b,rd,X86_EAX);
664     x86_set_membase(b->jit_ptr,X86_CC_C,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
665    
666     x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
667     ppc32_update_cr0(b);
668     return(0);
669     }
670    
671     /* ADDIS - ADD Immediate Shifted */
672     DECLARE_INSN(ADDIS)
673     {
674     int rd = bits(insn,21,25);
675     int ra = bits(insn,16,20);
676     m_uint32_t imm = bits(insn,0,15);
677    
678     ppc32_load_imm(b,X86_EBX,imm << 16);
679    
680     if (ra != 0)
681     x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EBX,X86_EDI,REG_OFFSET(ra));
682    
683     ppc32_store_gpr(b,rd,X86_EBX);
684     return(0);
685     }
686    
687     /* AND */
688     DECLARE_INSN(AND)
689     {
690     int rs = bits(insn,21,25);
691     int ra = bits(insn,16,20);
692     int rb = bits(insn,11,15);
693    
694     ppc32_load_gpr(b,X86_EBX,rs);
695     ppc32_alu_gpr(b,X86_AND,X86_EBX,rb);
696     ppc32_store_gpr(b,ra,X86_EBX);
697    
698     if (insn & 1)
699     ppc32_update_cr0(b);
700    
701     return(0);
702     }
703    
704     /* ANDC */
705     DECLARE_INSN(ANDC)
706     {
707     int rs = bits(insn,21,25);
708     int ra = bits(insn,16,20);
709     int rb = bits(insn,11,15);
710    
711     /* $ra = $rs & ~$rb */
712     ppc32_load_gpr(b,X86_EBX,rb);
713     x86_not_reg(b->jit_ptr,X86_EBX);
714     ppc32_alu_gpr(b,X86_AND,X86_EBX,rs);
715     ppc32_store_gpr(b,ra,X86_EBX);
716    
717     if (insn & 1)
718     ppc32_update_cr0(b);
719    
720     return(0);
721     }
722    
723     /* AND Immediate */
724     DECLARE_INSN(ANDI)
725     {
726     int rs = bits(insn,21,25);
727     int ra = bits(insn,16,20);
728     m_uint16_t imm = bits(insn,0,15);
729    
730     /* $ra = $rs & imm */
731     ppc32_load_imm(b,X86_EBX,imm);
732     ppc32_alu_gpr(b,X86_AND,X86_EBX,rs);
733     ppc32_store_gpr(b,ra,X86_EBX);
734    
735     ppc32_update_cr0(b);
736     return(0);
737     }
738    
739     /* AND Immediate Shifted */
740     DECLARE_INSN(ANDIS)
741     {
742     int rs = bits(insn,21,25);
743     int ra = bits(insn,16,20);
744     m_uint32_t imm = bits(insn,0,15);
745    
746     /* $ra = $rs & imm */
747     ppc32_load_imm(b,X86_EBX,imm << 16);
748     ppc32_alu_gpr(b,X86_AND,X86_EBX,rs);
749     ppc32_store_gpr(b,ra,X86_EBX);
750    
751     ppc32_update_cr0(b);
752     return(0);
753     }
754    
755     /* B - Branch */
756     DECLARE_INSN(B)
757     {
758     m_uint32_t offset = bits(insn,2,25);
759     m_uint64_t new_ia;
760    
761     /* compute the new ia */
762     new_ia = b->start_ia + ((b->ppc_trans_pos-1) << 2);
763     new_ia += sign_extend(offset << 2,26);
764     ppc32_set_jump(cpu,b,new_ia,1);
765     return(0);
766     }
767    
768     /* BA - Branch Absolute */
769     DECLARE_INSN(BA)
770     {
771     m_uint32_t offset = bits(insn,2,25);
772     m_uint64_t new_ia;
773    
774     /* compute the new ia */
775     new_ia = sign_extend(offset << 2,26);
776     ppc32_set_jump(cpu,b,new_ia,1);
777     return(0);
778     }
779    
780     /* BL - Branch and Link */
781     DECLARE_INSN(BL)
782     {
783     m_uint32_t offset = bits(insn,2,25);
784     m_uint64_t new_ia;
785    
786     /* compute the new ia */
787     new_ia = b->start_ia + ((b->ppc_trans_pos-1) << 2);
788     new_ia += sign_extend(offset << 2,26);
789    
790     /* set the return address */
791     ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
792    
793     ppc32_set_jump(cpu,b,new_ia,1);
794     return(0);
795     }
796    
797     /* BLA - Branch and Link Absolute */
798     DECLARE_INSN(BLA)
799     {
800     m_uint32_t offset = bits(insn,2,25);
801     m_uint64_t new_ia;
802    
803     /* compute the new ia */
804     new_ia = sign_extend(offset << 2,26);
805    
806     /* set the return address */
807     ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
808    
809     ppc32_set_jump(cpu,b,new_ia,1);
810     return(0);
811     }
812    
813     /* BC - Branch Conditional (Condition Check only) */
814     DECLARE_INSN(BCC)
815     {
816     int bo = bits(insn,21,25);
817     int bi = bits(insn,16,20);
818     int bd = bits(insn,2,15);
819     m_uint32_t new_ia;
820     u_char *jump_ptr;
821     int local_jump;
822     int cond;
823    
824     /* Get the wanted value for the condition bit */
825     cond = (bo >> 3) & 0x1;
826    
827     /* Set the return address */
828     if (insn & 1)
829     ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
830    
831     /* Compute the new ia */
832     new_ia = sign_extend_32(bd << 2,16);
833     if (!(insn & 0x02))
834     new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2);
835    
836     /* Test the condition bit */
837     x86_test_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr),
838     (1 << (31 - bi)));
839    
840     local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
841    
842     /*
843     * Optimize the jump, depending if the destination is in the same
844     * page or not.
845     */
846     if (local_jump) {
847     if (jump_ptr) {
848     x86_branch(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,jump_ptr,FALSE);
849     } else {
850     ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia);
851     x86_branch32(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,0,FALSE);
852     }
853     } else {
854     jump_ptr = b->jit_ptr;
855     x86_branch32(b->jit_ptr,(cond) ? X86_CC_Z : X86_CC_NZ,0,FALSE);
856     ppc32_set_jump(cpu,b,new_ia,TRUE);
857     x86_patch(jump_ptr,b->jit_ptr);
858     }
859    
860     return(0);
861     }
862    
863     /* BC - Branch Conditional */
864     DECLARE_INSN(BC)
865     {
866     int bo = bits(insn,21,25);
867     int bi = bits(insn,16,20);
868     int bd = bits(insn,2,15);
869     m_uint32_t new_ia;
870     u_char *jump_ptr;
871     int local_jump;
872     int cond,ctr;
873    
874     /* Get the wanted value for the condition bit and CTR value */
875     cond = (bo >> 3) & 0x1;
876     ctr = (bo >> 1) & 0x1;
877    
878     /* Set the return address */
879     if (insn & 1)
880     ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
881    
882     /* Compute the new ia */
883     new_ia = sign_extend_32(bd << 2,16);
884     if (!(insn & 0x02))
885     new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2);
886    
887     x86_mov_reg_imm(b->jit_ptr,X86_EAX,1);
888    
889     /* Decrement the count register */
890     if (!(bo & 0x04)) {
891     x86_dec_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
892     x86_set_reg(b->jit_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,X86_EBX,FALSE);
893     x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_EBX);
894     }
895    
896     /* Test the condition bit */
897     if (!((bo >> 4) & 0x01)) {
898     x86_test_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr),
899     (1 << (31 - bi)));
900     x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE);
901     x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX);
902     }
903    
904     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x01);
905    
906     local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
907    
908     /*
909     * Optimize the jump, depending if the destination is in the same
910     * page or not.
911     */
912     if (local_jump) {
913     if (jump_ptr) {
914     x86_branch(b->jit_ptr,X86_CC_NZ,jump_ptr,FALSE);
915     } else {
916     ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia);
917     x86_branch32(b->jit_ptr,X86_CC_NZ,0,FALSE);
918     }
919     } else {
920     jump_ptr = b->jit_ptr;
921     x86_branch32(b->jit_ptr,X86_CC_Z,0,FALSE);
922     ppc32_set_jump(cpu,b,new_ia,TRUE);
923     x86_patch(jump_ptr,b->jit_ptr);
924     }
925    
926     return(0);
927     }
928    
929     /* BCLR - Branch Conditional to Link register */
930     DECLARE_INSN(BCLR)
931     {
932     int bo = bits(insn,21,25);
933     int bi = bits(insn,16,20);
934     int bd = bits(insn,2,15);
935     m_uint32_t new_ia;
936     u_char *jump_ptr;
937     int cond,ctr;
938    
939     /* Get the wanted value for the condition bit and CTR value */
940     cond = (bo >> 3) & 0x1;
941     ctr = (bo >> 1) & 0x1;
942    
943     /* Compute the new ia */
944     new_ia = sign_extend_32(bd << 2,16);
945     if (!(insn & 0x02))
946     new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2);
947    
948     ppc32_load_imm(b,X86_EAX,1);
949    
950     /* Decrement the count register */
951     if (!(bo & 0x04)) {
952     x86_dec_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
953     x86_set_reg(b->jit_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,X86_EBX,FALSE);
954     x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_EBX);
955     }
956    
957     /* Test the condition bit */
958     if (!((bo >> 4) & 0x01)) {
959     x86_test_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr),
960     (1 << (31 - bi)));
961     x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE);
962     x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX);
963     }
964    
965     /* Set the return address */
966     x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
967    
968     if (insn & 1)
969     ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
970    
971     /* Branching */
972     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x01);
973    
974     jump_ptr = b->jit_ptr;
975     x86_branch32(b->jit_ptr,X86_CC_Z,0,FALSE);
976    
977     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EDX,0xFFFFFFFC);
978     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),X86_EDX,4);
979     ppc32_jit_tcb_push_epilog(b);
980    
981     x86_patch(jump_ptr,b->jit_ptr);
982     return(0);
983     }
984    
985     /* CMP - Compare */
986     DECLARE_INSN(CMP)
987     {
988     int rd = bits(insn,23,25);
989     int ra = bits(insn,16,20);
990     int rb = bits(insn,11,15);
991    
992     ppc32_load_gpr(b,X86_EBX,ra);
993     ppc32_alu_gpr(b,X86_CMP,X86_EBX,rb);
994     ppc32_update_cr(b,rd,TRUE);
995     return(0);
996     }
997    
998     /* CMPI - Compare Immediate */
999     DECLARE_INSN(CMPI)
1000     {
1001     int rd = bits(insn,23,25);
1002     int ra = bits(insn,16,20);
1003     m_uint16_t imm = bits(insn,0,15);
1004     m_uint32_t tmp = sign_extend_32(imm,16);
1005    
1006     ppc32_load_imm(b,X86_EBX,tmp);
1007     ppc32_load_gpr(b,X86_ESI,ra);
1008     x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ESI,X86_EBX);
1009    
1010     ppc32_update_cr(b,rd,TRUE);
1011     return(0);
1012     }
1013    
1014     /* CMPL - Compare Logical */
1015     DECLARE_INSN(CMPL)
1016     {
1017     int rd = bits(insn,23,25);
1018     int ra = bits(insn,16,20);
1019     int rb = bits(insn,11,15);
1020    
1021     ppc32_load_gpr(b,X86_EAX,ra);
1022     ppc32_alu_gpr(b,X86_CMP,X86_EAX,rb);
1023     ppc32_update_cr(b,rd,FALSE);
1024     return(0);
1025     }
1026    
1027     /* CMPLI - Compare Immediate */
1028     DECLARE_INSN(CMPLI)
1029     {
1030     int rd = bits(insn,23,25);
1031     int ra = bits(insn,16,20);
1032     m_uint16_t imm = bits(insn,0,15);
1033    
1034     ppc32_load_imm(b,X86_EBX,imm);
1035     ppc32_load_gpr(b,X86_ESI,ra);
1036     x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ESI,X86_EBX);
1037    
1038     ppc32_update_cr(b,rd,FALSE);
1039     return(0);
1040     }
1041    
1042     /* CRAND - Condition Register AND */
1043     DECLARE_INSN(CRAND)
1044     {
1045     int bd = bits(insn,21,25);
1046     int bb = bits(insn,16,20);
1047     int ba = bits(insn,11,15);
1048    
1049     ppc32_load_cr(b,X86_ESI);
1050    
1051     /* test $ba bit */
1052     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba)));
1053     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1054    
1055     /* test $bb bit */
1056     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb)));
1057     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1058    
1059     /* result of AND between $ba and $bb */
1060     x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EBX,X86_EAX);
1061     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1062    
1063     /* set/clear $bd bit depending on the result */
1064     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd)));
1065     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd));
1066     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX);
1067    
1068     ppc32_store_cr(b,X86_ESI);
1069     return(0);
1070     }
1071    
1072     /* CRANDC - Condition Register AND with Complement */
1073     DECLARE_INSN(CRANDC)
1074     {
1075     int bd = bits(insn,21,25);
1076     int bb = bits(insn,16,20);
1077     int ba = bits(insn,11,15);
1078    
1079     ppc32_load_cr(b,X86_ESI);
1080    
1081     /* test $ba bit */
1082     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba)));
1083     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1084    
1085     /* test $bb bit */
1086     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb)));
1087     x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE);
1088    
1089     /* result of AND between $ba and $bb */
1090     x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EBX,X86_EAX);
1091     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1092    
1093     /* set/clear $bd bit depending on the result */
1094     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd)));
1095     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd));
1096     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX);
1097    
1098     ppc32_store_cr(b,X86_ESI);
1099     return(0);
1100     }
1101    
1102     /* CREQV - Condition Register EQV */
1103     DECLARE_INSN(CREQV)
1104     {
1105     int bd = bits(insn,21,25);
1106     int bb = bits(insn,16,20);
1107     int ba = bits(insn,11,15);
1108    
1109     ppc32_load_cr(b,X86_ESI);
1110    
1111     /* test $ba bit */
1112     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba)));
1113     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1114    
1115     /* test $bb bit */
1116     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb)));
1117     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1118    
1119     /* result of XOR between $ba and $bb */
1120     x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EAX);
1121     x86_not_reg(b->jit_ptr,X86_EBX);
1122     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1123    
1124     /* set/clear $bd bit depending on the result */
1125     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd)));
1126     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd));
1127     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX);
1128    
1129     ppc32_store_cr(b,X86_ESI);
1130     return(0);
1131     }
1132    
1133     /* CRNAND - Condition Register NAND */
1134     DECLARE_INSN(CRNAND)
1135     {
1136     int bd = bits(insn,21,25);
1137     int bb = bits(insn,16,20);
1138     int ba = bits(insn,11,15);
1139    
1140     ppc32_load_cr(b,X86_ESI);
1141    
1142     /* test $ba bit */
1143     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba)));
1144     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1145    
1146     /* test $bb bit */
1147     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb)));
1148     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1149    
1150     /* result of NAND between $ba and $bb */
1151     x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EBX,X86_EAX);
1152     x86_not_reg(b->jit_ptr,X86_EBX);
1153     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1154    
1155     /* set/clear $bd bit depending on the result */
1156     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd)));
1157     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd));
1158     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX);
1159    
1160     ppc32_store_cr(b,X86_ESI);
1161     return(0);
1162     }
1163    
1164     /* CRNOR - Condition Register NOR */
1165     DECLARE_INSN(CRNOR)
1166     {
1167     int bd = bits(insn,21,25);
1168     int bb = bits(insn,16,20);
1169     int ba = bits(insn,11,15);
1170    
1171     ppc32_load_cr(b,X86_ESI);
1172    
1173     /* test $ba bit */
1174     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba)));
1175     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1176    
1177     /* test $bb bit */
1178     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb)));
1179     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1180    
1181     /* result of NOR between $ba and $bb */
1182     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
1183     x86_not_reg(b->jit_ptr,X86_EBX);
1184     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1185    
1186     /* set/clear $bd bit depending on the result */
1187     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd)));
1188     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd));
1189     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX);
1190    
1191     ppc32_store_cr(b,X86_ESI);
1192     return(0);
1193     }
1194    
1195     /* CROR - Condition Register OR */
1196     DECLARE_INSN(CROR)
1197     {
1198     int bd = bits(insn,21,25);
1199     int bb = bits(insn,16,20);
1200     int ba = bits(insn,11,15);
1201    
1202     ppc32_load_cr(b,X86_ESI);
1203    
1204     /* test $ba bit */
1205     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba)));
1206     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1207    
1208     /* test $bb bit */
1209     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb)));
1210     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1211    
1212     /* result of OR between $ba and $bb */
1213     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
1214     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1215    
1216     /* set/clear $bd bit depending on the result */
1217     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd)));
1218     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd));
1219     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX);
1220    
1221     ppc32_store_cr(b,X86_ESI);
1222     return(0);
1223     }
1224    
1225     /* CRORC - Condition Register OR with Complement */
1226     DECLARE_INSN(CRORC)
1227     {
1228     int bd = bits(insn,21,25);
1229     int bb = bits(insn,16,20);
1230     int ba = bits(insn,11,15);
1231    
1232     ppc32_load_cr(b,X86_ESI);
1233    
1234     /* test $ba bit */
1235     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba)));
1236     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1237    
1238     /* test $bb bit */
1239     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb)));
1240     x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE);
1241    
1242     /* result of ORC between $ba and $bb */
1243     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
1244     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1245    
1246     /* set/clear $bd bit depending on the result */
1247     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd)));
1248     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd));
1249     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX);
1250    
1251     ppc32_store_cr(b,X86_ESI);
1252     return(0);
1253     }
1254    
1255     /* CRXOR - Condition Register XOR */
1256     DECLARE_INSN(CRXOR)
1257     {
1258     int bd = bits(insn,21,25);
1259     int bb = bits(insn,16,20);
1260     int ba = bits(insn,11,15);
1261    
1262     ppc32_load_cr(b,X86_ESI);
1263    
1264     /* test $ba bit */
1265     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba)));
1266     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1267    
1268     /* test $bb bit */
1269     x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb)));
1270     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1271    
1272     /* result of XOR between $ba and $bb */
1273     x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EAX);
1274     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1275    
1276     /* set/clear $bd bit depending on the result */
1277     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd)));
1278     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd));
1279     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX);
1280    
1281     ppc32_store_cr(b,X86_ESI);
1282     return(0);
1283     }
1284    
1285     /* DIVWU - Divide Word Unsigned */
1286     DECLARE_INSN(DIVWU)
1287     {
1288     int rd = bits(insn,21,25);
1289     int ra = bits(insn,16,20);
1290     int rb = bits(insn,11,15);
1291    
1292     ppc32_load_gpr(b,X86_EAX,ra);
1293     ppc32_load_gpr(b,X86_EBX,rb);
1294     ppc32_load_imm(b,X86_EDX,0);
1295    
1296     x86_div_reg(b->jit_ptr,X86_EBX,0);
1297     ppc32_store_gpr(b,rd,X86_EAX);
1298    
1299     if (insn & 1) {
1300     x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
1301     ppc32_update_cr0(b);
1302     }
1303    
1304     return(0);
1305     }
1306    
1307     /* EQV */
1308     DECLARE_INSN(EQV)
1309     {
1310     int rs = bits(insn,21,25);
1311     int ra = bits(insn,16,20);
1312     int rb = bits(insn,11,15);
1313    
1314     /* $ra = ~($rs ^ $rb) */
1315     ppc32_load_gpr(b,X86_EBX,rs);
1316     ppc32_alu_gpr(b,X86_XOR,X86_EBX,rb);
1317     x86_not_reg(b->jit_ptr,X86_EBX);
1318     ppc32_store_gpr(b,ra,X86_EBX);
1319    
1320     if (insn & 1) {
1321     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1322     ppc32_update_cr0(b);
1323     }
1324    
1325     return(0);
1326     }
1327    
1328     /* EXTSB - Extend Sign Byte */
1329     DECLARE_INSN(EXTSB)
1330     {
1331     int rs = bits(insn,21,25);
1332     int ra = bits(insn,16,20);
1333    
1334     ppc32_load_gpr(b,X86_EBX,rs);
1335     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,24);
1336     x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,24);
1337     ppc32_store_gpr(b,ra,X86_EBX);
1338    
1339     if (insn & 1) {
1340     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1341     ppc32_update_cr0(b);
1342     }
1343    
1344     return(0);
1345     }
1346    
1347     /* EXTSH - Extend Sign Word */
1348     DECLARE_INSN(EXTSH)
1349     {
1350     int rs = bits(insn,21,25);
1351     int ra = bits(insn,16,20);
1352    
1353     ppc32_load_gpr(b,X86_EBX,rs);
1354     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,16);
1355     x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,16);
1356     ppc32_store_gpr(b,ra,X86_EBX);
1357    
1358     if (insn & 1) {
1359     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1360     ppc32_update_cr0(b);
1361     }
1362    
1363     return(0);
1364     }
1365    
1366     /* LBZ - Load Byte and Zero */
1367     DECLARE_INSN(LBZ)
1368     {
1369     int rs = bits(insn,21,25);
1370     int ra = bits(insn,16,20);
1371     m_uint16_t offset = bits(insn,0,15);
1372    
1373     //ppc32_emit_memop(b,PPC_MEMOP_LBZ,ra,offset,rs,0);
1374     ppc32_emit_memop_fast(b,0,PPC_MEMOP_LBZ,ra,offset,rs,ppc32_memop_fast_lbz);
1375     return(0);
1376     }
1377    
1378     /* LBZU - Load Byte and Zero with Update */
1379     DECLARE_INSN(LBZU)
1380     {
1381     int rs = bits(insn,21,25);
1382     int ra = bits(insn,16,20);
1383     m_uint16_t offset = bits(insn,0,15);
1384    
1385     ppc32_emit_memop(b,PPC_MEMOP_LBZ,ra,offset,rs,1);
1386     return(0);
1387     }
1388    
1389     /* LBZUX - Load Byte and Zero with Update Indexed */
1390     DECLARE_INSN(LBZUX)
1391     {
1392     int rs = bits(insn,21,25);
1393     int ra = bits(insn,16,20);
1394     int rb = bits(insn,11,15);
1395    
1396     ppc32_emit_memop_idx(b,PPC_MEMOP_LBZ,ra,rb,rs,1);
1397     return(0);
1398     }
1399    
1400     /* LBZX - Load Byte and Zero Indexed */
1401     DECLARE_INSN(LBZX)
1402     {
1403     int rs = bits(insn,21,25);
1404     int ra = bits(insn,16,20);
1405     int rb = bits(insn,11,15);
1406    
1407     ppc32_emit_memop_idx(b,PPC_MEMOP_LBZ,ra,rb,rs,0);
1408     return(0);
1409     }
1410    
1411     /* LHA - Load Half-Word Algebraic */
1412     DECLARE_INSN(LHA)
1413     {
1414     int rs = bits(insn,21,25);
1415     int ra = bits(insn,16,20);
1416     m_uint16_t offset = bits(insn,0,15);
1417    
1418     ppc32_emit_memop(b,PPC_MEMOP_LHA,ra,offset,rs,0);
1419     return(0);
1420     }
1421    
1422     /* LHAU - Load Half-Word Algebraic with Update */
1423     DECLARE_INSN(LHAU)
1424     {
1425     int rs = bits(insn,21,25);
1426     int ra = bits(insn,16,20);
1427     m_uint16_t offset = bits(insn,0,15);
1428    
1429     ppc32_emit_memop(b,PPC_MEMOP_LHA,ra,offset,rs,1);
1430     return(0);
1431     }
1432    
1433     /* LHAUX - Load Half-Word Algebraic with Update Indexed */
1434     DECLARE_INSN(LHAUX)
1435     {
1436     int rs = bits(insn,21,25);
1437     int ra = bits(insn,16,20);
1438     int rb = bits(insn,11,15);
1439    
1440     ppc32_emit_memop_idx(b,PPC_MEMOP_LHA,ra,rb,rs,1);
1441     return(0);
1442     }
1443    
1444     /* LHAX - Load Half-Word Algebraic Indexed */
1445     DECLARE_INSN(LHAX)
1446     {
1447     int rs = bits(insn,21,25);
1448     int ra = bits(insn,16,20);
1449     int rb = bits(insn,11,15);
1450    
1451     ppc32_emit_memop_idx(b,PPC_MEMOP_LHA,ra,rb,rs,0);
1452     return(0);
1453     }
1454    
1455     /* LHZ - Load Half-Word and Zero */
1456     DECLARE_INSN(LHZ)
1457     {
1458     int rs = bits(insn,21,25);
1459     int ra = bits(insn,16,20);
1460     m_uint16_t offset = bits(insn,0,15);
1461    
1462     ppc32_emit_memop(b,PPC_MEMOP_LHZ,ra,offset,rs,0);
1463     return(0);
1464     }
1465    
1466     /* LHZU - Load Half-Word and Zero with Update */
1467     DECLARE_INSN(LHZU)
1468     {
1469     int rs = bits(insn,21,25);
1470     int ra = bits(insn,16,20);
1471     m_uint16_t offset = bits(insn,0,15);
1472    
1473     ppc32_emit_memop(b,PPC_MEMOP_LHZ,ra,offset,rs,1);
1474     return(0);
1475     }
1476    
1477     /* LHZUX - Load Half-Word and Zero with Update Indexed */
1478     DECLARE_INSN(LHZUX)
1479     {
1480     int rs = bits(insn,21,25);
1481     int ra = bits(insn,16,20);
1482     int rb = bits(insn,11,15);
1483    
1484     ppc32_emit_memop_idx(b,PPC_MEMOP_LHZ,ra,rb,rs,1);
1485     return(0);
1486     }
1487    
1488     /* LHZX - Load Half-Word and Zero Indexed */
1489     DECLARE_INSN(LHZX)
1490     {
1491     int rs = bits(insn,21,25);
1492     int ra = bits(insn,16,20);
1493     int rb = bits(insn,11,15);
1494    
1495     ppc32_emit_memop_idx(b,PPC_MEMOP_LHZ,ra,rb,rs,0);
1496     return(0);
1497     }
1498    
1499     /* LWZ - Load Word and Zero */
1500     DECLARE_INSN(LWZ)
1501     {
1502     int rs = bits(insn,21,25);
1503     int ra = bits(insn,16,20);
1504     m_uint16_t offset = bits(insn,0,15);
1505    
1506     //ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,0);
1507     ppc32_emit_memop_fast(b,0,PPC_MEMOP_LWZ,ra,offset,rs,ppc32_memop_fast_lwz);
1508     return(0);
1509     }
1510    
1511     /* LWZU - Load Word and Zero with Update */
1512     DECLARE_INSN(LWZU)
1513     {
1514     int rs = bits(insn,21,25);
1515     int ra = bits(insn,16,20);
1516     m_uint16_t offset = bits(insn,0,15);
1517    
1518     ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,1);
1519     return(0);
1520     }
1521    
1522     /* LWZUX - Load Word and Zero with Update Indexed */
1523     DECLARE_INSN(LWZUX)
1524     {
1525     int rs = bits(insn,21,25);
1526     int ra = bits(insn,16,20);
1527     int rb = bits(insn,11,15);
1528    
1529     ppc32_emit_memop_idx(b,PPC_MEMOP_LWZ,ra,rb,rs,1);
1530     return(0);
1531     }
1532    
1533     /* LWZX - Load Word and Zero Indexed */
1534     DECLARE_INSN(LWZX)
1535     {
1536     int rs = bits(insn,21,25);
1537     int ra = bits(insn,16,20);
1538     int rb = bits(insn,11,15);
1539    
1540     ppc32_emit_memop_idx(b,PPC_MEMOP_LWZ,ra,rb,rs,0);
1541     return(0);
1542     }
1543    
1544     /* MCRF - Move Condition Register Field */
1545     DECLARE_INSN(MCRF)
1546     {
1547     int rd = bits(insn,23,25);
1548     int rs = bits(insn,18,20);
1549     m_uint32_t dmask;
1550    
1551     /* %eax = %ebx = CR */
1552     ppc32_load_cr(b,X86_EAX);
1553     x86_mov_reg_reg(b->jit_ptr,X86_EBX,X86_EAX,4);
1554    
1555     x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EBX,(28 - (rs << 2)));
1556     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x0F);
1557     x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(28 - (rd << 2)));
1558    
1559     /* clear the destination bits */
1560     dmask = (0xF0000000 >> (rd << 2));
1561     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,~dmask);
1562    
1563     /* set the new field value */
1564     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_EBX);
1565     ppc32_store_cr(b,X86_EAX);
1566     return(0);
1567     }
1568    
1569     /* MFCR - Move from Condition Register */
1570     DECLARE_INSN(MFCR)
1571     {
1572     int rd = bits(insn,21,25);
1573    
1574     ppc32_load_cr(b,X86_EAX);
1575     ppc32_store_gpr(b,rd,X86_EAX);
1576     return(0);
1577     }
1578    
1579     /* MFMSR - Move from Machine State Register */
1580     DECLARE_INSN(MFMSR)
1581     {
1582     int rd = bits(insn,21,25);
1583    
1584     x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,OFFSET(cpu_ppc_t,msr),4);
1585     ppc32_store_gpr(b,rd,X86_EAX);
1586     return(0);
1587     }
1588    
1589     /* MFSR - Move From Segment Register */
1590     DECLARE_INSN(MFSR)
1591     {
1592     int rd = bits(insn,21,25);
1593     int sr = bits(insn,16,19);
1594    
1595     x86_mov_reg_membase(b->jit_ptr,X86_EAX,
1596     X86_EDI,(OFFSET(cpu_ppc_t,sr) + (sr << 2)),4);
1597     ppc32_store_gpr(b,rd,X86_EAX);
1598     return(0);
1599     }
1600    
1601     /* MTCRF - Move to Condition Register Fields */
1602     DECLARE_INSN(MTCRF)
1603     {
1604     int rs = bits(insn,21,25);
1605     int crm = bits(insn,12,19);
1606     m_uint32_t mask = 0;
1607     int i;
1608    
1609     for(i=0;i<8;i++)
1610     if (crm & (1 << i))
1611     mask |= 0xF << (i << 2);
1612    
1613     ppc32_load_cr(b,X86_EAX);
1614     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,~mask);
1615    
1616     ppc32_load_gpr(b,X86_EDX,rs);
1617     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EDX,mask);
1618    
1619     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EDX,X86_EAX);
1620     ppc32_store_cr(b,X86_EDX);
1621     return(0);
1622     }
1623    
1624     /* MULHW - Multiply High Word */
1625     DECLARE_INSN(MULHW)
1626     {
1627     int rd = bits(insn,21,25);
1628     int ra = bits(insn,16,20);
1629     int rb = bits(insn,11,15);
1630    
1631     ppc32_load_gpr(b,X86_EAX,ra);
1632     ppc32_load_gpr(b,X86_EBX,rb);
1633     x86_mul_reg(b->jit_ptr,X86_EBX,1);
1634     ppc32_store_gpr(b,rd,X86_EDX);
1635    
1636     if (insn & 1) {
1637     x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
1638     ppc32_update_cr0(b);
1639     }
1640    
1641     return(0);
1642     }
1643    
1644     /* MULHWU - Multiply High Word Unsigned */
1645     DECLARE_INSN(MULHWU)
1646     {
1647     int rd = bits(insn,21,25);
1648     int ra = bits(insn,16,20);
1649     int rb = bits(insn,11,15);
1650    
1651     ppc32_load_gpr(b,X86_EAX,ra);
1652     ppc32_load_gpr(b,X86_EBX,rb);
1653     x86_mul_reg(b->jit_ptr,X86_EBX,0);
1654     ppc32_store_gpr(b,rd,X86_EDX);
1655    
1656     if (insn & 1) {
1657     x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
1658     ppc32_update_cr0(b);
1659     }
1660    
1661     return(0);
1662     }
1663    
1664     /* MULLI - Multiply Low Immediate */
1665     DECLARE_INSN(MULLI)
1666     {
1667     int rd = bits(insn,21,25);
1668     int ra = bits(insn,16,20);
1669     m_uint32_t imm = bits(insn,0,15);
1670    
1671     ppc32_load_gpr(b,X86_EAX,ra);
1672     ppc32_load_imm(b,X86_EBX,sign_extend_32(imm,16));
1673    
1674     x86_mul_reg(b->jit_ptr,X86_EBX,1);
1675     ppc32_store_gpr(b,rd,X86_EAX);
1676     return(0);
1677     }
1678    
1679     /* MULLW - Multiply Low Word */
1680     DECLARE_INSN(MULLW)
1681     {
1682     int rd = bits(insn,21,25);
1683     int ra = bits(insn,16,20);
1684     int rb = bits(insn,11,15);
1685    
1686     ppc32_load_gpr(b,X86_EAX,ra);
1687     ppc32_load_gpr(b,X86_EBX,rb);
1688     x86_mul_reg(b->jit_ptr,X86_EBX,1);
1689     ppc32_store_gpr(b,rd,X86_EAX);
1690    
1691     if (insn & 1) {
1692     x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
1693     ppc32_update_cr0(b);
1694     }
1695    
1696     return(0);
1697     }
1698    
1699     /* NAND */
1700     DECLARE_INSN(NAND)
1701     {
1702     int rs = bits(insn,21,25);
1703     int ra = bits(insn,16,20);
1704     int rb = bits(insn,11,15);
1705    
1706     /* $ra = ~($rs & $rb) */
1707     ppc32_load_gpr(b,X86_EBX,rs);
1708     ppc32_alu_gpr(b,X86_AND,X86_EBX,rb);
1709     x86_not_reg(b->jit_ptr,X86_EBX);
1710     ppc32_store_gpr(b,ra,X86_EBX);
1711    
1712     if (insn & 1) {
1713     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1714     ppc32_update_cr0(b);
1715     }
1716    
1717     return(0);
1718     }
1719    
1720     /* NEG */
1721     DECLARE_INSN(NEG)
1722     {
1723     int rd = bits(insn,21,25);
1724     int ra = bits(insn,16,20);
1725    
1726     ppc32_load_gpr(b,X86_EBX,ra);
1727     x86_neg_reg(b->jit_ptr,X86_EBX);
1728     ppc32_store_gpr(b,rd,X86_EBX);
1729    
1730     if (insn & 1) {
1731     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1732     ppc32_update_cr0(b);
1733     }
1734    
1735     return(0);
1736     }
1737    
1738     /* NOR */
1739     DECLARE_INSN(NOR)
1740     {
1741     int rs = bits(insn,21,25);
1742     int ra = bits(insn,16,20);
1743     int rb = bits(insn,11,15);
1744    
1745     /* $ra = ~($rs | $rb) */
1746     ppc32_load_gpr(b,X86_EBX,rs);
1747     ppc32_alu_gpr(b,X86_OR,X86_EBX,rb);
1748     x86_not_reg(b->jit_ptr,X86_EBX);
1749     ppc32_store_gpr(b,ra,X86_EBX);
1750    
1751     if (insn & 1) {
1752     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1753     ppc32_update_cr0(b);
1754     }
1755    
1756     return(0);
1757     }
1758    
1759     /* OR */
1760     DECLARE_INSN(OR)
1761     {
1762     int rs = bits(insn,21,25);
1763     int ra = bits(insn,16,20);
1764     int rb = bits(insn,11,15);
1765    
1766     ppc32_load_gpr(b,X86_ECX,rs);
1767    
1768     if (rs != rb)
1769     ppc32_alu_gpr(b,X86_OR,X86_ECX,rb);
1770    
1771     ppc32_store_gpr(b,ra,X86_ECX);
1772    
1773     if (insn & 1) {
1774     if (rs == rb)
1775     x86_test_reg_reg(b->jit_ptr,X86_ECX,X86_ECX);
1776     ppc32_update_cr0(b);
1777     }
1778    
1779     return(0);
1780     }
1781    
1782     /* OR with Complement */
1783     DECLARE_INSN(ORC)
1784     {
1785     int rs = bits(insn,21,25);
1786     int ra = bits(insn,16,20);
1787     int rb = bits(insn,11,15);
1788    
1789     /* $ra = $rs | ~$rb */
1790     ppc32_load_gpr(b,X86_EBX,rb);
1791     x86_not_reg(b->jit_ptr,X86_EBX);
1792     ppc32_alu_gpr(b,X86_OR,X86_EBX,rs);
1793     ppc32_store_gpr(b,ra,X86_EBX);
1794    
1795     if (insn & 1)
1796     ppc32_update_cr0(b);
1797    
1798     return(0);
1799     }
1800    
1801     /* OR Immediate */
1802     DECLARE_INSN(ORI)
1803     {
1804     int rs = bits(insn,21,25);
1805     int ra = bits(insn,16,20);
1806     m_uint16_t imm = bits(insn,0,15);
1807    
1808     /* $ra = $rs | imm */
1809     ppc32_load_imm(b,X86_EBX,imm);
1810     ppc32_alu_gpr(b,X86_OR,X86_EBX,rs);
1811     ppc32_store_gpr(b,ra,X86_EBX);
1812     return(0);
1813     }
1814    
1815     /* OR Immediate Shifted */
1816     DECLARE_INSN(ORIS)
1817     {
1818     int rs = bits(insn,21,25);
1819     int ra = bits(insn,16,20);
1820     m_uint32_t imm = bits(insn,0,15);
1821    
1822     /* $ra = $rs | (imm << 16) */
1823     ppc32_load_imm(b,X86_EBX,imm << 16);
1824     ppc32_alu_gpr(b,X86_OR,X86_EBX,rs);
1825     ppc32_store_gpr(b,ra,X86_EBX);
1826     return(0);
1827     }
1828    
1829     /* RLWIMI - Rotate Left Word Immediate then Mask Insert */
1830     DECLARE_INSN(RLWIMI)
1831     {
1832     int rs = bits(insn,21,25);
1833     int ra = bits(insn,16,20);
1834     int sh = bits(insn,11,15);
1835     int mb = bits(insn,6,10);
1836     int me = bits(insn,1,5);
1837     register m_uint32_t mask;
1838    
1839     mask = ppc32_rotate_mask(mb,me);
1840    
1841     /* Apply inverse mask to %eax "ra" */
1842     ppc32_load_gpr(b,X86_EAX,ra);
1843     if (mask != 0)
1844     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,~mask);
1845    
1846     /* Rotate %ebx ("rs") of "sh" bits and apply the mask */
1847     ppc32_load_gpr(b,X86_EBX,rs);
1848    
1849     if (sh != 0)
1850     x86_shift_reg_imm(b->jit_ptr,X86_ROL,X86_EBX,sh);
1851    
1852     if (mask != 0xFFFFFFFF)
1853     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,mask);
1854    
1855     /* Store the result */
1856     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
1857     ppc32_store_gpr(b,ra,X86_EBX);
1858    
1859     if (insn & 1)
1860     ppc32_update_cr0(b);
1861    
1862     return(0);
1863     }
1864    
1865     /* RLWINM - Rotate Left Word Immediate AND with Mask */
1866     DECLARE_INSN(RLWINM)
1867     {
1868     int rs = bits(insn,21,25);
1869     int ra = bits(insn,16,20);
1870     int sh = bits(insn,11,15);
1871     int mb = bits(insn,6,10);
1872     int me = bits(insn,1,5);
1873     register m_uint32_t mask;
1874    
1875     mask = ppc32_rotate_mask(mb,me);
1876    
1877     /* Rotate %ebx ("rs") of "sh" bits and apply the mask */
1878     ppc32_load_gpr(b,X86_EBX,rs);
1879    
1880     if (sh != 0)
1881     x86_shift_reg_imm(b->jit_ptr,X86_ROL,X86_EBX,sh);
1882    
1883     if (mask != 0xFFFFFFFF)
1884     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,mask);
1885    
1886     ppc32_store_gpr(b,ra,X86_EBX);
1887    
1888     if (insn & 1) {
1889     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1890     ppc32_update_cr0(b);
1891     }
1892    
1893     return(0);
1894     }
1895    
1896     /* RLWNM - Rotate Left Word then Mask Insert */
1897     DECLARE_INSN(RLWNM)
1898     {
1899     int rs = bits(insn,21,25);
1900     int ra = bits(insn,16,20);
1901     int rb = bits(insn,11,15);
1902     int mb = bits(insn,6,10);
1903     int me = bits(insn,1,5);
1904     register m_uint32_t mask;
1905    
1906     mask = ppc32_rotate_mask(mb,me);
1907    
1908     /* Load the shift register ("sh") */
1909     ppc32_load_gpr(b,X86_ECX,rb);
1910    
1911     /* Rotate %ebx ("rs") and apply the mask */
1912     ppc32_load_gpr(b,X86_EBX,rs);
1913     x86_shift_reg(b->jit_ptr,X86_ROL,X86_EBX);
1914    
1915     if (mask != 0xFFFFFFFF)
1916     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,mask);
1917    
1918     ppc32_store_gpr(b,ra,X86_EBX);
1919    
1920     if (insn & 1) {
1921     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1922     ppc32_update_cr0(b);
1923     }
1924    
1925     return(0);
1926     }
1927    
1928     /* Shift Left Word */
1929     DECLARE_INSN(SLW)
1930     {
1931     int rs = bits(insn,21,25);
1932     int ra = bits(insn,16,20);
1933     int rb = bits(insn,11,15);
1934     u_char *test1;
1935    
1936     /* If count >= 32, then null result */
1937     ppc32_load_gpr(b,X86_ECX,rb);
1938     x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EBX);
1939    
1940     x86_test_reg_imm(b->jit_ptr,X86_ECX,0x20);
1941     test1 = b->jit_ptr;
1942     x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
1943    
1944     ppc32_load_gpr(b,X86_EBX,rs);
1945     x86_shift_reg(b->jit_ptr,X86_SHL,X86_EBX);
1946    
1947     /* Store the result */
1948     x86_patch(test1,b->jit_ptr);
1949     ppc32_store_gpr(b,ra,X86_EBX);
1950    
1951     if (insn & 1) {
1952     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1953     ppc32_update_cr0(b);
1954     }
1955    
1956     return(0);
1957     }
1958    
1959     /* SRAWI - Shift Right Algebraic Word Immediate */
1960     DECLARE_INSN(SRAWI)
1961     {
1962     int rs = bits(insn,21,25);
1963     int ra = bits(insn,16,20);
1964     int sh = bits(insn,11,15);
1965     register m_uint32_t mask;
1966    
1967     mask = ~(0xFFFFFFFFU << sh);
1968    
1969     /* $ra = (int32)$rs >> sh */
1970     ppc32_load_gpr(b,X86_EBX,rs);
1971     x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EBX,4);
1972     x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,sh);
1973     ppc32_store_gpr(b,ra,X86_EBX);
1974    
1975     /* test the sign-bit of gpr[rs] */
1976     x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
1977     x86_set_reg(b->jit_ptr,X86_CC_LT,X86_EAX,TRUE);
1978    
1979     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,mask);
1980     x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_ECX,TRUE);
1981    
1982     x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_ECX,X86_EAX);
1983     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,0x1);
1984     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_ECX,4);
1985    
1986     if (insn & 1) {
1987     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1988     ppc32_update_cr0(b);
1989     }
1990    
1991     return(0);
1992     }
1993    
1994     /* Shift Right Word */
1995     DECLARE_INSN(SRW)
1996     {
1997     int rs = bits(insn,21,25);
1998     int ra = bits(insn,16,20);
1999     int rb = bits(insn,11,15);
2000     u_char *test1;
2001    
2002     /* If count >= 32, then null result */
2003     ppc32_load_gpr(b,X86_ECX,rb);
2004     x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EBX);
2005    
2006     x86_test_reg_imm(b->jit_ptr,X86_ECX,0x20);
2007     test1 = b->jit_ptr;
2008     x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
2009    
2010     ppc32_load_gpr(b,X86_EBX,rs);
2011     x86_shift_reg(b->jit_ptr,X86_SHR,X86_EBX);
2012    
2013     /* Store the result */
2014     x86_patch(test1,b->jit_ptr);
2015     ppc32_store_gpr(b,ra,X86_EBX);
2016    
2017     if (insn & 1) {
2018     x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
2019     ppc32_update_cr0(b);
2020     }
2021    
2022     return(0);
2023     }
2024    
2025     /* STB - Store Byte */
2026     DECLARE_INSN(STB)
2027     {
2028     int rs = bits(insn,21,25);
2029     int ra = bits(insn,16,20);
2030     m_uint16_t offset = bits(insn,0,15);
2031    
2032     //ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,0);
2033     ppc32_emit_memop_fast(b,1,PPC_MEMOP_STB,ra,offset,rs,ppc32_memop_fast_stb);
2034     return(0);
2035     }
2036    
2037     /* STBU - Store Byte with Update */
2038     DECLARE_INSN(STBU)
2039     {
2040     int rs = bits(insn,21,25);
2041     int ra = bits(insn,16,20);
2042     m_uint16_t offset = bits(insn,0,15);
2043    
2044     ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,1);
2045     return(0);
2046     }
2047    
2048     /* STBUX - Store Byte with Update Indexed */
2049     DECLARE_INSN(STBUX)
2050     {
2051     int rs = bits(insn,21,25);
2052     int ra = bits(insn,16,20);
2053     int rb = bits(insn,11,15);
2054    
2055     ppc32_emit_memop_idx(b,PPC_MEMOP_STB,ra,rb,rs,1);
2056     return(0);
2057     }
2058    
2059     /* STBUX - Store Byte Indexed */
2060     DECLARE_INSN(STBX)
2061     {
2062     int rs = bits(insn,21,25);
2063     int ra = bits(insn,16,20);
2064     int rb = bits(insn,11,15);
2065    
2066     ppc32_emit_memop_idx(b,PPC_MEMOP_STB,ra,rb,rs,0);
2067     return(0);
2068     }
2069    
2070     /* STH - Store Half-Word */
2071     DECLARE_INSN(STH)
2072     {
2073     int rs = bits(insn,21,25);
2074     int ra = bits(insn,16,20);
2075     m_uint16_t offset = bits(insn,0,15);
2076    
2077     ppc32_emit_memop(b,PPC_MEMOP_STH,ra,offset,rs,0);
2078     return(0);
2079     }
2080    
2081     /* STHU - Store Half-Word with Update */
2082     DECLARE_INSN(STHU)
2083     {
2084     int rs = bits(insn,21,25);
2085     int ra = bits(insn,16,20);
2086     m_uint16_t offset = bits(insn,0,15);
2087    
2088     ppc32_emit_memop(b,PPC_MEMOP_STH,ra,offset,rs,1);
2089     return(0);
2090     }
2091    
2092     /* STHUX - Store Half-Word with Update Indexed */
2093     DECLARE_INSN(STHUX)
2094     {
2095     int rs = bits(insn,21,25);
2096     int ra = bits(insn,16,20);
2097     int rb = bits(insn,11,15);
2098    
2099     ppc32_emit_memop_idx(b,PPC_MEMOP_STH,ra,rb,rs,1);
2100     return(0);
2101     }
2102    
2103     /* STHUX - Store Half-Word Indexed */
2104     DECLARE_INSN(STHX)
2105     {
2106     int rs = bits(insn,21,25);
2107     int ra = bits(insn,16,20);
2108     int rb = bits(insn,11,15);
2109    
2110     ppc32_emit_memop_idx(b,PPC_MEMOP_STH,ra,rb,rs,0);
2111     return(0);
2112     }
2113    
2114     /* STW - Store Word */
2115     DECLARE_INSN(STW)
2116     {
2117     int rs = bits(insn,21,25);
2118     int ra = bits(insn,16,20);
2119     m_uint16_t offset = bits(insn,0,15);
2120    
2121     //ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,0);
2122     ppc32_emit_memop_fast(b,1,PPC_MEMOP_STW,ra,offset,rs,ppc32_memop_fast_stw);
2123     return(0);
2124     }
2125    
2126     /* STWU - Store Word with Update */
2127     DECLARE_INSN(STWU)
2128     {
2129     int rs = bits(insn,21,25);
2130     int ra = bits(insn,16,20);
2131     m_uint16_t offset = bits(insn,0,15);
2132    
2133     ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,1);
2134     return(0);
2135     }
2136    
2137     /* STWUX - Store Word with Update Indexed */
2138     DECLARE_INSN(STWUX)
2139     {
2140     int rs = bits(insn,21,25);
2141     int ra = bits(insn,16,20);
2142     int rb = bits(insn,11,15);
2143    
2144     ppc32_emit_memop_idx(b,PPC_MEMOP_STW,ra,rb,rs,1);
2145     return(0);
2146     }
2147    
2148     /* STWUX - Store Word Indexed */
2149     DECLARE_INSN(STWX)
2150     {
2151     int rs = bits(insn,21,25);
2152     int ra = bits(insn,16,20);
2153     int rb = bits(insn,11,15);
2154    
2155     ppc32_emit_memop_idx(b,PPC_MEMOP_STW,ra,rb,rs,0);
2156     return(0);
2157     }
2158    
2159     /* SUBF - Subtract From */
2160     DECLARE_INSN(SUBF)
2161     {
2162     int rd = bits(insn,21,25);
2163     int ra = bits(insn,16,20);
2164     int rb = bits(insn,11,15);
2165    
2166     /* $rd = $rb - $rb */
2167     ppc32_load_gpr(b,X86_EBX,rb);
2168     ppc32_alu_gpr(b,X86_SUB,X86_EBX,ra);
2169     ppc32_store_gpr(b,rd,X86_EBX);
2170    
2171     if (insn & 1)
2172     ppc32_update_cr0(b);
2173    
2174     return(0);
2175     }
2176    
2177     /* SUBFC - Subtract From Carrying */
2178     DECLARE_INSN(SUBFC)
2179     {
2180     int rd = bits(insn,21,25);
2181     int ra = bits(insn,16,20);
2182     int rb = bits(insn,11,15);
2183    
2184     /* ~$ra + 1 */
2185     ppc32_load_gpr(b,X86_ESI,ra);
2186     x86_not_reg(b->jit_ptr,X86_ESI);
2187     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESI,1);
2188     x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
2189    
2190     /* add $rb */
2191     ppc32_alu_gpr(b,X86_ADD,X86_ESI,rb);
2192     x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
2193    
2194     ppc32_store_gpr(b,rd,X86_ESI);
2195    
2196     /* store the carry flag */
2197     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
2198     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
2199    
2200     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
2201    
2202     /* update cr0 */
2203     if (insn & 1) {
2204     x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
2205     ppc32_update_cr0(b);
2206     }
2207    
2208     return(0);
2209     }
2210    
2211     /* SUBFE - Subtract From Extended */
2212     DECLARE_INSN(SUBFE)
2213     {
2214     int rd = bits(insn,21,25);
2215     int ra = bits(insn,16,20);
2216     int rb = bits(insn,11,15);
2217    
2218     /* ~$ra + carry */
2219     ppc32_load_gpr(b,X86_ESI,ra);
2220     x86_not_reg(b->jit_ptr,X86_ESI);
2221     x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_ESI,
2222     X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
2223     x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
2224    
2225     /* add $rb */
2226     ppc32_alu_gpr(b,X86_ADD,X86_ESI,rb);
2227     x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
2228    
2229     ppc32_store_gpr(b,rd,X86_ESI);
2230    
2231     /* store the carry flag */
2232     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
2233     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
2234     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
2235    
2236     /* update cr0 */
2237     if (insn & 1) {
2238     x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
2239     ppc32_update_cr0(b);
2240     }
2241    
2242     return(0);
2243     }
2244    
2245     /* SUBFIC - Subtract From Immediate Carrying */
2246     DECLARE_INSN(SUBFIC)
2247     {
2248     int rd = bits(insn,21,25);
2249     int ra = bits(insn,16,20);
2250     m_uint16_t imm = bits(insn,0,15);
2251     m_uint32_t tmp = sign_extend_32(imm,16);
2252    
2253     /* ~$ra + 1 */
2254     ppc32_load_gpr(b,X86_ESI,ra);
2255     x86_not_reg(b->jit_ptr,X86_ESI);
2256     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESI,1);
2257     x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
2258    
2259     /* add sign-extended $immediate */
2260     x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESI,tmp);
2261     x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
2262    
2263     ppc32_store_gpr(b,rd,X86_ESI);
2264    
2265     /* store the carry flag */
2266     x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
2267     x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
2268    
2269     x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
2270     return(0);
2271     }
2272    
2273     /* SYNC - Synchronize */
2274     DECLARE_INSN(SYNC)
2275     {
2276     return(0);
2277     }
2278    
2279     /* XOR */
2280     DECLARE_INSN(XOR)
2281     {
2282     int rs = bits(insn,21,25);
2283     int ra = bits(insn,16,20);
2284     int rb = bits(insn,11,15);
2285    
2286     ppc32_load_gpr(b,X86_EBX,rs);
2287     ppc32_alu_gpr(b,X86_XOR,X86_EBX,rb);
2288     ppc32_store_gpr(b,ra,X86_EBX);
2289    
2290     if (insn & 1)
2291     ppc32_update_cr0(b);
2292    
2293     return(0);
2294     }
2295    
2296     /* XORI - XOR Immediate */
2297     DECLARE_INSN(XORI)
2298     {
2299     int rs = bits(insn,21,25);
2300     int ra = bits(insn,16,20);
2301     m_uint32_t imm = bits(insn,0,15);
2302    
2303     ppc32_load_imm(b,X86_EBX,imm);
2304     ppc32_alu_gpr(b,X86_XOR,X86_EBX,rs);
2305     ppc32_store_gpr(b,ra,X86_EBX);
2306     return(0);
2307     }
2308    
2309     /* XORIS - XOR Immediate Shifted */
2310     DECLARE_INSN(XORIS)
2311     {
2312     int rs = bits(insn,21,25);
2313     int ra = bits(insn,16,20);
2314     m_uint32_t imm = bits(insn,0,15);
2315    
2316     ppc32_load_imm(b,X86_EBX,imm << 16);
2317     ppc32_alu_gpr(b,X86_XOR,X86_EBX,rs);
2318     ppc32_store_gpr(b,ra,X86_EBX);
2319     return(0);
2320     }
2321    
2322     /* PPC instruction array */
2323     struct ppc32_insn_tag ppc32_insn_tags[] = {
2324     { ppc32_emit_BLR , 0xfffffffe , 0x4e800020 },
2325     { ppc32_emit_BCTR , 0xfffffffe , 0x4e800420 },
2326     { ppc32_emit_MFLR , 0xfc1fffff , 0x7c0802a6 },
2327     { ppc32_emit_MTLR , 0xfc1fffff , 0x7c0803a6 },
2328     { ppc32_emit_MFCTR , 0xfc1fffff , 0x7c0902a6 },
2329     { ppc32_emit_MTCTR , 0xfc1fffff , 0x7c0903a6 },
2330     { ppc32_emit_MFTBL , 0xfc1ff7ff , 0x7c0c42e6 },
2331     { ppc32_emit_MFTBU , 0xfc1ff7ff , 0x7c0d42e6 },
2332     { ppc32_emit_ADD , 0xfc0007fe , 0x7c000214 },
2333     { ppc32_emit_ADDC , 0xfc0007fe , 0x7c000014 },
2334     { ppc32_emit_ADDE , 0xfc0007fe , 0x7c000114 },
2335     { ppc32_emit_ADDI , 0xfc000000 , 0x38000000 },
2336     { ppc32_emit_ADDIC , 0xfc000000 , 0x30000000 },
2337     { ppc32_emit_ADDIC_dot , 0xfc000000 , 0x34000000 },
2338     { ppc32_emit_ADDIS , 0xfc000000 , 0x3c000000 },
2339     { ppc32_emit_AND , 0xfc0007fe , 0x7c000038 },
2340     { ppc32_emit_ANDC , 0xfc0007fe , 0x7c000078 },
2341     { ppc32_emit_ANDI , 0xfc000000 , 0x70000000 },
2342     { ppc32_emit_ANDIS , 0xfc000000 , 0x74000000 },
2343     { ppc32_emit_B , 0xfc000003 , 0x48000000 },
2344     { ppc32_emit_BA , 0xfc000003 , 0x48000002 },
2345     { ppc32_emit_BL , 0xfc000003 , 0x48000001 },
2346     { ppc32_emit_BLA , 0xfc000003 , 0x48000003 },
2347     { ppc32_emit_BCC , 0xfe800000 , 0x40800000 },
2348     { ppc32_emit_BC , 0xfc000000 , 0x40000000 },
2349     { ppc32_emit_BCLR , 0xfc00fffe , 0x4c000020 },
2350     { ppc32_emit_CMP , 0xfc6007ff , 0x7c000000 },
2351     { ppc32_emit_CMPI , 0xfc600000 , 0x2c000000 },
2352     { ppc32_emit_CMPL , 0xfc6007ff , 0x7c000040 },
2353     { ppc32_emit_CMPLI , 0xfc600000 , 0x28000000 },
2354     { ppc32_emit_CRAND , 0xfc0007ff , 0x4c000202 },
2355     { ppc32_emit_CRANDC , 0xfc0007ff , 0x4c000102 },
2356     { ppc32_emit_CREQV , 0xfc0007ff , 0x4c000242 },
2357     { ppc32_emit_CRNAND , 0xfc0007ff , 0x4c0001c2 },
2358     { ppc32_emit_CRNOR , 0xfc0007ff , 0x4c000042 },
2359     { ppc32_emit_CROR , 0xfc0007ff , 0x4c000382 },
2360     { ppc32_emit_CRORC , 0xfc0007ff , 0x4c000342 },
2361     { ppc32_emit_CRXOR , 0xfc0007ff , 0x4c000182 },
2362     { ppc32_emit_DIVWU , 0xfc0007fe , 0x7c000396 },
2363     { ppc32_emit_EQV , 0xfc0007fe , 0x7c000238 },
2364     { ppc32_emit_EXTSB , 0xfc00fffe , 0x7c000774 },
2365     { ppc32_emit_EXTSH , 0xfc00fffe , 0x7c000734 },
2366     { ppc32_emit_LBZ , 0xfc000000 , 0x88000000 },
2367     { ppc32_emit_LBZU , 0xfc000000 , 0x8c000000 },
2368     { ppc32_emit_LBZUX , 0xfc0007ff , 0x7c0000ee },
2369     { ppc32_emit_LBZX , 0xfc0007ff , 0x7c0000ae },
2370     { ppc32_emit_LHA , 0xfc000000 , 0xa8000000 },
2371     { ppc32_emit_LHAU , 0xfc000000 , 0xac000000 },
2372     { ppc32_emit_LHAUX , 0xfc0007ff , 0x7c0002ee },
2373     { ppc32_emit_LHAX , 0xfc0007ff , 0x7c0002ae },
2374     { ppc32_emit_LHZ , 0xfc000000 , 0xa0000000 },
2375     { ppc32_emit_LHZU , 0xfc000000 , 0xa4000000 },
2376     { ppc32_emit_LHZUX , 0xfc0007ff , 0x7c00026e },
2377     { ppc32_emit_LHZX , 0xfc0007ff , 0x7c00022e },
2378     { ppc32_emit_LWZ , 0xfc000000 , 0x80000000 },
2379     { ppc32_emit_LWZU , 0xfc000000 , 0x84000000 },
2380     { ppc32_emit_LWZUX , 0xfc0007ff , 0x7c00006e },
2381     { ppc32_emit_LWZX , 0xfc0007ff , 0x7c00002e },
2382     { ppc32_emit_MCRF , 0xfc63ffff , 0x4c000000 },
2383     { ppc32_emit_MFCR , 0xfc1fffff , 0x7c000026 },
2384     { ppc32_emit_MFMSR , 0xfc1fffff , 0x7c0000a6 },
2385     { ppc32_emit_MFSR , 0xfc10ffff , 0x7c0004a6 },
2386     { ppc32_emit_MTCRF , 0xfc100fff , 0x7c000120 },
2387     { ppc32_emit_MULHW , 0xfc0007fe , 0x7c000096 },
2388     { ppc32_emit_MULHWU , 0xfc0007fe , 0x7c000016 },
2389     { ppc32_emit_MULLI , 0xfc000000 , 0x1c000000 },
2390     { ppc32_emit_MULLW , 0xfc0007fe , 0x7c0001d6 },
2391     { ppc32_emit_NAND , 0xfc0007fe , 0x7c0003b8 },
2392     { ppc32_emit_NEG , 0xfc00fffe , 0x7c0000d0 },
2393     { ppc32_emit_NOR , 0xfc0007fe , 0x7c0000f8 },
2394     { ppc32_emit_OR , 0xfc0007fe , 0x7c000378 },
2395     { ppc32_emit_ORC , 0xfc0007fe , 0x7c000338 },
2396     { ppc32_emit_ORI , 0xfc000000 , 0x60000000 },
2397     { ppc32_emit_ORIS , 0xfc000000 , 0x64000000 },
2398     { ppc32_emit_RLWIMI , 0xfc000000 , 0x50000000 },
2399     { ppc32_emit_RLWINM , 0xfc000000 , 0x54000000 },
2400     { ppc32_emit_RLWNM , 0xfc000000 , 0x5c000000 },
2401     { ppc32_emit_SLW , 0xfc0007fe , 0x7c000030 },
2402     { ppc32_emit_SRAWI , 0xfc0007fe , 0x7c000670 },
2403     { ppc32_emit_SRW , 0xfc0007fe , 0x7c000430 },
2404     { ppc32_emit_STB , 0xfc000000 , 0x98000000 },
2405     { ppc32_emit_STBU , 0xfc000000 , 0x9c000000 },
2406     { ppc32_emit_STBUX , 0xfc0007ff , 0x7c0001ee },
2407     { ppc32_emit_STBX , 0xfc0007ff , 0x7c0001ae },
2408     { ppc32_emit_STH , 0xfc000000 , 0xb0000000 },
2409     { ppc32_emit_STHU , 0xfc000000 , 0xb4000000 },
2410     { ppc32_emit_STHUX , 0xfc0007ff , 0x7c00036e },
2411     { ppc32_emit_STHX , 0xfc0007ff , 0x7c00032e },
2412     { ppc32_emit_STW , 0xfc000000 , 0x90000000 },
2413     { ppc32_emit_STWU , 0xfc000000 , 0x94000000 },
2414     { ppc32_emit_STWUX , 0xfc0007ff , 0x7c00016e },
2415     { ppc32_emit_STWX , 0xfc0007ff , 0x7c00012e },
2416     { ppc32_emit_SUBF , 0xfc0007fe , 0x7c000050 },
2417     { ppc32_emit_SUBFC , 0xfc0007fe , 0x7c000010 },
2418     { ppc32_emit_SUBFE , 0xfc0007fe , 0x7c000110 },
2419     { ppc32_emit_SUBFIC , 0xfc000000 , 0x20000000 },
2420     { ppc32_emit_SYNC , 0xffffffff , 0x7c0004ac },
2421     { ppc32_emit_XOR , 0xfc0007fe , 0x7c000278 },
2422     { ppc32_emit_XORI , 0xfc000000 , 0x68000000 },
2423     { ppc32_emit_XORIS , 0xfc000000 , 0x6c000000 },
2424     { ppc32_emit_unknown , 0x00000000 , 0x00000000 },
2425     };

  ViewVC Help
Powered by ViewVC 1.1.26