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();
106 if (!
cpu->SetVariableValue(
"model",
"\"" +
settings[
"model"] +
"\""))
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.";
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;
993 cpu->m_pc =
cpu->m_pc + (int32_t)
ic->arg[2].u32;
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;
1027 cpu->m_pc +=
ic->arg[0].u32;
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;
1054 cpu->m_pc +=
ic->arg[0].u32;
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))
1160 addr = (int32_t) (
REG64(
ic->arg[1]) + (int32_t)
ic->arg[2].u32);
1162 if (
sizeof(T) > 1 && (
addr & (
sizeof(T)-1))) {
1163 std::cerr <<
"TODO: MIPS unaligned data access exception!\n";
1164 throw std::exception();
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];
1263 ic->arg[2].u32 = sa;
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;
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()
1822 cpu->GetVariable(
"model")->ToString(),
"5KE");
1825 static void Test_MIPS_CPUComponent_ModelChange()
1830 cpu->SetVariableValue(
"model",
"\"R2000\"");
1832 cpu->GetVariable(
"model")->ToString(),
"R2000");
1834 cpu->SetVariableValue(
"model",
"\"R1000\"");
1836 cpu->GetVariable(
"model")->ToString(),
"R2000");
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;
1854 len =
cpu->DisassembleInstruction(0x12345678,
sizeof(uint32_t),
1855 instruction, result);
1864 static void Test_MIPS_CPUComponent_Execute_DelayBranchWithValidInstruction()
1875 uint32_t data32 = 0x10000111;
1879 data32 = 0x27bdffd8;
1883 cpu->SetVariableValue(
"pc",
"0xffffffff80004000");
1884 UnitTest::Assert(
"setting pc failed?",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004000ULL);
1885 UnitTest::Assert(
"sp before execute",
cpu->GetVariable(
"sp")->ToInteger(), 0xffffffffa0007f00ULL);
1892 UnitTest::Assert(
"pc should have changed",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004448ULL);
1893 UnitTest::Assert(
"sp should have changed",
cpu->GetVariable(
"sp")->ToInteger(), 0xffffffffa0007ed8ULL);
1896 static void Test_MIPS_CPUComponent_Execute_DelayBranchWithValidInstruction_SingleStepping()
1907 uint32_t data32 = 0x10000111;
1911 data32 = 0x27bdffd8;
1915 cpu->SetVariableValue(
"pc",
"0xffffffff80004000");
1916 UnitTest::Assert(
"setting pc failed?",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004000ULL);
1917 UnitTest::Assert(
"sp before execute",
cpu->GetVariable(
"sp")->ToInteger(), 0xffffffffa0007f00ULL);
1925 UnitTest::Assert(
"pc should have changed 1",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004004ULL);
1927 UnitTest::Assert(
"sp should not yet have changed",
cpu->GetVariable(
"sp")->ToInteger(), 0xffffffffa0007f00ULL);
1932 UnitTest::Assert(
"pc should have changed 2",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004448ULL);
1933 UnitTest::Assert(
"delay slot after branch",
cpu->GetVariable(
"inDelaySlot")->ToString(),
"false");
1934 UnitTest::Assert(
"sp should have changed",
cpu->GetVariable(
"sp")->ToInteger(), 0xffffffffa0007ed8ULL);
1937 static void Test_MIPS_CPUComponent_Execute_DelayBranchWithValidInstruction_RunTwoTimes()
1948 uint32_t data32 = 0x10000111;
1952 data32 = 0x27bdffd8;
1956 cpu->SetVariableValue(
"pc",
"0xffffffff80004000");
1957 UnitTest::Assert(
"setting pc failed?",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004000ULL);
1958 UnitTest::Assert(
"sp before execute",
cpu->GetVariable(
"sp")->ToInteger(), 0xffffffffa0007f00ULL);
1966 UnitTest::Assert(
"pc should have changed 1",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004004ULL);
1968 UnitTest::Assert(
"sp should not yet have changed",
cpu->GetVariable(
"sp")->ToInteger(), 0xffffffffa0007f00ULL);
1973 UnitTest::Assert(
"pc should have changed 2",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004448ULL);
1974 UnitTest::Assert(
"delay slot after branch",
cpu->GetVariable(
"inDelaySlot")->ToString(),
"false");
1975 UnitTest::Assert(
"sp should have changed",
cpu->GetVariable(
"sp")->ToInteger(), 0xffffffffa0007ed8ULL);
1978 static void Test_MIPS_CPUComponent_Execute_DelayBranchWithFault()
1989 uint32_t data32 = 0x10000111;
1993 data32 = 0xffffffff;
1997 cpu->SetVariableValue(
"pc",
"0xffffffff80004000");
1998 UnitTest::Assert(
"setting pc failed?",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004000ULL);
1999 UnitTest::Assert(
"should not be in delay slot before execution",
cpu->GetVariable(
"inDelaySlot")->ToString(),
"false");
2006 UnitTest::Assert(
"pc should have increased one step",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004004ULL);
2007 UnitTest::Assert(
"should be in delay slot after execution",
cpu->GetVariable(
"inDelaySlot")->ToString(),
"true");
2012 UnitTest::Assert(
"pc should not have increased",
cpu->GetVariable(
"pc")->ToInteger(), 0xffffffff80004004ULL);
2013 UnitTest::Assert(
"should still be in delay slot",
cpu->GetVariable(
"inDelaySlot")->ToString(),
"true");
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);