branch.isa revision 2665
12934Sktlim@umich.edu// -*- mode:c++ -*- 22934Sktlim@umich.edu 32934Sktlim@umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan 42934Sktlim@umich.edu// All rights reserved. 52934Sktlim@umich.edu// 62934Sktlim@umich.edu// Redistribution and use in source and binary forms, with or without 72934Sktlim@umich.edu// modification, are permitted provided that the following conditions are 82934Sktlim@umich.edu// met: redistributions of source code must retain the above copyright 92934Sktlim@umich.edu// notice, this list of conditions and the following disclaimer; 102934Sktlim@umich.edu// redistributions in binary form must reproduce the above copyright 112934Sktlim@umich.edu// notice, this list of conditions and the following disclaimer in the 122934Sktlim@umich.edu// documentation and/or other materials provided with the distribution; 132934Sktlim@umich.edu// neither the name of the copyright holders nor the names of its 142934Sktlim@umich.edu// contributors may be used to endorse or promote products derived from 152934Sktlim@umich.edu// this software without specific prior written permission. 162934Sktlim@umich.edu// 172934Sktlim@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182934Sktlim@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192934Sktlim@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202934Sktlim@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212934Sktlim@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222934Sktlim@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232934Sktlim@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242934Sktlim@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252934Sktlim@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262934Sktlim@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272934Sktlim@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282934Sktlim@umich.edu// 292934Sktlim@umich.edu// Authors: Steve Reinhardt 302934Sktlim@umich.edu 312934Sktlim@umich.edu//////////////////////////////////////////////////////////////////// 322934Sktlim@umich.edu// 332934Sktlim@umich.edu// Control transfer instructions 342934Sktlim@umich.edu// 352934Sktlim@umich.edu 362934Sktlim@umich.eduoutput header {{ 372934Sktlim@umich.edu 382934Sktlim@umich.edu /** 392934Sktlim@umich.edu * Base class for instructions whose disassembly is not purely a 402934Sktlim@umich.edu * function of the machine instruction (i.e., it depends on the 412934Sktlim@umich.edu * PC). This class overrides the disassemble() method to check 422934Sktlim@umich.edu * the PC and symbol table values before re-using a cached 432934Sktlim@umich.edu * disassembly string. This is necessary for branches and jumps, 442934Sktlim@umich.edu * where the disassembly string includes the target address (which 452934Sktlim@umich.edu * may depend on the PC and/or symbol table). 462934Sktlim@umich.edu */ 472934Sktlim@umich.edu class PCDependentDisassembly : public AlphaStaticInst 482934Sktlim@umich.edu { 492934Sktlim@umich.edu protected: 502934Sktlim@umich.edu /// Cached program counter from last disassembly 512934Sktlim@umich.edu mutable Addr cachedPC; 522934Sktlim@umich.edu /// Cached symbol table pointer from last disassembly 532934Sktlim@umich.edu mutable const SymbolTable *cachedSymtab; 542934Sktlim@umich.edu 552934Sktlim@umich.edu /// Constructor 562934Sktlim@umich.edu PCDependentDisassembly(const char *mnem, ExtMachInst _machInst, 572934Sktlim@umich.edu OpClass __opClass) 582934Sktlim@umich.edu : AlphaStaticInst(mnem, _machInst, __opClass), 592934Sktlim@umich.edu cachedPC(0), cachedSymtab(0) 602934Sktlim@umich.edu { 612934Sktlim@umich.edu } 622934Sktlim@umich.edu 632934Sktlim@umich.edu const std::string & 642934Sktlim@umich.edu disassemble(Addr pc, const SymbolTable *symtab) const; 652934Sktlim@umich.edu }; 662934Sktlim@umich.edu 672934Sktlim@umich.edu /** 682934Sktlim@umich.edu * Base class for branches (PC-relative control transfers), 692934Sktlim@umich.edu * conditional or unconditional. 702934Sktlim@umich.edu */ 712934Sktlim@umich.edu class Branch : public PCDependentDisassembly 722934Sktlim@umich.edu { 732934Sktlim@umich.edu protected: 742934Sktlim@umich.edu /// Displacement to target address (signed). 752934Sktlim@umich.edu int32_t disp; 762934Sktlim@umich.edu 772934Sktlim@umich.edu /// Constructor. 782934Sktlim@umich.edu Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 792934Sktlim@umich.edu : PCDependentDisassembly(mnem, _machInst, __opClass), 802934Sktlim@umich.edu disp(BRDISP << 2) 812934Sktlim@umich.edu { 822934Sktlim@umich.edu } 832934Sktlim@umich.edu 842934Sktlim@umich.edu Addr branchTarget(Addr branchPC) const; 852934Sktlim@umich.edu 862934Sktlim@umich.edu std::string 872934Sktlim@umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 882934Sktlim@umich.edu }; 892934Sktlim@umich.edu 902934Sktlim@umich.edu /** 912934Sktlim@umich.edu * Base class for jumps (register-indirect control transfers). In 922934Sktlim@umich.edu * the Alpha ISA, these are always unconditional. 932934Sktlim@umich.edu */ 942934Sktlim@umich.edu class Jump : public PCDependentDisassembly 952934Sktlim@umich.edu { 962934Sktlim@umich.edu protected: 972934Sktlim@umich.edu 982934Sktlim@umich.edu /// Displacement to target address (signed). 992934Sktlim@umich.edu int32_t disp; 1002934Sktlim@umich.edu 1012934Sktlim@umich.edu public: 1022934Sktlim@umich.edu /// Constructor 1032934Sktlim@umich.edu Jump(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 1042934Sktlim@umich.edu : PCDependentDisassembly(mnem, _machInst, __opClass), 105 disp(BRDISP) 106 { 107 } 108 109 Addr branchTarget(ExecContext *xc) const; 110 111 std::string 112 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 113 }; 114}}; 115 116output decoder {{ 117 Addr 118 Branch::branchTarget(Addr branchPC) const 119 { 120 return branchPC + 4 + disp; 121 } 122 123 Addr 124 Jump::branchTarget(ExecContext *xc) const 125 { 126 Addr NPC = xc->readPC() + 4; 127 uint64_t Rb = xc->readIntReg(_srcRegIdx[0]); 128 return (Rb & ~3) | (NPC & 1); 129 } 130 131 const std::string & 132 PCDependentDisassembly::disassemble(Addr pc, 133 const SymbolTable *symtab) const 134 { 135 if (!cachedDisassembly || 136 pc != cachedPC || symtab != cachedSymtab) 137 { 138 if (cachedDisassembly) 139 delete cachedDisassembly; 140 141 cachedDisassembly = 142 new std::string(generateDisassembly(pc, symtab)); 143 cachedPC = pc; 144 cachedSymtab = symtab; 145 } 146 147 return *cachedDisassembly; 148 } 149 150 std::string 151 Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const 152 { 153 std::stringstream ss; 154 155 ccprintf(ss, "%-10s ", mnemonic); 156 157 // There's only one register arg (RA), but it could be 158 // either a source (the condition for conditional 159 // branches) or a destination (the link reg for 160 // unconditional branches) 161 if (_numSrcRegs > 0) { 162 printReg(ss, _srcRegIdx[0]); 163 ss << ","; 164 } 165 else if (_numDestRegs > 0) { 166 printReg(ss, _destRegIdx[0]); 167 ss << ","; 168 } 169 170#ifdef SS_COMPATIBLE_DISASSEMBLY 171 if (_numSrcRegs == 0 && _numDestRegs == 0) { 172 printReg(ss, 31); 173 ss << ","; 174 } 175#endif 176 177 Addr target = pc + 4 + disp; 178 179 std::string str; 180 if (symtab && symtab->findSymbol(target, str)) 181 ss << str; 182 else 183 ccprintf(ss, "0x%x", target); 184 185 return ss.str(); 186 } 187 188 std::string 189 Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const 190 { 191 std::stringstream ss; 192 193 ccprintf(ss, "%-10s ", mnemonic); 194 195#ifdef SS_COMPATIBLE_DISASSEMBLY 196 if (_numDestRegs == 0) { 197 printReg(ss, 31); 198 ss << ","; 199 } 200#endif 201 202 if (_numDestRegs > 0) { 203 printReg(ss, _destRegIdx[0]); 204 ss << ","; 205 } 206 207 ccprintf(ss, "(r%d)", RB); 208 209 return ss.str(); 210 } 211}}; 212 213def template JumpOrBranchDecode {{ 214 return (RA == 31) 215 ? (StaticInst *)new %(class_name)s(machInst) 216 : (StaticInst *)new %(class_name)sAndLink(machInst); 217}}; 218 219def format CondBranch(code) {{ 220 code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; 221 iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), 222 ('IsDirectControl', 'IsCondControl')) 223 header_output = BasicDeclare.subst(iop) 224 decoder_output = BasicConstructor.subst(iop) 225 decode_block = BasicDecode.subst(iop) 226 exec_output = BasicExecute.subst(iop) 227}}; 228 229let {{ 230def UncondCtrlBase(name, Name, base_class, npc_expr, flags): 231 # Declare basic control transfer w/o link (i.e. link reg is R31) 232 nolink_code = 'NPC = %s;\n' % npc_expr 233 nolink_iop = InstObjParams(name, Name, base_class, 234 CodeBlock(nolink_code), flags) 235 header_output = BasicDeclare.subst(nolink_iop) 236 decoder_output = BasicConstructor.subst(nolink_iop) 237 exec_output = BasicExecute.subst(nolink_iop) 238 239 # Generate declaration of '*AndLink' version, append to decls 240 link_code = 'Ra = NPC & ~3;\n' + nolink_code 241 link_iop = InstObjParams(name, Name + 'AndLink', base_class, 242 CodeBlock(link_code), flags) 243 header_output += BasicDeclare.subst(link_iop) 244 decoder_output += BasicConstructor.subst(link_iop) 245 exec_output += BasicExecute.subst(link_iop) 246 247 # need to use link_iop for the decode template since it is expecting 248 # the shorter version of class_name (w/o "AndLink") 249 250 return (header_output, decoder_output, 251 JumpOrBranchDecode.subst(nolink_iop), exec_output) 252}}; 253 254def format UncondBranch(*flags) {{ 255 flags += ('IsUncondControl', 'IsDirectControl') 256 (header_output, decoder_output, decode_block, exec_output) = \ 257 UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags) 258}}; 259 260def format Jump(*flags) {{ 261 flags += ('IsUncondControl', 'IsIndirectControl') 262 (header_output, decoder_output, decode_block, exec_output) = \ 263 UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags) 264}}; 265 266 267