/[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

Annotation of /trunk/mips64_exec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/mips64_exec.c
File MIME type: text/plain
File size: 59815 byte(s)
dynamips-0.2.7-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26