static_inst.hh revision 7400
1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2007-2008 The Florida State University 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Stephen Hines 41 */ 42#ifndef __ARCH_ARM_INSTS_STATICINST_HH__ 43#define __ARCH_ARM_INSTS_STATICINST_HH__ 44 45#include "base/trace.hh" 46#include "cpu/static_inst.hh" 47 48namespace ArmISA 49{ 50class ArmStaticInst : public StaticInst 51{ 52 protected: 53 int32_t shift_rm_imm(uint32_t base, uint32_t shamt, 54 uint32_t type, uint32_t cfval) const; 55 int32_t shift_rm_rs(uint32_t base, uint32_t shamt, 56 uint32_t type, uint32_t cfval) const; 57 58 bool shift_carry_imm(uint32_t base, uint32_t shamt, 59 uint32_t type, uint32_t cfval) const; 60 bool shift_carry_rs(uint32_t base, uint32_t shamt, 61 uint32_t type, uint32_t cfval) const; 62 63 template<int width> 64 static bool 65 saturateOp(int32_t &res, int64_t op1, int64_t op2, bool sub=false) 66 { 67 int64_t midRes = sub ? (op1 - op2) : (op1 + op2); 68 if (bits(midRes, width) != bits(midRes, width - 1)) { 69 if (midRes > 0) 70 res = (LL(1) << (width - 1)) - 1; 71 else 72 res = -(LL(1) << (width - 1)); 73 return true; 74 } else { 75 res = midRes; 76 return false; 77 } 78 } 79 80 static bool 81 satInt(int32_t &res, int64_t op, int width) 82 { 83 width--; 84 if (op >= (LL(1) << width)) { 85 res = (LL(1) << width) - 1; 86 return true; 87 } else if (op < -(LL(1) << width)) { 88 res = -(LL(1) << width); 89 return true; 90 } else { 91 res = op; 92 return false; 93 } 94 } 95 96 template<int width> 97 static bool 98 uSaturateOp(uint32_t &res, int64_t op1, int64_t op2, bool sub=false) 99 { 100 int64_t midRes = sub ? (op1 - op2) : (op1 + op2); 101 if (midRes >= (LL(1) << width)) { 102 res = (LL(1) << width) - 1; 103 return true; 104 } else if (midRes < 0) { 105 res = 0; 106 return true; 107 } else { 108 res = midRes; 109 return false; 110 } 111 } 112 113 static bool 114 uSatInt(int32_t &res, int64_t op, int width) 115 { 116 if (op >= (LL(1) << width)) { 117 res = (LL(1) << width) - 1; 118 return true; 119 } else if (op < 0) { 120 res = 0; 121 return true; 122 } else { 123 res = op; 124 return false; 125 } 126 } 127 128 // Constructor 129 ArmStaticInst(const char *mnem, ExtMachInst _machInst, 130 OpClass __opClass) 131 : StaticInst(mnem, _machInst, __opClass) 132 { 133 } 134 135 /// Print a register name for disassembly given the unique 136 /// dependence tag number (FP or int). 137 void printReg(std::ostream &os, int reg) const; 138 void printMnemonic(std::ostream &os, 139 const std::string &suffix = "", 140 bool withPred = true) const; 141 void printMemSymbol(std::ostream &os, const SymbolTable *symtab, 142 const std::string &prefix, const Addr addr, 143 const std::string &suffix) const; 144 void printShiftOperand(std::ostream &os, IntRegIndex rm, 145 bool immShift, uint32_t shiftAmt, 146 IntRegIndex rs, ArmShiftType type) const; 147 148 149 void printDataInst(std::ostream &os, bool withImm) const; 150 void printDataInst(std::ostream &os, bool withImm, bool immShift, bool s, 151 IntRegIndex rd, IntRegIndex rn, IntRegIndex rm, 152 IntRegIndex rs, uint32_t shiftAmt, ArmShiftType type, 153 uint32_t imm) const; 154 155 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 156 157 static uint32_t 158 cpsrWriteByInstr(CPSR cpsr, uint32_t val, 159 uint8_t byteMask, bool affectState, bool nmfi) 160 { 161 bool privileged = (cpsr.mode != MODE_USER); 162 163 uint32_t bitMask = 0; 164 165 if (bits(byteMask, 3)) { 166 unsigned lowIdx = affectState ? 24 : 27; 167 bitMask = bitMask | mask(31, lowIdx); 168 } 169 if (bits(byteMask, 2)) { 170 bitMask = bitMask | mask(19, 16); 171 } 172 if (bits(byteMask, 1)) { 173 unsigned highIdx = affectState ? 15 : 9; 174 unsigned lowIdx = privileged ? 8 : 9; 175 bitMask = bitMask | mask(highIdx, lowIdx); 176 } 177 if (bits(byteMask, 0)) { 178 if (privileged) { 179 bitMask = bitMask | mask(7, 6); 180 if (!badMode((OperatingMode)(val & mask(5)))) { 181 bitMask = bitMask | mask(5); 182 } else { 183 warn_once("Ignoring write of bad mode to CPSR.\n"); 184 } 185 } 186 if (affectState) 187 bitMask = bitMask | (1 << 5); 188 } 189 190 bool cpsr_f = cpsr.f; 191 uint32_t new_cpsr = ((uint32_t)cpsr & ~bitMask) | (val & bitMask); 192 if (nmfi && !cpsr_f) 193 new_cpsr &= ~(1 << 6); 194 return new_cpsr; 195 } 196 197 static uint32_t 198 spsrWriteByInstr(uint32_t spsr, uint32_t val, 199 uint8_t byteMask, bool affectState) 200 { 201 uint32_t bitMask = 0; 202 203 if (bits(byteMask, 3)) 204 bitMask = bitMask | mask(31, 24); 205 if (bits(byteMask, 2)) 206 bitMask = bitMask | mask(19, 16); 207 if (bits(byteMask, 1)) 208 bitMask = bitMask | mask(15, 8); 209 if (bits(byteMask, 0)) 210 bitMask = bitMask | mask(7, 0); 211 212 return ((spsr & ~bitMask) | (val & bitMask)); 213 } 214 215 template<class XC> 216 static Addr 217 readPC(XC *xc) 218 { 219 Addr pc = xc->readPC(); 220 Addr tBit = pc & (ULL(1) << PcTBitShift); 221 if (tBit) 222 return pc + 4; 223 else 224 return pc + 8; 225 } 226 227 // Perform an regular branch. 228 template<class XC> 229 static void 230 setNextPC(XC *xc, Addr val) 231 { 232 Addr npc = xc->readNextPC(); 233 if (npc & (ULL(1) << PcTBitShift)) { 234 val &= ~mask(1); 235 } else { 236 val &= ~mask(2); 237 } 238 xc->setNextPC((npc & PcModeMask) | 239 (val & ~PcModeMask)); 240 } 241 242 template<class T> 243 static T 244 cSwap(T val, bool big) 245 { 246 if (big) { 247 return gtobe(val); 248 } else { 249 return gtole(val); 250 } 251 } 252 253 // Perform an interworking branch. 254 template<class XC> 255 static void 256 setIWNextPC(XC *xc, Addr val) 257 { 258 Addr stateBits = xc->readPC() & PcModeMask; 259 Addr jBit = (ULL(1) << PcJBitShift); 260 Addr tBit = (ULL(1) << PcTBitShift); 261 bool thumbEE = (stateBits == (tBit | jBit)); 262 263 Addr newPc = (val & ~PcModeMask); 264 if (thumbEE) { 265 if (bits(newPc, 0)) { 266 newPc = newPc & ~mask(1); 267 } else { 268 panic("Bad thumbEE interworking branch address %#x.\n", newPc); 269 } 270 } else { 271 if (bits(newPc, 0)) { 272 stateBits = tBit; 273 newPc = newPc & ~mask(1); 274 } else if (!bits(newPc, 1)) { 275 stateBits = 0; 276 } else { 277 warn("Bad interworking branch address %#x.\n", newPc); 278 } 279 } 280 newPc = newPc | stateBits; 281 xc->setNextPC(newPc); 282 } 283 284 // Perform an interworking branch in ARM mode, a regular branch 285 // otherwise. 286 template<class XC> 287 static void 288 setAIWNextPC(XC *xc, Addr val) 289 { 290 Addr stateBits = xc->readPC() & PcModeMask; 291 Addr jBit = (ULL(1) << PcJBitShift); 292 Addr tBit = (ULL(1) << PcTBitShift); 293 if (!jBit && !tBit) { 294 setIWNextPC(xc, val); 295 } else { 296 setNextPC(xc, val); 297 } 298 } 299}; 300} 301 302#endif //__ARCH_ARM_INSTS_STATICINST_HH__ 303