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