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