branch.isa (6243:3a1698fbbc9f) | branch.isa (6253:988a001820f8) |
---|---|
1// -*- mode:c++ -*- 2 3// Copyright (c) 2007-2008 The Florida State University 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright --- 19 unchanged lines hidden (view full) --- 28// 29// Authors: Stephen Hines 30 31//////////////////////////////////////////////////////////////////// 32// 33// Control transfer instructions 34// 35 | 1// -*- mode:c++ -*- 2 3// Copyright (c) 2007-2008 The Florida State University 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright --- 19 unchanged lines hidden (view full) --- 28// 29// Authors: Stephen Hines 30 31//////////////////////////////////////////////////////////////////// 32// 33// Control transfer instructions 34// 35 |
36output header {{ 37 38#include <iostream> 39 40 /** 41 * Base class for instructions whose disassembly is not purely a 42 * function of the machine instruction (i.e., it depends on the 43 * PC). This class overrides the disassemble() method to check 44 * the PC and symbol table values before re-using a cached 45 * disassembly string. This is necessary for branches and jumps, 46 * where the disassembly string includes the target address (which 47 * may depend on the PC and/or symbol table). 48 */ 49 class PCDependentDisassembly : public PredOp 50 { 51 protected: 52 /// Cached program counter from last disassembly 53 mutable Addr cachedPC; 54 55 /// Cached symbol table pointer from last disassembly 56 mutable const SymbolTable *cachedSymtab; 57 58 /// Constructor 59 PCDependentDisassembly(const char *mnem, MachInst _machInst, 60 OpClass __opClass) 61 : PredOp(mnem, _machInst, __opClass), 62 cachedPC(0), cachedSymtab(0) 63 { 64 } 65 66 const std::string & 67 disassemble(Addr pc, const SymbolTable *symtab) const; 68 }; 69 70 /** 71 * Base class for branches (PC-relative control transfers), 72 * conditional or unconditional. 73 */ 74 class Branch : public PCDependentDisassembly 75 { 76 protected: 77 /// target address (signed) Displacement . 78 int32_t disp; 79 80 /// Constructor. 81 Branch(const char *mnem, MachInst _machInst, OpClass __opClass) 82 : PCDependentDisassembly(mnem, _machInst, __opClass), 83 disp(OFFSET << 2) 84 { 85 //If Bit 26 is 1 then Sign Extend 86 if ( (disp & 0x02000000) > 0 ) { 87 disp |= 0xFC000000; 88 } 89 } 90 91 Addr branchTarget(Addr branchPC) const; 92 93 std::string 94 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 95 }; 96 97 /** 98 * Base class for branch and exchange instructions on the ARM 99 */ 100 class BranchExchange : public PredOp 101 { 102 protected: 103 /// Constructor 104 BranchExchange(const char *mnem, MachInst _machInst, 105 OpClass __opClass) 106 : PredOp(mnem, _machInst, __opClass) 107 { 108 } 109 110 std::string 111 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 112 }; 113 114 115 /** 116 * Base class for jumps (register-indirect control transfers). In 117 * the Arm ISA, these are always unconditional. 118 */ 119 class Jump : public PCDependentDisassembly 120 { 121 protected: 122 123 /// Displacement to target address (signed). 124 int32_t disp; 125 126 uint32_t target; 127 128 public: 129 /// Constructor 130 Jump(const char *mnem, MachInst _machInst, OpClass __opClass) 131 : PCDependentDisassembly(mnem, _machInst, __opClass), 132 disp(OFFSET << 2) 133 { 134 } 135 136 Addr branchTarget(ThreadContext *tc) const; 137 138 std::string 139 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 140 }; 141}}; 142 143output decoder {{ 144 Addr 145 Branch::branchTarget(Addr branchPC) const 146 { 147 return branchPC + 8 + disp; 148 } 149 150 Addr 151 Jump::branchTarget(ThreadContext *tc) const 152 { 153 Addr NPC = tc->readPC() + 8; 154 uint64_t Rb = tc->readIntReg(_srcRegIdx[0]); 155 return (Rb & ~3) | (NPC & 1); 156 } 157 158 const std::string & 159 PCDependentDisassembly::disassemble(Addr pc, 160 const SymbolTable *symtab) const 161 { 162 if (!cachedDisassembly || 163 pc != cachedPC || symtab != cachedSymtab) 164 { 165 if (cachedDisassembly) 166 delete cachedDisassembly; 167 168 cachedDisassembly = 169 new std::string(generateDisassembly(pc, symtab)); 170 cachedPC = pc; 171 cachedSymtab = symtab; 172 } 173 174 return *cachedDisassembly; 175 } 176 177 std::string 178 Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const 179 { 180 std::stringstream ss; 181 182 ccprintf(ss, "%-10s ", mnemonic); 183 184 Addr target = pc + 8 + disp; 185 186 std::string str; 187 if (symtab && symtab->findSymbol(target, str)) 188 ss << str; 189 else 190 ccprintf(ss, "0x%x", target); 191 192 return ss.str(); 193 } 194 195 std::string 196 BranchExchange::generateDisassembly(Addr pc, const SymbolTable *symtab) const 197 { 198 std::stringstream ss; 199 200 ccprintf(ss, "%-10s ", mnemonic); 201 202 if (_numSrcRegs > 0) { 203 printReg(ss, _srcRegIdx[0]); 204 } 205 206 return ss.str(); 207 } 208 209 std::string 210 Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const 211 { 212 std::stringstream ss; 213 214 ccprintf(ss, "%-10s ", mnemonic); 215 216 return ss.str(); 217 } 218}}; 219 | |
220def format Branch(code,*opt_flags) {{ 221 222 #Build Instruction Flags 223 #Use Link & Likely Flags to Add Link/Condition Code 224 inst_flags = ('IsDirectControl', ) 225 for x in opt_flags: 226 if x == 'Link': 227 code += 'LR = NPC;\n' --- 80 unchanged lines hidden --- | 36def format Branch(code,*opt_flags) {{ 37 38 #Build Instruction Flags 39 #Use Link & Likely Flags to Add Link/Condition Code 40 inst_flags = ('IsDirectControl', ) 41 for x in opt_flags: 42 if x == 'Link': 43 code += 'LR = NPC;\n' --- 80 unchanged lines hidden --- |