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