ISSでシステムレジスタをサポートしたので、トレースログに表示できるようにしよう。
基本的にやっていることはこれと一緒。というか、単純に移植しただけだ。
システムレジスタにアクセスすると、そのアクセス情報を記録しておき、最後のトレース出力でその結果を出すことにする。
void InstEnv::MIPS_INST_MFC0 (Word_t inst_hex) { RegAddr_t rd_addr = ExtractRDField (inst_hex); RegAddr_t rt_addr = ExtractRTField (inst_hex); RegAddr_t sel = ExtractBitField (inst_hex, 2, 0); RegAddr_t csr_addr = (rd_addr << 3) | sel; Word_t csr_val; m_env->CSRRead (csr_addr, &csr_val); m_env->GRegWrite (rt_addr, csr_val); } void InstEnv::MIPS_INST_MTC0 (Word_t inst_hex) { RegAddr_t rd_addr = ExtractRDField (inst_hex); RegAddr_t rt_addr = ExtractRTField (inst_hex); RegAddr_t sel = ExtractBitField (inst_hex, 2, 0); RegAddr_t csr_addr = (rd_addr << 3) | sel; Word_t rt_val = m_env->GRegRead (rt_addr); m_env->CSRWrite (csr_addr, rt_val); }
最後の表記の拡張部分:
void MipsEnv::PrintOperand (std::stringstream *operand_str) { uint32_t trace_count; for (trace_count = 0; trace_count < GetTrace()->GetMax (); trace_count ++) { switch (GetTrace()->GetTraceType(trace_count)) { case traceInfo::trace_regwrite : if (GetTrace()->GetTraceAddr (trace_count) == REG_PC) { (*operand_str) << "pc<=" << std::hex << std::setw(8) << GetTrace()->GetTraceValue (trace_count) << " "; } else { RegAddr_t reg_addr = GetTrace()->GetTraceAddr (trace_count); if (GetPrintRegStyle () == ABI_REG_HARD_NAME) { (*operand_str) << "r" << std::dec << std::setw(2) << std::setfill('0') << static_cast<uint32_t>(reg_addr); } else { (*operand_str) << m_abi_regs[reg_addr]; } (*operand_str) << "<=" << std::hex << std::setw(8) << std::setfill('0') << GetTrace()->GetTraceValue (trace_count) << " "; } break; case traceInfo::trace_regread : { RegAddr_t reg_addr = GetTrace()->GetTraceAddr (trace_count); if (GetPrintRegStyle () == ABI_REG_HARD_NAME) { (*operand_str) << "r" << std::dec << std::setw(2) << std::setfill('0') << static_cast<uint32_t>(reg_addr); } else { (*operand_str) << m_abi_regs[reg_addr]; } (*operand_str) << "=>" << std::hex << std::setw(8) << std::setfill('0') << GetTrace()->GetTraceValue (trace_count) << ' '; break; } case traceInfo::trace_memwrite : (*operand_str) << "(" << std::hex << std::setw(8) << std::setfill('0') << GetTrace()->GetTraceAddr (trace_count) << ")" << "<=" << std::hex << std::setw(8) << std::setfill('0') << GetTrace()->GetTraceValue (trace_count) << " "; break; case traceInfo::trace_memread : { (*operand_str) << "(" << std::hex << std::setw(8) << std::setfill('0') << GetTrace()->GetTraceAddr (trace_count) << ")" << "=>" << std::hex << std::setw(8) << std::setfill('0') << GetTrace()->GetTraceValue (trace_count) << " "; break; } case traceInfo::trace_csrWrite : { std::string csr_name = m_csr_env->GetCSRName (GetTrace()->GetTraceAddr (trace_count)); (*operand_str) << csr_name << "<=" << std::hex << std::setw(8) << std::setfill('0') << GetTrace()->GetTraceValue (trace_count) << " "; break; } case traceInfo::trace_csrRead : { std::string csr_name = m_csr_env->GetCSRName (GetTrace()->GetTraceAddr (trace_count)); (*operand_str) << csr_name << "=>" << std::hex << std::setw(8) << std::setfill('0') << GetTrace()->GetTraceValue (trace_count) << " "; break; } } } }
これで、トレース表記が拡張された。mtc0, mfc0命令で、アクセスしたシステムレジスタが表示されるようになった。
4962779 : [00100058] 00000000 : sll r00,r00,0x00 r00=>00000000 4962780 : [0010005c] 1d20fff9 : bgtz r09,0xfff9 r09=>0000001e pc<=00100060 pc<=00100044 4962781 : [00100060] 00000000 : sll r00,r00,0x00 r00=>00000000 4962782 : [00100044] 40885000 : mtc0 r10,0x0a,0x0 r08=>a0004000 PageMask<=a0004000 4962783 : [00100048] 25082000 : addiu r08,r08,0x2000 r08=>a0004000 r08<=a0006000 4962784 : [0010004c] 2529ffff : addiu r09,r09,0xffff r09=>0000001e r09<=0000001d 4962785 : [00100050] 40890000 : mtc0 r00,0x00,0x0 r09=>0000001d Index<=0000001d