branch.hh revision 12616:4b463b4dc098
12SN/A/* Copyright (c) 2007-2008 The Florida State University 21762SN/A * Copyright (c) 2009 The University of Edinburgh 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Timothy M. Jones 292665Ssaidi@eecs.umich.edu */ 302SN/A 312SN/A#ifndef __ARCH_POWER_INSTS_BRANCH_HH__ 322SN/A#define __ARCH_POWER_INSTS_BRANCH_HH__ 332SN/A 342SN/A#include "arch/power/insts/static_inst.hh" 351984SN/A 36857SN/Anamespace PowerISA 375952Ssaidi@eecs.umich.edu{ 381984SN/A 396214Snate@binkert.org/** 402SN/A * Base class for instructions whose disassembly is not purely a 411984SN/A * function of the machine instruction (i.e., it depends on the 422SN/A * PC). This class overrides the disassemble() method to check 432SN/A * the PC and symbol table values before re-using a cached 441912SN/A * disassembly string. This is necessary for branches and jumps, 452130SN/A * where the disassembly string includes the target address (which 46857SN/A * may depend on the PC and/or symbol table). 472SN/A */ 481912SN/Aclass PCDependentDisassembly : public PowerStaticInst 492SN/A{ 502SN/A protected: 512SN/A /// Cached program counter from last disassembly 521912SN/A mutable Addr cachedPC; 531912SN/A /// Cached symbol table pointer from last disassembly 541912SN/A mutable const SymbolTable *cachedSymtab; 551912SN/A 561912SN/A /// Constructor 571912SN/A PCDependentDisassembly(const char *mnem, ExtMachInst _machInst, 581912SN/A OpClass __opClass) 591912SN/A : PowerStaticInst(mnem, _machInst, __opClass), 601912SN/A cachedPC(0), cachedSymtab(0) 611912SN/A { 621912SN/A } 631912SN/A 641912SN/A const std::string & 651912SN/A disassemble(Addr pc, const SymbolTable *symtab) const; 662SN/A}; 672SN/A 682SN/A/** 692SN/A * Base class for unconditional, PC-relative branches. 702SN/A */ 711984SN/Aclass BranchPCRel : public PCDependentDisassembly 722SN/A{ 732SN/A protected: 742SN/A 751912SN/A /// Displacement 761912SN/A uint32_t disp; 771912SN/A 781912SN/A /// Constructor. 791984SN/A BranchPCRel(const char *mnem, MachInst _machInst, OpClass __opClass) 801984SN/A : PCDependentDisassembly(mnem, _machInst, __opClass), 811984SN/A disp(machInst.li << 2) 821984SN/A { 831984SN/A // If bit 26 is 1 then sign extend 841912SN/A if (disp & 0x2000000) { 851912SN/A disp |= 0xfc000000; 861912SN/A } 871912SN/A } 881912SN/A 891912SN/A PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override; 901912SN/A 911912SN/A /// Explicitly import the otherwise hidden branchTarget 921912SN/A using StaticInst::branchTarget; 931912SN/A 941912SN/A std::string generateDisassembly( 951912SN/A Addr pc, const SymbolTable *symtab) const override; 961912SN/A}; 971912SN/A 981912SN/A/** 991912SN/A * Base class for unconditional, non PC-relative branches. 1001912SN/A */ 1011912SN/Aclass BranchNonPCRel : public PCDependentDisassembly 1021912SN/A{ 1031912SN/A protected: 1041912SN/A 1051912SN/A /// Target address 1061158SN/A uint32_t targetAddr; 1071158SN/A 1082982Sstever@eecs.umich.edu /// Constructor. 1092982Sstever@eecs.umich.edu BranchNonPCRel(const char *mnem, MachInst _machInst, OpClass __opClass) 1102982Sstever@eecs.umich.edu : PCDependentDisassembly(mnem, _machInst, __opClass), 1112982Sstever@eecs.umich.edu targetAddr(machInst.li << 2) 1122982Sstever@eecs.umich.edu { 1131158SN/A // If bit 26 is 1 then sign extend 1141912SN/A if (targetAddr & 0x2000000) { 1151912SN/A targetAddr |= 0xfc000000; 1161912SN/A } 1171912SN/A } 1181912SN/A 1191912SN/A PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override; 1201912SN/A 1211912SN/A /// Explicitly import the otherwise hidden branchTarget 1221912SN/A using StaticInst::branchTarget; 1231912SN/A 1241912SN/A std::string generateDisassembly( 1251912SN/A Addr pc, const SymbolTable *symtab) const override; 1261912SN/A}; 1271912SN/A 1281158SN/A/** 1291158SN/A * Base class for conditional branches. 1302982Sstever@eecs.umich.edu */ 1311912SN/Aclass BranchCond : public PCDependentDisassembly 1321912SN/A{ 1331158SN/A protected: 1341912SN/A 1351912SN/A /// Fields needed for conditions 1361912SN/A uint32_t bo; 1371912SN/A uint32_t bi; 1381912SN/A 1391912SN/A /// Constructor. 1401912SN/A BranchCond(const char *mnem, MachInst _machInst, OpClass __opClass) 1411912SN/A : PCDependentDisassembly(mnem, _machInst, __opClass), 1421158SN/A bo(machInst.bo), 1431158SN/A bi(machInst.bi) 1441158SN/A { 1451912SN/A } 1461912SN/A 1471912SN/A inline bool 1481912SN/A ctrOk(uint32_t& ctr) const 1491912SN/A { 1501912SN/A bool ctr_ok; 1511912SN/A if (bo & 4) { 1521912SN/A ctr_ok = true; 1531912SN/A } else { 1541912SN/A ctr--; 1551912SN/A if (ctr != 0) { 1561912SN/A ctr_ok = ((bo & 2) == 0); 1571912SN/A } else { 1581912SN/A ctr_ok = ((bo & 2) != 0); 1591912SN/A } 1601912SN/A } 1611912SN/A return ctr_ok; 1621912SN/A } 1631912SN/A 1641912SN/A inline bool 1651912SN/A condOk(uint32_t cr) const 1661912SN/A { 1671912SN/A bool cond_ok; 1681912SN/A if (bo & 16) { 1692SN/A cond_ok = true; 1702SN/A } else { 1711158SN/A cond_ok = (((cr >> (31 - bi)) & 1) == ((bo >> 3) & 1)); 1721158SN/A } 1731158SN/A return cond_ok; 1741158SN/A } 1751158SN/A}; 1761158SN/A 1772SN/A/** 178 * Base class for conditional, PC-relative branches. 179 */ 180class BranchPCRelCond : public BranchCond 181{ 182 protected: 183 184 /// Displacement 185 uint32_t disp; 186 187 /// Constructor. 188 BranchPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass) 189 : BranchCond(mnem, _machInst, __opClass), 190 disp(machInst.bd << 2) 191 { 192 // If bit 16 is 1 then sign extend 193 if (disp & 0x8000) { 194 disp |= 0xffff0000; 195 } 196 } 197 198 PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override; 199 200 /// Explicitly import the otherwise hidden branchTarget 201 using StaticInst::branchTarget; 202 203 std::string generateDisassembly( 204 Addr pc, const SymbolTable *symtab) const override; 205}; 206 207/** 208 * Base class for conditional, non PC-relative branches. 209 */ 210class BranchNonPCRelCond : public BranchCond 211{ 212 protected: 213 214 /// Target address 215 uint32_t targetAddr; 216 217 /// Constructor. 218 BranchNonPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass) 219 : BranchCond(mnem, _machInst, __opClass), 220 targetAddr(machInst.bd << 2) 221 { 222 // If bit 16 is 1 then sign extend 223 if (targetAddr & 0x8000) { 224 targetAddr |= 0xffff0000; 225 } 226 } 227 228 PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const override; 229 230 /// Explicitly import the otherwise hidden branchTarget 231 using StaticInst::branchTarget; 232 233 std::string generateDisassembly( 234 Addr pc, const SymbolTable *symtab) const override; 235}; 236 237/** 238 * Base class for conditional, register-based branches 239 */ 240class BranchRegCond : public BranchCond 241{ 242 protected: 243 244 /// Constructor. 245 BranchRegCond(const char *mnem, MachInst _machInst, OpClass __opClass) 246 : BranchCond(mnem, _machInst, __opClass) 247 { 248 } 249 250 PowerISA::PCState branchTarget(ThreadContext *tc) const override; 251 252 /// Explicitly import the otherwise hidden branchTarget 253 using StaticInst::branchTarget; 254 255 std::string generateDisassembly( 256 Addr pc, const SymbolTable *symtab) const override; 257}; 258 259} // namespace PowerISA 260 261#endif //__ARCH_POWER_INSTS_BRANCH_HH__ 262