50 #include "config/the_isa.hh" 65 const int TarmacParserRecord::MaxLineLength;
66 int8_t TarmacParserRecord::maxVectorLength = 0;
68 TarmacParserRecord::ParserInstEntry TarmacParserRecord::instRecord;
69 TarmacParserRecord::ParserRegEntry TarmacParserRecord::regRecord;
70 TarmacParserRecord::ParserMemEntry TarmacParserRecord::memRecord;
71 TarmacBaseRecord::TarmacRecordType TarmacParserRecord::currRecordType;
74 char TarmacParserRecord::buf[TarmacParserRecord::MaxLineLength];
75 TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
634 TarmacParserRecord::TarmacParserRecordEvent::process()
639 end = destRegRecords.end();
643 for (; it != end; ++it) {
648 values.push_back(thread->readIntReg(it->index));
651 if (instRecord.isetstate == ISET_A64) {
654 auto vv = vc.as<uint32_t>();
655 values.push_back(vv[0]);
657 const VecElem elem = thread->readVecElem(
661 values.push_back(elem);
665 if (instRecord.isetstate == ISET_A64) {
668 auto vv = vc.as<uint64_t>();
669 values.push_back(vv[0]);
671 const VecElem w0 = thread->readVecElem(
675 const VecElem w1 = thread->readVecElem(
680 values.push_back((uint64_t)(w1) << 32 | w0);
687 auto pv = pc.as<uint8_t>();
689 for (
int i = maxVectorLength * 8;
i > 0; ) {
690 p = (p << 1) | pv[--
i];
696 if (instRecord.isetstate == ISET_A64) {
699 auto vv = vc.as<uint64_t>();
700 values.push_back(vv[0]);
701 values.push_back(vv[1]);
703 const VecElem w0 = thread->readVecElem(
707 const VecElem w1 = thread->readVecElem(
711 const VecElem w2 = thread->readVecElem(
715 const VecElem w3 = thread->readVecElem(
720 values.push_back((uint64_t)(w1) << 32 | w0);
721 values.push_back((uint64_t)(w3) << 32 | w2);
726 int8_t
i = maxVectorLength;
729 auto vv = vc.as<uint64_t>();
731 values.push_back(vv[--i]);
738 CPSR cpsr = thread->readMiscRegNoEffect(it->index);
739 cpsr.nz = thread->readCCReg(
CCREG_NZ);
740 cpsr.c = thread->readCCReg(
CCREG_C);
741 cpsr.v = thread->readCCReg(
CCREG_V);
742 cpsr.ge = thread->readCCReg(
CCREG_GE);
743 values.push_back(cpsr);
746 cpsr.nz = thread->readCCReg(
CCREG_NZ);
747 cpsr.c = thread->readCCReg(
CCREG_C);
748 cpsr.v = thread->readCCReg(
CCREG_V);
749 values.push_back(cpsr);
753 const uint32_t ones = (uint32_t)(-1);
762 fpcrMask.stride = ones;
763 fpcrMask.rMode = ones;
767 values.push_back(fpscr & fpcrMask);
771 const uint32_t ones = (uint32_t)(-1);
784 values.push_back(fpscr & fpsrMask);
786 values.push_back(thread->readMiscRegNoEffect(it->index));
790 panic(
"Unknown TARMAC trace record type!");
794 if (values.size() != it->values.size()) same =
false;
796 uint32_t size = values.size();
797 if (size > it->values.size())
798 size = it->values.size();
801 for (
int i = 0;
i < size; ++
i) {
802 if (values[
i] != it->values[
i]) {
811 TarmacParserRecord::printMismatchHeader(inst,
pc);
814 outs <<
"diff> [" << it->repr <<
"] gem5: 0x" << hex;
815 for (
auto v : values)
816 outs << setw(16) << setfill(
'0') <<
v;
818 outs <<
", TARMAC: 0x" << hex;
819 for (
auto v : it->values)
820 outs << setw(16) << setfill(
'0') <<
v;
824 destRegRecords.clear();
826 if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
827 parent.exitOnInsnDiff))
828 exitSimLoop(
"a mismatch with the TARMAC trace has been detected " 829 "on PC or opcode", 1);
830 if (mismatch && parent.exitOnDiff)
831 exitSimLoop(
"a mismatch with the TARMAC trace has been detected " 836 TarmacParserRecord::TarmacParserRecordEvent::description()
const 838 return "TARMAC parser record event";
847 outs <<
"\nMismatch between gem5 and TARMAC trace @ " << dec <<
curTick()
849 <<
"[seq_num: " << dec << instRecord.seq_num
850 <<
", opcode: 0x" << hex << (staticInst->
machInst & 0xffffffff)
851 <<
", PC: 0x" << pc.pc()
852 <<
", disasm: " << staticInst->
disassemble(pc.pc()) <<
"]" 862 _pc, _macroStaticInst),
863 parsingStarted(false), mismatch(false),
864 mismatchOnPcOrOpcode(false), parent(_parent)
866 memReq = std::make_shared<Request>();
877 uint64_t written_data = 0;
905 outs <<
"diff> [PC] gem5: 0x" << hex <<
pc.instAddr()
911 if (arm_inst->encoding() !=
instRecord.opcode) {
914 outs <<
"diff> [opcode] gem5: 0x" << hex
915 << arm_inst->encoding()
916 <<
", TARMAC: 0x" <<
instRecord.opcode << endl;
928 outs <<
"diff> [iset_state] gem5: " 949 outs <<
"diff> [mem(0x" << hex <<
memRecord.addr
950 <<
")] gem5: 0x" << written_data
960 panic(
"Unknown TARMAC trace record type!");
972 exitSimLoop(
"a mismatch with the TARMAC trace has been detected " 973 "on PC or opcode", 1);
992 assert((buf[0] ==
'c') && (buf[1] ==
'p') && (buf[2] ==
'u'));
1000 if (
buf[0] ==
'I') {
1009 char c = trace.peek();
1027 warn(
"Invalid TARMAC trace record (seq_num: %lld)",
1035 }
else if (
buf[0] ==
'R') {
1041 if (std::tolower(buf[0]) ==
'r' && isdigit(buf[1])) {
1044 int base_index = atoi(&buf[1]);
1045 char* pch = strchr(buf,
'_');
1050 if (strncmp(pch,
"usr", 3) == 0)
1052 else if (strncmp(pch,
"fiq", 3) == 0)
1054 else if (strncmp(pch,
"irq", 3) == 0)
1056 else if (strncmp(pch,
"svc", 3) == 0)
1058 else if (strncmp(pch,
"mon", 3) == 0)
1060 else if (strncmp(pch,
"abt", 3) == 0)
1062 else if (strncmp(pch,
"und", 3) == 0)
1064 else if (strncmp(pch,
"hyp", 3) == 0)
1067 }
else if (std::tolower(buf[0]) ==
'x' && isdigit(buf[1])) {
1071 }
else if (std::tolower(buf[0]) ==
's' && isdigit(buf[1])) {
1075 }
else if (std::tolower(buf[0]) ==
'd' && isdigit(buf[1])) {
1079 }
else if (std::tolower(buf[0]) ==
'q' && isdigit(buf[1])) {
1083 }
else if (std::tolower(buf[0]) ==
'z' && isdigit(buf[1])) {
1087 }
else if (std::tolower(buf[0]) ==
'p' && isdigit(buf[1])) {
1091 }
else if (strncmp(buf,
"SP_EL", 5) == 0) {
1101 string reg_name =
buf;
1102 transform(reg_name.begin(), reg_name.end(), reg_name.begin(),
1108 warn(
"Unknown register in TARMAC trace (%s).\n", buf);
1118 uint64_t hi = strtoull(buf, NULL, 16);
1120 uint64_t
lo = strtoull(buf, NULL, 16);
1134 v = (v << 32) | lsw;
1135 if (
i < maxVectorLength - 1) trace >>
c;
1142 char c = trace.peek();
1143 if ((c ==
':') || (c ==
'_')) {
1147 v = (v << 32) | lsw;
1157 char c = trace.peek();
1169 data = (data << 32) | lsw;
1190 req->setVirt(0, addr, size, flags,
thread->
pcState().instAddr(),
1203 if (req->isLLSC() || req->isMmappedIpr())
1230 saved_offset = trace.tellg();
1231 trace >> buf >> buf >>
buf;
1234 if (buf[0] ==
'I') {
1236 if (pc == startPc) {
1238 trace.seekg(saved_offset, ios::beg);
1241 trace.ignore(TarmacParserRecord::MaxLineLength,
'\n');
1244 trace.ignore(TarmacParserRecord::MaxLineLength,
'\n');
1247 panic(
"End of TARMAC trace reached before start PC\n");
1254 switch (isetstate) {
1258 return "Thumb (A32)";
1262 return "UNSUPPORTED";
1269 TarmacParserParams::create()
#define panic(...)
This implements a cprintf based panic() function.
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.
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.
virtual const std::string & disassemble(Addr pc, const SymbolTable *symtab=0) const
Return string representation of disassembled instruction.
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.
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.
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.
::DummyVecRegContainer VecRegContainer
VecPredReg::Container VecPredRegContainer
static ParserMemEntry memRecord
Buffer for memory access trace records (stores only).
static IntRegIndex INTREG_MON(unsigned index)
union Trace::InstRecord::@120 data
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)
This master id is used for functional requests that don't come from a particular device.
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.
The request should not cause a memory access.
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 IntRegIndex INTREG_ABT(unsigned index)
Declaration of the Packet class.
VecReg::Container VecRegContainer
GenericISA::SimplePCState< MachInst > PCState
static IntRegIndex INTREG_HYP(unsigned index)
AddrRange ignoredAddrRange
Ignored addresses (ignored if empty).
TranslatingPortProxy Object Declaration for FS.
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
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