branch.isa revision 3792
13691Shsul@eecs.umich.edu// Copyright (c) 2006 The Regents of The University of Michigan 23691Shsul@eecs.umich.edu// All rights reserved. 33691Shsul@eecs.umich.edu// 43691Shsul@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 53691Shsul@eecs.umich.edu// modification, are permitted provided that the following conditions are 63691Shsul@eecs.umich.edu// met: redistributions of source code must retain the above copyright 73691Shsul@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 83691Shsul@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 93691Shsul@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 103691Shsul@eecs.umich.edu// documentation and/or other materials provided with the distribution; 113691Shsul@eecs.umich.edu// neither the name of the copyright holders nor the names of its 123691Shsul@eecs.umich.edu// contributors may be used to endorse or promote products derived from 133691Shsul@eecs.umich.edu// this software without specific prior written permission. 143691Shsul@eecs.umich.edu// 153691Shsul@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163691Shsul@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173691Shsul@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 183691Shsul@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 193691Shsul@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 203691Shsul@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 213691Shsul@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 223691Shsul@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233691Shsul@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 243691Shsul@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 253691Shsul@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 263691Shsul@eecs.umich.edu// 273691Shsul@eecs.umich.edu// Authors: Gabe Black 283691Shsul@eecs.umich.edu// Steve Reinhardt 293691Shsul@eecs.umich.edu 303691Shsul@eecs.umich.edu//////////////////////////////////////////////////////////////////// 3111682Sandreas.hansson@arm.com// 3213916Sodanrc@yahoo.com.br// Branch instructions 333691Shsul@eecs.umich.edu// 3413950Sodanrc@yahoo.com.br 3513950Sodanrc@yahoo.com.broutput header {{ 3613916Sodanrc@yahoo.com.br /** 379793Sakash.bagdia@arm.com * Base class for branch operations. 389827Sakash.bagdia@arm.com */ 399827Sakash.bagdia@arm.com class Branch : public SparcStaticInst 409827Sakash.bagdia@arm.com { 419793Sakash.bagdia@arm.com protected: 429827Sakash.bagdia@arm.com // Constructor 439827Sakash.bagdia@arm.com Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : 449793Sakash.bagdia@arm.com SparcStaticInst(mnem, _machInst, __opClass) 453691Shsul@eecs.umich.edu { 468876Sandreas.hansson@arm.com } 478876Sandreas.hansson@arm.com 487876Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, 499793Sakash.bagdia@arm.com const SymbolTable *symtab) const; 509793Sakash.bagdia@arm.com }; 519793Sakash.bagdia@arm.com 529827Sakash.bagdia@arm.com /** 539827Sakash.bagdia@arm.com * Base class for branch operations with an immediate displacement. 549827Sakash.bagdia@arm.com */ 559793Sakash.bagdia@arm.com class BranchDisp : public Branch 569793Sakash.bagdia@arm.com { 579827Sakash.bagdia@arm.com protected: 589827Sakash.bagdia@arm.com // Constructor 599827Sakash.bagdia@arm.com BranchDisp(const char *mnem, MachInst _machInst, 609793Sakash.bagdia@arm.com OpClass __opClass) : 618713Sandreas.hansson@arm.com Branch(mnem, _machInst, __opClass) 628713Sandreas.hansson@arm.com { 638713Sandreas.hansson@arm.com } 649408Sandreas.hansson@arm.com 658839Sandreas.hansson@arm.com std::string generateDisassembly(Addr pc, 668839Sandreas.hansson@arm.com const SymbolTable *symtab) const; 673691Shsul@eecs.umich.edu 689826Sandreas.hansson@arm.com int32_t disp; 699826Sandreas.hansson@arm.com }; 709826Sandreas.hansson@arm.com 7113950Sodanrc@yahoo.com.br /** 7213950Sodanrc@yahoo.com.br * Base class for branches with n bit displacements. 7313916Sodanrc@yahoo.com.br */ 749827Sakash.bagdia@arm.com template<int bits> 759827Sakash.bagdia@arm.com class BranchNBits : public BranchDisp 769793Sakash.bagdia@arm.com { 779827Sakash.bagdia@arm.com protected: 789827Sakash.bagdia@arm.com // Constructor 799827Sakash.bagdia@arm.com BranchNBits(const char *mnem, MachInst _machInst, 803691Shsul@eecs.umich.edu OpClass __opClass) : 818876Sandreas.hansson@arm.com BranchDisp(mnem, _machInst, __opClass) 828876Sandreas.hansson@arm.com { 837876Sgblack@eecs.umich.edu disp = sext<bits + 2>((_machInst & mask(bits)) << 2); 849793Sakash.bagdia@arm.com } 859793Sakash.bagdia@arm.com }; 869793Sakash.bagdia@arm.com 879827Sakash.bagdia@arm.com /** 889827Sakash.bagdia@arm.com * Base class for 16bit split displacements. 899827Sakash.bagdia@arm.com */ 909793Sakash.bagdia@arm.com class BranchSplit : public BranchDisp 919793Sakash.bagdia@arm.com { 929827Sakash.bagdia@arm.com protected: 939827Sakash.bagdia@arm.com // Constructor 949827Sakash.bagdia@arm.com BranchSplit(const char *mnem, MachInst _machInst, 959793Sakash.bagdia@arm.com OpClass __opClass) : 969408Sandreas.hansson@arm.com BranchDisp(mnem, _machInst, __opClass) 978839Sandreas.hansson@arm.com { 988839Sandreas.hansson@arm.com disp = sext<18>((D16HI << 16) | (D16LO << 2)); 993691Shsul@eecs.umich.edu } 1009826Sandreas.hansson@arm.com }; 1019826Sandreas.hansson@arm.com 1029826Sandreas.hansson@arm.com /** 10313950Sodanrc@yahoo.com.br * Base class for branches that use an immediate and a register to 1043691Shsul@eecs.umich.edu * compute their displacements. 1053691Shsul@eecs.umich.edu */ 106 class BranchImm13 : public Branch 107 { 108 protected: 109 // Constructor 110 BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) : 111 Branch(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) 112 { 113 } 114 115 std::string generateDisassembly(Addr pc, 116 const SymbolTable *symtab) const; 117 118 int32_t imm; 119 }; 120}}; 121 122output decoder {{ 123 124 template class BranchNBits<19>; 125 126 template class BranchNBits<22>; 127 128 template class BranchNBits<30>; 129 130 std::string Branch::generateDisassembly(Addr pc, 131 const SymbolTable *symtab) const 132 { 133 std::stringstream response; 134 135 printMnemonic(response, mnemonic); 136 printRegArray(response, _srcRegIdx, _numSrcRegs); 137 if(_numDestRegs && _numSrcRegs) 138 response << ", "; 139 printDestReg(response, 0); 140 141 return response.str(); 142 } 143 144 std::string BranchImm13::generateDisassembly(Addr pc, 145 const SymbolTable *symtab) const 146 { 147 std::stringstream response; 148 149 printMnemonic(response, mnemonic); 150 printRegArray(response, _srcRegIdx, _numSrcRegs); 151 if(_numSrcRegs > 0) 152 response << ", "; 153 ccprintf(response, "0x%x", imm); 154 if (_numDestRegs > 0) 155 response << ", "; 156 printDestReg(response, 0); 157 158 return response.str(); 159 } 160 161 std::string BranchDisp::generateDisassembly(Addr pc, 162 const SymbolTable *symtab) const 163 { 164 std::stringstream response; 165 std::string symbol; 166 Addr symbolAddr; 167 168 Addr target = disp + pc; 169 170 printMnemonic(response, mnemonic); 171 ccprintf(response, "0x%x", target); 172 173 if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) 174 { 175 ccprintf(response, " <%s", symbol); 176 if(symbolAddr != target) 177 ccprintf(response, "+%d>", target - symbolAddr); 178 else 179 ccprintf(response, ">"); 180 } 181 else 182 { 183 ccprintf(response, "<%d>", target); 184 } 185 186 return response.str(); 187 } 188}}; 189 190def template BranchExecute {{ 191 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 192 Trace::InstRecord *traceData) const 193 { 194 //Attempt to execute the instruction 195 Fault fault = NoFault; 196 197 %(op_decl)s; 198 %(op_rd)s; 199 200 NNPC = xc->readNextNPC(); 201 %(code)s; 202 203 if(fault == NoFault) 204 { 205 //Write the resulting state to the execution context 206 %(op_wb)s; 207 } 208 209 return fault; 210 } 211}}; 212 213let {{ 214 handle_annul = ''' 215 { 216 if(A) 217 { 218 NPC = xc->readNextNPC(); 219 NNPC = NPC + 4; 220 } 221 else 222 { 223 NPC = xc->readNextPC(); 224 NNPC = xc->readNextNPC(); 225 } 226 }''' 227}}; 228 229// Primary format for branch instructions: 230def format Branch(code, *opt_flags) {{ 231 (usesImm, code, immCode, 232 rString, iString) = splitOutImm(code) 233 iop = InstObjParams(name, Name, 'Branch', code, opt_flags) 234 header_output = BasicDeclare.subst(iop) 235 decoder_output = BasicConstructor.subst(iop) 236 exec_output = BranchExecute.subst(iop) 237 if usesImm: 238 imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, 239 immCode, opt_flags) 240 header_output += BasicDeclare.subst(imm_iop) 241 decoder_output += BasicConstructor.subst(imm_iop) 242 exec_output += BranchExecute.subst(imm_iop) 243 decode_block = ROrImmDecode.subst(iop) 244 else: 245 decode_block = BasicDecode.subst(iop) 246}}; 247 248// Primary format for branch instructions: 249def format BranchN(bits, code, *opt_flags) {{ 250 code = re.sub(r'handle_annul', handle_annul, code) 251 new_opt_flags = [] 252 for flag in opt_flags: 253 if flag == ',a': 254 name += ',a' 255 Name += 'Annul' 256 else: 257 new_opt_flags += flag 258 iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags) 259 header_output = BasicDeclare.subst(iop) 260 decoder_output = BasicConstructor.subst(iop) 261 exec_output = BranchExecute.subst(iop) 262 decode_block = BasicDecode.subst(iop) 263}}; 264 265// Primary format for branch instructions: 266def format BranchSplit(code, *opt_flags) {{ 267 code = re.sub(r'handle_annul', handle_annul, code) 268 iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags) 269 header_output = BasicDeclare.subst(iop) 270 decoder_output = BasicConstructor.subst(iop) 271 exec_output = BranchExecute.subst(iop) 272 decode_block = BasicDecode.subst(iop) 273}}; 274 275