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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Sat Oct 6 16:01:44 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.5/mips64_exec.c
File MIME type: text/plain
File size: 59708 byte(s)
import 0.2.5 from upstream

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

  ViewVC Help
Powered by ViewVC 1.1.26