diff options
Diffstat (limited to 'arch/sparc/isa/formats/branch.isa')
-rw-r--r-- | arch/sparc/isa/formats/branch.isa | 241 |
1 files changed, 234 insertions, 7 deletions
diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa index b9dc960de..e4ce4592c 100644 --- a/arch/sparc/isa/formats/branch.isa +++ b/arch/sparc/isa/formats/branch.isa @@ -5,7 +5,7 @@ output header {{ /** - * Base class for integer operations. + * Base class for branch operations. */ class Branch : public SparcStaticInst { @@ -19,12 +19,187 @@ output header {{ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; + + /** + * Base class for branch operations with an immediate displacement. + */ + class BranchDisp : public Branch + { + protected: + // Constructor + BranchDisp(const char *mnem, MachInst _machInst, + OpClass __opClass) : + Branch(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + int32_t disp; + }; + + /** + * Base class for branches with 19 bit displacements. + */ + class Branch19 : public BranchDisp + { + protected: + // Constructor + Branch19(const char *mnem, MachInst _machInst, + OpClass __opClass) : + BranchDisp(mnem, _machInst, __opClass) + { + disp = sign_ext(DISP19 << 2, 21); + } + }; + + /** + * Base class for branches with 22 bit displacements. + */ + class Branch22 : public BranchDisp + { + protected: + // Constructor + Branch22(const char *mnem, MachInst _machInst, + OpClass __opClass) : + BranchDisp(mnem, _machInst, __opClass) + { + disp = sign_ext(DISP22 << 2, 24); + } + }; + + /** + * Base class for branches with 30 bit displacements. + */ + class Branch30 : public BranchDisp + { + protected: + // Constructor + Branch30(const char *mnem, MachInst _machInst, + OpClass __opClass) : + BranchDisp(mnem, _machInst, __opClass) + { + disp = sign_ext(DISP30 << 2, 32); + } + }; + + /** + * Base class for 16bit split displacements. + */ + class BranchSplit : public BranchDisp + { + protected: + // Constructor + BranchSplit(const char *mnem, MachInst _machInst, + OpClass __opClass) : + BranchDisp(mnem, _machInst, __opClass) + { + disp = sign_ext((D16HI << 16) | (D16LO << 2), 18); + } + }; + + /** + * Base class for branches that use an immediate and a register to + * compute their displacements. + */ + class BranchImm13 : public Branch + { + protected: + // Constructor + BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) : + Branch(mnem, _machInst, __opClass), imm(sign_ext(SIMM13, 13)) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + int32_t imm; + }; }}; output decoder {{ - std::string Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string Branch::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { - return "Branch instruction\n"; + std::stringstream response; + + printMnemonic(response, mnemonic); + + if (_numSrcRegs > 0) + { + printReg(response, _srcRegIdx[0]); + for(int x = 1; x < _numSrcRegs; x++) + { + response << ", "; + printReg(response, _srcRegIdx[x]); + } + } + + if (_numDestRegs > 0) + { + if(_numSrcRegs > 0) + response << ", "; + printReg(response, _destRegIdx[0]); + } + + return response.str(); + } + + std::string BranchImm13::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, mnemonic); + + if (_numSrcRegs > 0) + { + printReg(response, _srcRegIdx[0]); + for(int x = 1; x < _numSrcRegs; x++) + { + response << ", "; + printReg(response, _srcRegIdx[x]); + } + } + + if(_numSrcRegs > 0) + response << ", "; + + ccprintf(response, "0x%x", imm); + + if (_numDestRegs > 0) + { + response << ", "; + printReg(response, _destRegIdx[0]); + } + + return response.str(); + } + + std::string BranchDisp::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + std::string symbol; + Addr symbolAddr; + + Addr target = disp + pc; + + printMnemonic(response, mnemonic); + ccprintf(response, "0x%x", target); + + if(symtab->findNearestSymbol(target, symbol, symbolAddr)) + { + ccprintf(response, " <%s", symbol); + if(symbolAddr != target) + ccprintf(response, "+0x%x>", target - symbolAddr); + else + ccprintf(response, ">"); + } + + return response.str(); } }}; @@ -37,6 +212,8 @@ def template BranchExecute {{ %(op_decl)s; %(op_rd)s; + + NNPC = xc->readNextNPC(); %(code)s; if(fault == NoFault) @@ -49,13 +226,63 @@ def template BranchExecute {{ } }}; -// Primary format for integer operate instructions: +// Primary format for branch instructions: def format Branch(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + (usesImm, code, immCode, + rString, iString) = splitOutImm(code) + codeBlk = CodeBlock(code) + iop = InstObjParams(name, Name, 'Branch', codeBlk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) + exec_output = BranchExecute.subst(iop) + if usesImm: + imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, + codeBlk, opt_flags) + header_output += BasicDeclare.subst(imm_iop) + decoder_output += BasicConstructor.subst(imm_iop) + exec_output += BranchExecute.subst(imm_iop) + decode_block = ROrImmDecode.subst(iop) + else: + decode_block = BasicDecode.subst(iop) +}}; + +// Primary format for branch instructions: +def format Branch19(code, *opt_flags) {{ + codeBlk = CodeBlock(code) + iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = BranchExecute.subst(iop) decode_block = BasicDecode.subst(iop) +}}; + +// Primary format for branch instructions: +def format Branch22(code, *opt_flags) {{ + codeBlk = CodeBlock(code) + iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) exec_output = BranchExecute.subst(iop) + decode_block = BasicDecode.subst(iop) +}}; + +// Primary format for branch instructions: +def format Branch30(code, *opt_flags) {{ + codeBlk = CodeBlock(code) + iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = BranchExecute.subst(iop) + decode_block = BasicDecode.subst(iop) }}; + +// Primary format for branch instructions: +def format BranchSplit(code, *opt_flags) {{ + codeBlk = CodeBlock(code) + iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = BranchExecute.subst(iop) + decode_block = BasicDecode.subst(iop) +}}; + |