static_inst.cc revision 9913
1/* 2 * Copyright (c) 2010 ARM Limited 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license 11 * terms below provided that you ensure that this notice is replicated 12 * unmodified and in its entirety in all distributions of the software, 13 * modified or unmodified, in source code or in binary form. 14 * 15 * Copyright (c) 2007-2008 The Florida State University 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; 22 * redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution; 25 * neither the name of the copyright holders nor the names of its 26 * contributors may be used to endorse or promote products derived from 27 * this software without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Authors: Stephen Hines 42 */ 43 44#include "arch/arm/insts/static_inst.hh" 45#include "arch/arm/faults.hh" 46#include "base/loader/symtab.hh" 47#include "base/condcodes.hh" 48#include "base/cprintf.hh" 49#include "cpu/reg_class.hh" 50 51namespace ArmISA 52{ 53// Shift Rm by an immediate value 54int32_t 55ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt, 56 uint32_t type, uint32_t cfval) const 57{ 58 assert(shamt < 32); 59 ArmShiftType shiftType; 60 shiftType = (ArmShiftType)type; 61 62 switch (shiftType) 63 { 64 case LSL: 65 return base << shamt; 66 case LSR: 67 if (shamt == 0) 68 return 0; 69 else 70 return base >> shamt; 71 case ASR: 72 if (shamt == 0) 73 return (base >> 31) | -((base & (1 << 31)) >> 31); 74 else 75 return (base >> shamt) | -((base & (1 << 31)) >> shamt); 76 case ROR: 77 if (shamt == 0) 78 return (cfval << 31) | (base >> 1); // RRX 79 else 80 return (base << (32 - shamt)) | (base >> shamt); 81 default: 82 ccprintf(std::cerr, "Unhandled shift type\n"); 83 exit(1); 84 break; 85 } 86 return 0; 87} 88 89// Shift Rm by Rs 90int32_t 91ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt, 92 uint32_t type, uint32_t cfval) const 93{ 94 enum ArmShiftType shiftType; 95 shiftType = (enum ArmShiftType) type; 96 97 switch (shiftType) 98 { 99 case LSL: 100 if (shamt >= 32) 101 return 0; 102 else 103 return base << shamt; 104 case LSR: 105 if (shamt >= 32) 106 return 0; 107 else 108 return base >> shamt; 109 case ASR: 110 if (shamt >= 32) 111 return (base >> 31) | -((base & (1 << 31)) >> 31); 112 else 113 return (base >> shamt) | -((base & (1 << 31)) >> shamt); 114 case ROR: 115 shamt = shamt & 0x1f; 116 if (shamt == 0) 117 return base; 118 else 119 return (base << (32 - shamt)) | (base >> shamt); 120 default: 121 ccprintf(std::cerr, "Unhandled shift type\n"); 122 exit(1); 123 break; 124 } 125 return 0; 126} 127 128 129// Generate C for a shift by immediate 130bool 131ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt, 132 uint32_t type, uint32_t cfval) const 133{ 134 enum ArmShiftType shiftType; 135 shiftType = (enum ArmShiftType) type; 136 137 switch (shiftType) 138 { 139 case LSL: 140 if (shamt == 0) 141 return cfval; 142 else 143 return (base >> (32 - shamt)) & 1; 144 case LSR: 145 if (shamt == 0) 146 return (base >> 31); 147 else 148 return (base >> (shamt - 1)) & 1; 149 case ASR: 150 if (shamt == 0) 151 return (base >> 31); 152 else 153 return (base >> (shamt - 1)) & 1; 154 case ROR: 155 shamt = shamt & 0x1f; 156 if (shamt == 0) 157 return (base & 1); // RRX 158 else 159 return (base >> (shamt - 1)) & 1; 160 default: 161 ccprintf(std::cerr, "Unhandled shift type\n"); 162 exit(1); 163 break; 164 } 165 return 0; 166} 167 168 169// Generate C for a shift by Rs 170bool 171ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt, 172 uint32_t type, uint32_t cfval) const 173{ 174 enum ArmShiftType shiftType; 175 shiftType = (enum ArmShiftType) type; 176 177 if (shamt == 0) 178 return cfval; 179 180 switch (shiftType) 181 { 182 case LSL: 183 if (shamt > 32) 184 return 0; 185 else 186 return (base >> (32 - shamt)) & 1; 187 case LSR: 188 if (shamt > 32) 189 return 0; 190 else 191 return (base >> (shamt - 1)) & 1; 192 case ASR: 193 if (shamt > 32) 194 shamt = 32; 195 return (base >> (shamt - 1)) & 1; 196 case ROR: 197 shamt = shamt & 0x1f; 198 if (shamt == 0) 199 shamt = 32; 200 return (base >> (shamt - 1)) & 1; 201 default: 202 ccprintf(std::cerr, "Unhandled shift type\n"); 203 exit(1); 204 break; 205 } 206 return 0; 207} 208 209 210void 211ArmStaticInst::printReg(std::ostream &os, int reg) const 212{ 213 RegIndex rel_reg; 214 215 switch (regIdxToClass(reg, &rel_reg)) { 216 case IntRegClass: 217 switch (rel_reg) { 218 case PCReg: 219 ccprintf(os, "pc"); 220 break; 221 case StackPointerReg: 222 ccprintf(os, "sp"); 223 break; 224 case FramePointerReg: 225 ccprintf(os, "fp"); 226 break; 227 case ReturnAddressReg: 228 ccprintf(os, "lr"); 229 break; 230 default: 231 ccprintf(os, "r%d", reg); 232 break; 233 } 234 break; 235 case FloatRegClass: 236 ccprintf(os, "f%d", rel_reg); 237 break; 238 case MiscRegClass: 239 assert(rel_reg < NUM_MISCREGS); 240 ccprintf(os, "%s", ArmISA::miscRegName[rel_reg]); 241 break; 242 } 243} 244 245void 246ArmStaticInst::printMnemonic(std::ostream &os, 247 const std::string &suffix, 248 bool withPred) const 249{ 250 os << " " << mnemonic; 251 if (withPred) { 252 unsigned condCode = machInst.condCode; 253 switch (condCode) { 254 case COND_EQ: 255 os << "eq"; 256 break; 257 case COND_NE: 258 os << "ne"; 259 break; 260 case COND_CS: 261 os << "cs"; 262 break; 263 case COND_CC: 264 os << "cc"; 265 break; 266 case COND_MI: 267 os << "mi"; 268 break; 269 case COND_PL: 270 os << "pl"; 271 break; 272 case COND_VS: 273 os << "vs"; 274 break; 275 case COND_VC: 276 os << "vc"; 277 break; 278 case COND_HI: 279 os << "hi"; 280 break; 281 case COND_LS: 282 os << "ls"; 283 break; 284 case COND_GE: 285 os << "ge"; 286 break; 287 case COND_LT: 288 os << "lt"; 289 break; 290 case COND_GT: 291 os << "gt"; 292 break; 293 case COND_LE: 294 os << "le"; 295 break; 296 case COND_AL: 297 // This one is implicit. 298 break; 299 case COND_UC: 300 // Unconditional. 301 break; 302 default: 303 panic("Unrecognized condition code %d.\n", condCode); 304 } 305 os << suffix; 306 if (machInst.bigThumb) 307 os << ".w"; 308 os << " "; 309 } 310} 311 312void 313ArmStaticInst::printMemSymbol(std::ostream &os, 314 const SymbolTable *symtab, 315 const std::string &prefix, 316 const Addr addr, 317 const std::string &suffix) const 318{ 319 Addr symbolAddr; 320 std::string symbol; 321 if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) { 322 ccprintf(os, "%s%s", prefix, symbol); 323 if (symbolAddr != addr) 324 ccprintf(os, "+%d", addr - symbolAddr); 325 ccprintf(os, suffix); 326 } 327} 328 329void 330ArmStaticInst::printShiftOperand(std::ostream &os, 331 IntRegIndex rm, 332 bool immShift, 333 uint32_t shiftAmt, 334 IntRegIndex rs, 335 ArmShiftType type) const 336{ 337 bool firstOp = false; 338 339 if (rm != INTREG_ZERO) { 340 printReg(os, rm); 341 } 342 343 bool done = false; 344 345 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0) 346 shiftAmt = 32; 347 348 switch (type) { 349 case LSL: 350 if (immShift && shiftAmt == 0) { 351 done = true; 352 break; 353 } 354 if (!firstOp) 355 os << ", "; 356 os << "LSL"; 357 break; 358 case LSR: 359 if (!firstOp) 360 os << ", "; 361 os << "LSR"; 362 break; 363 case ASR: 364 if (!firstOp) 365 os << ", "; 366 os << "ASR"; 367 break; 368 case ROR: 369 if (immShift && shiftAmt == 0) { 370 if (!firstOp) 371 os << ", "; 372 os << "RRX"; 373 done = true; 374 break; 375 } 376 if (!firstOp) 377 os << ", "; 378 os << "ROR"; 379 break; 380 default: 381 panic("Tried to disassemble unrecognized shift type.\n"); 382 } 383 if (!done) { 384 if (!firstOp) 385 os << " "; 386 if (immShift) 387 os << "#" << shiftAmt; 388 else 389 printReg(os, rs); 390 } 391} 392 393void 394ArmStaticInst::printDataInst(std::ostream &os, bool withImm, 395 bool immShift, bool s, IntRegIndex rd, IntRegIndex rn, 396 IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt, 397 ArmShiftType type, uint32_t imm) const 398{ 399 printMnemonic(os, s ? "s" : ""); 400 bool firstOp = true; 401 402 // Destination 403 if (rd != INTREG_ZERO) { 404 firstOp = false; 405 printReg(os, rd); 406 } 407 408 // Source 1. 409 if (rn != INTREG_ZERO) { 410 if (!firstOp) 411 os << ", "; 412 firstOp = false; 413 printReg(os, rn); 414 } 415 416 if (!firstOp) 417 os << ", "; 418 if (withImm) { 419 ccprintf(os, "#%d", imm); 420 } else { 421 printShiftOperand(os, rm, immShift, shiftAmt, rs, type); 422 } 423} 424 425std::string 426ArmStaticInst::generateDisassembly(Addr pc, 427 const SymbolTable *symtab) const 428{ 429 std::stringstream ss; 430 printMnemonic(ss); 431 return ss.str(); 432} 433} 434