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