/[dynamips]/upstream/dynamips-0.2.6-RC3/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

Annotation of /upstream/dynamips-0.2.6-RC3/mips64_exec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (hide annotations)
Sat Oct 6 16:05:34 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC2/mips64_exec.c
File MIME type: text/plain
File size: 59696 byte(s)
dynamips-0.2.6-RC2

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

  ViewVC Help
Powered by ViewVC 1.1.26