/[dynamips]/upstream/dynamips-0.2.7-RC2/mips64_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

Annotation of /upstream/dynamips-0.2.7-RC2/mips64_x86_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/mips64_x86_trans.c
File MIME type: text/plain
File size: 86903 byte(s)
dynamips-0.2.7-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26