branch.isa revision 2516
18981Sandreas.hansson@arm.com//////////////////////////////////////////////////////////////////// 210744SGeoffrey.Blake@arm.com// 311804Srjthakur@google.com// Branch instructions 411804Srjthakur@google.com// 58981Sandreas.hansson@arm.com 68981Sandreas.hansson@arm.comoutput header {{ 78981Sandreas.hansson@arm.com /** 88981Sandreas.hansson@arm.com * Base class for branch operations. 98981Sandreas.hansson@arm.com */ 108981Sandreas.hansson@arm.com class Branch : public SparcStaticInst 118981Sandreas.hansson@arm.com { 128981Sandreas.hansson@arm.com protected: 138981Sandreas.hansson@arm.com // Constructor 148981Sandreas.hansson@arm.com Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : 158981Sandreas.hansson@arm.com SparcStaticInst(mnem, _machInst, __opClass) 168981Sandreas.hansson@arm.com { 178981Sandreas.hansson@arm.com } 188981Sandreas.hansson@arm.com 198981Sandreas.hansson@arm.com std::string generateDisassembly(Addr pc, 208981Sandreas.hansson@arm.com const SymbolTable *symtab) const; 218981Sandreas.hansson@arm.com }; 228981Sandreas.hansson@arm.com 238981Sandreas.hansson@arm.com /** 248981Sandreas.hansson@arm.com * Base class for branch operations with an immediate displacement. 258981Sandreas.hansson@arm.com */ 268981Sandreas.hansson@arm.com class BranchDisp : public Branch 278981Sandreas.hansson@arm.com { 288981Sandreas.hansson@arm.com protected: 298981Sandreas.hansson@arm.com // Constructor 308981Sandreas.hansson@arm.com BranchDisp(const char *mnem, MachInst _machInst, 318981Sandreas.hansson@arm.com OpClass __opClass) : 328981Sandreas.hansson@arm.com Branch(mnem, _machInst, __opClass) 338981Sandreas.hansson@arm.com { 348981Sandreas.hansson@arm.com } 358981Sandreas.hansson@arm.com 368981Sandreas.hansson@arm.com std::string generateDisassembly(Addr pc, 378981Sandreas.hansson@arm.com const SymbolTable *symtab) const; 388981Sandreas.hansson@arm.com 398981Sandreas.hansson@arm.com int32_t disp; 4011804Srjthakur@google.com }; 418981Sandreas.hansson@arm.com 428981Sandreas.hansson@arm.com /** 4311793Sbrandon.potter@amd.com * Base class for branches with 19 bit displacements. 4411793Sbrandon.potter@amd.com */ 459356Snilay@cs.wisc.edu class Branch19 : public BranchDisp 468981Sandreas.hansson@arm.com { 478981Sandreas.hansson@arm.com protected: 488981Sandreas.hansson@arm.com // Constructor 498981Sandreas.hansson@arm.com Branch19(const char *mnem, MachInst _machInst, 508981Sandreas.hansson@arm.com OpClass __opClass) : 518981Sandreas.hansson@arm.com BranchDisp(mnem, _machInst, __opClass) 528981Sandreas.hansson@arm.com { 538981Sandreas.hansson@arm.com disp = sign_ext(DISP19 << 2, 21); 548981Sandreas.hansson@arm.com } 5510902Sandreas.sandberg@arm.com }; 5610902Sandreas.sandberg@arm.com 578981Sandreas.hansson@arm.com /** 588981Sandreas.hansson@arm.com * Base class for branches with 22 bit displacements. 5910064Sandreas.hansson@arm.com */ 6010902Sandreas.sandberg@arm.com class Branch22 : public BranchDisp 618981Sandreas.hansson@arm.com { 628981Sandreas.hansson@arm.com protected: 638981Sandreas.hansson@arm.com // Constructor 648981Sandreas.hansson@arm.com Branch22(const char *mnem, MachInst _machInst, 658981Sandreas.hansson@arm.com OpClass __opClass) : 668981Sandreas.hansson@arm.com BranchDisp(mnem, _machInst, __opClass) 678981Sandreas.hansson@arm.com { 688981Sandreas.hansson@arm.com disp = sign_ext(DISP22 << 2, 24); 698981Sandreas.hansson@arm.com } 708981Sandreas.hansson@arm.com }; 718981Sandreas.hansson@arm.com 728981Sandreas.hansson@arm.com /** 738981Sandreas.hansson@arm.com * Base class for branches with 30 bit displacements. 748981Sandreas.hansson@arm.com */ 758981Sandreas.hansson@arm.com class Branch30 : public BranchDisp 768981Sandreas.hansson@arm.com { 7710994Sandreas.sandberg@arm.com protected: 7810994Sandreas.sandberg@arm.com // Constructor 7910994Sandreas.sandberg@arm.com Branch30(const char *mnem, MachInst _machInst, 8010994Sandreas.sandberg@arm.com OpClass __opClass) : 8110994Sandreas.sandberg@arm.com BranchDisp(mnem, _machInst, __opClass) 8210994Sandreas.sandberg@arm.com { 8310994Sandreas.sandberg@arm.com disp = sign_ext(DISP30 << 2, 32); 849294Sandreas.hansson@arm.com } 859294Sandreas.hansson@arm.com }; 868981Sandreas.hansson@arm.com 878981Sandreas.hansson@arm.com /** 888981Sandreas.hansson@arm.com * Base class for 16bit split displacements. 898981Sandreas.hansson@arm.com */ 908981Sandreas.hansson@arm.com class BranchSplit : public BranchDisp 918981Sandreas.hansson@arm.com { 928981Sandreas.hansson@arm.com protected: 938981Sandreas.hansson@arm.com // Constructor 949294Sandreas.hansson@arm.com BranchSplit(const char *mnem, MachInst _machInst, 959294Sandreas.hansson@arm.com OpClass __opClass) : 968981Sandreas.hansson@arm.com BranchDisp(mnem, _machInst, __opClass) 978981Sandreas.hansson@arm.com { 988981Sandreas.hansson@arm.com disp = sign_ext((D16HI << 16) | (D16LO << 2), 18); 998981Sandreas.hansson@arm.com } 1008981Sandreas.hansson@arm.com }; 1018981Sandreas.hansson@arm.com 1028981Sandreas.hansson@arm.com /** 1038981Sandreas.hansson@arm.com * Base class for branches that use an immediate and a register to 1048981Sandreas.hansson@arm.com * compute their displacements. 1058981Sandreas.hansson@arm.com */ 1068981Sandreas.hansson@arm.com class BranchImm13 : public Branch 1078981Sandreas.hansson@arm.com { 1088981Sandreas.hansson@arm.com protected: 1098981Sandreas.hansson@arm.com // Constructor 1108981Sandreas.hansson@arm.com BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) : 1118981Sandreas.hansson@arm.com Branch(mnem, _machInst, __opClass), imm(sign_ext(SIMM13, 13)) 1128981Sandreas.hansson@arm.com { 1138981Sandreas.hansson@arm.com } 1148981Sandreas.hansson@arm.com 1158981Sandreas.hansson@arm.com std::string generateDisassembly(Addr pc, 11611804Srjthakur@google.com const SymbolTable *symtab) const; 11711804Srjthakur@google.com 11811804Srjthakur@google.com int32_t imm; 11911804Srjthakur@google.com }; 12011804Srjthakur@google.com}}; 12111804Srjthakur@google.com 12211804Srjthakur@google.comoutput decoder {{ 12311804Srjthakur@google.com std::string Branch::generateDisassembly(Addr pc, 12411804Srjthakur@google.com const SymbolTable *symtab) const 12511804Srjthakur@google.com { 12611804Srjthakur@google.com std::stringstream response; 12711804Srjthakur@google.com 12811804Srjthakur@google.com printMnemonic(response, mnemonic); 12911804Srjthakur@google.com 13011804Srjthakur@google.com if (_numSrcRegs > 0) 13111804Srjthakur@google.com { 13211804Srjthakur@google.com printReg(response, _srcRegIdx[0]); 13311804Srjthakur@google.com for(int x = 1; x < _numSrcRegs; x++) 13411804Srjthakur@google.com { 13511804Srjthakur@google.com response << ", "; 13611804Srjthakur@google.com printReg(response, _srcRegIdx[x]); 13711804Srjthakur@google.com } 13811804Srjthakur@google.com } 13911804Srjthakur@google.com 14011804Srjthakur@google.com if (_numDestRegs > 0) 14111804Srjthakur@google.com { 14211804Srjthakur@google.com if(_numSrcRegs > 0) 14311804Srjthakur@google.com response << ", "; 14411804Srjthakur@google.com printReg(response, _destRegIdx[0]); 14511804Srjthakur@google.com } 14611804Srjthakur@google.com 14711804Srjthakur@google.com return response.str(); 14811804Srjthakur@google.com } 14911804Srjthakur@google.com 15011804Srjthakur@google.com std::string BranchImm13::generateDisassembly(Addr pc, 15111804Srjthakur@google.com const SymbolTable *symtab) const 15211804Srjthakur@google.com { 15311804Srjthakur@google.com std::stringstream response; 15411804Srjthakur@google.com 15511804Srjthakur@google.com printMnemonic(response, mnemonic); 15611804Srjthakur@google.com 15711804Srjthakur@google.com if (_numSrcRegs > 0) 15811804Srjthakur@google.com { 15911804Srjthakur@google.com printReg(response, _srcRegIdx[0]); 16011804Srjthakur@google.com for(int x = 1; x < _numSrcRegs; x++) 16111804Srjthakur@google.com { 16211804Srjthakur@google.com response << ", "; 16311804Srjthakur@google.com printReg(response, _srcRegIdx[x]); 16411804Srjthakur@google.com } 16511804Srjthakur@google.com } 16611804Srjthakur@google.com 16711804Srjthakur@google.com if(_numSrcRegs > 0) 16811804Srjthakur@google.com response << ", "; 16911804Srjthakur@google.com 17011804Srjthakur@google.com ccprintf(response, "0x%x", imm); 17111804Srjthakur@google.com 17211804Srjthakur@google.com if (_numDestRegs > 0) 17311804Srjthakur@google.com { 17411804Srjthakur@google.com response << ", "; 17511804Srjthakur@google.com printReg(response, _destRegIdx[0]); 17611804Srjthakur@google.com } 17711804Srjthakur@google.com 17811804Srjthakur@google.com return response.str(); 17911804Srjthakur@google.com } 18011804Srjthakur@google.com 18111804Srjthakur@google.com std::string BranchDisp::generateDisassembly(Addr pc, 18211804Srjthakur@google.com const SymbolTable *symtab) const 18311804Srjthakur@google.com { 18411804Srjthakur@google.com std::stringstream response; 18511804Srjthakur@google.com std::string symbol; 18611804Srjthakur@google.com Addr symbolAddr; 18711804Srjthakur@google.com 18811804Srjthakur@google.com Addr target = disp + pc; 18911804Srjthakur@google.com 19011804Srjthakur@google.com printMnemonic(response, mnemonic); 19111804Srjthakur@google.com ccprintf(response, "0x%x", target); 19211804Srjthakur@google.com 19311804Srjthakur@google.com if(symtab->findNearestSymbol(target, symbol, symbolAddr)) 19411804Srjthakur@google.com { 19511804Srjthakur@google.com ccprintf(response, " <%s", symbol); 19611804Srjthakur@google.com if(symbolAddr != target) 19711804Srjthakur@google.com ccprintf(response, "+0x%x>", target - symbolAddr); 19811804Srjthakur@google.com else 19911804Srjthakur@google.com ccprintf(response, ">"); 20011804Srjthakur@google.com } 20111804Srjthakur@google.com 20211804Srjthakur@google.com return response.str(); 20311804Srjthakur@google.com } 20411804Srjthakur@google.com}}; 20511804Srjthakur@google.com 20611804Srjthakur@google.comdef template BranchExecute {{ 20711804Srjthakur@google.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 20811804Srjthakur@google.com Trace::InstRecord *traceData) const 20911804Srjthakur@google.com { 21011804Srjthakur@google.com //Attempt to execute the instruction 21111804Srjthakur@google.com Fault fault = NoFault; 21211804Srjthakur@google.com 21311804Srjthakur@google.com %(op_decl)s; 21411804Srjthakur@google.com %(op_rd)s; 2158981Sandreas.hansson@arm.com 2168981Sandreas.hansson@arm.com NNPC = xc->readNextNPC(); 2178981Sandreas.hansson@arm.com %(code)s; 21811804Srjthakur@google.com 21911804Srjthakur@google.com if(fault == NoFault) 22011139Sandreas.hansson@arm.com { 22111139Sandreas.hansson@arm.com //Write the resulting state to the execution context 22210994Sandreas.sandberg@arm.com %(op_wb)s; 22310994Sandreas.sandberg@arm.com } 22411804Srjthakur@google.com 22511804Srjthakur@google.com return fault; 22611804Srjthakur@google.com } 22711804Srjthakur@google.com}}; 22811804Srjthakur@google.com 22910994Sandreas.sandberg@arm.com// Primary format for branch instructions: 23011139Sandreas.hansson@arm.comdef format Branch(code, *opt_flags) {{ 23111139Sandreas.hansson@arm.com (usesImm, code, immCode, 23210994Sandreas.sandberg@arm.com rString, iString) = splitOutImm(code) 2338981Sandreas.hansson@arm.com codeBlk = CodeBlock(code) 2348981Sandreas.hansson@arm.com iop = InstObjParams(name, Name, 'Branch', codeBlk, opt_flags) 2358981Sandreas.hansson@arm.com header_output = BasicDeclare.subst(iop) 2368981Sandreas.hansson@arm.com decoder_output = BasicConstructor.subst(iop) 2378981Sandreas.hansson@arm.com exec_output = BranchExecute.subst(iop) 2388981Sandreas.hansson@arm.com if usesImm: 2398981Sandreas.hansson@arm.com imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, 2408981Sandreas.hansson@arm.com codeBlk, opt_flags) 2418981Sandreas.hansson@arm.com header_output += BasicDeclare.subst(imm_iop) 2428981Sandreas.hansson@arm.com decoder_output += BasicConstructor.subst(imm_iop) 2438981Sandreas.hansson@arm.com exec_output += BranchExecute.subst(imm_iop) 2448981Sandreas.hansson@arm.com decode_block = ROrImmDecode.subst(iop) 2458981Sandreas.hansson@arm.com else: 2468981Sandreas.hansson@arm.com decode_block = BasicDecode.subst(iop) 2478981Sandreas.hansson@arm.com}}; 2488981Sandreas.hansson@arm.com 24911139Sandreas.hansson@arm.com// Primary format for branch instructions: 25011139Sandreas.hansson@arm.comdef format Branch19(code, *opt_flags) {{ 25111804Srjthakur@google.com codeBlk = CodeBlock(code) 25211804Srjthakur@google.com iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags) 2538981Sandreas.hansson@arm.com header_output = BasicDeclare.subst(iop) 2548981Sandreas.hansson@arm.com decoder_output = BasicConstructor.subst(iop) 2558981Sandreas.hansson@arm.com exec_output = BranchExecute.subst(iop) 25611284Sandreas.hansson@arm.com decode_block = BasicDecode.subst(iop) 25711284Sandreas.hansson@arm.com}}; 2589785Sandreas.hansson@arm.com 2599542Sandreas.hansson@arm.com// Primary format for branch instructions: 2608981Sandreas.hansson@arm.comdef format Branch22(code, *opt_flags) {{ 2618981Sandreas.hansson@arm.com codeBlk = CodeBlock(code) 26211284Sandreas.hansson@arm.com iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags) 2638981Sandreas.hansson@arm.com header_output = BasicDeclare.subst(iop) 2648981Sandreas.hansson@arm.com decoder_output = BasicConstructor.subst(iop) 2658981Sandreas.hansson@arm.com exec_output = BranchExecute.subst(iop) 2669785Sandreas.hansson@arm.com decode_block = BasicDecode.subst(iop) 2679542Sandreas.hansson@arm.com}}; 2688981Sandreas.hansson@arm.com 2698981Sandreas.hansson@arm.com// Primary format for branch instructions: 27010994Sandreas.sandberg@arm.comdef format Branch30(code, *opt_flags) {{ 27111139Sandreas.hansson@arm.com codeBlk = CodeBlock(code) 27210994Sandreas.sandberg@arm.com iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags) 27310994Sandreas.sandberg@arm.com header_output = BasicDeclare.subst(iop) 27411804Srjthakur@google.com decoder_output = BasicConstructor.subst(iop) 27511847Spierre-yves.peneau@lirmm.fr exec_output = BranchExecute.subst(iop) 27611847Spierre-yves.peneau@lirmm.fr decode_block = BasicDecode.subst(iop) 27711804Srjthakur@google.com}}; 2788981Sandreas.hansson@arm.com 2798981Sandreas.hansson@arm.com// Primary format for branch instructions: 2808981Sandreas.hansson@arm.comdef format BranchSplit(code, *opt_flags) {{ 2818981Sandreas.hansson@arm.com codeBlk = CodeBlock(code) 2828981Sandreas.hansson@arm.com iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags) 2838981Sandreas.hansson@arm.com header_output = BasicDeclare.subst(iop) 2848981Sandreas.hansson@arm.com decoder_output = BasicConstructor.subst(iop) 2858981Sandreas.hansson@arm.com exec_output = BranchExecute.subst(iop) 2868981Sandreas.hansson@arm.com decode_block = BasicDecode.subst(iop) 2878981Sandreas.hansson@arm.com}}; 2888981Sandreas.hansson@arm.com 2898981Sandreas.hansson@arm.com