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