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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Sat Oct 6 16:05:34 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC2/x86_trans.c
File MIME type: text/plain
File size: 89075 byte(s)
dynamips-0.2.6-RC2

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

  ViewVC Help
Powered by ViewVC 1.1.26