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