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