Go to the documentation of this file.
48 #include "config/the_isa.hh"
62 const int TarmacParserRecord::MaxLineLength;
63 int8_t TarmacParserRecord::maxVectorLength = 0;
65 TarmacParserRecord::ParserInstEntry TarmacParserRecord::instRecord;
66 TarmacParserRecord::ParserRegEntry TarmacParserRecord::regRecord;
67 TarmacParserRecord::ParserMemEntry TarmacParserRecord::memRecord;
68 TarmacBaseRecord::TarmacRecordType TarmacParserRecord::currRecordType;
71 TarmacParserRecord::destRegRecords;
72 char TarmacParserRecord::buf[TarmacParserRecord::MaxLineLength];
73 TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
738 TarmacParserRecord::TarmacParserRecordEvent::process()
743 end = destRegRecords.end();
747 for (; it != end; ++it) {
752 values.push_back(thread->readIntReg(it->index));
755 if (instRecord.isetstate == ISET_A64) {
758 auto vv = vc.as<uint32_t>();
759 values.push_back(vv[0]);
761 const VecElem elem = thread->readVecElem(
765 values.push_back(elem);
769 if (instRecord.isetstate == ISET_A64) {
772 auto vv = vc.as<uint64_t>();
773 values.push_back(vv[0]);
775 const VecElem w0 = thread->readVecElem(
779 const VecElem w1 = thread->readVecElem(
784 values.push_back((uint64_t)(w1) << 32 | w0);
791 auto pv =
pc.as<uint8_t>();
793 for (
int i = maxVectorLength * 8;
i > 0; ) {
794 p = (
p << 1) | pv[--
i];
800 if (instRecord.isetstate == ISET_A64) {
803 auto vv = vc.as<uint64_t>();
804 values.push_back(vv[0]);
805 values.push_back(vv[1]);
807 const VecElem w0 = thread->readVecElem(
811 const VecElem w1 = thread->readVecElem(
815 const VecElem w2 = thread->readVecElem(
819 const VecElem w3 = thread->readVecElem(
824 values.push_back((uint64_t)(w1) << 32 | w0);
825 values.push_back((uint64_t)(w3) << 32 | w2);
830 int8_t
i = maxVectorLength;
833 auto vv = vc.as<uint64_t>();
835 values.push_back(vv[--
i]);
842 CPSR cpsr = thread->readMiscRegNoEffect(it->index);
843 cpsr.nz = thread->readCCReg(
CCREG_NZ);
844 cpsr.c = thread->readCCReg(
CCREG_C);
845 cpsr.v = thread->readCCReg(
CCREG_V);
846 cpsr.ge = thread->readCCReg(
CCREG_GE);
847 values.push_back(cpsr);
850 cpsr.nz = thread->readCCReg(
CCREG_NZ);
851 cpsr.c = thread->readCCReg(
CCREG_C);
852 cpsr.v = thread->readCCReg(
CCREG_V);
853 values.push_back(cpsr);
857 const uint32_t ones = (uint32_t)(-1);
866 fpcrMask.stride = ones;
867 fpcrMask.rMode = ones;
871 values.push_back(fpscr & fpcrMask);
875 const uint32_t ones = (uint32_t)(-1);
888 values.push_back(fpscr & fpsrMask);
890 values.push_back(thread->readMiscRegNoEffect(it->index));
894 panic(
"Unknown TARMAC trace record type!");
898 if (values.size() != it->values.size()) same =
false;
900 uint32_t size = values.size();
901 if (size > it->values.size())
902 size = it->values.size();
905 for (
int i = 0;
i < size; ++
i) {
906 if (values[
i] != it->values[
i]) {
915 TarmacParserRecord::printMismatchHeader(inst,
pc);
918 outs <<
"diff> [" << it->repr <<
"] gem5: 0x" << std::hex;
919 for (
auto v : values)
920 outs << std::setw(16) << std::setfill(
'0') <<
v;
922 outs <<
", TARMAC: 0x" << std::hex;
923 for (
auto v : it->values)
924 outs << std::setw(16) << std::setfill(
'0') <<
v;
928 destRegRecords.clear();
930 if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
931 parent.exitOnInsnDiff))
932 exitSimLoop(
"a mismatch with the TARMAC trace has been detected "
933 "on PC or opcode", 1);
934 if (mismatch && parent.exitOnDiff)
935 exitSimLoop(
"a mismatch with the TARMAC trace has been detected "
940 TarmacParserRecord::TarmacParserRecordEvent::description()
const
942 return "TARMAC parser record event";
951 outs <<
"\nMismatch between gem5 and TARMAC trace @ " << std::dec
953 <<
"[seq_num: " << std::dec << instRecord.seq_num
954 <<
", opcode: 0x" << std::hex << (staticInst->
getEMI() & 0xffffffff)
955 <<
", PC: 0x" <<
pc.pc()
966 _pc, _macroStaticInst),
967 parsingStarted(false), mismatch(false),
968 mismatchOnPcOrOpcode(false), parent(_parent)
970 memReq = std::make_shared<Request>();
981 uint64_t written_data = 0;
1008 outs <<
"diff> [PC] gem5: 0x" << std::hex <<
pc.instAddr()
1009 <<
", TARMAC: 0x" <<
instRecord.addr << std::endl;
1014 if (arm_inst->encoding() !=
instRecord.opcode) {
1017 outs <<
"diff> [opcode] gem5: 0x" << std::hex
1018 << arm_inst->encoding()
1019 <<
", TARMAC: 0x" <<
instRecord.opcode << std::endl;
1031 outs <<
"diff> [iset_state] gem5: "
1052 outs <<
"diff> [mem(0x" << std::hex <<
memRecord.addr
1053 <<
")] gem5: 0x" << written_data
1063 panic(
"Unknown TARMAC trace record type!");
1075 exitSimLoop(
"a mismatch with the TARMAC trace has been detected "
1076 "on PC or opcode", 1);
1089 if (
buf[0] !=
'I') {
1095 assert((
buf[0] ==
'c') && (
buf[1] ==
'p') && (
buf[2] ==
'u'));
1103 if (
buf[0] ==
'I') {
1112 char c = trace.peek();
1130 warn(
"Invalid TARMAC trace record (seq_num: %lld)",
1138 }
else if (
buf[0] ==
'R') {
1144 if (std::tolower(
buf[0]) ==
'r' && isdigit(
buf[1])) {
1147 int base_index = atoi(&
buf[1]);
1148 char* pch = strchr(
buf,
'_');
1153 if (strncmp(pch,
"usr", 3) == 0)
1155 else if (strncmp(pch,
"fiq", 3) == 0)
1157 else if (strncmp(pch,
"irq", 3) == 0)
1159 else if (strncmp(pch,
"svc", 3) == 0)
1161 else if (strncmp(pch,
"mon", 3) == 0)
1163 else if (strncmp(pch,
"abt", 3) == 0)
1165 else if (strncmp(pch,
"und", 3) == 0)
1167 else if (strncmp(pch,
"hyp", 3) == 0)
1170 }
else if (std::tolower(
buf[0]) ==
'x' && isdigit(
buf[1])) {
1174 }
else if (std::tolower(
buf[0]) ==
's' && isdigit(
buf[1])) {
1178 }
else if (std::tolower(
buf[0]) ==
'd' && isdigit(
buf[1])) {
1182 }
else if (std::tolower(
buf[0]) ==
'q' && isdigit(
buf[1])) {
1186 }
else if (std::tolower(
buf[0]) ==
'z' && isdigit(
buf[1])) {
1190 }
else if (std::tolower(
buf[0]) ==
'p' && isdigit(
buf[1])) {
1194 }
else if (strncmp(
buf,
"SP_EL", 5) == 0) {
1204 std::string reg_name =
buf;
1205 std::transform(reg_name.begin(), reg_name.end(), reg_name.begin(),
1211 warn(
"Unknown register in TARMAC trace (%s).\n",
buf);
1221 uint64_t hi = strtoull(
buf, NULL, 16);
1223 uint64_t
lo = strtoull(
buf, NULL, 16);
1237 v = (
v << 32) | lsw;
1245 char c = trace.peek();
1246 if ((
c ==
':') || (
c ==
'_')) {
1250 v = (
v << 32) | lsw;
1260 char c = trace.peek();
1306 if (req->isLLSC() || req->isLocalAccess())
1333 saved_offset =
trace.tellg();
1334 trace >> buf >> buf >> buf;
1337 if (buf[0] ==
'I') {
1341 trace.seekg(saved_offset, std::ios::beg);
1350 panic(
"End of TARMAC trace reached before start PC\n");
1357 switch (isetstate) {
1361 return "Thumb (A32)";
1365 return "UNSUPPORTED";
@ MISCREG_ID_AA64MMFR2_EL1
union Trace::InstRecord::@112 data
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
virtual uint64_t getEMI() const
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
virtual BaseMMU * getMMUPtr()=0
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
virtual const std::string & disassemble(Addr pc, const Loader::SymbolTable *symtab=nullptr) const
Return string representation of disassembled instruction.
@ 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).
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 std::list< ParserRegEntry > destRegRecords
List of records of destination registers.
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 (...
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, BaseTLB::Mode mode)
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)
@ funcRequestorId
This requestor id is used for functional requests that don't come from a particular device.
virtual TheISA::PCState pcState() const =0
virtual PortProxy & getVirtProxy()=0
static IntRegIndex INTREG_ABT(unsigned index)
@ NO_ACCESS
The request should not cause a memory access.
bool isLastMicroop() const
@ VecRegClass
Vector Register.
Addr size
The size of the memory request.
@ MISCREG_TLBI_VALE1IS_Xt
GenericISA::DelaySlotPCState< MachInst > PCState
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.
std::vector< EventQueue * > mainEventQueue
Array for main event queues.
@ MISCREG_TLBI_IPAS2E1_Xt
Tick curTick()
The universal simulation clock.
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
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.
T * get() const
Directly access the pointer itself without taking a reference.
Generated on Tue Mar 23 2021 19:41:20 for gem5 by doxygen 1.8.17