Go to the documentation of this file.
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 = {
734 TarmacParserRecord::TarmacParserRecordEvent::process()
739 end = destRegRecords.end();
743 for (; it != end; ++it) {
748 values.push_back(thread->readIntReg(it->index));
751 if (instRecord.isetstate == ISET_A64) {
754 auto vv = vc.as<uint32_t>();
755 values.push_back(vv[0]);
757 const VecElem elem = thread->readVecElem(
761 values.push_back(elem);
765 if (instRecord.isetstate == ISET_A64) {
768 auto vv = vc.as<uint64_t>();
769 values.push_back(vv[0]);
771 const VecElem w0 = thread->readVecElem(
775 const VecElem w1 = thread->readVecElem(
780 values.push_back((uint64_t)(w1) << 32 | w0);
787 auto pv =
pc.as<uint8_t>();
789 for (
int i = maxVectorLength * 8;
i > 0; ) {
790 p = (
p << 1) | pv[--
i];
796 if (instRecord.isetstate == ISET_A64) {
799 auto vv = vc.as<uint64_t>();
800 values.push_back(vv[0]);
801 values.push_back(vv[1]);
803 const VecElem w0 = thread->readVecElem(
807 const VecElem w1 = thread->readVecElem(
811 const VecElem w2 = thread->readVecElem(
815 const VecElem w3 = thread->readVecElem(
820 values.push_back((uint64_t)(w1) << 32 | w0);
821 values.push_back((uint64_t)(w3) << 32 | w2);
826 int8_t
i = maxVectorLength;
829 auto vv = vc.as<uint64_t>();
831 values.push_back(vv[--
i]);
838 CPSR cpsr = thread->readMiscRegNoEffect(it->index);
839 cpsr.nz = thread->readCCReg(
CCREG_NZ);
840 cpsr.c = thread->readCCReg(
CCREG_C);
841 cpsr.v = thread->readCCReg(
CCREG_V);
842 cpsr.ge = thread->readCCReg(
CCREG_GE);
843 values.push_back(cpsr);
846 cpsr.nz = thread->readCCReg(
CCREG_NZ);
847 cpsr.c = thread->readCCReg(
CCREG_C);
848 cpsr.v = thread->readCCReg(
CCREG_V);
849 values.push_back(cpsr);
853 const uint32_t ones = (uint32_t)(-1);
862 fpcrMask.stride = ones;
863 fpcrMask.rMode = ones;
867 values.push_back(fpscr & fpcrMask);
871 const uint32_t ones = (uint32_t)(-1);
884 values.push_back(fpscr & fpsrMask);
886 values.push_back(thread->readMiscRegNoEffect(it->index));
890 panic(
"Unknown TARMAC trace record type!");
894 if (values.size() != it->values.size()) same =
false;
896 uint32_t size = values.size();
897 if (size > it->values.size())
898 size = it->values.size();
901 for (
int i = 0;
i < size; ++
i) {
902 if (values[
i] != it->values[
i]) {
911 TarmacParserRecord::printMismatchHeader(inst,
pc);
914 outs <<
"diff> [" << it->repr <<
"] gem5: 0x" << hex;
915 for (
auto v : values)
916 outs << setw(16) << setfill(
'0') <<
v;
918 outs <<
", TARMAC: 0x" << hex;
919 for (
auto v : it->values)
920 outs << setw(16) << setfill(
'0') <<
v;
924 destRegRecords.clear();
926 if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
927 parent.exitOnInsnDiff))
928 exitSimLoop(
"a mismatch with the TARMAC trace has been detected "
929 "on PC or opcode", 1);
930 if (mismatch && parent.exitOnDiff)
931 exitSimLoop(
"a mismatch with the TARMAC trace has been detected "
936 TarmacParserRecord::TarmacParserRecordEvent::description()
const
938 return "TARMAC parser record event";
947 outs <<
"\nMismatch between gem5 and TARMAC trace @ " << dec <<
curTick()
949 <<
"[seq_num: " << dec << instRecord.seq_num
950 <<
", opcode: 0x" << hex << (staticInst->
machInst & 0xffffffff)
951 <<
", PC: 0x" <<
pc.pc()
962 _pc, _macroStaticInst),
963 parsingStarted(false), mismatch(false),
964 mismatchOnPcOrOpcode(false), parent(_parent)
966 memReq = std::make_shared<Request>();
977 uint64_t written_data = 0;
1004 outs <<
"diff> [PC] gem5: 0x" << hex <<
pc.instAddr()
1005 <<
", TARMAC: 0x" <<
instRecord.addr << endl;
1010 if (arm_inst->encoding() !=
instRecord.opcode) {
1013 outs <<
"diff> [opcode] gem5: 0x" << hex
1014 << arm_inst->encoding()
1015 <<
", TARMAC: 0x" <<
instRecord.opcode << endl;
1027 outs <<
"diff> [iset_state] gem5: "
1048 outs <<
"diff> [mem(0x" << hex <<
memRecord.addr
1049 <<
")] gem5: 0x" << written_data
1059 panic(
"Unknown TARMAC trace record type!");
1071 exitSimLoop(
"a mismatch with the TARMAC trace has been detected "
1072 "on PC or opcode", 1);
1085 if (
buf[0] !=
'I') {
1091 assert((
buf[0] ==
'c') && (
buf[1] ==
'p') && (
buf[2] ==
'u'));
1099 if (
buf[0] ==
'I') {
1108 char c = trace.peek();
1126 warn(
"Invalid TARMAC trace record (seq_num: %lld)",
1134 }
else if (
buf[0] ==
'R') {
1140 if (std::tolower(
buf[0]) ==
'r' && isdigit(
buf[1])) {
1143 int base_index = atoi(&
buf[1]);
1144 char* pch = strchr(
buf,
'_');
1149 if (strncmp(pch,
"usr", 3) == 0)
1151 else if (strncmp(pch,
"fiq", 3) == 0)
1153 else if (strncmp(pch,
"irq", 3) == 0)
1155 else if (strncmp(pch,
"svc", 3) == 0)
1157 else if (strncmp(pch,
"mon", 3) == 0)
1159 else if (strncmp(pch,
"abt", 3) == 0)
1161 else if (strncmp(pch,
"und", 3) == 0)
1163 else if (strncmp(pch,
"hyp", 3) == 0)
1166 }
else if (std::tolower(
buf[0]) ==
'x' && isdigit(
buf[1])) {
1170 }
else if (std::tolower(
buf[0]) ==
's' && isdigit(
buf[1])) {
1174 }
else if (std::tolower(
buf[0]) ==
'd' && isdigit(
buf[1])) {
1178 }
else if (std::tolower(
buf[0]) ==
'q' && isdigit(
buf[1])) {
1182 }
else if (std::tolower(
buf[0]) ==
'z' && isdigit(
buf[1])) {
1186 }
else if (std::tolower(
buf[0]) ==
'p' && isdigit(
buf[1])) {
1190 }
else if (strncmp(
buf,
"SP_EL", 5) == 0) {
1200 string reg_name =
buf;
1201 transform(reg_name.begin(), reg_name.end(), reg_name.begin(),
1207 warn(
"Unknown register in TARMAC trace (%s).\n",
buf);
1217 uint64_t hi = strtoull(
buf, NULL, 16);
1219 uint64_t
lo = strtoull(
buf, NULL, 16);
1233 v = (
v << 32) | lsw;
1241 char c = trace.peek();
1242 if ((
c ==
':') || (
c ==
'_')) {
1246 v = (
v << 32) | lsw;
1256 char c = trace.peek();
1302 if (req->isLLSC() || req->isLocalAccess())
1329 saved_offset =
trace.tellg();
1330 trace >> buf >> buf >> buf;
1333 if (buf[0] ==
'I') {
1337 trace.seekg(saved_offset, ios::beg);
1346 panic(
"End of TARMAC trace reached before start PC\n");
1353 switch (isetstate) {
1357 return "Thumb (A32)";
1361 return "UNSUPPORTED";
1368 TarmacParserParams::create()
@ MISCREG_ID_AA64MMFR2_EL1
Addr startPc
Tracing starts when the PC gets this value for the first time (ignored if 0x0).
@ MISCREG_TLBI_IPAS2E1IS_Xt
static ParserRegEntry regRecord
Buffer for register trace records.
@ MISCREG_ID_AA64AFR1_EL1
Addr addr
The address that was accessed.
bool cpuId
If true, the trace format includes the CPU id.
@ MISCREG_ID_AA64ISAR1_EL1
union Trace::InstRecord::@115 data
VecReg::Container VecRegContainer
@ VecElemClass
Vector Register Native Elem lane.
bool mismatch
True if a mismatch has been detected for this instruction.
@ MISCREG_TLBI_VAALE1IS_Xt
bool memWrCheck
If true, memory write accesses are checked.
static ParserInstEntry instRecord
Buffer for instruction trace records.
@ MISCREG_ID_AA64ISAR0_EL1
@ MISCREG_DBGCLAIMCLR_EL1
@ MISCREG_TLBI_VAAE1IS_Xt
@ MISCREG_DBGAUTHSTATUS_EL1
@ NO_ACCESS
The request should not cause a memory access.
static IntRegIndex INTREG_SVC(unsigned index)
@ MISCREG_TLBI_VMALLS12E1
@ MISCREG_TLBI_VALE3IS_Xt
uint64_t Tick
Tick count type.
VecPredReg::Container VecPredRegContainer
bool contains(const Addr &a) const
Determine if the range contains an address.
@ MISCREG_TLBI_ASIDE1IS_Xt
std::shared_ptr< Request > RequestPtr
@ MISCREG_DBGCLAIMSET_EL1
static std::list< ParserRegEntry > destRegRecords
List of records of destination registers.
@ MISCREG_TLBI_IPAS2LE1IS_Xt
std::vector< uint64_t > values
bool mismatchOnPcOrOpcode
True if a mismatch has been detected for this instruction on PC or opcode.
bool readMemNoEffect(Addr addr, uint8_t *data, unsigned size, unsigned flags)
Performs a memory access to read the value written by a previous write.
@ MISCREG_TLBI_VALE2IS_Xt
@ MISCREG_ID_AA64MMFR0_EL1
@ MISCREG_ID_AA64AFR0_EL1
Register ID: describe an architectural register with its class and index.
@ MISCREG_ID_AA64DFR1_EL1
bool macroopInProgress
True if a macroop is currently in progress.
bool exitOnInsnDiff
If true, the simulation is stopped as the first mismatch is detected on PC or opcode.
static ParserMemEntry memRecord
Buffer for memory access trace records (stores only).
vector< EventQueue * > mainEventQueue
Array for main event queues.
static IntRegIndex INTREG_USR(unsigned index)
@ MISCREG_ID_AA64PFR0_EL1
ThreadContext is the external interface to all thread state for anything outside of the CPU.
static ISetState pcToISetState(ArmISA::PCState pc)
Returns the Instruction Set State according to the current PCState.
std::shared_ptr< FaultBase > Fault
@ MISCREG_ID_AA64MMFR1_EL1
const char * iSetStateToStr(ISetState isetstate) const
Returns the string representation of an instruction set state.
RequestPtr memReq
Request for memory write checks.
Tarmac Parser: this tracer parses an existing Tarmac trace and it diffs it with gem5 simulation statu...
@ MISCREG_ID_AA64DFR0_EL1
@ MISCREG_TLBI_VMALLS12E1IS
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 (...
static MiscRegMap miscRegMap
unsigned flags
The flags that were assigned to the request.
std::ifstream trace
TARMAC trace file.
ISetState
ARM instruction set state.
static int8_t maxVectorLength
Max.
std::ostream & output()
Get the ostream from the current global logger.
constexpr decltype(nullptr) NoFault
static IntRegIndex INTREG_MON(unsigned index)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
static IntRegIndex INTREG_HYP(unsigned index)
static IntRegIndex INTREG_UND(unsigned index)
virtual TheISA::PCState pcState() const =0
@ funcRequestorId
This requestor id is used for functional requests that don't come from a particular device.
virtual PortProxy & getVirtProxy()=0
static IntRegIndex INTREG_ABT(unsigned index)
bool isLastMicroop() const
@ VecRegClass
Vector Register.
Addr size
The size of the memory request.
@ MISCREG_TLBI_VALE1IS_Xt
const ExtMachInst machInst
The binary machine instruction.
Overload hash function for BasicBlockRange type.
GenericISA::DelaySlotPCState< MachInst > PCState
virtual const std::string & disassemble(Addr pc, const Loader::SymbolTable *symtab=nullptr) const
Return string representation of disassembled instruction.
constexpr unsigned NumVecElemPerNeonVecReg
static IntRegIndex INTREG_FIQ(unsigned index)
static const int MaxLineLength
void advanceTraceToStartPc()
Helper function to advance the trace up to startPc.
static TarmacRecordType currRecordType
Type of last parsed record.
static void printMismatchHeader(const StaticInstPtr inst, ArmISA::PCState pc)
Print a mismatch header containing the instruction fields as reported by gem5.
@ MISCREG_TLBI_IPAS2E1_Xt
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode, ArmTranslationType tranType)
AddrRange ignoredAddrRange
Ignored addresses (ignored if empty).
static IntRegIndex INTREG_IRQ(unsigned index)
bool parsingStarted
True if a TARMAC instruction record has already been parsed for this instruction.
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
@ MISCREG_TLBI_IPAS2LE1_Xt
Event triggered to check the value of the destination registers.
bool exitOnDiff
If true, the simulation is stopped as the first mismatch is detected.
@ MISCREG_ID_AA64PFR1_EL1
virtual BaseTLB * getDTBPtr()=0
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.
#define panic(...)
This implements a cprintf based panic() function.
Tick curTick()
The current simulated tick.
T * get() const
Directly access the pointer itself without taking a reference.
Generated on Wed Sep 30 2020 14:02:01 for gem5 by doxygen 1.8.17