static_inst.cc (9920:028e4da64b42) static_inst.cc (10037:5cac77888310)
1/*
1/*
2 * Copyright (c) 2010 ARM Limited
2 * Copyright (c) 2010-2013 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
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
89int64_t
90ArmStaticInst::shiftReg64(uint64_t base, uint64_t shiftAmt,
91 ArmShiftType type, uint8_t width) const
92{
93 shiftAmt = shiftAmt % width;
94 ArmShiftType shiftType;
95 shiftType = (ArmShiftType)type;
96
97 switch (shiftType)
98 {
99 case LSL:
100 return base << shiftAmt;
101 case LSR:
102 if (shiftAmt == 0)
103 return base;
104 else
105 return (base & mask(width)) >> shiftAmt;
106 case ASR:
107 if (shiftAmt == 0) {
108 return base;
109 } else {
110 int sign_bit = bits(base, intWidth - 1);
111 base >>= shiftAmt;
112 base = sign_bit ? (base | ~mask(intWidth - shiftAmt)) : base;
113 return base & mask(intWidth);
114 }
115 case ROR:
116 if (shiftAmt == 0)
117 return base;
118 else
119 return (base << (width - shiftAmt)) | (base >> shiftAmt);
120 default:
121 ccprintf(std::cerr, "Unhandled shift type\n");
122 exit(1);
123 break;
124 }
125 return 0;
126}
127
128int64_t
129ArmStaticInst::extendReg64(uint64_t base, ArmExtendType type,
130 uint64_t shiftAmt, uint8_t width) const
131{
132 bool sign_extend = false;
133 int len = 0;
134 switch (type) {
135 case UXTB:
136 len = 8;
137 break;
138 case UXTH:
139 len = 16;
140 break;
141 case UXTW:
142 len = 32;
143 break;
144 case UXTX:
145 len = 64;
146 break;
147 case SXTB:
148 len = 8;
149 sign_extend = true;
150 break;
151 case SXTH:
152 len = 16;
153 sign_extend = true;
154 break;
155 case SXTW:
156 len = 32;
157 sign_extend = true;
158 break;
159 case SXTX:
160 len = 64;
161 sign_extend = true;
162 break;
163 }
164 len = len <= width - shiftAmt ? len : width - shiftAmt;
165 uint64_t tmp = (uint64_t) bits(base, len - 1, 0) << shiftAmt;
166 if (sign_extend) {
167 int sign_bit = bits(tmp, len + shiftAmt - 1);
168 tmp = sign_bit ? (tmp | ~mask(len + shiftAmt)) : tmp;
169 }
170 return tmp & mask(width);
171}
172
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:
173// Shift Rm by Rs
174int32_t
175ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
176 uint32_t type, uint32_t cfval) const
177{
178 enum ArmShiftType shiftType;
179 shiftType = (enum ArmShiftType) type;
180
181 switch (shiftType)
182 {
183 case LSL:
184 if (shamt >= 32)
185 return 0;
186 else
187 return base << shamt;
188 case LSR:
189 if (shamt >= 32)
190 return 0;
191 else
192 return base >> shamt;
193 case ASR:
194 if (shamt >= 32)
195 return (base >> 31) | -((base & (1 << 31)) >> 31);
196 else
197 return (base >> shamt) | -((base & (1 << 31)) >> shamt);
198 case ROR:
199 shamt = shamt & 0x1f;
200 if (shamt == 0)
201 return base;
202 else
203 return (base << (32 - shamt)) | (base >> shamt);
204 default:
205 ccprintf(std::cerr, "Unhandled shift type\n");
206 exit(1);
207 break;
208 }
209 return 0;
210}
211
212
213// Generate C for a shift by immediate
214bool
215ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
216 uint32_t type, uint32_t cfval) const
217{
218 enum ArmShiftType shiftType;
219 shiftType = (enum ArmShiftType) type;
220
221 switch (shiftType)
222 {
223 case LSL:
224 if (shamt == 0)
225 return cfval;
226 else
227 return (base >> (32 - shamt)) & 1;
228 case LSR:
229 if (shamt == 0)
230 return (base >> 31);
231 else
232 return (base >> (shamt - 1)) & 1;
233 case ASR:
234 if (shamt == 0)
235 return (base >> 31);
236 else
237 return (base >> (shamt - 1)) & 1;
238 case ROR:
239 shamt = shamt & 0x1f;
240 if (shamt == 0)
241 return (base & 1); // RRX
242 else
243 return (base >> (shamt - 1)) & 1;
244 default:
245 ccprintf(std::cerr, "Unhandled shift type\n");
246 exit(1);
247 break;
248 }
249 return 0;
250}
251
252
253// Generate C for a shift by Rs
254bool
255ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
256 uint32_t type, uint32_t cfval) const
257{
258 enum ArmShiftType shiftType;
259 shiftType = (enum ArmShiftType) type;
260
261 if (shamt == 0)
262 return cfval;
263
264 switch (shiftType)
265 {
266 case LSL:
267 if (shamt > 32)
268 return 0;
269 else
270 return (base >> (32 - shamt)) & 1;
271 case LSR:
272 if (shamt > 32)
273 return 0;
274 else
275 return (base >> (shamt - 1)) & 1;
276 case ASR:
277 if (shamt > 32)
278 shamt = 32;
279 return (base >> (shamt - 1)) & 1;
280 case ROR:
281 shamt = shamt & 0x1f;
282 if (shamt == 0)
283 shamt = 32;
284 return (base >> (shamt - 1)) & 1;
285 default:
286 ccprintf(std::cerr, "Unhandled shift type\n");
287 exit(1);
288 break;
289 }
290 return 0;
291}
292
293
294void
295ArmStaticInst::printReg(std::ostream &os, int reg) const
296{
297 RegIndex rel_reg;
298
299 switch (regIdxToClass(reg, &rel_reg)) {
300 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;
301 if (aarch64) {
302 if (reg == INTREG_UREG0)
303 ccprintf(os, "ureg0");
304 else if (reg == INTREG_SPX)
305 ccprintf(os, "%s%s", (intWidth == 32) ? "w" : "", "sp");
306 else if (reg == INTREG_X31)
307 ccprintf(os, "%szr", (intWidth == 32) ? "w" : "x");
308 else
309 ccprintf(os, "%s%d", (intWidth == 32) ? "w" : "x", reg);
310 } else {
311 switch (rel_reg) {
312 case PCReg:
313 ccprintf(os, "pc");
314 break;
315 case StackPointerReg:
316 ccprintf(os, "sp");
317 break;
318 case FramePointerReg:
319 ccprintf(os, "fp");
320 break;
321 case ReturnAddressReg:
322 ccprintf(os, "lr");
323 break;
324 default:
325 ccprintf(os, "r%d", reg);
326 break;
327 }
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 case CCRegClass:
243 panic("printReg: CCRegClass but ARM has no CC regs\n");
244 }
245}
246
247void
248ArmStaticInst::printMnemonic(std::ostream &os,
249 const std::string &suffix,
328 }
329 break;
330 case FloatRegClass:
331 ccprintf(os, "f%d", rel_reg);
332 break;
333 case MiscRegClass:
334 assert(rel_reg < NUM_MISCREGS);
335 ccprintf(os, "%s", ArmISA::miscRegName[rel_reg]);
336 break;
337 case CCRegClass:
338 panic("printReg: CCRegClass but ARM has no CC regs\n");
339 }
340}
341
342void
343ArmStaticInst::printMnemonic(std::ostream &os,
344 const std::string &suffix,
250 bool withPred) const
345 bool withPred,
346 bool withCond64,
347 ConditionCode cond64) const
251{
252 os << " " << mnemonic;
348{
349 os << " " << mnemonic;
253 if (withPred) {
254 unsigned condCode = machInst.condCode;
255 switch (condCode) {
256 case COND_EQ:
257 os << "eq";
258 break;
259 case COND_NE:
260 os << "ne";
261 break;
262 case COND_CS:
263 os << "cs";
264 break;
265 case COND_CC:
266 os << "cc";
267 break;
268 case COND_MI:
269 os << "mi";
270 break;
271 case COND_PL:
272 os << "pl";
273 break;
274 case COND_VS:
275 os << "vs";
276 break;
277 case COND_VC:
278 os << "vc";
279 break;
280 case COND_HI:
281 os << "hi";
282 break;
283 case COND_LS:
284 os << "ls";
285 break;
286 case COND_GE:
287 os << "ge";
288 break;
289 case COND_LT:
290 os << "lt";
291 break;
292 case COND_GT:
293 os << "gt";
294 break;
295 case COND_LE:
296 os << "le";
297 break;
298 case COND_AL:
299 // This one is implicit.
300 break;
301 case COND_UC:
302 // Unconditional.
303 break;
304 default:
305 panic("Unrecognized condition code %d.\n", condCode);
306 }
350 if (withPred && !aarch64) {
351 printCondition(os, machInst.condCode);
307 os << suffix;
352 os << suffix;
308 if (machInst.bigThumb)
309 os << ".w";
310 os << " ";
353 } else if (withCond64) {
354 os << ".";
355 printCondition(os, cond64);
356 os << suffix;
311 }
357 }
358 if (machInst.bigThumb)
359 os << ".w";
360 os << " ";
312}
313
314void
361}
362
363void
364ArmStaticInst::printTarget(std::ostream &os, Addr target,
365 const SymbolTable *symtab) const
366{
367 Addr symbolAddr;
368 std::string symbol;
369
370 if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) {
371 ccprintf(os, "<%s", symbol);
372 if (symbolAddr != target)
373 ccprintf(os, "+%d>", target - symbolAddr);
374 else
375 ccprintf(os, ">");
376 } else {
377 ccprintf(os, "%#x", target);
378 }
379}
380
381void
382ArmStaticInst::printCondition(std::ostream &os,
383 unsigned code,
384 bool noImplicit) const
385{
386 switch (code) {
387 case COND_EQ:
388 os << "eq";
389 break;
390 case COND_NE:
391 os << "ne";
392 break;
393 case COND_CS:
394 os << "cs";
395 break;
396 case COND_CC:
397 os << "cc";
398 break;
399 case COND_MI:
400 os << "mi";
401 break;
402 case COND_PL:
403 os << "pl";
404 break;
405 case COND_VS:
406 os << "vs";
407 break;
408 case COND_VC:
409 os << "vc";
410 break;
411 case COND_HI:
412 os << "hi";
413 break;
414 case COND_LS:
415 os << "ls";
416 break;
417 case COND_GE:
418 os << "ge";
419 break;
420 case COND_LT:
421 os << "lt";
422 break;
423 case COND_GT:
424 os << "gt";
425 break;
426 case COND_LE:
427 os << "le";
428 break;
429 case COND_AL:
430 // This one is implicit.
431 if (noImplicit)
432 os << "al";
433 break;
434 case COND_UC:
435 // Unconditional.
436 if (noImplicit)
437 os << "uc";
438 break;
439 default:
440 panic("Unrecognized condition code %d.\n", code);
441 }
442}
443
444void
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,
333 IntRegIndex rm,
334 bool immShift,
335 uint32_t shiftAmt,
336 IntRegIndex rs,
337 ArmShiftType type) const
338{
339 bool firstOp = false;
340
341 if (rm != INTREG_ZERO) {
342 printReg(os, rm);
343 }
344
345 bool done = false;
346
347 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
348 shiftAmt = 32;
349
350 switch (type) {
351 case LSL:
352 if (immShift && shiftAmt == 0) {
353 done = true;
354 break;
355 }
356 if (!firstOp)
357 os << ", ";
358 os << "LSL";
359 break;
360 case LSR:
361 if (!firstOp)
362 os << ", ";
363 os << "LSR";
364 break;
365 case ASR:
366 if (!firstOp)
367 os << ", ";
368 os << "ASR";
369 break;
370 case ROR:
371 if (immShift && shiftAmt == 0) {
372 if (!firstOp)
373 os << ", ";
374 os << "RRX";
375 done = true;
376 break;
377 }
378 if (!firstOp)
379 os << ", ";
380 os << "ROR";
381 break;
382 default:
383 panic("Tried to disassemble unrecognized shift type.\n");
384 }
385 if (!done) {
386 if (!firstOp)
387 os << " ";
388 if (immShift)
389 os << "#" << shiftAmt;
390 else
391 printReg(os, rs);
392 }
393}
394
395void
445ArmStaticInst::printMemSymbol(std::ostream &os,
446 const SymbolTable *symtab,
447 const std::string &prefix,
448 const Addr addr,
449 const std::string &suffix) const
450{
451 Addr symbolAddr;
452 std::string symbol;
453 if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
454 ccprintf(os, "%s%s", prefix, symbol);
455 if (symbolAddr != addr)
456 ccprintf(os, "+%d", addr - symbolAddr);
457 ccprintf(os, suffix);
458 }
459}
460
461void
462ArmStaticInst::printShiftOperand(std::ostream &os,
463 IntRegIndex rm,
464 bool immShift,
465 uint32_t shiftAmt,
466 IntRegIndex rs,
467 ArmShiftType type) const
468{
469 bool firstOp = false;
470
471 if (rm != INTREG_ZERO) {
472 printReg(os, rm);
473 }
474
475 bool done = false;
476
477 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
478 shiftAmt = 32;
479
480 switch (type) {
481 case LSL:
482 if (immShift && shiftAmt == 0) {
483 done = true;
484 break;
485 }
486 if (!firstOp)
487 os << ", ";
488 os << "LSL";
489 break;
490 case LSR:
491 if (!firstOp)
492 os << ", ";
493 os << "LSR";
494 break;
495 case ASR:
496 if (!firstOp)
497 os << ", ";
498 os << "ASR";
499 break;
500 case ROR:
501 if (immShift && shiftAmt == 0) {
502 if (!firstOp)
503 os << ", ";
504 os << "RRX";
505 done = true;
506 break;
507 }
508 if (!firstOp)
509 os << ", ";
510 os << "ROR";
511 break;
512 default:
513 panic("Tried to disassemble unrecognized shift type.\n");
514 }
515 if (!done) {
516 if (!firstOp)
517 os << " ";
518 if (immShift)
519 os << "#" << shiftAmt;
520 else
521 printReg(os, rs);
522 }
523}
524
525void
526ArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
527 IntRegIndex rm, ArmExtendType type,
528 int64_t shiftAmt) const
529{
530 if (!firstOperand)
531 ccprintf(os, ", ");
532 printReg(os, rm);
533 if (type == UXTX && shiftAmt == 0)
534 return;
535 switch (type) {
536 case UXTB: ccprintf(os, ", UXTB");
537 break;
538 case UXTH: ccprintf(os, ", UXTH");
539 break;
540 case UXTW: ccprintf(os, ", UXTW");
541 break;
542 case UXTX: ccprintf(os, ", LSL");
543 break;
544 case SXTB: ccprintf(os, ", SXTB");
545 break;
546 case SXTH: ccprintf(os, ", SXTH");
547 break;
548 case SXTW: ccprintf(os, ", SXTW");
549 break;
550 case SXTX: ccprintf(os, ", SXTW");
551 break;
552 }
553 if (type == UXTX || shiftAmt)
554 ccprintf(os, " #%d", shiftAmt);
555}
556
557void
396ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
397 bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
398 IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
399 ArmShiftType type, uint32_t imm) const
400{
401 printMnemonic(os, s ? "s" : "");
402 bool firstOp = true;
403
404 // Destination
405 if (rd != INTREG_ZERO) {
406 firstOp = false;
407 printReg(os, rd);
408 }
409
410 // Source 1.
411 if (rn != INTREG_ZERO) {
412 if (!firstOp)
413 os << ", ";
414 firstOp = false;
415 printReg(os, rn);
416 }
417
418 if (!firstOp)
419 os << ", ";
420 if (withImm) {
421 ccprintf(os, "#%d", imm);
422 } else {
423 printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
424 }
425}
426
427std::string
428ArmStaticInst::generateDisassembly(Addr pc,
429 const SymbolTable *symtab) const
430{
431 std::stringstream ss;
432 printMnemonic(ss);
433 return ss.str();
434}
435}
558ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
559 bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
560 IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
561 ArmShiftType type, uint32_t imm) const
562{
563 printMnemonic(os, s ? "s" : "");
564 bool firstOp = true;
565
566 // Destination
567 if (rd != INTREG_ZERO) {
568 firstOp = false;
569 printReg(os, rd);
570 }
571
572 // Source 1.
573 if (rn != INTREG_ZERO) {
574 if (!firstOp)
575 os << ", ";
576 firstOp = false;
577 printReg(os, rn);
578 }
579
580 if (!firstOp)
581 os << ", ";
582 if (withImm) {
583 ccprintf(os, "#%d", imm);
584 } else {
585 printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
586 }
587}
588
589std::string
590ArmStaticInst::generateDisassembly(Addr pc,
591 const SymbolTable *symtab) const
592{
593 std::stringstream ss;
594 printMnemonic(ss);
595 return ss.str();
596}
597}