/[dynamips]/trunk/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 /trunk/mips64_x86_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 88638 byte(s)
make working copy

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

  ViewVC Help
Powered by ViewVC 1.1.26