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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Sat Oct 6 16:01:44 2007 UTC (14 years, 8 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.5/x86_trans.c
File MIME type: text/plain
File size: 89056 byte(s)
import 0.2.5 from upstream

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

  ViewVC Help
Powered by ViewVC 1.1.26