/[dynamips]/upstream/dynamips-0.2.6-RC4/mips64_exec.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.6-RC4/mips64_exec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations)
Sat Oct 6 16:08:03 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 59696 byte(s)
dynamips-0.2.6-RC4

1 /*
2 * Cisco 7200 (Predator) simulation platform.
3 * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4 *
5 * MIPS64 Step-by-step execution.
6 */
7
8 #if __GNUC__ > 2
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <sys/mman.h>
17 #include <fcntl.h>
18
19 #include "rbtree.h"
20 #include "mips64.h"
21 #include "dynamips.h"
22 #include "vm.h"
23 #include "memory.h"
24 #include "cpu.h"
25 #include "cp0.h"
26 #include "mips64_exec.h"
27 #include "insn_lookup.h"
28
29 /* Forward declaration of instruction array */
30 static struct insn_exec_tag mips64_exec_tags[];
31 static insn_lookup_t *ilt = NULL;
32
33 /* ILT */
34 static forced_inline void *mips64_exec_get_insn(int index)
35 {
36 return(&mips64_exec_tags[index]);
37 }
38
39 static int mips64_exec_chk_lo(struct insn_exec_tag *tag,int value)
40 {
41 return((value & tag->mask) == (tag->value & 0xFFFF));
42 }
43
44 static int mips64_exec_chk_hi(struct insn_exec_tag *tag,int value)
45 {
46 return((value & (tag->mask >> 16)) == (tag->value >> 16));
47 }
48
49 /* Initialize instruction lookup table */
50 void mips64_exec_create_ilt(void)
51 {
52 int i,count;
53
54 for(i=0,count=0;mips64_exec_tags[i].exec;i++)
55 count++;
56
57 ilt = ilt_create(count,
58 (ilt_get_insn_cbk_t)mips64_exec_get_insn,
59 (ilt_check_cbk_t)mips64_exec_chk_lo,
60 (ilt_check_cbk_t)mips64_exec_chk_hi);
61 }
62
63 /* Dump statistics */
64 void mips64_dump_stats(cpu_mips_t *cpu)
65 {
66 int i;
67
68 #if NJM_STATS_ENABLE
69 printf("\n");
70
71 for(i=0;mips64_exec_tags[i].exec;i++)
72 printf(" * %-10s : %10llu\n",
73 mips64_exec_tags[i].name,mips64_exec_tags[i].count);
74
75 printf("%llu instructions executed since startup.\n",cpu->insn_exec_count);
76 #else
77 printf("Statistics support is not compiled in.\n");
78 #endif
79 }
80
81 /* Dump an instruction */
82 int mips64_dump_insn(char *buffer,size_t buf_size,size_t insn_name_size,
83 m_uint64_t pc,mips_insn_t instruction)
84 {
85 char insn_name[64],insn_format[32],*name;
86 int base,rs,rd,rt,sa,offset,imm;
87 struct insn_exec_tag *tag;
88 m_uint64_t new_pc;
89 int index;
90
91 /* Lookup for instruction */
92 index = ilt_lookup(ilt,instruction);
93 tag = mips64_exec_get_insn(index);
94
95 if (!tag) {
96 snprintf(buffer,buf_size,"%8.8x (unknown)",instruction);
97 return(-1);
98 }
99
100 if (!(name = tag->name))
101 name = "[unknown]";
102
103 if (!insn_name_size)
104 insn_name_size = 10;
105
106 snprintf(insn_format,sizeof(insn_format),"%%-%lus",(u_long)insn_name_size);
107 snprintf(insn_name,sizeof(insn_name),insn_format,name);
108
109 switch(tag->instr_type) {
110 case 1: /* instructions without operands */
111 snprintf(buffer,buf_size,"%8.8x %s",instruction,insn_name);
112 break;
113
114 case 2: /* load/store instructions */
115 base = bits(instruction,21,25);
116 rt = bits(instruction,16,20);
117 offset = (m_int16_t)bits(instruction,0,15);
118 snprintf(buffer,buf_size,"%8.8x %s %s,%d(%s)",
119 instruction,insn_name,mips64_gpr_reg_names[rt],
120 offset,mips64_gpr_reg_names[base]);
121 break;
122
123 case 3: /* GPR[rd] = GPR[rs] op GPR[rt] */
124 rs = bits(instruction,21,25);
125 rt = bits(instruction,16,20);
126 rd = bits(instruction,11,15);
127 snprintf(buffer,buf_size,"%8.8x %s %s,%s,%s",
128 instruction,insn_name,mips64_gpr_reg_names[rd],
129 mips64_gpr_reg_names[rs],mips64_gpr_reg_names[rt]);
130 break;
131
132 case 4: /* GPR[rd] = GPR[rt] op GPR[rs] */
133 rs = bits(instruction,21,25);
134 rt = bits(instruction,16,20);
135 rd = bits(instruction,11,15);
136 snprintf(buffer,buf_size,"%8.8x %s %s,%s,%s",
137 instruction,insn_name,mips64_gpr_reg_names[rd],
138 mips64_gpr_reg_names[rt],mips64_gpr_reg_names[rs]);
139 break;
140
141 case 5: /* GPR[rt] = GPR[rs] op immediate (hex) */
142 rs = bits(instruction,21,25);
143 rt = bits(instruction,16,20);
144 imm = bits(instruction,0,15);
145 snprintf(buffer,buf_size,"%8.8x %s %s,%s,0x%x",
146 instruction,insn_name,mips64_gpr_reg_names[rt],
147 mips64_gpr_reg_names[rs],imm);
148 break;
149
150 case 6: /* GPR[rt] = GPR[rs] op immediate (dec) */
151 rs = bits(instruction,21,25);
152 rt = bits(instruction,16,20);
153 imm = bits(instruction,0,15);
154 snprintf(buffer,buf_size,"%8.8x %s %s,%s,%d",
155 instruction,insn_name,mips64_gpr_reg_names[rt],
156 mips64_gpr_reg_names[rs],(m_int16_t)imm);
157 break;
158
159 case 7: /* GPR[rd] = GPR[rt] op sa */
160 rt = bits(instruction,16,20);
161 rd = bits(instruction,11,15);
162 sa = bits(instruction,6,10);
163 snprintf(buffer,buf_size,"%8.8x %s %s,%s,%d",
164 instruction,insn_name,mips64_gpr_reg_names[rd],
165 mips64_gpr_reg_names[rt],sa);
166 break;
167
168 case 8: /* Branch with: GPR[rs] / GPR[rt] / offset */
169 rs = bits(instruction,21,25);
170 rt = bits(instruction,16,20);
171 offset = bits(instruction,0,15);
172 new_pc = (pc + 4) + sign_extend(offset << 2,18);
173 snprintf(buffer,buf_size,"%8.8x %s %s,%s,0x%llx",
174 instruction,insn_name,mips64_gpr_reg_names[rs],
175 mips64_gpr_reg_names[rt],new_pc);
176 break;
177
178 case 9: /* Branch with: GPR[rs] / offset */
179 rs = bits(instruction,21,25);
180 offset = bits(instruction,0,15);
181 new_pc = (pc + 4) + sign_extend(offset << 2,18);
182 snprintf(buffer,buf_size,"%8.8x %s %s,0x%llx",
183 instruction,insn_name,mips64_gpr_reg_names[rs],new_pc);
184 break;
185
186 case 10: /* Branch with: offset */
187 offset = bits(instruction,0,15);
188 new_pc = (pc + 4) + sign_extend(offset << 2,18);
189 snprintf(buffer,buf_size,"%8.8x %s 0x%llx",
190 instruction,insn_name,new_pc);
191 break;
192
193 case 11: /* Jump */
194 offset = bits(instruction,0,25);
195 new_pc = (pc & ~((1 << 28) - 1)) | (offset << 2);
196 snprintf(buffer,buf_size,"%8.8x %s 0x%llx",
197 instruction,insn_name,new_pc);
198 break;
199
200 case 13: /* op GPR[rs] */
201 rs = bits(instruction,21,25);
202 snprintf(buffer,buf_size,"%8.8x %s %s",
203 instruction,insn_name,mips64_gpr_reg_names[rs]);
204 break;
205
206 case 14: /* op GPR[rd] */
207 rd = bits(instruction,11,15);
208 snprintf(buffer,buf_size,"%8.8x %s %s",
209 instruction,insn_name,mips64_gpr_reg_names[rd]);
210 break;
211
212 case 15: /* op GPR[rd], GPR[rs] */
213 rs = bits(instruction,21,25);
214 rd = bits(instruction,11,15);
215 snprintf(buffer,buf_size,"%8.8x %s %s,%s",
216 instruction,insn_name,mips64_gpr_reg_names[rd],
217 mips64_gpr_reg_names[rs]);
218 break;
219
220 case 16: /* op GPR[rt], imm */
221 rt = bits(instruction,16,20);
222 imm = bits(instruction,0,15);
223 snprintf(buffer,buf_size,"%8.8x %s %s,0x%x",
224 instruction,insn_name,mips64_gpr_reg_names[rt],imm);
225 break;
226
227 case 17: /* op GPR[rs], GPR[rt] */
228 rs = bits(instruction,21,25);
229 rt = bits(instruction,16,20);
230 snprintf(buffer,buf_size,"%8.8x %s %s,%s",
231 instruction,insn_name,mips64_gpr_reg_names[rs],
232 mips64_gpr_reg_names[rt]);
233 break;
234
235 case 18: /* op GPR[rt], CP0[rd] */
236 rt = bits(instruction,16,20);
237 rd = bits(instruction,11,15);
238 snprintf(buffer,buf_size,"%8.8x %s %s,%s",
239 instruction,insn_name,mips64_gpr_reg_names[rt],
240 mips64_cp0_reg_names[rd]);
241 break;
242
243 case 19: /* op GPR[rt], $rd */
244 rt = bits(instruction,16,20);
245 rd = bits(instruction,11,15);
246 snprintf(buffer,buf_size,"%8.8x %s %s,$%d",
247 instruction,insn_name,mips64_gpr_reg_names[rt],rd);
248 break;
249
250 case 20: /* op GPR[rs], imm */
251 rs = bits(instruction,21,25);
252 imm = bits(instruction,0,15);
253 snprintf(buffer,buf_size,"%8.8x %s %s,0x%x",
254 instruction,insn_name,mips64_gpr_reg_names[rs],imm);
255 break;
256
257 default:
258 snprintf(buffer,buf_size,"%8.8x %s (TO DEFINE - %d)",
259 instruction,insn_name,tag->instr_type);
260 return(-1);
261 }
262
263 return(0);
264 }
265
266 /* Dump an instruction block */
267 void mips64_dump_insn_block(cpu_mips_t *cpu,m_uint64_t pc,u_int count,
268 size_t insn_name_size)
269 {
270 mips_insn_t *ptr,insn;
271 char buffer[80];
272 int i;
273
274 for(i=0;i<count;i++) {
275 ptr = cpu->mem_op_lookup(cpu,pc);
276 insn = vmtoh32(*ptr);
277
278 mips64_dump_insn(buffer,sizeof(buffer),insn_name_size,pc,insn);
279 printf("0x%llx: %s\n",pc,buffer);
280 pc += sizeof(mips_insn_t);
281 }
282 }
283
284 /* Execute a memory operation */
285 static forced_inline int mips64_exec_memop(cpu_mips_t *cpu,int memop,
286 m_uint64_t vaddr,u_int dst_reg,
287 int keep_ll_bit)
288 {
289 fastcall mips_memop_fn fn;
290
291 if (!keep_ll_bit) cpu->ll_bit = 0;
292 fn = cpu->mem_op_fn[memop];
293 return(fn(cpu,vaddr,dst_reg));
294 }
295
296 /* Execute a memory operation (2) */
297 static forced_inline int mips64_exec_memop2(cpu_mips_t *cpu,int memop,
298 m_uint64_t base,int offset,
299 u_int dst_reg,int keep_ll_bit)
300 {
301 m_uint64_t vaddr = cpu->gpr[base] + sign_extend(offset,16);
302 fastcall mips_memop_fn fn;
303
304 if (!keep_ll_bit) cpu->ll_bit = 0;
305 fn = cpu->mem_op_fn[memop];
306 return(fn(cpu,vaddr,dst_reg));
307 }
308
309 /* Fetch an instruction */
310 static forced_inline int mips64_exec_fetch(cpu_mips_t *cpu,m_uint64_t pc,
311 mips_insn_t *insn)
312 {
313 m_uint64_t exec_page;
314 m_uint32_t offset;
315
316 exec_page = pc & ~(m_uint64_t)MIPS_MIN_PAGE_IMASK;
317
318 if (unlikely(exec_page != cpu->njm_exec_page)) {
319 cpu->njm_exec_page = exec_page;
320 cpu->njm_exec_ptr = cpu->mem_op_lookup(cpu,exec_page);
321 }
322
323 offset = (pc & MIPS_MIN_PAGE_IMASK) >> 2;
324 *insn = vmtoh32(cpu->njm_exec_ptr[offset]);
325 return(0);
326 }
327
328 /* Execute a single instruction */
329 static forced_inline int
330 mips64_exec_single_instruction(cpu_mips_t *cpu,mips_insn_t instruction)
331 {
332 register fastcall int (*exec)(cpu_mips_t *,mips_insn_t) = NULL;
333 struct insn_exec_tag *tag;
334 int index;
335
336 #if DEBUG_PERF_COUNTER
337 cpu->perf_counter++;
338 #endif
339
340 /* Increment CP0 count register */
341 mips64_exec_inc_cp0_cnt(cpu);
342
343 /* Lookup for instruction */
344 index = ilt_lookup(ilt,instruction);
345 tag = mips64_exec_get_insn(index);
346 exec = tag->exec;
347
348 if (likely(exec != NULL)) {
349 #if NJM_STATS_ENABLE
350 cpu->insn_exec_count++;
351 mips64_exec_tags[index].count++;
352 #endif
353 #if 0
354 {
355 char buffer[80];
356
357 if (mips64_dump_insn(buffer,sizeof(buffer),0,cpu->pc,instruction)!=-1)
358 fprintf(log_file,"0x%llx: %s\n",cpu->pc,buffer);
359 }
360 #endif
361
362 return(exec(cpu,instruction));
363 }
364
365 printf("MIPS64: unknown opcode 0x%8.8x at pc = 0x%llx\n",
366 instruction,cpu->pc);
367 mips64_dump_regs(cpu);
368 return(0);
369 }
370
371 /* Single-step execution */
372 void mips64_exec_single_step(cpu_mips_t *cpu,mips_insn_t instruction)
373 {
374 int res;
375
376 res = mips64_exec_single_instruction(cpu,instruction);
377
378 /* Normal flow ? */
379 if (likely(!res)) cpu->pc += 4;
380 }
381
382 /* Run MIPS code in step-by-step mode */
383 void *mips64_exec_run_cpu(cpu_mips_t *cpu)
384 {
385 pthread_t timer_irq_thread;
386 mips_insn_t insn;
387 int timer_irq_check = 0;
388 int res;
389
390 if (pthread_create(&timer_irq_thread,NULL,
391 (void *)mips64_timer_irq_run,cpu))
392 {
393 fprintf(stderr,"VM '%s': unable to create Timer IRQ thread for CPU%u.\n",
394 cpu->vm->name,cpu->id);
395 cpu_stop(cpu);
396 return NULL;
397 }
398
399 cpu->cpu_thread_running = TRUE;
400
401 start_cpu:
402 cpu->idle_count = 0;
403
404 for(;;) {
405 if (unlikely(cpu->state != MIPS_CPU_RUNNING))
406 break;
407
408 /* Handle virtual idle loop */
409 if (unlikely(cpu->pc == cpu->idle_pc)) {
410 if (++cpu->idle_count == cpu->idle_max) {
411 mips64_idle_loop(cpu);
412 cpu->idle_count = 0;
413 }
414 }
415
416 /* Handle the virtual CPU clock */
417 if (++timer_irq_check == cpu->timer_irq_check_itv) {
418 timer_irq_check = 0;
419
420 if (cpu->timer_irq_pending && !cpu->irq_disable) {
421 mips64_trigger_timer_irq(cpu);
422 mips64_trigger_irq(cpu);
423 cpu->timer_irq_pending--;
424 }
425 }
426
427 /* Reset "zero register" (for safety) */
428 cpu->gpr[0] = 0;
429
430 /* Check IRQ */
431 if (unlikely(cpu->irq_pending)) {
432 mips64_trigger_irq(cpu);
433 continue;
434 }
435
436 /* Fetch and execute the instruction */
437 mips64_exec_fetch(cpu,cpu->pc,&insn);
438 res = mips64_exec_single_instruction(cpu,insn);
439
440 /* Normal flow ? */
441 if (likely(!res)) cpu->pc += 4;
442 }
443
444 if (!cpu->pc) {
445 cpu_stop(cpu);
446 cpu_log(cpu,"SLOW_EXEC","PC=0, halting CPU.\n");
447 }
448
449 /* Check regularly if the CPU has been restarted */
450 while(cpu->cpu_thread_running) {
451 cpu->seq_state++;
452
453 switch(cpu->state) {
454 case MIPS_CPU_RUNNING:
455 cpu->state = MIPS_CPU_RUNNING;
456 goto start_cpu;
457
458 case MIPS_CPU_HALTED:
459 cpu->cpu_thread_running = FALSE;
460 pthread_join(timer_irq_thread,NULL);
461 break;
462 }
463
464 /* CPU is paused */
465 usleep(200000);
466 }
467
468 return NULL;
469 }
470
471 /* Execute the instruction in delay slot */
472 static forced_inline void mips64_exec_bdslot(cpu_mips_t *cpu)
473 {
474 mips_insn_t insn;
475
476 /* Fetch the instruction in delay slot */
477 mips64_exec_fetch(cpu,cpu->pc+4,&insn);
478
479 /* Execute the instruction */
480 mips64_exec_single_instruction(cpu,insn);
481 }
482
483 /* ADD */
484 static fastcall int mips64_exec_ADD(cpu_mips_t *cpu,mips_insn_t insn)
485 {
486 int rs = bits(insn,21,25);
487 int rt = bits(insn,16,20);
488 int rd = bits(insn,11,15);
489 m_uint64_t res;
490
491 /* TODO: Exception handling */
492 res = (m_uint32_t)cpu->gpr[rs] + (m_uint32_t)cpu->gpr[rt];
493 cpu->gpr[rd] = sign_extend(res,32);
494 return(0);
495 }
496
497 /* ADDI */
498 static fastcall int mips64_exec_ADDI(cpu_mips_t *cpu,mips_insn_t insn)
499 {
500 int rs = bits(insn,21,25);
501 int rt = bits(insn,16,20);
502 int imm = bits(insn,0,15);
503 m_uint32_t res,val = sign_extend(imm,16);
504
505 /* TODO: Exception handling */
506 res = (m_uint32_t)cpu->gpr[rs] + val;
507 cpu->gpr[rt] = sign_extend(res,32);
508 return(0);
509 }
510
511 /* ADDIU */
512 static fastcall int mips64_exec_ADDIU(cpu_mips_t *cpu,mips_insn_t insn)
513 {
514 int rs = bits(insn,21,25);
515 int rt = bits(insn,16,20);
516 int imm = bits(insn,0,15);
517 m_uint32_t res,val = sign_extend(imm,16);
518
519 res = (m_uint32_t)cpu->gpr[rs] + val;
520 cpu->gpr[rt] = sign_extend(res,32);
521 return(0);
522 }
523
524 /* ADDU */
525 static fastcall int mips64_exec_ADDU(cpu_mips_t *cpu,mips_insn_t insn)
526 {
527 int rs = bits(insn,21,25);
528 int rt = bits(insn,16,20);
529 int rd = bits(insn,11,15);
530 m_uint32_t res;
531
532 res = (m_uint32_t)cpu->gpr[rs] + (m_uint32_t)cpu->gpr[rt];
533 cpu->gpr[rd] = sign_extend(res,32);
534 return(0);
535 }
536
537 /* AND */
538 static fastcall int mips64_exec_AND(cpu_mips_t *cpu,mips_insn_t insn)
539 {
540 int rs = bits(insn,21,25);
541 int rt = bits(insn,16,20);
542 int rd = bits(insn,11,15);
543
544 cpu->gpr[rd] = cpu->gpr[rs] & cpu->gpr[rt];
545 return(0);
546 }
547
548 /* ANDI */
549 static fastcall int mips64_exec_ANDI(cpu_mips_t *cpu,mips_insn_t insn)
550 {
551 int rs = bits(insn,21,25);
552 int rt = bits(insn,16,20);
553 int imm = bits(insn,0,15);
554
555 cpu->gpr[rt] = cpu->gpr[rs] & imm;
556 return(0);
557 }
558
559 /* B (Branch, virtual instruction) */
560 static fastcall int mips64_exec_B(cpu_mips_t *cpu,mips_insn_t insn)
561 {
562 int offset = bits(insn,0,15);
563 m_uint64_t new_pc;
564
565 /* compute the new pc */
566 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
567
568 /* exec the instruction in the delay slot */
569 mips64_exec_bdslot(cpu);
570
571 /* set the new pc in cpu structure */
572 cpu->pc = new_pc;
573 return(1);
574 }
575
576 /* BAL (Branch And Link, virtual instruction) */
577 static fastcall int mips64_exec_BAL(cpu_mips_t *cpu,mips_insn_t insn)
578 {
579 int offset = bits(insn,0,15);
580 m_uint64_t new_pc;
581
582 /* compute the new pc */
583 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
584
585 /* set the return address (instruction after the delay slot) */
586 cpu->gpr[MIPS_GPR_RA] = cpu->pc + 8;
587
588 /* exec the instruction in the delay slot */
589 mips64_exec_bdslot(cpu);
590
591 /* set the new pc in cpu structure */
592 cpu->pc = new_pc;
593 return(1);
594 }
595
596 /* BEQ (Branch On Equal) */
597 static fastcall int mips64_exec_BEQ(cpu_mips_t *cpu,mips_insn_t insn)
598 {
599 int rs = bits(insn,21,25);
600 int rt = bits(insn,16,20);
601 int offset = bits(insn,0,15);
602 m_uint64_t new_pc;
603 int res;
604
605 /* compute the new pc */
606 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
607
608 /* take the branch if gpr[rs] == gpr[rt] */
609 res = (cpu->gpr[rs] == cpu->gpr[rt]);
610
611 /* exec the instruction in the delay slot */
612 mips64_exec_bdslot(cpu);
613
614 /* take the branch if the test result is true */
615 if (res)
616 cpu->pc = new_pc;
617 else
618 cpu->pc += 8;
619
620 return(1);
621 }
622
623 /* BEQL (Branch On Equal Likely) */
624 static fastcall int mips64_exec_BEQL(cpu_mips_t *cpu,mips_insn_t insn)
625 {
626 int rs = bits(insn,21,25);
627 int rt = bits(insn,16,20);
628 int offset = bits(insn,0,15);
629 m_uint64_t new_pc;
630 int res;
631
632 /* compute the new pc */
633 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
634
635 /* take the branch if gpr[rs] == gpr[rt] */
636 res = (cpu->gpr[rs] == cpu->gpr[rt]);
637
638 /* take the branch if the test result is true */
639 if (res) {
640 mips64_exec_bdslot(cpu);
641 cpu->pc = new_pc;
642 } else
643 cpu->pc += 8;
644
645 return(1);
646 }
647
648 /* BEQZ (Branch On Equal Zero) - Virtual Instruction */
649 static fastcall int mips64_exec_BEQZ(cpu_mips_t *cpu,mips_insn_t insn)
650 {
651 int rs = bits(insn,21,25);
652 int offset = bits(insn,0,15);
653 m_uint64_t new_pc;
654 int res;
655
656 /* compute the new pc */
657 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
658
659 /* take the branch if gpr[rs] == 0 */
660 res = (cpu->gpr[rs] == 0);
661
662 /* exec the instruction in the delay slot */
663 mips64_exec_bdslot(cpu);
664
665 /* take the branch if the test result is true */
666 if (res)
667 cpu->pc = new_pc;
668 else
669 cpu->pc += 8;
670
671 return(1);
672 }
673
674 /* BNEZ (Branch On Not Equal Zero) - Virtual Instruction */
675 static fastcall int mips64_exec_BNEZ(cpu_mips_t *cpu,mips_insn_t insn)
676 {
677 int rs = bits(insn,21,25);
678 int offset = bits(insn,0,15);
679 m_uint64_t new_pc;
680 int res;
681
682 /* compute the new pc */
683 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
684
685 /* take the branch if gpr[rs] != 0 */
686 res = (cpu->gpr[rs] != 0);
687
688 /* exec the instruction in the delay slot */
689 mips64_exec_bdslot(cpu);
690
691 /* take the branch if the test result is true */
692 if (res)
693 cpu->pc = new_pc;
694 else
695 cpu->pc += 8;
696
697 return(1);
698 }
699
700 /* BGEZ (Branch On Greater or Equal Than Zero) */
701 static fastcall int mips64_exec_BGEZ(cpu_mips_t *cpu,mips_insn_t insn)
702 {
703 int rs = bits(insn,21,25);
704 int offset = bits(insn,0,15);
705 m_uint64_t new_pc;
706 int res;
707
708 /* compute the new pc */
709 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
710
711 /* take the branch if gpr[rs] >= 0 */
712 res = ((m_int64_t)cpu->gpr[rs] >= 0);
713
714 /* exec the instruction in the delay slot */
715 mips64_exec_bdslot(cpu);
716
717 /* take the branch if the test result is true */
718 if (res)
719 cpu->pc = new_pc;
720 else
721 cpu->pc += 8;
722
723 return(1);
724 }
725
726 /* BGEZAL (Branch On Greater or Equal Than Zero And Link) */
727 static fastcall int mips64_exec_BGEZAL(cpu_mips_t *cpu,mips_insn_t insn)
728 {
729 int rs = bits(insn,21,25);
730 int offset = bits(insn,0,15);
731 m_uint64_t new_pc;
732 int res;
733
734 /* compute the new pc */
735 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
736
737 /* set the return address (instruction after the delay slot) */
738 cpu->gpr[MIPS_GPR_RA] = cpu->pc + 8;
739
740 /* take the branch if gpr[rs] >= 0 */
741 res = ((m_int64_t)cpu->gpr[rs] >= 0);
742
743 /* exec the instruction in the delay slot */
744 mips64_exec_bdslot(cpu);
745
746 /* take the branch if the test result is true */
747 if (res)
748 cpu->pc = new_pc;
749 else
750 cpu->pc += 8;
751
752 return(1);
753 }
754
755 /* BGEZALL (Branch On Greater or Equal Than Zero And Link Likely) */
756 static fastcall int mips64_exec_BGEZALL(cpu_mips_t *cpu,mips_insn_t insn)
757 {
758 int rs = bits(insn,21,25);
759 int offset = bits(insn,0,15);
760 m_uint64_t new_pc;
761 int res;
762
763 /* compute the new pc */
764 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
765
766 /* set the return address (instruction after the delay slot) */
767 cpu->gpr[MIPS_GPR_RA] = cpu->pc + 8;
768
769 /* take the branch if gpr[rs] >= 0 */
770 res = ((m_int64_t)cpu->gpr[rs] >= 0);
771
772 /* take the branch if the test result is true */
773 if (res) {
774 mips64_exec_bdslot(cpu);
775 cpu->pc = new_pc;
776 } else
777 cpu->pc += 8;
778
779 return(1);
780 }
781
782 /* BGEZL (Branch On Greater or Equal Than Zero Likely) */
783 static fastcall int mips64_exec_BGEZL(cpu_mips_t *cpu,mips_insn_t insn)
784 {
785 int rs = bits(insn,21,25);
786 int offset = bits(insn,0,15);
787 m_uint64_t new_pc;
788 int res;
789
790 /* compute the new pc */
791 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
792
793 /* take the branch if gpr[rs] >= 0 */
794 res = ((m_int64_t)cpu->gpr[rs] >= 0);
795
796 /* take the branch if the test result is true */
797 if (res) {
798 mips64_exec_bdslot(cpu);
799 cpu->pc = new_pc;
800 } else
801 cpu->pc += 8;
802
803 return(1);
804 }
805
806 /* BGTZ (Branch On Greater Than Zero) */
807 static fastcall int mips64_exec_BGTZ(cpu_mips_t *cpu,mips_insn_t insn)
808 {
809 int rs = bits(insn,21,25);
810 int offset = bits(insn,0,15);
811 m_uint64_t new_pc;
812 int res;
813
814 /* compute the new pc */
815 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
816
817 /* take the branch if gpr[rs] > 0 */
818 res = ((m_int64_t)cpu->gpr[rs] > 0);
819
820 /* exec the instruction in the delay slot */
821 mips64_exec_bdslot(cpu);
822
823 /* take the branch if the test result is true */
824 if (res)
825 cpu->pc = new_pc;
826 else
827 cpu->pc += 8;
828
829 return(1);
830 }
831
832 /* BGTZL (Branch On Greater Than Zero Likely) */
833 static fastcall int mips64_exec_BGTZL(cpu_mips_t *cpu,mips_insn_t insn)
834 {
835 int rs = bits(insn,21,25);
836 int offset = bits(insn,0,15);
837 m_uint64_t new_pc;
838 int res;
839
840 /* compute the new pc */
841 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
842
843 /* take the branch if gpr[rs] > 0 */
844 res = ((m_int64_t)cpu->gpr[rs] > 0);
845
846 /* take the branch if the test result is true */
847 if (res) {
848 mips64_exec_bdslot(cpu);
849 cpu->pc = new_pc;
850 } else
851 cpu->pc += 8;
852
853 return(1);
854 }
855
856 /* BLEZ (Branch On Less or Equal Than Zero) */
857 static fastcall int mips64_exec_BLEZ(cpu_mips_t *cpu,mips_insn_t insn)
858 {
859 int rs = bits(insn,21,25);
860 int offset = bits(insn,0,15);
861 m_uint64_t new_pc;
862 int res;
863
864 /* compute the new pc */
865 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
866
867 /* take the branch if gpr[rs] <= 0 */
868 res = ((m_int64_t)cpu->gpr[rs] <= 0);
869
870 /* exec the instruction in the delay slot */
871 mips64_exec_bdslot(cpu);
872
873 /* take the branch if the test result is true */
874 if (res)
875 cpu->pc = new_pc;
876 else
877 cpu->pc += 8;
878
879 return(1);
880 }
881
882 /* BLEZL (Branch On Less or Equal Than Zero Likely) */
883 static fastcall int mips64_exec_BLEZL(cpu_mips_t *cpu,mips_insn_t insn)
884 {
885 int rs = bits(insn,21,25);
886 int offset = bits(insn,0,15);
887 m_uint64_t new_pc;
888 int res;
889
890 /* compute the new pc */
891 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
892
893 /* take the branch if gpr[rs] <= 0 */
894 res = ((m_int64_t)cpu->gpr[rs] <= 0);
895
896 /* take the branch if the test result is true */
897 if (res) {
898 mips64_exec_bdslot(cpu);
899 cpu->pc = new_pc;
900 } else
901 cpu->pc += 8;
902
903 return(1);
904 }
905
906 /* BLTZ (Branch On Less Than Zero) */
907 static fastcall int mips64_exec_BLTZ(cpu_mips_t *cpu,mips_insn_t insn)
908 {
909 int rs = bits(insn,21,25);
910 int offset = bits(insn,0,15);
911 m_uint64_t new_pc;
912 int res;
913
914 /* compute the new pc */
915 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
916
917 /* take the branch if gpr[rs] < 0 */
918 res = ((m_int64_t)cpu->gpr[rs] < 0);
919
920 /* exec the instruction in the delay slot */
921 mips64_exec_bdslot(cpu);
922
923 /* take the branch if the test result is true */
924 if (res)
925 cpu->pc = new_pc;
926 else
927 cpu->pc += 8;
928
929 return(1);
930 }
931
932 /* BLTZAL (Branch On Less Than Zero And Link) */
933 static fastcall int mips64_exec_BLTZAL(cpu_mips_t *cpu,mips_insn_t insn)
934 {
935 int rs = bits(insn,21,25);
936 int offset = bits(insn,0,15);
937 m_uint64_t new_pc;
938 int res;
939
940 /* compute the new pc */
941 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
942
943 /* set the return address (instruction after the delay slot) */
944 cpu->gpr[MIPS_GPR_RA] = cpu->pc + 8;
945
946 /* take the branch if gpr[rs] < 0 */
947 res = ((m_int64_t)cpu->gpr[rs] < 0);
948
949 /* exec the instruction in the delay slot */
950 mips64_exec_bdslot(cpu);
951
952 /* take the branch if the test result is true */
953 if (res)
954 cpu->pc = new_pc;
955 else
956 cpu->pc += 8;
957
958 return(1);
959 }
960
961 /* BLTZALL (Branch On Less Than Zero And Link Likely) */
962 static fastcall int mips64_exec_BLTZALL(cpu_mips_t *cpu,mips_insn_t insn)
963 {
964 int rs = bits(insn,21,25);
965 int offset = bits(insn,0,15);
966 m_uint64_t new_pc;
967 int res;
968
969 /* compute the new pc */
970 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
971
972 /* set the return address (instruction after the delay slot) */
973 cpu->gpr[MIPS_GPR_RA] = cpu->pc + 8;
974
975 /* take the branch if gpr[rs] < 0 */
976 res = ((m_int64_t)cpu->gpr[rs] < 0);
977
978 /* take the branch if the test result is true */
979 if (res) {
980 mips64_exec_bdslot(cpu);
981 cpu->pc = new_pc;
982 } else
983 cpu->pc += 8;
984
985 return(1);
986 }
987
988 /* BLTZL (Branch On Less Than Zero Likely) */
989 static fastcall int mips64_exec_BLTZL(cpu_mips_t *cpu,mips_insn_t insn)
990 {
991 int rs = bits(insn,21,25);
992 int offset = bits(insn,0,15);
993 m_uint64_t new_pc;
994 int res;
995
996 /* compute the new pc */
997 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
998
999 /* take the branch if gpr[rs] < 0 */
1000 res = ((m_int64_t)cpu->gpr[rs] < 0);
1001
1002 /* take the branch if the test result is true */
1003 if (res) {
1004 mips64_exec_bdslot(cpu);
1005 cpu->pc = new_pc;
1006 } else
1007 cpu->pc += 8;
1008
1009 return(1);
1010 }
1011
1012 /* BNE (Branch On Not Equal) */
1013 static fastcall int mips64_exec_BNE(cpu_mips_t *cpu,mips_insn_t insn)
1014 {
1015 int rs = bits(insn,21,25);
1016 int rt = bits(insn,16,20);
1017 int offset = bits(insn,0,15);
1018 m_uint64_t new_pc;
1019 int res;
1020
1021 /* compute the new pc */
1022 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
1023
1024 /* take the branch if gpr[rs] != gpr[rt] */
1025 res = (cpu->gpr[rs] != cpu->gpr[rt]);
1026
1027 /* exec the instruction in the delay slot */
1028 mips64_exec_bdslot(cpu);
1029
1030 /* take the branch if the test result is true */
1031 if (res)
1032 cpu->pc = new_pc;
1033 else
1034 cpu->pc += 8;
1035
1036 return(1);
1037 }
1038
1039 /* BNEL (Branch On Not Equal Likely) */
1040 static fastcall int mips64_exec_BNEL(cpu_mips_t *cpu,mips_insn_t insn)
1041 {
1042 int rs = bits(insn,21,25);
1043 int rt = bits(insn,16,20);
1044 int offset = bits(insn,0,15);
1045 m_uint64_t new_pc;
1046 int res;
1047
1048 /* compute the new pc */
1049 new_pc = (cpu->pc + 4) + sign_extend(offset << 2,18);
1050
1051 /* take the branch if gpr[rs] != gpr[rt] */
1052 res = (cpu->gpr[rs] != cpu->gpr[rt]);
1053
1054 /* take the branch if the test result is true */
1055 if (res) {
1056 mips64_exec_bdslot(cpu);
1057 cpu->pc = new_pc;
1058 } else
1059 cpu->pc += 8;
1060
1061 return(1);
1062 }
1063
1064 /* BREAK */
1065 static fastcall int mips64_exec_BREAK(cpu_mips_t *cpu,mips_insn_t insn)
1066 {
1067 u_int code = bits(insn,6,25);
1068
1069 mips64_exec_break(cpu,code);
1070 return(1);
1071 }
1072
1073 /* CACHE */
1074 static fastcall int mips64_exec_CACHE(cpu_mips_t *cpu,mips_insn_t insn)
1075 {
1076 int base = bits(insn,21,25);
1077 int op = bits(insn,16,20);
1078 int offset = bits(insn,0,15);
1079
1080 return(mips64_exec_memop2(cpu,MIPS_MEMOP_CACHE,base,offset,op,FALSE));
1081 }
1082
1083 /* CFC0 */
1084 static fastcall int mips64_exec_CFC0(cpu_mips_t *cpu,mips_insn_t insn)
1085 {
1086 int rt = bits(insn,16,20);
1087 int rd = bits(insn,11,15);
1088
1089 cp0_exec_cfc0(cpu,rt,rd);
1090 return(0);
1091 }
1092
1093 /* CTC0 */
1094 static fastcall int mips64_exec_CTC0(cpu_mips_t *cpu,mips_insn_t insn)
1095 {
1096 int rt = bits(insn,16,20);
1097 int rd = bits(insn,11,15);
1098
1099 cp0_exec_ctc0(cpu,rt,rd);
1100 return(0);
1101 }
1102
1103 /* DADDIU */
1104 static fastcall int mips64_exec_DADDIU(cpu_mips_t *cpu,mips_insn_t insn)
1105 {
1106 int rs = bits(insn,21,25);
1107 int rt = bits(insn,16,20);
1108 int imm = bits(insn,0,15);
1109 m_uint64_t val = sign_extend(imm,16);
1110
1111 cpu->gpr[rt] = cpu->gpr[rs] + val;
1112 return(0);
1113 }
1114
1115 /* DADDU: rd = rs + rt */
1116 static fastcall int mips64_exec_DADDU(cpu_mips_t *cpu,mips_insn_t insn)
1117 {
1118 int rs = bits(insn,21,25);
1119 int rt = bits(insn,16,20);
1120 int rd = bits(insn,11,15);
1121
1122 cpu->gpr[rd] = cpu->gpr[rs] + cpu->gpr[rt];
1123 return(0);
1124 }
1125
1126 /* DIV */
1127 static fastcall int mips64_exec_DIV(cpu_mips_t *cpu,mips_insn_t insn)
1128 {
1129 int rs = bits(insn,21,25);
1130 int rt = bits(insn,16,20);
1131
1132 cpu->lo = (m_int32_t)cpu->gpr[rs] / (m_int32_t)cpu->gpr[rt];
1133 cpu->hi = (m_int32_t)cpu->gpr[rs] % (m_int32_t)cpu->gpr[rt];
1134
1135 cpu->lo = sign_extend(cpu->lo,32);
1136 cpu->hi = sign_extend(cpu->hi,32);
1137 return(0);
1138 }
1139
1140 /* DIVU */
1141 static fastcall int mips64_exec_DIVU(cpu_mips_t *cpu,mips_insn_t insn)
1142 {
1143 int rs = bits(insn,21,25);
1144 int rt = bits(insn,16,20);
1145
1146 if (cpu->gpr[rt] == 0)
1147 return(0);
1148
1149 cpu->lo = (m_uint32_t)cpu->gpr[rs] / (m_uint32_t)cpu->gpr[rt];
1150 cpu->hi = (m_uint32_t)cpu->gpr[rs] % (m_uint32_t)cpu->gpr[rt];
1151
1152 cpu->lo = sign_extend(cpu->lo,32);
1153 cpu->hi = sign_extend(cpu->hi,32);
1154 return(0);
1155 }
1156
1157 /* DMFC0 */
1158 static fastcall int mips64_exec_DMFC0(cpu_mips_t *cpu,mips_insn_t insn)
1159 {
1160 int rt = bits(insn,16,20);
1161 int rd = bits(insn,11,15);
1162
1163 cp0_exec_dmfc0(cpu,rt,rd);
1164 return(0);
1165 }
1166
1167 /* DMFC1 */
1168 static fastcall int mips64_exec_DMFC1(cpu_mips_t *cpu,mips_insn_t insn)
1169 {
1170 int rt = bits(insn,16,20);
1171 int rd = bits(insn,11,15);
1172
1173 mips64_exec_dmfc1(cpu,rt,rd);
1174 return(0);
1175 }
1176
1177 /* DMTC0 */
1178 static fastcall int mips64_exec_DMTC0(cpu_mips_t *cpu,mips_insn_t insn)
1179 {
1180 int rt = bits(insn,16,20);
1181 int rd = bits(insn,11,15);
1182
1183 cp0_exec_dmtc0(cpu,rt,rd);
1184 return(0);
1185 }
1186
1187 /* DMTC1 */
1188 static fastcall int mips64_exec_DMTC1(cpu_mips_t *cpu,mips_insn_t insn)
1189 {
1190 int rt = bits(insn,16,20);
1191 int rd = bits(insn,11,15);
1192
1193 mips64_exec_dmtc1(cpu,rt,rd);
1194 return(0);
1195 }
1196
1197 /* DSLL */
1198 static fastcall int mips64_exec_DSLL(cpu_mips_t *cpu,mips_insn_t insn)
1199 {
1200 int rt = bits(insn,16,20);
1201 int rd = bits(insn,11,15);
1202 int sa = bits(insn,6,10);
1203
1204 cpu->gpr[rd] = cpu->gpr[rt] << sa;
1205 return(0);
1206 }
1207
1208 /* DSLL32 */
1209 static fastcall int mips64_exec_DSLL32(cpu_mips_t *cpu,mips_insn_t insn)
1210 {
1211 int rt = bits(insn,16,20);
1212 int rd = bits(insn,11,15);
1213 int sa = bits(insn,6,10);
1214
1215 cpu->gpr[rd] = cpu->gpr[rt] << (32 + sa);
1216 return(0);
1217 }
1218
1219 /* DSLLV */
1220 static fastcall int mips64_exec_DSLLV(cpu_mips_t *cpu,mips_insn_t insn)
1221 {
1222 int rs = bits(insn,21,25);
1223 int rt = bits(insn,16,20);
1224 int rd = bits(insn,11,15);
1225
1226 cpu->gpr[rd] = cpu->gpr[rt] << (cpu->gpr[rs] & 0x3f);
1227 return(0);
1228 }
1229
1230 /* DSRA */
1231 static fastcall int mips64_exec_DSRA(cpu_mips_t *cpu,mips_insn_t insn)
1232 {
1233 int rt = bits(insn,16,20);
1234 int rd = bits(insn,11,15);
1235 int sa = bits(insn,6,10);
1236
1237 cpu->gpr[rd] = (m_int64_t)cpu->gpr[rt] >> sa;
1238 return(0);
1239 }
1240
1241 /* DSRA32 */
1242 static fastcall int mips64_exec_DSRA32(cpu_mips_t *cpu,mips_insn_t insn)
1243 {
1244 int rt = bits(insn,16,20);
1245 int rd = bits(insn,11,15);
1246 int sa = bits(insn,6,10);
1247
1248 cpu->gpr[rd] = (m_int64_t)cpu->gpr[rt] >> (32 + sa);
1249 return(0);
1250 }
1251
1252 /* DSRAV */
1253 static fastcall int mips64_exec_DSRAV(cpu_mips_t *cpu,mips_insn_t insn)
1254 {
1255 int rs = bits(insn,21,25);
1256 int rt = bits(insn,16,20);
1257 int rd = bits(insn,11,15);
1258
1259 cpu->gpr[rd] = (m_int64_t)cpu->gpr[rt] >> (cpu->gpr[rs] & 0x3f);
1260 return(0);
1261 }
1262
1263 /* DSRL */
1264 static fastcall int mips64_exec_DSRL(cpu_mips_t *cpu,mips_insn_t insn)
1265 {
1266 int rt = bits(insn,16,20);
1267 int rd = bits(insn,11,15);
1268 int sa = bits(insn,6,10);
1269
1270 cpu->gpr[rd] = cpu->gpr[rt] >> sa;
1271 return(0);
1272 }
1273
1274 /* DSRL32 */
1275 static fastcall int mips64_exec_DSRL32(cpu_mips_t *cpu,mips_insn_t insn)
1276 {
1277 int rt = bits(insn,16,20);
1278 int rd = bits(insn,11,15);
1279 int sa = bits(insn,6,10);
1280
1281 cpu->gpr[rd] = cpu->gpr[rt] >> (32 + sa);
1282 return(0);
1283 }
1284
1285 /* DSRLV */
1286 static fastcall int mips64_exec_DSRLV(cpu_mips_t *cpu,mips_insn_t insn)
1287 {
1288 int rs = bits(insn,21,25);
1289 int rt = bits(insn,16,20);
1290 int rd = bits(insn,11,15);
1291
1292 cpu->gpr[rd] = cpu->gpr[rt] >> (cpu->gpr[rs] & 0x3f);
1293 return(0);
1294 }
1295
1296 /* DSUBU */
1297 static fastcall int mips64_exec_DSUBU(cpu_mips_t *cpu,mips_insn_t insn)
1298 {
1299 int rs = bits(insn,21,25);
1300 int rt = bits(insn,16,20);
1301 int rd = bits(insn,11,15);
1302
1303 cpu->gpr[rd] = cpu->gpr[rs] - cpu->gpr[rt];
1304 return(0);
1305 }
1306
1307 /* ERET */
1308 static fastcall int mips64_exec_ERET(cpu_mips_t *cpu,mips_insn_t insn)
1309 {
1310 mips64_exec_eret(cpu);
1311 return(1);
1312 }
1313
1314 /* J */
1315 static fastcall int mips64_exec_J(cpu_mips_t *cpu,mips_insn_t insn)
1316 {
1317 u_int instr_index = bits(insn,0,25);
1318 m_uint64_t new_pc;
1319
1320 /* compute the new pc */
1321 new_pc = cpu->pc & ~((1 << 28) - 1);
1322 new_pc |= instr_index << 2;
1323
1324 /* exec the instruction in the delay slot */
1325 mips64_exec_bdslot(cpu);
1326
1327 /* set the new pc */
1328 cpu->pc = new_pc;
1329 return(1);
1330 }
1331
1332 /* JAL */
1333 static fastcall int mips64_exec_JAL(cpu_mips_t *cpu,mips_insn_t insn)
1334 {
1335 u_int instr_index = bits(insn,0,25);
1336 m_uint64_t new_pc;
1337
1338 /* compute the new pc */
1339 new_pc = cpu->pc & ~((1 << 28) - 1);
1340 new_pc |= instr_index << 2;
1341
1342 /* set the return address (instruction after the delay slot) */
1343 cpu->gpr[MIPS_GPR_RA] = cpu->pc + 8;
1344
1345 /* exec the instruction in the delay slot */
1346 mips64_exec_bdslot(cpu);
1347
1348 /* set the new pc */
1349 cpu->pc = new_pc;
1350 return(1);
1351 }
1352
1353 /* JALR */
1354 static fastcall int mips64_exec_JALR(cpu_mips_t *cpu,mips_insn_t insn)
1355 {
1356 int rs = bits(insn,21,25);
1357 int rd = bits(insn,11,15);
1358 m_uint64_t new_pc;
1359
1360 /* set the return pc (instruction after the delay slot) in GPR[rd] */
1361 cpu->gpr[rd] = cpu->pc + 8;
1362
1363 /* get the new pc */
1364 new_pc = cpu->gpr[rs];
1365
1366 /* exec the instruction in the delay slot */
1367 mips64_exec_bdslot(cpu);
1368
1369 /* set the new pc */
1370 cpu->pc = new_pc;
1371 return(1);
1372 }
1373
1374 /* JR */
1375 static fastcall int mips64_exec_JR(cpu_mips_t *cpu,mips_insn_t insn)
1376 {
1377 int rs = bits(insn,21,25);
1378 m_uint64_t new_pc;
1379
1380 /* get the new pc */
1381 new_pc = cpu->gpr[rs];
1382
1383 /* exec the instruction in the delay slot */
1384 mips64_exec_bdslot(cpu);
1385
1386 /* set the new pc */
1387 cpu->pc = new_pc;
1388 return(1);
1389 }
1390
1391 /* LB (Load Byte) */
1392 static fastcall int mips64_exec_LB(cpu_mips_t *cpu,mips_insn_t insn)
1393 {
1394 int base = bits(insn,21,25);
1395 int rt = bits(insn,16,20);
1396 int offset = bits(insn,0,15);
1397
1398 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LB,base,offset,rt,TRUE));
1399 }
1400
1401 /* LBU (Load Byte Unsigned) */
1402 static fastcall int mips64_exec_LBU(cpu_mips_t *cpu,mips_insn_t insn)
1403 {
1404 int base = bits(insn,21,25);
1405 int rt = bits(insn,16,20);
1406 int offset = bits(insn,0,15);
1407
1408 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LBU,base,offset,rt,TRUE));
1409 }
1410
1411 /* LD (Load Double-Word) */
1412 static fastcall int mips64_exec_LD(cpu_mips_t *cpu,mips_insn_t insn)
1413 {
1414 int base = bits(insn,21,25);
1415 int rt = bits(insn,16,20);
1416 int offset = bits(insn,0,15);
1417
1418 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LD,base,offset,rt,TRUE));
1419 }
1420
1421 /* LDC1 (Load Double-Word to Coprocessor 1) */
1422 static fastcall int mips64_exec_LDC1(cpu_mips_t *cpu,mips_insn_t insn)
1423 {
1424 int base = bits(insn,21,25);
1425 int ft = bits(insn,16,20);
1426 int offset = bits(insn,0,15);
1427
1428 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LDC1,base,offset,ft,TRUE));
1429 }
1430
1431 /* LDL (Load Double-Word Left) */
1432 static fastcall int mips64_exec_LDL(cpu_mips_t *cpu,mips_insn_t insn)
1433 {
1434 int base = bits(insn,21,25);
1435 int rt = bits(insn,16,20);
1436 int offset = bits(insn,0,15);
1437
1438 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LDL,base,offset,rt,TRUE));
1439 }
1440
1441 /* LDR (Load Double-Word Right) */
1442 static fastcall int mips64_exec_LDR(cpu_mips_t *cpu,mips_insn_t insn)
1443 {
1444 int base = bits(insn,21,25);
1445 int rt = bits(insn,16,20);
1446 int offset = bits(insn,0,15);
1447
1448 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LDR,base,offset,rt,TRUE));
1449 }
1450
1451 /* LH (Load Half-Word) */
1452 static fastcall int mips64_exec_LH(cpu_mips_t *cpu,mips_insn_t insn)
1453 {
1454 int base = bits(insn,21,25);
1455 int rt = bits(insn,16,20);
1456 int offset = bits(insn,0,15);
1457
1458 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LH,base,offset,rt,TRUE));
1459 }
1460
1461 /* LHU (Load Half-Word Unsigned) */
1462 static fastcall int mips64_exec_LHU(cpu_mips_t *cpu,mips_insn_t insn)
1463 {
1464 int base = bits(insn,21,25);
1465 int rt = bits(insn,16,20);
1466 int offset = bits(insn,0,15);
1467
1468 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LHU,base,offset,rt,TRUE));
1469 }
1470
1471 /* LI (virtual) */
1472 static fastcall int mips64_exec_LI(cpu_mips_t *cpu,mips_insn_t insn)
1473 {
1474 int rt = bits(insn,16,20);
1475 int imm = bits(insn,0,15);
1476
1477 cpu->gpr[rt] = sign_extend(imm,16);
1478 return(0);
1479 }
1480
1481 /* LL (Load Linked) */
1482 static fastcall int mips64_exec_LL(cpu_mips_t *cpu,mips_insn_t insn)
1483 {
1484 int base = bits(insn,21,25);
1485 int rt = bits(insn,16,20);
1486 int offset = bits(insn,0,15);
1487
1488 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LL,base,offset,rt,TRUE));
1489 }
1490
1491 /* LUI */
1492 static fastcall int mips64_exec_LUI(cpu_mips_t *cpu,mips_insn_t insn)
1493 {
1494 int rt = bits(insn,16,20);
1495 int imm = bits(insn,0,15);
1496
1497 cpu->gpr[rt] = sign_extend(imm,16) << 16;
1498 return(0);
1499 }
1500
1501 /* LW (Load Word) */
1502 static fastcall int mips64_exec_LW(cpu_mips_t *cpu,mips_insn_t insn)
1503 {
1504 int base = bits(insn,21,25);
1505 int rt = bits(insn,16,20);
1506 int offset = bits(insn,0,15);
1507
1508 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LW,base,offset,rt,TRUE));
1509 }
1510
1511 /* LWL (Load Word Left) */
1512 static fastcall int mips64_exec_LWL(cpu_mips_t *cpu,mips_insn_t insn)
1513 {
1514 int base = bits(insn,21,25);
1515 int rt = bits(insn,16,20);
1516 int offset = bits(insn,0,15);
1517
1518 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LWL,base,offset,rt,TRUE));
1519 }
1520
1521 /* LWR (Load Word Right) */
1522 static fastcall int mips64_exec_LWR(cpu_mips_t *cpu,mips_insn_t insn)
1523 {
1524 int base = bits(insn,21,25);
1525 int rt = bits(insn,16,20);
1526 int offset = bits(insn,0,15);
1527
1528 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LWR,base,offset,rt,TRUE));
1529 }
1530
1531 /* LWU (Load Word Unsigned) */
1532 static fastcall int mips64_exec_LWU(cpu_mips_t *cpu,mips_insn_t insn)
1533 {
1534 int base = bits(insn,21,25);
1535 int rt = bits(insn,16,20);
1536 int offset = bits(insn,0,15);
1537
1538 return(mips64_exec_memop2(cpu,MIPS_MEMOP_LWU,base,offset,rt,TRUE));
1539 }
1540
1541 /* MFC0 */
1542 static fastcall int mips64_exec_MFC0(cpu_mips_t *cpu,mips_insn_t insn)
1543 {
1544 int rt = bits(insn,16,20);
1545 int rd = bits(insn,11,15);
1546
1547 cp0_exec_mfc0(cpu,rt,rd);
1548 return(0);
1549 }
1550
1551 /* MFC1 */
1552 static fastcall int mips64_exec_MFC1(cpu_mips_t *cpu,mips_insn_t insn)
1553 {
1554 int rt = bits(insn,16,20);
1555 int rd = bits(insn,11,15);
1556
1557 mips64_exec_mfc1(cpu,rt,rd);
1558 return(0);
1559 }
1560
1561 /* MFHI */
1562 static fastcall int mips64_exec_MFHI(cpu_mips_t *cpu,mips_insn_t insn)
1563 {
1564 int rd = bits(insn,11,15);
1565
1566 if (rd) cpu->gpr[rd] = cpu->hi;
1567 return(0);
1568 }
1569
1570 /* MFLO */
1571 static fastcall int mips64_exec_MFLO(cpu_mips_t *cpu,mips_insn_t insn)
1572 {
1573 int rd = bits(insn,11,15);
1574
1575 if (rd) cpu->gpr[rd] = cpu->lo;
1576 return(0);
1577 }
1578
1579 /* MOVE (virtual instruction, real: ADDU) */
1580 static fastcall int mips64_exec_MOVE(cpu_mips_t *cpu,mips_insn_t insn)
1581 {
1582 int rs = bits(insn,21,25);
1583 int rd = bits(insn,11,15);
1584
1585 cpu->gpr[rd] = sign_extend(cpu->gpr[rs],32);
1586 return(0);
1587 }
1588
1589 /* MTC0 */
1590 static fastcall int mips64_exec_MTC0(cpu_mips_t *cpu,mips_insn_t insn)
1591 {
1592 int rt = bits(insn,16,20);
1593 int rd = bits(insn,11,15);
1594
1595 cp0_exec_mtc0(cpu,rt,rd);
1596 return(0);
1597 }
1598
1599 /* MTC1 */
1600 static fastcall int mips64_exec_MTC1(cpu_mips_t *cpu,mips_insn_t insn)
1601 {
1602 int rt = bits(insn,16,20);
1603 int rd = bits(insn,11,15);
1604
1605 mips64_exec_mtc1(cpu,rt,rd);
1606 return(0);
1607 }
1608
1609 /* MTHI */
1610 static fastcall int mips64_exec_MTHI(cpu_mips_t *cpu,mips_insn_t insn)
1611 {
1612 int rs = bits(insn,21,25);
1613
1614 cpu->hi = cpu->gpr[rs];
1615 return(0);
1616 }
1617
1618 /* MTLO */
1619 static fastcall int mips64_exec_MTLO(cpu_mips_t *cpu,mips_insn_t insn)
1620 {
1621 int rs = bits(insn,21,25);
1622
1623 cpu->lo = cpu->gpr[rs];
1624 return(0);
1625 }
1626
1627 /* MUL */
1628 static fastcall int mips64_exec_MUL(cpu_mips_t *cpu,mips_insn_t insn)
1629 {
1630 int rs = bits(insn,21,25);
1631 int rt = bits(insn,16,20);
1632 int rd = bits(insn,11,15);
1633 m_int32_t val;
1634
1635 /* note: after this instruction, HI/LO regs are undefined */
1636 val = (m_int32_t)cpu->gpr[rs] * (m_int32_t)cpu->gpr[rt];
1637 cpu->gpr[rd] = sign_extend(val,32);
1638 return(0);
1639 }
1640
1641 /* MULT */
1642 static fastcall int mips64_exec_MULT(cpu_mips_t *cpu,mips_insn_t insn)
1643 {
1644 int rs = bits(insn,21,25);
1645 int rt = bits(insn,16,20);
1646 m_int64_t val;
1647
1648 val = (m_int64_t)(m_int32_t)cpu->gpr[rs];
1649 val *= (m_int64_t)(m_int32_t)cpu->gpr[rt];
1650
1651 cpu->lo = sign_extend(val,32);
1652 cpu->hi = sign_extend(val >> 32,32);
1653 return(0);
1654 }
1655
1656 /* MULTU */
1657 static fastcall int mips64_exec_MULTU(cpu_mips_t *cpu,mips_insn_t insn)
1658 {
1659 int rs = bits(insn,21,25);
1660 int rt = bits(insn,16,20);
1661 m_uint64_t val;
1662
1663 val = (m_uint64_t)(m_uint32_t)cpu->gpr[rs];
1664 val *= (m_uint64_t)(m_uint32_t)cpu->gpr[rt];
1665 cpu->lo = sign_extend(val,32);
1666 cpu->hi = sign_extend(val >> 32,32);
1667 return(0);
1668 }
1669
1670 /* NOP */
1671 static fastcall int mips64_exec_NOP(cpu_mips_t *cpu,mips_insn_t insn)
1672 {
1673 return(0);
1674 }
1675
1676 /* NOR */
1677 static fastcall int mips64_exec_NOR(cpu_mips_t *cpu,mips_insn_t insn)
1678 {
1679 int rs = bits(insn,21,25);
1680 int rt = bits(insn,16,20);
1681 int rd = bits(insn,11,15);
1682
1683 cpu->gpr[rd] = ~(cpu->gpr[rs] | cpu->gpr[rt]);
1684 return(0);
1685 }
1686
1687 /* OR */
1688 static fastcall int mips64_exec_OR(cpu_mips_t *cpu,mips_insn_t insn)
1689 {
1690 int rs = bits(insn,21,25);
1691 int rt = bits(insn,16,20);
1692 int rd = bits(insn,11,15);
1693
1694 cpu->gpr[rd] = cpu->gpr[rs] | cpu->gpr[rt];
1695 return(0);
1696 }
1697
1698 /* ORI */
1699 static fastcall int mips64_exec_ORI(cpu_mips_t *cpu,mips_insn_t insn)
1700 {
1701 int rs = bits(insn,21,25);
1702 int rt = bits(insn,16,20);
1703 int imm = bits(insn,0,15);
1704
1705 cpu->gpr[rt] = cpu->gpr[rs] | imm;
1706 return(0);
1707 }
1708
1709 /* PREF */
1710 static fastcall int mips64_exec_PREF(cpu_mips_t *cpu,mips_insn_t insn)
1711 {
1712 return(0);
1713 }
1714
1715 /* PREFI */
1716 static fastcall int mips64_exec_PREFI(cpu_mips_t *cpu,mips_insn_t insn)
1717 {
1718 return(0);
1719 }
1720
1721 /* SB (Store Byte) */
1722 static fastcall int mips64_exec_SB(cpu_mips_t *cpu,mips_insn_t insn)
1723 {
1724 int base = bits(insn,21,25);
1725 int rt = bits(insn,16,20);
1726 int offset = bits(insn,0,15);
1727
1728 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SB,base,offset,rt,FALSE));
1729 }
1730
1731 /* SC (Store Conditional) */
1732 static fastcall int mips64_exec_SC(cpu_mips_t *cpu,mips_insn_t insn)
1733 {
1734 int base = bits(insn,21,25);
1735 int rt = bits(insn,16,20);
1736 int offset = bits(insn,0,15);
1737
1738 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SC,base,offset,rt,TRUE));
1739 }
1740
1741 /* SD (Store Double-Word) */
1742 static fastcall int mips64_exec_SD(cpu_mips_t *cpu,mips_insn_t insn)
1743 {
1744 int base = bits(insn,21,25);
1745 int rt = bits(insn,16,20);
1746 int offset = bits(insn,0,15);
1747
1748 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SD,base,offset,rt,FALSE));
1749 }
1750
1751 /* SDL (Store Double-Word Left) */
1752 static fastcall int mips64_exec_SDL(cpu_mips_t *cpu,mips_insn_t insn)
1753 {
1754 int base = bits(insn,21,25);
1755 int rt = bits(insn,16,20);
1756 int offset = bits(insn,0,15);
1757
1758 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SDL,base,offset,rt,FALSE));
1759 }
1760
1761 /* SDR (Store Double-Word Right) */
1762 static fastcall int mips64_exec_SDR(cpu_mips_t *cpu,mips_insn_t insn)
1763 {
1764 int base = bits(insn,21,25);
1765 int rt = bits(insn,16,20);
1766 int offset = bits(insn,0,15);
1767
1768 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SDR,base,offset,rt,FALSE));
1769 }
1770
1771 /* SDC1 (Store Double-Word from Coprocessor 1) */
1772 static fastcall int mips64_exec_SDC1(cpu_mips_t *cpu,mips_insn_t insn)
1773 {
1774 int base = bits(insn,21,25);
1775 int ft = bits(insn,16,20);
1776 int offset = bits(insn,0,15);
1777
1778 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SDC1,base,offset,ft,FALSE));
1779 }
1780
1781 /* SH (Store Half-Word) */
1782 static fastcall int mips64_exec_SH(cpu_mips_t *cpu,mips_insn_t insn)
1783 {
1784 int base = bits(insn,21,25);
1785 int rt = bits(insn,16,20);
1786 int offset = bits(insn,0,15);
1787
1788 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SH,base,offset,rt,FALSE));
1789 }
1790
1791 /* SLL */
1792 static fastcall int mips64_exec_SLL(cpu_mips_t *cpu,mips_insn_t insn)
1793 {
1794 int rt = bits(insn,16,20);
1795 int rd = bits(insn,11,15);
1796 int sa = bits(insn,6,10);
1797 m_uint32_t res;
1798
1799 res = (m_uint32_t)cpu->gpr[rt] << sa;
1800 cpu->gpr[rd] = sign_extend(res,32);
1801 return(0);
1802 }
1803
1804 /* SLLV */
1805 static fastcall int mips64_exec_SLLV(cpu_mips_t *cpu,mips_insn_t insn)
1806 {
1807 int rs = bits(insn,21,25);
1808 int rt = bits(insn,16,20);
1809 int rd = bits(insn,11,15);
1810 m_uint32_t res;
1811
1812 res = (m_uint32_t)cpu->gpr[rt] << (cpu->gpr[rs] & 0x1f);
1813 cpu->gpr[rd] = sign_extend(res,32);
1814 return(0);
1815 }
1816
1817 /* SLT */
1818 static fastcall int mips64_exec_SLT(cpu_mips_t *cpu,mips_insn_t insn)
1819 {
1820 int rs = bits(insn,21,25);
1821 int rt = bits(insn,16,20);
1822 int rd = bits(insn,11,15);
1823
1824 if ((m_int64_t)cpu->gpr[rs] < (m_int64_t)cpu->gpr[rt])
1825 cpu->gpr[rd] = 1;
1826 else
1827 cpu->gpr[rd] = 0;
1828
1829 return(0);
1830 }
1831
1832 /* SLTI */
1833 static fastcall int mips64_exec_SLTI(cpu_mips_t *cpu,mips_insn_t insn)
1834 {
1835 int rs = bits(insn,21,25);
1836 int rt = bits(insn,16,20);
1837 int imm = bits(insn,0,15);
1838 m_int64_t val = sign_extend(imm,16);
1839
1840 if ((m_int64_t)cpu->gpr[rs] < val)
1841 cpu->gpr[rt] = 1;
1842 else
1843 cpu->gpr[rt] = 0;
1844
1845 return(0);
1846 }
1847
1848 /* SLTIU */
1849 static fastcall int mips64_exec_SLTIU(cpu_mips_t *cpu,mips_insn_t insn)
1850 {
1851 int rs = bits(insn,21,25);
1852 int rt = bits(insn,16,20);
1853 int imm = bits(insn,0,15);
1854 m_uint64_t val = sign_extend(imm,16);
1855
1856 if (cpu->gpr[rs] < val)
1857 cpu->gpr[rt] = 1;
1858 else
1859 cpu->gpr[rt] = 0;
1860
1861 return(0);
1862 }
1863
1864 /* SLTU */
1865 static fastcall int mips64_exec_SLTU(cpu_mips_t *cpu,mips_insn_t insn)
1866 {
1867 int rs = bits(insn,21,25);
1868 int rt = bits(insn,16,20);
1869 int rd = bits(insn,11,15);
1870
1871 if (cpu->gpr[rs] < cpu->gpr[rt])
1872 cpu->gpr[rd] = 1;
1873 else
1874 cpu->gpr[rd] = 0;
1875
1876 return(0);
1877 }
1878
1879 /* SRA */
1880 static fastcall int mips64_exec_SRA(cpu_mips_t *cpu,mips_insn_t insn)
1881 {
1882 int rt = bits(insn,16,20);
1883 int rd = bits(insn,11,15);
1884 int sa = bits(insn,6,10);
1885 m_int32_t res;
1886
1887 res = (m_int32_t)cpu->gpr[rt] >> sa;
1888 cpu->gpr[rd] = sign_extend(res,32);
1889 return(0);
1890 }
1891
1892 /* SRAV */
1893 static fastcall int mips64_exec_SRAV(cpu_mips_t *cpu,mips_insn_t insn)
1894 {
1895 int rs = bits(insn,21,25);
1896 int rt = bits(insn,16,20);
1897 int rd = bits(insn,11,15);
1898 m_int32_t res;
1899
1900 res = (m_int32_t)cpu->gpr[rt] >> (cpu->gpr[rs] & 0x1f);
1901 cpu->gpr[rd] = sign_extend(res,32);
1902 return(0);
1903 }
1904
1905 /* SRL */
1906 static fastcall int mips64_exec_SRL(cpu_mips_t *cpu,mips_insn_t insn)
1907 {
1908 int rt = bits(insn,16,20);
1909 int rd = bits(insn,11,15);
1910 int sa = bits(insn,6,10);
1911 m_uint32_t res;
1912
1913 res = (m_uint32_t)cpu->gpr[rt] >> sa;
1914 cpu->gpr[rd] = sign_extend(res,32);
1915 return(0);
1916 }
1917
1918 /* SRLV */
1919 static fastcall int mips64_exec_SRLV(cpu_mips_t *cpu,mips_insn_t insn)
1920 {
1921 int rs = bits(insn,21,25);
1922 int rt = bits(insn,16,20);
1923 int rd = bits(insn,11,15);
1924 m_uint32_t res;
1925
1926 res = (m_uint32_t)cpu->gpr[rt] >> (cpu->gpr[rs] & 0x1f);
1927 cpu->gpr[rd] = sign_extend(res,32);
1928 return(0);
1929 }
1930
1931 /* SUB */
1932 static fastcall int mips64_exec_SUB(cpu_mips_t *cpu,mips_insn_t insn)
1933 {
1934 int rs = bits(insn,21,25);
1935 int rt = bits(insn,16,20);
1936 int rd = bits(insn,11,15);
1937 m_uint32_t res;
1938
1939 /* TODO: Exception handling */
1940 res = (m_uint32_t)cpu->gpr[rs] - (m_uint32_t)cpu->gpr[rt];
1941 cpu->gpr[rd] = sign_extend(res,32);
1942 return(0);
1943 }
1944
1945 /* SUBU */
1946 static fastcall int mips64_exec_SUBU(cpu_mips_t *cpu,mips_insn_t insn)
1947 {
1948 int rs = bits(insn,21,25);
1949 int rt = bits(insn,16,20);
1950 int rd = bits(insn,11,15);
1951 m_uint32_t res;
1952
1953 res = (m_uint32_t)cpu->gpr[rs] - (m_uint32_t)cpu->gpr[rt];
1954 cpu->gpr[rd] = sign_extend(res,32);
1955 return(0);
1956 }
1957
1958 /* SW (Store Word) */
1959 static fastcall int mips64_exec_SW(cpu_mips_t *cpu,mips_insn_t insn)
1960 {
1961 int base = bits(insn,21,25);
1962 int rt = bits(insn,16,20);
1963 int offset = bits(insn,0,15);
1964
1965 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SW,base,offset,rt,FALSE));
1966 }
1967
1968 /* SWL (Store Word Left) */
1969 static fastcall int mips64_exec_SWL(cpu_mips_t *cpu,mips_insn_t insn)
1970 {
1971 int base = bits(insn,21,25);
1972 int rt = bits(insn,16,20);
1973 int offset = bits(insn,0,15);
1974
1975 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SWL,base,offset,rt,FALSE));
1976 }
1977
1978 /* SWR (Store Word Right) */
1979 static fastcall int mips64_exec_SWR(cpu_mips_t *cpu,mips_insn_t insn)
1980 {
1981 int base = bits(insn,21,25);
1982 int rt = bits(insn,16,20);
1983 int offset = bits(insn,0,15);
1984
1985 return(mips64_exec_memop2(cpu,MIPS_MEMOP_SWR,base,offset,rt,FALSE));
1986 }
1987
1988 /* SYNC */
1989 static fastcall int mips64_exec_SYNC(cpu_mips_t *cpu,mips_insn_t insn)
1990 {
1991 return(0);
1992 }
1993
1994 /* SYSCALL */
1995 static fastcall int mips64_exec_SYSCALL(cpu_mips_t *cpu,mips_insn_t insn)
1996 {
1997 mips64_exec_syscall(cpu);
1998 return(1);
1999 }
2000
2001 /* TEQ (Trap if Equal) */
2002 static fastcall int mips64_exec_TEQ(cpu_mips_t *cpu,mips_insn_t insn)
2003 {
2004 int rs = bits(insn,21,25);
2005 int rt = bits(insn,16,20);
2006
2007 if (unlikely(cpu->gpr[rs] == cpu->gpr[rt])) {
2008 mips64_trigger_trap_exception(cpu);
2009 return(1);
2010 }
2011
2012 return(0);
2013 }
2014
2015 /* TEQI (Trap if Equal Immediate) */
2016 static fastcall int mips64_exec_TEQI(cpu_mips_t *cpu,mips_insn_t insn)
2017 {
2018 int rs = bits(insn,21,25);
2019 int imm = bits(insn,0,15);
2020 m_uint64_t val = sign_extend(imm,16);
2021
2022 if (unlikely(cpu->gpr[rs] == val)) {
2023 mips64_trigger_trap_exception(cpu);
2024 return(1);
2025 }
2026
2027 return(0);
2028 }
2029
2030 /* TLBP */
2031 static fastcall int mips64_exec_TLBP(cpu_mips_t *cpu,mips_insn_t insn)
2032 {
2033 cp0_exec_tlbp(cpu);
2034 return(0);
2035 }
2036
2037 /* TLBR */
2038 static fastcall int mips64_exec_TLBR(cpu_mips_t *cpu,mips_insn_t insn)
2039 {
2040 cp0_exec_tlbr(cpu);
2041 return(0);
2042 }
2043
2044 /* TLBWI */
2045 static fastcall int mips64_exec_TLBWI(cpu_mips_t *cpu,mips_insn_t insn)
2046 {
2047 cp0_exec_tlbwi(cpu);
2048 return(0);
2049 }
2050
2051 /* TLBWR */
2052 static fastcall int mips64_exec_TLBWR(cpu_mips_t *cpu,mips_insn_t insn)
2053 {
2054 cp0_exec_tlbwr(cpu);
2055 return(0);
2056 }
2057
2058 /* XOR */
2059 static fastcall int mips64_exec_XOR(cpu_mips_t *cpu,mips_insn_t insn)
2060 {
2061 int rs = bits(insn,21,25);
2062 int rt = bits(insn,16,20);
2063 int rd = bits(insn,11,15);
2064
2065 cpu->gpr[rd] = cpu->gpr[rs] ^ cpu->gpr[rt];
2066 return(0);
2067 }
2068
2069 /* XORI */
2070 static fastcall int mips64_exec_XORI(cpu_mips_t *cpu,mips_insn_t insn)
2071 {
2072 int rs = bits(insn,21,25);
2073 int rt = bits(insn,16,20);
2074 int imm = bits(insn,0,15);
2075
2076 cpu->gpr[rt] = cpu->gpr[rs] ^ imm;
2077 return(0);
2078 }
2079
2080 /* MIPS instruction array */
2081 static struct insn_exec_tag mips64_exec_tags[] = {
2082 { "li" , mips64_exec_LI , 0xffe00000 , 0x24000000, 1, 16 },
2083 { "move" , mips64_exec_MOVE , 0xfc1f07ff , 0x00000021, 1, 15 },
2084 { "b" , mips64_exec_B , 0xffff0000 , 0x10000000, 0, 10 },
2085 { "bal" , mips64_exec_BAL , 0xffff0000 , 0x04110000, 0, 10 },
2086 { "beqz" , mips64_exec_BEQZ , 0xfc1f0000 , 0x10000000, 0, 9 },
2087 { "bnez" , mips64_exec_BNEZ , 0xfc1f0000 , 0x14000000, 0, 9 },
2088 { "add" , mips64_exec_ADD , 0xfc0007ff , 0x00000020, 1, 3 },
2089 { "addi" , mips64_exec_ADDI , 0xfc000000 , 0x20000000, 1, 6 },
2090 { "addiu" , mips64_exec_ADDIU , 0xfc000000 , 0x24000000, 1, 6 },
2091 { "addu" , mips64_exec_ADDU , 0xfc0007ff , 0x00000021, 1, 3 },
2092 { "and" , mips64_exec_AND , 0xfc0007ff , 0x00000024, 1, 3 },
2093 { "andi" , mips64_exec_ANDI , 0xfc000000 , 0x30000000, 1, 5 },
2094 { "beq" , mips64_exec_BEQ , 0xfc000000 , 0x10000000, 0, 8 },
2095 { "beql" , mips64_exec_BEQL , 0xfc000000 , 0x50000000, 0, 8 },
2096 { "bgez" , mips64_exec_BGEZ , 0xfc1f0000 , 0x04010000, 0, 9 },
2097 { "bgezal" , mips64_exec_BGEZAL , 0xfc1f0000 , 0x04110000, 0, 9 },
2098 { "bgezall", mips64_exec_BGEZALL , 0xfc1f0000 , 0x04130000, 0, 9 },
2099 { "bgezl" , mips64_exec_BGEZL , 0xfc1f0000 , 0x04030000, 0, 9 },
2100 { "bgtz" , mips64_exec_BGTZ , 0xfc1f0000 , 0x1c000000, 0, 9 },
2101 { "bgtzl" , mips64_exec_BGTZL , 0xfc1f0000 , 0x5c000000, 0, 9 },
2102 { "blez" , mips64_exec_BLEZ , 0xfc1f0000 , 0x18000000, 0, 9 },
2103 { "blezl" , mips64_exec_BLEZL , 0xfc1f0000 , 0x58000000, 0, 9 },
2104 { "bltz" , mips64_exec_BLTZ , 0xfc1f0000 , 0x04000000, 0, 9 },
2105 { "bltzal" , mips64_exec_BLTZAL , 0xfc1f0000 , 0x04100000, 0, 9 },
2106 { "bltzall", mips64_exec_BLTZALL , 0xfc1f0000 , 0x04120000, 0, 9 },
2107 { "bltzl" , mips64_exec_BLTZL , 0xfc1f0000 , 0x04020000, 0, 9 },
2108 { "bne" , mips64_exec_BNE , 0xfc000000 , 0x14000000, 0, 8 },
2109 { "bnel" , mips64_exec_BNEL , 0xfc000000 , 0x54000000, 0, 8 },
2110 { "break" , mips64_exec_BREAK , 0xfc00003f , 0x0000000d, 1, 0 },
2111 { "cache" , mips64_exec_CACHE , 0xfc000000 , 0xbc000000, 1, 2 },
2112 { "cfc0" , mips64_exec_CFC0 , 0xffe007ff , 0x40400000, 1, 18 },
2113 { "ctc0" , mips64_exec_CTC0 , 0xffe007ff , 0x40600000, 1, 18 },
2114 { "daddiu" , mips64_exec_DADDIU , 0xfc000000 , 0x64000000, 1, 5 },
2115 { "daddu" , mips64_exec_DADDU , 0xfc0007ff , 0x0000002d, 1, 3 },
2116 { "div" , mips64_exec_DIV , 0xfc00ffff , 0x0000001a, 1, 17 },
2117 { "divu" , mips64_exec_DIVU , 0xfc00ffff , 0x0000001b, 1, 17 },
2118 { "dmfc0" , mips64_exec_DMFC0 , 0xffe007f8 , 0x40200000, 1, 18 },
2119 { "dmfc1" , mips64_exec_DMFC1 , 0xffe007ff , 0x44200000, 1, 19 },
2120 { "dmtc0" , mips64_exec_DMTC0 , 0xffe007f8 , 0x40a00000, 1, 18 },
2121 { "dmtc1" , mips64_exec_DMTC1 , 0xffe007ff , 0x44a00000, 1, 19 },
2122 { "dsll" , mips64_exec_DSLL , 0xffe0003f , 0x00000038, 1, 7 },
2123 { "dsll32" , mips64_exec_DSLL32 , 0xffe0003f , 0x0000003c, 1, 7 },
2124 { "dsllv" , mips64_exec_DSLLV , 0xfc0007ff , 0x00000014, 1, 4 },
2125 { "dsra" , mips64_exec_DSRA , 0xffe0003f , 0x0000003b, 1, 7 },
2126 { "dsra32" , mips64_exec_DSRA32 , 0xffe0003f , 0x0000003f, 1, 7 },
2127 { "dsrav" , mips64_exec_DSRAV , 0xfc0007ff , 0x00000017, 1, 4 },
2128 { "dsrl" , mips64_exec_DSRL , 0xffe0003f , 0x0000003a, 1, 7 },
2129 { "dsrl32" , mips64_exec_DSRL32 , 0xffe0003f , 0x0000003e, 1, 7 },
2130 { "dsrlv" , mips64_exec_DSRLV , 0xfc0007ff , 0x00000016, 1, 4 },
2131 { "dsubu" , mips64_exec_DSUBU , 0xfc0007ff , 0x0000002f, 1, 3 },
2132 { "eret" , mips64_exec_ERET , 0xffffffff , 0x42000018, 0, 1 },
2133 { "j" , mips64_exec_J , 0xfc000000 , 0x08000000, 0, 11 },
2134 { "jal" , mips64_exec_JAL , 0xfc000000 , 0x0c000000, 0, 11 },
2135 { "jalr" , mips64_exec_JALR , 0xfc1f003f , 0x00000009, 0, 15 },
2136 { "jr" , mips64_exec_JR , 0xfc1ff83f , 0x00000008, 0, 13 },
2137 { "lb" , mips64_exec_LB , 0xfc000000 , 0x80000000, 1, 2 },
2138 { "lbu" , mips64_exec_LBU , 0xfc000000 , 0x90000000, 1, 2 },
2139 { "ld" , mips64_exec_LD , 0xfc000000 , 0xdc000000, 1, 2 },
2140 { "ldc1" , mips64_exec_LDC1 , 0xfc000000 , 0xd4000000, 1, 3 },
2141 { "ldl" , mips64_exec_LDL , 0xfc000000 , 0x68000000, 1, 2 },
2142 { "ldr" , mips64_exec_LDR , 0xfc000000 , 0x6c000000, 1, 2 },
2143 { "lh" , mips64_exec_LH , 0xfc000000 , 0x84000000, 1, 2 },
2144 { "lhu" , mips64_exec_LHU , 0xfc000000 , 0x94000000, 1, 2 },
2145 { "ll" , mips64_exec_LL , 0xfc000000 , 0xc0000000, 1, 2 },
2146 { "lui" , mips64_exec_LUI , 0xffe00000 , 0x3c000000, 1, 16 },
2147 { "lw" , mips64_exec_LW , 0xfc000000 , 0x8c000000, 1, 2 },
2148 { "lwl" , mips64_exec_LWL , 0xfc000000 , 0x88000000, 1, 2 },
2149 { "lwr" , mips64_exec_LWR , 0xfc000000 , 0x98000000, 1, 2 },
2150 { "lwu" , mips64_exec_LWU , 0xfc000000 , 0x9c000000, 1, 2 },
2151 { "mfc0" , mips64_exec_MFC0 , 0xffe007ff , 0x40000000, 1, 18 },
2152 { "mfc0_1" , mips64_exec_CFC0 , 0xffe007ff , 0x40000001, 1, 19 },
2153 { "mfc1" , mips64_exec_MFC1 , 0xffe007ff , 0x44000000, 1, 19 },
2154 { "mfhi" , mips64_exec_MFHI , 0xffff07ff , 0x00000010, 1, 14 },
2155 { "mflo" , mips64_exec_MFLO , 0xffff07ff , 0x00000012, 1, 14 },
2156 { "mtc0" , mips64_exec_MTC0 , 0xffe007ff , 0x40800000, 1, 18 },
2157 { "mtc1" , mips64_exec_MTC1 , 0xffe007ff , 0x44800000, 1, 19 },
2158 { "mthi" , mips64_exec_MTHI , 0xfc1fffff , 0x00000011, 1, 13 },
2159 { "mtlo" , mips64_exec_MTLO , 0xfc1fffff , 0x00000013, 1, 13 },
2160 { "mul" , mips64_exec_MUL , 0xfc0007ff , 0x70000002, 1, 4 },
2161 { "mult" , mips64_exec_MULT , 0xfc00ffff , 0x00000018, 1, 17 },
2162 { "multu" , mips64_exec_MULTU , 0xfc00ffff , 0x00000019, 1, 17 },
2163 { "nop" , mips64_exec_NOP , 0xffffffff , 0x00000000, 1, 1 },
2164 { "nor" , mips64_exec_NOR , 0xfc0007ff , 0x00000027, 1, 3 },
2165 { "or" , mips64_exec_OR , 0xfc0007ff , 0x00000025, 1, 3 },
2166 { "ori" , mips64_exec_ORI , 0xfc000000 , 0x34000000, 1, 5 },
2167 { "pref" , mips64_exec_PREF , 0xfc000000 , 0xcc000000, 1, 0 },
2168 { "prefi" , mips64_exec_PREFI , 0xfc0007ff , 0x4c00000f, 1, 0 },
2169 { "sb" , mips64_exec_SB , 0xfc000000 , 0xa0000000, 1, 2 },
2170 { "sc" , mips64_exec_SC , 0xfc000000 , 0xe0000000, 1, 2 },
2171 { "sd" , mips64_exec_SD , 0xfc000000 , 0xfc000000, 1, 2 },
2172 { "sdc1" , mips64_exec_SDC1 , 0xfc000000 , 0xf4000000, 1, 3 },
2173 { "sdl" , mips64_exec_SDL , 0xfc000000 , 0xb0000000, 1, 2 },
2174 { "sdr" , mips64_exec_SDR , 0xfc000000 , 0xb4000000, 1, 2 },
2175 { "sh" , mips64_exec_SH , 0xfc000000 , 0xa4000000, 1, 2 },
2176 { "sll" , mips64_exec_SLL , 0xffe0003f , 0x00000000, 1, 7 },
2177 { "sllv" , mips64_exec_SLLV , 0xfc0007ff , 0x00000004, 1, 4 },
2178 { "slt" , mips64_exec_SLT , 0xfc0007ff , 0x0000002a, 1, 3 },
2179 { "slti" , mips64_exec_SLTI , 0xfc000000 , 0x28000000, 1, 5 },
2180 { "sltiu" , mips64_exec_SLTIU , 0xfc000000 , 0x2c000000, 1, 5 },
2181 { "sltu" , mips64_exec_SLTU , 0xfc0007ff , 0x0000002b, 1, 3 },
2182 { "sra" , mips64_exec_SRA , 0xffe0003f , 0x00000003, 1, 7 },
2183 { "srav" , mips64_exec_SRAV , 0xfc0007ff , 0x00000007, 1, 4 },
2184 { "srl" , mips64_exec_SRL , 0xffe0003f , 0x00000002, 1, 7 },
2185 { "srlv" , mips64_exec_SRLV , 0xfc0007ff , 0x00000006, 1, 4 },
2186 { "sub" , mips64_exec_SUB , 0xfc0007ff , 0x00000022, 1, 3 },
2187 { "subu" , mips64_exec_SUBU , 0xfc0007ff , 0x00000023, 1, 3 },
2188 { "sw" , mips64_exec_SW , 0xfc000000 , 0xac000000, 1, 2 },
2189 { "swl" , mips64_exec_SWL , 0xfc000000 , 0xa8000000, 1, 2 },
2190 { "swr" , mips64_exec_SWR , 0xfc000000 , 0xb8000000, 1, 2 },
2191 { "sync" , mips64_exec_SYNC , 0xfffff83f , 0x0000000f, 1, 1 },
2192 { "syscall", mips64_exec_SYSCALL , 0xfc00003f , 0x0000000c, 1, 1 },
2193 { "teq" , mips64_exec_TEQ , 0xfc00003f , 0x00000034, 1, 17 },
2194 { "teqi" , mips64_exec_TEQI , 0xfc1f0000 , 0x040c0000, 1, 20 },
2195 { "tlbp" , mips64_exec_TLBP , 0xffffffff , 0x42000008, 1, 1 },
2196 { "tlbr" , mips64_exec_TLBR , 0xffffffff , 0x42000001, 1, 1 },
2197 { "tlbwi" , mips64_exec_TLBWI , 0xffffffff , 0x42000002, 1, 1 },
2198 { "tlbwr" , mips64_exec_TLBWR , 0xffffffff , 0x42000006, 1, 1 },
2199 { "xor" , mips64_exec_XOR , 0xfc0007ff , 0x00000026, 1, 3 },
2200 { "xori" , mips64_exec_XORI , 0xfc000000 , 0x38000000, 1, 5 },
2201 { NULL , NULL , 0x00000000 , 0x00000000, 1, 0 },
2202 };
2203
2204 #endif

  ViewVC Help
Powered by ViewVC 1.1.26