/[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 8 - (hide annotations)
Sat Oct 6 16:24:54 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC2/ppc32_x86_trans.c
File MIME type: text/plain
File size: 71864 byte(s)
dynamips-0.2.7-RC2

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

  ViewVC Help
Powered by ViewVC 1.1.26