/[dynamips]/upstream/dynamips-0.2.6-RC3/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.6-RC3/x86_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Sat Oct 6 16:03:58 2007 UTC (14 years, 9 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC1/x86_trans.c
File MIME type: text/plain
File size: 89075 byte(s)
import dynamips-0.2.6-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26