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

  ViewVC Help
Powered by ViewVC 1.1.26