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