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