25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_mips.c,v 1.79 2007/04/28 09:19:51 debug Exp $ |
* $Id: cpu_mips.c,v 1.83 2007/06/15 18:07:08 debug Exp $ |
29 |
* |
* |
30 |
* MIPS core CPU emulation. |
* MIPS core CPU emulation. |
31 |
*/ |
*/ |
52 |
#include "opcodes_mips.h" |
#include "opcodes_mips.h" |
53 |
#include "settings.h" |
#include "settings.h" |
54 |
#include "symbol.h" |
#include "symbol.h" |
55 |
|
#include "timer.h" |
56 |
|
|
57 |
|
|
58 |
extern volatile int single_step; |
extern int native_code_translation_enabled; |
59 |
|
|
60 |
static char *exception_names[] = EXCEPTION_NAMES; |
static char *exception_names[] = EXCEPTION_NAMES; |
61 |
|
|
84 |
|
|
85 |
|
|
86 |
/* |
/* |
|
* regname(): |
|
|
* |
|
|
* Convert a register number into either 'r0', 'r31' etc, or a symbolic |
|
|
* name, depending on machine->show_symbolic_register_names. |
|
|
* |
|
|
* NOTE: This helper function is _NOT_ reentrant. |
|
|
*/ |
|
|
static char *regname(struct machine *machine, int r) |
|
|
{ |
|
|
static char ch[4]; |
|
|
ch[3] = ch[2] = '\0'; |
|
|
|
|
|
if (r<0 || r>=32) |
|
|
strlcpy(ch, "xx", sizeof(ch)); |
|
|
else if (machine->show_symbolic_register_names) |
|
|
strlcpy(ch, regnames[r], sizeof(ch)); |
|
|
else |
|
|
snprintf(ch, sizeof(ch), "r%i", r); |
|
|
|
|
|
return ch; |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
87 |
* mips_cpu_new(): |
* mips_cpu_new(): |
88 |
* |
* |
89 |
* Create a new MIPS cpu object. |
* Create a new MIPS cpu object. |
159 |
x = DEFAULT_PCACHE_SIZE; |
x = DEFAULT_PCACHE_SIZE; |
160 |
if (cpu->cd.mips.cpu_type.pdcache) |
if (cpu->cd.mips.cpu_type.pdcache) |
161 |
x = cpu->cd.mips.cpu_type.pdcache; |
x = cpu->cd.mips.cpu_type.pdcache; |
162 |
if (machine->cache_pdcache == 0) |
if (cpu->cd.mips.cache_pdcache == 0) |
163 |
machine->cache_pdcache = x; |
cpu->cd.mips.cache_pdcache = x; |
164 |
|
|
165 |
x = DEFAULT_PCACHE_SIZE; |
x = DEFAULT_PCACHE_SIZE; |
166 |
if (cpu->cd.mips.cpu_type.picache) |
if (cpu->cd.mips.cpu_type.picache) |
167 |
x = cpu->cd.mips.cpu_type.picache; |
x = cpu->cd.mips.cpu_type.picache; |
168 |
if (machine->cache_picache == 0) |
if (cpu->cd.mips.cache_picache == 0) |
169 |
machine->cache_picache = x; |
cpu->cd.mips.cache_picache = x; |
170 |
|
|
171 |
if (machine->cache_secondary == 0) |
if (cpu->cd.mips.cache_secondary == 0) |
172 |
machine->cache_secondary = cpu->cd.mips.cpu_type.scache; |
cpu->cd.mips.cache_secondary = cpu->cd.mips.cpu_type.scache; |
173 |
|
|
174 |
linesize = DEFAULT_PCACHE_LINESIZE; |
linesize = DEFAULT_PCACHE_LINESIZE; |
175 |
if (cpu->cd.mips.cpu_type.pdlinesize) |
if (cpu->cd.mips.cpu_type.pdlinesize) |
176 |
linesize = cpu->cd.mips.cpu_type.pdlinesize; |
linesize = cpu->cd.mips.cpu_type.pdlinesize; |
177 |
if (machine->cache_pdcache_linesize == 0) |
if (cpu->cd.mips.cache_pdcache_linesize == 0) |
178 |
machine->cache_pdcache_linesize = linesize; |
cpu->cd.mips.cache_pdcache_linesize = linesize; |
179 |
|
|
180 |
linesize = DEFAULT_PCACHE_LINESIZE; |
linesize = DEFAULT_PCACHE_LINESIZE; |
181 |
if (cpu->cd.mips.cpu_type.pilinesize) |
if (cpu->cd.mips.cpu_type.pilinesize) |
182 |
linesize = cpu->cd.mips.cpu_type.pilinesize; |
linesize = cpu->cd.mips.cpu_type.pilinesize; |
183 |
if (machine->cache_picache_linesize == 0) |
if (cpu->cd.mips.cache_picache_linesize == 0) |
184 |
machine->cache_picache_linesize = linesize; |
cpu->cd.mips.cache_picache_linesize = linesize; |
185 |
|
|
186 |
linesize = 0; |
linesize = 0; |
187 |
if (cpu->cd.mips.cpu_type.slinesize) |
if (cpu->cd.mips.cpu_type.slinesize) |
188 |
linesize = cpu->cd.mips.cpu_type.slinesize; |
linesize = cpu->cd.mips.cpu_type.slinesize; |
189 |
if (machine->cache_secondary_linesize == 0) |
if (cpu->cd.mips.cache_secondary_linesize == 0) |
190 |
machine->cache_secondary_linesize = linesize; |
cpu->cd.mips.cache_secondary_linesize = linesize; |
191 |
|
|
192 |
|
|
193 |
/* |
/* |
196 |
for (i=CACHE_DATA; i<=CACHE_INSTRUCTION; i++) { |
for (i=CACHE_DATA; i<=CACHE_INSTRUCTION; i++) { |
197 |
switch (i) { |
switch (i) { |
198 |
case CACHE_DATA: |
case CACHE_DATA: |
199 |
x = 1 << machine->cache_pdcache; |
x = 1 << cpu->cd.mips.cache_pdcache; |
200 |
linesize = 1 << machine->cache_pdcache_linesize; |
linesize = 1 << cpu->cd.mips.cache_pdcache_linesize; |
201 |
break; |
break; |
202 |
case CACHE_INSTRUCTION: |
case CACHE_INSTRUCTION: |
203 |
x = 1 << machine->cache_picache; |
x = 1 << cpu->cd.mips.cache_picache; |
204 |
linesize = 1 << machine->cache_picache_linesize; |
linesize = 1 << cpu->cd.mips.cache_picache_linesize; |
205 |
break; |
break; |
206 |
} |
} |
207 |
|
|
215 |
size_per_cache_line = sizeof(struct r3000_cache_line); |
size_per_cache_line = sizeof(struct r3000_cache_line); |
216 |
break; |
break; |
217 |
default: |
default: |
218 |
size_per_cache_line = sizeof(struct r4000_cache_line); |
size_per_cache_line = 32; /* TODO */ |
219 |
} |
} |
220 |
|
|
221 |
cpu->cd.mips.cache_mask[i] = cpu->cd.mips.cache_size[i] - 1; |
cpu->cd.mips.cache_mask[i] = cpu->cd.mips.cache_size[i] - 1; |
|
cpu->cd.mips.cache_miss_penalty[i] = 10; /* TODO ? */ |
|
222 |
|
|
223 |
cpu->cd.mips.cache[i] = malloc(cpu->cd.mips.cache_size[i]); |
CHECK_ALLOCATION(cpu->cd.mips.cache[i] = |
224 |
if (cpu->cd.mips.cache[i] == NULL) { |
malloc(cpu->cd.mips.cache_size[i])); |
|
fprintf(stderr, "out of memory\n"); |
|
|
} |
|
225 |
|
|
226 |
n_cache_lines = cpu->cd.mips.cache_size[i] / |
n_cache_lines = cpu->cd.mips.cache_size[i] / |
227 |
cpu->cd.mips.cache_linesize[i]; |
cpu->cd.mips.cache_linesize[i]; |
228 |
tags_size = n_cache_lines * size_per_cache_line; |
tags_size = n_cache_lines * size_per_cache_line; |
229 |
|
|
230 |
cpu->cd.mips.cache_tags[i] = malloc(tags_size); |
CHECK_ALLOCATION(cpu->cd.mips.cache_tags[i] = |
231 |
if (cpu->cd.mips.cache_tags[i] == NULL) { |
malloc(tags_size)); |
|
fprintf(stderr, "out of memory\n"); |
|
|
} |
|
232 |
|
|
233 |
/* Initialize the cache tags: */ |
/* Initialize the cache tags: */ |
234 |
switch (cpu->cd.mips.cpu_type.rev) { |
switch (cpu->cd.mips.cpu_type.rev) { |
254 |
* Secondary cache: |
* Secondary cache: |
255 |
*/ |
*/ |
256 |
secondary_cache_size = 0; |
secondary_cache_size = 0; |
257 |
if (machine->cache_secondary) |
if (cpu->cd.mips.cache_secondary) |
258 |
secondary_cache_size = 1 << machine->cache_secondary; |
secondary_cache_size = 1 << cpu->cd.mips.cache_secondary; |
259 |
/* TODO: linesize... */ |
/* TODO: linesize... */ |
260 |
|
|
261 |
if (cpu_id == 0) { |
if (cpu_id == 0) { |
337 |
CPU_SETTINGS_ADD_REGISTER64(cop0_names[i], |
CPU_SETTINGS_ADD_REGISTER64(cop0_names[i], |
338 |
cpu->cd.mips.coproc[0]->reg[i]); |
cpu->cd.mips.coproc[0]->reg[i]); |
339 |
|
|
340 |
|
if (native_code_translation_enabled) |
341 |
|
cpu->sampling_timer = timer_add(CPU_SAMPLE_TIMER_HZ, |
342 |
|
mips_timer_sample_tick, cpu); |
343 |
|
|
344 |
return 1; |
return 1; |
345 |
} |
} |
346 |
|
|
790 |
|
|
791 |
switch (sub) { |
switch (sub) { |
792 |
case 0x00: |
case 0x00: |
793 |
debug("%s\t%s,", |
debug("%s\t%s,", special_names[special6], |
794 |
special_names[special6], |
regnames[rd]); |
795 |
regname(cpu->machine, rd)); |
debug("%s,%i", regnames[rt], sa); |
|
debug("%s,%i", regname(cpu->machine, rt), sa); |
|
796 |
break; |
break; |
797 |
case 0x01: |
case 0x01: |
798 |
debug("%s\t%s,", |
debug("%s\t%s,", |
799 |
special_rot_names[special6], |
special_rot_names[special6], |
800 |
regname(cpu->machine, rd)); |
regnames[rd]); |
801 |
debug("%s,%i", regname(cpu->machine, rt), sa); |
debug("%s,%i", regnames[rt], sa); |
802 |
break; |
break; |
803 |
default:debug("UNIMPLEMENTED special, sub=0x%02x\n", |
default:debug("UNIMPLEMENTED special, sub=0x%02x\n", |
804 |
sub); |
sub); |
818 |
switch (sub) { |
switch (sub) { |
819 |
case 0x00: |
case 0x00: |
820 |
debug("%s\t%s", special_names[special6], |
debug("%s\t%s", special_names[special6], |
821 |
regname(cpu->machine, rd)); |
regnames[rd]); |
822 |
debug(",%s", regname(cpu->machine, rt)); |
debug(",%s", regnames[rt]); |
823 |
debug(",%s", regname(cpu->machine, rs)); |
debug(",%s", regnames[rs]); |
824 |
break; |
break; |
825 |
case 0x01: |
case 0x01: |
826 |
debug("%s\t%s", special_rot_names[special6], |
debug("%s\t%s", special_rot_names[special6], |
827 |
regname(cpu->machine, rd)); |
regnames[rd]); |
828 |
debug(",%s", regname(cpu->machine, rt)); |
debug(",%s", regnames[rt]); |
829 |
debug(",%s", regname(cpu->machine, rs)); |
debug(",%s", regnames[rs]); |
830 |
break; |
break; |
831 |
default:debug("UNIMPLEMENTED special, sub=0x%02x\n", |
default:debug("UNIMPLEMENTED special, sub=0x%02x\n", |
832 |
sub); |
sub); |
839 |
/* .hb = hazard barrier hint on MIPS32/64 rev 2 */ |
/* .hb = hazard barrier hint on MIPS32/64 rev 2 */ |
840 |
debug("jr%s\t%s", |
debug("jr%s\t%s", |
841 |
(instr[1] & 0x04) ? ".hb" : "", |
(instr[1] & 0x04) ? ".hb" : "", |
842 |
regname(cpu->machine, rs)); |
regnames[rs]); |
843 |
if (running && symbol != NULL) |
if (running && symbol != NULL) |
844 |
debug("\t<%s>", symbol); |
debug("\t<%s>", symbol); |
845 |
break; |
break; |
851 |
/* .hb = hazard barrier hint on MIPS32/64 rev 2 */ |
/* .hb = hazard barrier hint on MIPS32/64 rev 2 */ |
852 |
debug("jalr%s\t%s", |
debug("jalr%s\t%s", |
853 |
(instr[1] & 0x04) ? ".hb" : "", |
(instr[1] & 0x04) ? ".hb" : "", |
854 |
regname(cpu->machine, rd)); |
regnames[rd]); |
855 |
debug(",%s", regname(cpu->machine, rs)); |
debug(",%s", regnames[rs]); |
856 |
if (running && symbol != NULL) |
if (running && symbol != NULL) |
857 |
debug("\t<%s>", symbol); |
debug("\t<%s>", symbol); |
858 |
break; |
break; |
859 |
case SPECIAL_MFHI: |
case SPECIAL_MFHI: |
860 |
case SPECIAL_MFLO: |
case SPECIAL_MFLO: |
861 |
rd = (instr[1] >> 3) & 31; |
rd = (instr[1] >> 3) & 31; |
862 |
debug("%s\t%s", special_names[special6], |
debug("%s\t%s", special_names[special6], regnames[rd]); |
|
regname(cpu->machine, rd)); |
|
863 |
break; |
break; |
864 |
case SPECIAL_MTLO: |
case SPECIAL_MTLO: |
865 |
case SPECIAL_MTHI: |
case SPECIAL_MTHI: |
866 |
rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7); |
rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7); |
867 |
debug("%s\t%s", special_names[special6], |
debug("%s\t%s", special_names[special6], regnames[rs]); |
|
regname(cpu->machine, rs)); |
|
868 |
break; |
break; |
869 |
case SPECIAL_ADD: |
case SPECIAL_ADD: |
870 |
case SPECIAL_ADDU: |
case SPECIAL_ADDU: |
889 |
special6 == SPECIAL_SUBU) && rt == 0) { |
special6 == SPECIAL_SUBU) && rt == 0) { |
890 |
/* Special case 1: addu/subu with |
/* Special case 1: addu/subu with |
891 |
rt = the zero register ==> move */ |
rt = the zero register ==> move */ |
892 |
debug("move\t%s", regname(cpu->machine, rd)); |
debug("move\t%s", regnames[rd]); |
893 |
debug(",%s", regname(cpu->machine, rs)); |
debug(",%s", regnames[rs]); |
894 |
} else if (special6 == SPECIAL_ADDU && cpu->is_32bit |
} else if (special6 == SPECIAL_ADDU && cpu->is_32bit |
895 |
&& rs == 0) { |
&& rs == 0) { |
896 |
/* Special case 2: addu with |
/* Special case 2: addu with |
897 |
rs = the zero register ==> move */ |
rs = the zero register ==> move */ |
898 |
debug("move\t%s", regname(cpu->machine, rd)); |
debug("move\t%s", regnames[rd]); |
899 |
debug(",%s", regname(cpu->machine, rt)); |
debug(",%s", regnames[rt]); |
900 |
} else { |
} else { |
901 |
debug("%s\t%s", special_names[special6], |
debug("%s\t%s", special_names[special6], |
902 |
regname(cpu->machine, rd)); |
regnames[rd]); |
903 |
debug(",%s", regname(cpu->machine, rs)); |
debug(",%s", regnames[rs]); |
904 |
debug(",%s", regname(cpu->machine, rt)); |
debug(",%s", regnames[rt]); |
905 |
} |
} |
906 |
break; |
break; |
907 |
case SPECIAL_MULT: |
case SPECIAL_MULT: |
926 |
if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) { |
if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) { |
927 |
if (special6 == SPECIAL_MULT || |
if (special6 == SPECIAL_MULT || |
928 |
special6 == SPECIAL_MULTU) |
special6 == SPECIAL_MULTU) |
929 |
debug("%s,", |
debug("%s,", regnames[rd]); |
|
regname(cpu->machine, rd)); |
|
930 |
else |
else |
931 |
debug("WEIRD_R5900_RD,"); |
debug("WEIRD_R5900_RD,"); |
932 |
} else { |
} else { |
933 |
debug("WEIRD_RD_NONZERO,"); |
debug("WEIRD_RD_NONZERO,"); |
934 |
} |
} |
935 |
} |
} |
936 |
debug("%s", regname(cpu->machine, rs)); |
debug("%s", regnames[rs]); |
937 |
debug(",%s", regname(cpu->machine, rt)); |
debug(",%s", regnames[rt]); |
938 |
break; |
break; |
939 |
case SPECIAL_SYNC: |
case SPECIAL_SYNC: |
940 |
imm = ((instr[1] & 7) << 2) + (instr[0] >> 6); |
imm = ((instr[1] & 7) << 2) + (instr[0] >> 6); |
959 |
case SPECIAL_MFSA: |
case SPECIAL_MFSA: |
960 |
if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) { |
if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) { |
961 |
rd = (instr[1] >> 3) & 31; |
rd = (instr[1] >> 3) & 31; |
962 |
debug("mfsa\t%s", regname(cpu->machine, rd)); |
debug("mfsa\t%s", regnames[rd]); |
963 |
} else { |
} else { |
964 |
debug("unimplemented special 0x28"); |
debug("unimplemented special 0x28"); |
965 |
} |
} |
968 |
if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) { |
if (cpu->cd.mips.cpu_type.rev == MIPS_R5900) { |
969 |
rs = ((instr[3] & 3) << 3) + |
rs = ((instr[3] & 3) << 3) + |
970 |
((instr[2] >> 5) & 7); |
((instr[2] >> 5) & 7); |
971 |
debug("mtsa\t%s", regname(cpu->machine, rs)); |
debug("mtsa\t%s", regnames[rs]); |
972 |
} else { |
} else { |
973 |
debug("unimplemented special 0x29"); |
debug("unimplemented special 0x29"); |
974 |
} |
} |
1002 |
case HI6_BEQL: |
case HI6_BEQL: |
1003 |
case HI6_BNE: |
case HI6_BNE: |
1004 |
case HI6_BNEL: |
case HI6_BNEL: |
1005 |
debug("%s,", regname(cpu->machine, rt)); |
debug("%s,", regnames[rt]); |
1006 |
} |
} |
1007 |
debug("%s,", regname(cpu->machine, rs)); |
debug("%s,", regnames[rs]); |
1008 |
} |
} |
1009 |
|
|
1010 |
if (cpu->is_32bit) |
if (cpu->is_32bit) |
1031 |
imm = (instr[1] << 8) + instr[0]; |
imm = (instr[1] << 8) + instr[0]; |
1032 |
if (imm >= 32768) |
if (imm >= 32768) |
1033 |
imm -= 65536; |
imm -= 65536; |
1034 |
debug("%s\t%s,", hi6_names[hi6], regname(cpu->machine, rt)); |
debug("%s\t%s,", hi6_names[hi6], regnames[rt]); |
1035 |
debug("%s,", regname(cpu->machine, rs)); |
debug("%s,", regnames[rs]); |
1036 |
if (hi6 == HI6_ANDI || hi6 == HI6_ORI || hi6 == HI6_XORI) |
if (hi6 == HI6_ANDI || hi6 == HI6_ORI || hi6 == HI6_XORI) |
1037 |
debug("0x%04x", imm & 0xffff); |
debug("0x%04x", imm & 0xffff); |
1038 |
else |
else |
1041 |
case HI6_LUI: |
case HI6_LUI: |
1042 |
rt = instr[2] & 31; |
rt = instr[2] & 31; |
1043 |
imm = (instr[1] << 8) + instr[0]; |
imm = (instr[1] << 8) + instr[0]; |
1044 |
debug("lui\t%s,0x%x", regname(cpu->machine, rt), imm); |
debug("lui\t%s,0x%x", regnames[rt], imm); |
1045 |
break; |
break; |
1046 |
case HI6_LB: |
case HI6_LB: |
1047 |
case HI6_LBU: |
case HI6_LBU: |
1104 |
msbd += 32; |
msbd += 32; |
1105 |
if (special6 == SPECIAL3_DEXTU) |
if (special6 == SPECIAL3_DEXTU) |
1106 |
lsb += 32; |
lsb += 32; |
1107 |
debug("\t%s", regname(cpu->machine, rt)); |
debug("\t%s", regnames[rt]); |
1108 |
debug(",%s", regname(cpu->machine, rs)); |
debug(",%s", regnames[rs]); |
1109 |
debug(",%i,%i", lsb, msbd + 1); |
debug(",%i,%i", lsb, msbd + 1); |
1110 |
break; |
break; |
1111 |
|
|
1121 |
msbd += 32; |
msbd += 32; |
1122 |
} |
} |
1123 |
msbd -= lsb; |
msbd -= lsb; |
1124 |
debug("\t%s", regname(cpu->machine, rt)); |
debug("\t%s", regnames[rt]); |
1125 |
debug(",%s", regname(cpu->machine, rs)); |
debug(",%s", regnames[rs]); |
1126 |
debug(",%i,%i", lsb, msbd + 1); |
debug(",%i,%i", lsb, msbd + 1); |
1127 |
break; |
break; |
1128 |
|
|
1136 |
case BSHFL_SEB: debug("seb"); break; |
case BSHFL_SEB: debug("seb"); break; |
1137 |
case BSHFL_SEH: debug("seh"); break; |
case BSHFL_SEH: debug("seh"); break; |
1138 |
} |
} |
1139 |
debug("\t%s", regname(cpu->machine,rd)); |
debug("\t%s", regnames[rd]); |
1140 |
debug(",%s", regname(cpu->machine,rt)); |
debug(",%s", regnames[rt]); |
1141 |
break; |
break; |
1142 |
default:debug("%s", special3_names[special6]); |
default:debug("%s", special3_names[special6]); |
1143 |
debug("\t(UNIMPLEMENTED)"); |
debug("\t(UNIMPLEMENTED)"); |
1152 |
case BSHFL_DSBH: debug("dsbh"); break; |
case BSHFL_DSBH: debug("dsbh"); break; |
1153 |
case BSHFL_DSHD: debug("dshd"); break; |
case BSHFL_DSHD: debug("dshd"); break; |
1154 |
} |
} |
1155 |
debug("\t%s", regname(cpu->machine,rd)); |
debug("\t%s", regnames[rd]); |
1156 |
debug(",%s", regname(cpu->machine,rt)); |
debug(",%s", regnames[rt]); |
1157 |
break; |
break; |
1158 |
default:debug("%s", special3_names[special6]); |
default:debug("%s", special3_names[special6]); |
1159 |
debug("\t(UNIMPLEMENTED)"); |
debug("\t(UNIMPLEMENTED)"); |
1162 |
|
|
1163 |
case SPECIAL3_RDHWR: |
case SPECIAL3_RDHWR: |
1164 |
debug("%s", special3_names[special6]); |
debug("%s", special3_names[special6]); |
1165 |
debug("\t%s", regname(cpu->machine, rt)); |
debug("\t%s", regnames[rt]); |
1166 |
debug(",hwr%i", rd); |
debug(",hwr%i", rd); |
1167 |
break; |
break; |
1168 |
|
|
1184 |
/* TODO: Which ISAs? IV? V? 32? 64? */ |
/* TODO: Which ISAs? IV? V? 32? 64? */ |
1185 |
if (cpu->cd.mips.cpu_type.isa_level >= 4 && hi6 == HI6_LWC3) { |
if (cpu->cd.mips.cpu_type.isa_level >= 4 && hi6 == HI6_LWC3) { |
1186 |
debug("pref\t0x%x,%i(%s)", |
debug("pref\t0x%x,%i(%s)", |
1187 |
rt, imm, regname(cpu->machine, rs)); |
rt, imm, regnames[rs]); |
1188 |
|
|
1189 |
if (running) { |
if (running) { |
1190 |
debug("\t[0x%016"PRIx64" = %s]", |
debug("\t[0x%016"PRIx64" = %s]", |
1204 |
hi6 == HI6_LDC1 || hi6 == HI6_LDC2) |
hi6 == HI6_LDC1 || hi6 == HI6_LDC2) |
1205 |
debug("r%i", rt); |
debug("r%i", rt); |
1206 |
else |
else |
1207 |
debug("%s", regname(cpu->machine, rt)); |
debug("%s", regnames[rt]); |
1208 |
|
|
1209 |
debug(",%i(%s)", imm, regname(cpu->machine, rs)); |
debug(",%i(%s)", imm, regnames[rs]); |
1210 |
|
|
1211 |
if (running) { |
if (running) { |
1212 |
debug("\t["); |
debug("\t["); |
1266 |
cache_op = copz >> 2; |
cache_op = copz >> 2; |
1267 |
which_cache = copz & 3; |
which_cache = copz & 3; |
1268 |
showtag = 0; |
showtag = 0; |
1269 |
debug("cache\t0x%02x,0x%04x(%s)", copz, imm, |
debug("cache\t0x%02x,0x%04x(%s)", copz, imm, regnames[rt]); |
|
regname(cpu->machine, rt)); |
|
1270 |
if (which_cache==0) debug(" [ primary I-cache"); |
if (which_cache==0) debug(" [ primary I-cache"); |
1271 |
if (which_cache==1) debug(" [ primary D-cache"); |
if (which_cache==1) debug(" [ primary D-cache"); |
1272 |
if (which_cache==2) debug(" [ secondary I-cache"); |
if (which_cache==2) debug(" [ secondary I-cache"); |
1309 |
case MMI_MADD: |
case MMI_MADD: |
1310 |
case MMI_MADDU: |
case MMI_MADDU: |
1311 |
if (rd != MIPS_GPR_ZERO) { |
if (rd != MIPS_GPR_ZERO) { |
1312 |
debug("%s,", regname(cpu->machine, rd)); |
debug("%s,", regnames[rd]); |
1313 |
} |
} |
1314 |
debug("%s", regname(cpu->machine, rs)); |
debug("%s,%s", regnames[rs], regnames[rt]); |
|
debug(",%s", regname(cpu->machine, rt)); |
|
1315 |
break; |
break; |
1316 |
|
|
1317 |
case MMI_MMI0: |
case MMI_MMI0: |
1326 |
case MMI0_PPACB: |
case MMI0_PPACB: |
1327 |
case MMI0_PPACH: |
case MMI0_PPACH: |
1328 |
case MMI0_PPACW: |
case MMI0_PPACW: |
1329 |
debug("%s", regname(cpu->machine, rd)); |
debug("%s,%s,%s", regnames[rd], |
1330 |
debug(",%s", regname(cpu->machine, rs)); |
regnames[rs], regnames[rt]); |
|
debug(",%s", regname(cpu->machine, rt)); |
|
1331 |
break; |
break; |
1332 |
|
|
1333 |
default:debug("(UNIMPLEMENTED)"); |
default:debug("(UNIMPLEMENTED)"); |
1343 |
case MMI1_PEXTUW: |
case MMI1_PEXTUW: |
1344 |
case MMI1_PMINH: |
case MMI1_PMINH: |
1345 |
case MMI1_PMINW: |
case MMI1_PMINW: |
1346 |
debug("%s", regname(cpu->machine, rd)); |
debug("%s,%s,%s", regnames[rd], |
1347 |
debug(",%s", regname(cpu->machine, rs)); |
regnames[rs], regnames[rt]); |
|
debug(",%s", regname(cpu->machine, rt)); |
|
1348 |
break; |
break; |
1349 |
|
|
1350 |
default:debug("(UNIMPLEMENTED)"); |
default:debug("(UNIMPLEMENTED)"); |
1357 |
|
|
1358 |
case MMI2_PMFHI: |
case MMI2_PMFHI: |
1359 |
case MMI2_PMFLO: |
case MMI2_PMFLO: |
1360 |
debug("%s", regname(cpu->machine, rd)); |
debug("%s", regnames[rd]); |
1361 |
break; |
break; |
1362 |
|
|
1363 |
case MMI2_PHMADH: |
case MMI2_PHMADH: |
1370 |
case MMI2_PMULTH: |
case MMI2_PMULTH: |
1371 |
case MMI2_PMULTW: |
case MMI2_PMULTW: |
1372 |
case MMI2_PSLLVW: |
case MMI2_PSLLVW: |
1373 |
debug("%s", regname(cpu->machine, rd)); |
debug("%s,%s,%s", regnames[rd], |
1374 |
debug(",%s", regname(cpu->machine, rs)); |
regnames[rs], regnames[rt]); |
|
debug(",%s", regname(cpu->machine, rt)); |
|
1375 |
break; |
break; |
1376 |
|
|
1377 |
default:debug("(UNIMPLEMENTED)"); |
default:debug("(UNIMPLEMENTED)"); |
1384 |
|
|
1385 |
case MMI3_PMTHI: |
case MMI3_PMTHI: |
1386 |
case MMI3_PMTLO: |
case MMI3_PMTLO: |
1387 |
debug("%s", regname(cpu->machine, rs)); |
debug("%s", regnames[rs]); |
1388 |
break; |
break; |
1389 |
|
|
1390 |
case MMI3_PINTEH: |
case MMI3_PINTEH: |
1393 |
case MMI3_PNOR: |
case MMI3_PNOR: |
1394 |
case MMI3_POR: |
case MMI3_POR: |
1395 |
case MMI3_PSRAVW: |
case MMI3_PSRAVW: |
1396 |
debug("%s", regname(cpu->machine, rd)); |
debug("%s,%s,%s", regnames[rd], |
1397 |
debug(",%s", regname(cpu->machine, rs)); |
regnames[rs], regnames[rt]); |
|
debug(",%s", regname(cpu->machine, rt)); |
|
1398 |
break; |
break; |
1399 |
|
|
1400 |
default:debug("(UNIMPLEMENTED)"); |
default:debug("(UNIMPLEMENTED)"); |
1417 |
case SPECIAL2_MSUBU: |
case SPECIAL2_MSUBU: |
1418 |
if (rd != MIPS_GPR_ZERO) { |
if (rd != MIPS_GPR_ZERO) { |
1419 |
debug("WEIRD_NONZERO_RD(%s),", |
debug("WEIRD_NONZERO_RD(%s),", |
1420 |
regname(cpu->machine, rd)); |
regnames[rd]); |
1421 |
} |
} |
1422 |
debug("%s", regname(cpu->machine, rs)); |
debug("%s,%s", regnames[rs], regnames[rt]); |
|
debug(",%s", regname(cpu->machine, rt)); |
|
1423 |
break; |
break; |
1424 |
|
|
1425 |
case SPECIAL2_MUL: |
case SPECIAL2_MUL: |
1426 |
/* Apparently used both on R5900 and MIPS32: */ |
/* Apparently used both on R5900 and MIPS32: */ |
1427 |
debug("%s", regname(cpu->machine, rd)); |
debug("%s,%s,%s", regnames[rd], |
1428 |
debug(",%s", regname(cpu->machine, rs)); |
regnames[rs], regnames[rt]); |
|
debug(",%s", regname(cpu->machine, rt)); |
|
1429 |
break; |
break; |
1430 |
|
|
1431 |
case SPECIAL2_CLZ: |
case SPECIAL2_CLZ: |
1432 |
case SPECIAL2_CLO: |
case SPECIAL2_CLO: |
1433 |
case SPECIAL2_DCLZ: |
case SPECIAL2_DCLZ: |
1434 |
case SPECIAL2_DCLO: |
case SPECIAL2_DCLO: |
1435 |
debug("%s", regname(cpu->machine, rd)); |
debug("%s,%s", regnames[rd], regnames[rs]); |
|
debug(",%s", regname(cpu->machine, rs)); |
|
1436 |
break; |
break; |
1437 |
|
|
1438 |
default: |
default: |
1457 |
case REGIMM_BLTZALL: |
case REGIMM_BLTZALL: |
1458 |
case REGIMM_BGEZAL: |
case REGIMM_BGEZAL: |
1459 |
case REGIMM_BGEZALL: |
case REGIMM_BGEZALL: |
1460 |
debug("%s\t%s,", regimm_names[regimm5], |
debug("%s\t%s,", regimm_names[regimm5], regnames[rs]); |
|
regname(cpu->machine, rs)); |
|
1461 |
|
|
1462 |
addr = (dumpaddr + 4) + (imm << 2); |
addr = (dumpaddr + 4) + (imm << 2); |
1463 |
|
|
1469 |
|
|
1470 |
case REGIMM_SYNCI: |
case REGIMM_SYNCI: |
1471 |
debug("%s\t%i(%s)", regimm_names[regimm5], |
debug("%s\t%i(%s)", regimm_names[regimm5], |
1472 |
imm, regname(cpu->machine, rs)); |
imm, regnames[rs]); |
1473 |
break; |
break; |
1474 |
|
|
1475 |
default: |
default: |
1549 |
" "); |
" "); |
1550 |
else |
else |
1551 |
debug(" %3s=%016"PRIx64"%016"PRIx64, |
debug(" %3s=%016"PRIx64"%016"PRIx64, |
1552 |
regname(cpu->machine, r), (uint64_t) |
regnames[r], (uint64_t) |
1553 |
cpu->cd.mips.gpr_quadhi[r], |
cpu->cd.mips.gpr_quadhi[r], |
1554 |
(uint64_t)cpu->cd.mips.gpr[r]); |
(uint64_t)cpu->cd.mips.gpr[r]); |
1555 |
if ((i & 1) == 1) |
if ((i & 1) == 1) |
1563 |
if (i == MIPS_GPR_ZERO) |
if (i == MIPS_GPR_ZERO) |
1564 |
debug(" "); |
debug(" "); |
1565 |
else |
else |
1566 |
debug(" %3s = %08"PRIx32, |
debug(" %3s = %08"PRIx32, regnames[i], |
|
regname(cpu->machine, i), |
|
1567 |
(uint32_t)cpu->cd.mips.gpr[i]); |
(uint32_t)cpu->cd.mips.gpr[i]); |
1568 |
if ((i & 3) == 3) |
if ((i & 3) == 3) |
1569 |
debug("\n"); |
debug("\n"); |
1578 |
debug(" "); |
debug(" "); |
1579 |
else |
else |
1580 |
debug(" %3s = 0x%016"PRIx64, |
debug(" %3s = 0x%016"PRIx64, |
1581 |
regname(cpu->machine, r), |
regnames[r], |
1582 |
(uint64_t)cpu->cd.mips.gpr[r]); |
(uint64_t)cpu->cd.mips.gpr[r]); |
1583 |
if ((i & 1) == 1) |
if ((i & 1) == 1) |
1584 |
debug("\n"); |
debug("\n"); |
1606 |
if ((i & nm1) == 0) |
if ((i & nm1) == 0) |
1607 |
debug("cpu%i:", cpu->cpu_id); |
debug("cpu%i:", cpu->cpu_id); |
1608 |
|
|
1609 |
if (cpu->machine->show_symbolic_register_names && |
if (coprocnr == 0) |
|
coprocnr == 0) |
|
1610 |
debug(" %8s", cop0_names[i]); |
debug(" %8s", cop0_names[i]); |
1611 |
else |
else |
1612 |
debug(" c%i,%02i", coprocnr, i); |
debug(" c%i,%02i", coprocnr, i); |