Go to the documentation of this file.
59 using namespace ArmISA;
64 const int TarmacParserRecord::MaxLineLength;
65 int8_t TarmacParserRecord::maxVectorLength = 0;
67 TarmacParserRecord::ParserInstEntry TarmacParserRecord::instRecord;
68 TarmacParserRecord::ParserRegEntry TarmacParserRecord::regRecord;
69 TarmacParserRecord::ParserMemEntry TarmacParserRecord::memRecord;
70 TarmacBaseRecord::TarmacRecordType TarmacParserRecord::currRecordType;
73 TarmacParserRecord::destRegRecords;
74 char TarmacParserRecord::buf[TarmacParserRecord::MaxLineLength];
75 TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
740 TarmacParserRecord::TarmacParserRecordEvent::process()
745 end = destRegRecords.end();
749 for (; it != end; ++it) {
754 values.push_back(thread->readIntReg(it->index));
757 if (instRecord.isetstate == ISET_A64) {
760 auto vv = vc.
as<uint32_t>();
761 values.push_back(vv[0]);
763 const VecElem elem = thread->readVecElem(
767 values.push_back(elem);
771 if (instRecord.isetstate == ISET_A64) {
774 auto vv = vc.
as<uint64_t>();
775 values.push_back(vv[0]);
777 const VecElem w0 = thread->readVecElem(
781 const VecElem w1 = thread->readVecElem(
786 values.push_back((uint64_t)(w1) << 32 | w0);
793 auto pv =
pc.as<uint8_t>();
795 for (
int i = maxVectorLength * 8;
i > 0; ) {
796 p = (
p << 1) | pv[--
i];
802 if (instRecord.isetstate == ISET_A64) {
805 auto vv = vc.
as<uint64_t>();
806 values.push_back(vv[0]);
807 values.push_back(vv[1]);
809 const VecElem w0 = thread->readVecElem(
813 const VecElem w1 = thread->readVecElem(
817 const VecElem w2 = thread->readVecElem(
821 const VecElem w3 = thread->readVecElem(
826 values.push_back((uint64_t)(w1) << 32 | w0);
827 values.push_back((uint64_t)(w3) << 32 | w2);
832 int8_t
i = maxVectorLength;
835 auto vv = vc.
as<uint64_t>();
837 values.push_back(vv[--
i]);
844 CPSR cpsr = thread->readMiscRegNoEffect(it->index);
845 cpsr.nz = thread->readCCReg(
CCREG_NZ);
846 cpsr.c = thread->readCCReg(
CCREG_C);
847 cpsr.v = thread->readCCReg(
CCREG_V);
848 cpsr.ge = thread->readCCReg(
CCREG_GE);
849 values.push_back(cpsr);
852 cpsr.nz = thread->readCCReg(
CCREG_NZ);
853 cpsr.c = thread->readCCReg(
CCREG_C);
854 cpsr.v = thread->readCCReg(
CCREG_V);
855 values.push_back(cpsr);
859 const uint32_t ones = (uint32_t)(-1);
868 fpcrMask.stride = ones;
869 fpcrMask.rMode = ones;
873 values.push_back(fpscr & fpcrMask);
877 const uint32_t ones = (uint32_t)(-1);
890 values.push_back(fpscr & fpsrMask);
892 values.push_back(thread->readMiscRegNoEffect(it->index));
896 panic(
"Unknown TARMAC trace record type!");
900 if (values.size() != it->values.size()) same =
false;
902 uint32_t size = values.size();
903 if (size > it->values.size())
904 size = it->values.size();
907 for (
int i = 0;
i < size; ++
i) {
908 if (values[
i] != it->values[
i]) {
917 TarmacParserRecord::printMismatchHeader(inst,
pc);
920 outs <<
"diff> [" << it->repr <<
"] gem5: 0x" << std::hex;
921 for (
auto v : values)
922 outs << std::setw(16) << std::setfill(
'0') <<
v;
924 outs <<
", TARMAC: 0x" << std::hex;
925 for (
auto v : it->values)
926 outs << std::setw(16) << std::setfill(
'0') <<
v;
930 destRegRecords.clear();
932 if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
933 parent.exitOnInsnDiff))
934 exitSimLoop(
"a mismatch with the TARMAC trace has been detected "
935 "on PC or opcode", 1);
936 if (mismatch && parent.exitOnDiff)
937 exitSimLoop(
"a mismatch with the TARMAC trace has been detected "
942 TarmacParserRecord::TarmacParserRecordEvent::description()
const
944 return "TARMAC parser record event";
953 outs <<
"\nMismatch between gem5 and TARMAC trace @ " << std::dec
955 <<
"[seq_num: " << std::dec << instRecord.seq_num
956 <<
", opcode: 0x" << std::hex << (staticInst->
getEMI() & 0xffffffff)
957 <<
", PC: 0x" <<
pc.pc()
968 _pc, _macroStaticInst),
969 parsingStarted(false), mismatch(false),
970 mismatchOnPcOrOpcode(false), parent(_parent)
972 memReq = std::make_shared<Request>();
983 uint64_t written_data = 0;
1010 outs <<
"diff> [PC] gem5: 0x" << std::hex <<
pc.instAddr()
1019 outs <<
"diff> [opcode] gem5: 0x" << std::hex
1020 << arm_inst->encoding()
1033 outs <<
"diff> [iset_state] gem5: "
1054 outs <<
"diff> [mem(0x" << std::hex <<
memRecord.addr
1055 <<
")] gem5: 0x" << written_data
1065 panic(
"Unknown TARMAC trace record type!");
1077 exitSimLoop(
"a mismatch with the TARMAC trace has been detected "
1078 "on PC or opcode", 1);
1091 if (
buf[0] !=
'I') {
1097 assert((
buf[0] ==
'c') && (
buf[1] ==
'p') && (
buf[2] ==
'u'));
1105 if (
buf[0] ==
'I') {
1114 char c = trace.peek();
1132 warn(
"Invalid TARMAC trace record (seq_num: %lld)",
1140 }
else if (
buf[0] ==
'R') {
1146 if (std::tolower(
buf[0]) ==
'r' && isdigit(
buf[1])) {
1149 int base_index = atoi(&
buf[1]);
1150 char* pch = strchr(
buf,
'_');
1155 if (strncmp(pch,
"usr", 3) == 0)
1157 else if (strncmp(pch,
"fiq", 3) == 0)
1159 else if (strncmp(pch,
"irq", 3) == 0)
1161 else if (strncmp(pch,
"svc", 3) == 0)
1163 else if (strncmp(pch,
"mon", 3) == 0)
1165 else if (strncmp(pch,
"abt", 3) == 0)
1167 else if (strncmp(pch,
"und", 3) == 0)
1169 else if (strncmp(pch,
"hyp", 3) == 0)
1172 }
else if (std::tolower(
buf[0]) ==
'x' && isdigit(
buf[1])) {
1176 }
else if (std::tolower(
buf[0]) ==
's' && isdigit(
buf[1])) {
1180 }
else if (std::tolower(
buf[0]) ==
'd' && isdigit(
buf[1])) {
1184 }
else if (std::tolower(
buf[0]) ==
'q' && isdigit(
buf[1])) {
1188 }
else if (std::tolower(
buf[0]) ==
'z' && isdigit(
buf[1])) {
1192 }
else if (std::tolower(
buf[0]) ==
'p' && isdigit(
buf[1])) {
1196 }
else if (strncmp(
buf,
"SP_EL", 5) == 0) {
1206 std::string reg_name =
buf;
1207 std::transform(reg_name.begin(), reg_name.end(), reg_name.begin(),
1213 warn(
"Unknown register in TARMAC trace (%s).\n",
buf);
1223 uint64_t hi = strtoull(
buf, NULL, 16);
1225 uint64_t
lo = strtoull(
buf, NULL, 16);
1239 v = (
v << 32) | lsw;
1247 char c = trace.peek();
1248 if ((
c ==
':') || (
c ==
'_')) {
1252 v = (
v << 32) | lsw;
1262 char c = trace.peek();
1308 if (req->isLLSC() || req->isLocalAccess())
1335 saved_offset =
trace.tellg();
1336 trace >> buf >> buf >> buf;
1339 if (buf[0] ==
'I') {
1343 trace.seekg(saved_offset, std::ios::beg);
1352 panic(
"End of TARMAC trace reached before start PC\n");
1359 switch (isetstate) {
1363 return "Thumb (A32)";
1367 return "UNSUPPORTED";
Tick curTick()
The universal simulation clock.
bool mismatch
True if a mismatch has been detected for this instruction.
@ VecElemClass
Vector Register Native Elem lane.
static char buf[MaxLineLength]
Buffer used for trace file parsing.
bool memWrCheck
If true, memory write accesses are checked.
static IntRegIndex INTREG_FIQ(unsigned index)
static IntRegIndex INTREG_MON(unsigned index)
constexpr decltype(nullptr) NoFault
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode, bool stage2)
@ MISCREG_TLBI_VAAE1IS_Xt
constexpr unsigned NumVecElemPerNeonVecReg
VecPredReg::Container VecPredRegContainer
static std::list< ParserRegEntry > destRegRecords
List of records of destination registers.
static int8_t maxVectorLength
Max.
@ MISCREG_TLBI_IPAS2E1IS_Xt
std::vector< EventQueue * > mainEventQueue
Array for main event queues.
static IntRegIndex INTREG_SVC(unsigned index)
static IntRegIndex INTREG_UND(unsigned index)
bool contains(const Addr &a) const
Determine if the range contains an address.
virtual BaseMMU * getMMUPtr()=0
static IntRegIndex INTREG_USR(unsigned index)
@ MISCREG_TLBI_IPAS2LE1IS_Xt
@ MISCREG_TLBI_VMALLS12E1IS
union gem5::Trace::InstRecord::@111 data
@ MISCREG_TLBI_VALE2IS_Xt
static IntRegIndex INTREG_HYP(unsigned index)
@ MISCREG_TLBI_VALE1IS_Xt
@ MISCREG_ID_AA64AFR1_EL1
@ MISCREG_ID_AA64MMFR0_EL1
std::ifstream trace
TARMAC trace file.
T * get() const
Directly access the pointer itself without taking a reference.
@ MISCREG_ID_AA64DFR1_EL1
@ MISCREG_TLBI_VALE3IS_Xt
@ MISCREG_TLBI_VMALLS12E1
bool cpuId
If true, the trace format includes the CPU id.
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 (...
@ MISCREG_DBGCLAIMCLR_EL1
AddrRange ignoredAddrRange
Ignored addresses (ignored if empty).
bool macroopInProgress
True if a macroop is currently in progress.
const char * iSetStateToStr(ISetState isetstate) const
Returns the string representation of an instruction set state.
Event triggered to check the value of the destination registers.
@ MISCREG_DBGAUTHSTATUS_EL1
static ParserInstEntry instRecord
Buffer for instruction trace records.
bool mismatchOnPcOrOpcode
True if a mismatch has been detected for this instruction on PC or opcode.
std::vector< uint64_t > values
@ MISCREG_DBGCLAIMSET_EL1
ISetState
ARM instruction set state.
static ParserMemEntry memRecord
Buffer for memory access trace records (stores only).
@ MISCREG_ID_AA64PFR1_EL1
ThreadContext is the external interface to all thread state for anything outside of the CPU.
@ MISCREG_ID_AA64MMFR2_EL1
std::shared_ptr< FaultBase > Fault
virtual PortProxy & getVirtProxy()=0
VecElem * as()
View interposers.
static const int MaxLineLength
GenericISA::DelaySlotPCState< 4 > PCState
@ MISCREG_ID_AA64AFR0_EL1
uint64_t Tick
Tick count type.
std::shared_ptr< Request > RequestPtr
static ParserRegEntry regRecord
Buffer for register trace records.
bool exitOnDiff
If true, the simulation is stopped as the first mismatch is detected.
@ MISCREG_TLBI_ASIDE1IS_Xt
std::ostream & output()
Get the ostream from the current global logger.
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
virtual TheISA::PCState pcState() const =0
@ MISCREG_ID_AA64DFR0_EL1
@ MISCREG_ID_AA64MMFR1_EL1
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
bool isLastMicroop() const
RequestPtr memReq
Request for memory write checks.
@ MISCREG_ID_AA64ISAR1_EL1
@ MISCREG_TLBI_IPAS2LE1_Xt
@ MISCREG_TLBI_VAALE1IS_Xt
bool readMemNoEffect(Addr addr, uint8_t *data, unsigned size, unsigned flags)
Performs a memory access to read the value written by a previous write.
Tarmac Parser: this tracer parses an existing Tarmac trace and it diffs it with gem5 simulation statu...
@ VecRegClass
Vector Register.
virtual uint64_t getEMI() const
Addr size
The size of the memory request.
static IntRegIndex INTREG_IRQ(unsigned index)
virtual const std::string & disassemble(Addr pc, const loader::SymbolTable *symtab=nullptr) const
Return string representation of disassembled instruction.
@ funcRequestorId
This requestor id is used for functional requests that don't come from a particular device.
static IntRegIndex INTREG_ABT(unsigned index)
static MiscRegMap miscRegMap
static ISetState pcToISetState(ArmISA::PCState pc)
Returns the Instruction Set State according to the current PCState.
bool parsingStarted
True if a TARMAC instruction record has already been parsed for this instruction.
Addr addr
The address that was accessed.
static void printMismatchHeader(const StaticInstPtr inst, ArmISA::PCState pc)
Print a mismatch header containing the instruction fields as reported by gem5.
@ NO_ACCESS
The request should not cause a memory access.
Addr startPc
Tracing starts when the PC gets this value for the first time (ignored if 0x0).
void advanceTraceToStartPc()
Helper function to advance the trace up to startPc.
bool exitOnInsnDiff
If true, the simulation is stopped as the first mismatch is detected on PC or opcode.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
@ MISCREG_ID_AA64PFR0_EL1
bool advanceTrace()
Advances the TARMAC trace up to the next instruction, register, or memory access record.
@ MISCREG_TLBI_IPAS2E1_Xt
static TarmacRecordType currRecordType
Type of last parsed record.
unsigned flags
The flags that were assigned to the request.
@ MISCREG_ID_AA64ISAR0_EL1
Register ID: describe an architectural register with its class and index.
#define panic(...)
This implements a cprintf based panic() function.
Generated on Tue Sep 21 2021 12:24:46 for gem5 by doxygen 1.8.17