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