/[dynamips]/upstream/dynamips-0.2.7-RC1/mips64_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.7-RC1/mips64_x86_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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

  ViewVC Help
Powered by ViewVC 1.1.26