/[dynamips]/upstream/dynamips-0.2.6-RC1/x86_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.6-RC1/x86_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Sat Oct 6 16:01:44 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.5/x86_trans.c
File MIME type: text/plain
File size: 89056 byte(s)
import 0.2.5 from upstream

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

  ViewVC Help
Powered by ViewVC 1.1.26