⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isa_desc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻
📖 第 1 页 / 共 5 页
字号:
	  public:	    /// Constructor	    EAComp(MachInst machInst);            %(BasicExecDeclare)s	};	/**	 * "Fake" memory access instruction class for "%(mnemonic)s".	 */	class MemAcc : public %(base_class)s	{	  public:	    /// Constructor	    MemAcc(MachInst machInst);            %(BasicExecDeclare)s	};      public:	/// Constructor.	%(class_name)s(MachInst machInst);	%(BasicExecDeclare)s    };}};def template LoadStoreConstructor {{    /** TODO: change op_class to AddrGenOp or something (requires     * creating new member of OpClass enum in op_class.hh, updating     * config files, etc.). */    inline %(class_name)s::EAComp::EAComp(MachInst machInst)	: %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)    {	%(ea_constructor)s;    }    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)	: %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)    {	%(memacc_constructor)s;    }    inline %(class_name)s::%(class_name)s(MachInst machInst)	 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,			  new EAComp(machInst), new MemAcc(machInst))    {	%(constructor)s;    }}};def template EACompExecute {{    Fault    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,				   Trace::InstRecord *traceData) const    {	Addr EA;	Fault fault = No_Fault;	%(fp_enable_check)s;	%(op_decl)s;	%(op_rd)s;	%(code)s;	if (fault == No_Fault) {	    %(op_wb)s;	    xc->setEA(EA);	}	return fault;    }}};def template MemAccExecute {{    Fault    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,				   Trace::InstRecord *traceData) const    {	Addr EA;	Fault fault = No_Fault;	%(fp_enable_check)s;	%(op_decl)s;	%(op_nonmem_rd)s;	EA = xc->getEA();		if (fault == No_Fault) {	    %(op_mem_rd)s;	    %(code)s;	}	if (fault == No_Fault) {	    %(op_mem_wb)s;	}	if (fault == No_Fault) {	    %(postacc_code)s;	}	if (fault == No_Fault) {	    %(op_nonmem_wb)s;	}	return fault;    }}};def template LoadStoreExecute {{    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,				  Trace::InstRecord *traceData) const    {	Addr EA;	Fault fault = No_Fault;	%(fp_enable_check)s;	%(op_decl)s;	%(op_nonmem_rd)s;	%(ea_code)s;	if (fault == No_Fault) {	    %(op_mem_rd)s;	    %(memacc_code)s;	}	if (fault == No_Fault) {	    %(op_mem_wb)s;	}	if (fault == No_Fault) {	    %(postacc_code)s;	}	if (fault == No_Fault) {	    %(op_nonmem_wb)s;	}	return fault;    }}};def template PrefetchExecute {{    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,				  Trace::InstRecord *traceData) const    {	Addr EA;	Fault fault = No_Fault;	%(fp_enable_check)s;	%(op_decl)s;	%(op_nonmem_rd)s;	%(ea_code)s;	if (fault == No_Fault) {	    xc->prefetch(EA, memAccessFlags);	}	return No_Fault;    }}};// load instructions use Ra as dest, so check for// Ra == 31 to detect nopsdef template LoadNopCheckDecode {{ {     AlphaStaticInst *i = new %(class_name)s(machInst);     if (RA == 31) {	 i = makeNop(i);     }     return i; }}};// for some load instructions, Ra == 31 indicates a prefetch (not a nop)def template LoadPrefetchCheckDecode {{ {     if (RA != 31) {	 return new %(class_name)s(machInst);     }     else {	 return new %(class_name)sPrefetch(machInst);     } }}};let {{def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '',		  base_class = 'MemoryDisp32', flags = [],		  decode_template = BasicDecode,		  exec_template = LoadStoreExecute):    # Segregate flags into instruction flags (handled by InstObjParams)    # and memory access flags (handled here).    # Would be nice to autogenerate this list, but oh well.    valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE']    mem_flags =  [f for f in flags if f in valid_mem_flags]    inst_flags = [f for f in flags if f not in valid_mem_flags]    # add hook to get effective addresses into execution trace output.    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'    # generate code block objects    ea_cblk = CodeBlock(ea_code)    memacc_cblk = CodeBlock(memacc_code)    postacc_cblk = CodeBlock(postacc_code)    # Some CPU models execute the memory operation as an atomic unit,    # while others want to separate them into an effective address    # computation and a memory access operation.  As a result, we need    # to generate three StaticInst objects.  Note that the latter two    # are nested inside the larger "atomic" one.    # generate InstObjParams for EAComp object    ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)        # generate InstObjParams for MemAcc object    memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)    # in the split execution model, the MemAcc portion is responsible    # for the post-access code.    memacc_iop.postacc_code = postacc_cblk.code    # generate InstObjParams for unified execution    cblk = CodeBlock(ea_code + memacc_code + postacc_code)    iop = InstObjParams(name, Name, base_class, cblk, inst_flags)    iop.ea_constructor = ea_cblk.constructor    iop.ea_code = ea_cblk.code    iop.memacc_constructor = memacc_cblk.constructor    iop.memacc_code = memacc_cblk.code    iop.postacc_code = postacc_cblk.code    if mem_flags:        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'        iop.constructor += s        memacc_iop.constructor += s    # (header_output, decoder_output, decode_block, exec_output)    return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),	    decode_template.subst(iop),            EACompExecute.subst(ea_iop)            + MemAccExecute.subst(memacc_iop)            + exec_template.subst(iop))}};def format LoadOrNop(ea_code, memacc_code, *flags) {{    (header_output, decoder_output, decode_block, exec_output) = \        LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,                      decode_template = LoadNopCheckDecode)}};// Note that the flags passed in apply only to the prefetch versiondef format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{    # declare the load instruction object and generate the decode block    (header_output, decoder_output, decode_block, exec_output) = \	LoadStoreBase(name, Name, ea_code, memacc_code,		      decode_template = LoadPrefetchCheckDecode)    # Declare the prefetch instruction object.    # convert flags from tuple to list to make them mutable    pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT']    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \	LoadStoreBase(name, Name + 'Prefetch', ea_code, '',		      flags = pf_flags, exec_template = PrefetchExecute)    header_output += pf_header_output    decoder_output += pf_decoder_output    exec_output += pf_exec_output}};def format Store(ea_code, memacc_code, *flags) {{    (header_output, decoder_output, decode_block, exec_output) = \        LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags)}};def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{    (header_output, decoder_output, decode_block, exec_output) = \        LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code,                      flags = flags)}};// Use 'MemoryNoDisp' as base: for wh64, fetch, ecbdef format MiscPrefetch(ea_code, memacc_code, *flags) {{    (header_output, decoder_output, decode_block, exec_output) = \        LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,                      base_class = 'MemoryNoDisp')}};//////////////////////////////////////////////////////////////////////// Control transfer instructions//output header {{    /**     * Base class for instructions whose disassembly is not purely a     * function of the machine instruction (i.e., it depends on the     * PC).  This class overrides the disassemble() method to check     * the PC and symbol table values before re-using a cached     * disassembly string.  This is necessary for branches and jumps,     * where the disassembly string includes the target address (which     * may depend on the PC and/or symbol table).     */    class PCDependentDisassembly : public AlphaStaticInst    {      protected:	/// Cached program counter from last disassembly	mutable Addr cachedPC;	/// Cached symbol table pointer from last disassembly	mutable const SymbolTable *cachedSymtab;	/// Constructor	PCDependentDisassembly(const char *mnem, MachInst _machInst,			       OpClass __opClass)	    : AlphaStaticInst(mnem, _machInst, __opClass),	      cachedPC(0), cachedSymtab(0)	{	}	const std::string &	disassemble(Addr pc, const SymbolTable *symtab) const;    };    /**     * Base class for branches (PC-relative control transfers),     * conditional or unconditional.     */    class Branch : public PCDependentDisassembly    {      protected:	/// Displacement to target address (signed).	int32_t disp;	/// Constructor.	Branch(const char *mnem, MachInst _machInst, OpClass __opClass)	    : PCDependentDisassembly(mnem, _machInst, __opClass),	      disp(BRDISP << 2)	{	}	Addr branchTarget(Addr branchPC) const;	std::string	generateDisassembly(Addr pc, const SymbolTable *symtab) const;    };    /**     * Base class for jumps (register-indirect control transfers).  In     * the Alpha ISA, these are always unconditional.     */    class Jump : public PCDependentDisassembly    {      protected:	/// Displacement to target address (signed).	int32_t disp;      public:	/// Constructor	Jump(const char *mnem, MachInst _machInst, OpClass __opClass)	    : PCDependentDisassembly(mnem, _machInst, __opClass),	      disp(BRDISP)	{	}	Addr branchTarget(ExecContext *xc) const;	std::string	generateDisassembly(Addr pc, const SymbolTable *symtab) const;    };}};output decoder {{    Addr    Branch::branchTarget(Addr branchPC) const    {	return branchPC + 4 + disp;    }    Addr    Jump::branchTarget(ExecContext *xc) const    {	Addr NPC = xc->readPC() + 4;	uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);	return (Rb & ~3) | (NPC & 1);    }    const std::string &    PCDependentDisassembly::disassemble(Addr pc,					const SymbolTable *symtab) const    {	if (!cachedDisassembly ||	    pc != cachedPC || symtab != cachedSymtab)	{	    if (cachedDisassembly)		delete cachedDisassembly;	    cachedDisassembly =		new std::string(generateDisassembly(pc, symtab));	    cachedPC = pc;	    cachedSymtab = symtab;	}	return *cachedDisassembly;    }    std::string    Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const    {	std::stringstream ss;	ccprintf(ss, "%-10s ", mnemonic);	// There's only one register arg (RA), but it could be	// either a source (the condition for conditional	// branches) or a destination (the link reg for	// unconditional branches)	if (_numSrcRegs > 0) {	    printReg(ss, _srcRegIdx[0]);	    ss << ",";	}	else if (_numDestRegs > 0) {	    printReg(ss, _destRegIdx[0]);	    ss << ",";	}#ifdef SS_COMPATIBLE_DISASSEMBLY	if (_numSrcRegs == 0 && _numDestRegs == 0) {	    printReg(ss, 31);	    ss << ",";	}#endif	Addr target = pc + 4 + disp;	std::string str;	if (symtab && symtab->findSymbol(target, str))	    ss << str;	else 	    ccprintf(ss, "0x%x", target);	return ss.str();    }    std::string    Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const    {	std::stringstream ss;	ccprintf(ss, "%-10s ", mnemonic);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -