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