static_inst.cc (10934:5af8f40d8f2c) static_inst.cc (10935:acd48ddd725f)
1/*
2 * Copyright (c) 2010-2014 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
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
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:
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 }
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 ccprintf(os, "cc_%s", ArmISA::ccRegName[rel_reg]);
339 break;
1/*
2 * Copyright (c) 2010-2014 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
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
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:
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 }
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 ccprintf(os, "cc_%s", ArmISA::ccRegName[rel_reg]);
339 break;
340 case VectorRegClass:
341 panic("ARM ISA does not have any vector registers yet!");
342 }
343}
344
345void
346ArmStaticInst::printMnemonic(std::ostream &os,
347 const std::string &suffix,
348 bool withPred,
349 bool withCond64,
350 ConditionCode cond64) const
351{
352 os << " " << mnemonic;
353 if (withPred && !aarch64) {
354 printCondition(os, machInst.condCode);
355 os << suffix;
356 } else if (withCond64) {
357 os << ".";
358 printCondition(os, cond64);
359 os << suffix;
360 }
361 if (machInst.bigThumb)
362 os << ".w";
363 os << " ";
364}
365
366void
367ArmStaticInst::printTarget(std::ostream &os, Addr target,
368 const SymbolTable *symtab) const
369{
370 Addr symbolAddr;
371 std::string symbol;
372
373 if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) {
374 ccprintf(os, "<%s", symbol);
375 if (symbolAddr != target)
376 ccprintf(os, "+%d>", target - symbolAddr);
377 else
378 ccprintf(os, ">");
379 } else {
380 ccprintf(os, "%#x", target);
381 }
382}
383
384void
385ArmStaticInst::printCondition(std::ostream &os,
386 unsigned code,
387 bool noImplicit) const
388{
389 switch (code) {
390 case COND_EQ:
391 os << "eq";
392 break;
393 case COND_NE:
394 os << "ne";
395 break;
396 case COND_CS:
397 os << "cs";
398 break;
399 case COND_CC:
400 os << "cc";
401 break;
402 case COND_MI:
403 os << "mi";
404 break;
405 case COND_PL:
406 os << "pl";
407 break;
408 case COND_VS:
409 os << "vs";
410 break;
411 case COND_VC:
412 os << "vc";
413 break;
414 case COND_HI:
415 os << "hi";
416 break;
417 case COND_LS:
418 os << "ls";
419 break;
420 case COND_GE:
421 os << "ge";
422 break;
423 case COND_LT:
424 os << "lt";
425 break;
426 case COND_GT:
427 os << "gt";
428 break;
429 case COND_LE:
430 os << "le";
431 break;
432 case COND_AL:
433 // This one is implicit.
434 if (noImplicit)
435 os << "al";
436 break;
437 case COND_UC:
438 // Unconditional.
439 if (noImplicit)
440 os << "uc";
441 break;
442 default:
443 panic("Unrecognized condition code %d.\n", code);
444 }
445}
446
447void
448ArmStaticInst::printMemSymbol(std::ostream &os,
449 const SymbolTable *symtab,
450 const std::string &prefix,
451 const Addr addr,
452 const std::string &suffix) const
453{
454 Addr symbolAddr;
455 std::string symbol;
456 if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
457 ccprintf(os, "%s%s", prefix, symbol);
458 if (symbolAddr != addr)
459 ccprintf(os, "+%d", addr - symbolAddr);
460 ccprintf(os, suffix);
461 }
462}
463
464void
465ArmStaticInst::printShiftOperand(std::ostream &os,
466 IntRegIndex rm,
467 bool immShift,
468 uint32_t shiftAmt,
469 IntRegIndex rs,
470 ArmShiftType type) const
471{
472 bool firstOp = false;
473
474 if (rm != INTREG_ZERO) {
475 printReg(os, rm);
476 }
477
478 bool done = false;
479
480 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
481 shiftAmt = 32;
482
483 switch (type) {
484 case LSL:
485 if (immShift && shiftAmt == 0) {
486 done = true;
487 break;
488 }
489 if (!firstOp)
490 os << ", ";
491 os << "LSL";
492 break;
493 case LSR:
494 if (!firstOp)
495 os << ", ";
496 os << "LSR";
497 break;
498 case ASR:
499 if (!firstOp)
500 os << ", ";
501 os << "ASR";
502 break;
503 case ROR:
504 if (immShift && shiftAmt == 0) {
505 if (!firstOp)
506 os << ", ";
507 os << "RRX";
508 done = true;
509 break;
510 }
511 if (!firstOp)
512 os << ", ";
513 os << "ROR";
514 break;
515 default:
516 panic("Tried to disassemble unrecognized shift type.\n");
517 }
518 if (!done) {
519 if (!firstOp)
520 os << " ";
521 if (immShift)
522 os << "#" << shiftAmt;
523 else
524 printReg(os, rs);
525 }
526}
527
528void
529ArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
530 IntRegIndex rm, ArmExtendType type,
531 int64_t shiftAmt) const
532{
533 if (!firstOperand)
534 ccprintf(os, ", ");
535 printReg(os, rm);
536 if (type == UXTX && shiftAmt == 0)
537 return;
538 switch (type) {
539 case UXTB: ccprintf(os, ", UXTB");
540 break;
541 case UXTH: ccprintf(os, ", UXTH");
542 break;
543 case UXTW: ccprintf(os, ", UXTW");
544 break;
545 case UXTX: ccprintf(os, ", LSL");
546 break;
547 case SXTB: ccprintf(os, ", SXTB");
548 break;
549 case SXTH: ccprintf(os, ", SXTH");
550 break;
551 case SXTW: ccprintf(os, ", SXTW");
552 break;
553 case SXTX: ccprintf(os, ", SXTW");
554 break;
555 }
556 if (type == UXTX || shiftAmt)
557 ccprintf(os, " #%d", shiftAmt);
558}
559
560void
561ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
562 bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
563 IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
564 ArmShiftType type, uint32_t imm) const
565{
566 printMnemonic(os, s ? "s" : "");
567 bool firstOp = true;
568
569 // Destination
570 if (rd != INTREG_ZERO) {
571 firstOp = false;
572 printReg(os, rd);
573 }
574
575 // Source 1.
576 if (rn != INTREG_ZERO) {
577 if (!firstOp)
578 os << ", ";
579 firstOp = false;
580 printReg(os, rn);
581 }
582
583 if (!firstOp)
584 os << ", ";
585 if (withImm) {
586 ccprintf(os, "#%d", imm);
587 } else {
588 printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
589 }
590}
591
592std::string
593ArmStaticInst::generateDisassembly(Addr pc,
594 const SymbolTable *symtab) const
595{
596 std::stringstream ss;
597 printMnemonic(ss);
598 return ss.str();
599}
600}
340 }
341}
342
343void
344ArmStaticInst::printMnemonic(std::ostream &os,
345 const std::string &suffix,
346 bool withPred,
347 bool withCond64,
348 ConditionCode cond64) const
349{
350 os << " " << mnemonic;
351 if (withPred && !aarch64) {
352 printCondition(os, machInst.condCode);
353 os << suffix;
354 } else if (withCond64) {
355 os << ".";
356 printCondition(os, cond64);
357 os << suffix;
358 }
359 if (machInst.bigThumb)
360 os << ".w";
361 os << " ";
362}
363
364void
365ArmStaticInst::printTarget(std::ostream &os, Addr target,
366 const SymbolTable *symtab) const
367{
368 Addr symbolAddr;
369 std::string symbol;
370
371 if (symtab && symtab->findNearestSymbol(target, symbol, symbolAddr)) {
372 ccprintf(os, "<%s", symbol);
373 if (symbolAddr != target)
374 ccprintf(os, "+%d>", target - symbolAddr);
375 else
376 ccprintf(os, ">");
377 } else {
378 ccprintf(os, "%#x", target);
379 }
380}
381
382void
383ArmStaticInst::printCondition(std::ostream &os,
384 unsigned code,
385 bool noImplicit) const
386{
387 switch (code) {
388 case COND_EQ:
389 os << "eq";
390 break;
391 case COND_NE:
392 os << "ne";
393 break;
394 case COND_CS:
395 os << "cs";
396 break;
397 case COND_CC:
398 os << "cc";
399 break;
400 case COND_MI:
401 os << "mi";
402 break;
403 case COND_PL:
404 os << "pl";
405 break;
406 case COND_VS:
407 os << "vs";
408 break;
409 case COND_VC:
410 os << "vc";
411 break;
412 case COND_HI:
413 os << "hi";
414 break;
415 case COND_LS:
416 os << "ls";
417 break;
418 case COND_GE:
419 os << "ge";
420 break;
421 case COND_LT:
422 os << "lt";
423 break;
424 case COND_GT:
425 os << "gt";
426 break;
427 case COND_LE:
428 os << "le";
429 break;
430 case COND_AL:
431 // This one is implicit.
432 if (noImplicit)
433 os << "al";
434 break;
435 case COND_UC:
436 // Unconditional.
437 if (noImplicit)
438 os << "uc";
439 break;
440 default:
441 panic("Unrecognized condition code %d.\n", code);
442 }
443}
444
445void
446ArmStaticInst::printMemSymbol(std::ostream &os,
447 const SymbolTable *symtab,
448 const std::string &prefix,
449 const Addr addr,
450 const std::string &suffix) const
451{
452 Addr symbolAddr;
453 std::string symbol;
454 if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
455 ccprintf(os, "%s%s", prefix, symbol);
456 if (symbolAddr != addr)
457 ccprintf(os, "+%d", addr - symbolAddr);
458 ccprintf(os, suffix);
459 }
460}
461
462void
463ArmStaticInst::printShiftOperand(std::ostream &os,
464 IntRegIndex rm,
465 bool immShift,
466 uint32_t shiftAmt,
467 IntRegIndex rs,
468 ArmShiftType type) const
469{
470 bool firstOp = false;
471
472 if (rm != INTREG_ZERO) {
473 printReg(os, rm);
474 }
475
476 bool done = false;
477
478 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
479 shiftAmt = 32;
480
481 switch (type) {
482 case LSL:
483 if (immShift && shiftAmt == 0) {
484 done = true;
485 break;
486 }
487 if (!firstOp)
488 os << ", ";
489 os << "LSL";
490 break;
491 case LSR:
492 if (!firstOp)
493 os << ", ";
494 os << "LSR";
495 break;
496 case ASR:
497 if (!firstOp)
498 os << ", ";
499 os << "ASR";
500 break;
501 case ROR:
502 if (immShift && shiftAmt == 0) {
503 if (!firstOp)
504 os << ", ";
505 os << "RRX";
506 done = true;
507 break;
508 }
509 if (!firstOp)
510 os << ", ";
511 os << "ROR";
512 break;
513 default:
514 panic("Tried to disassemble unrecognized shift type.\n");
515 }
516 if (!done) {
517 if (!firstOp)
518 os << " ";
519 if (immShift)
520 os << "#" << shiftAmt;
521 else
522 printReg(os, rs);
523 }
524}
525
526void
527ArmStaticInst::printExtendOperand(bool firstOperand, std::ostream &os,
528 IntRegIndex rm, ArmExtendType type,
529 int64_t shiftAmt) const
530{
531 if (!firstOperand)
532 ccprintf(os, ", ");
533 printReg(os, rm);
534 if (type == UXTX && shiftAmt == 0)
535 return;
536 switch (type) {
537 case UXTB: ccprintf(os, ", UXTB");
538 break;
539 case UXTH: ccprintf(os, ", UXTH");
540 break;
541 case UXTW: ccprintf(os, ", UXTW");
542 break;
543 case UXTX: ccprintf(os, ", LSL");
544 break;
545 case SXTB: ccprintf(os, ", SXTB");
546 break;
547 case SXTH: ccprintf(os, ", SXTH");
548 break;
549 case SXTW: ccprintf(os, ", SXTW");
550 break;
551 case SXTX: ccprintf(os, ", SXTW");
552 break;
553 }
554 if (type == UXTX || shiftAmt)
555 ccprintf(os, " #%d", shiftAmt);
556}
557
558void
559ArmStaticInst::printDataInst(std::ostream &os, bool withImm,
560 bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
561 IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
562 ArmShiftType type, uint32_t imm) const
563{
564 printMnemonic(os, s ? "s" : "");
565 bool firstOp = true;
566
567 // Destination
568 if (rd != INTREG_ZERO) {
569 firstOp = false;
570 printReg(os, rd);
571 }
572
573 // Source 1.
574 if (rn != INTREG_ZERO) {
575 if (!firstOp)
576 os << ", ";
577 firstOp = false;
578 printReg(os, rn);
579 }
580
581 if (!firstOp)
582 os << ", ";
583 if (withImm) {
584 ccprintf(os, "#%d", imm);
585 } else {
586 printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
587 }
588}
589
590std::string
591ArmStaticInst::generateDisassembly(Addr pc,
592 const SymbolTable *symtab) const
593{
594 std::stringstream ss;
595 printMnemonic(ss);
596 return ss.str();
597}
598}