/[dynamips]/upstream/dynamips-0.2.7-RC1/mips64_amd64_trans.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.7-RC1/mips64_amd64_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 75828 byte(s)
dynamips-0.2.7-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26