//---------------------------------------------------------------------------- // // Disassembly portions of IA64 machine implementation. // // Copyright (C) Microsoft Corporation, 2000-2001. // //---------------------------------------------------------------------------- #include "ntsdp.hpp" #include "ia64_dis.h" // See Get/SetRegVal comments in machine.hpp. #define RegValError Do_not_use_GetSetRegVal_in_machine_implementations #define GetRegVal(index, val) RegValError #define GetRegVal32(index) RegValError #define GetRegVal64(index) RegValError #define SetRegVal(index, val) RegValError #define SetRegVal32(index, val) RegValError #define SetRegVal64(index, val) RegValError // Breakpoint insertion and removal are done on bundle boundaries. #define IA64_BP_ALIGN 0xf #define IA64_BP_LEN 16 // defined in IA64INST.H ULONGLONG g_Ia64TrapInstr = BREAK_INSTR | (IA64_DEBUG_STOP_BREAKPOINT << 6); #ifdef DW3 // defined in vdmdbg.h which is in conflict with iel.h #undef DW3 #endif #define DECEM 1 /* GetNextOffset() based on Intel Falcon decoder DLL */ #include "decem.h" /*****************************************************************************/ // Temporary variables for IEL library unsigned int IEL_t1, IEL_t2, IEL_t3, IEL_t4; U32 IEL_tempc; U64 IEL_et1, IEL_et2; U128 IEL_ext1, IEL_ext2, IEL_ext3, IEL_ext4, IEL_ext5; S128 IEL_ts1, IEL_ts2; #define IEL_GETQW0(x) ((ULONG64)IEL_GETDW1(x)) << 32 | IEL_GETDW0(x) /*****************************************************************************/ #ifdef DECEM EM_Decoder_Machine_Type machineType = EM_DECODER_CPU_P7; EM_Decoder_Machine_Mode machineMode = EM_DECODER_MODE_EM; BOOL fDecoderInitDone = FALSE; BOOL fDecoderActive = FALSE; EM_Decoder_Id DecoderId = -1; EM_Decoder_Id (__cdecl *pfnEM_Decoder_open)(void); EM_Decoder_Err (__cdecl *pfnEM_Decoder_associate_one)(const EM_Decoder_Id, const EM_Decoder_Inst_Id, const void *); EM_Decoder_Err (__cdecl *pfnEM_Decoder_associate_check)(const EM_Decoder_Id, EM_Decoder_Inst_Id *); EM_Decoder_Err (__cdecl *pfnEM_Decoder_setenv)(const EM_Decoder_Id, const EM_Decoder_Machine_Type, const EM_Decoder_Machine_Mode); EM_Decoder_Err (__cdecl *pfnEM_Decoder_close)(const EM_Decoder_Id); EM_Decoder_Err (__cdecl *pfnEM_Decoder_decode)(const EM_Decoder_Id, const unsigned char *, const int, const EM_IL, EM_Decoder_Info *); EM_Decoder_Err (__cdecl *pfnEM_Decoder_inst_static_info)(const EM_Decoder_Id, const EM_Decoder_Inst_Id, EM_Decoder_Inst_Static_Info *); const char* (__cdecl *pfnEM_Decoder_ver_str)(void); void (__cdecl *pfnEM_Decoder_get_version)(EM_library_version_t *); const char* (__cdecl *pfnEM_Decoder_err_msg)(EM_Decoder_Err); EM_Decoder_Err (__cdecl *pfnEM_Decoder_decode_bundle)(const EM_Decoder_Id, const unsigned char*, const int, EM_Decoder_Bundle_Info*); BOOL InitDecoder (void) { EM_library_version_t dec_vs; EM_library_version_t *dec_version; EM_Decoder_Err err; HINSTANCE hmodDecoder; // load EM deocder library if it is not done yet if (!fDecoderInitDone) { fDecoderInitDone = TRUE; const char* c_szFailure = NULL; if ( (hmodDecoder = LoadLibrary("DECEM.DLL")) && (pfnEM_Decoder_open = (EM_Decoder_Id (__cdecl*)(void)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_open") ) && (pfnEM_Decoder_associate_one = (EM_Decoder_Err (__cdecl*)(const EM_Decoder_Id, const EM_Decoder_Inst_Id, const void*)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_associate_one") ) && (pfnEM_Decoder_associate_check = (EM_Decoder_Err (__cdecl*)(const EM_Decoder_Id, EM_Decoder_Inst_Id*)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_associate_check") ) && (pfnEM_Decoder_setenv = (EM_Decoder_Err (__cdecl*)(const EM_Decoder_Id, const EM_Decoder_Machine_Type, const EM_Decoder_Machine_Mode)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_setenv") ) && (pfnEM_Decoder_close = (EM_Decoder_Err (__cdecl*)(const EM_Decoder_Id)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_close") ) && (pfnEM_Decoder_decode = (EM_Decoder_Err (__cdecl*)(const EM_Decoder_Id, const unsigned char*, const int, const EM_IL, EM_Decoder_Info*)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_decode") ) && (pfnEM_Decoder_inst_static_info = (EM_Decoder_Err (__cdecl*)(const EM_Decoder_Id, const EM_Decoder_Inst_Id, EM_Decoder_Inst_Static_Info*)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_inst_static_info") ) && (pfnEM_Decoder_ver_str = (const char* (__cdecl*)(void)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_ver_str") ) && (pfnEM_Decoder_get_version = (void (__cdecl*)(EM_library_version_t*)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_get_version") ) && (pfnEM_Decoder_err_msg = (const char* (__cdecl*)(EM_Decoder_Err)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_err_msg") ) && (pfnEM_Decoder_decode_bundle = (EM_Decoder_Err (__cdecl*)(const EM_Decoder_Id, const unsigned char*, const int, EM_Decoder_Bundle_Info*)) GetProcAddress(hmodDecoder, c_szFailure = "em_decoder_decode_bundle") ) ){ // Display DECEM.DLL version on initial load dec_version = &dec_vs; (*pfnEM_Decoder_get_version)(dec_version); dprintf("Falcon EM Decoder xversion " "%d.%d, api %d.%d, emdb %d.%d\n", dec_version->xversion.major, dec_version->xversion.minor, dec_version->api.major, dec_version->api.minor, dec_version->emdb.major, dec_version->emdb.minor); if ((DecoderId = (*pfnEM_Decoder_open)()) == -1) { ErrOut("em_decoder_open failed\n"); } else { if ( (err = (*pfnEM_Decoder_setenv)(DecoderId, machineType, machineMode) ) != EM_DECODER_NO_ERROR) { ErrOut("em_decoder_setenv: %s\n", (*pfnEM_Decoder_err_msg)((EM_Decoder_Err)err)); } else { fDecoderActive = TRUE; } // if } // if } else { // error processing.... if (!hmodDecoder) { ErrOut("LoadLibrary(DECEM.DLL) failed.\n"); } else if (c_szFailure && *c_szFailure) { ErrOut("GetProcAddress failed for %s at DECEM.DLL\n", c_szFailure); } else { ErrOut("Unknown failure while initializing DECEM.DLL\n"); } // iff } // if } // if (!fDecoderInitDone) return fDecoderActive; } // InitDecoder #endif /* DECEM */ BOOL fDisasmInitDone = FALSE; BOOL fDisasmActive = FALSE; // // CIa64Disasm - disassemble an IA64 instruction // typedef class CIa64Disasm { public: typedef union SBundle { UCHAR BundleBuffer[EM_BUNDLE_SIZE]; } typedef_SBundle; static bool GetBundleAndSlot(ULONG64 uLocation, ULONG64* pBundleLoc, UINT* pSlotNum) { if (pSlotNum) { switch (uLocation & 0xf) { case 0: *pSlotNum = 0; break; case 4: *pSlotNum = 1; break; case 8: *pSlotNum = 2; break; default: return false; } // switch (uLocation & 0xf) } if (pBundleLoc) { *pBundleLoc = uLocation & ~0xf; } return true; } // GetBundleAndSlot CIa64Disasm(Ia64MachineInfo* pMachineInit); bool DecodeInstruction(ULONG64 uBundleLoc, const SBundle& r_Bundle, UINT uSlotNum, EM_Decoder_Info* pInstrInfo); bool Disassemble(ULONG64 uLocation, const SBundle& r_Bundle, UINT* pInstrLen, char* szDisBuf, size_t nDisBufSize, bool bContext); private: Ia64MachineInfo* pMachine; typedef class CSzBuffer { public: CSzBuffer(char* szDisBuf, size_t nDisBufSize); void Add(const char* szSrc, size_t nStart = 0); void Validate(); bool IsValid() const {return bValid;} size_t length() const {return nSize;} const char* c_str() const {return szBuf;} protected: char* szBuf; size_t nMaxSize; size_t nSize; bool bValid; } typedef_CSzBuffer; typedef struct SRegFileInfo { EM_Decoder_Regfile_Name DecoderName; char* szName; char* szAlias; char* szMasm; } typedef_SRegFileInfo; typedef struct SRegInfo { EM_Decoder_Reg_Name DecoderName; char* szName; char* szAlias; char* szMasm; } typedef_SRegInfo; void AddRegister(CSzBuffer* pBuf, const EM_Decoder_Reg_Info& c_RegInfo); void AddRegister(CSzBuffer* pBuf, const EM_Decoder_Regfile_Info& c_RegInfo); void AddRegister(CSzBuffer* pBuf, EM_Decoder_Reg_Name RegName); void AddPredicate(CSzBuffer* pBuf, const EM_Decoder_Info& c_InstrInfo, bool bContext); void AddMnemonic(CSzBuffer* pBuf, const EM_Decoder_Info& c_InstrInfo); void AddOperandList(CSzBuffer* pBuf, ULONG64 uBundleLoc, UINT uSlotNum, const EM_Decoder_Info& c_InstrInfo); void AddComment(CSzBuffer* pBuf, ULONG64 uBundleLoc, UINT uSlotNum, const EM_Decoder_Info& c_InstrInfo, bool bContext); bool AddOperand(CSzBuffer* pBuf, ULONG64 uBundleLoc, UINT uSlotNum, const EM_Decoder_Operand_Info& c_OperandInfo, bool bSeparator); void AddSeparator(CSzBuffer* pBuf); static void AddString(CSzBuffer* pBuf, const char* szSrc, size_t nStart = 0) { pBuf->Add(szSrc, nStart); } // AddString void AddSymAddr(CSzBuffer* pBuf, ULONG64 uAddress); static SRegFileInfo c_aRegFileInfo[]; static SRegInfo c_aRegInfo[]; } typedef_CIa64Disasm; // // CIa64Disasm::CSzBuffer implementation // CIa64Disasm::CSzBuffer::CSzBuffer(char* szDisBuf, size_t nDisBufSize) :szBuf(szDisBuf), nMaxSize(nDisBufSize) { if (nMaxSize) { --nMaxSize; } Validate(); } // CIa64Disasm::CSzBuffer::CSzBuffer void CIa64Disasm::CSzBuffer::Validate() { nSize = 0; bValid = false; if (szBuf && nMaxSize) { nSize = strlen(szBuf); bValid = true; } } // CIa64Disasm::CSzBuffer::Validate void CIa64Disasm::CSzBuffer::Add(const char* szSrc, size_t nStart /*= 0*/) { if (!bValid || (nSize >= nMaxSize)) { return; } if (nSize < nStart) { size_t nSpaceSize = nStart - nSize; memset(szBuf + nSize, ' ', nSpaceSize); szBuf[nStart] = char(0); nSize = nStart; } if (!(szSrc && *szSrc)) { return; } strncat(szBuf, szSrc, nMaxSize - nSize); szBuf[nMaxSize] = char(0); nSize += strlen(szBuf + nSize); } // CIa64Disasm::CSzBuffer::Add // // CIa64Disasm implementation // CIa64Disasm::CIa64Disasm(Ia64MachineInfo* pMachineInit) :pMachine(pMachineInit) { InitDecoder(); } // CIa64Disasm::CIa64Disasm bool CIa64Disasm::DecodeInstruction(ULONG64 uBundleLoc, const SBundle& r_Bundle, UINT uSlot, EM_Decoder_Info* pInstrInfo) { if ((uBundleLoc & 0xf) || (uSlot > 2) || !pInstrInfo) { return false; } uBundleLoc += uSlot; U64 Location; //IEL_ZERO(DecLocation); IEL_ASSIGNU(Location, *(U64*)&uBundleLoc); EM_Decoder_Err Error = pfnEM_Decoder_decode(DecoderId, (unsigned char*)&r_Bundle, sizeof(r_Bundle), Location, pInstrInfo); return ((Error == EM_DECODER_NO_ERROR) && (pInstrInfo->inst != EM_IGNOP)); } // CIa64Disasm::DecodeInstruction bool CIa64Disasm::Disassemble(ULONG64 uLocation, const CIa64Disasm::SBundle& r_Bundle, UINT* pInstrLen, char* szDisBuf, size_t nDisBufSize, bool bContext) { if (!InitDecoder()) { ErrOut("EM decoder library(DECEM.DLL) not active\n"); return false; } ULONG64 uBundleLoc; UINT uSlotNum; if (!GetBundleAndSlot(uLocation, &uBundleLoc, &uSlotNum)) { return false; } CSzBuffer Buf(szDisBuf, nDisBufSize); EM_Decoder_Info InstrInfo; if (!DecodeInstruction(uBundleLoc, r_Bundle, uSlotNum, &InstrInfo)) { EM_Decoder_static_info_t StaticInfo; ZeroMemory(&StaticInfo, sizeof(StaticInfo)); StaticInfo.mnemonic = "???"; InstrInfo.static_info = &StaticInfo; AddMnemonic(&Buf, InstrInfo); return true; } // if AddPredicate(&Buf, InstrInfo, bContext); AddMnemonic(&Buf, InstrInfo); AddString(&Buf, " "); AddOperandList(&Buf, uBundleLoc, uSlotNum, InstrInfo); if (EM_DECODER_CYCLE_BREAK((&InstrInfo))) { AddString(&Buf, " ;;"); } AddComment(&Buf, uBundleLoc, uSlotNum, InstrInfo, bContext); if (pInstrLen) { *pInstrLen = InstrInfo.size; } return true; } // CIa64Disasm::Disassemble void CIa64Disasm::AddRegister(CSzBuffer* pBuf, const EM_Decoder_Reg_Info& c_RegInfo) { AddString(pBuf, c_aRegInfo[c_RegInfo.name].szAlias); } void CIa64Disasm::AddRegister(CSzBuffer* pBuf, const EM_Decoder_Regfile_Info& c_RegFileInfo) { AddString(pBuf, c_aRegFileInfo[c_RegFileInfo.index.name].szName); } void CIa64Disasm::AddRegister(CSzBuffer* pBuf, EM_Decoder_Reg_Name RegName) { AddString(pBuf, c_aRegInfo[RegName].szAlias); } // CIa64Disasm::AddRegister(CSzBuffer&, EM_Decoder_Reg_Name) void CIa64Disasm::AddPredicate(CSzBuffer* pBuf, const EM_Decoder_Info& c_InstrInfo, bool bContext) { if (!(c_InstrInfo.pred.valid && c_InstrInfo.pred.value)) { return; } AddString(pBuf, "("); AddRegister(pBuf, c_InstrInfo.pred); const char* szClose; if (bContext) { if ((pMachine->GetReg64(PREDS) >> c_InstrInfo.pred.value) & 0x1) { szClose = "=1)"; } else { szClose = "=0)"; } // iff } else { szClose = ")"; } // iff AddString(pBuf, szClose); } // CIa64Disasm::AddPredicate void CIa64Disasm::AddMnemonic(CSzBuffer* pBuf, const EM_Decoder_Info& c_InstrInfo) { AddString(pBuf, c_InstrInfo.static_info->mnemonic, 7); AddString(pBuf, NULL, 13); } // CIa64Disasm::AddMnemonic void CIa64Disasm::AddOperandList(CSzBuffer* pBuf, ULONG64 uBundleLoc, UINT uSlotNum, const EM_Decoder_Info& c_InstrInfo) { bool bAdd = false; bAdd |= AddOperand(pBuf, uBundleLoc, uSlotNum, c_InstrInfo.dst1, false); bAdd |= AddOperand(pBuf, uBundleLoc, uSlotNum, c_InstrInfo.dst2, bAdd); if ((c_InstrInfo.dst1.type != EM_DECODER_NO_OPER) && (c_InstrInfo.src1.type != EM_DECODER_NO_OPER)) { AddString(pBuf, "="); bAdd = false; } bAdd = AddOperand(pBuf, uBundleLoc, uSlotNum, c_InstrInfo.src1, bAdd); bAdd = AddOperand(pBuf, uBundleLoc, uSlotNum, c_InstrInfo.src2, bAdd); bAdd = AddOperand(pBuf, uBundleLoc, uSlotNum, c_InstrInfo.src3, bAdd); bAdd = AddOperand(pBuf, uBundleLoc, uSlotNum, c_InstrInfo.src4, bAdd); bAdd = AddOperand(pBuf, uBundleLoc, uSlotNum, c_InstrInfo.src5, bAdd); } // CIa64Disasm::AddOperandList void CIa64Disasm::AddComment(CSzBuffer* pBuf, ULONG64 uBundleLoc, UINT uSlotNum, const EM_Decoder_Info& c_InstrInfo, bool bContext) { if (bContext) { char szComment[128]; *szComment = 0; CSzBuffer Comment(szComment, sizeof(szComment) / sizeof(*szComment)); if ( !strncmp(c_InstrInfo.static_info->mnemonic, "br.", 3) && (c_InstrInfo.src1.reg_info.type == EM_DECODER_BR_REG)) { ULONG64 uTargetAddr = pMachine->GetReg64(c_InstrInfo.src1.reg_info.value + BRRP); Comment.Add(" // "); AddSymAddr(&Comment, uTargetAddr); if ((uTargetAddr == IA64_MM_EPC_VA + 0x20) && !IS_KERNEL_TARGET()) { Comment.Add(" system call"); } } if (Comment.length()) { long iCommentStart = long(g_OutputWidth) - Comment.length() - 18; AddString(pBuf, Comment.c_str(), (iCommentStart > 0) ? size_t(iCommentStart) : 0); } } } // CIa64Disasm::AddComment bool CIa64Disasm::AddOperand(CSzBuffer* pBuf, ULONG64 uBundleLoc, UINT uSlotNum, const EM_Decoder_Operand_Info& c_OperandInfo, bool bSeparator) { switch (c_OperandInfo.type) { case EM_DECODER_REGISTER: { if (bSeparator) { AddSeparator(pBuf); } AddRegister(pBuf, c_OperandInfo.reg_info); } // case EM_DECODER_REGISTER break; case EM_DECODER_REGFILE: { if (bSeparator) { AddSeparator(pBuf); } AddString(pBuf, c_aRegFileInfo[c_OperandInfo.regfile_info.name].szName); AddString(pBuf, "["); AddRegister(pBuf, c_OperandInfo.regfile_info.index.name); AddString(pBuf, "]"); } // case EM_DECODER_REGFILE break; case EM_DECODER_IMMEDIATE: { if (bSeparator) { AddSeparator(pBuf); } if (EM_DECODER_OPER_IMM_REG((&c_OperandInfo))) { EM_Decoder_Reg_Name RegName; if (EM_DECODER_OPER_IMM_FREG((&c_OperandInfo))) { RegName = EM_DECODER_REG_F0; } else { DBG_ASSERT(EM_DECODER_OPER_IMM_IREG((&c_OperandInfo))); RegName = EM_DECODER_REG_R0; } RegName = EM_Decoder_Reg_Name( UINT(RegName) + IEL_GETDW0(c_OperandInfo.imm_info.val64)); AddRegister(pBuf, RegName); } else { U64 ImmVal = c_OperandInfo.imm_info.val64; ULONG64 uImmVal = IEL_GETQW0(ImmVal); if (c_OperandInfo.imm_info.size == 64) { AddSymAddr(pBuf, uImmVal); } else { AddString(pBuf, FormatDisp64(uImmVal)); } } } break; case EM_DECODER_MEMORY: { if (bSeparator) { AddSeparator(pBuf); } AddString(pBuf, "["); AddRegister(pBuf, c_OperandInfo.mem_info.mem_base.name); AddString(pBuf, "]"); } // case EM_DECODER_MEMORY break; case EM_DECODER_IP_RELATIVE: { if (bSeparator) { AddSeparator(pBuf); } ULONG64 uOffset = IEL_GETQW0(c_OperandInfo.imm_info.val64); if (uOffset) { uOffset += uBundleLoc; AddSymAddr(pBuf, uOffset); } else { AddString(pBuf, "+0"); } // iff } // case EM_DECODER_IP_RELATIVE break; default: { return false; } // default } // switch (c_OperandInfo.type) return true; } // CIa64Disasm::AddOperand void CIa64Disasm::AddSeparator(CSzBuffer* pBuf) { AddString(pBuf, ", "); } // CIa64Disasm::AddSeparator void CIa64Disasm::AddSymAddr(CSzBuffer* pBuf, ULONG64 uAddress) { char szSymbol[MAX_SYMBOL_LEN]; ULONG64 uDisplacement = 0; GetSymbolStdCall(uAddress, szSymbol, sizeof(szSymbol), &uDisplacement, NULL); szSymbol[MAX_SYMBOL_LEN - 1] = char(0); if (*szSymbol) { AddString(pBuf, szSymbol); AddString(pBuf, "+"); AddString(pBuf, FormatDisp64(uDisplacement)); AddString(pBuf, " ("); AddString(pBuf, FormatAddr64(uAddress)); AddString(pBuf, ")"); } else { AddString(pBuf, FormatAddr64(uAddress)); } // iff } // CIa64Disasm::AddSymAddr CIa64Disasm::SRegFileInfo CIa64Disasm::c_aRegFileInfo[] = { {EM_DECODER_NO_REGFILE, "no", "no", "no" }, {EM_DECODER_REGFILE_PMC, "pmc", "pmc", "pmc" }, {EM_DECODER_REGFILE_PMD, "pmd", "pmd", "pmd" }, {EM_DECODER_REGFILE_PKR, "pkr", "pkr", "pkr" }, {EM_DECODER_REGFILE_RR, "rr", "rr", "rr" }, {EM_DECODER_REGFILE_IBR, "ibr", "ibr", "ibr" }, {EM_DECODER_REGFILE_DBR, "dbr", "dbr", "dbr" }, {EM_DECODER_REGFILE_ITR, "itr", "itr", "itr" }, {EM_DECODER_REGFILE_DTR, "dtr", "dtr", "dtr" }, {EM_DECODER_REGFILE_MSR, "msr", "msr", "msr" }, {EM_DECODER_REGFILE_CPUID, "cpuid", "cpuid", "cpuid"}, {EM_DECODER_REGFILE_LAST, "last", "last", "last" } }; // CIa64Disasm::c_aRegFileInfo CIa64Disasm::SRegInfo CIa64Disasm::c_aRegInfo[] = { {EM_DECODER_NO_REG, "%mm", "%mm", "mm"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_NO_REG, "%error", "%error", "error"}, {EM_DECODER_REG_R0, "r0", "r0", "r0" }, {EM_DECODER_REG_R1, "r1", "gp", "gp" }, {EM_DECODER_REG_R2, "r2", "r2", "r2" }, {EM_DECODER_REG_R3, "r3", "r3", "r3" }, {EM_DECODER_REG_R4, "r4", "r4", "r4" }, {EM_DECODER_REG_R5, "r5", "r5", "r5" }, {EM_DECODER_REG_R6, "r6", "r6", "r6" }, {EM_DECODER_REG_R7, "r7", "r7", "r7" }, {EM_DECODER_REG_R8, "r8", "ret0", "ret0"}, {EM_DECODER_REG_R9, "r9", "ret1", "ret1"}, {EM_DECODER_REG_R10, "r10", "ret2", "ret2"}, {EM_DECODER_REG_R11, "r11", "ret3", "ret3"}, {EM_DECODER_REG_R12, "r12", "sp", "sp" }, {EM_DECODER_REG_R13, "r13", "r13", "r13" }, {EM_DECODER_REG_R14, "r14", "r14", "r14" }, {EM_DECODER_REG_R15, "r15", "r15", "r15" }, {EM_DECODER_REG_R16, "r16", "r16", "r16" }, {EM_DECODER_REG_R17, "r17", "r17", "r17" }, {EM_DECODER_REG_R18, "r18", "r18", "r18" }, {EM_DECODER_REG_R19, "r19", "r19", "r19" }, {EM_DECODER_REG_R20, "r20", "r20", "r20" }, {EM_DECODER_REG_R21, "r21", "r21", "r21" }, {EM_DECODER_REG_R22, "r22", "r22", "r22" }, {EM_DECODER_REG_R23, "r23", "r23", "r23" }, {EM_DECODER_REG_R24, "r24", "r24", "r24" }, {EM_DECODER_REG_R25, "r25", "r25", "r25" }, {EM_DECODER_REG_R26, "r26", "r26", "r26" }, {EM_DECODER_REG_R27, "r27", "r27", "r27" }, {EM_DECODER_REG_R28, "r28", "r28", "r28" }, {EM_DECODER_REG_R29, "r29", "r29", "r29" }, {EM_DECODER_REG_R30, "r30", "r30", "r30" }, {EM_DECODER_REG_R31, "r31", "r31", "r31" }, {EM_DECODER_REG_R32, "r32", "r32", "r32" }, {EM_DECODER_REG_R33, "r33", "r33", "r33" }, {EM_DECODER_REG_R34, "r34", "r34", "r34" }, {EM_DECODER_REG_R35, "r35", "r35", "r35" }, {EM_DECODER_REG_R36, "r36", "r36", "r36" }, {EM_DECODER_REG_R37, "r37", "r37", "r37" }, {EM_DECODER_REG_R38, "r38", "r38", "r38" }, {EM_DECODER_REG_R39, "r39", "r39", "r39" }, {EM_DECODER_REG_R40, "r40", "r40", "r40" }, {EM_DECODER_REG_R41, "r41", "r41", "r41" }, {EM_DECODER_REG_R42, "r42", "r42", "r42" }, {EM_DECODER_REG_R43, "r43", "r43", "r43" }, {EM_DECODER_REG_R44, "r44", "r44", "r44" }, {EM_DECODER_REG_R45, "r45", "r45", "r45" }, {EM_DECODER_REG_R46, "r46", "r46", "r46" }, {EM_DECODER_REG_R47, "r47", "r47", "r47" }, {EM_DECODER_REG_R48, "r48", "r48", "r48" }, {EM_DECODER_REG_R49, "r49", "r49", "r49" }, {EM_DECODER_REG_R50, "r50", "r50", "r50" }, {EM_DECODER_REG_R51, "r51", "r51", "r51" }, {EM_DECODER_REG_R52, "r52", "r52", "r52" }, {EM_DECODER_REG_R53, "r53", "r53", "r53" }, {EM_DECODER_REG_R54, "r54", "r54", "r54" }, {EM_DECODER_REG_R55, "r55", "r55", "r55" }, {EM_DECODER_REG_R56, "r56", "r56", "r56" }, {EM_DECODER_REG_R57, "r57", "r57", "r57" }, {EM_DECODER_REG_R58, "r58", "r58", "r58" }, {EM_DECODER_REG_R59, "r59", "r59", "r59" }, {EM_DECODER_REG_R60, "r60", "r60", "r60" }, {EM_DECODER_REG_R61, "r61", "r61", "r61" }, {EM_DECODER_REG_R62, "r62", "r62", "r62" }, {EM_DECODER_REG_R63, "r63", "r63", "r63" }, {EM_DECODER_REG_R64, "r64", "r64", "r64" }, {EM_DECODER_REG_R65, "r65", "r65", "r65" }, {EM_DECODER_REG_R66, "r66", "r66", "r66" }, {EM_DECODER_REG_R67, "r67", "r67", "r67" }, {EM_DECODER_REG_R68, "r68", "r68", "r68" }, {EM_DECODER_REG_R69, "r69", "r69", "r69" }, {EM_DECODER_REG_R70, "r70", "r70", "r70" }, {EM_DECODER_REG_R71, "r71", "r71", "r71" }, {EM_DECODER_REG_R72, "r72", "r72", "r72" }, {EM_DECODER_REG_R73, "r73", "r73", "r73" }, {EM_DECODER_REG_R74, "r74", "r74", "r74" }, {EM_DECODER_REG_R75, "r75", "r75", "r75" }, {EM_DECODER_REG_R76, "r76", "r76", "r76" }, {EM_DECODER_REG_R77, "r77", "r77", "r77" }, {EM_DECODER_REG_R78, "r78", "r78", "r78" }, {EM_DECODER_REG_R79, "r79", "r79", "r79" }, {EM_DECODER_REG_R80, "r80", "r80", "r80" }, {EM_DECODER_REG_R81, "r81", "r81", "r81" }, {EM_DECODER_REG_R82, "r82", "r82", "r82" }, {EM_DECODER_REG_R83, "r83", "r83", "r83" }, {EM_DECODER_REG_R84, "r84", "r84", "r84" }, {EM_DECODER_REG_R85, "r85", "r85", "r85" }, {EM_DECODER_REG_R86, "r86", "r86", "r86" }, {EM_DECODER_REG_R87, "r87", "r87", "r87" }, {EM_DECODER_REG_R88, "r88", "r88", "r88" }, {EM_DECODER_REG_R89, "r89", "r89", "r89" }, {EM_DECODER_REG_R90, "r90", "r90", "r90" }, {EM_DECODER_REG_R91, "r91", "r91", "r91" }, {EM_DECODER_REG_R92, "r92", "r92", "r92" }, {EM_DECODER_REG_R93, "r93", "r93", "r93" }, {EM_DECODER_REG_R94, "r94", "r94", "r94" }, {EM_DECODER_REG_R95, "r95", "r95", "r95" }, {EM_DECODER_REG_R96, "r96", "r96", "r96" }, {EM_DECODER_REG_R97, "r97", "r97", "r97" }, {EM_DECODER_REG_R98, "r98", "r98", "r98" }, {EM_DECODER_REG_R99, "r99", "r99", "r99" }, {EM_DECODER_REG_R100, "r100", "r100", "r100"}, {EM_DECODER_REG_R101, "r101", "r101", "r101"}, {EM_DECODER_REG_R102, "r102", "r102", "r102"}, {EM_DECODER_REG_R103, "r103", "r103", "r103"}, {EM_DECODER_REG_R104, "r104", "r104", "r104"}, {EM_DECODER_REG_R105, "r105", "r105", "r105"}, {EM_DECODER_REG_R106, "r106", "r106", "r106"}, {EM_DECODER_REG_R107, "r107", "r107", "r107"}, {EM_DECODER_REG_R108, "r108", "r108", "r108"}, {EM_DECODER_REG_R109, "r109", "r109", "r109"}, {EM_DECODER_REG_R110, "r110", "r110", "r110"}, {EM_DECODER_REG_R111, "r111", "r111", "r111"}, {EM_DECODER_REG_R112, "r112", "r112", "r112"}, {EM_DECODER_REG_R113, "r113", "r113", "r113"}, {EM_DECODER_REG_R114, "r114", "r114", "r114"}, {EM_DECODER_REG_R115, "r115", "r115", "r115"}, {EM_DECODER_REG_R116, "r116", "r116", "r116"}, {EM_DECODER_REG_R117, "r117", "r117", "r117"}, {EM_DECODER_REG_R118, "r118", "r118", "r118"}, {EM_DECODER_REG_R119, "r119", "r119", "r119"}, {EM_DECODER_REG_R120, "r120", "r120", "r120"}, {EM_DECODER_REG_R121, "r121", "r121", "r121"}, {EM_DECODER_REG_R122, "r122", "r122", "r122"}, {EM_DECODER_REG_R123, "r123", "r123", "r123"}, {EM_DECODER_REG_R124, "r124", "r124", "r124"}, {EM_DECODER_REG_R125, "r125", "r125", "r125"}, {EM_DECODER_REG_R126, "r126", "r126", "r126"}, {EM_DECODER_REG_R127, "r127", "r127", "r127"}, {EM_DECODER_REG_F0, "f0", "f0", "f0" }, {EM_DECODER_REG_F1, "f1", "f1", "f1" }, {EM_DECODER_REG_F2, "f2", "f2", "f2" }, {EM_DECODER_REG_F3, "f3", "f3", "f3" }, {EM_DECODER_REG_F4, "f4", "f4", "f4" }, {EM_DECODER_REG_F5, "f5", "f5", "f5" }, {EM_DECODER_REG_F6, "f6", "f6", "f6" }, {EM_DECODER_REG_F7, "f7", "f7", "f7" }, {EM_DECODER_REG_F8, "f8", "farg0", "fret0"}, {EM_DECODER_REG_F9, "f9", "farg1", "fret1"}, {EM_DECODER_REG_F10, "f10", "farg2", "fret2"}, {EM_DECODER_REG_F11, "f11", "farg3", "fret3"}, {EM_DECODER_REG_F12, "f12", "farg4", "fret4"}, {EM_DECODER_REG_F13, "f13", "farg5", "fret5"}, {EM_DECODER_REG_F14, "f14", "farg6", "fret6"}, {EM_DECODER_REG_F15, "f15", "farg7", "fret7"}, {EM_DECODER_REG_F16, "f16", "f16", "f16" }, {EM_DECODER_REG_F17, "f17", "f17", "f17" }, {EM_DECODER_REG_F18, "f18", "f18", "f18" }, {EM_DECODER_REG_F19, "f19", "f19", "f19" }, {EM_DECODER_REG_F20, "f20", "f20", "f20" }, {EM_DECODER_REG_F21, "f21", "f21", "f21" }, {EM_DECODER_REG_F22, "f22", "f22", "f22" }, {EM_DECODER_REG_F23, "f23", "f23", "f23" }, {EM_DECODER_REG_F24, "f24", "f24", "f24" }, {EM_DECODER_REG_F25, "f25", "f25", "f25" }, {EM_DECODER_REG_F26, "f26", "f26", "f26" }, {EM_DECODER_REG_F27, "f27", "f27", "f27" }, {EM_DECODER_REG_F28, "f28", "f28", "f28" }, {EM_DECODER_REG_F29, "f29", "f29", "f29" }, {EM_DECODER_REG_F30, "f30", "f30", "f30" }, {EM_DECODER_REG_F31, "f31", "f31", "f31" }, {EM_DECODER_REG_F32, "f32", "f32", "f32" }, {EM_DECODER_REG_F33, "f33", "f33", "f33" }, {EM_DECODER_REG_F34, "f34", "f34", "f34" }, {EM_DECODER_REG_F35, "f35", "f35", "f35" }, {EM_DECODER_REG_F36, "f36", "f36", "f36" }, {EM_DECODER_REG_F37, "f37", "f37", "f37" }, {EM_DECODER_REG_F38, "f38", "f38", "f38" }, {EM_DECODER_REG_F39, "f39", "f39", "f39" }, {EM_DECODER_REG_F40, "f40", "f40", "f40" }, {EM_DECODER_REG_F41, "f41", "f41", "f41" }, {EM_DECODER_REG_F42, "f42", "f42", "f42" }, {EM_DECODER_REG_F43, "f43", "f43", "f43" }, {EM_DECODER_REG_F44, "f44", "f44", "f44" }, {EM_DECODER_REG_F45, "f45", "f45", "f45" }, {EM_DECODER_REG_F46, "f46", "f46", "f46" }, {EM_DECODER_REG_F47, "f47", "f47", "f47" }, {EM_DECODER_REG_F48, "f48", "f48", "f48" }, {EM_DECODER_REG_F49, "f49", "f49", "f49" }, {EM_DECODER_REG_F50, "f50", "f50", "f50" }, {EM_DECODER_REG_F51, "f51", "f51", "f51" }, {EM_DECODER_REG_F52, "f52", "f52", "f52" }, {EM_DECODER_REG_F53, "f53", "f53", "f53" }, {EM_DECODER_REG_F54, "f54", "f54", "f54" }, {EM_DECODER_REG_F55, "f55", "f55", "f55" }, {EM_DECODER_REG_F56, "f56", "f56", "f56" }, {EM_DECODER_REG_F57, "f57", "f57", "f57" }, {EM_DECODER_REG_F58, "f58", "f58", "f58" }, {EM_DECODER_REG_F59, "f59", "f59", "f59" }, {EM_DECODER_REG_F60, "f60", "f60", "f60" }, {EM_DECODER_REG_F61, "f61", "f61", "f61" }, {EM_DECODER_REG_F62, "f62", "f62", "f62" }, {EM_DECODER_REG_F63, "f63", "f63", "f63" }, {EM_DECODER_REG_F64, "f64", "f64", "f64" }, {EM_DECODER_REG_F65, "f65", "f65", "f65" }, {EM_DECODER_REG_F66, "f66", "f66", "f66" }, {EM_DECODER_REG_F67, "f67", "f67", "f67" }, {EM_DECODER_REG_F68, "f68", "f68", "f68" }, {EM_DECODER_REG_F69, "f69", "f69", "f69" }, {EM_DECODER_REG_F70, "f70", "f70", "f70" }, {EM_DECODER_REG_F71, "f71", "f71", "f71" }, {EM_DECODER_REG_F72, "f72", "f72", "f72" }, {EM_DECODER_REG_F73, "f73", "f73", "f73" }, {EM_DECODER_REG_F74, "f74", "f74", "f74" }, {EM_DECODER_REG_F75, "f75", "f75", "f75" }, {EM_DECODER_REG_F76, "f76", "f76", "f76" }, {EM_DECODER_REG_F77, "f77", "f77", "f77" }, {EM_DECODER_REG_F78, "f78", "f78", "f78" }, {EM_DECODER_REG_F79, "f79", "f79", "f79" }, {EM_DECODER_REG_F80, "f80", "f80", "f80" }, {EM_DECODER_REG_F81, "f81", "f81", "f81" }, {EM_DECODER_REG_F82, "f82", "f82", "f82" }, {EM_DECODER_REG_F83, "f83", "f83", "f83" }, {EM_DECODER_REG_F84, "f84", "f84", "f84" }, {EM_DECODER_REG_F85, "f85", "f85", "f85" }, {EM_DECODER_REG_F86, "f86", "f86", "f86" }, {EM_DECODER_REG_F87, "f87", "f87", "f87" }, {EM_DECODER_REG_F88, "f88", "f88", "f88" }, {EM_DECODER_REG_F89, "f89", "f89", "f89" }, {EM_DECODER_REG_F90, "f90", "f90", "f90" }, {EM_DECODER_REG_F91, "f91", "f91", "f91" }, {EM_DECODER_REG_F92, "f92", "f92", "f92" }, {EM_DECODER_REG_F93, "f93", "f93", "f93" }, {EM_DECODER_REG_F94, "f94", "f94", "f94" }, {EM_DECODER_REG_F95, "f95", "f95", "f95" }, {EM_DECODER_REG_F96, "f96", "f96", "f96" }, {EM_DECODER_REG_F97, "f97", "f97", "f97" }, {EM_DECODER_REG_F98, "f98", "f98", "f98" }, {EM_DECODER_REG_F99, "f99", "f99", "f99" }, {EM_DECODER_REG_F100, "f100", "f100", "f100" }, {EM_DECODER_REG_F101, "f101", "f101", "f101" }, {EM_DECODER_REG_F102, "f102", "f102", "f102" }, {EM_DECODER_REG_F103, "f103", "f103", "f103" }, {EM_DECODER_REG_F104, "f104", "f104", "f104" }, {EM_DECODER_REG_F105, "f105", "f105", "f105" }, {EM_DECODER_REG_F106, "f106", "f106", "f106" }, {EM_DECODER_REG_F107, "f107", "f107", "f107" }, {EM_DECODER_REG_F108, "f108", "f108", "f108" }, {EM_DECODER_REG_F109, "f109", "f109", "f109" }, {EM_DECODER_REG_F110, "f110", "f110", "f110" }, {EM_DECODER_REG_F111, "f111", "f111", "f111" }, {EM_DECODER_REG_F112, "f112", "f112", "f112" }, {EM_DECODER_REG_F113, "f113", "f113", "f113" }, {EM_DECODER_REG_F114, "f114", "f114", "f114" }, {EM_DECODER_REG_F115, "f115", "f115", "f115" }, {EM_DECODER_REG_F116, "f116", "f116", "f116" }, {EM_DECODER_REG_F117, "f117", "f117", "f117" }, {EM_DECODER_REG_F118, "f118", "f118", "f118" }, {EM_DECODER_REG_F119, "f119", "f119", "f119" }, {EM_DECODER_REG_F120, "f120", "f120", "f120" }, {EM_DECODER_REG_F121, "f121", "f121", "f121" }, {EM_DECODER_REG_F122, "f122", "f122", "f122" }, {EM_DECODER_REG_F123, "f123", "f123", "f123" }, {EM_DECODER_REG_F124, "f124", "f124", "f124" }, {EM_DECODER_REG_F125, "f125", "f125", "f125" }, {EM_DECODER_REG_F126, "f126", "f126", "f126" }, {EM_DECODER_REG_F127, "f127", "f127", "f127" }, {EM_DECODER_REG_AR0, "ar0", "ar.k0", "ar.kr0" }, {EM_DECODER_REG_AR1, "ar1", "ar.k1", "ar.kr1" }, {EM_DECODER_REG_AR2, "ar2", "ar.k2", "ar.kr2" }, {EM_DECODER_REG_AR3, "ar3", "ar.k3", "ar.kr3" }, {EM_DECODER_REG_AR4, "ar4", "ar.k4", "ar.kr4" }, {EM_DECODER_REG_AR5, "ar5", "ar.k5", "ar.kr5" }, {EM_DECODER_REG_AR6, "ar6", "ar.k6", "ar.kr6" }, {EM_DECODER_REG_AR7, "ar7", "ar.k7", "ar.kr7" }, {EM_DECODER_REG_AR8, "ar8", "ar8", "ar8-res" }, {EM_DECODER_REG_AR9, "ar9", "ar9", "ar9-res" }, {EM_DECODER_REG_AR10, "ar10", "ar10", "ar10-res" }, {EM_DECODER_REG_AR11, "ar11", "ar11", "ar11-res" }, {EM_DECODER_REG_AR12, "ar12", "ar12", "ar12-res" }, {EM_DECODER_REG_AR13, "ar13", "ar13", "ar13-res" }, {EM_DECODER_REG_AR14, "ar14", "ar14", "ar14-res" }, {EM_DECODER_REG_AR15, "ar15", "ar15", "ar15-res" }, {EM_DECODER_REG_AR16, "ar16", "ar.rsc", "ar.rsc" }, {EM_DECODER_REG_AR17, "ar17", "ar.bsp", "ar.bsp" }, {EM_DECODER_REG_AR18, "ar18", "ar.bspstore", "ar.bspstore"}, {EM_DECODER_REG_AR19, "ar19", "ar.rnat", "ar.rnat" }, {EM_DECODER_REG_AR20, "ar20", "ar20", "ar20-res" }, {EM_DECODER_REG_AR21, "ar21", "ar.fcr", "ar21-ia32" }, {EM_DECODER_REG_AR22, "ar22", "ar22", "ar22-res" }, {EM_DECODER_REG_AR23, "ar23", "ar23", "ar23-res" }, {EM_DECODER_REG_AR24, "ar24", "ar.eflag", "ar24-ia32" }, {EM_DECODER_REG_AR25, "ar25", "ar.csd", "ar25-ia32" }, {EM_DECODER_REG_AR26, "ar26", "ar.ssd", "ar26-ia32" }, {EM_DECODER_REG_AR27, "ar27", "ar.cflg", "ar27-ia32" }, {EM_DECODER_REG_AR28, "ar28", "ar.fsr", "ar28-ia32" }, {EM_DECODER_REG_AR29, "ar29", "ar.fir", "ar29-ia32" }, {EM_DECODER_REG_AR30, "ar30", "ar.fdr", "ar30-ia32" }, {EM_DECODER_REG_AR31, "ar31", "ar31", "ar31-res" }, {EM_DECODER_REG_AR32, "ar32", "ar.ccv", "ar.ccv" }, {EM_DECODER_REG_AR33, "ar33", "ar33", "ar33-res" }, {EM_DECODER_REG_AR34, "ar34", "ar34", "ar34-res" }, {EM_DECODER_REG_AR35, "ar35", "ar35", "ar35-res" }, {EM_DECODER_REG_AR36, "ar36", "ar.unat", "ar.unat" }, {EM_DECODER_REG_AR37, "ar37", "ar37", "ar37-res" }, {EM_DECODER_REG_AR38, "ar38", "ar38", "ar38-res" }, {EM_DECODER_REG_AR39, "ar39", "ar39", "ar39-res" }, {EM_DECODER_REG_AR40, "ar40", "ar.fpsr", "ar.fpsr" }, {EM_DECODER_REG_AR41, "ar41", "ar41", "ar41-res" }, {EM_DECODER_REG_AR42, "ar42", "ar42", "ar42-res" }, {EM_DECODER_REG_AR43, "ar43", "ar43", "ar43-res" }, {EM_DECODER_REG_AR44, "ar44", "ar.itc", "ar.itc" }, {EM_DECODER_REG_AR45, "ar45", "ar45", "ar45-res" }, {EM_DECODER_REG_AR46, "ar46", "ar46", "ar46-res" }, {EM_DECODER_REG_AR47, "ar47", "ar47", "ar47-res" }, {EM_DECODER_REG_AR48, "ar48", "ar48", "ar48-ign" }, {EM_DECODER_REG_AR49, "ar49", "ar49", "ar49-ign" }, {EM_DECODER_REG_AR50, "ar50", "ar50", "ar50-ign" }, {EM_DECODER_REG_AR51, "ar51", "ar51", "ar51-ign" }, {EM_DECODER_REG_AR52, "ar52", "ar52", "ar52-ign" }, {EM_DECODER_REG_AR53, "ar53", "ar53", "ar53-ign" }, {EM_DECODER_REG_AR54, "ar54", "ar54", "ar54-ign" }, {EM_DECODER_REG_AR55, "ar55", "ar55", "ar55-ign" }, {EM_DECODER_REG_AR56, "ar56", "ar56", "ar56-ign" }, {EM_DECODER_REG_AR57, "ar57", "ar57", "ar57-ign" }, {EM_DECODER_REG_AR58, "ar58", "ar58", "ar58-ign" }, {EM_DECODER_REG_AR59, "ar59", "ar59", "ar59-ign" }, {EM_DECODER_REG_AR60, "ar60", "ar60", "ar60-ign" }, {EM_DECODER_REG_AR61, "ar61", "ar61", "ar61-ign" }, {EM_DECODER_REG_AR62, "ar62", "ar62", "ar62-ign" }, {EM_DECODER_REG_AR63, "ar63", "ar63", "ar63-ign" }, {EM_DECODER_REG_AR64, "ar64", "ar.pfs", "ar.pfs" }, {EM_DECODER_REG_AR65, "ar65", "ar.lc", "ar.lc" }, {EM_DECODER_REG_AR66, "ar66", "ar.ec", "ar.ec" }, {EM_DECODER_REG_AR67, "ar67", "ar67", "ar67-res" }, {EM_DECODER_REG_AR68, "ar68", "ar68", "ar68-res" }, {EM_DECODER_REG_AR69, "ar69", "ar69", "ar69-res" }, {EM_DECODER_REG_AR70, "ar70", "ar70", "ar70-res" }, {EM_DECODER_REG_AR71, "ar71", "ar71", "ar71-res" }, {EM_DECODER_REG_AR72, "ar72", "ar72", "ar72-res" }, {EM_DECODER_REG_AR73, "ar73", "ar73", "ar73-res" }, {EM_DECODER_REG_AR74, "ar74", "ar74", "ar74-res" }, {EM_DECODER_REG_AR75, "ar75", "ar75", "ar75-res" }, {EM_DECODER_REG_AR76, "ar76", "ar76", "ar76-res" }, {EM_DECODER_REG_AR77, "ar77", "ar77", "ar77-res" }, {EM_DECODER_REG_AR78, "ar78", "ar78", "ar78-res" }, {EM_DECODER_REG_AR79, "ar79", "ar79", "ar79-res" }, {EM_DECODER_REG_AR80, "ar80", "ar80", "ar80-res" }, {EM_DECODER_REG_AR81, "ar81", "ar81", "ar81-res" }, {EM_DECODER_REG_AR82, "ar82", "ar82", "ar82-res" }, {EM_DECODER_REG_AR83, "ar83", "ar83", "ar83-res" }, {EM_DECODER_REG_AR84, "ar84", "ar84", "ar84-res" }, {EM_DECODER_REG_AR85, "ar85", "ar85", "ar85-res" }, {EM_DECODER_REG_AR86, "ar86", "ar86", "ar86-res" }, {EM_DECODER_REG_AR87, "ar87", "ar87", "ar87-res" }, {EM_DECODER_REG_AR88, "ar88", "ar88", "ar88-res" }, {EM_DECODER_REG_AR89, "ar89", "ar89", "ar89-res" }, {EM_DECODER_REG_AR90, "ar90", "ar90", "ar90-res" }, {EM_DECODER_REG_AR91, "ar91", "ar91", "ar91-res" }, {EM_DECODER_REG_AR92, "ar92", "ar92", "ar92-res" }, {EM_DECODER_REG_AR93, "ar93", "ar93", "ar93-res" }, {EM_DECODER_REG_AR94, "ar94", "ar94", "ar94-res" }, {EM_DECODER_REG_AR95, "ar95", "ar95", "ar95-res" }, {EM_DECODER_REG_AR96, "ar96", "ar96", "ar96-res" }, {EM_DECODER_REG_AR97, "ar97", "ar97", "ar97-res" }, {EM_DECODER_REG_AR98, "ar98", "ar98", "ar98-res" }, {EM_DECODER_REG_AR99, "ar99", "ar99", "ar99-res" }, {EM_DECODER_REG_AR100, "ar100", "ar100", "ar100-res" }, {EM_DECODER_REG_AR101, "ar101", "ar101", "ar101-res" }, {EM_DECODER_REG_AR102, "ar102", "ar102", "ar102-res" }, {EM_DECODER_REG_AR103, "ar103", "ar103", "ar103-res" }, {EM_DECODER_REG_AR104, "ar104", "ar104", "ar104-res" }, {EM_DECODER_REG_AR105, "ar105", "ar105", "ar105-res" }, {EM_DECODER_REG_AR106, "ar106", "ar106", "ar106-res" }, {EM_DECODER_REG_AR107, "ar107", "ar107", "ar107-res" }, {EM_DECODER_REG_AR108, "ar108", "ar108", "ar108-res" }, {EM_DECODER_REG_AR109, "ar109", "ar109", "ar109-res" }, {EM_DECODER_REG_AR110, "ar110", "ar110", "ar110-res" }, {EM_DECODER_REG_AR111, "ar111", "ar111", "ar111-res" }, {EM_DECODER_REG_AR112, "ar112", "ar112", "ar112-ign" }, {EM_DECODER_REG_AR113, "ar113", "ar113", "ar113-ign" }, {EM_DECODER_REG_AR114, "ar114", "ar114", "ar114-ign" }, {EM_DECODER_REG_AR115, "ar115", "ar115", "ar115-ign" }, {EM_DECODER_REG_AR116, "ar116", "ar116", "ar116-ign" }, {EM_DECODER_REG_AR117, "ar117", "ar117", "ar117-ign" }, {EM_DECODER_REG_AR118, "ar118", "ar118", "ar118-ign" }, {EM_DECODER_REG_AR119, "ar119", "ar119", "ar119-ign" }, {EM_DECODER_REG_AR120, "ar120", "ar120", "ar120-ign" }, {EM_DECODER_REG_AR121, "ar121", "ar121", "ar121-ign" }, {EM_DECODER_REG_AR122, "ar122", "ar122", "ar122-ign" }, {EM_DECODER_REG_AR123, "ar123", "ar123", "ar123-ign" }, {EM_DECODER_REG_AR124, "ar124", "ar124", "ar124-ign" }, {EM_DECODER_REG_AR125, "ar125", "ar125", "ar125-ign" }, {EM_DECODER_REG_AR126, "ar126", "ar126", "ar126-ign" }, {EM_DECODER_REG_AR127, "ar127", "ar127", "ar127-ign" }, {EM_DECODER_REG_P0, "p0", "p0", "p0" }, {EM_DECODER_REG_P1, "p1", "p1", "p1" }, {EM_DECODER_REG_P2, "p2", "p2", "p2" }, {EM_DECODER_REG_P3, "p3", "p3", "p3" }, {EM_DECODER_REG_P4, "p4", "p4", "p4" }, {EM_DECODER_REG_P5, "p5", "p5", "p5" }, {EM_DECODER_REG_P6, "p6", "p6", "p6" }, {EM_DECODER_REG_P7, "p7", "p7", "p7" }, {EM_DECODER_REG_P8, "p8", "p8", "p8" }, {EM_DECODER_REG_P9, "p9", "p9", "p9" }, {EM_DECODER_REG_P10, "p10", "p10", "p10"}, {EM_DECODER_REG_P11, "p11", "p11", "p11"}, {EM_DECODER_REG_P12, "p12", "p12", "p12"}, {EM_DECODER_REG_P13, "p13", "p13", "p13"}, {EM_DECODER_REG_P14, "p14", "p14", "p14"}, {EM_DECODER_REG_P15, "p15", "p15", "p15"}, {EM_DECODER_REG_P16, "p16", "p16", "p16"}, {EM_DECODER_REG_P17, "p17", "p17", "p17"}, {EM_DECODER_REG_P18, "p18", "p18", "p18"}, {EM_DECODER_REG_P19, "p19", "p19", "p19"}, {EM_DECODER_REG_P20, "p20", "p20", "p20"}, {EM_DECODER_REG_P21, "p21", "p21", "p21"}, {EM_DECODER_REG_P22, "p22", "p22", "p22"}, {EM_DECODER_REG_P23, "p23", "p23", "p23"}, {EM_DECODER_REG_P24, "p24", "p24", "p24"}, {EM_DECODER_REG_P25, "p25", "p25", "p25"}, {EM_DECODER_REG_P26, "p26", "p26", "p26"}, {EM_DECODER_REG_P27, "p27", "p27", "p27"}, {EM_DECODER_REG_P28, "p28", "p28", "p28"}, {EM_DECODER_REG_P29, "p29", "p29", "p29"}, {EM_DECODER_REG_P30, "p30", "p30", "p30"}, {EM_DECODER_REG_P31, "p31", "p31", "p31"}, {EM_DECODER_REG_P32, "p32", "p32", "p32"}, {EM_DECODER_REG_P33, "p33", "p33", "p33"}, {EM_DECODER_REG_P34, "p34", "p34", "p34"}, {EM_DECODER_REG_P35, "p35", "p35", "p35"}, {EM_DECODER_REG_P36, "p36", "p36", "p36"}, {EM_DECODER_REG_P37, "p37", "p37", "p37"}, {EM_DECODER_REG_P38, "p38", "p38", "p38"}, {EM_DECODER_REG_P39, "p39", "p39", "p39"}, {EM_DECODER_REG_P40, "p40", "p40", "p40"}, {EM_DECODER_REG_P41, "p41", "p41", "p41"}, {EM_DECODER_REG_P42, "p42", "p42", "p42"}, {EM_DECODER_REG_P43, "p43", "p43", "p43"}, {EM_DECODER_REG_P44, "p44", "p44", "p44"}, {EM_DECODER_REG_P45, "p45", "p45", "p45"}, {EM_DECODER_REG_P46, "p46", "p46", "p46"}, {EM_DECODER_REG_P47, "p47", "p47", "p47"}, {EM_DECODER_REG_P48, "p48", "p48", "p48"}, {EM_DECODER_REG_P49, "p49", "p49", "p49"}, {EM_DECODER_REG_P50, "p50", "p50", "p50"}, {EM_DECODER_REG_P51, "p51", "p51", "p51"}, {EM_DECODER_REG_P52, "p52", "p52", "p52"}, {EM_DECODER_REG_P53, "p53", "p53", "p53"}, {EM_DECODER_REG_P54, "p54", "p54", "p54"}, {EM_DECODER_REG_P55, "p55", "p55", "p55"}, {EM_DECODER_REG_P56, "p56", "p56", "p56"}, {EM_DECODER_REG_P57, "p57", "p57", "p57"}, {EM_DECODER_REG_P58, "p58", "p58", "p58"}, {EM_DECODER_REG_P59, "p59", "p59", "p59"}, {EM_DECODER_REG_P60, "p60", "p60", "p60"}, {EM_DECODER_REG_P61, "p61", "p61", "p61"}, {EM_DECODER_REG_P62, "p62", "p62", "p62"}, {EM_DECODER_REG_P63, "p63", "p63", "p63"}, {EM_DECODER_REG_BR0, "b0", "rp", "bret"}, {EM_DECODER_REG_BR1, "b1", "b1", "b1" }, {EM_DECODER_REG_BR2, "b2", "b2", "b2" }, {EM_DECODER_REG_BR3, "b3", "b3", "b3" }, {EM_DECODER_REG_BR4, "b4", "b4", "b4" }, {EM_DECODER_REG_BR5, "b5", "b5", "b5" }, {EM_DECODER_REG_BR6, "b6", "b6", "b6" }, {EM_DECODER_REG_BR7, "b7", "b7", "b7" }, {EM_DECODER_REG_PR, "pr", "pr", "pr" }, {EM_DECODER_REG_PR_ROT, "pr.rot", "pr.rot", "pr.rot" }, {EM_DECODER_REG_CR0, "cr0", "cr.dcr", "cr.dcr" }, {EM_DECODER_REG_CR1, "cr1", "cr.itm", "cr.itm" }, {EM_DECODER_REG_CR2, "cr2", "cr.iva", "cr.iva" }, {EM_DECODER_REG_CR3, "cr3", "cr3", "cr3-res" }, {EM_DECODER_REG_CR4, "cr4", "cr4", "cr4-res" }, {EM_DECODER_REG_CR5, "cr5", "cr5", "cr5-res" }, {EM_DECODER_REG_CR6, "cr6", "cr6", "cr6-res" }, {EM_DECODER_REG_CR7, "cr7", "cr7", "cr7-res" }, {EM_DECODER_REG_CR8, "cr8", "cr.pta", "cr.pta" }, {EM_DECODER_REG_CR9, "cr9", "cr.gpta", "cr.gpta" }, {EM_DECODER_REG_CR10, "cr10", "cr10", "cr10-res" }, {EM_DECODER_REG_CR11, "cr11", "cr11", "cr11-res" }, {EM_DECODER_REG_CR12, "cr12", "cr12", "cr12-res" }, {EM_DECODER_REG_CR13, "cr13", "cr13", "cr13-res" }, {EM_DECODER_REG_CR14, "cr14", "cr14", "cr14-res" }, {EM_DECODER_REG_CR15, "cr15", "cr15", "cr15-res" }, {EM_DECODER_REG_CR16, "cr16", "cr.ipsr", "cr.ipsr" }, {EM_DECODER_REG_CR17, "cr17", "cr.isr", "cr.isr" }, {EM_DECODER_REG_CR18, "cr18", "cr18", "cr18-res" }, {EM_DECODER_REG_CR19, "cr19", "cr.iip", "cr.iip" }, {EM_DECODER_REG_CR20, "cr20", "cr.ifa", "cr.ifa" }, {EM_DECODER_REG_CR21, "cr21", "cr.itir", "cr.itir" }, {EM_DECODER_REG_CR22, "cr22", "cr.iipa", "cr.iipa" }, {EM_DECODER_REG_CR23, "cr23", "cr.ifs", "cr.ifs" }, {EM_DECODER_REG_CR24, "cr24", "cr.iim", "cr.iim" }, {EM_DECODER_REG_CR25, "cr25", "cr.iha", "cr.iha" }, {EM_DECODER_REG_CR26, "cr26", "cr26", "cr26-res" }, {EM_DECODER_REG_CR27, "cr27", "cr27", "cr27-res" }, {EM_DECODER_REG_CR28, "cr28", "cr28", "cr28-res" }, {EM_DECODER_REG_CR29, "cr29", "cr29", "cr29-res" }, {EM_DECODER_REG_CR30, "cr30", "cr30", "cr30-res" }, {EM_DECODER_REG_CR31, "cr31", "cr31", "cr31-res" }, {EM_DECODER_REG_CR32, "cr32", "cr32", "cr32-res" }, {EM_DECODER_REG_CR33, "cr33", "cr33", "cr33-res" }, {EM_DECODER_REG_CR34, "cr34", "cr34", "cr34-res" }, {EM_DECODER_REG_CR35, "cr35", "cr35", "cr35-res" }, {EM_DECODER_REG_CR36, "cr36", "cr36", "cr36-res" }, {EM_DECODER_REG_CR37, "cr37", "cr37", "cr37-res" }, {EM_DECODER_REG_CR38, "cr38", "cr38", "cr38-res" }, {EM_DECODER_REG_CR39, "cr39", "cr39", "cr39-res" }, {EM_DECODER_REG_CR40, "cr40", "cr40", "cr40-res" }, {EM_DECODER_REG_CR41, "cr41", "cr41", "cr41-res" }, {EM_DECODER_REG_CR42, "cr42", "cr42", "cr42-res" }, {EM_DECODER_REG_CR43, "cr43", "cr43", "cr43-res" }, {EM_DECODER_REG_CR44, "cr44", "cr44", "cr44-res" }, {EM_DECODER_REG_CR45, "cr45", "cr45", "cr45-res" }, {EM_DECODER_REG_CR46, "cr46", "cr46", "cr46-res" }, {EM_DECODER_REG_CR47, "cr47", "cr47", "cr47-res" }, {EM_DECODER_REG_CR48, "cr48", "cr48", "cr48-res" }, {EM_DECODER_REG_CR49, "cr49", "cr49", "cr49-res" }, {EM_DECODER_REG_CR50, "cr50", "cr50", "cr50-res" }, {EM_DECODER_REG_CR51, "cr51", "cr51", "cr51-res" }, {EM_DECODER_REG_CR52, "cr52", "cr52", "cr52-res" }, {EM_DECODER_REG_CR53, "cr53", "cr53", "cr53-res" }, {EM_DECODER_REG_CR54, "cr54", "cr54", "cr54-res" }, {EM_DECODER_REG_CR55, "cr55", "cr55", "cr55-res" }, {EM_DECODER_REG_CR56, "cr56", "cr56", "cr56-res" }, {EM_DECODER_REG_CR57, "cr57", "cr57", "cr57-res" }, {EM_DECODER_REG_CR58, "cr58", "cr58", "cr58-res" }, {EM_DECODER_REG_CR59, "cr59", "cr59", "cr59-res" }, {EM_DECODER_REG_CR60, "cr60", "cr60", "cr60-res" }, {EM_DECODER_REG_CR61, "cr61", "cr61", "cr61-res" }, {EM_DECODER_REG_CR62, "cr62", "cr62", "cr62-res" }, {EM_DECODER_REG_CR63, "cr63", "cr63", "cr63-res" }, {EM_DECODER_REG_CR64, "cr64", "cr.lid", "cr.lid" }, {EM_DECODER_REG_CR65, "cr65", "cr.ivr", "cr.ivr" }, {EM_DECODER_REG_CR66, "cr66", "cr.tpr", "cr.tpr" }, {EM_DECODER_REG_CR67, "cr67", "cr.eoi", "cr.eoi" }, {EM_DECODER_REG_CR68, "cr68", "cr.irr0", "cr.irr0" }, {EM_DECODER_REG_CR69, "cr69", "cr.irr1", "cr.irr1" }, {EM_DECODER_REG_CR70, "cr70", "cr.irr2", "cr.irr2" }, {EM_DECODER_REG_CR71, "cr71", "cr.irr3", "cr.irr3" }, {EM_DECODER_REG_CR72, "cr72", "cr.itv", "cr.itv" }, {EM_DECODER_REG_CR73, "cr73", "cr.pmv", "cr.pmv" }, {EM_DECODER_REG_CR74, "cr74", "cr.cmcv", "cr.cmcv" }, {EM_DECODER_REG_CR75, "cr75", "cr75", "cr75-res" }, {EM_DECODER_REG_CR76, "cr76", "cr76", "cr76-res" }, {EM_DECODER_REG_CR77, "cr77", "cr77", "cr77-res" }, {EM_DECODER_REG_CR78, "cr78", "cr78", "cr78-res" }, {EM_DECODER_REG_CR79, "cr79", "cr79", "cr79-res" }, {EM_DECODER_REG_CR80, "cr80", "cr.lrr0", "cr.lrr0" }, {EM_DECODER_REG_CR81, "cr81", "cr.lrr1", "cr.lrr1" }, {EM_DECODER_REG_CR82, "cr82", "cr82", "cr82-res" }, {EM_DECODER_REG_CR83, "cr83", "cr83", "cr83-res" }, {EM_DECODER_REG_CR84, "cr84", "cr84", "cr84-res" }, {EM_DECODER_REG_CR85, "cr85", "cr85", "cr85-res" }, {EM_DECODER_REG_CR86, "cr86", "cr86", "cr86-res" }, {EM_DECODER_REG_CR87, "cr87", "cr87", "cr87-res" }, {EM_DECODER_REG_CR88, "cr88", "cr88", "cr88-res" }, {EM_DECODER_REG_CR89, "cr89", "cr89", "cr89-res" }, {EM_DECODER_REG_CR90, "cr90", "cr90", "cr90-res" }, {EM_DECODER_REG_CR91, "cr91", "cr91", "cr91-res" }, {EM_DECODER_REG_CR92, "cr92", "cr92", "cr92-res" }, {EM_DECODER_REG_CR93, "cr93", "cr93", "cr93-res" }, {EM_DECODER_REG_CR94, "cr94", "cr94", "cr94-res" }, {EM_DECODER_REG_CR95, "cr95", "cr95", "cr95-res" }, {EM_DECODER_REG_CR96, "cr96", "cr96", "cr96-res" }, {EM_DECODER_REG_CR97, "cr97", "cr97", "cr97-res" }, {EM_DECODER_REG_CR98, "cr98", "cr98", "cr98-res" }, {EM_DECODER_REG_CR99, "cr99", "cr99", "cr99-res" }, {EM_DECODER_REG_CR100, "cr100", "cr100", "cr100-res"}, {EM_DECODER_REG_CR101, "cr101", "cr101", "cr101-res"}, {EM_DECODER_REG_CR102, "cr102", "cr102", "cr102-res"}, {EM_DECODER_REG_CR103, "cr103", "cr103", "cr103-res"}, {EM_DECODER_REG_CR104, "cr104", "cr104", "cr104-res"}, {EM_DECODER_REG_CR105, "cr105", "cr105", "cr105-res"}, {EM_DECODER_REG_CR106, "cr106", "cr106", "cr106-res"}, {EM_DECODER_REG_CR107, "cr107", "cr107", "cr107-res"}, {EM_DECODER_REG_CR108, "cr108", "cr108", "cr108-res"}, {EM_DECODER_REG_CR109, "cr109", "cr109", "cr109-res"}, {EM_DECODER_REG_CR110, "cr110", "cr110", "cr110-res"}, {EM_DECODER_REG_CR111, "cr111", "cr111", "cr111-res"}, {EM_DECODER_REG_CR112, "cr112", "cr112", "cr112-res"}, {EM_DECODER_REG_CR113, "cr113", "cr113", "cr113-res"}, {EM_DECODER_REG_CR114, "cr114", "cr114", "cr114-res"}, {EM_DECODER_REG_CR115, "cr115", "cr115", "cr115-res"}, {EM_DECODER_REG_CR116, "cr116", "cr116", "cr116-res"}, {EM_DECODER_REG_CR117, "cr117", "cr117", "cr117-res"}, {EM_DECODER_REG_CR118, "cr118", "cr118", "cr118-res"}, {EM_DECODER_REG_CR119, "cr119", "cr119", "cr119-res"}, {EM_DECODER_REG_CR120, "cr120", "cr120", "cr120-res"}, {EM_DECODER_REG_CR121, "cr121", "cr121", "cr121-res"}, {EM_DECODER_REG_CR122, "cr122", "cr122", "cr122-res"}, {EM_DECODER_REG_CR123, "cr123", "cr123", "cr123-res"}, {EM_DECODER_REG_CR124, "cr124", "cr124", "cr124-res"}, {EM_DECODER_REG_CR125, "cr125", "cr125", "cr125-res"}, {EM_DECODER_REG_CR126, "cr126", "cr126", "cr126-res"}, {EM_DECODER_REG_CR127, "cr127", "cr127", "cr127-res"}, {EM_DECODER_REG_PSR, "psr", "psr", "psr" }, {EM_DECODER_REG_PSR_L, "psr.l", "psr.l", "psr.l" }, {EM_DECODER_REG_PSR_UM, "psr.um", "psr.um", "psr.um" }, {EM_DECODER_REG_IP, "IP", "IP", "ip" }, {EM_DECODER_EM_REG_LAST, "", "", ""}, {EM_DECODER_REG_LAST, "", "", ""} }; UCHAR g_Ia64Disinstr[EM_BUNDLE_SIZE]; /****************************************************************** ** Simple IA64 template info... Thierry 12/99. ** */ #define GET_TEMPLATE(Bits) \ ((EM_template_t)(((Bits) >> EM_TEMPLATE_POS) & (EM_NUM_OF_TEMPLATES - 1))) typedef enum _EM_UNIT { I_Unit, M_Unit, F_Unit, B_Unit, X_Unit, L_Unit, A_Unit, No_Unit } EM_UNIT; typedef enum _EM_SB { SB_Cont, SB_Stop } EM_SB; typedef struct _EM_TEMPLATE_INFO { struct { EM_UNIT unit; EM_SB stop; } slot[EM_SLOT_LAST]; const char *name; } EM_TEMPLATE_INFO, *PEM_TEMPLATE_INFO; EM_TEMPLATE_INFO EmTemplates[] = { /* Slot 0 Slot 1 Slot 2 ----------------------------------------------------------*/ { {{M_Unit, SB_Cont}, {I_Unit, SB_Cont}, {I_Unit, SB_Cont}}, ".mii " }, { {{M_Unit, SB_Cont}, {I_Unit, SB_Stop}, {I_Unit, SB_Cont}}, ".mi_i" }, { {{M_Unit, SB_Cont}, {L_Unit, SB_Cont}, {X_Unit, SB_Cont}}, ".mlx " }, { {{No_Unit, SB_Cont}, {No_Unit, SB_Cont}, {No_Unit, SB_Cont}}, "?res " }, { {{M_Unit, SB_Cont}, {M_Unit, SB_Cont}, {I_Unit, SB_Cont}}, ".mmi " }, { {{M_Unit, SB_Stop}, {M_Unit, SB_Cont}, {I_Unit, SB_Cont}}, ".m_mi" }, { {{M_Unit, SB_Cont}, {F_Unit, SB_Cont}, {I_Unit, SB_Cont}}, ".mfi " }, { {{M_Unit, SB_Cont}, {M_Unit, SB_Cont}, {F_Unit, SB_Cont}}, ".mmf " }, { {{M_Unit, SB_Cont}, {I_Unit, SB_Cont}, {B_Unit, SB_Cont}}, ".mib " }, { {{M_Unit, SB_Cont}, {B_Unit, SB_Cont}, {B_Unit, SB_Cont}}, ".mbb " }, { {{No_Unit, SB_Cont}, {No_Unit, SB_Cont}, {No_Unit, SB_Cont}}, "?res " }, { {{B_Unit, SB_Cont}, {B_Unit, SB_Cont}, {B_Unit, SB_Cont}}, ".bbb " }, { {{M_Unit, SB_Cont}, {M_Unit, SB_Cont}, {B_Unit, SB_Cont}}, ".mmb " }, { {{No_Unit, SB_Cont}, {No_Unit, SB_Cont}, {No_Unit, SB_Cont}}, "?res " }, { {{M_Unit, SB_Cont}, {F_Unit, SB_Cont}, {B_Unit, SB_Cont}}, ".mfb " }, { {{No_Unit, SB_Cont}, {No_Unit, SB_Cont}, {No_Unit, SB_Cont}}, "?res " }, }; PEM_TEMPLATE_INFO __inline EmTemplateInfo(EM_template_t Template) { if (Template >= sizeof(EmTemplates)/sizeof(EmTemplates[0])) { return NULL; } return &EmTemplates[Template]; } // EmTemplateInfo() /* ** End of Simple IA64 template info. ******************************************************************* */ /**** disasm - disassemble an IA64 instruction * Purpose: * Disassemble version based on Falcon DISASM.DLL * * Input: * pOffset = pointer to offset to start disassembly * fEAout = if set, include EA (effective address) * * Output: * pOffset = pointer to offset of next instruction * pchDst = pointer to result string * ***************************************************************************/ BOOL Ia64MachineInfo::Disassemble (PADDR poffset, PSTR bufptr, BOOL fEAout) { U64 location; ULONG64 gb_offset; UINT ascii_inst_buf_length; PUINT pascii_inst_buf_length = &ascii_inst_buf_length; UINT bin_inst_buf_length; unsigned int actual_length; ADDR tempaddr; UCHAR * pbin_inst_buf = &g_Ia64Disinstr[0]; static CIa64Disasm* pIa64Disasm = NULL; if (!pIa64Disasm) { pIa64Disasm = new CIa64Disasm(this); if (!pIa64Disasm) { ErrOut("IA64 disassembler initialization failure\n"); return FALSE; } /*if*/ } /*if*/ if (IsIA32InstructionSet()) { WarnOut("The current context is in IA32 mode. " "IA64 disassembly may be inaccurate.\n"); } IEL_ZERO(location); // convert EM address to Gambit internal address. // i.e., move slot number from bit(2,3) to bit(0,1) gb_offset = ((Flat(*poffset) & (~0xf)) | ((Flat(*poffset) & 0xf) >> 2)); IEL_ASSIGNU(location, *(U64*)(&gb_offset)); // convert to bundle address. must be 16 byte aligned ADDRFLAT(&tempaddr, (Flat(*poffset) & ~0xf)); // copy data (if KD, from remote system) to local temp buffer - // g_Ia64Disinstr[] bin_inst_buf_length = GetMemString(&tempaddr, pbin_inst_buf, sizeof(U128)); m_BufStart = (PCHAR)bufptr; m_Buf = m_BufStart; // display 64-bit address sprintf(m_Buf, "%s ", FormatAddr64(Flat(*poffset))); m_Buf += strlen(m_Buf); // TBD display opcode // If we're in verbose mode leave space for the bundle type. if (g_AsmOptions & ASMOPT_VERBOSE) { // Show the bundle type at the beginning of the bundle. if (AddrEqu(tempaddr, *poffset)) { if (bin_inst_buf_length == sizeof(U128)) { PEM_TEMPLATE_INFO Templ = EmTemplateInfo(GET_TEMPLATE(pbin_inst_buf[0])); sprintf(m_Buf, "{ %s", Templ->name); } else { strcpy(m_Buf, "{ ??? "); } } else { strcpy(m_Buf, " "); } m_Buf += strlen(m_Buf); } if (bin_inst_buf_length != sizeof(U128)) { BufferString(" ???????? ????\n"); *m_Buf = '\0'; return FALSE; } *pascii_inst_buf_length = ASCII_BUF_LENGTH; if (!pIa64Disasm->Disassemble( Flat(*poffset), *(CIa64Disasm::SBundle*)pbin_inst_buf, &actual_length, m_Buf, *pascii_inst_buf_length, (fEAout != FALSE))) { ErrOut("Dissassembler failure!!!!\n"); } switch (EM_IL_GET_SLOT_NO(location)) { case 0: IEL_INCU(location); break; case 1: IEL_INCU(location); if ((actual_length) != 2) { break; } /*** else fall-through ***/ case 2: U32 syl_size; IEL_CONVERT1(syl_size, EM_BUNDLE_SIZE-2); IEL_ADDU((location), syl_size, (location)); break; } gb_offset = ((ULONG64)IEL_GETQW0(location)); // convert Gambit internal address to EM address Off(*poffset) = (gb_offset & (~0xf)) | ((gb_offset & 0xf) << 2); NotFlat(*poffset); ComputeFlatAddress(poffset, NULL); m_Buf += strlen(m_Buf); // If this the last instruction of a bundle mark it. if ((Flat(*poffset) & 0xf) == 0) { if (g_AsmOptions & ASMOPT_VERBOSE) { strcpy(m_Buf, "}\n"); m_Buf += strlen(m_Buf); } else { *m_Buf++ = '\n'; } } /* add new line at the end */ *m_Buf++ = '\n'; *m_Buf = '\0'; return TRUE; } // Ia64MachineInfo::Disassemble HRESULT Ia64MachineInfo::NewBreakpoint(DebugClient* Client, ULONG Type, ULONG Id, Breakpoint** RetBp) { HRESULT Status; switch(Type & (DEBUG_BREAKPOINT_CODE | DEBUG_BREAKPOINT_DATA)) { case DEBUG_BREAKPOINT_CODE: *RetBp = new CodeBreakpoint(Client, Id, IMAGE_FILE_MACHINE_IA64); Status = (*RetBp) ? S_OK : E_OUTOFMEMORY; break; case DEBUG_BREAKPOINT_DATA: *RetBp = new Ia64DataBreakpoint(Client, Id); Status = (*RetBp) ? S_OK : E_OUTOFMEMORY; break; default: // Unknown breakpoint type. Status = E_NOINTERFACE; } return Status; } BOOL Ia64MachineInfo::IsBreakpointInstruction(PADDR Addr) { ULONG64 Instr; if (IsIA32InstructionSet()) { return g_X86Machine.IsBreakpointInstruction(Addr); } else { // No need to align for this check. if (GetMemString(Addr, &Instr, sizeof(Instr)) != sizeof(Instr)) { return FALSE; } switch (Flat(*Addr) & 0xf) { case 0: if ((Instr & (INST_SLOT0_MASK)) == (g_Ia64TrapInstr << 5)) { return TRUE; } break; case 4: if ((Instr & (INST_SLOT1_MASK)) == (g_Ia64TrapInstr << 14)) { return TRUE; } break; case 8: if ((Instr & (INST_SLOT2_MASK)) == (g_Ia64TrapInstr << 23)) { return TRUE; } break; } } return FALSE; } HRESULT Ia64MachineInfo::InsertBreakpointInstruction(PUSER_DEBUG_SERVICES Services, ULONG64 Process, ULONG64 Offset, PUCHAR SaveInstr, PULONG64 ChangeStart, PULONG ChangeLen) { ULONG64 Aligned; ULONG Off; ULONG Done; HRESULT Status; // Make sure the storage area has space for both the saved // instruction bundle and some flags. DBG_ASSERT(MAX_BREAKPOINT_LENGTH >= IA64_BP_LEN + sizeof(BOOL)); Aligned = Offset; Off = (ULONG)(Aligned & IA64_BP_ALIGN); Aligned -= Off; *ChangeStart = Aligned; *ChangeLen = IA64_BP_LEN; Status = Services->ReadVirtual(Process, Aligned, SaveInstr, IA64_BP_LEN, &Done); if (Status != S_OK) { return Status; } if (Done != IA64_BP_LEN) { return HRESULT_FROM_WIN32(ERROR_READ_FAULT); } UCHAR TempInstr[IA64_BP_LEN]; ULONG64 UNALIGNED *New = (ULONG64 UNALIGNED *)(TempInstr + Off); PBOOL Mli = (PBOOL)(SaveInstr + IA64_BP_LEN); memcpy(TempInstr, SaveInstr, IA64_BP_LEN); *Mli = FALSE; switch(Off) { case 0: *New = (*New & ~(INST_SLOT0_MASK)) | (g_Ia64TrapInstr << 5); break; case 4: *New = (*New & ~(INST_SLOT1_MASK)) | (g_Ia64TrapInstr << 14); break; case 8: *New = (*New & ~(INST_SLOT2_MASK)) | (g_Ia64TrapInstr << 23); break; default: return E_INVALIDARG; } // If current instruction is // NOT slot 0 check for two-slot MOVL instruction. Reject // request if attempt to set break in slot 2 of MLI template. if (Off != 0) { New = (PULONG64)TempInstr; if (((*New & INST_TEMPL_MASK) >> 1) == 0x2) { if (Off == 4) { // if template= type 2 MLI, change to type 0 *New &= ~((INST_TEMPL_MASK >> 1) << 1); *Mli = TRUE; } else { // set breakpoint at slot 2 of MOVL is illegal return E_UNEXPECTED; } } } Status = Services->WriteVirtual(Process, Aligned, TempInstr, IA64_BP_LEN, &Done); if (Status == S_OK && Done != IA64_BP_LEN) { Status = HRESULT_FROM_WIN32(ERROR_WRITE_FAULT); } return Status; } HRESULT Ia64MachineInfo::RemoveBreakpointInstruction(PUSER_DEBUG_SERVICES Services, ULONG64 Process, ULONG64 Offset, PUCHAR SaveInstr, PULONG64 ChangeStart, PULONG ChangeLen) { ULONG64 Aligned; ULONG Off; ULONG Done; HRESULT Status; Aligned = Offset; Off = (ULONG)(Aligned & IA64_BP_ALIGN); Aligned -= Off; *ChangeStart = Aligned; *ChangeLen = IA64_BP_LEN; UCHAR TempInstr[IA64_BP_LEN]; ULONG64 UNALIGNED *New; ULONG64 UNALIGNED *Old; PBOOL Mli; // Read in memory since adjacent instructions in the same bundle // may have been modified after we save them. We only restore the // content of the slot which has the break instruction inserted. Status = Services->ReadVirtual(Process, Aligned, TempInstr, IA64_BP_LEN, &Done); if (Status != S_OK) { return Status; } if (Done != IA64_BP_LEN) { return HRESULT_FROM_WIN32(ERROR_READ_FAULT); } New = (ULONG64 UNALIGNED *)(TempInstr + Off); Old = (ULONG64 UNALIGNED *)(SaveInstr + Off); Mli = (PBOOL)(SaveInstr + IA64_BP_LEN); switch(Off) { case 0: *New = (*New & ~(INST_SLOT0_MASK)) | (*Old & INST_SLOT0_MASK); break; case 4: *New = (*New & ~(INST_SLOT1_MASK)) | (*Old & INST_SLOT1_MASK); break; case 8: *New = (*New & ~(INST_SLOT2_MASK)) | (*Old & INST_SLOT2_MASK); break; default: return E_INVALIDARG; } // restore template to MLI if displaced instruction was MOVL if (*Mli) { New = (PULONG64)TempInstr; *New &= ~((INST_TEMPL_MASK >> 1) << 1); // set template to MLI *New |= 0x4; } Status = Services->WriteVirtual(Process, Aligned, TempInstr, IA64_BP_LEN, &Done); if (Status == S_OK && Done != IA64_BP_LEN) { Status = HRESULT_FROM_WIN32(ERROR_WRITE_FAULT); } return Status; } void Ia64MachineInfo::AdjustPCPastBreakpointInstruction (PADDR Addr, ULONG BreakType) { DBG_ASSERT(BreakType == DEBUG_BREAKPOINT_CODE); if (IsIA32InstructionSet()) { // // IA32 instruction set // SetPC(AddrAdd(Addr, 1)); } else { // // IA64 instruction set // if ((Flat(*Addr) & 0xf) != 8) { SetPC(AddrAdd(Addr, 4)); } else { SetPC(AddrAdd(Addr, 8)); } } } void Ia64MachineInfo::InsertAllDataBreakpoints (void) { PPROCESS_INFO ProcessSave = g_CurrentProcess; PTHREAD_INFO Thread; // Update thread context for every thread. g_CurrentProcess = g_ProcessHead; while (g_CurrentProcess != NULL) { Thread = g_CurrentProcess->ThreadHead; while (Thread != NULL) { DBG_ASSERT(Thread->NumDataBreaks <= m_MaxDataBreakpoints); BpOut("Thread %d data %d\n", Thread->UserId, Thread->NumDataBreaks); ChangeRegContext(Thread); // The kernel automatically sets PSR.db for the // kernel so this code only needs to manipulate PSR.db // for user-mode debugging. ULONG64 RegIPSR; ULONG RegDBD = REGDBD0; ULONG RegDBDEnd = min(REGDBD7 + 1, REGDBD0 + 2 * m_MaxDataBreakpoints); ULONG RegDBI = REGDBI0; ULONG RegDBIEnd = min(REGDBI7 + 1, REGDBI0 + 2 * m_MaxDataBreakpoints); // Start with all breaks turned off. if (IS_USER_TARGET()) { RegIPSR = GetReg64(STIPSR); RegIPSR &= ~((ULONG64)1 << PSR_DB); } if (Thread->NumDataBreaks > 0) { ULONG i; for (i = 0; i < Thread->NumDataBreaks; i++) { Breakpoint* Bp = Thread->DataBreakBps[i]; ULONG ProcType = Bp->GetProcType(); DBG_ASSERT((ProcType == IMAGE_FILE_MACHINE_IA64) || (ProcType == IMAGE_FILE_MACHINE_I386)); ULONG64 Addr, Control; if (ProcType == IMAGE_FILE_MACHINE_I386) { Addr = (ULONG)Flat(*Bp->GetAddr()); Control = ((X86OnIa64DataBreakpoint*)Bp)->m_Control; } else { Addr = Flat(*Bp->GetAddr()); Control = ((Ia64DataBreakpoint*)Bp)->m_Control; } if (Bp->m_DataAccessType == DEBUG_BREAK_EXECUTE) { BpOut(" ibp %d at %p\n", i, Addr); SetReg64(RegDBI++, Addr); SetReg64(RegDBI++, Control); } else { BpOut(" dbp %d at %p\n", i, Addr); SetReg64(RegDBD++, Addr); SetReg64(RegDBD++, Control); } // iff } // for RegIPSR |= ((ULONG64)1 << PSR_DB); } else if (IS_KERNEL_TARGET()) { } // Make sure unused debug registers are clear. while (RegDBD < RegDBDEnd) { SetReg64(RegDBD++, 0); } while (RegDBI < RegDBIEnd) { SetReg64(RegDBI++, 0); } if (IS_USER_TARGET()) { SetReg64(STIPSR, RegIPSR); } Thread = Thread->Next; } g_CurrentProcess = g_CurrentProcess->Next; } g_CurrentProcess = ProcessSave; if (g_CurrentProcess != NULL) { ChangeRegContext(g_CurrentProcess->CurrentThread); } else { ChangeRegContext(NULL); } } void Ia64MachineInfo::RemoveAllDataBreakpoints (void) { if (IS_USER_TARGET()) { ULONG64 RegIPSR; RegIPSR = GetReg64(STIPSR); RegIPSR &= ~((ULONG64)1 << PSR_DB); SetReg64(STIPSR, RegIPSR); } else { for (UINT i = 1; i < 2 * m_MaxDataBreakpoints; i += 2) { SetReg64(REGDBD0 + i, 0); SetReg64(REGDBI0 + i, 0); } } } ULONG Ia64MachineInfo::IsBreakpointOrStepException (PEXCEPTION_RECORD64 Record, ULONG FirstChance, PADDR BpAddr, PADDR RelAddr) { if (Record->ExceptionCode == STATUS_BREAKPOINT) { // Data breakpoints come in as SINGLE_STEP so // this must be a code breakpoint. return EXBS_BREAKPOINT_CODE; } else if (Record->ExceptionCode == STATUS_SINGLE_STEP) { DBG_ASSERT(Record->NumberParameters >= 5); // Data breakpoints put the faulting address in // the exception information, whereas a true single // step exception sets the address to zero. if (Record->ExceptionInformation[1]) { // This should be read, write or execute interrupt. DBG_ASSERT(Record->ExceptionInformation[4] & (((ULONG64)1 << ISR_X) | ((ULONG64)1 << ISR_W) | ((ULONG64)1 << ISR_R))); ADDRFLAT(BpAddr, Record->ExceptionInformation[1]); return EXBS_BREAKPOINT_DATA; } else if (Record->ExceptionInformation[4] & 0x4) { // Must be taken branch exception if (RelAddr) { // TrapFrame->StIIPA contains actual branch address ADDRFLAT(RelAddr, Record->ExceptionInformation[3]); } return EXBS_STEP_BRANCH; } else { // Must be a real single-step. return EXBS_STEP_INSTRUCTION; } } return EXBS_NONE; } BOOL Ia64MachineInfo::IsCallDisasm (PCSTR Disasm) { return (strstr(Disasm, " br.call") || strstr(Disasm, ")br.call")) && !strstr(Disasm, "=0)"); } BOOL Ia64MachineInfo::IsReturnDisasm (PCSTR Disasm) { return (strstr(Disasm, " br.ret") || strstr(Disasm, ")br.ret")) && !strstr(Disasm, "=0)"); } BOOL Ia64MachineInfo::IsSystemCallDisasm(PCSTR Disasm) { return (strstr(Disasm, " break ") || strstr(Disasm, ")break ")) && strstr(Disasm, " 18000") && !strstr(Disasm, "=0)"); } BOOL Ia64MachineInfo::IsDelayInstruction (PADDR Addr) { return FALSE; // EM does not implement delay slot } void Ia64MachineInfo::GetEffectiveAddr (PADDR Addr) { ErrOut("! IA64 does not set EA during disasm !\n"); ADDRFLAT(Addr, 0); } void Ia64MachineInfo::GetNextOffset(BOOL StepOver, PADDR NextAddr, PULONG NextMachine) { ULONG64 returnvalue; ULONG64 firaddr, syladdr; ADDR fir; ULONG slot; EM_IL location; // Default NextMachine to the same machine. *NextMachine = m_ExecTypes[0]; // Check support for hardware stepping. Older // kernels did not handle it properly. BOOL UseTraceFlag = !IS_KERNEL_TARGET() || (g_KdVersion.Flags & DBGKD_VERS_FLAG_HSS); int instr_length; EM_Decoder_Info info; IEL_ZERO(location); firaddr = GetReg64(STIIP); // get bundle address from IIP ADDRFLAT( &fir, firaddr ); instr_length = GetMemString(&fir, (PUCHAR)&g_Ia64Disinstr, sizeof(U128)); slot = (ULONG)((GetReg64(STIPSR) >> PSR_RI) & 0x3); // get slot number from ISR.ei syladdr = firaddr | slot ; IEL_ASSIGNU(location, *(U64*)(&syladdr)); // assume next slot is the target address // convert bundle address - firaddr to EM address // the slot# of Gambit internal address is at bit(0,1) // EM address slot# is at bit(2,3) switch (slot) { case 0: returnvalue = firaddr + 4; break; case 1: returnvalue = firaddr + 8; break; case 2: returnvalue = firaddr + 16; break; default: WarnOut("GetNextOffset: illegal EM address: %s", FormatAddr64(firaddr)); } if (!InitDecoder()) { ErrOut("EM decoder library(DECEM.DLL) not active\n"); // We can't analyze the current instruction to // determine how and where to step so just rely // on hardware tracing if possible. if (UseTraceFlag) { returnvalue = OFFSET_TRACE; } } else { EM_Decoder_Err err = (*pfnEM_Decoder_decode)(DecoderId, g_Ia64Disinstr, instr_length, location, &info); if (err == EM_DECODER_NO_ERROR) { #if 0 dprintf("GNO inst at %I64x:%d is %d\n", firaddr, slot, info.inst); #endif if (info.EM_info.em_bundle_info.b_template == EM_template_mlx && slot == 1) { // Increment return offset since L+X instructions take // two instruction slots. switch (returnvalue & 0xf) { case 8: returnvalue = returnvalue + 8; break; default: WarnOut("GetNextOffset: illegal L+X address: %s", FormatAddr64(firaddr)); break; } } switch (info.inst) { // break imm21 // case EM_BREAK_I_IMM21: case EM_BREAK_M_IMM21: case EM_BREAK_B_IMM21: case EM_BREAK_F_IMM21: // Stepping over a syscall instruction must set the breakpoint // at the caller's return address, not the inst after the // syscall. Stepping into a syscall is not allowed // from user-mode. if (!StepOver && IS_KERNEL_TARGET() && UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } if (info.src1.type == EM_DECODER_IMMEDIATE) { if (info.src1.imm_info.imm_type == EM_DECODER_IMM_UNSIGNED) { if (((IEL_GETDW0(info.src1.imm_info.val64) & 0x1c0000) == IA64_BREAK_SYSCALL_BASE) || ((IEL_GETDW0(info.src1.imm_info.val64) & 0x1c0000) == IA64_BREAK_FASTSYS_BASE)) { returnvalue = GetReg64(BRRP); } } } break; // // IP-Relative call B3 - br.call b1=target25 // case EM_BR_CALL_SPNT_FEW_B1_TARGET25: case EM_BR_CALL_SPNT_MANY_B1_TARGET25: case EM_BR_CALL_SPTK_FEW_B1_TARGET25: case EM_BR_CALL_SPTK_MANY_B1_TARGET25: case EM_BR_CALL_DPNT_FEW_B1_TARGET25: case EM_BR_CALL_DPNT_MANY_B1_TARGET25: case EM_BR_CALL_DPTK_FEW_B1_TARGET25: case EM_BR_CALL_DPTK_MANY_B1_TARGET25: case EM_BR_CALL_SPNT_FEW_CLR_B1_TARGET25: case EM_BR_CALL_SPNT_MANY_CLR_B1_TARGET25: case EM_BR_CALL_SPTK_FEW_CLR_B1_TARGET25: case EM_BR_CALL_SPTK_MANY_CLR_B1_TARGET25: case EM_BR_CALL_DPNT_FEW_CLR_B1_TARGET25: case EM_BR_CALL_DPNT_MANY_CLR_B1_TARGET25: case EM_BR_CALL_DPTK_FEW_CLR_B1_TARGET25: case EM_BR_CALL_DPTK_MANY_CLR_B1_TARGET25: // 64-bit target L+X forms. case EM_BRL_CALL_SPTK_FEW_B1_TARGET64: case EM_BRL_CALL_SPTK_MANY_B1_TARGET64: case EM_BRL_CALL_SPNT_FEW_B1_TARGET64: case EM_BRL_CALL_SPNT_MANY_B1_TARGET64: case EM_BRL_CALL_DPTK_FEW_B1_TARGET64: case EM_BRL_CALL_DPTK_MANY_B1_TARGET64: case EM_BRL_CALL_DPNT_FEW_B1_TARGET64: case EM_BRL_CALL_DPNT_MANY_B1_TARGET64: case EM_BRL_CALL_SPTK_FEW_CLR_B1_TARGET64: case EM_BRL_CALL_SPTK_MANY_CLR_B1_TARGET64: case EM_BRL_CALL_SPNT_FEW_CLR_B1_TARGET64: case EM_BRL_CALL_SPNT_MANY_CLR_B1_TARGET64: case EM_BRL_CALL_DPTK_FEW_CLR_B1_TARGET64: case EM_BRL_CALL_DPTK_MANY_CLR_B1_TARGET64: case EM_BRL_CALL_DPNT_FEW_CLR_B1_TARGET64: case EM_BRL_CALL_DPNT_MANY_CLR_B1_TARGET64: if (StepOver) { // // Step over the subroutine call; // break; } // fall through // // // IP-Relative branch B1 - br.cond target25 // case EM_BR_COND_SPNT_FEW_TARGET25: case EM_BR_COND_SPNT_MANY_TARGET25: case EM_BR_COND_SPTK_FEW_TARGET25: case EM_BR_COND_SPTK_MANY_TARGET25: case EM_BR_COND_DPNT_FEW_TARGET25: case EM_BR_COND_DPNT_MANY_TARGET25: case EM_BR_COND_DPTK_FEW_TARGET25: case EM_BR_COND_DPTK_MANY_TARGET25: case EM_BR_COND_SPNT_FEW_CLR_TARGET25: case EM_BR_COND_SPNT_MANY_CLR_TARGET25: case EM_BR_COND_SPTK_FEW_CLR_TARGET25: case EM_BR_COND_SPTK_MANY_CLR_TARGET25: case EM_BR_COND_DPNT_FEW_CLR_TARGET25: case EM_BR_COND_DPNT_MANY_CLR_TARGET25: case EM_BR_COND_DPTK_FEW_CLR_TARGET25: case EM_BR_COND_DPTK_MANY_CLR_TARGET25: // 64-bit target L+X forms. case EM_BRL_COND_SPTK_FEW_TARGET64: case EM_BRL_COND_SPTK_MANY_TARGET64: case EM_BRL_COND_SPNT_FEW_TARGET64: case EM_BRL_COND_SPNT_MANY_TARGET64: case EM_BRL_COND_DPTK_FEW_TARGET64: case EM_BRL_COND_DPTK_MANY_TARGET64: case EM_BRL_COND_DPNT_FEW_TARGET64: case EM_BRL_COND_DPNT_MANY_TARGET64: case EM_BRL_COND_SPTK_FEW_CLR_TARGET64: case EM_BRL_COND_SPTK_MANY_CLR_TARGET64: case EM_BRL_COND_SPNT_FEW_CLR_TARGET64: case EM_BRL_COND_SPNT_MANY_CLR_TARGET64: case EM_BRL_COND_DPTK_FEW_CLR_TARGET64: case EM_BRL_COND_DPTK_MANY_CLR_TARGET64: case EM_BRL_COND_DPNT_FEW_CLR_TARGET64: case EM_BRL_COND_DPNT_MANY_CLR_TARGET64: if (UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } if ((info.pred.valid == TRUE) && (info.pred.type == EM_DECODER_PRED_REG)) { if ((GetReg64(PREDS) >> info.pred.value) & 0x1) // if PR[qp] = 1 { if (info.src1.type == EM_DECODER_IP_RELATIVE) { // imm_info.val64 is sign-extended (imm21 << 4) returnvalue = (IEL_GETQW0(info.src1.imm_info.val64)) + firaddr; } } } break; // - br.wexit target25 case EM_BR_WEXIT_SPNT_FEW_TARGET25: case EM_BR_WEXIT_SPNT_MANY_TARGET25: case EM_BR_WEXIT_SPTK_FEW_TARGET25: case EM_BR_WEXIT_SPTK_MANY_TARGET25: case EM_BR_WEXIT_DPNT_FEW_TARGET25: case EM_BR_WEXIT_DPNT_MANY_TARGET25: case EM_BR_WEXIT_DPTK_FEW_TARGET25: case EM_BR_WEXIT_DPTK_MANY_TARGET25: case EM_BR_WEXIT_SPNT_FEW_CLR_TARGET25: case EM_BR_WEXIT_SPNT_MANY_CLR_TARGET25: case EM_BR_WEXIT_SPTK_FEW_CLR_TARGET25: case EM_BR_WEXIT_SPTK_MANY_CLR_TARGET25: case EM_BR_WEXIT_DPNT_FEW_CLR_TARGET25: case EM_BR_WEXIT_DPNT_MANY_CLR_TARGET25: case EM_BR_WEXIT_DPTK_FEW_CLR_TARGET25: case EM_BR_WEXIT_DPTK_MANY_CLR_TARGET25: if (UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } if ((info.pred.valid == TRUE) && (info.pred.type == EM_DECODER_PRED_REG)) { if ((GetReg64(PREDS) >> info.pred.value) & 0x1) // if PR[qp] = 1, epilog { if (GetReg64(APEC) <= 1) // WEXIT; branch if EC = 0 or 1 { if (info.src1.type == EM_DECODER_IP_RELATIVE) { returnvalue = (IEL_GETQW0(info.src1.imm_info.val64)) + firaddr; } } } } // if PR[qp] = 0, kernel; fall-thru break; // - br.wtop target25 case EM_BR_WTOP_SPNT_FEW_TARGET25: case EM_BR_WTOP_SPNT_MANY_TARGET25: case EM_BR_WTOP_SPTK_FEW_TARGET25: case EM_BR_WTOP_SPTK_MANY_TARGET25: case EM_BR_WTOP_DPNT_FEW_TARGET25: case EM_BR_WTOP_DPNT_MANY_TARGET25: case EM_BR_WTOP_DPTK_FEW_TARGET25: case EM_BR_WTOP_DPTK_MANY_TARGET25: case EM_BR_WTOP_SPNT_FEW_CLR_TARGET25: case EM_BR_WTOP_SPNT_MANY_CLR_TARGET25: case EM_BR_WTOP_SPTK_FEW_CLR_TARGET25: case EM_BR_WTOP_SPTK_MANY_CLR_TARGET25: case EM_BR_WTOP_DPNT_FEW_CLR_TARGET25: case EM_BR_WTOP_DPNT_MANY_CLR_TARGET25: case EM_BR_WTOP_DPTK_FEW_CLR_TARGET25: case EM_BR_WTOP_DPTK_MANY_CLR_TARGET25: if (UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } if ((info.pred.valid == TRUE) && (info.pred.type == EM_DECODER_PRED_REG)) { if ((GetReg64(PREDS) >> info.pred.value) & 0x1) // if PR[qp] = 1, epilog { if (GetReg64(APEC) > 1) // WTOP; branch if EC > 1 { if (info.src1.type == EM_DECODER_IP_RELATIVE) { returnvalue = (IEL_GETQW0(info.src1.imm_info.val64)) + firaddr; } } } } else // if PR[qp] = 0, kernel; branch { if (info.src1.type == EM_DECODER_IP_RELATIVE) { returnvalue = (IEL_GETQW0(info.src1.imm_info.val64)) + firaddr; } } break; // // IP-Relative counted branch B2 - br.cloop target25 // case EM_BR_CLOOP_SPNT_FEW_TARGET25: case EM_BR_CLOOP_SPNT_MANY_TARGET25: case EM_BR_CLOOP_SPTK_FEW_TARGET25: case EM_BR_CLOOP_SPTK_MANY_TARGET25: case EM_BR_CLOOP_DPNT_FEW_TARGET25: case EM_BR_CLOOP_DPNT_MANY_TARGET25: case EM_BR_CLOOP_DPTK_FEW_TARGET25: case EM_BR_CLOOP_DPTK_MANY_TARGET25: case EM_BR_CLOOP_SPNT_FEW_CLR_TARGET25: case EM_BR_CLOOP_SPNT_MANY_CLR_TARGET25: case EM_BR_CLOOP_SPTK_FEW_CLR_TARGET25: case EM_BR_CLOOP_SPTK_MANY_CLR_TARGET25: case EM_BR_CLOOP_DPNT_FEW_CLR_TARGET25: case EM_BR_CLOOP_DPNT_MANY_CLR_TARGET25: case EM_BR_CLOOP_DPTK_FEW_CLR_TARGET25: case EM_BR_CLOOP_DPTK_MANY_CLR_TARGET25: if (UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } if (GetReg64(APLC)) // branch if LC != 0 { if (info.src1.type == EM_DECODER_IP_RELATIVE) { returnvalue = (IEL_GETQW0(info.src1.imm_info.val64)) + firaddr; } } break; // - br.cexit target25 case EM_BR_CEXIT_SPNT_FEW_TARGET25: case EM_BR_CEXIT_SPNT_MANY_TARGET25: case EM_BR_CEXIT_SPTK_FEW_TARGET25: case EM_BR_CEXIT_SPTK_MANY_TARGET25: case EM_BR_CEXIT_DPNT_FEW_TARGET25: case EM_BR_CEXIT_DPNT_MANY_TARGET25: case EM_BR_CEXIT_DPTK_FEW_TARGET25: case EM_BR_CEXIT_DPTK_MANY_TARGET25: case EM_BR_CEXIT_SPNT_FEW_CLR_TARGET25: case EM_BR_CEXIT_SPNT_MANY_CLR_TARGET25: case EM_BR_CEXIT_SPTK_FEW_CLR_TARGET25: case EM_BR_CEXIT_SPTK_MANY_CLR_TARGET25: case EM_BR_CEXIT_DPNT_FEW_CLR_TARGET25: case EM_BR_CEXIT_DPNT_MANY_CLR_TARGET25: case EM_BR_CEXIT_DPTK_FEW_CLR_TARGET25: case EM_BR_CEXIT_DPTK_MANY_CLR_TARGET25: if (UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } if (!GetReg64(APLC)) // if LC = 0, epilog { if (GetReg64(APEC) <= 1) // CEXIT; branch if EC = 0 or 1 { if (info.src1.type == EM_DECODER_IP_RELATIVE) { returnvalue = (IEL_GETQW0(info.src1.imm_info.val64)) + firaddr; } } } // if LC > 0, kernel; fall-thru break; // - br.ctop target25 case EM_BR_CTOP_SPNT_FEW_TARGET25: case EM_BR_CTOP_SPNT_MANY_TARGET25: case EM_BR_CTOP_SPTK_FEW_TARGET25: case EM_BR_CTOP_SPTK_MANY_TARGET25: case EM_BR_CTOP_DPNT_FEW_TARGET25: case EM_BR_CTOP_DPNT_MANY_TARGET25: case EM_BR_CTOP_DPTK_FEW_TARGET25: case EM_BR_CTOP_DPTK_MANY_TARGET25: case EM_BR_CTOP_SPNT_FEW_CLR_TARGET25: case EM_BR_CTOP_SPNT_MANY_CLR_TARGET25: case EM_BR_CTOP_SPTK_FEW_CLR_TARGET25: case EM_BR_CTOP_SPTK_MANY_CLR_TARGET25: case EM_BR_CTOP_DPNT_FEW_CLR_TARGET25: case EM_BR_CTOP_DPNT_MANY_CLR_TARGET25: case EM_BR_CTOP_DPTK_FEW_CLR_TARGET25: case EM_BR_CTOP_DPTK_MANY_CLR_TARGET25: if (!GetReg64(APLC)) // if LC = 0, epilog { if (GetReg64(APEC) > 1) // CTOP; branch if EC > 1 { if (info.src1.type == EM_DECODER_IP_RELATIVE) { returnvalue = (IEL_GETQW0(info.src1.imm_info.val64)) + firaddr; } } } else // if LC > 0, kernel; branch { if (info.src1.type == EM_DECODER_IP_RELATIVE) { returnvalue = (IEL_GETQW0(info.src1.imm_info.val64)) + firaddr; } } break; // // Indirect call B5 - br.call b1=b2 // case EM_BR_CALL_SPNT_FEW_B1_B2: case EM_BR_CALL_SPNT_MANY_B1_B2: case EM_BR_CALL_SPTK_FEW_B1_B2: case EM_BR_CALL_SPTK_MANY_B1_B2: case EM_BR_CALL_DPNT_FEW_B1_B2: case EM_BR_CALL_DPNT_MANY_B1_B2: case EM_BR_CALL_DPTK_FEW_B1_B2: case EM_BR_CALL_DPTK_MANY_B1_B2: case EM_BR_CALL_SPNT_FEW_CLR_B1_B2: case EM_BR_CALL_SPNT_MANY_CLR_B1_B2: case EM_BR_CALL_SPTK_FEW_CLR_B1_B2: case EM_BR_CALL_SPTK_MANY_CLR_B1_B2: case EM_BR_CALL_DPNT_FEW_CLR_B1_B2: case EM_BR_CALL_DPNT_MANY_CLR_B1_B2: case EM_BR_CALL_DPTK_FEW_CLR_B1_B2: case EM_BR_CALL_DPTK_MANY_CLR_B1_B2: if (StepOver) { // // Step over the subroutine call; // break; } // fall through // // // Indirect branch B4 - br.ia b2 // case EM_BR_IA_SPNT_FEW_B2: case EM_BR_IA_SPNT_MANY_B2: case EM_BR_IA_SPTK_FEW_B2: case EM_BR_IA_SPTK_MANY_B2: case EM_BR_IA_DPNT_FEW_B2: case EM_BR_IA_DPNT_MANY_B2: case EM_BR_IA_DPTK_FEW_B2: case EM_BR_IA_DPTK_MANY_B2: case EM_BR_IA_SPNT_FEW_CLR_B2: case EM_BR_IA_SPNT_MANY_CLR_B2: case EM_BR_IA_SPTK_FEW_CLR_B2: case EM_BR_IA_SPTK_MANY_CLR_B2: case EM_BR_IA_DPNT_FEW_CLR_B2: case EM_BR_IA_DPNT_MANY_CLR_B2: case EM_BR_IA_DPTK_FEW_CLR_B2: case EM_BR_IA_DPTK_MANY_CLR_B2: if (UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } // Unconditional branch to IA32 so the machine // changes. *NextMachine = IMAGE_FILE_MACHINE_I386; // fall through // // - br.cond b2 case EM_BR_COND_SPNT_FEW_B2: case EM_BR_COND_SPNT_MANY_B2: case EM_BR_COND_SPTK_FEW_B2: case EM_BR_COND_SPTK_MANY_B2: case EM_BR_COND_DPNT_FEW_B2: case EM_BR_COND_DPNT_MANY_B2: case EM_BR_COND_DPTK_FEW_B2: case EM_BR_COND_DPTK_MANY_B2: case EM_BR_COND_SPNT_FEW_CLR_B2: case EM_BR_COND_SPNT_MANY_CLR_B2: case EM_BR_COND_SPTK_FEW_CLR_B2: case EM_BR_COND_SPTK_MANY_CLR_B2: case EM_BR_COND_DPNT_FEW_CLR_B2: case EM_BR_COND_DPNT_MANY_CLR_B2: case EM_BR_COND_DPTK_FEW_CLR_B2: case EM_BR_COND_DPTK_MANY_CLR_B2: // If we're in user-mode we can't necessarily // use hardware stepping here because this // may be a branch into the EPC region for // a system call that we do not want to trace. if (!StepOver && IS_KERNEL_TARGET() && UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } if ((info.pred.valid == TRUE) && (info.pred.type == EM_DECODER_PRED_REG)) { if ((GetReg64(PREDS) >> info.pred.value) & 0x1) // if PR[qp] = 1 { if (info.src1.type == EM_DECODER_REGISTER) { if (info.src1.reg_info.type == EM_DECODER_BR_REG) { returnvalue = GetReg64(info.src1.reg_info.value + BRRP); // Check for syscall (IA64_MM_EPC_VA) then // return address is in B0 if (!IS_KERNEL_TARGET() && (returnvalue == IA64_MM_EPC_VA + 0x20)) { returnvalue = GetReg64(BRRP); } } } } } break; // - br.ret b2 case EM_BR_RET_SPNT_FEW_B2: case EM_BR_RET_SPNT_MANY_B2: case EM_BR_RET_SPTK_FEW_B2: case EM_BR_RET_SPTK_MANY_B2: case EM_BR_RET_DPNT_FEW_B2: case EM_BR_RET_DPNT_MANY_B2: case EM_BR_RET_DPTK_FEW_B2: case EM_BR_RET_DPTK_MANY_B2: case EM_BR_RET_SPNT_FEW_CLR_B2: case EM_BR_RET_SPNT_MANY_CLR_B2: case EM_BR_RET_SPTK_FEW_CLR_B2: case EM_BR_RET_SPTK_MANY_CLR_B2: case EM_BR_RET_DPNT_FEW_CLR_B2: case EM_BR_RET_DPNT_MANY_CLR_B2: case EM_BR_RET_DPTK_FEW_CLR_B2: case EM_BR_RET_DPTK_MANY_CLR_B2: if (UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } if ((info.pred.valid == TRUE) && (info.pred.type == EM_DECODER_PRED_REG)) { if ((GetReg64(PREDS) >> info.pred.value) & 0x1) // if PR[qp] = 1 { if (info.src1.type == EM_DECODER_REGISTER) { if (info.src1.reg_info.type == EM_DECODER_BR_REG) { returnvalue = GetReg64(info.src1.reg_info.value + BRRP); } } } } break; // chk always branches under debugger case EM_CHK_S_I_R2_TARGET25: case EM_CHK_S_M_R2_TARGET25: case EM_CHK_S_F2_TARGET25: case EM_CHK_A_CLR_R1_TARGET25: case EM_CHK_A_CLR_F1_TARGET25: case EM_CHK_A_NC_R1_TARGET25: case EM_CHK_A_NC_F1_TARGET25: if (UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } if ((info.pred.valid == TRUE) && (info.pred.type == EM_DECODER_PRED_REG)) { if ((GetReg64(PREDS) >> info.pred.value) & 0x1) // if PR[qp] = 1 { returnvalue = IEL_GETQW0(info.src2.imm_info.val64) + firaddr; } } break; default: if (UseTraceFlag) { returnvalue = OFFSET_TRACE; break; } break; } } else if (UseTraceFlag) { // We can't analyze the current instruction to // determine how and where to step so just rely // on hardware tracing if possible. returnvalue = OFFSET_TRACE; } else { ErrOut("em_decoder_decode: %s\n", (*pfnEM_Decoder_err_msg)((EM_Decoder_Err) err)); } } ADDRFLAT( NextAddr, returnvalue ); } BOOL Ia64MachineInfo::GetPrefixedSymbolOffset(ULONG64 SymOffset, ULONG Flags, PULONG64 PrefixedSymOffset) { ULONG64 EntryPoint; ULONG64 HalfBundle; if (g_Target->ReadPointer(this, SymOffset, &EntryPoint) != S_OK) { if (Flags & GETPREF_VERBOSE) { ErrOut("Ia64MachineInfo::GetPrefixedSymbolOffset: " "Unable to read IA64 PLABEL entry point @ 0x%I64x\n", SymOffset); } return FALSE; } *PrefixedSymOffset = EntryPoint; if (!ReadVirt(EntryPoint, HalfBundle)) { if (Flags & GETPREF_VERBOSE) { WarnOut("Ia64MachineInfo::GetPrefixedSymbolOffset: " "Reading half bundle @ 0x%I64x failed\n", EntryPoint); } } else { PEM_TEMPLATE_INFO TemplInfo; TemplInfo = EmTemplateInfo(GET_TEMPLATE(HalfBundle)); if (TemplInfo && (TemplInfo->slot[0].unit != No_Unit)) { #if 0 dprintf("Ia64MachineInfo::GetPrefixedSymbolOffset: " "Seems to be a valid bundle: %s.\n", TemplInfo->name); #endif } else if (Flags & GETPREF_VERBOSE) { WarnOut("Ia64MachineInfo::GetPrefixedSymbolOffset: " "Read IA64 PLABEL entry point @ 0xI64x is NOT " "a valid bundle...\n", EntryPoint); } } return TRUE; } void Ia64MachineInfo::IncrementBySmallestInstruction (PADDR Addr) { if ((Flat(*Addr) & 0xf) == 8) { AddrAdd(Addr, 8); } else { AddrAdd(Addr, 4); } } void Ia64MachineInfo::DecrementBySmallestInstruction (PADDR Addr) { if ((Flat(*Addr) & 0xf) == 0) { AddrSub(Addr, 8); } else { AddrSub(Addr, 4); } } void Ia64MachineInfo::PrintStackFrameAddressesTitle(ULONG Flags) { if (Flags & DEBUG_STACK_FRAME_ADDRESSES_RA_ONLY) { MachineInfo::PrintStackFrameAddressesTitle(Flags); } else { PrintMultiPtrTitle("Child-SP", 1); PrintMultiPtrTitle("Child-BSP", 1); PrintMultiPtrTitle("RetAddr", 1); } } void Ia64MachineInfo::PrintStackFrameAddresses(ULONG Flags, PDEBUG_STACK_FRAME StackFrame) { if (Flags & DEBUG_STACK_FRAME_ADDRESSES_RA_ONLY) { MachineInfo::PrintStackFrameAddresses(Flags, StackFrame); } else { dprintf("%s %s %s ", FormatAddr64(StackFrame->StackOffset), FormatAddr64(StackFrame->FrameOffset), FormatAddr64(StackFrame->ReturnOffset)); } } void Ia64MachineInfo::PrintStackArgumentsTitle(ULONG Flags) { if (Flags & DEBUG_STACK_NONVOLATILE_REGISTERS) { return; } MachineInfo::PrintStackArgumentsTitle(Flags); } void Ia64MachineInfo::PrintStackArguments(ULONG Flags, PDEBUG_STACK_FRAME StackFrame) { if (Flags & DEBUG_STACK_NONVOLATILE_REGISTERS) { return; } MachineInfo::PrintStackArguments(Flags, StackFrame); } void Ia64MachineInfo::PrintStackNonvolatileRegisters(ULONG Flags, PDEBUG_STACK_FRAME StackFrame, PCROSS_PLATFORM_CONTEXT Context, ULONG FrameNum) { ULONGLONG Registers[96+2]; ULONGLONG RegisterHome = Context->IA64Context.RsBSP; ULONG RegisterCount; ULONG RegisterNumber; ULONG ReadLength; ULONG i; i = (ULONG)Context->IA64Context.StIFS & 0x3fff; if (FrameNum = 0) { RegisterCount = i & 0x7f; } else { RegisterCount = (i >> 7) & 0x7f; } // Sanity. if (RegisterCount > 96) { return; } if (RegisterHome & 3) { return; } #if 0 // // This is only for debugging this function. // dprintf(" IFS %016I64x PFS %016I64x\n", Context->IA64Context.StIFS, Context->IA64Context.RsPFS); #endif if (RegisterCount == 0) { #if 0 // // // // Not much point doing anything in this case. // // // // dprintf("\n"); // return; #endif // Display at least 4 registers RegisterCount = 4; } // // Calculate the number of registers to read from the // RSE stack. For every 63 registers there will be at // at least one NaT collection register, depending on // where we start, there may be another one. // // First, starting at the current BSP, if we cross a 64 (0x40) // boundry, then we have an extra. // ReadLength = (((((ULONG)Context->IA64Context.RsBSP) >> 3) & 0x1f) + RegisterCount) >> 6; // // Add 1 for every 63 registers. // ReadLength = (RegisterCount / 63) + RegisterCount; ReadLength *= sizeof(ULONGLONG); // // Read the registers for this frame. // if (!SwReadMemory(g_CurrentProcess->Handle, RegisterHome, Registers, ReadLength, &i)) { // // This shouldn't have happened. // ErrOut("-- Couldn't read registers BSP=%I64x, length %d.\n", RegisterHome, ReadLength); return; } // // Note: the following code should be altered to understand // NaTs as they come from the register stack (currently // it ignores them). // RegisterNumber = 32; for (i = 0; RegisterCount; RegisterHome += sizeof(ULONGLONG), i++) { // // For now, just skip NaT collection registers. Every // 64th entry is a NaT collection register and the RSE // stack is nicely aligned so any entry at an address // ending in 63*8 is a NaT entry. // // 63 * 8 == 0x3f << 3 == 0x1f8 // if ((RegisterHome & 0x1f8) == 0x1f8) { continue; } if ((RegisterNumber & 3) == 0) { if (RegisterNumber <= 99) { dprintf(" "); } dprintf("r%d", RegisterNumber); } dprintf(" %s", FormatAddr64(Registers[i])); if ((RegisterNumber & 3) == 3) { dprintf("\n"); } RegisterNumber++; RegisterCount--; } if ((RegisterNumber & 3) != 0) { dprintf("\n"); } dprintf("\n"); }