39 static const char* hi6_names[] =
HI6_NAMES;
48 static const char* regname(
int i,
const string& abi)
51 return regnames_old[i];
65 memset((
void*) &m_type, 0,
sizeof(m_type));
66 for (
size_t j=0; cpu_type_defs[j].
name != NULL; j++) {
67 if (m_mips_type == cpu_type_defs[j].name) {
68 m_type = cpu_type_defs[j];
73 if (m_type.name == NULL) {
74 std::cerr <<
"Internal error: Unimplemented MIPS type?\n";
75 throw std::exception();
100 settings[
"model"] =
"5KE";
142 "must contain the value 0.\n");
148 " can not have bit 1 set!\n");
154 if ((int64_t)
m_pc != (int64_t)(int32_t)
m_pc) {
156 "CPU is 32-bit, but the pc register is not" 157 " a correctly sign-extended 32-bit value!\n");
162 if ((int64_t)m_gpr[i] != (int64_t)(int32_t)m_gpr[i]) {
164 "CPU is 32-bit, but the " + regname(i, m_abi) +
" register is not" 165 " a correctly sign-extended 32-bit value!\n");
184 "must contain the value 0.\n");
189 if (m_mips_type != m_type.
name) {
191 for (
size_t j=0; cpu_type_defs[j].
name != NULL; j++) {
192 if (m_mips_type == cpu_type_defs[j].name) {
193 m_type = cpu_type_defs[j];
202 ss <<
"Unknown model \"" + m_mips_type +
"\". Available types are:\n";
203 for (
size_t j=0; cpu_type_defs[j].
name != NULL; j++) {
206 ss << cpu_type_defs[j].
name;
220 bool MIPS_CPUComponent::Is32Bit()
const 226 static uint64_t Trunc3264(uint64_t x,
bool is32bit)
228 return is32bit? (uint32_t)x : x;
232 static uint64_t TruncSigned3264(uint64_t x,
bool is32bit)
234 return is32bit? (int32_t)x : x;
240 bool is32bit = Is32Bit();
243 ss.flags(std::ios::hex);
244 ss << std::setfill(
'0');
255 ss << Trunc3264(
m_pc, is32bit);
258 ss <<
" <" << symbol <<
">";
266 ss << Trunc3264(m_hi, is32bit) <<
" lo=";
271 ss << Trunc3264(m_lo, is32bit) <<
"\n";
274 ss << regname(i, m_abi) <<
"=";
279 ss << Trunc3264(m_gpr[i], is32bit);
322 bool mips16 =
m_pc & 1? true :
false;
326 return mips16? 1 : 2;
332 bool mips16 =
m_pc & 1? true :
false;
333 return mips16? instr_ToBeTranslated_MIPS16 : instr_ToBeTranslated;
341 vaddr = (int32_t)vaddr;
344 if (vaddr >= 0xffffffff80000000ULL && vaddr < 0xffffffffc0000000ULL) {
345 paddr = vaddr & 0x1fffffff;
351 if (vaddr >= 0xa800000000000000ULL && vaddr < 0xa8000fffffffffffULL) {
352 paddr = vaddr & 0xfffffffffffULL;
369 size_t MIPS_CPUComponent::DisassembleInstructionMIPS16(uint64_t vaddr,
370 unsigned char *instruction, vector<string>& result)
373 uint16_t iword = *((uint16_t *)(
void*) instruction);
381 snprintf(tmp,
sizeof(tmp),
"%04x", iword);
382 result.push_back(tmp);
384 int hi5 = iword >> 11;
385 int rx = (iword >> 8) & 7;
386 int ry = (iword >> 5) & 7;
388 int imm5 = iword & 0x1f;
403 case 0x14: result.push_back(
"lbu");
break;
404 case 0x18: result.push_back(
"sb");
break;
409 ss << regname(ry, m_abi) <<
"," << ofs <<
"(" << regname(rx, m_abi) <<
")";
410 result.push_back(ss.str());
417 ss.flags(std::ios::hex);
418 ss <<
"unimplemented MIPS16 opcode 0x" << hi5;
419 result.push_back(ss.str());
424 return sizeof(uint16_t);
429 unsigned char *instruction, vector<string>& result)
431 const bool mips16 =
m_pc & 1? true :
false;
432 const size_t instrSize = mips16?
sizeof(uint16_t) :
sizeof(uint32_t);
434 if (maxLen < instrSize) {
440 return DisassembleInstructionMIPS16(vaddr,
441 instruction, result);
444 uint32_t instructionWord = *((uint32_t *)(
void*) instruction);
450 const uint32_t iword = instructionWord;
455 ss.flags(std::ios::hex);
456 ss << std::setfill(
'0') << std::setw(8) << (uint32_t) iword;
458 ss <<
" (delayslot)";
459 result.push_back(ss.str());
462 const int hi6 = iword >> 26;
463 const int rs = (iword >> 21) & 31;
464 const int rt = (iword >> 16) & 31;
465 const int rd = (iword >> 11) & 31;
466 const int sa = (iword >> 6) & 31;
472 int special6 = iword & 0x3f;
495 ss <<
"nop (weird, sa=" 498 result.push_back(ss.str());
505 special_names[special6]);
506 ss << regname(rd, m_abi) <<
"," <<
507 regname(rt, m_abi) <<
"," << sa;
508 result.push_back(ss.str());
512 special_rot_names[special6]);
513 ss << regname(rd, m_abi) <<
"," <<
514 regname(rt, m_abi) <<
"," << sa;
515 result.push_back(ss.str());
517 default:ss <<
"unimpl special, sub=" << sub;
518 result.push_back(ss.str());
533 special_names[special6]);
534 ss << regname(rd, m_abi) <<
"," <<
535 regname(rt, m_abi) <<
"," <<
537 result.push_back(ss.str());
541 special_rot_names[special6]);
542 ss << regname(rd, m_abi) <<
"," <<
543 regname(rt, m_abi) <<
"," <<
545 result.push_back(ss.str());
547 default:ss <<
"unimpl special, sub=" 549 result.push_back(ss.str());
556 if ((iword >> 10) & 1)
557 result.push_back(
"jr.hb");
559 result.push_back(
"jr");
560 ss << regname(rs, m_abi);
561 result.push_back(ss.str());
567 if ((iword >> 10) & 1)
568 result.push_back(
"jalr.hb");
570 result.push_back(
"jalr");
571 ss << regname(rd, m_abi) <<
"," << regname(rs, m_abi);
572 result.push_back(ss.str());
577 result.push_back(special_names[special6]);
578 result.push_back(regname(rd, m_abi));
583 result.push_back(special_names[special6]);
584 result.push_back(regname(rs, m_abi));
603 result.push_back(special_names[special6]);
604 ss << regname(rd, m_abi) <<
"," <<
605 regname(rs, m_abi) <<
"," << regname(rt, m_abi);
606 result.push_back(ss.str());
623 result.push_back(special_names[special6]);
628 ss << regname(rd, m_abi)<<
",";
630 ss <<
"WEIRD_R5900_RD,";
632 ss <<
"WEIRD_R5900_RD,";
636 ss << regname(rs, m_abi) <<
"," << regname(rt, m_abi);
637 result.push_back(ss.str());
641 result.push_back(special_names[special6]);
642 ss << ((iword >> 6) & 31);
643 result.push_back(ss.str());
648 result.push_back(special_names[special6]);
649 if (((iword >> 6) & 0xfffff) != 0) {
650 ss << ((iword >> 6) & 0xfffff);
651 result.push_back(ss.str());
657 result.push_back(
"mfsa");
658 result.push_back(regname(rd, m_abi));
661 "unimplemented special 0x28");
667 result.push_back(
"mtsa");
668 result.push_back(regname(rs, m_abi));
671 "unimplemented special 0x29");
676 ss <<
"unimplemented: " <<
677 special_names[special6];
678 result.push_back(ss.str());
693 int imm = (int16_t) iword;
694 uint64_t
addr = vaddr + 4 + (imm << 2);
700 result.push_back(
"b");
702 result.push_back(hi6_names[hi6]);
709 ss << regname(rt, m_abi) <<
",";
712 ss << regname(rs, m_abi) <<
",";
715 ss.flags(std::ios::hex | std::ios::showbase);
717 result.push_back(ss.str());
721 result.push_back(
"; <" + symbol +
">");
735 result.push_back(hi6_names[hi6]);
738 ss << regname(rt, m_abi) <<
"," << regname(rs, m_abi) <<
",";
741 ss.flags(std::ios::hex | std::ios::showbase);
742 ss << (uint16_t) iword;
744 ss << (int16_t) iword;
746 result.push_back(ss.str());
752 result.push_back(hi6_names[hi6]);
755 ss << regname(rt, m_abi) <<
",";
756 ss.flags(std::ios::hex | std::ios::showbase);
757 ss << (uint16_t) iword;
758 result.push_back(ss.str());
799 result.push_back(
"mdmx (UNIMPLEMENTED)");
803 result.push_back(
"special3 (UNIMPLEMENTED)");
808 int imm = (int16_t) iword;
814 result.push_back(
"pref");
816 ss << rt <<
"," << imm <<
817 "(" << regname(rs, m_abi) <<
")";
818 result.push_back(ss.str());
822 result.push_back(hi6_names[hi6]);
832 ss << regname(rt, m_abi);
834 ss <<
"," << imm <<
"(" << regname(rs, m_abi) <<
")";
836 result.push_back(ss.str());
843 result.push_back(hi6_names[hi6]);
845 int imm = (iword & 0x03ffffff) << 2;
846 uint64_t
addr = (vaddr + 4) & ~((1 << 28) - 1);
850 ss.flags(std::ios::hex | std::ios::showbase);
852 result.push_back(ss.str());
856 result.push_back(
"; <" + symbol +
">");
866 int regimm5 = (iword >> 16) & 0x1f;
867 int imm = (int16_t) iword;
868 uint64_t
addr = (vaddr + 4) + (imm << 2);
871 ss.flags(std::ios::hex | std::ios::showbase);
883 result.push_back(regimm_names[regimm5]);
885 ss << regname(rs, m_abi) <<
"," <<
addr;
886 result.push_back(ss.str());
890 result.push_back(regimm_names[regimm5]);
892 ss << imm <<
"(" << regname(rs, m_abi) <<
")";
893 result.push_back(ss.str());
898 ss <<
"unimplemented: " <<
899 regimm_names[regimm5];
900 result.push_back(ss.str());
909 ss <<
"unimplemented: " << hi6_names[hi6];
910 result.push_back(ss.str());
921 if (attributeName ==
"stable")
924 if (attributeName ==
"description")
925 return "MIPS processor.";
954 else if (
op == 2) cond = (int64_t)
REG64(ic->
arg[0]) <= 0;
955 else cond = (int64_t)
REG64(ic->
arg[0]) > 0;
961 cpu->m_inDelaySlot =
true;
962 cpu->m_exceptionOrAbortInDelaySlot =
false;
966 std::cerr <<
"MIPS b instruction: samepage singlestep: should not happen.\n";
967 throw std::exception();
969 cpu->m_delaySlotTarget =
cpu->m_pc & ~
cpu->m_dyntransPageMask;
970 cpu->m_delaySlotTarget =
cpu->m_delaySlotTarget + (int32_t)ic->
arg[2].
u32;
973 cpu->m_delaySlotTarget =
cpu->m_pc + 8;
976 cpu->m_nextIC = ic + 1;
979 cpu->m_inDelaySlot =
true;
980 cpu->m_exceptionOrAbortInDelaySlot =
false;
984 cpu->m_executedCycles ++;
987 if (!
cpu->m_exceptionOrAbortInDelaySlot) {
992 cpu->m_pc &= ~
cpu->m_dyntransPageMask;
994 cpu->DyntransPCtoPointers();
997 cpu->m_nextIC = ic + 2;
1000 cpu->m_inDelaySlot =
false;
1006 cpu->m_exceptionOrAbortInDelaySlot =
false;
1024 if (
cpu->m_showFunctionTraceCall) {
1025 uint64_t saved_pc =
cpu->m_pc;
1026 cpu->m_pc =
cpu->m_pc & ~0x0fffffffUL;
1028 cpu->FunctionTraceCall();
1029 cpu->m_pc = saved_pc;
1035 cpu->m_inDelaySlot =
true;
1036 cpu->m_exceptionOrAbortInDelaySlot =
false;
1038 cpu->m_delaySlotTarget =
cpu->m_pc & ~0x0fffffffUL;
1039 cpu->m_delaySlotTarget += ic->
arg[0].
u32;
1041 cpu->m_nextIC = ic + 1;
1044 cpu->m_inDelaySlot =
true;
1045 cpu->m_exceptionOrAbortInDelaySlot =
false;
1049 cpu->m_executedCycles ++;
1052 if (!
cpu->m_exceptionOrAbortInDelaySlot) {
1053 cpu->m_pc =
cpu->m_pc & ~0x0fffffffUL;
1055 cpu->DyntransPCtoPointers();
1057 cpu->m_inDelaySlot =
false;
1063 cpu->m_exceptionOrAbortInDelaySlot =
false;
1083 uint64_t saved_pc =
cpu->m_pc;
1085 cpu->FunctionTraceCall();
1086 cpu->m_pc = saved_pc;
1091 cpu->FunctionTraceReturn();
1095 cpu->m_inDelaySlot =
true;
1096 cpu->m_exceptionOrAbortInDelaySlot =
false;
1099 cpu->m_nextIC = ic + 1;
1102 cpu->m_inDelaySlot =
true;
1103 cpu->m_exceptionOrAbortInDelaySlot =
false;
1107 cpu->m_executedCycles ++;
1110 if (!
cpu->m_exceptionOrAbortInDelaySlot) {
1112 cpu->DyntransPCtoPointers();
1114 cpu->m_inDelaySlot =
false;
1120 cpu->m_exceptionOrAbortInDelaySlot =
false;
1130 uint64_t res = (uint64_t)a * (uint64_t)b;
1132 cpu->m_lo = (int32_t)res;
1133 cpu->m_hi = (int32_t)(res >> 32);
1149 template<
bool store,
typename addressType,
typename T,
bool signedLoad>
void MIPS_CPUComponent::instr_loadstore(
CPUDyntransComponent* cpubase,
DyntransIC* ic)
1157 if (
sizeof(addressType) ==
sizeof(uint64_t))
1162 if (
sizeof(T) > 1 && (addr & (
sizeof(T)-1))) {
1163 std::cerr <<
"TODO: MIPS unaligned data access exception!\n";
1164 throw std::exception();
1170 cpu->AddressSelect(addr);
1184 if (
sizeof(T) ==
sizeof(uint32_t))
1186 if (
sizeof(T) ==
sizeof(uint16_t))
1188 if (
sizeof(T) ==
sizeof(uint8_t))
1200 void MIPS_CPUComponent::Translate(uint32_t iword,
struct DyntransIC* ic)
1204 int requiredISA = 1;
1205 int requiredISArevision = 1;
1207 int hi6 = iword >> 26;
1208 int rs = (iword >> 21) & 31;
1209 int rt = (iword >> 16) & 31;
1210 int rd = (iword >> 11) & 31;
1211 int sa = (iword >> 6) & 31;
1212 int32_t imm = (int16_t)iword;
1213 int s6 = iword & 63;
1237 case SPECIAL_SLL: ic->
f = instr_shift_left_u64_u64_imm5_truncS32;
break;
1239 case SPECIAL_SRL: ic->
f = instr_shift_right_u64_u64asu32_imm5_truncS32;
break;
1260 ic->
arg[0].
p = &m_gpr[rd];
1261 ic->
arg[1].
p = &m_gpr[rt];
1265 ic->
arg[2].
p = &m_gpr[rs];
1347 case SPECIAL_ADDU: ic->
f = instr_add_u64_u64_u64_truncS32;
break;
1349 case SPECIAL_SUBU: ic->
f = instr_sub_u64_u64_u64_truncS32;
break;
1358 case SPECIAL_XOR: ic->
f = instr_xor_u64_u64_u64;
break;
1385 ic->
arg[0].
p = &m_gpr[rd];
1386 ic->
arg[1].
p = &m_gpr[rs];
1387 ic->
arg[2].
p = &m_gpr[rt];
1424 std::cerr <<
"TODO: rd NON-zero\n";
1454 ic->
f = instr_jr<false, false>;
1455 f_singleStepping = instr_jr<false, true>;
1458 ic->
f = instr_jr<true, false>;
1459 f_singleStepping = instr_jr<true, true>;
1464 if (singleInstructionLeft)
1465 ic->
f = f_singleStepping;
1467 ic->
arg[0].
p = &m_gpr[rs];
1468 ic->
arg[1].
p = &m_gpr[rd];
1473 " TODO: How should this be handled?");
1483 ss.flags(std::ios::hex);
1484 ss <<
"unimplemented opcode HI6_SPECIAL, s6 = 0x" << s6;
1501 bool warnAboutNonZeroRT =
false;
1505 ic->
f = instr_b<0, false, false>;
1506 samepage_function = instr_b<0, true, false>;
1507 f_singleStepping = instr_b<0, false, true>;
1510 ic->
f = instr_b<1, false, false>;
1511 samepage_function = instr_b<1, true, false>;
1512 f_singleStepping = instr_b<1, false, true>;
1515 ic->
f = instr_b<2, false, false>;
1516 samepage_function = instr_b<2, true, false>;
1517 f_singleStepping = instr_b<2, false, true>;
1518 warnAboutNonZeroRT =
true;
1521 ic->
f = instr_b<3, false, false>;
1522 samepage_function = instr_b<3, true, false>;
1523 f_singleStepping = instr_b<3, false, true>;
1524 warnAboutNonZeroRT =
true;
1528 if (singleInstructionLeft) {
1531 ic->
f = f_singleStepping;
1532 samepage_function = NULL;
1537 ic->
arg[0].
p = &m_gpr[rs];
1538 ic->
arg[1].
p = &m_gpr[rt];
1542 if (rt !=
MIPS_GPR_ZERO && warnAboutNonZeroRT && ui != NULL)
1543 ui->
ShowDebugMessage(
this,
"MIPS branch with rt non-zero, where it should have been zero?");
1547 if (samepage_function != NULL &&
1553 ic->
f = samepage_function;
1559 " TODO: How should this be handled?");
1575 ic->
arg[0].
p = &m_gpr[rt];
1576 ic->
arg[1].
p = &m_gpr[rs];
1580 ic->
arg[2].
u32 = (int16_t)iword;
1582 ic->
arg[2].
u32 = (uint16_t)iword;
1586 case HI6_ADDIU: ic->
f = instr_add_u64_u64_imms32_truncS32;
break;
1590 case HI6_DADDIU: ic->
f = instr_add_u64_u64_imms32; requiredISA = 3;
break;
1591 case HI6_ANDI: ic->
f = instr_and_u64_u64_immu32;
break;
1592 case HI6_ORI: ic->
f = instr_or_u64_u64_immu32;
break;
1593 case HI6_XORI: ic->
f = instr_xor_u64_u64_immu32;
break;
1601 ic->
f = instr_set_u64_imms32;
1602 ic->
arg[0].
p = &m_gpr[rt];
1603 ic->
arg[1].
u32 = (int32_t) (imm << 16);
1616 ic->
f = instr_j<false, false>;
1617 f_singleStepping = instr_j<false, true>;
1620 ic->
f = instr_j<true, false>;
1621 f_singleStepping = instr_j<true, true>;
1626 if (singleInstructionLeft)
1627 ic->
f = f_singleStepping;
1629 ic->
arg[0].
u32 = (iword & 0x03ffffff) << 2;
1634 " TODO: How should this be handled?");
1654 ic->
arg[0].
p = &m_gpr[rt];
1655 ic->
arg[1].
p = &m_gpr[rs];
1656 ic->
arg[2].
u32 = (int32_t)imm;
1662 case HI6_LW: ic->
f = instr_loadstore<false, int32_t, uint32_t, true>;
break;
1663 case HI6_SB: ic->
f = instr_loadstore<true, int32_t, uint8_t, false>; store =
true;
break;
1664 case HI6_SW: ic->
f = instr_loadstore<true, int32_t, uint32_t, false>; store =
true;
break;
1668 case HI6_LW: ic->
f = instr_loadstore<false, uint64_t, uint32_t, true>;
break;
1669 case HI6_SB: ic->
f = instr_loadstore<true, uint64_t, uint8_t, false>; store =
true;
break;
1670 case HI6_SW: ic->
f = instr_loadstore<true, uint64_t, uint32_t, false>; store =
true;
break;
1676 ic->
arg[0].
p = &m_scratch;
1683 ss.flags(std::ios::hex);
1684 ss <<
"unimplemented opcode 0x" << hi6;
1698 ss.flags(std::ios::hex);
1699 ss <<
"instruction at 0x" <<
m_pc <<
" requires ISA level ";
1700 ss.flags(std::ios::dec);
1701 ss << requiredISA <<
"; this cpu supports only ISA level " <<
1708 if ((requiredISA == 3 || requiredISA == 4) && Is32Bit()) {
1716 ss.flags(std::ios::hex);
1717 ss <<
"instruction at 0x" <<
m_pc <<
" is a 64-bit instruction," 1718 " which cannot be executed on this CPU\n";
1732 ss.flags(std::ios::hex);
1733 ss <<
"instruction at 0x" <<
m_pc <<
" is a MIPS32/64 revision ";
1734 ss << requiredISArevision <<
" instruction; this cpu supports" 1746 cpu->DyntransToBeTranslatedBegin(ic);
1749 if (
cpu->DyntransReadInstruction(iword))
1750 cpu->Translate(iword, ic);
1752 if (
cpu->m_inDelaySlot && ic->
f == NULL)
1753 ic->
f = instr_abort;
1755 cpu->DyntransToBeTranslatedDone(ic);
1763 cpu->DyntransToBeTranslatedBegin(ic);
1766 if (
cpu->DyntransReadInstruction(iword)) {
1768 UI* ui =
cpu->GetUI();
1771 ss.flags(std::ios::hex);
1772 ss <<
"TODO: recode MIPS16 => regular MIPS instruction\n";
1779 cpu->DyntransToBeTranslatedDone(ic);
1786 #ifdef WITHUNITTESTS 1790 static void Test_MIPS_CPUComponent_IsStable()
1796 static void Test_MIPS_CPUComponent_Create()
1807 static void Test_MIPS_CPUComponent_IsCPU()
1815 static void Test_MIPS_CPUComponent_DefaultModel()
1825 static void Test_MIPS_CPUComponent_ModelChange()
1839 static void Test_MIPS_CPUComponent_Disassembly_Basic()
1845 vector<string> result;
1847 unsigned char instruction[
sizeof(uint32_t)];
1849 instruction[0] = 0x27;
1850 instruction[1] = 0xbd;
1851 instruction[2] = 0xff;
1852 instruction[3] = 0xd8;
1855 instruction, result);
1864 static void Test_MIPS_CPUComponent_Execute_DelayBranchWithValidInstruction()
1875 uint32_t data32 = 0x10000111;
1876 bus->AddressSelect(0xffffffff80004000ULL);
1879 data32 = 0x27bdffd8;
1880 bus->AddressSelect(0xffffffff80004004ULL);
1896 static void Test_MIPS_CPUComponent_Execute_DelayBranchWithValidInstruction_SingleStepping()
1907 uint32_t data32 = 0x10000111;
1908 bus->AddressSelect(0xffffffff80004000ULL);
1911 data32 = 0x27bdffd8;
1912 bus->AddressSelect(0xffffffff80004004ULL);
1937 static void Test_MIPS_CPUComponent_Execute_DelayBranchWithValidInstruction_RunTwoTimes()
1948 uint32_t data32 = 0x10000111;
1949 bus->AddressSelect(0xffffffff80004000ULL);
1952 data32 = 0x27bdffd8;
1953 bus->AddressSelect(0xffffffff80004004ULL);
1978 static void Test_MIPS_CPUComponent_Execute_DelayBranchWithFault()
1989 uint32_t data32 = 0x10000111;
1990 bus->AddressSelect(0xffffffff80004000ULL);
1993 data32 = 0xffffffff;
1994 bus->AddressSelect(0xffffffff80004004ULL);
2018 UNITTEST(Test_MIPS_CPUComponent_IsStable);
2019 UNITTEST(Test_MIPS_CPUComponent_Create);
2020 UNITTEST(Test_MIPS_CPUComponent_IsCPU);
2021 UNITTEST(Test_MIPS_CPUComponent_DefaultModel);
2022 UNITTEST(Test_MIPS_CPUComponent_ModelChange);
2025 UNITTEST(Test_MIPS_CPUComponent_Disassembly_Basic);
2028 UNITTEST(Test_MIPS_CPUComponent_Execute_DelayBranchWithValidInstruction);
2029 UNITTEST(Test_MIPS_CPUComponent_Execute_DelayBranchWithValidInstruction_SingleStepping);
2030 UNITTEST(Test_MIPS_CPUComponent_Execute_DelayBranchWithValidInstruction_RunTwoTimes);
2031 UNITTEST(Test_MIPS_CPUComponent_Execute_DelayBranchWithFault);
void SetRunState(RunState newState)
Sets the RunState.
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
virtual CPUComponent * AsCPUComponent()
Returns the component's CPUComponent interface.
#define MIPS_REGISTER_NAMES
virtual void ShowDebugMessage(const string &msg)=0
Shows a debug message.
StateVariable * GetVariable(const string &name)
Gets a pointer to a state variable.
static string GetAttribute(const string &attributeName)
static refcount_ptr< Component > CreateComponent(const string &componentNameAndOptionalArgs, GXemul *gxemul=NULL)
Creates a component given a short component name.
void(* f)(CPUDyntransComponent *, DyntransIC *)
struct arm_instr_call * ic
#define MIPS_OLDABI_REGISTER_NAMES
uint64_t m_delaySlotTarget
virtual int64_t FunctionTraceArgument(int n)
bool RunCommand(const string &command, bool *pSuccess=NULL)
Runs a command, given as a string.
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
virtual void ShowRegisters(GXemul *gxemul, const vector< string > &arguments) const
bool AddVariable(const string &name, T *variablePointer)
Adds a state variable of type T to the Component.
UI * GetUI()
Gets an UI reference for outputting debug messages during runtime.
int m_nrOfCyclesToExecute
union DyntransIC::@0 arg[N_DYNTRANS_IC_ARGS]
static refcount_ptr< Component > Create(const ComponentCreateArgs &args)
Creates a MIPS_CPUComponent.
A dyntrans instruction call.
An interface for implementing components that read/write data via an address bus. ...
static string GetAttribute(const string &attributeName)
Creates a Component.
MIPS_CPUComponent()
Constructs a MIPS_CPUComponent.
#define UNITTESTS(class)
Helper for unit test case execution.
CommandInterpreter & GetCommandInterpreter()
Gets a reference to the CommandInterpreter.
map< string, string > ComponentCreationSettings
virtual size_t DisassembleInstruction(uint64_t vaddr, size_t maxlen, unsigned char *instruction, vector< string > &result)
Disassembles an instruction into readable strings.
struct DyntransIC * m_firstIConPage
string LookupAddress(uint64_t vaddr, bool allowOffset) const
Looks up an address.
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
virtual int FunctionTraceArgumentCount()
string ToString() const
Returns the variable as a readable string.
static bool HasAttribute(const string &name, const string &attributeName)
Checks if a component has a specific attribute.
#define DYNTRANS_SYNCH_PC
A Component representing a MIPS processor.
virtual void ResetState()
Resets the state variables of this component.
virtual bool FunctionTraceReturnImpl(int64_t &retval)
SymbolRegistry & GetSymbolRegistry()
Gets a reference to the CPU's symbol registry.
#define MIPS_CPU_TYPE_DEFS
DYNTRANS_INSTR(MIPS_CPUComponent, multu)
int m_dyntransICentriesPerPage
A base-class for processors Component implementations that use dynamic translation.
uint64_t ToInteger() const
Returns the variable as an unsignedinteger value.
virtual void(*)(CPUDyntransComponent *, DyntransIC *) GetDyntransToBeTranslated()
StateVariables make up the persistent state of Component objects.
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
A base-class for processors Component implementations.
#define MIPS_INITIAL_STACK_POINTER
virtual size_t DisassembleInstruction(uint64_t vaddr, size_t maxLen, unsigned char *instruction, vector< string > &result)=0
Disassembles an instruction into readable strings.
static void Assert(const string &strFailMessage, bool condition)
Asserts that a boolean condition is correct.
virtual void ResetState()
Resets the state variables of this component.
bool SetVariableValue(const string &name, const string &expression)
Sets a variable to a new value.
refcount_ptr< Component > GetRootComponent()
Gets a pointer to the root configuration component.
virtual AddressDataBus * AsAddressDataBus()
Returns the component's AddressDataBus interface, if any.
#define SPECIAL_ROT_NAMES
#define DYNTRANS_INSTR_HEAD(class)
UI * GetUI()
Gets a pointer to the GXemul instance' active UI.
static bool GetCreationArgOverrides(ComponentCreationSettings &settings, const ComponentCreateArgs &createArgs)
Get override arguments for component creation.
virtual int GetDyntransICshift() const
Base class for a User Interface.
virtual bool VirtualToPhysical(uint64_t vaddr, uint64_t &paddr, bool &writable)
Virtual to physical address translation (MMU).
const refcount_ptr< Component > LookupPath(string path) const
Looks up a path from this Component, and returns a pointer to the found Component, if any.
virtual uint64_t PCtoInstructionAddress(uint64_t pc)
Convert PC value to instuction address.
void Execute(const int longestTotalRun=100000)
Run the emulation for "a while".
#define UNITTEST(functionname)
Helper for unit test case execution.
bool IsNULL() const
Checks whether or not an object is referenced by the reference counted pointer.