1 /*
2  * Cisco router simulation platform.
3  * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)
4  *
5  * JIT engine for 32-bit PowerPC architecture
6  * Copyright (c) 2006, 2007 Zhe Fang (fangzhe@msn.com)
7  */
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 
17 #include "cpu.h"
18 #include "mips64_jit.h"
19 #include "mips64_ppc32_trans.h"
20 #include "mips64_cp0.h"
21 #include "memory.h"
22 
23 /* Macros for CPU structure access */
24 #define REG_OFFSET(reg)       (OFFSET(cpu_mips_t,gpr[(reg)]))
25 #define CP0_REG_OFFSET(c0reg) (OFFSET(cpu_mips_t,cp0.reg[(c0reg)]))
26 #define MEMOP_OFFSET(op)      (OFFSET(cpu_mips_t,mem_op_fn[(op)]))
27 
28 #define DECLARE_INSN(name) \
29    static int mips64_emit_##name(cpu_mips_t *cpu,mips64_jit_tcb_t *b, \
30                                  mips_insn_t insn)
31 
32 /* Set an IRQ */
mips64_set_irq(cpu_mips_t * cpu,m_uint8_t irq)33 void mips64_set_irq(cpu_mips_t *cpu,m_uint8_t irq)
34 {
35    m_uint32_t m;
36    m = (1 << (irq + MIPS_CP0_CAUSE_ISHIFT)) & MIPS_CP0_CAUSE_IMASK;
37    atomic_or(&cpu->irq_cause,m);
38 }
39 
40 /* Clear an IRQ */
mips64_clear_irq(cpu_mips_t * cpu,m_uint8_t irq)41 void mips64_clear_irq(cpu_mips_t *cpu,m_uint8_t irq)
42 {
43    m_uint32_t m;
44    m = (1 << (irq + MIPS_CP0_CAUSE_ISHIFT)) & MIPS_CP0_CAUSE_IMASK;
45    atomic_and(&cpu->irq_cause,~m);
46 
47    if (!cpu->irq_cause)
48       cpu->irq_pending = 0;
49 }
50 
51 /* Set the Pointer Counter (PC) register */
mips64_set_pc(mips64_jit_tcb_t * b,m_uint64_t new_pc)52 void mips64_set_pc(mips64_jit_tcb_t *b,m_uint64_t new_pc)
53 {
54    ppc_load(b->jit_ptr,ppc_r0,new_pc >> 32);
55    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,pc),ppc_r3);
56    ppc_load(b->jit_ptr,ppc_r0,new_pc & 0xffffffff);
57    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,pc)+4,ppc_r3);
58 }
59 
60 /* Set the Return Address (RA) register */
mips64_set_ra(mips64_jit_tcb_t * b,m_uint64_t ret_pc)61 void mips64_set_ra(mips64_jit_tcb_t *b,m_uint64_t ret_pc)
62 {
63    ppc_load(b->jit_ptr,ppc_r0,ret_pc >> 32);
64    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(MIPS_GPR_RA),ppc_r3);
65    ppc_load(b->jit_ptr,ppc_r0,ret_pc & 0xffffffff);
66    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(MIPS_GPR_RA)+4,ppc_r3);
67 }
68 
69 /*
70  * Try to branch directly to the specified JIT block without returning to
71  * main loop.
72  */
mips64_try_direct_far_jump(cpu_mips_t * cpu,mips64_jit_tcb_t * b,m_uint64_t new_pc)73 static void mips64_try_direct_far_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
74                                        m_uint64_t new_pc)
75 {
76    m_uint64_t new_page;
77    m_uint32_t pc_hash,pc_offset;
78    u_char *test1,*test2,*test3,*test4;
79 
80    new_page = new_pc & MIPS_MIN_PAGE_MASK;
81    pc_offset = ((new_pc & MIPS_MIN_PAGE_IMASK) >> 2) * sizeof(u_char *);
82    pc_hash = mips64_jit_get_pc_hash(new_pc) * sizeof(mips64_jit_tcb_t *);
83 
84    /* Get JIT block info in r4 */
85    ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(cpu_mips_t,exec_blk_map),ppc_r3);
86    /* Check if offset is too big for a 16-bit immediate value */
87    if (pc_hash > 0x7fff)
88       ppc_addis(b->jit_ptr,ppc_r4,ppc_r4,ppc_ha16(pc_hash));
89    ppc_lwz(b->jit_ptr,ppc_r4,ppc_lo16(pc_hash),ppc_r4);
90 
91    /* no JIT block found ? */
92    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r4,0);
93    test1 = b->jit_ptr;
94    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
95 
96    /* r5:r6 = start_pc, r7:r8 = new_page */
97    ppc_lwz(b->jit_ptr,ppc_r5,OFFSET(mips64_jit_tcb_t,start_pc),ppc_r4);
98    ppc_lwz(b->jit_ptr,ppc_r6,OFFSET(mips64_jit_tcb_t,start_pc)+4,ppc_r4);
99    ppc_load(b->jit_ptr,ppc_r7,new_page >> 32);
100    ppc_load(b->jit_ptr,ppc_r8,new_page & 0xffffffff);
101 
102    /* Check block PC (lower 32-bits first) */
103    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r6,ppc_r8);
104    test2 = b->jit_ptr;
105    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
106 
107    /* Check higher bits... */
108    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r5,ppc_r7);
109    test3 = b->jit_ptr;
110    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
111 
112    /* Jump to the code */
113    ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(mips64_jit_tcb_t,jit_insn_ptr),ppc_r4);
114    ppc_lwz(b->jit_ptr,ppc_r12,pc_offset,ppc_r4);
115    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r12,0);
116    test4 = b->jit_ptr;
117    ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
118    ppc_mtlr(b->jit_ptr,ppc_r12);
119    ppc_blr(b->jit_ptr);
120 
121    /* Returns to caller... */
122    ppc_patch(test1,b->jit_ptr);
123    ppc_patch(test2,b->jit_ptr);
124    ppc_patch(test3,b->jit_ptr);
125    ppc_patch(test4,b->jit_ptr);
126 
127    mips64_set_pc(b,new_pc);
128    mips64_jit_tcb_push_epilog(b);
129 }
130 
131 /* Set Jump */
mips64_set_jump(cpu_mips_t * cpu,mips64_jit_tcb_t * b,m_uint64_t new_pc,int local_jump)132 static void mips64_set_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
133                             m_uint64_t new_pc,int local_jump)
134 {
135    int return_to_caller = FALSE;
136    u_char *jump_ptr;
137 
138    if (cpu->sym_trace && !local_jump)
139       return_to_caller = TRUE;
140 
141    if (!return_to_caller && mips64_jit_tcb_local_addr(b,new_pc,&jump_ptr)) {
142       if (jump_ptr) {
143          ppc_emit_jump_code(b->jit_ptr, jump_ptr, 0);
144       } else {
145          /* To check if the target is in a delay slot (previous
146             instruction's delay_slot == 0) */
147          if (mips64_jit_is_delay_slot(b,new_pc)) {
148             mips64_set_pc(b,new_pc);
149             mips64_jit_tcb_push_epilog(b);
150             return;
151          }
152       /* When using ppc_patch from mono, the following code will be
153          invalid if cpu->vm->exec_area_size, or MIPS_EXEC_AREA_SIZE > 32,
154          so here's a hacked way - ppc_emit_jump_code has been used to
155          support 32-bit addressing.
156          Also notice that += 16 hack depends on insn_block_record_patch
157          is called for unconditional branch only.
158        */
159          mips64_jit_tcb_record_patch(b,b->jit_ptr,new_pc);
160          b->jit_ptr += 16;
161          /*ppc_nop(b->jit_ptr);
162          ppc_nop(b->jit_ptr);
163          ppc_nop(b->jit_ptr);
164          ppc_nop(b->jit_ptr);*/
165       }
166    } else {
167       if (cpu->exec_blk_direct_jump) {
168          /* Block lookup optimization */
169          mips64_try_direct_far_jump(cpu,b,new_pc);
170       } else {
171          mips64_set_pc(b,new_pc);
172          mips64_jit_tcb_push_epilog(b);
173       }
174    }
175 }
176 
177 /* Basic C call */
mips64_emit_basic_c_call(mips64_jit_tcb_t * b,void * f)178 static forced_inline void mips64_emit_basic_c_call(mips64_jit_tcb_t *b,void *f)
179 {
180    ppc_emit_jump_code(b->jit_ptr, (u_char *)f, 1/*linked*/);
181    /* Restore the volatile r3 */
182    ppc_lwz(b->jit_ptr,ppc_r3,PPC_STACK_DECREMENTER+PPC_STACK_PARAM_OFFSET,ppc_r1);
183 }
184 
185 /* Emit a simple call to a C function without any parameter */
mips64_emit_c_call(mips64_jit_tcb_t * b,void * f)186 static void mips64_emit_c_call(mips64_jit_tcb_t *b,void *f)
187 {
188    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
189    mips64_emit_basic_c_call(b,f);
190 }
191 
192 /* Single-step operation */
mips64_emit_single_step(mips64_jit_tcb_t * b,mips_insn_t insn)193 void mips64_emit_single_step(mips64_jit_tcb_t *b,mips_insn_t insn)
194 {
195    ppc_load(b->jit_ptr,ppc_r4,insn);
196 //   mips64_emit_basic_c_call(b,mips64_exec_single_step);
197    /* Restore link register */
198    ppc_lwz(b->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1);
199    ppc_mtlr(b->jit_ptr,ppc_r0);
200    /* Trick: let callee return directly to the caller */
201    ppc_emit_jump_code(b->jit_ptr, (u_char *)mips64_exec_single_step, 0);
202 }
203 
204 /* Fast memory operation prototype */
205 typedef void (*memop_fast_access)(mips64_jit_tcb_t *b,int target);
206 
207 /* Fast LB */
mips64_memop_fast_lb(mips64_jit_tcb_t * b,int target)208 static void mips64_memop_fast_lb(mips64_jit_tcb_t *b,int target)
209 {
210    ppc_lbzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8);
211    ppc_extsb(b->jit_ptr,ppc_r10,ppc_r10);
212    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
213    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(target),ppc_r3);
214    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
215 }
216 
217 /* Fast LBU */
mips64_memop_fast_lbu(mips64_jit_tcb_t * b,int target)218 static void mips64_memop_fast_lbu(mips64_jit_tcb_t *b,int target)
219 {
220    ppc_lbzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8);
221    ppc_li(b->jit_ptr,ppc_r0,0);
222    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(target),ppc_r3);
223    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
224 }
225 
226 /* Fast LD */
mips64_memop_fast_ld(mips64_jit_tcb_t * b,int target)227 static void mips64_memop_fast_ld(mips64_jit_tcb_t *b,int target)
228 {
229    ppc_lwzux(b->jit_ptr,ppc_r9,ppc_r7,ppc_r8);
230    ppc_lwz(b->jit_ptr,ppc_r10,4,ppc_r7);
231    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(target),ppc_r3);
232    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
233 }
234 
235 /* Fast LH */
mips64_memop_fast_lh(mips64_jit_tcb_t * b,int target)236 static void mips64_memop_fast_lh(mips64_jit_tcb_t *b,int target)
237 {
238    ppc_lhax(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8);
239    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
240    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(target),ppc_r3);
241    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
242 }
243 
244 /* Fast LHU */
mips64_memop_fast_lhu(mips64_jit_tcb_t * b,int target)245 static void mips64_memop_fast_lhu(mips64_jit_tcb_t *b,int target)
246 {
247    ppc_lhzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8);
248    ppc_li(b->jit_ptr,ppc_r0,0);
249    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(target),ppc_r3);
250    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
251 }
252 
253 /* Fast LW */
mips64_memop_fast_lw(mips64_jit_tcb_t * b,int target)254 static void mips64_memop_fast_lw(mips64_jit_tcb_t *b,int target)
255 {
256    ppc_lwzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8);
257    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
258    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(target),ppc_r3);
259    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
260 }
261 
262 /* Fast LWU */
mips64_memop_fast_lwu(mips64_jit_tcb_t * b,int target)263 static void mips64_memop_fast_lwu(mips64_jit_tcb_t *b,int target)
264 {
265    ppc_lwzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8);
266    ppc_li(b->jit_ptr,ppc_r0,0);
267    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(target),ppc_r3);
268    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
269 }
270 
271 /* Fast SB */
mips64_memop_fast_sb(mips64_jit_tcb_t * b,int target)272 static void mips64_memop_fast_sb(mips64_jit_tcb_t *b,int target)
273 {
274    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
275    ppc_stbx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8);
276 }
277 
278 /* Fast SD */
mips64_memop_fast_sd(mips64_jit_tcb_t * b,int target)279 static void mips64_memop_fast_sd(mips64_jit_tcb_t *b,int target)
280 {
281    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(target),ppc_r3);
282    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
283    ppc_stwux(b->jit_ptr,ppc_r9,ppc_r7,ppc_r8);
284    ppc_stw(b->jit_ptr,ppc_r10,4,ppc_r7);
285 }
286 
287 /* Fast SH */
mips64_memop_fast_sh(mips64_jit_tcb_t * b,int target)288 static void mips64_memop_fast_sh(mips64_jit_tcb_t *b,int target)
289 {
290    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
291    ppc_sthx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8);
292 }
293 
294 /* Fast SW */
mips64_memop_fast_sw(mips64_jit_tcb_t * b,int target)295 static void mips64_memop_fast_sw(mips64_jit_tcb_t *b,int target)
296 {
297    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3);
298    ppc_stwx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8);
299 }
300 
301 /* Fast memory operation (64-bit) */
mips64_emit_memop_fast64(mips64_jit_tcb_t * b,int write_op,int opcode,int base,int offset,int target,int keep_ll_bit,memop_fast_access op_handler)302 static void mips64_emit_memop_fast64(mips64_jit_tcb_t *b,int write_op,
303                                      int opcode,int base,int offset,
304                                      int target,int keep_ll_bit,
305                                      memop_fast_access op_handler)
306 {
307    u_char *test1,*test2,*test3,*p_exit;
308 
309    test3 = NULL;
310 
311    /* r4:r5 = GPR[base] + sign-extended offset */
312    ppc_lwz(b->jit_ptr,ppc_r4,REG_OFFSET(base),ppc_r3);
313    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(base)+4,ppc_r3);
314    ppc_addic(b->jit_ptr,ppc_r5,ppc_r5,offset);
315    if (offset & 0x8000 /* < 0 */)
316       ppc_addme(b->jit_ptr,ppc_r4,ppc_r4);
317    else
318       ppc_addze(b->jit_ptr,ppc_r4,ppc_r4);
319 
320    /* r7 = offset in mts cache */
321    ppc_srwi(b->jit_ptr,ppc_r7,ppc_r5,MTS64_HASH_SHIFT1);
322    ppc_srwi(b->jit_ptr,ppc_r6,ppc_r5,MTS64_HASH_SHIFT2);
323    ppc_xor(b->jit_ptr,ppc_r8,ppc_r7,ppc_r6);
324    ppc_rlwinm(b->jit_ptr,ppc_r7,ppc_r8,
325               MTS64_HASH_BITS+5,
326               32-(MTS64_HASH_BITS+5),
327               31-MTS64_HASH_BITS);
328 
329    /* r8 = mts64_cache */
330    ppc_lwz(b->jit_ptr,ppc_r8,OFFSET(cpu_mips_t,mts_u.mts64_cache),ppc_r3);
331    /* r6 = mts64_entry */
332    ppc_add(b->jit_ptr,ppc_r6,ppc_r8,ppc_r7);
333    /* r7, r8 are temporary */
334 
335    /* Compare virtual page address */
336    ppc_lwz(b->jit_ptr,ppc_r7,OFFSET(mts64_entry_t,gvpa),ppc_r6);
337    ppc_lwz(b->jit_ptr,ppc_r8,OFFSET(mts64_entry_t,gvpa)+4,ppc_r6);
338 
339    /* Compare the high part of the vaddr */
340    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r4,ppc_r7);
341    test1 = b->jit_ptr;
342    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
343 
344    /* Compare the low part of the vaddr & MIPS_MIN_PAGE_MASK (vpage) */
345    ppc_rlwinm(b->jit_ptr,ppc_r0,ppc_r5,0,0,19);
346    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r0,ppc_r8);
347    test2 = b->jit_ptr;
348    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
349 
350    /* Test if we are writing to a COW page */
351    if (write_op) {
352       ppc_lwz(b->jit_ptr,ppc_r0,OFFSET(mts64_entry_t,flags),ppc_r6);
353       ppc_mtcrf(b->jit_ptr,0x01,ppc_r0);
354 	  /* MTS_FLAG_COW is moved to EQ bit of cr7 */
355       test3 = b->jit_ptr;
356       ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
357    }
358 
359    /* r7 = Host Page Address, r8 = offset in page */
360    ppc_lwz(b->jit_ptr,ppc_r7,OFFSET(mts64_entry_t,hpa),ppc_r6);
361    //ppc_rlwinm(b->jit_ptr,ppc_r8,ppc_r5,0,32-MIPS_MIN_PAGE_SHIFT,31);
362    ppc_andid(b->jit_ptr,ppc_r8,ppc_r5,MIPS_MIN_PAGE_IMASK);
363 
364    /* Memory access */
365    op_handler(b,target);
366 
367    p_exit = b->jit_ptr;
368    ppc_b(b->jit_ptr,0);
369 
370    /* === Slow lookup === */
371    ppc_patch(test1,b->jit_ptr);
372    ppc_patch(test2,b->jit_ptr);
373    if (test3)
374       ppc_patch(test3,b->jit_ptr);
375 
376    /* The following codes are copied from mips64_emit_memop */
377    /* lr = r12 = address of memory function */
378    ppc_lwz(b->jit_ptr,ppc_r12,MEMOP_OFFSET(opcode),ppc_r3);
379    ppc_mtlr(b->jit_ptr,ppc_r12);
380    /* Save PC for exception handling */
381    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
382    /* r6 = target register */
383    ppc_li(b->jit_ptr,ppc_r6,target);
384    /* Call memory function */
385    ppc_blrl(b->jit_ptr);
386    /* Restore the volatile r3 */
387    ppc_lwz(b->jit_ptr,ppc_r3,PPC_STACK_DECREMENTER+PPC_STACK_PARAM_OFFSET,ppc_r1);
388 
389    ppc_patch(p_exit,b->jit_ptr);
390 }
391 
392 /* Fast memory operation (32-bit) */
mips64_emit_memop_fast32(mips64_jit_tcb_t * b,int write_op,int opcode,int base,int offset,int target,int keep_ll_bit,memop_fast_access op_handler)393 static void mips64_emit_memop_fast32(mips64_jit_tcb_t *b,int write_op,
394                                      int opcode,int base,int offset,
395                                      int target,int keep_ll_bit,
396                                      memop_fast_access op_handler)
397 {
398    u_char *test2,*test3,*p_exit;
399 
400    test3 = NULL;
401 
402    /* r5 = GPR[base] + sign-extended offset */
403    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(base)+4,ppc_r3);
404    ppc_addi(b->jit_ptr,ppc_r5,ppc_r5,offset);
405 
406    /* r7 = offset in mts cache */
407    ppc_srwi(b->jit_ptr,ppc_r7,ppc_r5,MTS32_HASH_SHIFT1);
408    ppc_srwi(b->jit_ptr,ppc_r6,ppc_r5,MTS32_HASH_SHIFT2);
409    ppc_xor(b->jit_ptr,ppc_r8,ppc_r7,ppc_r6);
410    ppc_rlwinm(b->jit_ptr,ppc_r7,ppc_r8,
411               MTS32_HASH_BITS+4,
412               32-(MTS32_HASH_BITS+4),
413               31-MTS32_HASH_BITS);
414 
415    /* r8 = mts32_cache */
416    ppc_lwz(b->jit_ptr,ppc_r8,OFFSET(cpu_mips_t,mts_u.mts32_cache),ppc_r3);
417    /* r6 = mts32_entry */
418    ppc_add(b->jit_ptr,ppc_r6,ppc_r8,ppc_r7);
419    /* r7, r8 are temporary */
420 
421    /* Compare virtual page address (vaddr & MIPS_MIN_PAGE_MASK) */
422    ppc_lwz(b->jit_ptr,ppc_r8,OFFSET(mts32_entry_t,gvpa),ppc_r6);
423 
424    ppc_rlwinm(b->jit_ptr,ppc_r0,ppc_r5,0,0,19);
425    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r0,ppc_r8);
426    test2 = b->jit_ptr;
427    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
428 
429    /* Test if we are writing to a COW page */
430    if (write_op) {
431       ppc_lwz(b->jit_ptr,ppc_r0,OFFSET(mts32_entry_t,flags),ppc_r6);
432       ppc_mtcrf(b->jit_ptr,0x01,ppc_r0);
433 	  /* MTS_FLAG_COW is moved to EQ bit of cr7 */
434       test3 = b->jit_ptr;
435       ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
436    }
437 
438    /* r7 = Host Page Address, r8 = offset in page */
439    ppc_lwz(b->jit_ptr,ppc_r7,OFFSET(mts32_entry_t,hpa),ppc_r6);
440    //ppc_rlwinm(b->jit_ptr,ppc_r8,ppc_r5,0,32-MIPS_MIN_PAGE_SHIFT,31);
441    ppc_andid(b->jit_ptr,ppc_r8,ppc_r5,MIPS_MIN_PAGE_IMASK);
442 
443    /* Memory access */
444    op_handler(b,target);
445 
446    p_exit = b->jit_ptr;
447    ppc_b(b->jit_ptr,0);
448 
449    /* === Slow lookup === */
450    ppc_patch(test2,b->jit_ptr);
451    if (test3)
452       ppc_patch(test3,b->jit_ptr);
453 
454    /* The following codes are copied from mips64_emit_memop */
455    /* lr = r12 = address of memory function */
456    ppc_lwz(b->jit_ptr,ppc_r12,MEMOP_OFFSET(opcode),ppc_r3);
457    ppc_mtlr(b->jit_ptr,ppc_r12);
458    /* Save PC for exception handling */
459    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
460    /* r4 = sign extention of r5 */
461    ppc_srawi(b->jit_ptr,ppc_r4,ppc_r5,31);
462    /* r6 = target register */
463    ppc_li(b->jit_ptr,ppc_r6,target);
464    /* Call memory function */
465    ppc_blrl(b->jit_ptr);
466    /* Restore the volatile r3 */
467    ppc_lwz(b->jit_ptr,ppc_r3,PPC_STACK_DECREMENTER+PPC_STACK_PARAM_OFFSET,ppc_r1);
468 
469    ppc_patch(p_exit,b->jit_ptr);
470 }
471 
472 /* Fast memory operation */
mips64_emit_memop_fast(cpu_mips_t * cpu,mips64_jit_tcb_t * b,int write_op,int opcode,int base,int offset,int target,int keep_ll_bit,memop_fast_access op_handler)473 static void mips64_emit_memop_fast(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
474                                    int write_op,int opcode,
475                                    int base,int offset,
476                                    int target,int keep_ll_bit,
477                                    memop_fast_access op_handler)
478 {
479    switch(cpu->addr_mode) {
480       case 32:
481          mips64_emit_memop_fast32(b,write_op,opcode,base,offset,target,
482                                   keep_ll_bit,op_handler);
483          break;
484       case 64:
485          mips64_emit_memop_fast64(b,write_op,opcode,base,offset,target,
486                                   keep_ll_bit,op_handler);
487          break;
488    }
489 }
490 
491 /* Memory operation */
mips64_emit_memop(mips64_jit_tcb_t * b,int opcode,int base,int offset,int target,int keep_ll_bit)492 static void mips64_emit_memop(mips64_jit_tcb_t *b,int opcode,int base,int offset,
493                               int target,int keep_ll_bit)
494 {
495    /* lr = r12 = address of memory function */
496    ppc_lwz(b->jit_ptr,ppc_r12,MEMOP_OFFSET(opcode),ppc_r3);
497    ppc_mtlr(b->jit_ptr,ppc_r12);
498 
499    /* Save PC for exception handling */
500    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
501    if (!keep_ll_bit) {
502       ppc_li(b->jit_ptr,ppc_r0,0);
503       ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,ll_bit),ppc_r3);
504    }
505 
506    /* r3 = CPU instance pointer */
507    /* r4:r5 = GPR[base] + sign-extended offset */
508    ppc_lwz(b->jit_ptr,ppc_r4,REG_OFFSET(base),ppc_r3);
509    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(base)+4,ppc_r3);
510    ppc_addic(b->jit_ptr,ppc_r5,ppc_r5,offset);
511 
512    if (offset & 0x8000 /* < 0 */)
513       ppc_addme(b->jit_ptr,ppc_r4,ppc_r4);
514    else
515       ppc_addze(b->jit_ptr,ppc_r4,ppc_r4);
516 
517    /* r6 = target register */
518    ppc_li(b->jit_ptr,ppc_r6,target);
519 
520    /* Call memory function */
521    ppc_blrl(b->jit_ptr);
522 
523    /* Restore the volatile r3 */
524    ppc_lwz(b->jit_ptr,ppc_r3,PPC_STACK_DECREMENTER+PPC_STACK_PARAM_OFFSET,ppc_r1);
525 }
526 
527 /* Coprocessor Register transfert operation */
mips64_emit_cp_xfr_op(mips64_jit_tcb_t * b,int rt,int rd,void * f)528 static void mips64_emit_cp_xfr_op(mips64_jit_tcb_t *b,int rt,int rd,void *f)
529 {
530    /* update pc */
531    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
532 
533    /* r3 = CPU instance pointer */
534    /* r4 = gpr */
535    ppc_load(b->jit_ptr,ppc_r4,rt);
536 
537    /* r5 = cp0 register */
538    ppc_load(b->jit_ptr,ppc_r5,rd);
539 
540    mips64_emit_basic_c_call(b,f);
541 }
542 
543 /* Virtual Breakpoint */
mips64_emit_breakpoint(mips64_jit_tcb_t * b)544 void mips64_emit_breakpoint(mips64_jit_tcb_t *b)
545 {
546    mips64_emit_c_call(b,mips64_run_breakpoint);
547 }
548 
549 /* Unknown opcode handler */
mips64_unknown_opcode(cpu_mips_t * cpu,m_uint32_t opcode)550 static asmlinkage void mips64_unknown_opcode(cpu_mips_t *cpu,m_uint32_t opcode)
551 {
552    printf("MIPS64: unhandled opcode 0x%8.8x at 0x%llx (ra=0x%llx)\n",
553           opcode,cpu->pc,cpu->gpr[MIPS_GPR_RA]);
554 
555    mips64_dump_regs(cpu->gen);
556 }
557 
558 /* Emit unhandled instruction code */
mips64_emit_unknown(cpu_mips_t * cpu,mips64_jit_tcb_t * b,mips_insn_t opcode)559 static int mips64_emit_unknown(cpu_mips_t *cpu,mips64_jit_tcb_t *b,
560                                mips_insn_t opcode)
561 {
562    ppc_load(b->jit_ptr,ppc_r4,opcode);
563    mips64_emit_c_call(b,mips64_unknown_opcode);
564    return(0);
565 }
566 
567 /* Invalid delay slot handler */
mips64_invalid_delay_slot(cpu_mips_t * cpu)568 static fastcall void mips64_invalid_delay_slot(cpu_mips_t *cpu)
569 {
570    printf("MIPS64: invalid instruction in delay slot at 0x%llx (ra=0x%llx)\n",
571           cpu->pc,cpu->gpr[MIPS_GPR_RA]);
572 
573    mips64_dump_regs(cpu->gen);
574 
575    /* Halt the virtual CPU */
576    cpu->pc = 0;
577 }
578 
579 /* Emit invalid delay slot */
mips64_emit_invalid_delay_slot(mips64_jit_tcb_t * b)580 int mips64_emit_invalid_delay_slot(mips64_jit_tcb_t *b)
581 {
582    /* Restore link register */
583    ppc_lwz(b->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1);
584    ppc_mtlr(b->jit_ptr,ppc_r0);
585 
586    /* Trick: let callee return directly to the caller */
587    ppc_emit_jump_code(b->jit_ptr, (u_char *)mips64_invalid_delay_slot, 0);
588    return(0);
589 }
590 
591 /*
592  * Increment count register and trigger the timer IRQ if value in compare
593  * register is the same.
594  */
mips64_inc_cp0_count_reg(mips64_jit_tcb_t * b)595 void mips64_inc_cp0_count_reg(mips64_jit_tcb_t *b)
596 {
597    ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(cpu_mips_t,cp0_virt_cnt_reg),ppc_r3);
598    ppc_addi(b->jit_ptr,ppc_r4,ppc_r4,1); // addi takes 0 instead of r0
599    ppc_stw(b->jit_ptr,ppc_r4,OFFSET(cpu_mips_t,cp0_virt_cnt_reg),ppc_r3);
600 }
601 
602 /* Check if there are pending IRQ */
mips64_check_pending_irq(mips64_jit_tcb_t * b)603 void mips64_check_pending_irq(mips64_jit_tcb_t *b)
604 {
605    u_char *test1;
606 
607    /* Check the pending IRQ flag */
608    ppc_lwz(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,irq_pending),ppc_r3);
609    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r0,0);
610    test1 = b->jit_ptr;
611    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
612 
613    /* Save PC */
614    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
615 
616    /* Trigger the IRQ */
617    mips64_emit_basic_c_call(b,mips64_trigger_irq);
618    mips64_jit_tcb_push_epilog(b);
619 
620    ppc_patch(test1,b->jit_ptr);
621 }
622 
623 /* Increment the number of executed instructions (performance debugging) */
mips64_inc_perf_counter(mips64_jit_tcb_t * b)624 void mips64_inc_perf_counter(mips64_jit_tcb_t *b)
625 {
626    ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(cpu_mips_t,perf_counter),ppc_r3);
627    ppc_addi(b->jit_ptr,ppc_r4,ppc_r4,1); // addi takes 0 instead of r0
628    ppc_stw(b->jit_ptr,ppc_r4,OFFSET(cpu_mips_t,perf_counter),ppc_r3);
629 }
630 
631 /* ADD */
DECLARE_INSN(ADD)632 DECLARE_INSN(ADD)
633 {
634    int rs = bits(insn,21,25);
635    int rt = bits(insn,16,20);
636    int rd = bits(insn,11,15);
637 
638    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
639    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
640    ppc_addo(b->jit_ptr,ppc_r10,ppc_r8,ppc_r9);
641 
642    /* TODO: Exception handling */
643 
644    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
645    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
646    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
647    return(0);
648 }
649 
650 /* ADDI */
DECLARE_INSN(ADDI)651 DECLARE_INSN(ADDI)
652 {
653    int rs  = bits(insn,21,25);
654    int rt  = bits(insn,16,20);
655    int imm = bits(insn,0,15);
656    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
657    ppc_addi(b->jit_ptr,ppc_r9,ppc_r8,imm);
658 
659    /* TODO: Exception handling */
660 
661    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
662    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r9,31);
663    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rt),ppc_r3);
664    return(0);
665 }
666 
667 /* ADDIU */
DECLARE_INSN(ADDIU)668 DECLARE_INSN(ADDIU)
669 {
670    int rs  = bits(insn,21,25);
671    int rt  = bits(insn,16,20);
672    int imm = bits(insn,0,15);
673    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
674    ppc_addi(b->jit_ptr,ppc_r9,ppc_r8,imm);
675 
676    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
677    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r9,31);
678    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rt),ppc_r3);
679    return(0);
680 }
681 
682 /* ADDU */
DECLARE_INSN(ADDU)683 DECLARE_INSN(ADDU)
684 {
685    int rs = bits(insn,21,25);
686    int rt = bits(insn,16,20);
687    int rd = bits(insn,11,15);
688 
689    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
690    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
691    ppc_add(b->jit_ptr,ppc_r10,ppc_r8,ppc_r9);
692 
693    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
694    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
695    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
696    return(0);
697 }
698 
699 /* AND */
DECLARE_INSN(AND)700 DECLARE_INSN(AND)
701 {
702    int rs = bits(insn,21,25);
703    int rt = bits(insn,16,20);
704    int rd = bits(insn,11,15);
705 
706    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
707    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
708    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
709    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
710 
711    ppc_and(b->jit_ptr,ppc_r9,ppc_r5,ppc_r7);
712    ppc_and(b->jit_ptr,ppc_r10,ppc_r6,ppc_r8);
713 
714    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rd),ppc_r3);
715    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
716    return(0);
717 }
718 
719 /* ANDI */
DECLARE_INSN(ANDI)720 DECLARE_INSN(ANDI)
721 {
722    int rs  = bits(insn,21,25);
723    int rt  = bits(insn,16,20);
724    int imm = bits(insn,0,15);
725 
726    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
727 
728    ppc_andid(b->jit_ptr,ppc_r8,ppc_r6,imm);
729 
730    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
731    ppc_li(b->jit_ptr,ppc_r0,0);
732    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rt),ppc_r3);
733 
734    return(0);
735 }
736 
737 /* B (virtual) */
DECLARE_INSN(B)738 DECLARE_INSN(B)
739 {
740    int offset = bits(insn,0,15);
741    m_uint64_t new_pc;
742 
743    /* compute the new pc */
744    new_pc = b->start_pc + (b->mips_trans_pos << 2);
745    new_pc += sign_extend(offset << 2,18);
746 
747    /* insert the instruction in the delay slot */
748    mips64_jit_fetch_and_emit(cpu,b,1);
749 
750    /* set the new pc in cpu structure */
751    mips64_set_jump(cpu,b,new_pc,1);
752    return(0);
753 }
754 
755 /* BAL (virtual) */
DECLARE_INSN(BAL)756 DECLARE_INSN(BAL)
757 {
758    int offset = bits(insn,0,15);
759    m_uint64_t new_pc;
760 
761    /* compute the new pc */
762    new_pc = b->start_pc + (b->mips_trans_pos << 2);
763    new_pc += sign_extend(offset << 2,18);
764 
765    /* set the return address (instruction after the delay slot) */
766    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
767 
768    /* insert the instruction in the delay slot */
769    mips64_jit_fetch_and_emit(cpu,b,1);
770 
771    /* set the new pc in cpu structure */
772    mips64_set_jump(cpu,b,new_pc,0);
773    return(0);
774 }
775 
776 /* BEQ */
DECLARE_INSN(BEQ)777 DECLARE_INSN(BEQ)
778 {
779    int rs = bits(insn,21,25);
780    int rt = bits(insn,16,20);
781    int offset = bits(insn,0,15);
782    u_char *test1,*test2;
783    m_uint64_t new_pc;
784 
785    /* compute the new pc */
786    new_pc = b->start_pc + (b->mips_trans_pos << 2);
787    new_pc += sign_extend(offset << 2,18);
788 
789    /*
790     * compare gpr[rs] and gpr[rt].
791     * compare the low 32 bits first (higher probability).
792     */
793    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
794    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
795    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r6,ppc_r8);
796    test1 = b->jit_ptr;
797    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
798 
799    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
800    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
801    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r5,ppc_r7);
802    test2 = b->jit_ptr;
803    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
804 
805    /* insert the instruction in the delay slot */
806    mips64_jit_fetch_and_emit(cpu,b,2);
807 
808    /* set the new pc in cpu structure */
809    mips64_set_jump(cpu,b,new_pc,1);
810 
811    ppc_patch(test1,b->jit_ptr);
812    ppc_patch(test2,b->jit_ptr);
813 
814    /* if the branch is not taken, we have to execute the delay slot too */
815    mips64_jit_fetch_and_emit(cpu,b,1);
816    return(0);
817 }
818 
819 /* BEQL (Branch On Equal Likely) */
DECLARE_INSN(BEQL)820 DECLARE_INSN(BEQL)
821 {
822    int rs = bits(insn,21,25);
823    int rt = bits(insn,16,20);
824    int offset = bits(insn,0,15);
825    u_char *test1,*test2;
826    m_uint64_t new_pc;
827 
828    /* compute the new pc */
829    new_pc = b->start_pc + (b->mips_trans_pos << 2);
830    new_pc += sign_extend(offset << 2,18);
831 
832    /*
833     * compare gpr[rs] and gpr[rt].
834     * compare the low 32 bits first (higher probability).
835     */
836    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
837    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
838    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r6,ppc_r8);
839    test1 = b->jit_ptr;
840    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
841 
842    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
843    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
844    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r5,ppc_r7);
845    test2 = b->jit_ptr;
846    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
847 
848    /* insert the instruction in the delay slot */
849    mips64_jit_fetch_and_emit(cpu,b,1);
850 
851    /* set the new pc in cpu structure */
852    mips64_set_jump(cpu,b,new_pc,1);
853 
854    ppc_patch(test1,b->jit_ptr);
855    ppc_patch(test2,b->jit_ptr);
856    return(0);
857 }
858 
859 /* BEQZ (virtual) */
DECLARE_INSN(BEQZ)860 DECLARE_INSN(BEQZ)
861 {
862    int rs = bits(insn,21,25);
863    int offset = bits(insn,0,15);
864    u_char *test1,*test2;
865    m_uint64_t new_pc;
866 
867    /* compute the new pc */
868    new_pc = b->start_pc + (b->mips_trans_pos << 2);
869    new_pc += sign_extend(offset << 2,18);
870 
871    /*
872     * compare gpr[rs] and gpr[rt].
873     * compare the low 32 bits first (higher probability).
874     */
875    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
876    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r6,0);
877    test1 = b->jit_ptr;
878    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
879 
880    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
881    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
882    test2 = b->jit_ptr;
883    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
884 
885    /* insert the instruction in the delay slot */
886    mips64_jit_fetch_and_emit(cpu,b,2);
887 
888    /* set the new pc in cpu structure */
889    mips64_set_jump(cpu,b,new_pc,1);
890 
891    ppc_patch(test1,b->jit_ptr);
892    ppc_patch(test2,b->jit_ptr);
893 
894    /* if the branch is not taken, we have to execute the delay slot too */
895    mips64_jit_fetch_and_emit(cpu,b,1);
896    return(0);
897 }
898 
899 /* BNEZ (virtual) */
DECLARE_INSN(BNEZ)900 DECLARE_INSN(BNEZ)
901 {
902    int rs = bits(insn,21,25);
903    int offset = bits(insn,0,15);
904    u_char *test1,*test2;
905    m_uint64_t new_pc;
906 
907    /* compute the new pc */
908    new_pc = b->start_pc + (b->mips_trans_pos << 2);
909    new_pc += sign_extend(offset << 2,18);
910 
911    /*
912     * compare gpr[rs] and gpr[rt].
913     * compare the low 32 bits first (higher probability).
914     */
915    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
916    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r6,0);
917    test1 = b->jit_ptr;
918    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
919 
920    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
921    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
922    test2 = b->jit_ptr;
923    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
924 
925    ppc_patch(test1,b->jit_ptr);
926 
927    /* insert the instruction in the delay slot */
928    mips64_jit_fetch_and_emit(cpu,b,2);
929 
930    /* set the new pc in cpu structure */
931    mips64_set_jump(cpu,b,new_pc,1);
932 
933    ppc_patch(test2,b->jit_ptr);
934 
935    /* if the branch is not taken, we have to execute the delay slot too */
936    mips64_jit_fetch_and_emit(cpu,b,1);
937    return(0);
938 }
939 
940 /* BGEZ */
DECLARE_INSN(BGEZ)941 DECLARE_INSN(BGEZ)
942 {
943    int rs = bits(insn,21,25);
944    int offset = bits(insn,0,15);
945    u_char *test1;
946    m_uint64_t new_pc;
947 
948    /* compute the new pc */
949    new_pc = b->start_pc + (b->mips_trans_pos << 2);
950    new_pc += sign_extend(offset << 2,18);
951 
952    /* If sign bit is set, don't take the branch */
953    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
954    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
955    test1 = b->jit_ptr;
956    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
957 
958    /* insert the instruction in the delay slot */
959    mips64_jit_fetch_and_emit(cpu,b,2);
960 
961    /* set the new pc in cpu structure */
962    mips64_set_jump(cpu,b,new_pc,1);
963 
964    ppc_patch(test1,b->jit_ptr);
965 
966    /* if the branch is not taken, we have to execute the delay slot too */
967    mips64_jit_fetch_and_emit(cpu,b,1);
968    return(0);
969 }
970 
971 /* BGEZAL */
DECLARE_INSN(BGEZAL)972 DECLARE_INSN(BGEZAL)
973 {
974    int rs = bits(insn,21,25);
975    int offset = bits(insn,0,15);
976    u_char *test1;
977    m_uint64_t new_pc;
978 
979    /* compute the new pc */
980    new_pc = b->start_pc + (b->mips_trans_pos << 2);
981    new_pc += sign_extend(offset << 2,18);
982 
983    /* set the return address (instruction after the delay slot) */
984    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
985 
986    /* If sign bit is set, don't take the branch */
987    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
988    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
989    test1 = b->jit_ptr;
990    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
991 
992    /* insert the instruction in the delay slot */
993    mips64_jit_fetch_and_emit(cpu,b,2);
994 
995    /* set the new pc in cpu structure */
996    mips64_set_jump(cpu,b,new_pc,1);
997 
998    ppc_patch(test1,b->jit_ptr);
999 
1000    /* if the branch is not taken, we have to execute the delay slot too */
1001    mips64_jit_fetch_and_emit(cpu,b,1);
1002    return(0);
1003 }
1004 
1005 /* BGEZALL */
DECLARE_INSN(BGEZALL)1006 DECLARE_INSN(BGEZALL)
1007 {
1008    int rs = bits(insn,21,25);
1009    int offset = bits(insn,0,15);
1010    u_char *test1;
1011    m_uint64_t new_pc;
1012 
1013    /* compute the new pc */
1014    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1015    new_pc += sign_extend(offset << 2,18);
1016 
1017    /* set the return address (instruction after the delay slot) */
1018    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
1019 
1020    /* if sign bit is set, don't take the branch */
1021    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1022    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1023    test1 = b->jit_ptr;
1024    ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1025 
1026    /* insert the instruction in the delay slot */
1027    mips64_jit_fetch_and_emit(cpu,b,1);
1028 
1029    /* set the new pc in cpu structure */
1030    mips64_set_jump(cpu,b,new_pc,1);
1031 
1032    ppc_patch(test1,b->jit_ptr);
1033    return(0);
1034 }
1035 
1036 /* BGEZL */
DECLARE_INSN(BGEZL)1037 DECLARE_INSN(BGEZL)
1038 {
1039    int rs = bits(insn,21,25);
1040    int offset = bits(insn,0,15);
1041    u_char *test1;
1042    m_uint64_t new_pc;
1043 
1044    /* compute the new pc */
1045    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1046    new_pc += sign_extend(offset << 2,18);
1047 
1048    /* If sign bit is set, don't take the branch */
1049    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1050    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1051    test1 = b->jit_ptr;
1052    ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1053 
1054    /* insert the instruction in the delay slot */
1055    mips64_jit_fetch_and_emit(cpu,b,1);
1056 
1057    /* set the new pc in cpu structure */
1058    mips64_set_jump(cpu,b,new_pc,1);
1059 
1060    ppc_patch(test1,b->jit_ptr);
1061    return(0);
1062 }
1063 
1064 /* BGTZ */
DECLARE_INSN(BGTZ)1065 DECLARE_INSN(BGTZ)
1066 {
1067    int rs = bits(insn,21,25);
1068    int offset = bits(insn,0,15);
1069    u_char *test1,*test2,*test3;
1070    m_uint64_t new_pc;
1071 
1072    /* compute the new pc */
1073    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1074    new_pc += sign_extend(offset << 2,18);
1075 
1076    /*
1077     * test the hi word of gpr[rs]
1078     */
1079    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1080    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1081    test1 = b->jit_ptr;
1082    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_GT),0);
1083    test2 = b->jit_ptr;
1084    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1085 
1086    /* test the lo word of gpr[rs] (here hi word == 0) */
1087    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1088    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r6,0);
1089    test3 = b->jit_ptr;
1090    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
1091 
1092    ppc_patch(test1,b->jit_ptr);
1093 
1094    /* insert the instruction in the delay slot */
1095    mips64_jit_fetch_and_emit(cpu,b,2);
1096 
1097    /* set the new pc in cpu structure */
1098    mips64_set_jump(cpu,b,new_pc,1);
1099 
1100    ppc_patch(test2,b->jit_ptr);
1101    ppc_patch(test3,b->jit_ptr);
1102 
1103    /* if the branch is not taken, we have to execute the delay slot too */
1104    mips64_jit_fetch_and_emit(cpu,b,1);
1105    return(0);
1106 }
1107 
1108 /* BGTZL */
DECLARE_INSN(BGTZL)1109 DECLARE_INSN(BGTZL)
1110 {
1111    int rs = bits(insn,21,25);
1112    int offset = bits(insn,0,15);
1113    u_char *test1,*test2,*test3;
1114    m_uint64_t new_pc;
1115 
1116    /* compute the new pc */
1117    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1118    new_pc += sign_extend(offset << 2,18);
1119 
1120    /*
1121     * test the hi word of gpr[rs]
1122     */
1123    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1124    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1125    test1 = b->jit_ptr;
1126    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_GT),0);
1127    test2 = b->jit_ptr;
1128    ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1129 
1130    /* test the lo word of gpr[rs] (here hi word == 0) */
1131    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1132    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r6,0);
1133    test3 = b->jit_ptr;
1134    ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
1135 
1136    ppc_patch(test1,b->jit_ptr);
1137 
1138    /* insert the instruction in the delay slot */
1139    mips64_jit_fetch_and_emit(cpu,b,1);
1140 
1141    /* set the new pc in cpu structure */
1142    mips64_set_jump(cpu,b,new_pc,1);
1143 
1144    ppc_patch(test2,b->jit_ptr);
1145    ppc_patch(test3,b->jit_ptr);
1146    return(0);
1147 }
1148 
1149 /* BLEZ */
DECLARE_INSN(BLEZ)1150 DECLARE_INSN(BLEZ)
1151 {
1152    int rs = bits(insn,21,25);
1153    int offset = bits(insn,0,15);
1154    u_char *test1,*test2,*test3;
1155    m_uint64_t new_pc;
1156 
1157    /* compute the new pc */
1158    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1159    new_pc += sign_extend(offset << 2,18);
1160 
1161    /*
1162     * test the hi word of gpr[rs]
1163     */
1164    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1165    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1166    test1 = b->jit_ptr;
1167    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1168    test2 = b->jit_ptr;
1169    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_GT),0);
1170 
1171    /* test the lo word of gpr[rs] (here hi word == 0) */
1172    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1173    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r6,0);
1174    test3 = b->jit_ptr;
1175    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
1176 
1177    ppc_patch(test1,b->jit_ptr);
1178 
1179    /* insert the instruction in the delay slot */
1180    mips64_jit_fetch_and_emit(cpu,b,2);
1181 
1182    /* set the new pc in cpu structure */
1183    mips64_set_jump(cpu,b,new_pc,1);
1184 
1185    ppc_patch(test2,b->jit_ptr);
1186    ppc_patch(test3,b->jit_ptr);
1187 
1188    /* if the branch is not taken, we have to execute the delay slot too */
1189    mips64_jit_fetch_and_emit(cpu,b,1);
1190    return(0);
1191 }
1192 
1193 /* BLEZL */
DECLARE_INSN(BLEZL)1194 DECLARE_INSN(BLEZL)
1195 {
1196    int rs = bits(insn,21,25);
1197    int offset = bits(insn,0,15);
1198    u_char *test1,*test2,*test3;
1199    m_uint64_t new_pc;
1200 
1201    /* compute the new pc */
1202    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1203    new_pc += sign_extend(offset << 2,18);
1204 
1205    /*
1206     * test the hi word of gpr[rs]
1207     */
1208    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1209    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1210    test1 = b->jit_ptr;
1211    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1212    test2 = b->jit_ptr;
1213    ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_GT),0);
1214 
1215    /* test the lo word of gpr[rs] (here hi word == 0) */
1216    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1217    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r6,0);
1218    test3 = b->jit_ptr;
1219    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
1220 
1221    ppc_patch(test1,b->jit_ptr);
1222 
1223    /* insert the instruction in the delay slot */
1224    mips64_jit_fetch_and_emit(cpu,b,1);
1225 
1226    /* set the new pc in cpu structure */
1227    mips64_set_jump(cpu,b,new_pc,1);
1228 
1229    ppc_patch(test2,b->jit_ptr);
1230    ppc_patch(test3,b->jit_ptr);
1231    return(0);
1232 }
1233 
1234 /* BLTZ */
DECLARE_INSN(BLTZ)1235 DECLARE_INSN(BLTZ)
1236 {
1237    int rs = bits(insn,21,25);
1238    int offset = bits(insn,0,15);
1239    u_char *test1;
1240    m_uint64_t new_pc;
1241 
1242    /* compute the new pc */
1243    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1244    new_pc += sign_extend(offset << 2,18);
1245 
1246    /*
1247     * test the sign bit of gpr[rs], if set, take the branch.
1248     */
1249    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1250    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1251    test1 = b->jit_ptr;
1252    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1253 
1254    /* insert the instruction in the delay slot */
1255    mips64_jit_fetch_and_emit(cpu,b,2);
1256 
1257    /* set the new pc in cpu structure */
1258    mips64_set_jump(cpu,b,new_pc,1);
1259 
1260    ppc_patch(test1,b->jit_ptr);
1261 
1262    /* if the branch is not taken, we have to execute the delay slot too */
1263    mips64_jit_fetch_and_emit(cpu,b,1);
1264    return(0);
1265 }
1266 
1267 /* BLTZAL */
DECLARE_INSN(BLTZAL)1268 DECLARE_INSN(BLTZAL)
1269 {
1270    int rs = bits(insn,21,25);
1271    int offset = bits(insn,0,15);
1272    u_char *test1;
1273    m_uint64_t new_pc;
1274 
1275    /* compute the new pc */
1276    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1277    new_pc += sign_extend(offset << 2,18);
1278 
1279    /* set the return address (instruction after the delay slot) */
1280    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
1281 
1282    /*
1283     * test the sign bit of gpr[rs], if set, take the branch.
1284     */
1285    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1286    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1287    test1 = b->jit_ptr;
1288    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1289 
1290    /* insert the instruction in the delay slot */
1291    mips64_jit_fetch_and_emit(cpu,b,2);
1292 
1293    /* set the new pc in cpu structure */
1294    mips64_set_jump(cpu,b,new_pc,1);
1295 
1296    ppc_patch(test1,b->jit_ptr);
1297 
1298    /* if the branch is not taken, we have to execute the delay slot too */
1299    mips64_jit_fetch_and_emit(cpu,b,1);
1300    return(0);
1301 }
1302 
1303 /* BLTZALL */
DECLARE_INSN(BLTZALL)1304 DECLARE_INSN(BLTZALL)
1305 {
1306    int rs = bits(insn,21,25);
1307    int offset = bits(insn,0,15);
1308    u_char *test1;
1309    m_uint64_t new_pc;
1310 
1311    /* compute the new pc */
1312    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1313    new_pc += sign_extend(offset << 2,18);
1314 
1315    /* set the return address (instruction after the delay slot) */
1316    mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2));
1317 
1318    /*
1319     * test the sign bit of gpr[rs], if set, take the branch.
1320     */
1321    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1322    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1323    test1 = b->jit_ptr;
1324    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1325 
1326    /* insert the instruction in the delay slot */
1327    mips64_jit_fetch_and_emit(cpu,b,1);
1328 
1329    /* set the new pc in cpu structure */
1330    mips64_set_jump(cpu,b,new_pc,1);
1331 
1332    ppc_patch(test1,b->jit_ptr);
1333    return(0);
1334 }
1335 
1336 /* BLTZL */
DECLARE_INSN(BLTZL)1337 DECLARE_INSN(BLTZL)
1338 {
1339    int rs = bits(insn,21,25);
1340    int offset = bits(insn,0,15);
1341    u_char *test1;
1342    m_uint64_t new_pc;
1343 
1344    /* compute the new pc */
1345    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1346    new_pc += sign_extend(offset << 2,18);
1347 
1348    /*
1349     * test the sign bit of gpr[rs], if set, take the branch.
1350     */
1351    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1352    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0);
1353    test1 = b->jit_ptr;
1354    ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_LT),0);
1355 
1356    /* insert the instruction in the delay slot */
1357    mips64_jit_fetch_and_emit(cpu,b,1);
1358 
1359    /* set the new pc in cpu structure */
1360    mips64_set_jump(cpu,b,new_pc,1);
1361 
1362    ppc_patch(test1,b->jit_ptr);
1363    return(0);
1364 }
1365 
1366 /* BNE */
DECLARE_INSN(BNE)1367 DECLARE_INSN(BNE)
1368 {
1369    int rs = bits(insn,21,25);
1370    int rt = bits(insn,16,20);
1371    int offset = bits(insn,0,15);
1372    u_char *test1,*test2;
1373    m_uint64_t new_pc;
1374 
1375    /* compute the new pc */
1376    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1377    new_pc += sign_extend(offset << 2,18);
1378 
1379    /*
1380     * compare gpr[rs] and gpr[rt].
1381     * compare the low 32 bits first (higher probability).
1382     */
1383    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1384    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
1385    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r6,ppc_r8);
1386    test1 = b->jit_ptr;
1387    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
1388 
1389    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1390    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
1391    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r5,ppc_r7);
1392    test2 = b->jit_ptr;
1393    ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
1394 
1395    ppc_patch(test1,b->jit_ptr);
1396 
1397    /* insert the instruction in the delay slot */
1398    mips64_jit_fetch_and_emit(cpu,b,2);
1399 
1400    /* set the new pc in cpu structure */
1401    mips64_set_jump(cpu,b,new_pc,1);
1402 
1403    ppc_patch(test2,b->jit_ptr);
1404 
1405    /* if the branch is not taken, we have to execute the delay slot too */
1406    mips64_jit_fetch_and_emit(cpu,b,1);
1407    return(0);
1408 }
1409 
1410 /* BNEL */
DECLARE_INSN(BNEL)1411 DECLARE_INSN(BNEL)
1412 {
1413    int rs = bits(insn,21,25);
1414    int rt = bits(insn,16,20);
1415    int offset = bits(insn,0,15);
1416    u_char *test1,*test2;
1417    m_uint64_t new_pc;
1418 
1419    /* compute the new pc */
1420    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1421    new_pc += sign_extend(offset << 2,18);
1422 
1423    /*
1424     * compare gpr[rs] and gpr[rt].
1425     * compare the low 32 bits first (higher probability).
1426     */
1427    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1428    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
1429    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r6,ppc_r8);
1430    test1 = b->jit_ptr;
1431    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
1432 
1433    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1434    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
1435    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r5,ppc_r7);
1436    test2 = b->jit_ptr;
1437    ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
1438 
1439    ppc_patch(test1,b->jit_ptr);
1440 
1441    /* insert the instruction in the delay slot */
1442    mips64_jit_fetch_and_emit(cpu,b,1);
1443 
1444    /* set the new pc in cpu structure */
1445    mips64_set_jump(cpu,b,new_pc,1);
1446 
1447    ppc_patch(test2,b->jit_ptr);
1448    return(0);
1449 }
1450 
1451 /* BREAK */
DECLARE_INSN(BREAK)1452 DECLARE_INSN(BREAK)
1453 {
1454    u_int code = bits(insn,6,25);
1455    /* r3 = CPU instance pointer */
1456    /* r4 = code */
1457    ppc_load(b->jit_ptr,ppc_r4,code);
1458    mips64_emit_basic_c_call(b,mips64_exec_break);
1459    mips64_jit_tcb_push_epilog(b);
1460    return(0);
1461 }
1462 
1463 /* CACHE */
DECLARE_INSN(CACHE)1464 DECLARE_INSN(CACHE)
1465 {
1466    int base   = bits(insn,21,25);
1467    int op     = bits(insn,16,20);
1468    int offset = bits(insn,0,15);
1469 
1470    mips64_emit_memop(b,MIPS_MEMOP_CACHE,base,offset,op,FALSE);
1471    return(0);
1472 }
1473 
1474 /* CFC0 */
DECLARE_INSN(CFC0)1475 DECLARE_INSN(CFC0)
1476 {
1477    int rt = bits(insn,16,20);
1478    int rd = bits(insn,11,15);
1479 
1480    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_cfc0);
1481    return(0);
1482 }
1483 
1484 /* CTC0 */
DECLARE_INSN(CTC0)1485 DECLARE_INSN(CTC0)
1486 {
1487    int rt = bits(insn,16,20);
1488    int rd = bits(insn,11,15);
1489 
1490    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_ctc0);
1491    return(0);
1492 }
1493 
1494 /* DADDIU */
DECLARE_INSN(DADDIU)1495 DECLARE_INSN(DADDIU)
1496 {
1497    int rs  = bits(insn,21,25);
1498    int rt  = bits(insn,16,20);
1499    int imm = bits(insn,0,15);
1500    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1501    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1502 
1503    ppc_addic(b->jit_ptr,ppc_r6,ppc_r6,imm);
1504    if (imm  & 0x8000 /* < 0 */)
1505       ppc_addme(b->jit_ptr,ppc_r5,ppc_r5);
1506    else
1507       ppc_addze(b->jit_ptr,ppc_r5,ppc_r5);
1508 
1509    ppc_stw(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
1510    ppc_stw(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
1511    return(0);
1512 }
1513 
1514 /* DADDU */
DECLARE_INSN(DADDU)1515 DECLARE_INSN(DADDU)
1516 {
1517    int rs = bits(insn,21,25);
1518    int rt = bits(insn,16,20);
1519    int rd = bits(insn,11,15);
1520 
1521    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1522    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
1523    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1524    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
1525 
1526    ppc_addc(b->jit_ptr,ppc_r10,ppc_r6,ppc_r8);
1527    ppc_adde(b->jit_ptr,ppc_r9,ppc_r5,ppc_r7);
1528 
1529    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
1530    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rd),ppc_r3);
1531    return(0);
1532 }
1533 
1534 /* DIV */
DECLARE_INSN(DIV)1535 DECLARE_INSN(DIV)
1536 {
1537    int rs = bits(insn,21,25);
1538    int rt = bits(insn,16,20);
1539 
1540    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1541    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
1542 
1543    ppc_divw(b->jit_ptr,ppc_r10,ppc_r6,ppc_r8);
1544    /* store LO (quotient) */
1545    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,lo)+4,ppc_r3);
1546    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
1547    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,lo),ppc_r3);
1548 
1549    ppc_mullw(b->jit_ptr,ppc_r9,ppc_r10,ppc_r8);
1550    ppc_subf(b->jit_ptr,ppc_r9,ppc_r9,ppc_r6);
1551    /* store HI (remainder) */
1552    ppc_stw(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,hi)+4,ppc_r3);
1553    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r9,31);
1554    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,hi),ppc_r3);
1555    return(0);
1556 }
1557 
1558 /* DIVU */
DECLARE_INSN(DIVU)1559 DECLARE_INSN(DIVU)
1560 {
1561    int rs = bits(insn,21,25);
1562    int rt = bits(insn,16,20);
1563 
1564    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1565    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
1566 
1567    ppc_divwu(b->jit_ptr,ppc_r10,ppc_r6,ppc_r8);
1568    /* store LO (quotient) */
1569    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,lo)+4,ppc_r3);
1570    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
1571    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,lo),ppc_r3);
1572 
1573    ppc_mullw(b->jit_ptr,ppc_r9,ppc_r10,ppc_r8);
1574    ppc_subf(b->jit_ptr,ppc_r9,ppc_r9,ppc_r6);
1575    /* store HI (remainder) */
1576    ppc_stw(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,hi)+4,ppc_r3);
1577    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r9,31);
1578    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,hi),ppc_r3);
1579    return(0);
1580 }
1581 
1582 /* DMFC0 */
DECLARE_INSN(DMFC0)1583 DECLARE_INSN(DMFC0)
1584 {
1585    int rt = bits(insn,16,20);
1586    int rd = bits(insn,11,15);
1587 
1588    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_dmfc0);
1589    return(0);
1590 }
1591 
1592 /* DMFC1 */
DECLARE_INSN(DMFC1)1593 DECLARE_INSN(DMFC1)
1594 {
1595    int rt = bits(insn,16,20);
1596    int rd = bits(insn,11,15);
1597 
1598    mips64_emit_cp_xfr_op(b,rt,rd,mips64_exec_dmfc1);
1599    return(0);
1600 }
1601 
1602 /* DMTC0 */
DECLARE_INSN(DMTC0)1603 DECLARE_INSN(DMTC0)
1604 {
1605    int rt = bits(insn,16,20);
1606    int rd = bits(insn,11,15);
1607 
1608    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_dmtc0);
1609    return(0);
1610 }
1611 
1612 /* DMTC1 */
DECLARE_INSN(DMTC1)1613 DECLARE_INSN(DMTC1)
1614 {
1615    int rt = bits(insn,16,20);
1616    int rd = bits(insn,11,15);
1617 
1618    mips64_emit_cp_xfr_op(b,rt,rd,mips64_exec_dmtc1);
1619    return(0);
1620 }
1621 
1622 /* DSLL */
DECLARE_INSN(DSLL)1623 DECLARE_INSN(DSLL)
1624 {
1625    int rt = bits(insn,16,20);
1626    int rd = bits(insn,11,15);
1627    int sa = bits(insn,6,10);
1628 
1629    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
1630    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
1631 
1632    ppc_slwi(b->jit_ptr,ppc_r7,ppc_r5,sa);
1633    if (sa > 0)
1634       ppc_rlwimi(b->jit_ptr,ppc_r7,ppc_r6,sa,32-sa,31);
1635    ppc_slwi(b->jit_ptr,ppc_r8,ppc_r6,sa);
1636 
1637    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1638    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1639    return(0);
1640 }
1641 
1642 /* DSLL32 */
DECLARE_INSN(DSLL32)1643 DECLARE_INSN(DSLL32)
1644 {
1645    int rt = bits(insn,16,20);
1646    int rd = bits(insn,11,15);
1647    int sa = bits(insn,6,10);
1648 
1649    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
1650 
1651    ppc_slwi(b->jit_ptr,ppc_r7,ppc_r6,sa);
1652    ppc_li(b->jit_ptr,ppc_r8,0);
1653 
1654    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1655    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1656    return(0);
1657 }
1658 
1659 /* DSLLV */
DECLARE_INSN(DSLLV)1660 DECLARE_INSN(DSLLV)
1661 {
1662    int rs = bits(insn,21,25);
1663    int rt = bits(insn,16,20);
1664    int rd = bits(insn,11,15);
1665 
1666    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
1667    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
1668    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
1669 
1670    ppc_andid(b->jit_ptr,ppc_r10,ppc_r10,0x3f);
1671 //   ppc_rlwinm(b->jit_ptr,ppc_r10,ppc_r10,0,26,31);
1672    ppc_subfic(b->jit_ptr,ppc_r9,ppc_r10,32);
1673    ppc_slw(b->jit_ptr,ppc_r7,ppc_r5,ppc_r10);
1674    ppc_srw(b->jit_ptr,ppc_r9,ppc_r6,ppc_r9);
1675    ppc_or(b->jit_ptr,ppc_r7,ppc_r7,ppc_r9);
1676    ppc_subi(b->jit_ptr,ppc_r9,ppc_r10,32);
1677    ppc_slw(b->jit_ptr,ppc_r9,ppc_r6,ppc_r9);
1678    ppc_or(b->jit_ptr,ppc_r7,ppc_r7,ppc_r9);
1679    ppc_slw(b->jit_ptr,ppc_r8,ppc_r6,ppc_r10);
1680 
1681    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1682    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1683    return(0);
1684 }
1685 
1686 /* DSRA */
DECLARE_INSN(DSRA)1687 DECLARE_INSN(DSRA)
1688 {
1689    int rt = bits(insn,16,20);
1690    int rd = bits(insn,11,15);
1691    int sa = bits(insn,6,10);
1692 
1693    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
1694    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
1695 
1696    ppc_srawi(b->jit_ptr,ppc_r7,ppc_r5,sa);
1697    ppc_srwi(b->jit_ptr,ppc_r8,ppc_r6,sa);
1698    if (sa > 0)
1699       ppc_rlwimi(b->jit_ptr,ppc_r8,ppc_r5,32-sa,0,sa-1);
1700 
1701    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1702    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1703    return(0);
1704 }
1705 
1706 /* DSRA32 */
DECLARE_INSN(DSRA32)1707 DECLARE_INSN(DSRA32)
1708 {
1709    int rt = bits(insn,16,20);
1710    int rd = bits(insn,11,15);
1711    int sa = bits(insn,6,10);
1712 
1713    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
1714 
1715    ppc_srawi(b->jit_ptr,ppc_r7,ppc_r5,31);
1716    ppc_srawi(b->jit_ptr,ppc_r8,ppc_r5,sa);
1717 
1718    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1719    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1720    return(0);
1721 }
1722 
1723 /* DSRAV */
DECLARE_INSN(DSRAV)1724 DECLARE_INSN(DSRAV)
1725 {
1726    int rs = bits(insn,21,25);
1727    int rt = bits(insn,16,20);
1728    int rd = bits(insn,11,15);
1729    u_char *test1;
1730 
1731    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
1732    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
1733    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
1734 
1735    ppc_andid(b->jit_ptr,ppc_r10,ppc_r10,0x3f);
1736 //   ppc_rlwinm(b->jit_ptr,ppc_r10,ppc_r10,0,26,31);
1737    ppc_subfic(b->jit_ptr,ppc_r9,ppc_r10,32);
1738    ppc_srw(b->jit_ptr,ppc_r8,ppc_r6,ppc_r10);
1739    ppc_slw(b->jit_ptr,ppc_r7,ppc_r5,ppc_r9);
1740    ppc_or(b->jit_ptr,ppc_r8,ppc_r8,ppc_r7);
1741    ppc_subicd(b->jit_ptr,ppc_r9,ppc_r10,32);
1742    ppc_sraw(b->jit_ptr,ppc_r7,ppc_r5,ppc_r9);
1743    test1 = b->jit_ptr;
1744    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr0,PPC_BR_GT),0);
1745 
1746    ppc_mr(b->jit_ptr,ppc_r8,ppc_r7);
1747    ppc_sraw(b->jit_ptr,ppc_r7,ppc_r5,ppc_r10);
1748 
1749    ppc_patch(test1,b->jit_ptr);
1750    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1751    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1752    return(0);
1753 }
1754 
1755 /* DSRL */
DECLARE_INSN(DSRL)1756 DECLARE_INSN(DSRL)
1757 {
1758    int rt = bits(insn,16,20);
1759    int rd = bits(insn,11,15);
1760    int sa = bits(insn,6,10);
1761 
1762    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
1763    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
1764 
1765    ppc_srwi(b->jit_ptr,ppc_r7,ppc_r5,sa);
1766    ppc_srwi(b->jit_ptr,ppc_r8,ppc_r6,sa);
1767    if (sa > 0)
1768       ppc_rlwimi(b->jit_ptr,ppc_r8,ppc_r5,32-sa,0,sa-1);
1769 
1770    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1771    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1772    return(0);
1773 }
1774 
1775 /* DSRL32 */
DECLARE_INSN(DSRL32)1776 DECLARE_INSN(DSRL32)
1777 {
1778    int rt = bits(insn,16,20);
1779    int rd = bits(insn,11,15);
1780    int sa = bits(insn,6,10);
1781 
1782    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
1783 
1784    ppc_li(b->jit_ptr,ppc_r7,0);
1785    ppc_srwi(b->jit_ptr,ppc_r8,ppc_r5,sa);
1786 
1787    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1788    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1789    return(0);
1790 }
1791 
1792 /* DSRLV */
DECLARE_INSN(DSRLV)1793 DECLARE_INSN(DSRLV)
1794 {
1795    int rs = bits(insn,21,25);
1796    int rt = bits(insn,16,20);
1797    int rd = bits(insn,11,15);
1798 
1799    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
1800    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
1801    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
1802 
1803    ppc_andid(b->jit_ptr,ppc_r10,ppc_r10,0x3f);
1804 //   ppc_rlwinm(b->jit_ptr,ppc_r10,ppc_r10,0,26,31);
1805    ppc_subfic(b->jit_ptr,ppc_r9,ppc_r10,32);
1806    ppc_srw(b->jit_ptr,ppc_r8,ppc_r6,ppc_r10);
1807    ppc_slw(b->jit_ptr,ppc_r9,ppc_r5,ppc_r9);
1808    ppc_or(b->jit_ptr,ppc_r8,ppc_r8,ppc_r9);
1809    ppc_subi(b->jit_ptr,ppc_r9,ppc_r10,32);
1810    ppc_srw(b->jit_ptr,ppc_r9,ppc_r5,ppc_r9);
1811    ppc_or(b->jit_ptr,ppc_r8,ppc_r8,ppc_r9);
1812    ppc_srw(b->jit_ptr,ppc_r7,ppc_r5,ppc_r10);
1813 
1814    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1815    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1816    return(0);
1817 }
1818 
1819 /* DSUBU */
DECLARE_INSN(DSUBU)1820 DECLARE_INSN(DSUBU)
1821 {
1822    int rs = bits(insn,21,25);
1823    int rt = bits(insn,16,20);
1824    int rd = bits(insn,11,15);
1825 
1826    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
1827    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
1828    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
1829    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
1830 
1831    ppc_subc(b->jit_ptr,ppc_r10,ppc_r6,ppc_r8);
1832    ppc_subfe(b->jit_ptr,ppc_r9,ppc_r7,ppc_r5);
1833 
1834    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
1835    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rd),ppc_r3);
1836    return(0);
1837 }
1838 
1839 /* ERET */
DECLARE_INSN(ERET)1840 DECLARE_INSN(ERET)
1841 {
1842    /* Restore link register */
1843    ppc_lwz(b->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1);
1844    ppc_mtlr(b->jit_ptr,ppc_r0);
1845    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
1846    /* Trick: let callee return directly to the caller */
1847    ppc_emit_jump_code(b->jit_ptr, (u_char *)mips64_exec_eret, 0);
1848    return(0);
1849 }
1850 
1851 /* J */
DECLARE_INSN(J)1852 DECLARE_INSN(J)
1853 {
1854    u_int instr_index = bits(insn,0,25);
1855    m_uint64_t new_pc;
1856 
1857    /* compute the new pc */
1858    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1859    new_pc &= ~((1 << 28) - 1);
1860    new_pc |= instr_index << 2;
1861 
1862    /* insert the instruction in the delay slot */
1863    mips64_jit_fetch_and_emit(cpu,b,1);
1864 
1865    /* set the new pc in cpu structure */
1866    mips64_set_jump(cpu,b,new_pc,1);
1867    return(0);
1868 }
1869 
1870 /* JAL */
DECLARE_INSN(JAL)1871 DECLARE_INSN(JAL)
1872 {
1873    u_int instr_index = bits(insn,0,25);
1874    m_uint64_t new_pc,ret_pc;
1875 
1876    /* compute the new pc */
1877    new_pc = b->start_pc + (b->mips_trans_pos << 2);
1878    new_pc &= ~((1 << 28) - 1);
1879    new_pc |= instr_index << 2;
1880 
1881    /* set the return address (instruction after the delay slot) */
1882    ret_pc = b->start_pc + ((b->mips_trans_pos + 1) << 2);
1883    mips64_set_ra(b,ret_pc);
1884 
1885    /* insert the instruction in the delay slot */
1886    mips64_jit_fetch_and_emit(cpu,b,1);
1887 
1888    /* set the new pc in cpu structure */
1889    mips64_set_jump(cpu,b,new_pc,0);
1890    return(0);
1891 }
1892 
1893 /* JALR */
DECLARE_INSN(JALR)1894 DECLARE_INSN(JALR)
1895 {
1896    int rs = bits(insn,21,25);
1897    int rd = bits(insn,11,15);
1898    m_uint64_t ret_pc;
1899 
1900    /* set the return pc (instruction after the delay slot) in GPR[rd] */
1901    ret_pc = b->start_pc + ((b->mips_trans_pos + 1) << 2);
1902    ppc_load(b->jit_ptr,ppc_r7,ret_pc >> 32);
1903    ppc_load(b->jit_ptr,ppc_r8,ret_pc & 0xffffffff);
1904    ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3);
1905    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
1906 
1907    /* get the new pc */
1908    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rs),ppc_r3);
1909    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
1910    ppc_stw(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,ret_pc),ppc_r3);
1911    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,ret_pc)+4,ppc_r3);
1912 
1913    /* insert the instruction in the delay slot */
1914    mips64_jit_fetch_and_emit(cpu,b,1);
1915 
1916    /* set the new pc */
1917    ppc_lwz(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,ret_pc),ppc_r3);
1918    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,pc),ppc_r3);
1919    ppc_lwz(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,ret_pc)+4,ppc_r3);
1920    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,pc)+4,ppc_r3);
1921 
1922    /* returns to the caller which will determine the next path */
1923    mips64_jit_tcb_push_epilog(b);
1924    return(0);
1925 }
1926 
1927 /* JR */
DECLARE_INSN(JR)1928 DECLARE_INSN(JR)
1929 {
1930    int rs = bits(insn,21,25);
1931 
1932    /* get the new pc */
1933    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rs),ppc_r3);
1934    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
1935    ppc_stw(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,ret_pc),ppc_r3);
1936    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,ret_pc)+4,ppc_r3);
1937 
1938    /* insert the instruction in the delay slot */
1939    mips64_jit_fetch_and_emit(cpu,b,1);
1940 
1941    /* set the new pc */
1942    ppc_lwz(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,ret_pc),ppc_r3);
1943    ppc_lwz(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,ret_pc)+4,ppc_r3);
1944    ppc_stw(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,pc),ppc_r3);
1945    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,pc)+4,ppc_r3);
1946 
1947    /* returns to the caller which will determine the next path */
1948    mips64_jit_tcb_push_epilog(b);
1949    return(0);
1950 }
1951 
1952 /* LB */
DECLARE_INSN(LB)1953 DECLARE_INSN(LB)
1954 {
1955    int base   = bits(insn,21,25);
1956    int rt     = bits(insn,16,20);
1957    int offset = bits(insn,0,15);
1958 
1959    if (cpu->fast_memop) {
1960       mips64_emit_memop_fast(cpu,b,0,MIPS_MEMOP_LB,base,offset,rt,TRUE,
1961                              mips64_memop_fast_lb);
1962    } else {
1963       mips64_emit_memop(b,MIPS_MEMOP_LB,base,offset,rt,TRUE);
1964    }
1965    return(0);
1966 }
1967 
1968 /* LBU */
DECLARE_INSN(LBU)1969 DECLARE_INSN(LBU)
1970 {
1971    int base   = bits(insn,21,25);
1972    int rt     = bits(insn,16,20);
1973    int offset = bits(insn,0,15);
1974 
1975    if (cpu->fast_memop) {
1976       mips64_emit_memop_fast(cpu,b,0,MIPS_MEMOP_LBU,base,offset,rt,TRUE,
1977                              mips64_memop_fast_lbu);
1978    } else {
1979       mips64_emit_memop(b,MIPS_MEMOP_LBU,base,offset,rt,TRUE);
1980    }
1981    return(0);
1982 }
1983 
1984 /* LD */
DECLARE_INSN(LD)1985 DECLARE_INSN(LD)
1986 {
1987    int base   = bits(insn,21,25);
1988    int rt     = bits(insn,16,20);
1989    int offset = bits(insn,0,15);
1990 
1991    if (cpu->fast_memop) {
1992       mips64_emit_memop_fast(cpu,b,0,MIPS_MEMOP_LD,base,offset,rt,TRUE,
1993                              mips64_memop_fast_ld);
1994    } else {
1995       mips64_emit_memop(b,MIPS_MEMOP_LD,base,offset,rt,TRUE);
1996    }
1997    return(0);
1998 }
1999 
2000 /* LDC1 */
DECLARE_INSN(LDC1)2001 DECLARE_INSN(LDC1)
2002 {
2003    int base   = bits(insn,21,25);
2004    int ft     = bits(insn,16,20);
2005    int offset = bits(insn,0,15);
2006 
2007    mips64_emit_memop(b,MIPS_MEMOP_LDC1,base,offset,ft,TRUE);
2008    return(0);
2009 }
2010 
2011 /* LDL */
DECLARE_INSN(LDL)2012 DECLARE_INSN(LDL)
2013 {
2014    int base   = bits(insn,21,25);
2015    int rt     = bits(insn,16,20);
2016    int offset = bits(insn,0,15);
2017 
2018    mips64_emit_memop(b,MIPS_MEMOP_LDL,base,offset,rt,TRUE);
2019    return(0);
2020 }
2021 
2022 /* LDR */
DECLARE_INSN(LDR)2023 DECLARE_INSN(LDR)
2024 {
2025    int base   = bits(insn,21,25);
2026    int rt     = bits(insn,16,20);
2027    int offset = bits(insn,0,15);
2028 
2029    mips64_emit_memop(b,MIPS_MEMOP_LDR,base,offset,rt,TRUE);
2030    return(0);
2031 }
2032 
2033 /* LH */
DECLARE_INSN(LH)2034 DECLARE_INSN(LH)
2035 {
2036    int base   = bits(insn,21,25);
2037    int rt     = bits(insn,16,20);
2038    int offset = bits(insn,0,15);
2039 
2040    if (cpu->fast_memop) {
2041       mips64_emit_memop_fast(cpu,b,0,MIPS_MEMOP_LH,base,offset,rt,TRUE,
2042                              mips64_memop_fast_lh);
2043    } else {
2044       mips64_emit_memop(b,MIPS_MEMOP_LH,base,offset,rt,TRUE);
2045    }
2046    return(0);
2047 }
2048 
2049 /* LHU */
DECLARE_INSN(LHU)2050 DECLARE_INSN(LHU)
2051 {
2052    int base   = bits(insn,21,25);
2053    int rt     = bits(insn,16,20);
2054    int offset = bits(insn,0,15);
2055 
2056    if (cpu->fast_memop) {
2057       mips64_emit_memop_fast(cpu,b,0,MIPS_MEMOP_LHU,base,offset,rt,TRUE,
2058                              mips64_memop_fast_lhu);
2059    } else {
2060       mips64_emit_memop(b,MIPS_MEMOP_LHU,base,offset,rt,TRUE);
2061    }
2062    return(0);
2063 }
2064 
2065 /* LI (virtual) */
DECLARE_INSN(LI)2066 DECLARE_INSN(LI)
2067 {
2068    int rt  = bits(insn,16,20);
2069    int imm = bits(insn,0,15);
2070 
2071    ppc_li(b->jit_ptr,ppc_r9,imm);
2072    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
2073    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r9,31);
2074    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rt),ppc_r3);
2075    return(0);
2076 }
2077 
2078 /* LL */
DECLARE_INSN(LL)2079 DECLARE_INSN(LL)
2080 {
2081    int base   = bits(insn,21,25);
2082    int rt     = bits(insn,16,20);
2083    int offset = bits(insn,0,15);
2084 
2085    mips64_emit_memop(b,MIPS_MEMOP_LL,base,offset,rt,TRUE);
2086    return(0);
2087 }
2088 
2089 /* LUI */
DECLARE_INSN(LUI)2090 DECLARE_INSN(LUI)
2091 {
2092    int rt  = bits(insn,16,20);
2093    int imm = bits(insn,0,15);
2094 
2095    ppc_lis(b->jit_ptr,ppc_r10,imm);
2096    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rt)+4,ppc_r3);
2097    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
2098    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rt),ppc_r3);
2099    return(0);
2100 }
2101 
2102 /* LW */
DECLARE_INSN(LW)2103 DECLARE_INSN(LW)
2104 {
2105    int base   = bits(insn,21,25);
2106    int rt     = bits(insn,16,20);
2107    int offset = bits(insn,0,15);
2108 
2109    if (cpu->fast_memop) {
2110       mips64_emit_memop_fast(cpu,b,0,MIPS_MEMOP_LW,base,offset,rt,TRUE,
2111                              mips64_memop_fast_lw);
2112    } else {
2113       mips64_emit_memop(b,MIPS_MEMOP_LW,base,offset,rt,TRUE);
2114    }
2115    return(0);
2116 }
2117 
2118 /* LWL */
DECLARE_INSN(LWL)2119 DECLARE_INSN(LWL)
2120 {
2121    int base   = bits(insn,21,25);
2122    int rt     = bits(insn,16,20);
2123    int offset = bits(insn,0,15);
2124 
2125    mips64_emit_memop(b,MIPS_MEMOP_LWL,base,offset,rt,TRUE);
2126    return(0);
2127 }
2128 
2129 /* LWR */
DECLARE_INSN(LWR)2130 DECLARE_INSN(LWR)
2131 {
2132    int base   = bits(insn,21,25);
2133    int rt     = bits(insn,16,20);
2134    int offset = bits(insn,0,15);
2135 
2136    mips64_emit_memop(b,MIPS_MEMOP_LWR,base,offset,rt,TRUE);
2137    return(0);
2138 }
2139 
2140 /* LWU */
DECLARE_INSN(LWU)2141 DECLARE_INSN(LWU)
2142 {
2143    int base   = bits(insn,21,25);
2144    int rt     = bits(insn,16,20);
2145    int offset = bits(insn,0,15);
2146 
2147    if (cpu->fast_memop) {
2148       mips64_emit_memop_fast(cpu,b,0,MIPS_MEMOP_LWU,base,offset,rt,TRUE,
2149                              mips64_memop_fast_lwu);
2150    } else {
2151       mips64_emit_memop(b,MIPS_MEMOP_LWU,base,offset,rt,TRUE);
2152    }
2153    return(0);
2154 }
2155 
2156 /* MFC0 */
DECLARE_INSN(MFC0)2157 DECLARE_INSN(MFC0)
2158 {
2159    int rt = bits(insn,16,20);
2160    int rd = bits(insn,11,15);
2161 
2162    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_mfc0);
2163    return(0);
2164 }
2165 
2166 /* MFC1 */
DECLARE_INSN(MFC1)2167 DECLARE_INSN(MFC1)
2168 {
2169    int rt = bits(insn,16,20);
2170    int rd = bits(insn,11,15);
2171 
2172    mips64_emit_cp_xfr_op(b,rt,rd,mips64_exec_mfc1);
2173    return(0);
2174 }
2175 
2176 /* MFHI */
DECLARE_INSN(MFHI)2177 DECLARE_INSN(MFHI)
2178 {
2179    int rd = bits(insn,11,15);
2180 
2181    ppc_lwz(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,hi),ppc_r3);
2182    ppc_lwz(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,hi)+4,ppc_r3);
2183    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rd),ppc_r3);
2184    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2185    return(0);
2186 }
2187 
2188 /* MFLO */
DECLARE_INSN(MFLO)2189 DECLARE_INSN(MFLO)
2190 {
2191    int rd = bits(insn,11,15);
2192 
2193    /* Optimization for "mflo zr" */
2194    if (!rd) return(0);
2195 
2196    ppc_lwz(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,lo),ppc_r3);
2197    ppc_lwz(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,lo)+4,ppc_r3);
2198    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rd),ppc_r3);
2199    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2200    return(0);
2201 }
2202 
2203 /* MOVE (virtual) */
DECLARE_INSN(MOVE)2204 DECLARE_INSN(MOVE)
2205 {
2206    int rs = bits(insn,21,25);
2207    int rd = bits(insn,11,15);
2208 
2209    if (rs != 0) {
2210       ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
2211       ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
2212       ppc_srawi(b->jit_ptr,ppc_r0,ppc_r8,31);
2213       ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2214    } else {
2215       ppc_li(b->jit_ptr,ppc_r0,0);
2216       ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd)+4,ppc_r3);
2217       ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2218    }
2219    return(0);
2220 }
2221 
2222 /* MTC0 */
DECLARE_INSN(MTC0)2223 DECLARE_INSN(MTC0)
2224 {
2225    int rt = bits(insn,16,20);
2226    int rd = bits(insn,11,15);
2227 
2228    mips64_emit_cp_xfr_op(b,rt,rd,mips64_cp0_exec_mtc0);
2229    return(0);
2230 }
2231 
2232 /* MTC1 */
DECLARE_INSN(MTC1)2233 DECLARE_INSN(MTC1)
2234 {
2235    int rt = bits(insn,16,20);
2236    int rd = bits(insn,11,15);
2237 
2238    mips64_emit_cp_xfr_op(b,rt,rd,mips64_exec_mtc1);
2239    return(0);
2240 }
2241 
2242 /* MTHI */
DECLARE_INSN(MTHI)2243 DECLARE_INSN(MTHI)
2244 {
2245    int rs = bits(insn,21,25);
2246 
2247    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rs),ppc_r3);
2248    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
2249    ppc_stw(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,hi),ppc_r3);
2250    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,hi)+4,ppc_r3);
2251    return(0);
2252 }
2253 
2254 /* MTLO */
DECLARE_INSN(MTLO)2255 DECLARE_INSN(MTLO)
2256 {
2257    int rs = bits(insn,21,25);
2258 
2259    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rs),ppc_r3);
2260    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
2261    ppc_stw(b->jit_ptr,ppc_r9,OFFSET(cpu_mips_t,lo),ppc_r3);
2262    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,lo)+4,ppc_r3);
2263    return(0);
2264 }
2265 
2266 /* MUL */
DECLARE_INSN(MUL)2267 DECLARE_INSN(MUL)
2268 {
2269    int rs = bits(insn,21,25);
2270    int rt = bits(insn,16,20);
2271    int rd = bits(insn,11,15);
2272 
2273    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
2274    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
2275    ppc_mullw(b->jit_ptr,ppc_r10,ppc_r8,ppc_r9);
2276 
2277    /* store result in gpr[rd] */
2278    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2279    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
2280    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2281    return(0);
2282 }
2283 
2284 /* MULT */
DECLARE_INSN(MULT)2285 DECLARE_INSN(MULT)
2286 {
2287    int rs = bits(insn,21,25);
2288    int rt = bits(insn,16,20);
2289 
2290    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
2291    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
2292 
2293    ppc_mullw(b->jit_ptr,ppc_r10,ppc_r8,ppc_r9);
2294    /* store LO */
2295    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,lo)+4,ppc_r3);
2296    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
2297    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,lo),ppc_r3);
2298 
2299    ppc_mulhw(b->jit_ptr,ppc_r10,ppc_r8,ppc_r9);
2300    /* store HI */
2301    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,hi)+4,ppc_r3);
2302    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
2303    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,hi),ppc_r3);
2304    return(0);
2305 }
2306 
2307 /* MULTU */
DECLARE_INSN(MULTU)2308 DECLARE_INSN(MULTU)
2309 {
2310    int rs = bits(insn,21,25);
2311    int rt = bits(insn,16,20);
2312 
2313    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
2314    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
2315 
2316    ppc_mullw(b->jit_ptr,ppc_r10,ppc_r8,ppc_r9);
2317    /* store LO */
2318    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,lo)+4,ppc_r3);
2319    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
2320    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,lo),ppc_r3);
2321 
2322    ppc_mulhwu(b->jit_ptr,ppc_r10,ppc_r8,ppc_r9);
2323    /* store HI */
2324    ppc_stw(b->jit_ptr,ppc_r10,OFFSET(cpu_mips_t,hi)+4,ppc_r3);
2325    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
2326    ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,hi),ppc_r3);
2327    return(0);
2328 }
2329 
2330 /* NOP */
DECLARE_INSN(NOP)2331 DECLARE_INSN(NOP)
2332 {
2333    return(0);
2334 }
2335 
2336 /* NOR */
DECLARE_INSN(NOR)2337 DECLARE_INSN(NOR)
2338 {
2339    int rs = bits(insn,21,25);
2340    int rt = bits(insn,16,20);
2341    int rd = bits(insn,11,15);
2342 
2343    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2344    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
2345    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2346    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
2347 
2348    ppc_nor(b->jit_ptr,ppc_r9,ppc_r5,ppc_r7);
2349    ppc_nor(b->jit_ptr,ppc_r10,ppc_r6,ppc_r8);
2350 
2351    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rd),ppc_r3);
2352    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2353    return(0);
2354 }
2355 
2356 /* OR */
DECLARE_INSN(OR)2357 DECLARE_INSN(OR)
2358 {
2359    int rs = bits(insn,21,25);
2360    int rt = bits(insn,16,20);
2361    int rd = bits(insn,11,15);
2362 
2363    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2364    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
2365    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2366    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
2367 
2368    ppc_or(b->jit_ptr,ppc_r9,ppc_r5,ppc_r7);
2369    ppc_or(b->jit_ptr,ppc_r10,ppc_r6,ppc_r8);
2370 
2371    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rd),ppc_r3);
2372    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2373    return(0);
2374 }
2375 
2376 /* ORI */
DECLARE_INSN(ORI)2377 DECLARE_INSN(ORI)
2378 {
2379    int rs  = bits(insn,21,25);
2380    int rt  = bits(insn,16,20);
2381    int imm = bits(insn,0,15);
2382 
2383    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2384    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2385 
2386    ppc_ori(b->jit_ptr,ppc_r8,ppc_r6,imm);
2387 
2388    ppc_stw(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
2389    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
2390    return(0);
2391 }
2392 
2393 /* PREF */
DECLARE_INSN(PREF)2394 DECLARE_INSN(PREF)
2395 {
2396 /*   int base   = bits(insn,21,25);
2397    int hint   = bits(insn,16,20);
2398    int offset = bits(insn,0,15);
2399 */
2400    return(0);
2401 }
2402 
2403 /* PREFX */
DECLARE_INSN(PREFX)2404 DECLARE_INSN(PREFX)
2405 {
2406 /*   int base   = bits(insn,21,25);
2407    int index  = bits(insn,16,20);
2408    int hint   = bits(insn,11,15);
2409 */
2410    return(0);
2411 }
2412 
2413 /* SB */
DECLARE_INSN(SB)2414 DECLARE_INSN(SB)
2415 {
2416    int base   = bits(insn,21,25);
2417    int rt     = bits(insn,16,20);
2418    int offset = bits(insn,0,15);
2419 
2420    if (cpu->fast_memop) {
2421       mips64_emit_memop_fast(cpu,b,1,MIPS_MEMOP_SB,base,offset,rt,FALSE,
2422                              mips64_memop_fast_sb);
2423    } else {
2424       mips64_emit_memop(b,MIPS_MEMOP_SB,base,offset,rt,FALSE);
2425    }
2426    return(0);
2427 }
2428 
2429 /* SC */
DECLARE_INSN(SC)2430 DECLARE_INSN(SC)
2431 {
2432    int base   = bits(insn,21,25);
2433    int rt     = bits(insn,16,20);
2434    int offset = bits(insn,0,15);
2435 
2436    mips64_emit_memop(b,MIPS_MEMOP_SC,base,offset,rt,TRUE);
2437    return(0);
2438 }
2439 
2440 /* SD */
DECLARE_INSN(SD)2441 DECLARE_INSN(SD)
2442 {
2443    int base   = bits(insn,21,25);
2444    int rt     = bits(insn,16,20);
2445    int offset = bits(insn,0,15);
2446 
2447    if (cpu->fast_memop) {
2448       mips64_emit_memop_fast(cpu,b,1,MIPS_MEMOP_SD,base,offset,rt,FALSE,
2449                              mips64_memop_fast_sd);
2450    } else {
2451       mips64_emit_memop(b,MIPS_MEMOP_SD,base,offset,rt,FALSE);
2452    }
2453    return(0);
2454 }
2455 
2456 /* SDL */
DECLARE_INSN(SDL)2457 DECLARE_INSN(SDL)
2458 {
2459    int base   = bits(insn,21,25);
2460    int rt     = bits(insn,16,20);
2461    int offset = bits(insn,0,15);
2462 
2463    mips64_emit_memop(b,MIPS_MEMOP_SDL,base,offset,rt,FALSE);
2464    return(0);
2465 }
2466 
2467 /* SDR */
DECLARE_INSN(SDR)2468 DECLARE_INSN(SDR)
2469 {
2470    int base   = bits(insn,21,25);
2471    int rt     = bits(insn,16,20);
2472    int offset = bits(insn,0,15);
2473 
2474    mips64_emit_memop(b,MIPS_MEMOP_SDR,base,offset,rt,FALSE);
2475    return(0);
2476 }
2477 
2478 /* SDC1 */
DECLARE_INSN(SDC1)2479 DECLARE_INSN(SDC1)
2480 {
2481    int base   = bits(insn,21,25);
2482    int ft     = bits(insn,16,20);
2483    int offset = bits(insn,0,15);
2484 
2485    mips64_emit_memop(b,MIPS_MEMOP_SDC1,base,offset,ft,FALSE);
2486    return(0);
2487 }
2488 
2489 /* SH */
DECLARE_INSN(SH)2490 DECLARE_INSN(SH)
2491 {
2492    int base   = bits(insn,21,25);
2493    int rt     = bits(insn,16,20);
2494    int offset = bits(insn,0,15);
2495 
2496    if (cpu->fast_memop) {
2497       mips64_emit_memop_fast(cpu,b,1,MIPS_MEMOP_SH,base,offset,rt,FALSE,
2498                              mips64_memop_fast_sh);
2499    } else {
2500       mips64_emit_memop(b,MIPS_MEMOP_SH,base,offset,rt,FALSE);
2501    }
2502    return(0);
2503 }
2504 
2505 /* SLL */
DECLARE_INSN(SLL)2506 DECLARE_INSN(SLL)
2507 {
2508    int rt = bits(insn,16,20);
2509    int rd = bits(insn,11,15);
2510    int sa = bits(insn,6,10);
2511    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
2512 
2513    ppc_slwi(b->jit_ptr,ppc_r8,ppc_r6,sa);
2514 
2515    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
2516    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r8,31);
2517    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2518    return(0);
2519 }
2520 
2521 /* SLLV */
DECLARE_INSN(SLLV)2522 DECLARE_INSN(SLLV)
2523 {
2524    int rs = bits(insn,21,25);
2525    int rt = bits(insn,16,20);
2526    int rd = bits(insn,11,15);
2527 
2528    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
2529    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
2530 
2531    ppc_andid(b->jit_ptr,ppc_r10,ppc_r10,0x1f);
2532 //   ppc_rlwinm(b->jit_ptr,ppc_r10,ppc_r10,0,27,31);
2533    ppc_slw(b->jit_ptr,ppc_r8,ppc_r6,ppc_r10);
2534 
2535    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
2536    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r8,31);
2537    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2538    return(0);
2539 }
2540 
2541 /* SLT */
DECLARE_INSN(SLT)2542 DECLARE_INSN(SLT)
2543 {
2544    int rs = bits(insn,21,25);
2545    int rt = bits(insn,16,20);
2546    int rd = bits(insn,11,15);
2547 
2548    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2549    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
2550    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2551    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
2552 
2553    ppc_subc(b->jit_ptr,ppc_r0,ppc_r6,ppc_r8);
2554    ppc_subfe(b->jit_ptr,ppc_r0,ppc_r7,ppc_r5);
2555    ppc_eqv(b->jit_ptr,ppc_r0,ppc_r7,ppc_r5);
2556    ppc_srwi(b->jit_ptr,ppc_r0,ppc_r0,31);
2557    ppc_addze(b->jit_ptr,ppc_r0,ppc_r0);
2558    ppc_andid(b->jit_ptr,ppc_r10,ppc_r0,0x1);
2559    //ppc_rlwinm(b->jit_ptr,ppc_r10,ppc_r0,0,31,31);
2560 
2561    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2562    ppc_li(b->jit_ptr,ppc_r0,0);
2563    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2564    return(0);
2565 }
2566 
2567 /* SLTI */
DECLARE_INSN(SLTI)2568 DECLARE_INSN(SLTI)
2569 {
2570    int rs = bits(insn,21,25);
2571    int rt = bits(insn,16,20);
2572    int imm = bits(insn,0,15);
2573 
2574    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2575    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2576 
2577    ppc_subic(b->jit_ptr,ppc_r0,ppc_r6,imm);
2578    if (imm  & 0x8000 /* < 0 */) {
2579       ppc_addze(b->jit_ptr,ppc_r0,ppc_r5);
2580       ppc_srwi(b->jit_ptr,ppc_r0,ppc_r5,31);
2581    } else {
2582       ppc_addme(b->jit_ptr,ppc_r0,ppc_r5);
2583       ppc_srwi(b->jit_ptr,ppc_r0,ppc_r5,31);
2584       ppc_xori(b->jit_ptr,ppc_r0,ppc_r0,0x1);
2585    }
2586    ppc_addze(b->jit_ptr,ppc_r0,ppc_r0);
2587    ppc_andid(b->jit_ptr,ppc_r10,ppc_r0,0x1);
2588    //ppc_rlwinm(b->jit_ptr,ppc_r10,ppc_r0,0,31,31);
2589 
2590    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rt)+4,ppc_r3);
2591    ppc_li(b->jit_ptr,ppc_r0,0);
2592    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rt),ppc_r3);
2593    return(0);
2594 }
2595 
2596 /* SLTIU */
DECLARE_INSN(SLTIU)2597 DECLARE_INSN(SLTIU)
2598 {
2599    int rs = bits(insn,21,25);
2600    int rt = bits(insn,16,20);
2601    int imm = bits(insn,0,15);
2602 
2603    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2604    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2605 
2606    ppc_subic(b->jit_ptr,ppc_r0,ppc_r6,imm);
2607    if (imm  & 0x8000 /* < 0 */)
2608       ppc_addze(b->jit_ptr,ppc_r0,ppc_r5);
2609    else
2610       ppc_addme(b->jit_ptr,ppc_r0,ppc_r5);
2611    ppc_subfe(b->jit_ptr,ppc_r0,ppc_r0,ppc_r0);
2612    ppc_neg(b->jit_ptr,ppc_r10,ppc_r0);
2613 
2614    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rt)+4,ppc_r3);
2615    ppc_li(b->jit_ptr,ppc_r0,0);
2616    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rt),ppc_r3);
2617    return(0);
2618 }
2619 
2620 /* SLTU */
DECLARE_INSN(SLTU)2621 DECLARE_INSN(SLTU)
2622 {
2623    int rs = bits(insn,21,25);
2624    int rt = bits(insn,16,20);
2625    int rd = bits(insn,11,15);
2626 
2627    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2628    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
2629    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2630    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
2631 
2632    ppc_subc(b->jit_ptr,ppc_r0,ppc_r6,ppc_r8);
2633    ppc_subfe(b->jit_ptr,ppc_r0,ppc_r7,ppc_r5);
2634    ppc_subfe(b->jit_ptr,ppc_r0,ppc_r0,ppc_r0);
2635    ppc_neg(b->jit_ptr,ppc_r10,ppc_r0);
2636 
2637    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2638    ppc_li(b->jit_ptr,ppc_r0,0);
2639    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2640    return(0);
2641 }
2642 
2643 /* SRA */
DECLARE_INSN(SRA)2644 DECLARE_INSN(SRA)
2645 {
2646    int rt = bits(insn,16,20);
2647    int rd = bits(insn,11,15);
2648    int sa = bits(insn,6,10);
2649 
2650    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
2651 
2652    ppc_srawi(b->jit_ptr,ppc_r8,ppc_r6,sa);
2653 
2654    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
2655    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r8,31);
2656    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2657    return(0);
2658 }
2659 
2660 /* SRAV */
DECLARE_INSN(SRAV)2661 DECLARE_INSN(SRAV)
2662 {
2663    int rs = bits(insn,21,25);
2664    int rt = bits(insn,16,20);
2665    int rd = bits(insn,11,15);
2666 
2667    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
2668    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
2669 
2670    ppc_andid(b->jit_ptr,ppc_r10,ppc_r10,0x1f);
2671 //   ppc_rlwinm(b->jit_ptr,ppc_r10,ppc_r10,0,27,31);
2672    ppc_sraw(b->jit_ptr,ppc_r8,ppc_r6,ppc_r10);
2673 
2674    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
2675    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r8,31);
2676    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2677    return(0);
2678 }
2679 
2680 /* SRL */
DECLARE_INSN(SRL)2681 DECLARE_INSN(SRL)
2682 {
2683    int rt = bits(insn,16,20);
2684    int rd = bits(insn,11,15);
2685    int sa = bits(insn,6,10);
2686 
2687    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
2688 
2689    ppc_srwi(b->jit_ptr,ppc_r8,ppc_r6,sa);
2690 
2691    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
2692    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r8,31);
2693    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2694    return(0);
2695 }
2696 
2697 /* SRLV */
DECLARE_INSN(SRLV)2698 DECLARE_INSN(SRLV)
2699 {
2700    int rs = bits(insn,21,25);
2701    int rt = bits(insn,16,20);
2702    int rd = bits(insn,11,15);
2703 
2704    ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(rs)+4,ppc_r3);
2705    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rt)+4,ppc_r3);
2706 
2707    ppc_andid(b->jit_ptr,ppc_r10,ppc_r10,0x1f);
2708 //   ppc_rlwinm(b->jit_ptr,ppc_r10,ppc_r10,0,27,31);
2709    ppc_srw(b->jit_ptr,ppc_r8,ppc_r6,ppc_r10);
2710 
2711    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rd)+4,ppc_r3);
2712    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r8,31);
2713    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2714    return(0);
2715 }
2716 
2717 /* SUB */
DECLARE_INSN(SUB)2718 DECLARE_INSN(SUB)
2719 {
2720    int rs = bits(insn,21,25);
2721    int rt = bits(insn,16,20);
2722    int rd = bits(insn,11,15);
2723 
2724    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
2725    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
2726    ppc_subfo(b->jit_ptr,ppc_r10,ppc_r9,ppc_r8);
2727 
2728    /* TODO: Exception handling */
2729 
2730    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2731    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
2732    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2733    return(0);
2734 }
2735 
2736 /* SUBU */
DECLARE_INSN(SUBU)2737 DECLARE_INSN(SUBU)
2738 {
2739    int rs = bits(insn,21,25);
2740    int rt = bits(insn,16,20);
2741    int rd = bits(insn,11,15);
2742 
2743    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rs)+4,ppc_r3);
2744    ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(rt)+4,ppc_r3);
2745    ppc_sub(b->jit_ptr,ppc_r10,ppc_r8,ppc_r9);
2746 
2747    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2748    ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31);
2749    ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(rd),ppc_r3);
2750    return(0);
2751 }
2752 
2753 /* SW */
DECLARE_INSN(SW)2754 DECLARE_INSN(SW)
2755 {
2756    int base   = bits(insn,21,25);
2757    int rt     = bits(insn,16,20);
2758    int offset = bits(insn,0,15);
2759 
2760    if (cpu->fast_memop) {
2761       mips64_emit_memop_fast(cpu,b,1,MIPS_MEMOP_SW,base,offset,rt,FALSE,
2762                              mips64_memop_fast_sw);
2763    } else {
2764       mips64_emit_memop(b,MIPS_MEMOP_SW,base,offset,rt,FALSE);
2765    }
2766    return(0);
2767 }
2768 
2769 /* SWL */
DECLARE_INSN(SWL)2770 DECLARE_INSN(SWL)
2771 {
2772    int base   = bits(insn,21,25);
2773    int rt     = bits(insn,16,20);
2774    int offset = bits(insn,0,15);
2775 
2776    mips64_emit_memop(b,MIPS_MEMOP_SWL,base,offset,rt,FALSE);
2777    return(0);
2778 }
2779 
2780 /* SWR */
DECLARE_INSN(SWR)2781 DECLARE_INSN(SWR)
2782 {
2783    int base   = bits(insn,21,25);
2784    int rt     = bits(insn,16,20);
2785    int offset = bits(insn,0,15);
2786 
2787    mips64_emit_memop(b,MIPS_MEMOP_SWR,base,offset,rt,FALSE);
2788    return(0);
2789 }
2790 
2791 /* SYNC */
DECLARE_INSN(SYNC)2792 DECLARE_INSN(SYNC)
2793 {
2794    return(0);
2795 }
2796 
2797 /* SYSCALL */
DECLARE_INSN(SYSCALL)2798 DECLARE_INSN(SYSCALL)
2799 {
2800    /* Restore link register */
2801    ppc_lwz(b->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1);
2802    ppc_mtlr(b->jit_ptr,ppc_r0);
2803    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
2804    /* Trick: let callee return directly to the caller */
2805    ppc_emit_jump_code(b->jit_ptr, (u_char *)mips64_exec_syscall, 0);
2806    return(0);
2807 }
2808 
2809 /* TEQ */
DECLARE_INSN(TEQ)2810 DECLARE_INSN(TEQ)
2811 {
2812    int rs = bits(insn,21,25);
2813    int rt = bits(insn,16,20);
2814    u_char *test1,*test2;
2815 
2816    /* Compare low part */
2817    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2818    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
2819    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r6,ppc_r8);
2820    test1 = b->jit_ptr;
2821    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
2822 
2823    /* Compare high part */
2824    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2825    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
2826    ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r5,ppc_r7);
2827    test2 = b->jit_ptr;
2828    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
2829 
2830    /* Generate trap exception */
2831    mips64_emit_c_call(b,mips64_trigger_trap_exception);
2832    mips64_jit_tcb_push_epilog(b);
2833 
2834    /* end */
2835    ppc_patch(test1,b->jit_ptr);
2836    ppc_patch(test2,b->jit_ptr);
2837    return(0);
2838 }
2839 
2840 /* TEQI (Trap If Equal Immediate) */
DECLARE_INSN(TEQI)2841 DECLARE_INSN(TEQI)
2842 {
2843    int rs  = bits(insn,21,25);
2844    int imm = bits(insn,0,15);
2845    u_char *test1,*test2;
2846 
2847    /* Compare low part */
2848    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2849    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r6,imm);
2850    test1 = b->jit_ptr;
2851    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
2852 
2853    /* Compare high part */
2854    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2855    ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,(imm << 16) >> 31);
2856    test2 = b->jit_ptr;
2857    ppc_bc(b->jit_ptr,PPC_BR_FALSE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0);
2858 
2859    /* Generate trap exception */
2860    mips64_emit_c_call(b,mips64_trigger_trap_exception);
2861    mips64_jit_tcb_push_epilog(b);
2862 
2863    /* end */
2864    ppc_patch(test1,b->jit_ptr);
2865    ppc_patch(test2,b->jit_ptr);
2866    return(0);
2867 }
2868 
2869 /* TLBP */
DECLARE_INSN(TLBP)2870 DECLARE_INSN(TLBP)
2871 {
2872    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
2873    mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbp);
2874    return(0);
2875 }
2876 
2877 /* TLBR */
DECLARE_INSN(TLBR)2878 DECLARE_INSN(TLBR)
2879 {
2880    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
2881    mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbr);
2882    return(0);
2883 }
2884 
2885 /* TLBWI */
DECLARE_INSN(TLBWI)2886 DECLARE_INSN(TLBWI)
2887 {
2888    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
2889    mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbwi);
2890    return(0);
2891 }
2892 
2893 /* TLBWR */
DECLARE_INSN(TLBWR)2894 DECLARE_INSN(TLBWR)
2895 {
2896    mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2));
2897    mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbwr);
2898    return(0);
2899 }
2900 
2901 /* XOR */
DECLARE_INSN(XOR)2902 DECLARE_INSN(XOR)
2903 {
2904    int rs = bits(insn,21,25);
2905    int rt = bits(insn,16,20);
2906    int rd = bits(insn,11,15);
2907 
2908    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2909    ppc_lwz(b->jit_ptr,ppc_r7,REG_OFFSET(rt),ppc_r3);
2910    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2911    ppc_lwz(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
2912 
2913    ppc_xor(b->jit_ptr,ppc_r9,ppc_r5,ppc_r7);
2914    ppc_xor(b->jit_ptr,ppc_r10,ppc_r6,ppc_r8);
2915 
2916    ppc_stw(b->jit_ptr,ppc_r9,REG_OFFSET(rd),ppc_r3);
2917    ppc_stw(b->jit_ptr,ppc_r10,REG_OFFSET(rd)+4,ppc_r3);
2918 
2919    return(0);
2920 }
2921 
2922 /* XORI */
DECLARE_INSN(XORI)2923 DECLARE_INSN(XORI)
2924 {
2925    int rs  = bits(insn,21,25);
2926    int rt  = bits(insn,16,20);
2927    int imm = bits(insn,0,15);
2928 
2929    ppc_lwz(b->jit_ptr,ppc_r6,REG_OFFSET(rs)+4,ppc_r3);
2930    ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3);
2931 
2932    ppc_xori(b->jit_ptr,ppc_r8,ppc_r6,imm);
2933 
2934    ppc_stw(b->jit_ptr,ppc_r5,REG_OFFSET(rt),ppc_r3);
2935    ppc_stw(b->jit_ptr,ppc_r8,REG_OFFSET(rt)+4,ppc_r3);
2936 
2937    return(0);
2938 }
2939 
2940 /* MIPS instruction array */
2941 struct mips64_insn_tag mips64_insn_tags[] = {
2942    { mips64_emit_LI      , 0xffe00000 , 0x24000000, 1 },   /* virtual */
2943    { mips64_emit_MOVE    , 0xfc1f07ff , 0x00000021, 1 },   /* virtual */
2944    { mips64_emit_B       , 0xffff0000 , 0x10000000, 0 },   /* virtual */
2945    { mips64_emit_BAL     , 0xffff0000 , 0x04110000, 0 },   /* virtual */
2946    { mips64_emit_BEQZ    , 0xfc1f0000 , 0x10000000, 0 },   /* virtual */
2947    { mips64_emit_BNEZ    , 0xfc1f0000 , 0x14000000, 0 },   /* virtual */
2948    { mips64_emit_ADD     , 0xfc0007ff , 0x00000020, 1 },
2949    { mips64_emit_ADDI    , 0xfc000000 , 0x20000000, 1 },
2950    { mips64_emit_ADDIU   , 0xfc000000 , 0x24000000, 1 },
2951    { mips64_emit_ADDU    , 0xfc0007ff , 0x00000021, 1 },
2952    { mips64_emit_AND     , 0xfc0007ff , 0x00000024, 1 },
2953    { mips64_emit_ANDI    , 0xfc000000 , 0x30000000, 1 },
2954    { mips64_emit_BEQ     , 0xfc000000 , 0x10000000, 0 },
2955    { mips64_emit_BEQL    , 0xfc000000 , 0x50000000, 0 },
2956    { mips64_emit_BGEZ    , 0xfc1f0000 , 0x04010000, 0 },
2957    { mips64_emit_BGEZAL  , 0xfc1f0000 , 0x04110000, 0 },
2958    { mips64_emit_BGEZALL , 0xfc1f0000 , 0x04130000, 0 },
2959    { mips64_emit_BGEZL   , 0xfc1f0000 , 0x04030000, 0 },
2960    { mips64_emit_BGTZ    , 0xfc1f0000 , 0x1c000000, 0 },
2961    { mips64_emit_BGTZL   , 0xfc1f0000 , 0x5c000000, 0 },
2962    { mips64_emit_BLEZ    , 0xfc1f0000 , 0x18000000, 0 },
2963    { mips64_emit_BLEZL   , 0xfc1f0000 , 0x58000000, 0 },
2964    { mips64_emit_BLTZ    , 0xfc1f0000 , 0x04000000, 0 },
2965    { mips64_emit_BLTZAL  , 0xfc1f0000 , 0x04100000, 0 },
2966    { mips64_emit_BLTZALL , 0xfc1f0000 , 0x04120000, 0 },
2967    { mips64_emit_BLTZL   , 0xfc1f0000 , 0x04020000, 0 },
2968    { mips64_emit_BNE     , 0xfc000000 , 0x14000000, 0 },
2969    { mips64_emit_BNEL    , 0xfc000000 , 0x54000000, 0 },
2970    { mips64_emit_BREAK   , 0xfc00003f , 0x0000000d, 1 },
2971    { mips64_emit_CACHE   , 0xfc000000 , 0xbc000000, 1 },
2972    { mips64_emit_CFC0    , 0xffe007ff , 0x40400000, 1 },
2973    { mips64_emit_CTC0    , 0xffe007ff , 0x40600000, 1 },
2974    { mips64_emit_DADDIU  , 0xfc000000 , 0x64000000, 1 },
2975    { mips64_emit_DADDU   , 0xfc0007ff , 0x0000002d, 1 },
2976    { mips64_emit_DIV     , 0xfc00ffff , 0x0000001a, 1 },
2977    { mips64_emit_DIVU    , 0xfc00ffff , 0x0000001b, 1 },
2978    { mips64_emit_DMFC0   , 0xffe007f8 , 0x40200000, 1 },
2979    { mips64_emit_DMFC1   , 0xffe007ff , 0x44200000, 1 },
2980    { mips64_emit_DMTC0   , 0xffe007f8 , 0x40a00000, 1 },
2981    { mips64_emit_DMTC1   , 0xffe007ff , 0x44a00000, 1 },
2982    { mips64_emit_DSLL    , 0xffe0003f , 0x00000038, 1 },
2983    { mips64_emit_DSLL32  , 0xffe0003f , 0x0000003c, 1 },
2984    { mips64_emit_DSLLV   , 0xfc0007ff , 0x00000014, 1 },
2985    { mips64_emit_DSRA    , 0xffe0003f , 0x0000003b, 1 },
2986    { mips64_emit_DSRA32  , 0xffe0003f , 0x0000003f, 1 },
2987    { mips64_emit_DSRAV   , 0xfc0007ff , 0x00000017, 1 },
2988    { mips64_emit_DSRL    , 0xffe0003f , 0x0000003a, 1 },
2989    { mips64_emit_DSRL32  , 0xffe0003f , 0x0000003e, 1 },
2990    { mips64_emit_DSRLV   , 0xfc0007ff , 0x00000016, 1 },
2991    { mips64_emit_DSUBU   , 0xfc0007ff , 0x0000002f, 1 },
2992    { mips64_emit_ERET    , 0xffffffff , 0x42000018, 0 },
2993    { mips64_emit_J       , 0xfc000000 , 0x08000000, 0 },
2994    { mips64_emit_JAL     , 0xfc000000 , 0x0c000000, 0 },
2995    { mips64_emit_JALR    , 0xfc1f003f , 0x00000009, 0 },
2996    { mips64_emit_JR      , 0xfc1ff83f , 0x00000008, 0 },
2997    { mips64_emit_LB      , 0xfc000000 , 0x80000000, 1 },
2998    { mips64_emit_LBU     , 0xfc000000 , 0x90000000, 1 },
2999    { mips64_emit_LD      , 0xfc000000 , 0xdc000000, 1 },
3000    { mips64_emit_LDC1    , 0xfc000000 , 0xd4000000, 1 },
3001    { mips64_emit_LDL     , 0xfc000000 , 0x68000000, 1 },
3002    { mips64_emit_LDR     , 0xfc000000 , 0x6c000000, 1 },
3003    { mips64_emit_LH      , 0xfc000000 , 0x84000000, 1 },
3004    { mips64_emit_LHU     , 0xfc000000 , 0x94000000, 1 },
3005    { mips64_emit_LL      , 0xfc000000 , 0xc0000000, 1 },
3006    { mips64_emit_LUI     , 0xffe00000 , 0x3c000000, 1 },
3007    { mips64_emit_LW      , 0xfc000000 , 0x8c000000, 1 },
3008    { mips64_emit_LWL     , 0xfc000000 , 0x88000000, 1 },
3009    { mips64_emit_LWR     , 0xfc000000 , 0x98000000, 1 },
3010    { mips64_emit_LWU     , 0xfc000000 , 0x9c000000, 1 },
3011    { mips64_emit_MFC0    , 0xffe007ff , 0x40000000, 1 },
3012    { mips64_emit_CFC0    , 0xffe007ff , 0x40000001, 1 },  /* MFC0 / Set 1 */
3013    { mips64_emit_MFC1    , 0xffe007ff , 0x44000000, 1 },
3014    { mips64_emit_MFHI    , 0xffff07ff , 0x00000010, 1 },
3015    { mips64_emit_MFLO    , 0xffff07ff , 0x00000012, 1 },
3016    { mips64_emit_MTC0    , 0xffe007ff , 0x40800000, 1 },
3017    { mips64_emit_MTC1    , 0xffe007ff , 0x44800000, 1 },
3018    { mips64_emit_MTHI    , 0xfc1fffff , 0x00000011, 1 },
3019    { mips64_emit_MTLO    , 0xfc1fffff , 0x00000013, 1 },
3020    { mips64_emit_MUL     , 0xfc0007ff , 0x70000002, 1 },
3021    { mips64_emit_MULT    , 0xfc00ffff , 0x00000018, 1 },
3022    { mips64_emit_MULTU   , 0xfc00ffff , 0x00000019, 1 },
3023    { mips64_emit_NOP     , 0xffffffff , 0x00000000, 1 },
3024    { mips64_emit_NOR     , 0xfc0007ff , 0x00000027, 1 },
3025    { mips64_emit_OR      , 0xfc0007ff , 0x00000025, 1 },
3026    { mips64_emit_ORI     , 0xfc000000 , 0x34000000, 1 },
3027    { mips64_emit_PREF    , 0xfc000000 , 0xcc000000, 1 },
3028    { mips64_emit_PREFX   , 0xfc0007ff , 0x4c00000f, 1 },
3029    { mips64_emit_SB      , 0xfc000000 , 0xa0000000, 1 },
3030    { mips64_emit_SC      , 0xfc000000 , 0xe0000000, 1 },
3031    { mips64_emit_SD      , 0xfc000000 , 0xfc000000, 1 },
3032    { mips64_emit_SDC1    , 0xfc000000 , 0xf4000000, 1 },
3033    { mips64_emit_SDL     , 0xfc000000 , 0xb0000000, 1 },
3034    { mips64_emit_SDR     , 0xfc000000 , 0xb4000000, 1 },
3035    { mips64_emit_SH      , 0xfc000000 , 0xa4000000, 1 },
3036    { mips64_emit_SLL     , 0xffe0003f , 0x00000000, 1 },
3037    { mips64_emit_SLLV    , 0xfc0007ff , 0x00000004, 1 },
3038    { mips64_emit_SLT     , 0xfc0007ff , 0x0000002a, 1 },
3039    { mips64_emit_SLTI    , 0xfc000000 , 0x28000000, 1 },
3040    { mips64_emit_SLTIU   , 0xfc000000 , 0x2c000000, 1 },
3041    { mips64_emit_SLTU    , 0xfc0007ff , 0x0000002b, 1 },
3042    { mips64_emit_SRA     , 0xffe0003f , 0x00000003, 1 },
3043    { mips64_emit_SRAV    , 0xfc0007ff , 0x00000007, 1 },
3044    { mips64_emit_SRL     , 0xffe0003f , 0x00000002, 1 },
3045    { mips64_emit_SRLV    , 0xfc0007ff , 0x00000006, 1 },
3046    { mips64_emit_SUB     , 0xfc0007ff , 0x00000022, 1 },
3047    { mips64_emit_SUBU    , 0xfc0007ff , 0x00000023, 1 },
3048    { mips64_emit_SW      , 0xfc000000 , 0xac000000, 1 },
3049    { mips64_emit_SWL     , 0xfc000000 , 0xa8000000, 1 },
3050    { mips64_emit_SWR     , 0xfc000000 , 0xb8000000, 1 },
3051    { mips64_emit_SYNC    , 0xfffff83f , 0x0000000f, 1 },
3052    { mips64_emit_SYSCALL , 0xfc00003f , 0x0000000c, 1 },
3053    { mips64_emit_TEQ     , 0xfc00003f , 0x00000034, 1 },
3054    { mips64_emit_TEQI    , 0xfc1f0000 , 0x040c0000, 1 },
3055    { mips64_emit_TLBP    , 0xffffffff , 0x42000008, 1 },
3056    { mips64_emit_TLBR    , 0xffffffff , 0x42000001, 1 },
3057    { mips64_emit_TLBWI   , 0xffffffff , 0x42000002, 1 },
3058    { mips64_emit_TLBWR   , 0xffffffff , 0x42000006, 1 },
3059    { mips64_emit_XOR     , 0xfc0007ff , 0x00000026, 1 },
3060    { mips64_emit_XORI    , 0xfc000000 , 0x38000000, 1 },
3061    { mips64_emit_unknown , 0x00000000 , 0x00000000, 1 },
3062    { NULL                , 0x00000000 , 0x00000000, 0 },
3063 };
3064