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

Contents of /trunk/x86_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations)
Sat Oct 6 16:33:40 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.8-RC1/x86_trans.c
File MIME type: text/plain
File size: 93191 byte(s)
dynamips-0.2.8-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26