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