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

Parent Directory Parent Directory | Revision Log Revision Log


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

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

  ViewVC Help
Powered by ViewVC 1.1.26