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

  ViewVC Help
Powered by ViewVC 1.1.26