/[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 11 - (hide annotations)
Sat Oct 6 16:33:40 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.8-RC1/ppc32_x86_trans.c
File MIME type: text/plain
File size: 111515 byte(s)
dynamips-0.2.8-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 dpavlin 9 #include "jit_op.h"
17 dpavlin 7 #include "ppc32_jit.h"
18     #include "ppc32_x86_trans.h"
19     #include "memory.h"
20    
21 dpavlin 11 /* %esp adjustment (for MacOS X) */
22     #define STACK_ADJUST 12
23    
24 dpavlin 8 /* ======================================================================= */
25    
26 dpavlin 7 /* Macros for CPU structure access */
27     #define REG_OFFSET(reg) (OFFSET(cpu_ppc_t,gpr[(reg)]))
28     #define MEMOP_OFFSET(op) (OFFSET(cpu_ppc_t,mem_op_fn[(op)]))
29    
30     #define DECLARE_INSN(name) \
31     static int ppc32_emit_##name(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, \
32     ppc_insn_t insn)
33    
34 dpavlin 8 /* EFLAGS to Condition Register (CR) field - signed */
35     static m_uint32_t eflags_to_cr_signed[256] = {
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     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
41     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
42     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
43     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
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     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
49     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
50     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
51     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
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     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
57     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
58     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
59     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
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     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
65     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
66     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
67     0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
68     };
69    
70     /* EFLAGS to Condition Register (CR) field - unsigned */
71     static m_uint32_t eflags_to_cr_unsigned[256] = {
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     0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
77     0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
78     0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
79     0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
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     0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
85     0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
86     0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
87     0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
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     0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
93     0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
94     0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
95     0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
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     0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
101     0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
102     0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
103     0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
104     };
105    
106 dpavlin 9 /* Emit unhandled instruction code */
107     static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
108     ppc_insn_t opcode);
109 dpavlin 7
110     /* Load a 32 bit immediate value */
111 dpavlin 9 static forced_inline void ppc32_load_imm(u_char **ptr,u_int reg,m_uint32_t val)
112 dpavlin 7 {
113     if (val)
114 dpavlin 9 x86_mov_reg_imm(*ptr,reg,val);
115 dpavlin 7 else
116 dpavlin 9 x86_alu_reg_reg(*ptr,X86_XOR,reg,reg);
117 dpavlin 7 }
118    
119     /* Set the Instruction Address (IA) register */
120 dpavlin 9 void ppc32_set_ia(u_char **ptr,m_uint32_t new_ia)
121 dpavlin 7 {
122 dpavlin 9 x86_mov_membase_imm(*ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),new_ia,4);
123 dpavlin 7 }
124    
125     /* Set the Link Register (LR) */
126 dpavlin 9 static void ppc32_set_lr(jit_op_t *iop,m_uint32_t new_lr)
127 dpavlin 7 {
128 dpavlin 9 x86_mov_membase_imm(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),new_lr,4);
129 dpavlin 7 }
130    
131 dpavlin 8 /*
132     * Try to branch directly to the specified JIT block without returning to
133     * main loop.
134     */
135 dpavlin 9 static void ppc32_try_direct_far_jump(cpu_ppc_t *cpu,jit_op_t *iop,
136 dpavlin 8 m_uint32_t new_ia)
137     {
138     m_uint32_t new_page,ia_hash,ia_offset;
139     u_char *test1,*test2,*test3;
140    
141 dpavlin 9 /* Indicate that we throw %esi, %edx */
142     ppc32_op_emit_alter_host_reg(cpu,X86_ESI);
143     ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
144    
145 dpavlin 8 new_page = new_ia & PPC32_MIN_PAGE_MASK;
146     ia_offset = (new_ia & PPC32_MIN_PAGE_IMASK) >> 2;
147     ia_hash = ppc32_jit_get_ia_hash(new_ia);
148    
149     /* Get JIT block info in %edx */
150 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,X86_EBX,
151 dpavlin 8 X86_EDI,OFFSET(cpu_ppc_t,exec_blk_map),4);
152 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,X86_EDX,X86_EBX,ia_hash*sizeof(void *),4);
153 dpavlin 8
154     /* no JIT block found ? */
155 dpavlin 9 x86_test_reg_reg(iop->ob_ptr,X86_EDX,X86_EDX);
156     test1 = iop->ob_ptr;
157     x86_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
158 dpavlin 8
159     /* Check block IA */
160 dpavlin 9 x86_mov_reg_imm(iop->ob_ptr,X86_ESI,new_page);
161     x86_alu_reg_membase(iop->ob_ptr,X86_CMP,X86_ESI,X86_EDX,
162 dpavlin 8 OFFSET(ppc32_jit_tcb_t,start_ia));
163 dpavlin 9 test2 = iop->ob_ptr;
164     x86_branch8(iop->ob_ptr, X86_CC_NE, 0, 1);
165 dpavlin 8
166     /* Jump to the code */
167 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,X86_ESI,
168 dpavlin 8 X86_EDX,OFFSET(ppc32_jit_tcb_t,jit_insn_ptr),4);
169 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,X86_EBX,
170 dpavlin 8 X86_ESI,ia_offset * sizeof(void *),4);
171    
172 dpavlin 9 x86_test_reg_reg(iop->ob_ptr,X86_EBX,X86_EBX);
173     test3 = iop->ob_ptr;
174     x86_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
175     x86_jump_reg(iop->ob_ptr,X86_EBX);
176 dpavlin 8
177     /* Returns to caller... */
178 dpavlin 9 x86_patch(test1,iop->ob_ptr);
179     x86_patch(test2,iop->ob_ptr);
180     x86_patch(test3,iop->ob_ptr);
181 dpavlin 8
182 dpavlin 9 ppc32_set_ia(&iop->ob_ptr,new_ia);
183     ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
184 dpavlin 8 }
185    
186 dpavlin 7 /* Set Jump */
187 dpavlin 9 static void ppc32_set_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,jit_op_t *iop,
188 dpavlin 7 m_uint32_t new_ia,int local_jump)
189     {
190     int return_to_caller = FALSE;
191     u_char *jump_ptr;
192    
193     #if 0
194     if (cpu->sym_trace && !local_jump)
195     return_to_caller = TRUE;
196     #endif
197 dpavlin 11
198 dpavlin 7 if (!return_to_caller && ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr)) {
199 dpavlin 9 ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia);
200     x86_jump32(iop->ob_ptr,0);
201 dpavlin 7 } else {
202 dpavlin 8 if (cpu->exec_blk_direct_jump) {
203     /* Block lookup optimization */
204 dpavlin 9 ppc32_try_direct_far_jump(cpu,iop,new_ia);
205 dpavlin 8 } else {
206 dpavlin 9 ppc32_set_ia(&iop->ob_ptr,new_ia);
207     ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
208 dpavlin 8 }
209 dpavlin 7 }
210     }
211    
212 dpavlin 9 /* Jump to the next page */
213     void ppc32_set_page_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b)
214     {
215     jit_op_t *iop,*op_list = NULL;
216    
217     cpu->gen->jit_op_current = &op_list;
218    
219     iop = ppc32_op_emit_insn_output(cpu,4,"set_page_jump");
220     ppc32_set_jump(cpu,b,iop,b->start_ia + PPC32_MIN_PAGE_SIZE,FALSE);
221     ppc32_op_insn_output(b,iop);
222    
223     jit_op_free_list(cpu->gen,op_list);
224     cpu->gen->jit_op_current = NULL;
225     }
226    
227 dpavlin 7 /* Load a GPR into the specified host register */
228 dpavlin 9 static forced_inline void ppc32_load_gpr(u_char **ptr,u_int host_reg,
229 dpavlin 7 u_int ppc_reg)
230     {
231 dpavlin 9 x86_mov_reg_membase(*ptr,host_reg,X86_EDI,REG_OFFSET(ppc_reg),4);
232 dpavlin 7 }
233    
234     /* Store contents for a host register into a GPR register */
235 dpavlin 9 static forced_inline void ppc32_store_gpr(u_char **ptr,u_int ppc_reg,
236 dpavlin 7 u_int host_reg)
237     {
238 dpavlin 9 x86_mov_membase_reg(*ptr,X86_EDI,REG_OFFSET(ppc_reg),host_reg,4);
239 dpavlin 7 }
240    
241     /* Apply an ALU operation on a GPR register and a host register */
242 dpavlin 9 static forced_inline void ppc32_alu_gpr(u_char **ptr,u_int op,
243 dpavlin 7 u_int host_reg,u_int ppc_reg)
244     {
245 dpavlin 9 x86_alu_reg_membase(*ptr,op,host_reg,X86_EDI,REG_OFFSET(ppc_reg));
246 dpavlin 7 }
247    
248     /*
249     * Update CR from %eflags
250 dpavlin 8 * %eax, %edx, %esi are modified.
251 dpavlin 7 */
252     static void ppc32_update_cr(ppc32_jit_tcb_t *b,int field,int is_signed)
253     {
254 dpavlin 8 /* Get status bits from EFLAGS */
255     x86_mov_reg_imm(b->jit_ptr,X86_EAX,0);
256     x86_lahf(b->jit_ptr);
257     x86_xchg_ah_al(b->jit_ptr);
258 dpavlin 7
259 dpavlin 8 if (is_signed)
260     x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_signed);
261     else
262     x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_unsigned);
263 dpavlin 7
264 dpavlin 8 x86_mov_reg_memindex(b->jit_ptr,X86_EAX,X86_EDX,0,X86_EAX,2,4);
265 dpavlin 7
266     /* Check XER Summary of Overflow and report it */
267 dpavlin 9 x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,xer),4);
268 dpavlin 8 //x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_XER_SO);
269     //x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_ESI,PPC32_XER_SO_BIT);
270     //x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ESI);
271 dpavlin 7
272 dpavlin 8 /* Store modified CR field */
273     x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(field),
274     X86_EAX,4);
275 dpavlin 7 }
276    
277     /*
278     * Update CR0 from %eflags
279 dpavlin 9 * %eax, %edx, %esi are modified.
280 dpavlin 7 */
281     static void ppc32_update_cr0(ppc32_jit_tcb_t *b)
282     {
283     ppc32_update_cr(b,0,TRUE);
284     }
285    
286 dpavlin 9 /* Indicate registers modified by ppc32_update_cr() functions */
287     void ppc32_update_cr_set_altered_hreg(cpu_ppc_t *cpu)
288     {
289     /* Throw %eax and %edx, which are modifed by ppc32_update_cr() */
290     ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
291     ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
292     }
293    
294 dpavlin 7 /* Basic C call */
295 dpavlin 9 static forced_inline
296     void ppc32_emit_basic_c_call(u_char **ptr,void *f)
297 dpavlin 7 {
298 dpavlin 9 x86_mov_reg_imm(*ptr,X86_EBX,f);
299     x86_call_reg(*ptr,X86_EBX);
300 dpavlin 7 }
301    
302     /* Emit a simple call to a C function without any parameter */
303 dpavlin 9 static void ppc32_emit_c_call(ppc32_jit_tcb_t *b,jit_op_t *iop,void *f)
304 dpavlin 7 {
305 dpavlin 9 ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
306     ppc32_emit_basic_c_call(&iop->ob_ptr,f);
307 dpavlin 7 }
308    
309 dpavlin 9 /* ======================================================================== */
310    
311     /* Initialize register mapping */
312     void ppc32_jit_init_hreg_mapping(cpu_ppc_t *cpu)
313     {
314     int avail_hregs[] = { X86_ESI, X86_EAX, X86_ECX, X86_EDX, -1 };
315     struct hreg_map *map;
316     int i,hreg;
317    
318     cpu->hreg_map_list = cpu->hreg_lru = NULL;
319    
320     /* Add the available registers to the map list */
321     for(i=0;avail_hregs[i]!=-1;i++) {
322     hreg = avail_hregs[i];
323     map = &cpu->hreg_map[hreg];
324    
325     /* Initialize mapping. At the beginning, no PPC reg is mapped */
326     map->flags = 0;
327     map->hreg = hreg;
328     map->vreg = -1;
329     ppc32_jit_insert_hreg_mru(cpu,map);
330     }
331    
332     /* Clear PPC registers mapping */
333     for(i=0;i<PPC32_GPR_NR;i++)
334     cpu->ppc_reg_map[i] = -1;
335     }
336    
337     /* Allocate a specific temp register */
338     static int ppc32_jit_get_tmp_hreg(cpu_ppc_t *cpu)
339     {
340     return(X86_EBX);
341     }
342    
343     /* ======================================================================== */
344     /* JIT operations (specific to target CPU). */
345     /* ======================================================================== */
346    
347     /* INSN_OUTPUT */
348     void ppc32_op_insn_output(ppc32_jit_tcb_t *b,jit_op_t *op)
349     {
350     op->ob_final = b->jit_ptr;
351     memcpy(b->jit_ptr,op->ob_data,op->ob_ptr - op->ob_data);
352     b->jit_ptr += op->ob_ptr - op->ob_data;
353    
354     if ((op->ob_ptr - op->ob_data) >= jit_op_blk_sizes[op->ob_size_index]) {
355 dpavlin 11 printf("ppc32_op_insn_output: FAILURE: count=%d, size=%d\n",
356 dpavlin 9 op->ob_ptr - op->ob_data, jit_op_blk_sizes[op->ob_size_index]);
357     }
358     }
359    
360     /* LOAD_GPR: p[0] = %host_reg, p[1] = %ppc_reg */
361     void ppc32_op_load_gpr(ppc32_jit_tcb_t *b,jit_op_t *op)
362     {
363     if (op->param[0] != JIT_OP_INV_REG)
364     ppc32_load_gpr(&b->jit_ptr,op->param[0],op->param[1]);
365     }
366    
367     /* STORE_GPR: p[0] = %host_reg, p[1] = %ppc_reg */
368     void ppc32_op_store_gpr(ppc32_jit_tcb_t *b,jit_op_t *op)
369     {
370     if (op->param[0] != JIT_OP_INV_REG)
371     ppc32_store_gpr(&b->jit_ptr,op->param[1],op->param[0]);
372     }
373    
374     /* UPDATE_FLAGS: p[0] = cr_field, p[1] = is_signed */
375     void ppc32_op_update_flags(ppc32_jit_tcb_t *b,jit_op_t *op)
376     {
377     if (op->param[0] != JIT_OP_INV_REG)
378     ppc32_update_cr(b,op->param[0],op->param[1]);
379     }
380    
381     /* MOVE_HOST_REG: p[0] = %host_dst_reg, p[1] = %host_src_reg */
382     void ppc32_op_move_host_reg(ppc32_jit_tcb_t *b,jit_op_t *op)
383     {
384     if ((op->param[0] != JIT_OP_INV_REG) && (op->param[1] != JIT_OP_INV_REG))
385     x86_mov_reg_reg(b->jit_ptr,op->param[0],op->param[1],4);
386     }
387    
388     /* SET_HOST_REG_IMM32: p[0] = %host_reg, p[1] = imm32 */
389     void ppc32_op_set_host_reg_imm32(ppc32_jit_tcb_t *b,jit_op_t *op)
390     {
391     if (op->param[0] != JIT_OP_INV_REG)
392     ppc32_load_imm(&b->jit_ptr,op->param[0],op->param[1]);
393     }
394    
395     /* ======================================================================== */
396    
397 dpavlin 7 /* Memory operation */
398 dpavlin 9 static void ppc32_emit_memop(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
399     int op,int base,int offset,int target,int update)
400 dpavlin 7 {
401     m_uint32_t val = sign_extend(offset,16);
402 dpavlin 9 jit_op_t *iop;
403 dpavlin 7
404 dpavlin 9 /*
405     * Since an exception can be triggered, clear JIT state. This allows
406     * to use branch target tag (we can directly branch on this instruction).
407     */
408     ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);
409     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
410    
411     iop = ppc32_op_emit_insn_output(cpu,5,"memop");
412    
413 dpavlin 7 /* Save PC for exception handling */
414 dpavlin 9 ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
415 dpavlin 7
416     /* EDX = sign-extended offset */
417 dpavlin 9 ppc32_load_imm(&iop->ob_ptr,X86_EDX,val);
418 dpavlin 7
419     /* EDX = GPR[base] + sign-extended offset */
420     if (update || (base != 0))
421 dpavlin 9 ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,X86_EDX,base);
422 dpavlin 7
423     if (update)
424 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EDX,4);
425 dpavlin 7
426     /* ECX = target register */
427 dpavlin 9 x86_mov_reg_imm(iop->ob_ptr,X86_ECX,target);
428 dpavlin 7
429     /* EAX = CPU instance pointer */
430 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
431 dpavlin 7
432     /* Call memory function */
433 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
434 dpavlin 9 x86_call_membase(iop->ob_ptr,X86_EDI,MEMOP_OFFSET(op));
435 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
436    
437 dpavlin 7 if (update)
438 dpavlin 9 ppc32_store_gpr(&iop->ob_ptr,base,X86_ESI);
439 dpavlin 7 }
440    
441     /* Memory operation (indexed) */
442 dpavlin 9 static void ppc32_emit_memop_idx(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
443     int op,int ra,int rb,int target,int update)
444 dpavlin 7 {
445 dpavlin 9 jit_op_t *iop;
446 dpavlin 7
447 dpavlin 9 /*
448     * Since an exception can be triggered, clear JIT state. This allows
449     * to use branch target tag (we can directly branch on this instruction).
450     */
451     ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);
452     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
453    
454     iop = ppc32_op_emit_insn_output(cpu,5,"memop_idx");
455    
456 dpavlin 7 /* Save PC for exception handling */
457 dpavlin 9 ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
458 dpavlin 7
459     /* EDX = $rb */
460 dpavlin 9 ppc32_load_gpr(&iop->ob_ptr,X86_EDX,rb);
461 dpavlin 7
462     /* EDX = $rb + $ra */
463     if (update || (ra != 0))
464 dpavlin 9 ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,X86_EDX,ra);
465 dpavlin 7
466     if (update)
467 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EDX,4);
468 dpavlin 7
469     /* ECX = target register */
470 dpavlin 9 x86_mov_reg_imm(iop->ob_ptr,X86_ECX,target);
471 dpavlin 7
472     /* EAX = CPU instance pointer */
473 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
474 dpavlin 7
475     /* Call memory function */
476 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
477 dpavlin 9 x86_call_membase(iop->ob_ptr,X86_EDI,MEMOP_OFFSET(op));
478 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
479    
480 dpavlin 7 if (update)
481 dpavlin 9 ppc32_store_gpr(&iop->ob_ptr,ra,X86_ESI);
482 dpavlin 7 }
483    
484 dpavlin 9 typedef void (*memop_fast_access)(jit_op_t *iop,int target);
485 dpavlin 7
486     /* Fast LBZ */
487 dpavlin 9 static void ppc32_memop_fast_lbz(jit_op_t *iop,int target)
488 dpavlin 7 {
489 dpavlin 9 x86_clear_reg(iop->ob_ptr,X86_ECX);
490     x86_mov_reg_memindex(iop->ob_ptr,X86_ECX,X86_EAX,0,X86_EBX,0,1);
491     ppc32_store_gpr(&iop->ob_ptr,target,X86_ECX);
492 dpavlin 7 }
493    
494     /* Fast STB */
495 dpavlin 9 static void ppc32_memop_fast_stb(jit_op_t *iop,int target)
496 dpavlin 7 {
497 dpavlin 9 ppc32_load_gpr(&iop->ob_ptr,X86_EDX,target);
498     x86_mov_memindex_reg(iop->ob_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,1);
499 dpavlin 7 }
500    
501     /* Fast LWZ */
502 dpavlin 9 static void ppc32_memop_fast_lwz(jit_op_t *iop,int target)
503 dpavlin 7 {
504 dpavlin 9 x86_mov_reg_memindex(iop->ob_ptr,X86_EAX,X86_EAX,0,X86_EBX,0,4);
505     x86_bswap(iop->ob_ptr,X86_EAX);
506     ppc32_store_gpr(&iop->ob_ptr,target,X86_EAX);
507 dpavlin 7 }
508    
509     /* Fast STW */
510 dpavlin 9 static void ppc32_memop_fast_stw(jit_op_t *iop,int target)
511 dpavlin 7 {
512 dpavlin 9 ppc32_load_gpr(&iop->ob_ptr,X86_EDX,target);
513     x86_bswap(iop->ob_ptr,X86_EDX);
514     x86_mov_memindex_reg(iop->ob_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,4);
515 dpavlin 7 }
516    
517     /* Fast memory operation */
518 dpavlin 9 static void ppc32_emit_memop_fast(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
519     int write_op,int opcode,
520 dpavlin 7 int base,int offset,int target,
521     memop_fast_access op_handler)
522     {
523     m_uint32_t val = sign_extend(offset,16);
524 dpavlin 11 u_char *test1,*test2,*p_exit,*p_fast_exit;
525 dpavlin 9 jit_op_t *iop;
526 dpavlin 7
527 dpavlin 9 /*
528     * Since an exception can be triggered, clear JIT state. This allows
529     * to use branch target tag (we can directly branch on this instruction).
530     */
531     ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);
532     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
533    
534     iop = ppc32_op_emit_insn_output(cpu,5,"memop_fast");
535    
536 dpavlin 7 test2 = NULL;
537    
538 dpavlin 9 if (val != 0) {
539     /* EBX = sign-extended offset */
540     ppc32_load_imm(&iop->ob_ptr,X86_EBX,val);
541 dpavlin 7
542 dpavlin 9 /* EBX = GPR[base] + sign-extended offset */
543     if (base != 0)
544     ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,X86_EBX,base);
545     } else {
546     if (base != 0)
547     ppc32_load_gpr(&iop->ob_ptr,X86_EBX,base);
548     else
549     ppc32_load_imm(&iop->ob_ptr,X86_EBX,0);
550     }
551 dpavlin 7
552 dpavlin 11 #if 0
553     /* ======= zzz ======= */
554     {
555     u_char *testZ;
556    
557     x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EBX,4);
558     x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_MASK);
559     x86_alu_reg_membase(iop->ob_ptr,X86_CMP,X86_ESI,X86_EDI,
560     OFFSET(cpu_ppc_t,vtlb[base].vaddr));
561     testZ = iop->ob_ptr;
562     x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
563    
564     x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EBX,PPC32_MIN_PAGE_IMASK);
565     x86_mov_reg_membase(iop->ob_ptr,X86_EAX,
566     X86_EDI,OFFSET(cpu_ppc_t,vtlb[base].haddr),4);
567    
568     /* Memory access */
569     op_handler(iop,target);
570    
571     p_fast_exit = iop->ob_ptr;
572     x86_jump8(iop->ob_ptr,0);
573    
574     x86_patch(testZ,iop->ob_ptr);
575     }
576     #endif
577    
578 dpavlin 7 /* EAX = mts32_entry index */
579 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EBX,4);
580     x86_shift_reg_imm(iop->ob_ptr,X86_SHR,X86_EAX,MTS32_HASH_SHIFT);
581     x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EAX,MTS32_HASH_MASK);
582 dpavlin 7
583     /* EDX = mts32_entry */
584 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,X86_EDX,
585 dpavlin 7 X86_EDI,OFFSET(cpu_ppc_t,mts_cache[PPC32_MTS_DCACHE]),
586     4);
587 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,X86_EAX,4);
588     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,X86_EDX,X86_EAX);
589 dpavlin 7
590     /* Compare virtual page address (ESI = vpage) */
591 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_ESI,X86_EBX,4);
592     x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_MASK);
593 dpavlin 7
594 dpavlin 9 x86_alu_reg_membase(iop->ob_ptr,X86_CMP,X86_ESI,X86_EDX,
595 dpavlin 7 OFFSET(mts32_entry_t,gvpa));
596 dpavlin 9 test1 = iop->ob_ptr;
597     x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
598 dpavlin 7
599     /* Test if we are writing to a COW page */
600     if (write_op) {
601 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,X86_EDX,OFFSET(mts32_entry_t,flags),
602 dpavlin 8 MTS_FLAG_COW|MTS_FLAG_EXEC);
603 dpavlin 9 test2 = iop->ob_ptr;
604     x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
605 dpavlin 7 }
606    
607     /* EBX = offset in page, EAX = Host Page Address */
608 dpavlin 9 x86_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EBX,PPC32_MIN_PAGE_IMASK);
609     x86_mov_reg_membase(iop->ob_ptr,X86_EAX,
610     X86_EDX,OFFSET(mts32_entry_t,hpa),4);
611 dpavlin 7
612 dpavlin 11 #if 0
613     /* zzz */
614     {
615     x86_mov_membase_reg(iop->ob_ptr,
616     X86_EDI,OFFSET(cpu_ppc_t,vtlb[base].vaddr),
617     X86_ESI,4);
618     x86_mov_membase_reg(iop->ob_ptr,
619     X86_EDI,OFFSET(cpu_ppc_t,vtlb[base].haddr),
620     X86_EAX,4);
621     }
622     #endif
623    
624 dpavlin 7 /* Memory access */
625 dpavlin 9 op_handler(iop,target);
626 dpavlin 7
627 dpavlin 9 p_exit = iop->ob_ptr;
628     x86_jump8(iop->ob_ptr,0);
629 dpavlin 7
630     /* === Slow lookup === */
631 dpavlin 9 x86_patch(test1,iop->ob_ptr);
632 dpavlin 7 if (test2)
633 dpavlin 9 x86_patch(test2,iop->ob_ptr);
634 dpavlin 7
635     /* Update IA (EBX = vaddr) */
636 dpavlin 9 ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
637 dpavlin 7
638     /* EDX = virtual address */
639 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_EDX,X86_EBX,4);
640 dpavlin 7
641     /* ECX = target register */
642 dpavlin 9 x86_mov_reg_imm(iop->ob_ptr,X86_ECX,target);
643 dpavlin 7
644     /* EAX = CPU instance pointer */
645 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
646 dpavlin 7
647     /* Call memory function */
648 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
649 dpavlin 9 x86_call_membase(iop->ob_ptr,X86_EDI,MEMOP_OFFSET(opcode));
650 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
651    
652     x86_patch(p_exit,iop->ob_ptr);
653 dpavlin 7
654 dpavlin 11 /* zzz */
655     #if 0
656     x86_patch(p_fast_exit,iop->ob_ptr);
657     #endif
658 dpavlin 7 }
659    
660     /* Emit unhandled instruction code */
661     static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
662     ppc_insn_t opcode)
663     {
664     u_char *test1;
665 dpavlin 9 jit_op_t *iop;
666 dpavlin 7
667 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,3,"unknown");
668 dpavlin 7
669     /* Update IA */
670 dpavlin 9 ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
671 dpavlin 7
672     /* Fallback to non-JIT mode */
673 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
674 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
675     x86_mov_reg_imm(iop->ob_ptr,X86_EDX,opcode);
676 dpavlin 7
677 dpavlin 11 ppc32_emit_basic_c_call(&iop->ob_ptr,ppc32_exec_single_insn_ext);
678     x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
679    
680 dpavlin 9 x86_test_reg_reg(iop->ob_ptr,X86_EAX,X86_EAX);
681     test1 = iop->ob_ptr;
682     x86_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
683     ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
684 dpavlin 7
685 dpavlin 9 x86_patch(test1,iop->ob_ptr);
686    
687     /* Signal this as an EOB to reset JIT state */
688     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
689 dpavlin 7 return(0);
690     }
691    
692 dpavlin 9 /* Virtual Breakpoint */
693     void ppc32_emit_breakpoint(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b)
694     {
695     jit_op_t *iop;
696 dpavlin 7
697 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,2,"breakpoint");
698    
699 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST);
700 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_EDI,4);
701     ppc32_emit_c_call(b,iop,ppc32_run_breakpoint);
702 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
703 dpavlin 9
704     /* Signal this as an EOB to to reset JIT state */
705     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
706 dpavlin 7 }
707    
708 dpavlin 9 /* Dump regs */
709     static void ppc32_emit_dump_regs(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b)
710     {
711     jit_op_t *iop;
712 dpavlin 11
713 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,2,"dump_regs");
714 dpavlin 8
715 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,X86_EAX,X86_EDI,OFFSET(cpu_ppc_t,gen),4);
716 dpavlin 11
717     x86_alu_reg_imm(iop->ob_ptr,X86_SUB,X86_ESP,STACK_ADJUST-4);
718 dpavlin 9 x86_push_reg(iop->ob_ptr,X86_EAX);
719     ppc32_emit_c_call(b,iop,ppc32_dump_regs);
720 dpavlin 11 x86_alu_reg_imm(iop->ob_ptr,X86_ADD,X86_ESP,STACK_ADJUST);
721 dpavlin 8
722 dpavlin 9 /* Signal this as an EOB to to reset JIT state */
723     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
724 dpavlin 8 }
725    
726 dpavlin 11 /* Increment the number of executed instructions (performance debugging) */
727     void ppc32_inc_perf_counter(cpu_ppc_t *cpu)
728     {
729     jit_op_t *iop;
730    
731     iop = ppc32_op_emit_insn_output(cpu,1,"perf_cnt");
732     x86_inc_membase(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,perf_counter));
733     }
734    
735 dpavlin 7 /* ======================================================================== */
736    
737     /* BLR - Branch to Link Register */
738     DECLARE_INSN(BLR)
739     {
740 dpavlin 9 jit_op_t *iop;
741     int hreg;
742 dpavlin 7
743 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"blr");
744     hreg = ppc32_jit_alloc_hreg(cpu,-1);
745     ppc32_op_emit_alter_host_reg(cpu,hreg);
746    
747     iop = ppc32_op_emit_insn_output(cpu,2,"blr");
748    
749     x86_mov_reg_membase(iop->ob_ptr,hreg,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
750     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),hreg,4);
751    
752 dpavlin 7 /* set the return address */
753     if (insn & 1)
754 dpavlin 9 ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
755 dpavlin 7
756 dpavlin 9 ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
757     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
758     ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
759    
760     ppc32_jit_close_hreg_seq(cpu);
761 dpavlin 7 return(0);
762     }
763    
764     /* BCTR - Branch to Count Register */
765     DECLARE_INSN(BCTR)
766     {
767 dpavlin 9 jit_op_t *iop;
768     int hreg;
769 dpavlin 7
770 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"bctr");
771     hreg = ppc32_jit_alloc_hreg(cpu,-1);
772     ppc32_op_emit_alter_host_reg(cpu,hreg);
773    
774     iop = ppc32_op_emit_insn_output(cpu,2,"bctr");
775    
776     x86_mov_reg_membase(iop->ob_ptr,hreg,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
777     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),hreg,4);
778    
779 dpavlin 7 /* set the return address */
780     if (insn & 1)
781 dpavlin 9 ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
782 dpavlin 7
783 dpavlin 9 ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
784     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
785     ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
786    
787     ppc32_jit_close_hreg_seq(cpu);
788 dpavlin 7 return(0);
789     }
790    
791     /* MFLR - Move From Link Register */
792     DECLARE_INSN(MFLR)
793     {
794     int rd = bits(insn,21,25);
795 dpavlin 9 int hreg_rd;
796     jit_op_t *iop;
797    
798     ppc32_jit_start_hreg_seq(cpu,"mflr");
799     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
800     iop = ppc32_op_emit_insn_output(cpu,1,"mflr");
801    
802     x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
803     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
804    
805     ppc32_jit_close_hreg_seq(cpu);
806 dpavlin 7 return(0);
807     }
808    
809     /* MTLR - Move To Link Register */
810     DECLARE_INSN(MTLR)
811     {
812     int rs = bits(insn,21,25);
813 dpavlin 9 int hreg_rs;
814     jit_op_t *iop;
815    
816     ppc32_jit_start_hreg_seq(cpu,"mtlr");
817     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
818     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
819 dpavlin 7
820 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,1,"mtlr");
821     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),hreg_rs,4);
822    
823     ppc32_jit_close_hreg_seq(cpu);
824 dpavlin 7 return(0);
825     }
826    
827     /* MFCTR - Move From Counter Register */
828     DECLARE_INSN(MFCTR)
829     {
830     int rd = bits(insn,21,25);
831 dpavlin 9 int hreg_rd;
832     jit_op_t *iop;
833 dpavlin 7
834 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mfctr");
835     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
836    
837     iop = ppc32_op_emit_insn_output(cpu,1,"mfctr");
838    
839     x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
840     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
841    
842     ppc32_jit_close_hreg_seq(cpu);
843 dpavlin 7 return(0);
844     }
845    
846     /* MTCTR - Move To Counter Register */
847     DECLARE_INSN(MTCTR)
848     {
849     int rs = bits(insn,21,25);
850 dpavlin 9 int hreg_rs;
851     jit_op_t *iop;
852 dpavlin 7
853 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mtctr");
854     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
855     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
856    
857     iop = ppc32_op_emit_insn_output(cpu,1,"mtctr");
858     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr),hreg_rs,4);
859    
860     ppc32_jit_close_hreg_seq(cpu);
861 dpavlin 7 return(0);
862     }
863    
864     /* MFTBU - Move from Time Base (Up) */
865     DECLARE_INSN(MFTBU)
866     {
867     int rd = bits(insn,21,25);
868 dpavlin 9 int hreg_rd;
869     jit_op_t *iop;
870 dpavlin 7
871 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mftbu");
872     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
873    
874     iop = ppc32_op_emit_insn_output(cpu,1,"mftbu");
875    
876     x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
877     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
878    
879     ppc32_jit_close_hreg_seq(cpu);
880 dpavlin 7 return(0);
881     }
882    
883     #define PPC32_TB_INCREMENT 50
884    
885     /* MFTBL - Move from Time Base (Lo) */
886     DECLARE_INSN(MFTBL)
887     {
888     int rd = bits(insn,21,25);
889 dpavlin 9 int hreg_rd,hreg_t0;
890     jit_op_t *iop;
891 dpavlin 7
892 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mftbl");
893     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
894     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
895    
896     iop = ppc32_op_emit_insn_output(cpu,3,"mftbl");
897    
898     x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,tb),4);
899    
900 dpavlin 7 /* Increment the time base register */
901 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,tb),4);
902     x86_mov_reg_membase(iop->ob_ptr,hreg_t0,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
903     x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,PPC32_TB_INCREMENT);
904     x86_alu_reg_imm(iop->ob_ptr,X86_ADC,hreg_t0,0);
905     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb),hreg_rd,4);
906     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,hreg_t0,4);
907 dpavlin 7
908 dpavlin 9 ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
909    
910     ppc32_jit_close_hreg_seq(cpu);
911 dpavlin 7 return(0);
912     }
913    
914     /* ADD */
915     DECLARE_INSN(ADD)
916     {
917     int rd = bits(insn,21,25);
918     int ra = bits(insn,16,20);
919     int rb = bits(insn,11,15);
920 dpavlin 9 int hreg_rd,hreg_ra,hreg_rb;
921     jit_op_t *iop;
922 dpavlin 7
923     /* $rd = $ra + $rb */
924 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"add");
925     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
926     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
927     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
928 dpavlin 7
929 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
930     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
931    
932     iop = ppc32_op_emit_insn_output(cpu,2,"add");
933    
934     if (rd == ra)
935     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb);
936     else if (rd == rb)
937     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_ra);
938     else {
939     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
940     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb);
941     }
942    
943     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
944    
945 dpavlin 7 if (insn & 1)
946 dpavlin 9 ppc32_op_emit_update_flags(cpu,0,TRUE);
947    
948     ppc32_jit_close_hreg_seq(cpu);
949 dpavlin 7 return(0);
950     }
951    
952     /* ADDC */
953     DECLARE_INSN(ADDC)
954     {
955     int rd = bits(insn,21,25);
956     int ra = bits(insn,16,20);
957     int rb = bits(insn,11,15);
958 dpavlin 9 int hreg_rd,hreg_ra,hreg_rb,hreg_t0;
959     jit_op_t *iop;
960 dpavlin 7
961     /* $rd = $ra + $rb */
962 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"addc");
963     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
964     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
965     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
966 dpavlin 7
967     /* store the carry flag */
968 dpavlin 9 hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
969 dpavlin 7
970 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
971     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
972    
973     iop = ppc32_op_emit_insn_output(cpu,2,"addc");
974    
975     if (rd == ra)
976     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb);
977     else if (rd == rb)
978     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_ra);
979     else {
980     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
981     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb);
982     }
983    
984     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
985    
986     x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t0,FALSE);
987     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x1);
988     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
989     hreg_t0,4);
990    
991 dpavlin 7 if (insn & 1) {
992 dpavlin 9 x86_test_reg_reg(iop->ob_ptr,hreg_rd,hreg_rd);
993     ppc32_op_emit_update_flags(cpu,0,TRUE);
994 dpavlin 7 }
995 dpavlin 9
996     ppc32_jit_close_hreg_seq(cpu);
997 dpavlin 7 return(0);
998     }
999    
1000     /* ADDE - Add Extended */
1001     DECLARE_INSN(ADDE)
1002     {
1003     int rd = bits(insn,21,25);
1004     int ra = bits(insn,16,20);
1005     int rb = bits(insn,11,15);
1006 dpavlin 9 int hreg_ra,hreg_rb,hreg_rd,hreg_t0,hreg_t1;
1007     jit_op_t *iop;
1008 dpavlin 7
1009 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"adde");
1010     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1011     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1012     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1013 dpavlin 7
1014 dpavlin 9 hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
1015     hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
1016 dpavlin 7
1017 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
1018     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1019     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1020 dpavlin 7
1021 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,3,"adde");
1022 dpavlin 7
1023 dpavlin 9 /* $t0 = $ra + carry */
1024     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
1025     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
1026 dpavlin 7
1027 dpavlin 9 x86_alu_reg_membase(iop->ob_ptr,X86_ADD,hreg_t0,
1028     X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
1029     x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
1030     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t1,4);
1031    
1032     /* $t0 += $rb */
1033     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_t0,hreg_rb);
1034     x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
1035     x86_alu_membase_reg(iop->ob_ptr,X86_OR,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
1036     hreg_t1);
1037    
1038 dpavlin 7 /* update cr0 */
1039 dpavlin 9 if (insn & 1)
1040     x86_test_reg_reg(iop->ob_ptr,hreg_t0,hreg_t0);
1041 dpavlin 7
1042 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
1043     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1044    
1045     if (insn & 1)
1046     ppc32_op_emit_update_flags(cpu,0,TRUE);
1047    
1048     ppc32_jit_close_hreg_seq(cpu);
1049 dpavlin 7 return(0);
1050     }
1051    
1052     /* ADDI - ADD Immediate */
1053     DECLARE_INSN(ADDI)
1054     {
1055     int rd = bits(insn,21,25);
1056     int ra = bits(insn,16,20);
1057     int imm = bits(insn,0,15);
1058     m_uint32_t tmp = sign_extend_32(imm,16);
1059 dpavlin 9 int hreg_rd,hreg_ra;
1060     jit_op_t *iop;
1061 dpavlin 7
1062 dpavlin 9 /* $rd = $ra + imm */
1063     ppc32_jit_start_hreg_seq(cpu,"addi");
1064     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1065 dpavlin 7
1066 dpavlin 9 if (ra != 0) {
1067     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1068     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1069 dpavlin 7
1070 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,2,"addi");
1071    
1072     if (rd != ra)
1073     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1074    
1075     x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,tmp);
1076     } else {
1077     iop = ppc32_op_emit_insn_output(cpu,1,"addi");
1078     ppc32_load_imm(&iop->ob_ptr,hreg_rd,tmp);
1079     }
1080    
1081     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1082    
1083     ppc32_jit_close_hreg_seq(cpu);
1084 dpavlin 7 return(0);
1085     }
1086    
1087     /* ADDIC - ADD Immediate with Carry */
1088     DECLARE_INSN(ADDIC)
1089     {
1090     int rd = bits(insn,21,25);
1091     int ra = bits(insn,16,20);
1092     int imm = bits(insn,0,15);
1093     m_uint32_t tmp = sign_extend_32(imm,16);
1094 dpavlin 9 int hreg_rd,hreg_ra;
1095     jit_op_t *iop;
1096 dpavlin 7
1097 dpavlin 9 /* $rd = $ra + imm */
1098     ppc32_jit_start_hreg_seq(cpu,"addic");
1099     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1100     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1101    
1102     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1103    
1104     iop = ppc32_op_emit_insn_output(cpu,1,"addic");
1105    
1106     if (rd != ra)
1107     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1108    
1109     x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,tmp);
1110     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1111    
1112     x86_set_membase(iop->ob_ptr,X86_CC_C,
1113     X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
1114    
1115     ppc32_jit_close_hreg_seq(cpu);
1116 dpavlin 7 return(0);
1117     }
1118    
1119     /* ADDIC. */
1120     DECLARE_INSN(ADDIC_dot)
1121     {
1122     int rd = bits(insn,21,25);
1123     int ra = bits(insn,16,20);
1124     int imm = bits(insn,0,15);
1125     m_uint32_t tmp = sign_extend_32(imm,16);
1126 dpavlin 9 int hreg_rd,hreg_ra;
1127     jit_op_t *iop;
1128 dpavlin 7
1129 dpavlin 9 /* $rd = $ra + imm */
1130     ppc32_jit_start_hreg_seq(cpu,"addic.");
1131     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1132     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1133 dpavlin 7
1134 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1135    
1136     iop = ppc32_op_emit_insn_output(cpu,1,"addic.");
1137    
1138     if (rd != ra)
1139     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1140    
1141     x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,tmp);
1142     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1143    
1144     x86_set_membase(iop->ob_ptr,X86_CC_C,
1145     X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
1146    
1147     ppc32_op_emit_update_flags(cpu,0,TRUE);
1148    
1149     ppc32_jit_close_hreg_seq(cpu);
1150 dpavlin 7 return(0);
1151     }
1152    
1153     /* ADDIS - ADD Immediate Shifted */
1154     DECLARE_INSN(ADDIS)
1155     {
1156     int rd = bits(insn,21,25);
1157     int ra = bits(insn,16,20);
1158     m_uint32_t imm = bits(insn,0,15);
1159 dpavlin 9 m_uint32_t tmp = imm << 16;
1160     int hreg_rd,hreg_ra;
1161     jit_op_t *iop;
1162 dpavlin 7
1163 dpavlin 9 /* $rd = $ra + (imm << 16) */
1164     ppc32_jit_start_hreg_seq(cpu,"addis");
1165     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1166 dpavlin 7
1167 dpavlin 9 if (ra != 0) {
1168     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1169     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1170 dpavlin 7
1171 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,1,"addis");
1172    
1173     if (rd != ra)
1174     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1175    
1176     x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,tmp);
1177     } else {
1178     //iop = ppc32_op_emit_insn_output(cpu,1,"addis");
1179     //x86_mov_reg_imm(iop->ob_ptr,hreg_rd,tmp);
1180     ppc32_op_emit_set_host_reg_imm32(cpu,hreg_rd,tmp);
1181     }
1182    
1183     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1184    
1185     ppc32_jit_close_hreg_seq(cpu);
1186 dpavlin 7 return(0);
1187     }
1188    
1189 dpavlin 9 /* ADDZE */
1190     DECLARE_INSN(ADDZE)
1191     {
1192     int rd = bits(insn,21,25);
1193     int ra = bits(insn,16,20);
1194     int hreg_rd,hreg_ra,hreg_t0;
1195     jit_op_t *iop;
1196    
1197     /* $rd = $ra + xer_ca + set_carry */
1198     ppc32_jit_start_hreg_seq(cpu,"addze");
1199     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1200     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1201     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1202    
1203     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1204    
1205     iop = ppc32_op_emit_insn_output(cpu,2,"addze");
1206    
1207     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,hreg_t0);
1208    
1209     if (rd != ra)
1210     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1211    
1212     x86_alu_reg_membase(iop->ob_ptr,X86_ADD,hreg_rd,
1213     X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
1214    
1215     x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t0,FALSE);
1216     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t0,4);
1217    
1218     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1219    
1220     if (insn & 1)
1221     ppc32_op_emit_update_flags(cpu,0,TRUE);
1222    
1223     ppc32_jit_close_hreg_seq(cpu);
1224     return(0);
1225     }
1226    
1227 dpavlin 7 /* AND */
1228     DECLARE_INSN(AND)
1229     {
1230     int rs = bits(insn,21,25);
1231     int ra = bits(insn,16,20);
1232     int rb = bits(insn,11,15);
1233 dpavlin 9 int hreg_rs,hreg_ra,hreg_rb;
1234     jit_op_t *iop;
1235 dpavlin 7
1236 dpavlin 9 /* $ra = $rs & $rb */
1237     ppc32_jit_start_hreg_seq(cpu,"and");
1238     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
1239     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1240     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1241 dpavlin 7
1242 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1243     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1244    
1245     iop = ppc32_op_emit_insn_output(cpu,1,"and");
1246    
1247     if (ra == rs)
1248     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb);
1249     else if (ra == rb)
1250     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rs);
1251     else {
1252     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1253     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb);
1254     }
1255    
1256     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1257    
1258 dpavlin 7 if (insn & 1)
1259 dpavlin 9 ppc32_op_emit_update_flags(cpu,0,TRUE);
1260 dpavlin 7
1261 dpavlin 9 ppc32_jit_close_hreg_seq(cpu);
1262 dpavlin 7 return(0);
1263     }
1264    
1265     /* ANDC */
1266     DECLARE_INSN(ANDC)
1267     {
1268     int rs = bits(insn,21,25);
1269     int ra = bits(insn,16,20);
1270     int rb = bits(insn,11,15);
1271 dpavlin 9 int hreg_rs,hreg_ra,hreg_rb,hreg_t0;
1272     jit_op_t *iop;
1273 dpavlin 7
1274     /* $ra = $rs & ~$rb */
1275 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"andc");
1276     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
1277     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1278     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1279 dpavlin 7
1280 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1281     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1282    
1283     iop = ppc32_op_emit_insn_output(cpu,1,"andc");
1284    
1285     /* $t0 = ~$rb */
1286     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1287     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rb,4);
1288     x86_not_reg(iop->ob_ptr,hreg_t0);
1289    
1290     /* $ra = $rs & $t0 */
1291     if (ra == rs)
1292     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_t0);
1293     else {
1294     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_rs);
1295     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
1296     }
1297    
1298     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1299    
1300 dpavlin 7 if (insn & 1)
1301 dpavlin 9 ppc32_op_emit_update_flags(cpu,0,TRUE);
1302 dpavlin 7
1303 dpavlin 9 ppc32_jit_close_hreg_seq(cpu);
1304 dpavlin 7 return(0);
1305     }
1306    
1307     /* AND Immediate */
1308     DECLARE_INSN(ANDI)
1309     {
1310     int rs = bits(insn,21,25);
1311     int ra = bits(insn,16,20);
1312     m_uint16_t imm = bits(insn,0,15);
1313 dpavlin 9 m_uint32_t tmp = imm;
1314     int hreg_rs,hreg_ra;
1315     jit_op_t *iop;
1316 dpavlin 7
1317     /* $ra = $rs & imm */
1318 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"andi");
1319     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
1320     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1321 dpavlin 7
1322 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1323    
1324     iop = ppc32_op_emit_insn_output(cpu,2,"andi");
1325    
1326     if (ra != rs)
1327     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1328    
1329     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,tmp);
1330     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1331    
1332     ppc32_op_emit_update_flags(cpu,0,TRUE);
1333    
1334     ppc32_jit_close_hreg_seq(cpu);
1335 dpavlin 7 return(0);
1336     }
1337    
1338     /* AND Immediate Shifted */
1339     DECLARE_INSN(ANDIS)
1340     {
1341     int rs = bits(insn,21,25);
1342     int ra = bits(insn,16,20);
1343     m_uint32_t imm = bits(insn,0,15);
1344 dpavlin 9 m_uint32_t tmp = imm << 16;
1345     int hreg_rs,hreg_ra;
1346     jit_op_t *iop;
1347 dpavlin 7
1348     /* $ra = $rs & imm */
1349 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"andis");
1350     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
1351     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1352 dpavlin 7
1353 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1354    
1355     iop = ppc32_op_emit_insn_output(cpu,2,"andis");
1356    
1357     if (ra != rs)
1358     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1359    
1360     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,tmp);
1361     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1362    
1363     ppc32_op_emit_update_flags(cpu,0,TRUE);
1364    
1365     ppc32_jit_close_hreg_seq(cpu);
1366 dpavlin 7 return(0);
1367     }
1368    
1369     /* B - Branch */
1370     DECLARE_INSN(B)
1371     {
1372     m_uint32_t offset = bits(insn,2,25);
1373 dpavlin 9 m_uint32_t new_ia;
1374     jit_op_t *iop;
1375 dpavlin 7
1376 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,4,"b");
1377    
1378 dpavlin 7 /* compute the new ia */
1379 dpavlin 9 new_ia = b->start_ia + (b->ppc_trans_pos << 2);
1380 dpavlin 7 new_ia += sign_extend(offset << 2,26);
1381 dpavlin 9 ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1382    
1383     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1384     ppc32_op_emit_branch_target(cpu,b,new_ia);
1385     ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1386 dpavlin 7 return(0);
1387     }
1388    
1389     /* BA - Branch Absolute */
1390     DECLARE_INSN(BA)
1391     {
1392     m_uint32_t offset = bits(insn,2,25);
1393 dpavlin 9 m_uint32_t new_ia;
1394     jit_op_t *iop;
1395 dpavlin 7
1396 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,4,"ba");
1397    
1398 dpavlin 7 /* compute the new ia */
1399     new_ia = sign_extend(offset << 2,26);
1400 dpavlin 9 ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1401    
1402     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1403     ppc32_op_emit_branch_target(cpu,b,new_ia);
1404     ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1405 dpavlin 7 return(0);
1406     }
1407    
1408     /* BL - Branch and Link */
1409     DECLARE_INSN(BL)
1410     {
1411     m_uint32_t offset = bits(insn,2,25);
1412 dpavlin 9 m_uint32_t new_ia;
1413     jit_op_t *iop;
1414 dpavlin 7
1415 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,4,"bl");
1416    
1417 dpavlin 7 /* compute the new ia */
1418 dpavlin 9 new_ia = b->start_ia + (b->ppc_trans_pos << 2);
1419 dpavlin 7 new_ia += sign_extend(offset << 2,26);
1420    
1421     /* set the return address */
1422 dpavlin 9 ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1423     ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1424 dpavlin 7
1425 dpavlin 9 ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1426     ppc32_op_emit_branch_target(cpu,b,new_ia);
1427     ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1428 dpavlin 7 return(0);
1429     }
1430    
1431     /* BLA - Branch and Link Absolute */
1432     DECLARE_INSN(BLA)
1433     {
1434     m_uint32_t offset = bits(insn,2,25);
1435 dpavlin 9 m_uint32_t new_ia;
1436     jit_op_t *iop;
1437 dpavlin 7
1438 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,4,"bla");
1439    
1440 dpavlin 7 /* compute the new ia */
1441     new_ia = sign_extend(offset << 2,26);
1442    
1443     /* set the return address */
1444 dpavlin 9 ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1445     ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1446 dpavlin 7
1447 dpavlin 9 ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1448     ppc32_op_emit_branch_target(cpu,b,new_ia);
1449     ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1450 dpavlin 7 return(0);
1451     }
1452    
1453     /* BC - Branch Conditional (Condition Check only) */
1454     DECLARE_INSN(BCC)
1455     {
1456     int bo = bits(insn,21,25);
1457     int bi = bits(insn,16,20);
1458     int bd = bits(insn,2,15);
1459 dpavlin 9 jit_op_t *iop;
1460 dpavlin 8 u_int cr_field,cr_bit;
1461 dpavlin 7 m_uint32_t new_ia;
1462     u_char *jump_ptr;
1463     int local_jump;
1464     int cond;
1465    
1466 dpavlin 9 ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP);
1467    
1468     iop = ppc32_op_emit_insn_output(cpu,5,"bcc");
1469    
1470 dpavlin 7 /* Get the wanted value for the condition bit */
1471     cond = (bo >> 3) & 0x1;
1472    
1473     /* Set the return address */
1474 dpavlin 9 if (insn & 1) {
1475     ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1476     ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2));
1477     }
1478 dpavlin 7
1479     /* Compute the new ia */
1480     new_ia = sign_extend_32(bd << 2,16);
1481     if (!(insn & 0x02))
1482 dpavlin 9 new_ia += b->start_ia + (b->ppc_trans_pos << 2);
1483 dpavlin 7
1484     /* Test the condition bit */
1485 dpavlin 8 cr_field = ppc32_get_cr_field(bi);
1486     cr_bit = ppc32_get_cr_bit(bi);
1487 dpavlin 7
1488 dpavlin 9 ppc32_op_emit_require_flags(cpu,cr_field);
1489    
1490     x86_test_membase_imm(iop->ob_ptr,
1491 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
1492     (1 << cr_bit));
1493    
1494 dpavlin 7 local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
1495    
1496     /*
1497     * Optimize the jump, depending if the destination is in the same
1498     * page or not.
1499     */
1500     if (local_jump) {
1501 dpavlin 9 ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia);
1502     x86_branch32(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,0,FALSE);
1503 dpavlin 7 } else {
1504 dpavlin 9 jump_ptr = iop->ob_ptr;
1505     x86_branch32(iop->ob_ptr,(cond) ? X86_CC_Z : X86_CC_NZ,0,FALSE);
1506     ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1507     x86_patch(jump_ptr,iop->ob_ptr);
1508 dpavlin 7 }
1509    
1510 dpavlin 9 ppc32_op_emit_branch_target(cpu,b,new_ia);
1511 dpavlin 7 return(0);
1512     }
1513    
1514     /* BC - Branch Conditional */
1515     DECLARE_INSN(BC)
1516     {
1517     int bo = bits(insn,21,25);
1518     int bi = bits(insn,16,20);
1519     int bd = bits(insn,2,15);
1520 dpavlin 9 int hreg_t0,hreg_t1;
1521     jit_op_t *iop;
1522 dpavlin 8 u_int cr_field,cr_bit;
1523 dpavlin 7 m_uint32_t new_ia;
1524     u_char *jump_ptr;
1525     int local_jump;
1526     int cond,ctr;
1527    
1528 dpavlin 9 ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP);
1529    
1530     iop = ppc32_op_emit_insn_output(cpu,5,"bc");
1531    
1532     ppc32_jit_start_hreg_seq(cpu,"bc");
1533     hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
1534     hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
1535    
1536     ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
1537    
1538 dpavlin 7 /* Get the wanted value for the condition bit and CTR value */
1539     cond = (bo >> 3) & 0x1;
1540     ctr = (bo >> 1) & 0x1;
1541    
1542     /* Set the return address */
1543 dpavlin 9 if (insn & 1) {
1544     ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1545     ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2));
1546     }
1547 dpavlin 7
1548     /* Compute the new ia */
1549     new_ia = sign_extend_32(bd << 2,16);
1550     if (!(insn & 0x02))
1551 dpavlin 9 new_ia += b->start_ia + (b->ppc_trans_pos << 2);
1552 dpavlin 7
1553 dpavlin 9 x86_mov_reg_imm(iop->ob_ptr,hreg_t0,1);
1554 dpavlin 7
1555     /* Decrement the count register */
1556     if (!(bo & 0x04)) {
1557 dpavlin 9 x86_dec_membase(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
1558     x86_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE);
1559     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1560 dpavlin 7 }
1561    
1562     /* Test the condition bit */
1563     if (!((bo >> 4) & 0x01)) {
1564 dpavlin 8 cr_field = ppc32_get_cr_field(bi);
1565     cr_bit = ppc32_get_cr_bit(bi);
1566    
1567 dpavlin 9 ppc32_op_emit_require_flags(cpu,cr_field);
1568    
1569     x86_test_membase_imm(iop->ob_ptr,
1570 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
1571     (1 << cr_bit));
1572    
1573 dpavlin 9 x86_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE);
1574     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1575 dpavlin 7 }
1576    
1577 dpavlin 9 x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1578 dpavlin 7
1579     local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
1580    
1581     /*
1582     * Optimize the jump, depending if the destination is in the same
1583     * page or not.
1584     */
1585     if (local_jump) {
1586 dpavlin 9 ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia);
1587     x86_branch32(iop->ob_ptr,X86_CC_NZ,0,FALSE);
1588 dpavlin 7 } else {
1589 dpavlin 9 jump_ptr = iop->ob_ptr;
1590     x86_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE);
1591     ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1592     x86_patch(jump_ptr,iop->ob_ptr);
1593 dpavlin 7 }
1594    
1595 dpavlin 9 ppc32_op_emit_branch_target(cpu,b,new_ia);
1596    
1597     ppc32_jit_close_hreg_seq(cpu);
1598 dpavlin 7 return(0);
1599     }
1600    
1601     /* BCLR - Branch Conditional to Link register */
1602     DECLARE_INSN(BCLR)
1603     {
1604     int bo = bits(insn,21,25);
1605     int bi = bits(insn,16,20);
1606     int bd = bits(insn,2,15);
1607 dpavlin 9 int hreg_t0,hreg_t1;
1608     jit_op_t *iop;
1609 dpavlin 8 u_int cr_field,cr_bit;
1610 dpavlin 7 m_uint32_t new_ia;
1611     u_char *jump_ptr;
1612     int cond,ctr;
1613    
1614 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"bclr");
1615     hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
1616     hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
1617    
1618     ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
1619    
1620     iop = ppc32_op_emit_insn_output(cpu,5,"bclr");
1621    
1622 dpavlin 7 /* Get the wanted value for the condition bit and CTR value */
1623     cond = (bo >> 3) & 0x1;
1624     ctr = (bo >> 1) & 0x1;
1625    
1626     /* Compute the new ia */
1627     new_ia = sign_extend_32(bd << 2,16);
1628     if (!(insn & 0x02))
1629 dpavlin 9 new_ia += b->start_ia + (b->ppc_trans_pos << 2);
1630 dpavlin 7
1631 dpavlin 9 x86_mov_reg_imm(iop->ob_ptr,hreg_t0,1);
1632 dpavlin 7
1633     /* Decrement the count register */
1634     if (!(bo & 0x04)) {
1635 dpavlin 9 x86_dec_membase(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
1636     x86_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE);
1637     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1638 dpavlin 7 }
1639    
1640     /* Test the condition bit */
1641     if (!((bo >> 4) & 0x01)) {
1642 dpavlin 8 cr_field = ppc32_get_cr_field(bi);
1643     cr_bit = ppc32_get_cr_bit(bi);
1644    
1645 dpavlin 9 ppc32_op_emit_require_flags(cpu,cr_field);
1646    
1647     x86_test_membase_imm(iop->ob_ptr,
1648 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
1649     (1 << cr_bit));
1650    
1651 dpavlin 9 x86_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE);
1652     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1653 dpavlin 7 }
1654    
1655     /* Set the return address */
1656 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,hreg_t1,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
1657 dpavlin 7
1658 dpavlin 9 if (insn & 1) {
1659     ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1660     ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2));
1661     }
1662 dpavlin 7
1663     /* Branching */
1664 dpavlin 9 x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1665 dpavlin 7
1666 dpavlin 9 jump_ptr = iop->ob_ptr;
1667     x86_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE);
1668 dpavlin 7
1669 dpavlin 9 x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t1,0xFFFFFFFC);
1670     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),hreg_t1,4);
1671     ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
1672 dpavlin 7
1673 dpavlin 9 x86_patch(jump_ptr,iop->ob_ptr);
1674    
1675     ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1676    
1677     ppc32_jit_close_hreg_seq(cpu);
1678 dpavlin 7 return(0);
1679     }
1680    
1681     /* CMP - Compare */
1682     DECLARE_INSN(CMP)
1683     {
1684     int rd = bits(insn,23,25);
1685     int ra = bits(insn,16,20);
1686     int rb = bits(insn,11,15);
1687 dpavlin 9 int hreg_ra,hreg_rb;
1688     jit_op_t *iop;
1689    
1690     ppc32_jit_start_hreg_seq(cpu,"cmp");
1691     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1692     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1693 dpavlin 7
1694 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1695     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1696    
1697     iop = ppc32_op_emit_insn_output(cpu,1,"cmp");
1698    
1699     x86_alu_reg_reg(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb);
1700     ppc32_op_emit_update_flags(cpu,rd,TRUE);
1701    
1702     ppc32_jit_close_hreg_seq(cpu);
1703 dpavlin 7 return(0);
1704     }
1705    
1706     /* CMPI - Compare Immediate */
1707     DECLARE_INSN(CMPI)
1708     {
1709     int rd = bits(insn,23,25);
1710     int ra = bits(insn,16,20);
1711     m_uint16_t imm = bits(insn,0,15);
1712     m_uint32_t tmp = sign_extend_32(imm,16);
1713 dpavlin 9 int hreg_ra;
1714     jit_op_t *iop;
1715 dpavlin 7
1716 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"cmpi");
1717     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1718     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1719 dpavlin 7
1720 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,1,"cmpi");
1721    
1722     x86_alu_reg_imm(iop->ob_ptr,X86_CMP,hreg_ra,tmp);
1723     ppc32_op_emit_update_flags(cpu,rd,TRUE);
1724    
1725     ppc32_jit_close_hreg_seq(cpu);
1726 dpavlin 7 return(0);
1727     }
1728    
1729     /* CMPL - Compare Logical */
1730     DECLARE_INSN(CMPL)
1731     {
1732     int rd = bits(insn,23,25);
1733     int ra = bits(insn,16,20);
1734     int rb = bits(insn,11,15);
1735 dpavlin 9 int hreg_ra,hreg_rb;
1736     jit_op_t *iop;
1737    
1738     ppc32_jit_start_hreg_seq(cpu,"cmpl");
1739     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1740     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1741 dpavlin 7
1742 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1743     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1744    
1745     iop = ppc32_op_emit_insn_output(cpu,1,"cmpl");
1746    
1747     x86_alu_reg_reg(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb);
1748     ppc32_op_emit_update_flags(cpu,rd,FALSE);
1749    
1750     ppc32_jit_close_hreg_seq(cpu);
1751 dpavlin 7 return(0);
1752     }
1753    
1754     /* CMPLI - Compare Immediate */
1755     DECLARE_INSN(CMPLI)
1756     {
1757     int rd = bits(insn,23,25);
1758     int ra = bits(insn,16,20);
1759 dpavlin 9 m_uint32_t imm = bits(insn,0,15);
1760     int hreg_ra;
1761     jit_op_t *iop;
1762 dpavlin 7
1763 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"cmpli");
1764     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1765     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1766 dpavlin 7
1767 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,1,"cmpli");
1768    
1769     x86_alu_reg_imm(iop->ob_ptr,X86_CMP,hreg_ra,imm);
1770     ppc32_op_emit_update_flags(cpu,rd,FALSE);
1771    
1772     ppc32_jit_close_hreg_seq(cpu);
1773 dpavlin 7 return(0);
1774     }
1775    
1776     /* CRAND - Condition Register AND */
1777     DECLARE_INSN(CRAND)
1778     {
1779     int bd = bits(insn,21,25);
1780     int bb = bits(insn,16,20);
1781     int ba = bits(insn,11,15);
1782 dpavlin 9 int hreg_t0;
1783     jit_op_t *iop;
1784 dpavlin 7
1785 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
1786    
1787     ppc32_jit_start_hreg_seq(cpu,"crand");
1788     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1789     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
1790    
1791     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1792     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1793     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1794    
1795     iop = ppc32_op_emit_insn_output(cpu,3,"crand");
1796    
1797 dpavlin 7 /* test $ba bit */
1798 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
1799 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1800     (1 << ppc32_get_cr_bit(ba)));
1801 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1802 dpavlin 7
1803     /* test $bb bit */
1804 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
1805 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
1806     (1 << ppc32_get_cr_bit(bb)));
1807 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1808 dpavlin 7
1809     /* result of AND between $ba and $bb */
1810 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,X86_EDX);
1811     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1812 dpavlin 7
1813     /* set/clear $bd bit depending on the result */
1814 dpavlin 9 x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1815 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1816     ~(1 << ppc32_get_cr_bit(bd)));
1817 dpavlin 7
1818 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
1819     x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1820 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1821 dpavlin 9 hreg_t0);
1822    
1823     ppc32_jit_close_hreg_seq(cpu);
1824 dpavlin 7 return(0);
1825     }
1826    
1827     /* CRANDC - Condition Register AND with Complement */
1828     DECLARE_INSN(CRANDC)
1829     {
1830     int bd = bits(insn,21,25);
1831     int bb = bits(insn,16,20);
1832     int ba = bits(insn,11,15);
1833 dpavlin 9 int hreg_t0;
1834     jit_op_t *iop;
1835 dpavlin 7
1836 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
1837    
1838     ppc32_jit_start_hreg_seq(cpu,"crandc");
1839     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1840     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
1841    
1842     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1843     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1844     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1845    
1846     iop = ppc32_op_emit_insn_output(cpu,3,"crandc");
1847    
1848 dpavlin 7 /* test $ba bit */
1849 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
1850 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1851     (1 << ppc32_get_cr_bit(ba)));
1852 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1853 dpavlin 7
1854     /* test $bb bit */
1855 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
1856 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
1857     (1 << ppc32_get_cr_bit(bb)));
1858 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_Z,hreg_t0,FALSE);
1859 dpavlin 7
1860     /* result of AND between $ba and $bb */
1861 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,X86_EDX);
1862     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1863 dpavlin 7
1864     /* set/clear $bd bit depending on the result */
1865 dpavlin 9 x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1866 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1867     ~(1 << ppc32_get_cr_bit(bd)));
1868 dpavlin 7
1869 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
1870     x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1871 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1872 dpavlin 9 hreg_t0);
1873    
1874     ppc32_jit_close_hreg_seq(cpu);
1875 dpavlin 7 return(0);
1876     }
1877    
1878     /* CREQV - Condition Register EQV */
1879     DECLARE_INSN(CREQV)
1880     {
1881     int bd = bits(insn,21,25);
1882     int bb = bits(insn,16,20);
1883     int ba = bits(insn,11,15);
1884 dpavlin 9 int hreg_t0;
1885     jit_op_t *iop;
1886 dpavlin 7
1887 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
1888    
1889     ppc32_jit_start_hreg_seq(cpu,"creqv");
1890     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1891     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
1892    
1893     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1894     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1895     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1896    
1897     iop = ppc32_op_emit_insn_output(cpu,3,"creqv");
1898    
1899 dpavlin 7 /* test $ba bit */
1900 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
1901 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1902     (1 << ppc32_get_cr_bit(ba)));
1903 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1904 dpavlin 7
1905     /* test $bb bit */
1906 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
1907 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
1908     (1 << ppc32_get_cr_bit(bb)));
1909 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1910 dpavlin 7
1911     /* result of XOR between $ba and $bb */
1912 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,X86_EDX);
1913     x86_not_reg(iop->ob_ptr,hreg_t0);
1914     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1915 dpavlin 7
1916     /* set/clear $bd bit depending on the result */
1917 dpavlin 9 x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1918 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1919     ~(1 << ppc32_get_cr_bit(bd)));
1920 dpavlin 7
1921 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
1922     x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1923 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1924 dpavlin 9 hreg_t0);
1925    
1926     ppc32_jit_close_hreg_seq(cpu);
1927 dpavlin 7 return(0);
1928     }
1929    
1930     /* CRNAND - Condition Register NAND */
1931     DECLARE_INSN(CRNAND)
1932     {
1933     int bd = bits(insn,21,25);
1934     int bb = bits(insn,16,20);
1935     int ba = bits(insn,11,15);
1936 dpavlin 9 int hreg_t0;
1937     jit_op_t *iop;
1938 dpavlin 7
1939 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
1940    
1941     ppc32_jit_start_hreg_seq(cpu,"crnand");
1942     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1943     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
1944    
1945     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1946     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1947     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1948    
1949     iop = ppc32_op_emit_insn_output(cpu,3,"crnand");
1950    
1951 dpavlin 7 /* test $ba bit */
1952 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
1953 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1954     (1 << ppc32_get_cr_bit(ba)));
1955 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
1956 dpavlin 7
1957     /* test $bb bit */
1958 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
1959 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
1960     (1 << ppc32_get_cr_bit(bb)));
1961 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1962 dpavlin 7
1963     /* result of NAND between $ba and $bb */
1964 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,X86_EDX);
1965     x86_not_reg(iop->ob_ptr,hreg_t0);
1966     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1967 dpavlin 7
1968     /* set/clear $bd bit depending on the result */
1969 dpavlin 9 x86_alu_membase_imm(iop->ob_ptr,X86_AND,
1970 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1971     ~(1 << ppc32_get_cr_bit(bd)));
1972 dpavlin 7
1973 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
1974     x86_alu_membase_reg(iop->ob_ptr,X86_OR,
1975 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1976 dpavlin 9 hreg_t0);
1977    
1978     ppc32_jit_close_hreg_seq(cpu);
1979 dpavlin 7 return(0);
1980     }
1981    
1982     /* CRNOR - Condition Register NOR */
1983     DECLARE_INSN(CRNOR)
1984     {
1985     int bd = bits(insn,21,25);
1986     int bb = bits(insn,16,20);
1987     int ba = bits(insn,11,15);
1988 dpavlin 9 int hreg_t0;
1989     jit_op_t *iop;
1990 dpavlin 7
1991 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
1992    
1993     ppc32_jit_start_hreg_seq(cpu,"crnor");
1994     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1995     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
1996    
1997     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1998     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1999     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
2000    
2001     iop = ppc32_op_emit_insn_output(cpu,3,"crnor");
2002    
2003 dpavlin 7 /* test $ba bit */
2004 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
2005 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
2006     (1 << ppc32_get_cr_bit(ba)));
2007 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
2008 dpavlin 7
2009     /* test $bb bit */
2010 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
2011 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
2012     (1 << ppc32_get_cr_bit(bb)));
2013 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
2014 dpavlin 7
2015     /* result of NOR between $ba and $bb */
2016 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,X86_EDX);
2017     x86_not_reg(iop->ob_ptr,hreg_t0);
2018     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
2019 dpavlin 7
2020     /* set/clear $bd bit depending on the result */
2021 dpavlin 9 x86_alu_membase_imm(iop->ob_ptr,X86_AND,
2022 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2023     ~(1 << ppc32_get_cr_bit(bd)));
2024 dpavlin 7
2025 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
2026     x86_alu_membase_reg(iop->ob_ptr,X86_OR,
2027 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2028 dpavlin 9 hreg_t0);
2029    
2030     ppc32_jit_close_hreg_seq(cpu);
2031 dpavlin 7 return(0);
2032     }
2033    
2034     /* CROR - Condition Register OR */
2035     DECLARE_INSN(CROR)
2036     {
2037     int bd = bits(insn,21,25);
2038     int bb = bits(insn,16,20);
2039     int ba = bits(insn,11,15);
2040 dpavlin 9 int hreg_t0;
2041     jit_op_t *iop;
2042 dpavlin 7
2043 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
2044    
2045     ppc32_jit_start_hreg_seq(cpu,"cror");
2046     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2047     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
2048    
2049     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
2050     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
2051     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
2052    
2053     iop = ppc32_op_emit_insn_output(cpu,3,"cror");
2054    
2055 dpavlin 7 /* test $ba bit */
2056 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
2057 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
2058     (1 << ppc32_get_cr_bit(ba)));
2059 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
2060 dpavlin 7
2061     /* test $bb bit */
2062 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
2063 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
2064     (1 << ppc32_get_cr_bit(bb)));
2065 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
2066 dpavlin 7
2067     /* result of OR between $ba and $bb */
2068 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,X86_EDX);
2069     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
2070 dpavlin 7
2071     /* set/clear $bd bit depending on the result */
2072 dpavlin 9 x86_alu_membase_imm(iop->ob_ptr,X86_AND,
2073 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2074     ~(1 << ppc32_get_cr_bit(bd)));
2075 dpavlin 7
2076 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
2077     x86_alu_membase_reg(iop->ob_ptr,X86_OR,
2078 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2079 dpavlin 9 hreg_t0);
2080    
2081     ppc32_jit_close_hreg_seq(cpu);
2082 dpavlin 7 return(0);
2083     }
2084    
2085     /* CRORC - Condition Register OR with Complement */
2086     DECLARE_INSN(CRORC)
2087     {
2088     int bd = bits(insn,21,25);
2089     int bb = bits(insn,16,20);
2090     int ba = bits(insn,11,15);
2091 dpavlin 9 int hreg_t0;
2092     jit_op_t *iop;
2093 dpavlin 7
2094 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
2095    
2096     ppc32_jit_start_hreg_seq(cpu,"crorc");
2097     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2098     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
2099    
2100     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
2101     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
2102     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
2103    
2104     iop = ppc32_op_emit_insn_output(cpu,3,"crorc");
2105    
2106 dpavlin 7 /* test $ba bit */
2107 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
2108 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
2109     (1 << ppc32_get_cr_bit(ba)));
2110 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
2111 dpavlin 7
2112     /* test $bb bit */
2113 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
2114 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
2115     (1 << ppc32_get_cr_bit(bb)));
2116 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_Z,hreg_t0,FALSE);
2117 dpavlin 7
2118     /* result of ORC between $ba and $bb */
2119 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,X86_EDX);
2120     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
2121 dpavlin 7
2122     /* set/clear $bd bit depending on the result */
2123 dpavlin 9 x86_alu_membase_imm(iop->ob_ptr,X86_AND,
2124 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2125     ~(1 << ppc32_get_cr_bit(bd)));
2126 dpavlin 7
2127 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
2128     x86_alu_membase_reg(iop->ob_ptr,X86_OR,
2129 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2130 dpavlin 9 hreg_t0);
2131    
2132     ppc32_jit_close_hreg_seq(cpu);
2133 dpavlin 7 return(0);
2134     }
2135    
2136     /* CRXOR - Condition Register XOR */
2137     DECLARE_INSN(CRXOR)
2138     {
2139     int bd = bits(insn,21,25);
2140     int bb = bits(insn,16,20);
2141     int ba = bits(insn,11,15);
2142 dpavlin 9 int hreg_t0;
2143     jit_op_t *iop;
2144 dpavlin 7
2145 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
2146    
2147     ppc32_jit_start_hreg_seq(cpu,"crxor");
2148     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2149     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
2150    
2151     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
2152     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
2153     ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
2154    
2155     iop = ppc32_op_emit_insn_output(cpu,3,"crxor");
2156    
2157 dpavlin 7 /* test $ba bit */
2158 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
2159 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
2160     (1 << ppc32_get_cr_bit(ba)));
2161 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,X86_EDX,FALSE);
2162 dpavlin 7
2163     /* test $bb bit */
2164 dpavlin 9 x86_test_membase_imm(iop->ob_ptr,
2165 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
2166     (1 << ppc32_get_cr_bit(bb)));
2167 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
2168 dpavlin 7
2169     /* result of XOR between $ba and $bb */
2170 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,X86_EDX);
2171     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
2172 dpavlin 7
2173     /* set/clear $bd bit depending on the result */
2174 dpavlin 9 x86_alu_membase_imm(iop->ob_ptr,X86_AND,
2175 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2176     ~(1 << ppc32_get_cr_bit(bd)));
2177 dpavlin 7
2178 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
2179     x86_alu_membase_reg(iop->ob_ptr,X86_OR,
2180 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2181 dpavlin 9 hreg_t0);
2182    
2183     ppc32_jit_close_hreg_seq(cpu);
2184 dpavlin 7 return(0);
2185     }
2186    
2187     /* DIVWU - Divide Word Unsigned */
2188     DECLARE_INSN(DIVWU)
2189     {
2190     int rd = bits(insn,21,25);
2191     int ra = bits(insn,16,20);
2192     int rb = bits(insn,11,15);
2193 dpavlin 9 int hreg_rb;
2194     jit_op_t *iop;
2195 dpavlin 7
2196 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"divwu");
2197     ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
2198     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
2199     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2200 dpavlin 7
2201 dpavlin 9 /* $rd = $ra / $rb */
2202     ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
2203     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2204 dpavlin 7
2205 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,2,"divwu");
2206     ppc32_load_imm(&iop->ob_ptr,X86_EDX,0);
2207    
2208     x86_div_reg(iop->ob_ptr,hreg_rb,0);
2209    
2210     if (insn & 1)
2211     x86_test_reg_reg(iop->ob_ptr,X86_EAX,X86_EAX);
2212    
2213     ppc32_op_emit_store_gpr(cpu,rd,X86_EAX);
2214    
2215     if (insn & 1)
2216     ppc32_op_emit_update_flags(cpu,0,TRUE);
2217    
2218     /* edx:eax are directly modified: throw them */
2219     ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
2220     ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
2221    
2222     ppc32_jit_close_hreg_seq(cpu);
2223 dpavlin 7 return(0);
2224     }
2225    
2226     /* EQV */
2227     DECLARE_INSN(EQV)
2228     {
2229     int rs = bits(insn,21,25);
2230     int ra = bits(insn,16,20);
2231     int rb = bits(insn,11,15);
2232 dpavlin 9 int hreg_rs,hreg_ra,hreg_rb;
2233     jit_op_t *iop;
2234 dpavlin 7
2235     /* $ra = ~($rs ^ $rb) */
2236 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"eqv");
2237     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2238     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2239     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2240 dpavlin 7
2241 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2242     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2243    
2244     iop = ppc32_op_emit_insn_output(cpu,1,"eqv");
2245    
2246     if (ra == rs)
2247     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb);
2248     else if (ra == rb)
2249     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rs);
2250     else {
2251     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2252     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb);
2253 dpavlin 7 }
2254    
2255 dpavlin 9 x86_not_reg(iop->ob_ptr,hreg_ra);
2256    
2257     if (insn & 1)
2258     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
2259    
2260     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2261    
2262     if (insn & 1)
2263     ppc32_op_emit_update_flags(cpu,0,TRUE);
2264    
2265     ppc32_jit_close_hreg_seq(cpu);
2266 dpavlin 7 return(0);
2267     }
2268    
2269     /* EXTSB - Extend Sign Byte */
2270     DECLARE_INSN(EXTSB)
2271     {
2272     int rs = bits(insn,21,25);
2273     int ra = bits(insn,16,20);
2274 dpavlin 9 int hreg_rs,hreg_ra;
2275     jit_op_t *iop;
2276 dpavlin 7
2277 dpavlin 9 /* $ra = extsb($rs) */
2278     ppc32_jit_start_hreg_seq(cpu,"extsb");
2279     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2280     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2281 dpavlin 7
2282 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2283 dpavlin 7
2284 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,2,"extsb");
2285    
2286     if (rs != ra)
2287     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2288    
2289     x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_ra,24);
2290     x86_shift_reg_imm(iop->ob_ptr,X86_SAR,hreg_ra,24);
2291    
2292     if (insn & 1)
2293     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
2294    
2295     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2296    
2297     if (insn & 1)
2298     ppc32_op_emit_update_flags(cpu,0,TRUE);
2299    
2300     ppc32_jit_close_hreg_seq(cpu);
2301 dpavlin 7 return(0);
2302     }
2303    
2304     /* EXTSH - Extend Sign Word */
2305     DECLARE_INSN(EXTSH)
2306     {
2307     int rs = bits(insn,21,25);
2308     int ra = bits(insn,16,20);
2309 dpavlin 9 int hreg_rs,hreg_ra;
2310     jit_op_t *iop;
2311 dpavlin 7
2312 dpavlin 9 /* $ra = extsh($rs) */
2313     ppc32_jit_start_hreg_seq(cpu,"extsh");
2314     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2315     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2316 dpavlin 7
2317 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2318 dpavlin 7
2319 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,2,"extsh");
2320    
2321     if (rs != ra)
2322     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2323    
2324     x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_ra,16);
2325     x86_shift_reg_imm(iop->ob_ptr,X86_SAR,hreg_ra,16);
2326    
2327     if (insn & 1)
2328     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
2329    
2330     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2331    
2332     if (insn & 1)
2333     ppc32_op_emit_update_flags(cpu,0,TRUE);
2334    
2335     ppc32_jit_close_hreg_seq(cpu);
2336 dpavlin 7 return(0);
2337     }
2338    
2339     /* LBZ - Load Byte and Zero */
2340     DECLARE_INSN(LBZ)
2341     {
2342     int rs = bits(insn,21,25);
2343     int ra = bits(insn,16,20);
2344     m_uint16_t offset = bits(insn,0,15);
2345    
2346 dpavlin 9 //ppc32_emit_memop(cpu,b,PPC_MEMOP_LBZ,ra,offset,rs,0);
2347     ppc32_emit_memop_fast(cpu,b,0,PPC_MEMOP_LBZ,ra,offset,rs,
2348     ppc32_memop_fast_lbz);
2349 dpavlin 7 return(0);
2350     }
2351    
2352     /* LBZU - Load Byte and Zero with Update */
2353     DECLARE_INSN(LBZU)
2354     {
2355     int rs = bits(insn,21,25);
2356     int ra = bits(insn,16,20);
2357     m_uint16_t offset = bits(insn,0,15);
2358    
2359 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_LBZ,ra,offset,rs,1);
2360 dpavlin 7 return(0);
2361     }
2362    
2363     /* LBZUX - Load Byte and Zero with Update Indexed */
2364     DECLARE_INSN(LBZUX)
2365     {
2366     int rs = bits(insn,21,25);
2367     int ra = bits(insn,16,20);
2368     int rb = bits(insn,11,15);
2369    
2370 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LBZ,ra,rb,rs,1);
2371 dpavlin 7 return(0);
2372     }
2373    
2374     /* LBZX - Load Byte and Zero Indexed */
2375     DECLARE_INSN(LBZX)
2376     {
2377     int rs = bits(insn,21,25);
2378     int ra = bits(insn,16,20);
2379     int rb = bits(insn,11,15);
2380    
2381 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LBZ,ra,rb,rs,0);
2382 dpavlin 7 return(0);
2383     }
2384    
2385     /* LHA - Load Half-Word Algebraic */
2386     DECLARE_INSN(LHA)
2387     {
2388     int rs = bits(insn,21,25);
2389     int ra = bits(insn,16,20);
2390     m_uint16_t offset = bits(insn,0,15);
2391    
2392 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_LHA,ra,offset,rs,0);
2393 dpavlin 7 return(0);
2394     }
2395    
2396     /* LHAU - Load Half-Word Algebraic with Update */
2397     DECLARE_INSN(LHAU)
2398     {
2399     int rs = bits(insn,21,25);
2400     int ra = bits(insn,16,20);
2401     m_uint16_t offset = bits(insn,0,15);
2402    
2403 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_LHA,ra,offset,rs,1);
2404 dpavlin 7 return(0);
2405     }
2406    
2407     /* LHAUX - Load Half-Word Algebraic with Update Indexed */
2408     DECLARE_INSN(LHAUX)
2409     {
2410     int rs = bits(insn,21,25);
2411     int ra = bits(insn,16,20);
2412     int rb = bits(insn,11,15);
2413    
2414 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHA,ra,rb,rs,1);
2415 dpavlin 7 return(0);
2416     }
2417    
2418     /* LHAX - Load Half-Word Algebraic Indexed */
2419     DECLARE_INSN(LHAX)
2420     {
2421     int rs = bits(insn,21,25);
2422     int ra = bits(insn,16,20);
2423     int rb = bits(insn,11,15);
2424    
2425 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHA,ra,rb,rs,0);
2426 dpavlin 7 return(0);
2427     }
2428    
2429     /* LHZ - Load Half-Word and Zero */
2430     DECLARE_INSN(LHZ)
2431     {
2432     int rs = bits(insn,21,25);
2433     int ra = bits(insn,16,20);
2434     m_uint16_t offset = bits(insn,0,15);
2435    
2436 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_LHZ,ra,offset,rs,0);
2437 dpavlin 7 return(0);
2438     }
2439    
2440     /* LHZU - Load Half-Word and Zero with Update */
2441     DECLARE_INSN(LHZU)
2442     {
2443     int rs = bits(insn,21,25);
2444     int ra = bits(insn,16,20);
2445     m_uint16_t offset = bits(insn,0,15);
2446    
2447 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_LHZ,ra,offset,rs,1);
2448 dpavlin 7 return(0);
2449     }
2450    
2451     /* LHZUX - Load Half-Word and Zero with Update Indexed */
2452     DECLARE_INSN(LHZUX)
2453     {
2454     int rs = bits(insn,21,25);
2455     int ra = bits(insn,16,20);
2456     int rb = bits(insn,11,15);
2457    
2458 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHZ,ra,rb,rs,1);
2459 dpavlin 7 return(0);
2460     }
2461    
2462     /* LHZX - Load Half-Word and Zero Indexed */
2463     DECLARE_INSN(LHZX)
2464     {
2465     int rs = bits(insn,21,25);
2466     int ra = bits(insn,16,20);
2467     int rb = bits(insn,11,15);
2468    
2469 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHZ,ra,rb,rs,0);
2470 dpavlin 7 return(0);
2471     }
2472    
2473     /* LWZ - Load Word and Zero */
2474     DECLARE_INSN(LWZ)
2475     {
2476     int rs = bits(insn,21,25);
2477     int ra = bits(insn,16,20);
2478     m_uint16_t offset = bits(insn,0,15);
2479    
2480     //ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,0);
2481 dpavlin 9 ppc32_emit_memop_fast(cpu,b,0,PPC_MEMOP_LWZ,ra,offset,rs,
2482     ppc32_memop_fast_lwz);
2483 dpavlin 7 return(0);
2484     }
2485    
2486     /* LWZU - Load Word and Zero with Update */
2487     DECLARE_INSN(LWZU)
2488     {
2489     int rs = bits(insn,21,25);
2490     int ra = bits(insn,16,20);
2491     m_uint16_t offset = bits(insn,0,15);
2492    
2493 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_LWZ,ra,offset,rs,1);
2494 dpavlin 7 return(0);
2495     }
2496    
2497     /* LWZUX - Load Word and Zero with Update Indexed */
2498     DECLARE_INSN(LWZUX)
2499     {
2500     int rs = bits(insn,21,25);
2501     int ra = bits(insn,16,20);
2502     int rb = bits(insn,11,15);
2503    
2504 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LWZ,ra,rb,rs,1);
2505 dpavlin 7 return(0);
2506     }
2507    
2508     /* LWZX - Load Word and Zero Indexed */
2509     DECLARE_INSN(LWZX)
2510     {
2511     int rs = bits(insn,21,25);
2512     int ra = bits(insn,16,20);
2513     int rb = bits(insn,11,15);
2514    
2515 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LWZ,ra,rb,rs,0);
2516 dpavlin 7 return(0);
2517     }
2518    
2519     /* MCRF - Move Condition Register Field */
2520     DECLARE_INSN(MCRF)
2521     {
2522     int rd = bits(insn,23,25);
2523     int rs = bits(insn,18,20);
2524 dpavlin 9 int hreg_t0;
2525     jit_op_t *iop;
2526 dpavlin 7
2527 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mcrf");
2528     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2529     ppc32_op_emit_require_flags(cpu,rs);
2530    
2531     iop = ppc32_op_emit_insn_output(cpu,1,"mcrf");
2532    
2533 dpavlin 8 /* Load "rs" field in %edx */
2534 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,hreg_t0,
2535     X86_EDI,PPC32_CR_FIELD_OFFSET(rs),4);
2536 dpavlin 7
2537 dpavlin 8 /* Store it in "rd" field */
2538 dpavlin 9 x86_mov_membase_reg(iop->ob_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(rd),
2539     hreg_t0,4);
2540    
2541     ppc32_jit_close_hreg_seq(cpu);
2542 dpavlin 7 return(0);
2543     }
2544    
2545     /* MFCR - Move from Condition Register */
2546     DECLARE_INSN(MFCR)
2547     {
2548     int rd = bits(insn,21,25);
2549 dpavlin 9 int hreg_rd,hreg_t0;
2550     jit_op_t *iop;
2551 dpavlin 8 int i;
2552 dpavlin 7
2553 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mfcr");
2554     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
2555     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2556     ppc32_op_emit_require_flags(cpu,JIT_OP_PPC_ALL_FLAGS);
2557 dpavlin 8
2558 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,3,"mfcr");
2559    
2560     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_rd,hreg_rd);
2561    
2562 dpavlin 8 for(i=0;i<8;i++) {
2563     /* load field in %edx */
2564 dpavlin 9 x86_mov_reg_membase(iop->ob_ptr,hreg_t0,
2565 dpavlin 8 X86_EDI,PPC32_CR_FIELD_OFFSET(i),4);
2566 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_rd,4);
2567     x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_rd,hreg_t0);
2568 dpavlin 8 }
2569    
2570 dpavlin 9 ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
2571    
2572     ppc32_jit_close_hreg_seq(cpu);
2573 dpavlin 7 return(0);
2574     }
2575    
2576     /* MFMSR - Move from Machine State Register */
2577     DECLARE_INSN(MFMSR)
2578     {
2579     int rd = bits(insn,21,25);
2580 dpavlin 9 int hreg_rd;
2581     jit_op_t *iop;
2582 dpavlin 7
2583 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mfmsr");
2584     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
2585    
2586     iop = ppc32_op_emit_insn_output(cpu,1,"mfmsr");
2587     x86_mov_reg_membase(iop->ob_ptr,hreg_rd,X86_EDI,OFFSET(cpu_ppc_t,msr),4);
2588     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
2589    
2590     ppc32_jit_close_hreg_seq(cpu);
2591 dpavlin 7 return(0);
2592     }
2593    
2594     /* MFSR - Move From Segment Register */
2595     DECLARE_INSN(MFSR)
2596     {
2597     int rd = bits(insn,21,25);
2598     int sr = bits(insn,16,19);
2599 dpavlin 9 int hreg_rd;
2600     jit_op_t *iop;
2601 dpavlin 7
2602 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mfsr");
2603     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
2604    
2605     iop = ppc32_op_emit_insn_output(cpu,1,"mfsr");
2606    
2607     x86_mov_reg_membase(iop->ob_ptr,hreg_rd,
2608 dpavlin 7 X86_EDI,(OFFSET(cpu_ppc_t,sr) + (sr << 2)),4);
2609 dpavlin 9 ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
2610    
2611     ppc32_jit_close_hreg_seq(cpu);
2612 dpavlin 7 return(0);
2613     }
2614    
2615     /* MTCRF - Move to Condition Register Fields */
2616     DECLARE_INSN(MTCRF)
2617     {
2618     int rs = bits(insn,21,25);
2619     int crm = bits(insn,12,19);
2620 dpavlin 9 int hreg_rs,hreg_t0;
2621     jit_op_t *iop;
2622 dpavlin 7 int i;
2623    
2624 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mtcrf");
2625     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2626     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2627 dpavlin 8
2628 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2629    
2630     iop = ppc32_op_emit_insn_output(cpu,3,"mtcrf");
2631    
2632 dpavlin 7 for(i=0;i<8;i++)
2633 dpavlin 8 if (crm & (1 << (7 - i))) {
2634 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
2635 dpavlin 7
2636 dpavlin 8 if (i != 7)
2637 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_SHR,hreg_t0,28 - (i << 2));
2638 dpavlin 7
2639 dpavlin 9 x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x0F);
2640     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(i),
2641     hreg_t0,4);
2642 dpavlin 8 }
2643 dpavlin 7
2644 dpavlin 9 ppc32_op_emit_basic_opcode(cpu,JIT_OP_TRASH_FLAGS);
2645    
2646     ppc32_jit_close_hreg_seq(cpu);
2647 dpavlin 7 return(0);
2648     }
2649    
2650     /* MULHW - Multiply High Word */
2651     DECLARE_INSN(MULHW)
2652     {
2653     int rd = bits(insn,21,25);
2654     int ra = bits(insn,16,20);
2655     int rb = bits(insn,11,15);
2656 dpavlin 9 int hreg_rb;
2657     jit_op_t *iop;
2658 dpavlin 7
2659 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mulhw");
2660     ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
2661     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
2662     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2663 dpavlin 7
2664 dpavlin 9 ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
2665     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2666 dpavlin 7
2667 dpavlin 9 /* rd = hi(ra * rb) */
2668     iop = ppc32_op_emit_insn_output(cpu,2,"mulhw");
2669     x86_mul_reg(iop->ob_ptr,hreg_rb,1);
2670    
2671     if (insn & 1)
2672     x86_test_reg_reg(iop->ob_ptr,X86_EDX,X86_EDX);
2673    
2674     ppc32_op_emit_store_gpr(cpu,rd,X86_EDX);
2675    
2676     if (insn & 1)
2677     ppc32_op_emit_update_flags(cpu,0,TRUE);
2678    
2679     /* edx:eax are directly modified: throw them */
2680     ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
2681     ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
2682    
2683     ppc32_jit_close_hreg_seq(cpu);
2684 dpavlin 7 return(0);
2685     }
2686    
2687     /* MULHWU - Multiply High Word Unsigned */
2688     DECLARE_INSN(MULHWU)
2689     {
2690     int rd = bits(insn,21,25);
2691     int ra = bits(insn,16,20);
2692     int rb = bits(insn,11,15);
2693 dpavlin 9 int hreg_rb;
2694     jit_op_t *iop;
2695 dpavlin 7
2696 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mulhwu");
2697     ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
2698     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
2699     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2700 dpavlin 7
2701 dpavlin 9 ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
2702     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2703 dpavlin 7
2704 dpavlin 9 /* rd = hi(ra * rb) */
2705     iop = ppc32_op_emit_insn_output(cpu,2,"mulhwu");
2706     x86_mul_reg(iop->ob_ptr,hreg_rb,0);
2707    
2708     if (insn & 1)
2709     x86_test_reg_reg(iop->ob_ptr,X86_EDX,X86_EDX);
2710    
2711     ppc32_op_emit_store_gpr(cpu,rd,X86_EDX);
2712    
2713     if (insn & 1)
2714     ppc32_op_emit_update_flags(cpu,0,TRUE);
2715    
2716     /* edx:eax are directly modified: throw them */
2717     ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
2718     ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
2719    
2720     ppc32_jit_close_hreg_seq(cpu);
2721 dpavlin 7 return(0);
2722     }
2723    
2724     /* MULLI - Multiply Low Immediate */
2725     DECLARE_INSN(MULLI)
2726     {
2727     int rd = bits(insn,21,25);
2728     int ra = bits(insn,16,20);
2729     m_uint32_t imm = bits(insn,0,15);
2730 dpavlin 9 int hreg_t0;
2731     jit_op_t *iop;
2732 dpavlin 7
2733 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mulli");
2734     ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
2735     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
2736     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2737 dpavlin 7
2738 dpavlin 9 ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
2739    
2740     /* rd = lo(ra * imm) */
2741     iop = ppc32_op_emit_insn_output(cpu,2,"mulli");
2742    
2743     ppc32_load_imm(&iop->ob_ptr,hreg_t0,sign_extend_32(imm,16));
2744     x86_mul_reg(iop->ob_ptr,hreg_t0,1);
2745     ppc32_op_emit_store_gpr(cpu,rd,X86_EAX);
2746    
2747     /* edx:eax are directly modified: throw them */
2748     ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
2749     ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
2750    
2751     ppc32_jit_close_hreg_seq(cpu);
2752 dpavlin 7 return(0);
2753     }
2754    
2755     /* MULLW - Multiply Low Word */
2756     DECLARE_INSN(MULLW)
2757     {
2758     int rd = bits(insn,21,25);
2759     int ra = bits(insn,16,20);
2760     int rb = bits(insn,11,15);
2761 dpavlin 9 int hreg_rb;
2762     jit_op_t *iop;
2763 dpavlin 7
2764 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"mullw");
2765     ppc32_jit_alloc_hreg_forced(cpu,X86_EAX);
2766     ppc32_jit_alloc_hreg_forced(cpu,X86_EDX);
2767     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2768 dpavlin 7
2769 dpavlin 9 ppc32_op_emit_load_gpr(cpu,X86_EAX,ra);
2770     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2771 dpavlin 7
2772 dpavlin 9 /* rd = lo(ra * rb) */
2773     iop = ppc32_op_emit_insn_output(cpu,2,"mullw");
2774     x86_mul_reg(iop->ob_ptr,hreg_rb,1);
2775    
2776     if (insn & 1)
2777     x86_test_reg_reg(iop->ob_ptr,X86_EAX,X86_EAX);
2778    
2779     ppc32_op_emit_store_gpr(cpu,rd,X86_EAX);
2780    
2781     if (insn & 1)
2782     ppc32_op_emit_update_flags(cpu,0,TRUE);
2783    
2784     /* edx:eax are directly modified: throw them */
2785     ppc32_op_emit_alter_host_reg(cpu,X86_EAX);
2786     ppc32_op_emit_alter_host_reg(cpu,X86_EDX);
2787    
2788     ppc32_jit_close_hreg_seq(cpu);
2789 dpavlin 7 return(0);
2790     }
2791    
2792     /* NAND */
2793     DECLARE_INSN(NAND)
2794     {
2795     int rs = bits(insn,21,25);
2796     int ra = bits(insn,16,20);
2797     int rb = bits(insn,11,15);
2798 dpavlin 9 int hreg_rs,hreg_ra,hreg_rb;
2799     jit_op_t *iop;
2800 dpavlin 7
2801     /* $ra = ~($rs & $rb) */
2802 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"nand");
2803     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2804     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2805     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2806 dpavlin 7
2807 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2808     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2809    
2810     iop = ppc32_op_emit_insn_output(cpu,2,"nand");
2811    
2812     if (ra == rs)
2813     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb);
2814     else if (ra == rb)
2815     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rs);
2816     else {
2817     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2818     x86_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb);
2819 dpavlin 7 }
2820    
2821 dpavlin 9 x86_not_reg(iop->ob_ptr,hreg_ra);
2822    
2823     if (insn & 1)
2824     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
2825    
2826     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2827    
2828     if (insn & 1)
2829     ppc32_op_emit_update_flags(cpu,0,TRUE);
2830    
2831     ppc32_jit_close_hreg_seq(cpu);
2832 dpavlin 7 return(0);
2833     }
2834    
2835     /* NEG */
2836     DECLARE_INSN(NEG)
2837     {
2838     int rd = bits(insn,21,25);
2839     int ra = bits(insn,16,20);
2840 dpavlin 9 int hreg_rd,hreg_ra;
2841     jit_op_t *iop;
2842 dpavlin 7
2843 dpavlin 9 /* $rd = neg($ra) */
2844     ppc32_jit_start_hreg_seq(cpu,"neg");
2845     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2846     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
2847 dpavlin 7
2848 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
2849 dpavlin 7
2850 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,1,"neg");
2851    
2852     if (rd != ra)
2853     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
2854    
2855     x86_neg_reg(iop->ob_ptr,hreg_rd);
2856    
2857     if (insn & 1)
2858     x86_test_reg_reg(iop->ob_ptr,hreg_rd,hreg_rd);
2859    
2860     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
2861    
2862     if (insn & 1)
2863     ppc32_op_emit_update_flags(cpu,0,TRUE);
2864    
2865     ppc32_jit_close_hreg_seq(cpu);
2866 dpavlin 7 return(0);
2867     }
2868    
2869     /* NOR */
2870     DECLARE_INSN(NOR)
2871     {
2872     int rs = bits(insn,21,25);
2873     int ra = bits(insn,16,20);
2874     int rb = bits(insn,11,15);
2875 dpavlin 9 int hreg_rs,hreg_ra,hreg_rb;
2876     jit_op_t *iop;
2877 dpavlin 7
2878     /* $ra = ~($rs | $rb) */
2879 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"nor");
2880     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2881     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2882     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2883 dpavlin 7
2884 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2885     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2886    
2887     iop = ppc32_op_emit_insn_output(cpu,2,"nor");
2888    
2889     if (ra == rs)
2890     x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb);
2891     else if (ra == rb)
2892     x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rs);
2893     else {
2894     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2895     x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb);
2896 dpavlin 7 }
2897    
2898 dpavlin 9 x86_not_reg(iop->ob_ptr,hreg_ra);
2899    
2900     if (insn & 1)
2901     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
2902    
2903     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2904    
2905     if (insn & 1)
2906     ppc32_op_emit_update_flags(cpu,0,TRUE);
2907    
2908     ppc32_jit_close_hreg_seq(cpu);
2909 dpavlin 7 return(0);
2910     }
2911    
2912     /* OR */
2913     DECLARE_INSN(OR)
2914     {
2915     int rs = bits(insn,21,25);
2916     int ra = bits(insn,16,20);
2917     int rb = bits(insn,11,15);
2918 dpavlin 9 int hreg_rs,hreg_ra,hreg_rb;
2919     jit_op_t *iop;
2920 dpavlin 7
2921 dpavlin 9 /* $ra = $rs | $rb */
2922     ppc32_jit_start_hreg_seq(cpu,"or");
2923     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2924     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2925     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2926 dpavlin 7
2927 dpavlin 9 /* special optimization for move/nop operation */
2928     if (rs == rb) {
2929     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2930     iop = ppc32_op_emit_insn_output(cpu,2,"or");
2931 dpavlin 7
2932 dpavlin 9 if (ra != rs)
2933     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2934 dpavlin 7
2935 dpavlin 9 if (insn & 1)
2936     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
2937    
2938     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2939    
2940     if (insn & 1)
2941     ppc32_op_emit_update_flags(cpu,0,TRUE);
2942    
2943     ppc32_jit_close_hreg_seq(cpu);
2944     return(0);
2945 dpavlin 7 }
2946    
2947 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2948     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2949    
2950     iop = ppc32_op_emit_insn_output(cpu,2,"or");
2951    
2952     if (ra == rs) {
2953     x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb);
2954     } else if (ra == rb)
2955     x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rs);
2956     else {
2957     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2958     x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb);
2959     }
2960    
2961     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2962    
2963     if (insn & 1)
2964     ppc32_op_emit_update_flags(cpu,0,TRUE);
2965    
2966     ppc32_jit_close_hreg_seq(cpu);
2967 dpavlin 7 return(0);
2968     }
2969    
2970     /* OR with Complement */
2971     DECLARE_INSN(ORC)
2972     {
2973     int rs = bits(insn,21,25);
2974     int ra = bits(insn,16,20);
2975     int rb = bits(insn,11,15);
2976 dpavlin 9 int hreg_rs,hreg_ra,hreg_rb,hreg_t0;
2977     jit_op_t *iop;
2978 dpavlin 7
2979 dpavlin 9 /* $ra = $rs & ~$rb */
2980     ppc32_jit_start_hreg_seq(cpu,"orc");
2981     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2982     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2983     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2984 dpavlin 7
2985 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2986     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2987    
2988     iop = ppc32_op_emit_insn_output(cpu,1,"orc");
2989    
2990     /* $t0 = ~$rb */
2991     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2992     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rb,4);
2993     x86_not_reg(iop->ob_ptr,hreg_t0);
2994    
2995     /* $ra = $rs | $t0 */
2996     if (ra == rs)
2997     x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_t0);
2998     else {
2999     x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,hreg_rs);
3000     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
3001     }
3002    
3003     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3004    
3005 dpavlin 7 if (insn & 1)
3006 dpavlin 9 ppc32_op_emit_update_flags(cpu,0,TRUE);
3007 dpavlin 7
3008 dpavlin 9 ppc32_jit_close_hreg_seq(cpu);
3009 dpavlin 7 return(0);
3010     }
3011    
3012     /* OR Immediate */
3013     DECLARE_INSN(ORI)
3014     {
3015     int rs = bits(insn,21,25);
3016     int ra = bits(insn,16,20);
3017     m_uint16_t imm = bits(insn,0,15);
3018 dpavlin 9 m_uint32_t tmp = imm;
3019     int hreg_rs,hreg_ra;
3020     jit_op_t *iop;
3021 dpavlin 7
3022     /* $ra = $rs | imm */
3023 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"ori");
3024     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3025     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3026    
3027     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3028    
3029     iop = ppc32_op_emit_insn_output(cpu,1,"ori");
3030    
3031     if (ra != rs)
3032     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3033    
3034     x86_alu_reg_imm(iop->ob_ptr,X86_OR,hreg_ra,tmp);
3035     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3036    
3037     ppc32_jit_close_hreg_seq(cpu);
3038 dpavlin 7 return(0);
3039     }
3040    
3041     /* OR Immediate Shifted */
3042     DECLARE_INSN(ORIS)
3043     {
3044     int rs = bits(insn,21,25);
3045     int ra = bits(insn,16,20);
3046 dpavlin 9 m_uint16_t imm = bits(insn,0,15);
3047     m_uint32_t tmp = imm << 16;
3048     int hreg_rs,hreg_ra;
3049     jit_op_t *iop;
3050 dpavlin 7
3051 dpavlin 9 /* $ra = $rs | imm */
3052     ppc32_jit_start_hreg_seq(cpu,"oris");
3053     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3054     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3055    
3056     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3057    
3058     iop = ppc32_op_emit_insn_output(cpu,1,"oris");
3059    
3060     if (ra != rs)
3061     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3062    
3063     x86_alu_reg_imm(iop->ob_ptr,X86_OR,hreg_ra,tmp);
3064     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3065    
3066     ppc32_jit_close_hreg_seq(cpu);
3067 dpavlin 7 return(0);
3068     }
3069    
3070     /* RLWIMI - Rotate Left Word Immediate then Mask Insert */
3071     DECLARE_INSN(RLWIMI)
3072     {
3073     int rs = bits(insn,21,25);
3074     int ra = bits(insn,16,20);
3075     int sh = bits(insn,11,15);
3076     int mb = bits(insn,6,10);
3077     int me = bits(insn,1,5);
3078     register m_uint32_t mask;
3079 dpavlin 9 int hreg_rs,hreg_ra,hreg_t0;
3080     jit_op_t *iop;
3081    
3082     ppc32_jit_start_hreg_seq(cpu,"rlwimi");
3083     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3084     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3085     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3086    
3087     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3088     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3089    
3090 dpavlin 7 mask = ppc32_rotate_mask(mb,me);
3091    
3092 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,2,"rlwimi");
3093    
3094     /* Apply inverse mask to $ra */
3095 dpavlin 7 if (mask != 0)
3096 dpavlin 9 x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,~mask);
3097 dpavlin 7
3098 dpavlin 9 /* Rotate $rs of "sh" bits and apply the mask */
3099     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
3100 dpavlin 7
3101     if (sh != 0)
3102 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_ROL,hreg_t0,sh);
3103 dpavlin 7
3104     if (mask != 0xFFFFFFFF)
3105 dpavlin 9 x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,mask);
3106 dpavlin 7
3107     /* Store the result */
3108 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_ra,hreg_t0);
3109     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3110 dpavlin 7
3111     if (insn & 1)
3112 dpavlin 9 ppc32_op_emit_update_flags(cpu,0,TRUE);
3113 dpavlin 7
3114 dpavlin 9 ppc32_jit_close_hreg_seq(cpu);
3115 dpavlin 7 return(0);
3116     }
3117    
3118     /* RLWINM - Rotate Left Word Immediate AND with Mask */
3119     DECLARE_INSN(RLWINM)
3120     {
3121     int rs = bits(insn,21,25);
3122     int ra = bits(insn,16,20);
3123     int sh = bits(insn,11,15);
3124     int mb = bits(insn,6,10);
3125     int me = bits(insn,1,5);
3126     register m_uint32_t mask;
3127 dpavlin 9 int hreg_rs,hreg_ra;
3128     jit_op_t *iop;
3129 dpavlin 7
3130 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"rlwinm");
3131     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3132     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3133    
3134     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3135    
3136     iop = ppc32_op_emit_insn_output(cpu,2,"rlwinm");
3137    
3138     /* Rotate $rs of "sh" bits and apply the mask */
3139 dpavlin 7 mask = ppc32_rotate_mask(mb,me);
3140    
3141 dpavlin 9 if (rs != ra)
3142     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3143 dpavlin 7
3144     if (sh != 0)
3145 dpavlin 9 x86_shift_reg_imm(iop->ob_ptr,X86_ROL,hreg_ra,sh);
3146 dpavlin 7
3147     if (mask != 0xFFFFFFFF)
3148 dpavlin 9 x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,mask);
3149 dpavlin 7
3150 dpavlin 9 if (insn & 1)
3151     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
3152 dpavlin 7
3153 dpavlin 9 ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3154 dpavlin 7
3155 dpavlin 9 if (insn & 1)
3156     ppc32_op_emit_update_flags(cpu,0,TRUE);
3157    
3158     ppc32_jit_close_hreg_seq(cpu);
3159 dpavlin 7 return(0);
3160     }
3161    
3162     /* RLWNM - Rotate Left Word then Mask Insert */
3163     DECLARE_INSN(RLWNM)
3164     {
3165     int rs = bits(insn,21,25);
3166     int ra = bits(insn,16,20);
3167     int rb = bits(insn,11,15);
3168     int mb = bits(insn,6,10);
3169     int me = bits(insn,1,5);
3170     register m_uint32_t mask;
3171 dpavlin 9 int hreg_rs,hreg_ra,hreg_t0;
3172     jit_op_t *iop;
3173 dpavlin 7
3174 dpavlin 9 /* ecx is directly modified: throw it */
3175     ppc32_op_emit_alter_host_reg(cpu,X86_ECX);
3176 dpavlin 7
3177 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"rlwnm");
3178     ppc32_jit_alloc_hreg_forced(cpu,X86_ECX);
3179    
3180     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3181     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3182     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3183    
3184     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3185     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3186     ppc32_op_emit_load_gpr(cpu,X86_ECX,rb);
3187    
3188     iop = ppc32_op_emit_insn_output(cpu,2,"rlwnm");
3189    
3190 dpavlin 7 /* Load the shift register ("sh") */
3191 dpavlin 9 mask = ppc32_rotate_mask(mb,me);
3192 dpavlin 7
3193 dpavlin 9 /* Rotate $rs and apply the mask */
3194     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
3195 dpavlin 7
3196 dpavlin 9 x86_shift_reg(iop->ob_ptr,X86_ROL,hreg_t0);
3197    
3198 dpavlin 7 if (mask != 0xFFFFFFFF)
3199 dpavlin 9 x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,mask);
3200 dpavlin 7
3201 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
3202 dpavlin 7
3203 dpavlin 9 if (insn & 1)
3204     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
3205 dpavlin 7
3206 dpavlin 9 ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3207    
3208     if (insn & 1)
3209     ppc32_op_emit_update_flags(cpu,0,TRUE);
3210    
3211     ppc32_jit_close_hreg_seq(cpu);
3212 dpavlin 7 return(0);
3213     }
3214    
3215     /* Shift Left Word */
3216     DECLARE_INSN(SLW)
3217     {
3218     int rs = bits(insn,21,25);
3219     int ra = bits(insn,16,20);
3220     int rb = bits(insn,11,15);
3221     u_char *test1;
3222 dpavlin 9 int hreg_rs,hreg_ra,hreg_t0;
3223     jit_op_t *iop;
3224 dpavlin 7
3225 dpavlin 9 /* ecx is directly modified: throw it */
3226     ppc32_op_emit_alter_host_reg(cpu,X86_ECX);
3227 dpavlin 7
3228 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"slw");
3229     ppc32_jit_alloc_hreg_forced(cpu,X86_ECX);
3230     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3231     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3232     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3233 dpavlin 7
3234 dpavlin 9 /* $ra = $rs << $rb. If count >= 32, then null result */
3235     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3236     ppc32_op_emit_load_gpr(cpu,X86_ECX,rb);
3237 dpavlin 7
3238 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,3,"slw");
3239 dpavlin 7
3240 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,hreg_t0);
3241     x86_test_reg_imm(iop->ob_ptr,X86_ECX,0x20);
3242     test1 = iop->ob_ptr;
3243     x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
3244 dpavlin 7
3245 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
3246     x86_shift_reg(iop->ob_ptr,X86_SHL,hreg_t0);
3247    
3248     /* store the result */
3249     x86_patch(test1,iop->ob_ptr);
3250     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
3251    
3252     if (insn & 1)
3253     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
3254    
3255     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3256    
3257     if (insn & 1)
3258     ppc32_op_emit_update_flags(cpu,0,TRUE);
3259    
3260     ppc32_jit_close_hreg_seq(cpu);
3261 dpavlin 7 return(0);
3262     }
3263    
3264     /* SRAWI - Shift Right Algebraic Word Immediate */
3265     DECLARE_INSN(SRAWI)
3266     {
3267     int rs = bits(insn,21,25);
3268     int ra = bits(insn,16,20);
3269     int sh = bits(insn,11,15);
3270     register m_uint32_t mask;
3271 dpavlin 9 int hreg_rs,hreg_ra,hreg_t0;
3272     jit_op_t *iop;
3273 dpavlin 7
3274 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"srawi");
3275     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3276     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3277     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3278 dpavlin 7
3279     /* $ra = (int32)$rs >> sh */
3280 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3281 dpavlin 7
3282 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,3,"srawi");
3283     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
3284    
3285     if (ra != rs)
3286     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3287     x86_shift_reg_imm(iop->ob_ptr,X86_SAR,hreg_ra,sh);
3288 dpavlin 7
3289 dpavlin 9 /* set XER_CA depending on the result */
3290     mask = ~(0xFFFFFFFFU << sh) | 0x80000000;
3291    
3292     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,mask);
3293     x86_alu_reg_imm(iop->ob_ptr,X86_CMP,hreg_t0,0x80000000);
3294     x86_set_reg(iop->ob_ptr,X86_CC_A,hreg_t0,FALSE);
3295     x86_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x1);
3296     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t0,4);
3297    
3298     if (insn & 1)
3299     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
3300    
3301     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3302 dpavlin 7
3303 dpavlin 9 if (insn & 1)
3304     ppc32_op_emit_update_flags(cpu,0,TRUE);
3305 dpavlin 7
3306 dpavlin 9 ppc32_jit_close_hreg_seq(cpu);
3307 dpavlin 7 return(0);
3308     }
3309    
3310     /* Shift Right Word */
3311     DECLARE_INSN(SRW)
3312     {
3313     int rs = bits(insn,21,25);
3314     int ra = bits(insn,16,20);
3315     int rb = bits(insn,11,15);
3316     u_char *test1;
3317 dpavlin 9 int hreg_rs,hreg_ra,hreg_t0;
3318     jit_op_t *iop;
3319 dpavlin 7
3320 dpavlin 9 /* ecx is directly modified: throw it */
3321     ppc32_op_emit_alter_host_reg(cpu,X86_ECX);
3322 dpavlin 7
3323 dpavlin 9 ppc32_jit_start_hreg_seq(cpu,"srw");
3324     ppc32_jit_alloc_hreg_forced(cpu,X86_ECX);
3325     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3326     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3327     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3328 dpavlin 7
3329 dpavlin 9 /* $ra = $rs >> $rb. If count >= 32, then null result */
3330     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3331     ppc32_op_emit_load_gpr(cpu,X86_ECX,rb);
3332 dpavlin 7
3333 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,3,"srw");
3334 dpavlin 7
3335 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,hreg_t0);
3336     x86_test_reg_imm(iop->ob_ptr,X86_ECX,0x20);
3337     test1 = iop->ob_ptr;
3338     x86_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
3339    
3340     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
3341     x86_shift_reg(iop->ob_ptr,X86_SHR,hreg_t0);
3342    
3343     /* store the result */
3344     x86_patch(test1,iop->ob_ptr);
3345     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
3346    
3347     if (insn & 1)
3348     x86_test_reg_reg(iop->ob_ptr,hreg_ra,hreg_ra);
3349    
3350     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3351    
3352     if (insn & 1)
3353     ppc32_op_emit_update_flags(cpu,0,TRUE);
3354    
3355     ppc32_jit_close_hreg_seq(cpu);
3356 dpavlin 7 return(0);
3357     }
3358    
3359     /* STB - Store Byte */
3360     DECLARE_INSN(STB)
3361     {
3362     int rs = bits(insn,21,25);
3363     int ra = bits(insn,16,20);
3364     m_uint16_t offset = bits(insn,0,15);
3365    
3366     //ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,0);
3367 dpavlin 9 ppc32_emit_memop_fast(cpu,b,1,PPC_MEMOP_STB,ra,offset,rs,
3368     ppc32_memop_fast_stb);
3369 dpavlin 7 return(0);
3370     }
3371    
3372     /* STBU - Store Byte with Update */
3373     DECLARE_INSN(STBU)
3374     {
3375     int rs = bits(insn,21,25);
3376     int ra = bits(insn,16,20);
3377     m_uint16_t offset = bits(insn,0,15);
3378    
3379 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_STB,ra,offset,rs,1);
3380 dpavlin 7 return(0);
3381     }
3382    
3383     /* STBUX - Store Byte with Update Indexed */
3384     DECLARE_INSN(STBUX)
3385     {
3386     int rs = bits(insn,21,25);
3387     int ra = bits(insn,16,20);
3388     int rb = bits(insn,11,15);
3389    
3390 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STB,ra,rb,rs,1);
3391 dpavlin 7 return(0);
3392     }
3393    
3394     /* STBUX - Store Byte Indexed */
3395     DECLARE_INSN(STBX)
3396     {
3397     int rs = bits(insn,21,25);
3398     int ra = bits(insn,16,20);
3399     int rb = bits(insn,11,15);
3400    
3401 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STB,ra,rb,rs,0);
3402 dpavlin 7 return(0);
3403     }
3404    
3405     /* STH - Store Half-Word */
3406     DECLARE_INSN(STH)
3407     {
3408     int rs = bits(insn,21,25);
3409     int ra = bits(insn,16,20);
3410     m_uint16_t offset = bits(insn,0,15);
3411    
3412 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_STH,ra,offset,rs,0);
3413 dpavlin 7 return(0);
3414     }
3415    
3416     /* STHU - Store Half-Word with Update */
3417     DECLARE_INSN(STHU)
3418     {
3419     int rs = bits(insn,21,25);
3420     int ra = bits(insn,16,20);
3421     m_uint16_t offset = bits(insn,0,15);
3422    
3423 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_STH,ra,offset,rs,1);
3424 dpavlin 7 return(0);
3425     }
3426    
3427     /* STHUX - Store Half-Word with Update Indexed */
3428     DECLARE_INSN(STHUX)
3429     {
3430     int rs = bits(insn,21,25);
3431     int ra = bits(insn,16,20);
3432     int rb = bits(insn,11,15);
3433    
3434 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STH,ra,rb,rs,1);
3435 dpavlin 7 return(0);
3436     }
3437    
3438     /* STHUX - Store Half-Word Indexed */
3439     DECLARE_INSN(STHX)
3440     {
3441     int rs = bits(insn,21,25);
3442     int ra = bits(insn,16,20);
3443     int rb = bits(insn,11,15);
3444    
3445 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STH,ra,rb,rs,0);
3446 dpavlin 7 return(0);
3447     }
3448    
3449     /* STW - Store Word */
3450     DECLARE_INSN(STW)
3451     {
3452     int rs = bits(insn,21,25);
3453     int ra = bits(insn,16,20);
3454     m_uint16_t offset = bits(insn,0,15);
3455    
3456     //ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,0);
3457 dpavlin 9 ppc32_emit_memop_fast(cpu,b,1,PPC_MEMOP_STW,ra,offset,rs,
3458     ppc32_memop_fast_stw);
3459 dpavlin 7 return(0);
3460     }
3461    
3462     /* STWU - Store Word with Update */
3463     DECLARE_INSN(STWU)
3464     {
3465     int rs = bits(insn,21,25);
3466     int ra = bits(insn,16,20);
3467     m_uint16_t offset = bits(insn,0,15);
3468    
3469 dpavlin 9 ppc32_emit_memop(cpu,b,PPC_MEMOP_STW,ra,offset,rs,1);
3470 dpavlin 7 return(0);
3471     }
3472    
3473     /* STWUX - Store Word with Update Indexed */
3474     DECLARE_INSN(STWUX)
3475     {
3476     int rs = bits(insn,21,25);
3477     int ra = bits(insn,16,20);
3478     int rb = bits(insn,11,15);
3479    
3480 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STW,ra,rb,rs,1);
3481 dpavlin 7 return(0);
3482     }
3483    
3484     /* STWUX - Store Word Indexed */
3485     DECLARE_INSN(STWX)
3486     {
3487     int rs = bits(insn,21,25);
3488     int ra = bits(insn,16,20);
3489     int rb = bits(insn,11,15);
3490    
3491 dpavlin 9 ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STW,ra,rb,rs,0);
3492 dpavlin 7 return(0);
3493     }
3494    
3495     /* SUBF - Subtract From */
3496     DECLARE_INSN(SUBF)
3497     {
3498     int rd = bits(insn,21,25);
3499     int ra = bits(insn,16,20);
3500     int rb = bits(insn,11,15);
3501 dpavlin 9 int hreg_rd,hreg_ra,hreg_rb,hreg_t0;
3502     jit_op_t *iop;
3503 dpavlin 7
3504 dpavlin 9 /* $rd = $rb - $ra */
3505     ppc32_jit_start_hreg_seq(cpu,"subf");
3506     hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3507 dpavlin 7
3508 dpavlin 9 hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
3509     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3510     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
3511    
3512     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3513     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
3514    
3515     iop = ppc32_op_emit_insn_output(cpu,2,"subf");
3516    
3517     if (rd == rb)
3518     x86_alu_reg_reg(iop->ob_ptr,X86_SUB,hreg_rd,hreg_ra);
3519     else if (rd == ra) {
3520     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rb,4);
3521     x86_alu_reg_reg(iop->ob_ptr,X86_SUB,hreg_t0,hreg_ra);
3522     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
3523     } else {
3524     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_rb,4);
3525     x86_alu_reg_reg(iop->ob_ptr,X86_SUB,hreg_rd,hreg_ra);
3526     }
3527    
3528     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
3529    
3530 dpavlin 7 if (insn & 1)
3531 dpavlin 9 ppc32_op_emit_update_flags(cpu,0,TRUE);
3532    
3533     ppc32_jit_close_hreg_seq(cpu);
3534 dpavlin 7 return(0);
3535     }
3536    
3537     /* SUBFC - Subtract From Carrying */
3538     DECLARE_INSN(SUBFC)
3539     {
3540     int rd = bits(insn,21,25);
3541     int ra = bits(insn,16,20);
3542     int rb = bits(insn,11,15);
3543 dpavlin 9 int hreg_ra,hreg_rb,hreg_rd,hreg_t0,hreg_t1;
3544     jit_op_t *iop;
3545 dpavlin 7
3546 dpavlin 9 /* $rd = ~$ra + 1 + $rb */
3547     ppc32_jit_start_hreg_seq(cpu,"subfc");
3548     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3549     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
3550     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
3551 dpavlin 7
3552 dpavlin 9 hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
3553     hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
3554 dpavlin 7
3555 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
3556     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3557     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
3558 dpavlin 7
3559 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,3,"subfc");
3560 dpavlin 7
3561 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
3562 dpavlin 7
3563 dpavlin 9 /* $t0 = ~$ra + 1 */
3564     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
3565     x86_not_reg(iop->ob_ptr,hreg_t0);
3566     x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_t0,1);
3567     x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3568     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t1,4);
3569    
3570     /* $t0 += $rb */
3571     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_t0,hreg_rb);
3572     x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3573     x86_alu_membase_reg(iop->ob_ptr,X86_OR,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
3574     hreg_t1);
3575    
3576     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
3577    
3578     if (insn & 1)
3579     x86_test_reg_reg(iop->ob_ptr,hreg_rd,hreg_rd);
3580    
3581     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
3582    
3583 dpavlin 7 /* update cr0 */
3584 dpavlin 9 if (insn & 1)
3585 dpavlin 7 ppc32_update_cr0(b);
3586    
3587 dpavlin 9 ppc32_jit_close_hreg_seq(cpu);
3588 dpavlin 7 return(0);
3589     }
3590    
3591     /* SUBFE - Subtract From Extended */
3592     DECLARE_INSN(SUBFE)
3593     {
3594     int rd = bits(insn,21,25);
3595     int ra = bits(insn,16,20);
3596     int rb = bits(insn,11,15);
3597 dpavlin 9 int hreg_ra,hreg_rb,hreg_rd,hreg_t0,hreg_t1;
3598     jit_op_t *iop;
3599 dpavlin 7
3600 dpavlin 9 /* $rd = ~$ra + $carry (xer_ca) + $rb */
3601     ppc32_jit_start_hreg_seq(cpu,"subfe");
3602     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3603     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
3604     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
3605    
3606     hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
3607     hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
3608    
3609     ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
3610     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3611     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
3612    
3613     iop = ppc32_op_emit_insn_output(cpu,3,"subfe");
3614    
3615     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
3616    
3617     /* $t0 = ~$ra + $carry */
3618     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
3619     x86_not_reg(iop->ob_ptr,hreg_t0);
3620     x86_alu_reg_membase(iop->ob_ptr,X86_ADD,hreg_t0,
3621 dpavlin 7 X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
3622    
3623 dpavlin 9 x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3624     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t1,4);
3625 dpavlin 7
3626 dpavlin 9 /* $t0 += $rb */
3627     x86_alu_reg_reg(iop->ob_ptr,X86_ADD,hreg_t0,hreg_rb);
3628     x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3629     x86_alu_membase_reg(iop->ob_ptr,X86_OR,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
3630     hreg_t1);
3631 dpavlin 7
3632 dpavlin 9 x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
3633 dpavlin 7
3634 dpavlin 9 if (insn & 1)
3635     x86_test_reg_reg(iop->ob_ptr,hreg_rd,hreg_rd);
3636    
3637     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
3638    
3639 dpavlin 7 /* update cr0 */
3640 dpavlin 9 if (insn & 1)
3641 dpavlin 7 ppc32_update_cr0(b);
3642    
3643 dpavlin 9 ppc32_jit_close_hreg_seq(cpu);
3644 dpavlin 7 return(0);
3645     }
3646    
3647     /* SUBFIC - Subtract From Immediate Carrying */
3648     DECLARE_INSN(SUBFIC)
3649     {
3650     int rd = bits(insn,21,25);
3651     int ra = bits(insn,16,20);
3652     m_uint16_t imm = bits(insn,0,15);
3653     m_uint32_t tmp = sign_extend_32(imm,16);
3654 dpavlin 9 int hreg_ra,hreg_rd,hreg_t0,hreg_t1;
3655     jit_op_t *iop;
3656 dpavlin 7
3657 dpavlin 9 /* $rd = ~$ra + 1 + sign_extend(imm,16) */
3658     ppc32_jit_start_hreg_seq(cpu,"subfic");
3659     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3660     hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
3661 dpavlin 7
3662 dpavlin 9 hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
3663     hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
3664 dpavlin 7
3665 dpavlin 9 ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
3666     ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3667 dpavlin 7
3668 dpavlin 9 iop = ppc32_op_emit_insn_output(cpu,3,"subfic");
3669 dpavlin 7
3670 dpavlin 9 x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
3671    
3672     /* $t0 = ~$ra + 1 */
3673     x86_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
3674     x86_not_reg(iop->ob_ptr,hreg_t0);
3675     x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_t0,1);
3676    
3677     x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3678     x86_mov_membase_reg(iop->ob_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),hreg_t1,4);
3679    
3680     /* $t0 += sign_extend(imm,16) */
3681     x86_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_t0,tmp);
3682     x86_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3683     x86_alu_membase_reg(iop->ob_ptr,X86_OR,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),
3684     hreg_t1);
3685    
3686     x86_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
3687     ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
3688    
3689     ppc32_jit_close_hreg_seq(cpu);
3690 dpavlin 7 return(0);
3691     }
3692    
3693     /* SYNC - Synchronize */
3694     DECLARE_INSN(SYNC)
3695     {
3696     return(0);
3697     }
3698    
3699     /* XOR */
3700     DECLARE_INSN(XOR)
3701     {
3702     int rs = bits(insn,21,25);
3703     int ra = bits(insn,16,20);
3704     int rb = bits(insn,11,15);
3705 dpavlin 9 int hreg_rs,hreg_ra,hreg_rb;
3706     jit_op_t *iop;
3707 dpavlin 7
3708 dpavlin 9 /* $ra = $rs ^ $rb */
3709     ppc32_jit_start_hreg_seq(cpu,"xor");
3710     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3711     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3712     hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
3713 dpavlin 7
3714 dpavlin 9 ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3715     ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
3716    
3717     iop = ppc32_op_emit_insn_output(cpu,1,"xor");
3718    
3719     if (ra == rs)
3720     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb);
3721     else if (ra == rb)
3722     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rs);
3723     else {
3724     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3725     x86_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb);
3726     }
3727    
3728     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3729    
3730 dpavlin 7 if (insn & 1)
3731 dpavlin 9 ppc32_op_emit_update_flags(cpu,0,TRUE);
3732 dpavlin 7
3733 dpavlin 9 ppc32_jit_close_hreg_seq(cpu);
3734 dpavlin 7 return(0);
3735     }
3736    
3737     /* XORI - XOR Immediate */
3738     DECLARE_INSN(XORI)
3739     {
3740     int rs = bits(insn,21,25);
3741     int ra = bits(insn,16,20);
3742     m_uint32_t imm = bits(insn,0,15);
3743 dpavlin 9 int hreg_rs,hreg_ra;
3744     jit_op_t *iop;
3745 dpavlin 7
3746 dpavlin 9 /* $ra = $rs ^ imm */
3747     ppc32_jit_start_hreg_seq(cpu,"xori");
3748     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3749     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3750    
3751     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3752    
3753     iop = ppc32_op_emit_insn_output(cpu,1,"xori");
3754    
3755     if (ra != rs)
3756     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3757    
3758     x86_alu_reg_imm(iop->ob_ptr,X86_XOR,hreg_ra,imm);
3759     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3760    
3761     ppc32_jit_close_hreg_seq(cpu);
3762 dpavlin 7 return(0);
3763     }
3764    
3765     /* XORIS - XOR Immediate Shifted */
3766     DECLARE_INSN(XORIS)
3767     {
3768     int rs = bits(insn,21,25);
3769     int ra = bits(insn,16,20);
3770 dpavlin 9 m_uint16_t imm = bits(insn,0,15);
3771     m_uint32_t tmp = imm << 16;
3772     int hreg_rs,hreg_ra;
3773     jit_op_t *iop;
3774 dpavlin 7
3775 dpavlin 9 /* $ra = $rs ^ (imm << 16) */
3776     ppc32_jit_start_hreg_seq(cpu,"xoris");
3777     hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3778     hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3779    
3780     ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3781    
3782     iop = ppc32_op_emit_insn_output(cpu,1,"xoris");
3783    
3784     if (ra != rs)
3785     x86_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3786    
3787     x86_alu_reg_imm(iop->ob_ptr,X86_XOR,hreg_ra,tmp);
3788     ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3789    
3790     ppc32_jit_close_hreg_seq(cpu);
3791 dpavlin 7 return(0);
3792     }
3793    
3794     /* PPC instruction array */
3795     struct ppc32_insn_tag ppc32_insn_tags[] = {
3796     { ppc32_emit_BLR , 0xfffffffe , 0x4e800020 },
3797     { ppc32_emit_BCTR , 0xfffffffe , 0x4e800420 },
3798     { ppc32_emit_MFLR , 0xfc1fffff , 0x7c0802a6 },
3799     { ppc32_emit_MTLR , 0xfc1fffff , 0x7c0803a6 },
3800     { ppc32_emit_MFCTR , 0xfc1fffff , 0x7c0902a6 },
3801     { ppc32_emit_MTCTR , 0xfc1fffff , 0x7c0903a6 },
3802     { ppc32_emit_MFTBL , 0xfc1ff7ff , 0x7c0c42e6 },
3803     { ppc32_emit_MFTBU , 0xfc1ff7ff , 0x7c0d42e6 },
3804     { ppc32_emit_ADD , 0xfc0007fe , 0x7c000214 },
3805     { ppc32_emit_ADDC , 0xfc0007fe , 0x7c000014 },
3806     { ppc32_emit_ADDE , 0xfc0007fe , 0x7c000114 },
3807     { ppc32_emit_ADDI , 0xfc000000 , 0x38000000 },
3808     { ppc32_emit_ADDIC , 0xfc000000 , 0x30000000 },
3809     { ppc32_emit_ADDIC_dot , 0xfc000000 , 0x34000000 },
3810     { ppc32_emit_ADDIS , 0xfc000000 , 0x3c000000 },
3811 dpavlin 9 { ppc32_emit_ADDZE , 0xfc00fffe , 0x7c000194 },
3812 dpavlin 7 { ppc32_emit_AND , 0xfc0007fe , 0x7c000038 },
3813     { ppc32_emit_ANDC , 0xfc0007fe , 0x7c000078 },
3814     { ppc32_emit_ANDI , 0xfc000000 , 0x70000000 },
3815     { ppc32_emit_ANDIS , 0xfc000000 , 0x74000000 },
3816     { ppc32_emit_B , 0xfc000003 , 0x48000000 },
3817     { ppc32_emit_BA , 0xfc000003 , 0x48000002 },
3818     { ppc32_emit_BL , 0xfc000003 , 0x48000001 },
3819     { ppc32_emit_BLA , 0xfc000003 , 0x48000003 },
3820     { ppc32_emit_BCC , 0xfe800000 , 0x40800000 },
3821     { ppc32_emit_BC , 0xfc000000 , 0x40000000 },
3822 dpavlin 11 { ppc32_emit_BCLR , 0xfc00fffe , 0x4c000020 },
3823 dpavlin 7 { ppc32_emit_CMP , 0xfc6007ff , 0x7c000000 },
3824     { ppc32_emit_CMPI , 0xfc600000 , 0x2c000000 },
3825     { ppc32_emit_CMPL , 0xfc6007ff , 0x7c000040 },
3826     { ppc32_emit_CMPLI , 0xfc600000 , 0x28000000 },
3827     { ppc32_emit_CRAND , 0xfc0007ff , 0x4c000202 },
3828     { ppc32_emit_CRANDC , 0xfc0007ff , 0x4c000102 },
3829     { ppc32_emit_CREQV , 0xfc0007ff , 0x4c000242 },
3830     { ppc32_emit_CRNAND , 0xfc0007ff , 0x4c0001c2 },
3831     { ppc32_emit_CRNOR , 0xfc0007ff , 0x4c000042 },
3832     { ppc32_emit_CROR , 0xfc0007ff , 0x4c000382 },
3833     { ppc32_emit_CRORC , 0xfc0007ff , 0x4c000342 },
3834     { ppc32_emit_CRXOR , 0xfc0007ff , 0x4c000182 },
3835     { ppc32_emit_DIVWU , 0xfc0007fe , 0x7c000396 },
3836     { ppc32_emit_EQV , 0xfc0007fe , 0x7c000238 },
3837     { ppc32_emit_EXTSB , 0xfc00fffe , 0x7c000774 },
3838     { ppc32_emit_EXTSH , 0xfc00fffe , 0x7c000734 },
3839     { ppc32_emit_LBZ , 0xfc000000 , 0x88000000 },
3840     { ppc32_emit_LBZU , 0xfc000000 , 0x8c000000 },
3841     { ppc32_emit_LBZUX , 0xfc0007ff , 0x7c0000ee },
3842     { ppc32_emit_LBZX , 0xfc0007ff , 0x7c0000ae },
3843     { ppc32_emit_LHA , 0xfc000000 , 0xa8000000 },
3844     { ppc32_emit_LHAU , 0xfc000000 , 0xac000000 },
3845     { ppc32_emit_LHAUX , 0xfc0007ff , 0x7c0002ee },
3846     { ppc32_emit_LHAX , 0xfc0007ff , 0x7c0002ae },
3847     { ppc32_emit_LHZ , 0xfc000000 , 0xa0000000 },
3848     { ppc32_emit_LHZU , 0xfc000000 , 0xa4000000 },
3849     { ppc32_emit_LHZUX , 0xfc0007ff , 0x7c00026e },
3850     { ppc32_emit_LHZX , 0xfc0007ff , 0x7c00022e },
3851     { ppc32_emit_LWZ , 0xfc000000 , 0x80000000 },
3852     { ppc32_emit_LWZU , 0xfc000000 , 0x84000000 },
3853     { ppc32_emit_LWZUX , 0xfc0007ff , 0x7c00006e },
3854     { ppc32_emit_LWZX , 0xfc0007ff , 0x7c00002e },
3855     { ppc32_emit_MCRF , 0xfc63ffff , 0x4c000000 },
3856     { ppc32_emit_MFCR , 0xfc1fffff , 0x7c000026 },
3857     { ppc32_emit_MFMSR , 0xfc1fffff , 0x7c0000a6 },
3858     { ppc32_emit_MFSR , 0xfc10ffff , 0x7c0004a6 },
3859     { ppc32_emit_MTCRF , 0xfc100fff , 0x7c000120 },
3860     { ppc32_emit_MULHW , 0xfc0007fe , 0x7c000096 },
3861     { ppc32_emit_MULHWU , 0xfc0007fe , 0x7c000016 },
3862     { ppc32_emit_MULLI , 0xfc000000 , 0x1c000000 },
3863     { ppc32_emit_MULLW , 0xfc0007fe , 0x7c0001d6 },
3864     { ppc32_emit_NAND , 0xfc0007fe , 0x7c0003b8 },
3865     { ppc32_emit_NEG , 0xfc00fffe , 0x7c0000d0 },
3866     { ppc32_emit_NOR , 0xfc0007fe , 0x7c0000f8 },
3867     { ppc32_emit_OR , 0xfc0007fe , 0x7c000378 },
3868     { ppc32_emit_ORC , 0xfc0007fe , 0x7c000338 },
3869     { ppc32_emit_ORI , 0xfc000000 , 0x60000000 },
3870     { ppc32_emit_ORIS , 0xfc000000 , 0x64000000 },
3871     { ppc32_emit_RLWIMI , 0xfc000000 , 0x50000000 },
3872     { ppc32_emit_RLWINM , 0xfc000000 , 0x54000000 },
3873     { ppc32_emit_RLWNM , 0xfc000000 , 0x5c000000 },
3874     { ppc32_emit_SLW , 0xfc0007fe , 0x7c000030 },
3875     { ppc32_emit_SRAWI , 0xfc0007fe , 0x7c000670 },
3876     { ppc32_emit_SRW , 0xfc0007fe , 0x7c000430 },
3877     { ppc32_emit_STB , 0xfc000000 , 0x98000000 },
3878     { ppc32_emit_STBU , 0xfc000000 , 0x9c000000 },
3879     { ppc32_emit_STBUX , 0xfc0007ff , 0x7c0001ee },
3880     { ppc32_emit_STBX , 0xfc0007ff , 0x7c0001ae },
3881     { ppc32_emit_STH , 0xfc000000 , 0xb0000000 },
3882     { ppc32_emit_STHU , 0xfc000000 , 0xb4000000 },
3883     { ppc32_emit_STHUX , 0xfc0007ff , 0x7c00036e },
3884     { ppc32_emit_STHX , 0xfc0007ff , 0x7c00032e },
3885     { ppc32_emit_STW , 0xfc000000 , 0x90000000 },
3886     { ppc32_emit_STWU , 0xfc000000 , 0x94000000 },
3887     { ppc32_emit_STWUX , 0xfc0007ff , 0x7c00016e },
3888     { ppc32_emit_STWX , 0xfc0007ff , 0x7c00012e },
3889     { ppc32_emit_SUBF , 0xfc0007fe , 0x7c000050 },
3890     { ppc32_emit_SUBFC , 0xfc0007fe , 0x7c000010 },
3891     { ppc32_emit_SUBFE , 0xfc0007fe , 0x7c000110 },
3892     { ppc32_emit_SUBFIC , 0xfc000000 , 0x20000000 },
3893     { ppc32_emit_SYNC , 0xffffffff , 0x7c0004ac },
3894     { ppc32_emit_XOR , 0xfc0007fe , 0x7c000278 },
3895     { ppc32_emit_XORI , 0xfc000000 , 0x68000000 },
3896     { ppc32_emit_XORIS , 0xfc000000 , 0x6c000000 },
3897     { ppc32_emit_unknown , 0x00000000 , 0x00000000 },
3898 dpavlin 8 { NULL , 0x00000000 , 0x00000000 },
3899 dpavlin 7 };

  ViewVC Help
Powered by ViewVC 1.1.26