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

Annotation of /trunk/ppc32_amd64_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26