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

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

  ViewVC Help
Powered by ViewVC 1.1.26