48 #include "config/the_isa.hh" 63 const int TarmacParserRecord::MaxLineLength;
64 int8_t TarmacParserRecord::maxVectorLength = 0;
66 TarmacParserRecord::ParserInstEntry TarmacParserRecord::instRecord;
67 TarmacParserRecord::ParserRegEntry TarmacParserRecord::regRecord;
68 TarmacParserRecord::ParserMemEntry TarmacParserRecord::memRecord;
69 TarmacBaseRecord::TarmacRecordType TarmacParserRecord::currRecordType;
72 char TarmacParserRecord::buf[TarmacParserRecord::MaxLineLength];
73 TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
632 TarmacParserRecord::TarmacParserRecordEvent::process()
637 end = destRegRecords.end();
641 for (; it != end; ++it) {
646 values.push_back(thread->readIntReg(it->index));
649 if (instRecord.isetstate == ISET_A64) {
652 auto vv = vc.as<uint32_t>();
653 values.push_back(vv[0]);
655 const VecElem elem = thread->readVecElem(
659 values.push_back(elem);
663 if (instRecord.isetstate == ISET_A64) {
666 auto vv = vc.as<uint64_t>();
667 values.push_back(vv[0]);
669 const VecElem w0 = thread->readVecElem(
673 const VecElem w1 = thread->readVecElem(
678 values.push_back((uint64_t)(w1) << 32 | w0);
685 auto pv = pc.as<uint8_t>();
687 for (
int i = maxVectorLength * 8;
i > 0; ) {
688 p = (p << 1) | pv[--
i];
694 if (instRecord.isetstate == ISET_A64) {
697 auto vv = vc.as<uint64_t>();
698 values.push_back(vv[0]);
699 values.push_back(vv[1]);
701 const VecElem w0 = thread->readVecElem(
705 const VecElem w1 = thread->readVecElem(
709 const VecElem w2 = thread->readVecElem(
713 const VecElem w3 = thread->readVecElem(
718 values.push_back((uint64_t)(w1) << 32 | w0);
719 values.push_back((uint64_t)(w3) << 32 | w2);
724 int8_t
i = maxVectorLength;
727 auto vv = vc.as<uint64_t>();
729 values.push_back(vv[--i]);
736 CPSR cpsr = thread->readMiscRegNoEffect(it->index);
737 cpsr.nz = thread->readCCReg(
CCREG_NZ);
738 cpsr.c = thread->readCCReg(
CCREG_C);
739 cpsr.v = thread->readCCReg(
CCREG_V);
740 cpsr.ge = thread->readCCReg(
CCREG_GE);
741 values.push_back(cpsr);
744 cpsr.nz = thread->readCCReg(
CCREG_NZ);
745 cpsr.c = thread->readCCReg(
CCREG_C);
746 cpsr.v = thread->readCCReg(
CCREG_V);
747 values.push_back(cpsr);
751 const uint32_t ones = (uint32_t)(-1);
760 fpcrMask.stride = ones;
761 fpcrMask.rMode = ones;
765 values.push_back(fpscr & fpcrMask);
769 const uint32_t ones = (uint32_t)(-1);
782 values.push_back(fpscr & fpsrMask);
784 values.push_back(thread->readMiscRegNoEffect(it->index));
788 panic(
"Unknown TARMAC trace record type!");
792 if (values.size() != it->values.size()) same =
false;
794 uint32_t size = values.size();
795 if (size > it->values.size())
796 size = it->values.size();
799 for (
int i = 0;
i < size; ++
i) {
800 if (values[
i] != it->values[
i]) {
809 TarmacParserRecord::printMismatchHeader(inst,
pc);
812 outs <<
"diff> [" << it->repr <<
"] gem5: 0x" << hex;
813 for (
auto v : values)
814 outs << setw(16) << setfill(
'0') <<
v;
816 outs <<
", TARMAC: 0x" << hex;
817 for (
auto v : it->values)
818 outs << setw(16) << setfill(
'0') <<
v;
822 destRegRecords.clear();
824 if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
825 parent.exitOnInsnDiff))
826 exitSimLoop(
"a mismatch with the TARMAC trace has been detected " 827 "on PC or opcode", 1);
828 if (mismatch && parent.exitOnDiff)
829 exitSimLoop(
"a mismatch with the TARMAC trace has been detected " 834 TarmacParserRecord::TarmacParserRecordEvent::description()
const 836 return "TARMAC parser record event";
845 outs <<
"\nMismatch between gem5 and TARMAC trace @ " << dec <<
curTick()
847 <<
"[seq_num: " << dec << instRecord.seq_num
848 <<
", opcode: 0x" << hex << (staticInst->
machInst & 0xffffffff)
849 <<
", PC: 0x" << pc.pc()
850 <<
", disasm: " << staticInst->
disassemble(pc.pc()) <<
"]" 860 _pc, _macroStaticInst),
861 parsingStarted(false), mismatch(false),
862 mismatchOnPcOrOpcode(false), parent(_parent)
864 memReq = std::make_shared<Request>();
875 uint64_t written_data = 0;
902 outs <<
"diff> [PC] gem5: 0x" << hex <<
pc.instAddr()
908 if (arm_inst->encoding() !=
instRecord.opcode) {
911 outs <<
"diff> [opcode] gem5: 0x" << hex
912 << arm_inst->encoding()
913 <<
", TARMAC: 0x" <<
instRecord.opcode << endl;
925 outs <<
"diff> [iset_state] gem5: " 946 outs <<
"diff> [mem(0x" << hex <<
memRecord.addr
947 <<
")] gem5: 0x" << written_data
957 panic(
"Unknown TARMAC trace record type!");
969 exitSimLoop(
"a mismatch with the TARMAC trace has been detected " 970 "on PC or opcode", 1);
989 assert((buf[0] ==
'c') && (buf[1] ==
'p') && (buf[2] ==
'u'));
1006 char c = trace.peek();
1024 warn(
"Invalid TARMAC trace record (seq_num: %lld)",
1032 }
else if (
buf[0] ==
'R') {
1038 if (std::tolower(buf[0]) ==
'r' && isdigit(buf[1])) {
1041 int base_index = atoi(&buf[1]);
1042 char* pch = strchr(buf,
'_');
1047 if (strncmp(pch,
"usr", 3) == 0)
1049 else if (strncmp(pch,
"fiq", 3) == 0)
1051 else if (strncmp(pch,
"irq", 3) == 0)
1053 else if (strncmp(pch,
"svc", 3) == 0)
1055 else if (strncmp(pch,
"mon", 3) == 0)
1057 else if (strncmp(pch,
"abt", 3) == 0)
1059 else if (strncmp(pch,
"und", 3) == 0)
1061 else if (strncmp(pch,
"hyp", 3) == 0)
1064 }
else if (std::tolower(buf[0]) ==
'x' && isdigit(buf[1])) {
1068 }
else if (std::tolower(buf[0]) ==
's' && isdigit(buf[1])) {
1072 }
else if (std::tolower(buf[0]) ==
'd' && isdigit(buf[1])) {
1076 }
else if (std::tolower(buf[0]) ==
'q' && isdigit(buf[1])) {
1080 }
else if (std::tolower(buf[0]) ==
'z' && isdigit(buf[1])) {
1084 }
else if (std::tolower(buf[0]) ==
'p' && isdigit(buf[1])) {
1088 }
else if (strncmp(buf,
"SP_EL", 5) == 0) {
1098 string reg_name =
buf;
1099 transform(reg_name.begin(), reg_name.end(), reg_name.begin(),
1105 warn(
"Unknown register in TARMAC trace (%s).\n", buf);
1115 uint64_t hi = strtoull(buf, NULL, 16);
1117 uint64_t
lo = strtoull(buf, NULL, 16);
1131 v = (v << 32) | lsw;
1132 if (
i < maxVectorLength - 1) trace >>
c;
1139 char c = trace.peek();
1140 if ((c ==
':') || (c ==
'_')) {
1144 v = (v << 32) | lsw;
1154 char c = trace.peek();
1166 data = (data << 32) | lsw;
1187 req->setVirt(addr, size, flags,
thread->
pcState().instAddr(),
1200 if (req->isLLSC() || req->isLocalAccess())
1227 saved_offset = trace.tellg();
1228 trace >> buf >> buf >>
buf;
1231 if (buf[0] ==
'I') {
1233 if (pc == startPc) {
1235 trace.seekg(saved_offset, ios::beg);
1238 trace.ignore(TarmacParserRecord::MaxLineLength,
'\n');
1241 trace.ignore(TarmacParserRecord::MaxLineLength,
'\n');
1244 panic(
"End of TARMAC trace reached before start PC\n");
1251 switch (isetstate) {
1255 return "Thumb (A32)";
1259 return "UNSUPPORTED";
1266 TarmacParserParams::create()
#define panic(...)
This implements a cprintf based panic() function.
virtual const std::string & disassemble(Addr pc, const Loader::SymbolTable *symtab=nullptr) const
Return string representation of disassembled instruction.
std::ifstream trace
TARMAC trace file.
static IntRegIndex INTREG_USR(unsigned index)
decltype(nullptr) constexpr NoFault
static IntRegIndex INTREG_SVC(unsigned index)
ISetState
ARM instruction set state.
Event triggered to check the value of the destination registers.
virtual BaseTLB * getDTBPtr()=0
static TarmacRecordType currRecordType
Type of last parsed record.
static IntRegIndex INTREG_IRQ(unsigned index)
virtual TheISA::PCState pcState() const =0
static ParserRegEntry regRecord
Buffer for register trace records.
union Trace::InstRecord::@115 data
bool contains(const Addr &a) const
Determine if the range contains an address.
bool exitOnInsnDiff
If true, the simulation is stopped as the first mismatch is detected on PC or opcode.
std::shared_ptr< Request > RequestPtr
static ISetState pcToISetState(ArmISA::PCState pc)
Returns the Instruction Set State according to the current PCState.
const char * iSetStateToStr(ISetState isetstate) const
Returns the string representation of an instruction set state.
bool parsingStarted
True if a TARMAC instruction record has already been parsed for this instruction. ...
virtual PortProxy & getVirtProxy()=0
Addr size
The size of the memory request.
RequestPtr memReq
Request for memory write checks.
bool mismatch
True if a mismatch has been detected for this instruction.
vector< EventQueue * > mainEventQueue
Array for main event queues.
Overload hash function for BasicBlockRange type.
ThreadContext is the external interface to all thread state for anything outside of the CPU...
bool cpuId
If true, the trace format includes the CPU id.
This master id is used for functional requests that don't come from a particular device.
static std::list< ParserRegEntry > destRegRecords
List of records of destination registers.
Tarmac Parser: this tracer parses an existing Tarmac trace and it diffs it with gem5 simulation statu...
bool mismatchOnPcOrOpcode
True if a mismatch has been detected for this instruction on PC or opcode.
Vector Register Native Elem lane.
const ExtMachInst machInst
The binary machine instruction.
PortProxy Object Declaration.
bool readMemNoEffect(Addr addr, uint8_t *data, unsigned size, unsigned flags)
Performs a memory access to read the value written by a previous write.
Tick curTick()
The current simulated tick.
static MiscRegMap miscRegMap
static ParserInstEntry instRecord
Buffer for instruction trace records.
uint64_t Tick
Tick count type.
static int8_t maxVectorLength
Max.
VecPredReg::Container VecPredRegContainer
static ParserMemEntry memRecord
Buffer for memory access trace records (stores only).
static IntRegIndex INTREG_MON(unsigned index)
std::ostream & output()
Get the ostream from the current global logger.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
static IntRegIndex INTREG_UND(unsigned index)
void advanceTraceToStartPc()
Helper function to advance the trace up to startPc.
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
static IntRegIndex INTREG_FIQ(unsigned index)
unsigned flags
The flags that were assigned to the request.
static void printMismatchHeader(const StaticInstPtr inst, ArmISA::PCState pc)
Print a mismatch header containing the instruction fields as reported by gem5.
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
The request should not cause a memory access.
static IntRegIndex INTREG_ABT(unsigned index)
Declaration of the Packet class.
VecReg::Container VecRegContainer
static IntRegIndex INTREG_HYP(unsigned index)
AddrRange ignoredAddrRange
Ignored addresses (ignored if empty).
bool macroopInProgress
True if a macroop is currently in progress.
Register ID: describe an architectural register with its class and index.
bool advanceTrace()
Advances the TARMAC trace up to the next instruction, register, or memory access record.
static char buf[MaxLineLength]
Buffer used for trace file parsing.
bool memWrCheck
If true, memory write accesses are checked.
bool exitOnDiff
If true, the simulation is stopped as the first mismatch is detected.
constexpr unsigned NumVecElemPerNeonVecReg
GenericISA::DelaySlotPCState< MachInst > PCState
T * get() const
Directly access the pointer itself without taking a reference.
static const int MaxLineLength
std::shared_ptr< FaultBase > Fault
Addr addr
The address that was accessed.
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode, ArmTranslationType tranType)
bool isLastMicroop() const