?? isa_desc
字號:
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 + -