static_inst.cc (7109:6670b4ab3abe) static_inst.cc (7111:ee902ae075bb)
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
43#include "arch/arm/faults.hh"
44#include "arch/arm/insts/static_inst.hh"
45#include "base/condcodes.hh"
46#include "base/cprintf.hh"
47#include "base/loader/symtab.hh"
48
49namespace ArmISA
50{
51// Shift Rm by an immediate value
52int32_t
53ArmStaticInstBase::shift_rm_imm(uint32_t base, uint32_t shamt,
54 uint32_t type, uint32_t cfval) const
55{
56 assert(shamt < 32);
57 ArmShiftType shiftType;
58 shiftType = (ArmShiftType)type;
59
60 switch (shiftType)
61 {
62 case LSL:
63 return base << shamt;
64 case LSR:
65 if (shamt == 0)
66 return 0;
67 else
68 return base >> shamt;
69 case ASR:
70 if (shamt == 0)
71 return (int32_t)base >> 31;
72 else
73 return (int32_t)base >> shamt;
74 case ROR:
75 if (shamt == 0)
76 return (cfval << 31) | (base >> 1); // RRX
77 else
78 return (base << (32 - shamt)) | (base >> shamt);
79 default:
80 ccprintf(std::cerr, "Unhandled shift type\n");
81 exit(1);
82 break;
83 }
84 return 0;
85}
86
87// Shift Rm by Rs
88int32_t
89ArmStaticInstBase::shift_rm_rs(uint32_t base, uint32_t shamt,
90 uint32_t type, uint32_t cfval) const
91{
92 enum ArmShiftType shiftType;
93 shiftType = (enum ArmShiftType) type;
94
95 switch (shiftType)
96 {
97 case LSL:
98 if (shamt >= 32)
99 return 0;
100 else
101 return base << shamt;
102 case LSR:
103 if (shamt >= 32)
104 return 0;
105 else
106 return base >> shamt;
107 case ASR:
108 if (shamt >= 32)
109 return (int32_t)base >> 31;
110 else
111 return (int32_t)base >> shamt;
112 case ROR:
113 shamt = shamt & 0x1f;
114 if (shamt == 0)
115 return base;
116 else
117 return (base << (32 - shamt)) | (base >> shamt);
118 default:
119 ccprintf(std::cerr, "Unhandled shift type\n");
120 exit(1);
121 break;
122 }
123 return 0;
124}
125
126
127// Generate C for a shift by immediate
128bool
129ArmStaticInstBase::shift_carry_imm(uint32_t base, uint32_t shamt,
130 uint32_t type, uint32_t cfval) const
131{
132 enum ArmShiftType shiftType;
133 shiftType = (enum ArmShiftType) type;
134
135 switch (shiftType)
136 {
137 case LSL:
138 if (shamt == 0)
139 return cfval;
140 else
141 return (base >> (32 - shamt)) & 1;
142 case LSR:
143 if (shamt == 0)
144 return (base >> 31);
145 else
146 return (base >> (shamt - 1)) & 1;
147 case ASR:
148 if (shamt == 0)
149 return (base >> 31);
150 else
151 return (base >> (shamt - 1)) & 1;
152 case ROR:
153 shamt = shamt & 0x1f;
154 if (shamt == 0)
155 return (base & 1); // RRX
156 else
157 return (base >> (shamt - 1)) & 1;
158 default:
159 ccprintf(std::cerr, "Unhandled shift type\n");
160 exit(1);
161 break;
162 }
163 return 0;
164}
165
166
167// Generate C for a shift by Rs
168bool
169ArmStaticInstBase::shift_carry_rs(uint32_t base, uint32_t shamt,
170 uint32_t type, uint32_t cfval) const
171{
172 enum ArmShiftType shiftType;
173 shiftType = (enum ArmShiftType) type;
174
175 if (shamt == 0)
176 return cfval;
177
178 switch (shiftType)
179 {
180 case LSL:
181 if (shamt > 32)
182 return 0;
183 else
184 return (base >> (32 - shamt)) & 1;
185 case LSR:
186 if (shamt > 32)
187 return 0;
188 else
189 return (base >> (shamt - 1)) & 1;
190 case ASR:
191 if (shamt > 32)
192 shamt = 32;
193 return (base >> (shamt - 1)) & 1;
194 case ROR:
195 shamt = shamt & 0x1f;
196 if (shamt == 0)
197 shamt = 32;
198 return (base >> (shamt - 1)) & 1;
199 default:
200 ccprintf(std::cerr, "Unhandled shift type\n");
201 exit(1);
202 break;
203 }
204 return 0;
205}
206
207
208// Generate the appropriate carry bit for an addition operation
209bool
210ArmStaticInstBase::arm_add_carry(int32_t result, int32_t lhs, int32_t rhs) const
211{
212 return findCarry(32, result, lhs, rhs);
213}
214
215// Generate the appropriate carry bit for a subtraction operation
216bool
217ArmStaticInstBase::arm_sub_carry(int32_t result, int32_t lhs, int32_t rhs) const
218{
219 return findCarry(32, result, lhs, ~rhs);
220}
221
222bool
223ArmStaticInstBase::arm_add_overflow(int32_t result, int32_t lhs, int32_t rhs) const
224{
225 return findOverflow(32, result, lhs, rhs);
226}
227
228bool
229ArmStaticInstBase::arm_sub_overflow(int32_t result, int32_t lhs, int32_t rhs) const
230{
231 return findOverflow(32, result, lhs, ~rhs);
232}
233
234uint32_t
235ArmStaticInstBase::modified_imm(uint8_t ctrlImm, uint8_t dataImm) const
236{
237 uint32_t bigData = dataImm;
238 uint32_t bigCtrl = ctrlImm;
239 if (bigCtrl < 4) {
240 switch (bigCtrl) {
241 case 0:
242 return bigData;
243 case 1:
244 return bigData | (bigData << 16);
245 case 2:
246 return (bigData << 8) | (bigData << 24);
247 case 3:
248 return (bigData << 0) | (bigData << 8) |
249 (bigData << 16) | (bigData << 24);
250 }
251 }
252 bigCtrl = (bigCtrl << 1) | ((bigData >> 7) & 0x1);
253 bigData |= (1 << 7);
254 return bigData << (32 - bigCtrl);
255}
256
257void
258ArmStaticInstBase::printReg(std::ostream &os, int reg) const
259{
260 if (reg < FP_Base_DepTag) {
261 switch (reg) {
262 case PCReg:
263 ccprintf(os, "pc");
264 break;
265 case StackPointerReg:
266 ccprintf(os, "sp");
267 break;
268 case FramePointerReg:
269 ccprintf(os, "fp");
270 break;
271 case ReturnAddressReg:
272 ccprintf(os, "lr");
273 break;
274 default:
275 ccprintf(os, "r%d", reg);
276 break;
277 }
278 } else if (reg < Ctrl_Base_DepTag) {
279 ccprintf(os, "f%d", reg - FP_Base_DepTag);
280 } else {
281 reg -= Ctrl_Base_DepTag;
282 assert(reg < NUM_MISCREGS);
283 ccprintf(os, "%s", ArmISA::miscRegName[reg]);
284 }
285}
286
287void
288ArmStaticInstBase::printMnemonic(std::ostream &os,
289 const std::string &suffix,
290 bool withPred) const
291{
292 os << " " << mnemonic;
293 if (withPred) {
294 unsigned condCode = machInst.condCode;
295 switch (condCode) {
296 case COND_EQ:
297 os << "eq";
298 break;
299 case COND_NE:
300 os << "ne";
301 break;
302 case COND_CS:
303 os << "cs";
304 break;
305 case COND_CC:
306 os << "cc";
307 break;
308 case COND_MI:
309 os << "mi";
310 break;
311 case COND_PL:
312 os << "pl";
313 break;
314 case COND_VS:
315 os << "vs";
316 break;
317 case COND_VC:
318 os << "vc";
319 break;
320 case COND_HI:
321 os << "hi";
322 break;
323 case COND_LS:
324 os << "ls";
325 break;
326 case COND_GE:
327 os << "ge";
328 break;
329 case COND_LT:
330 os << "lt";
331 break;
332 case COND_GT:
333 os << "gt";
334 break;
335 case COND_LE:
336 os << "le";
337 break;
338 case COND_AL:
339 // This one is implicit.
340 break;
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
43#include "arch/arm/faults.hh"
44#include "arch/arm/insts/static_inst.hh"
45#include "base/condcodes.hh"
46#include "base/cprintf.hh"
47#include "base/loader/symtab.hh"
48
49namespace ArmISA
50{
51// Shift Rm by an immediate value
52int32_t
53ArmStaticInstBase::shift_rm_imm(uint32_t base, uint32_t shamt,
54 uint32_t type, uint32_t cfval) const
55{
56 assert(shamt < 32);
57 ArmShiftType shiftType;
58 shiftType = (ArmShiftType)type;
59
60 switch (shiftType)
61 {
62 case LSL:
63 return base << shamt;
64 case LSR:
65 if (shamt == 0)
66 return 0;
67 else
68 return base >> shamt;
69 case ASR:
70 if (shamt == 0)
71 return (int32_t)base >> 31;
72 else
73 return (int32_t)base >> shamt;
74 case ROR:
75 if (shamt == 0)
76 return (cfval << 31) | (base >> 1); // RRX
77 else
78 return (base << (32 - shamt)) | (base >> shamt);
79 default:
80 ccprintf(std::cerr, "Unhandled shift type\n");
81 exit(1);
82 break;
83 }
84 return 0;
85}
86
87// Shift Rm by Rs
88int32_t
89ArmStaticInstBase::shift_rm_rs(uint32_t base, uint32_t shamt,
90 uint32_t type, uint32_t cfval) const
91{
92 enum ArmShiftType shiftType;
93 shiftType = (enum ArmShiftType) type;
94
95 switch (shiftType)
96 {
97 case LSL:
98 if (shamt >= 32)
99 return 0;
100 else
101 return base << shamt;
102 case LSR:
103 if (shamt >= 32)
104 return 0;
105 else
106 return base >> shamt;
107 case ASR:
108 if (shamt >= 32)
109 return (int32_t)base >> 31;
110 else
111 return (int32_t)base >> shamt;
112 case ROR:
113 shamt = shamt & 0x1f;
114 if (shamt == 0)
115 return base;
116 else
117 return (base << (32 - shamt)) | (base >> shamt);
118 default:
119 ccprintf(std::cerr, "Unhandled shift type\n");
120 exit(1);
121 break;
122 }
123 return 0;
124}
125
126
127// Generate C for a shift by immediate
128bool
129ArmStaticInstBase::shift_carry_imm(uint32_t base, uint32_t shamt,
130 uint32_t type, uint32_t cfval) const
131{
132 enum ArmShiftType shiftType;
133 shiftType = (enum ArmShiftType) type;
134
135 switch (shiftType)
136 {
137 case LSL:
138 if (shamt == 0)
139 return cfval;
140 else
141 return (base >> (32 - shamt)) & 1;
142 case LSR:
143 if (shamt == 0)
144 return (base >> 31);
145 else
146 return (base >> (shamt - 1)) & 1;
147 case ASR:
148 if (shamt == 0)
149 return (base >> 31);
150 else
151 return (base >> (shamt - 1)) & 1;
152 case ROR:
153 shamt = shamt & 0x1f;
154 if (shamt == 0)
155 return (base & 1); // RRX
156 else
157 return (base >> (shamt - 1)) & 1;
158 default:
159 ccprintf(std::cerr, "Unhandled shift type\n");
160 exit(1);
161 break;
162 }
163 return 0;
164}
165
166
167// Generate C for a shift by Rs
168bool
169ArmStaticInstBase::shift_carry_rs(uint32_t base, uint32_t shamt,
170 uint32_t type, uint32_t cfval) const
171{
172 enum ArmShiftType shiftType;
173 shiftType = (enum ArmShiftType) type;
174
175 if (shamt == 0)
176 return cfval;
177
178 switch (shiftType)
179 {
180 case LSL:
181 if (shamt > 32)
182 return 0;
183 else
184 return (base >> (32 - shamt)) & 1;
185 case LSR:
186 if (shamt > 32)
187 return 0;
188 else
189 return (base >> (shamt - 1)) & 1;
190 case ASR:
191 if (shamt > 32)
192 shamt = 32;
193 return (base >> (shamt - 1)) & 1;
194 case ROR:
195 shamt = shamt & 0x1f;
196 if (shamt == 0)
197 shamt = 32;
198 return (base >> (shamt - 1)) & 1;
199 default:
200 ccprintf(std::cerr, "Unhandled shift type\n");
201 exit(1);
202 break;
203 }
204 return 0;
205}
206
207
208// Generate the appropriate carry bit for an addition operation
209bool
210ArmStaticInstBase::arm_add_carry(int32_t result, int32_t lhs, int32_t rhs) const
211{
212 return findCarry(32, result, lhs, rhs);
213}
214
215// Generate the appropriate carry bit for a subtraction operation
216bool
217ArmStaticInstBase::arm_sub_carry(int32_t result, int32_t lhs, int32_t rhs) const
218{
219 return findCarry(32, result, lhs, ~rhs);
220}
221
222bool
223ArmStaticInstBase::arm_add_overflow(int32_t result, int32_t lhs, int32_t rhs) const
224{
225 return findOverflow(32, result, lhs, rhs);
226}
227
228bool
229ArmStaticInstBase::arm_sub_overflow(int32_t result, int32_t lhs, int32_t rhs) const
230{
231 return findOverflow(32, result, lhs, ~rhs);
232}
233
234uint32_t
235ArmStaticInstBase::modified_imm(uint8_t ctrlImm, uint8_t dataImm) const
236{
237 uint32_t bigData = dataImm;
238 uint32_t bigCtrl = ctrlImm;
239 if (bigCtrl < 4) {
240 switch (bigCtrl) {
241 case 0:
242 return bigData;
243 case 1:
244 return bigData | (bigData << 16);
245 case 2:
246 return (bigData << 8) | (bigData << 24);
247 case 3:
248 return (bigData << 0) | (bigData << 8) |
249 (bigData << 16) | (bigData << 24);
250 }
251 }
252 bigCtrl = (bigCtrl << 1) | ((bigData >> 7) & 0x1);
253 bigData |= (1 << 7);
254 return bigData << (32 - bigCtrl);
255}
256
257void
258ArmStaticInstBase::printReg(std::ostream &os, int reg) const
259{
260 if (reg < FP_Base_DepTag) {
261 switch (reg) {
262 case PCReg:
263 ccprintf(os, "pc");
264 break;
265 case StackPointerReg:
266 ccprintf(os, "sp");
267 break;
268 case FramePointerReg:
269 ccprintf(os, "fp");
270 break;
271 case ReturnAddressReg:
272 ccprintf(os, "lr");
273 break;
274 default:
275 ccprintf(os, "r%d", reg);
276 break;
277 }
278 } else if (reg < Ctrl_Base_DepTag) {
279 ccprintf(os, "f%d", reg - FP_Base_DepTag);
280 } else {
281 reg -= Ctrl_Base_DepTag;
282 assert(reg < NUM_MISCREGS);
283 ccprintf(os, "%s", ArmISA::miscRegName[reg]);
284 }
285}
286
287void
288ArmStaticInstBase::printMnemonic(std::ostream &os,
289 const std::string &suffix,
290 bool withPred) const
291{
292 os << " " << mnemonic;
293 if (withPred) {
294 unsigned condCode = machInst.condCode;
295 switch (condCode) {
296 case COND_EQ:
297 os << "eq";
298 break;
299 case COND_NE:
300 os << "ne";
301 break;
302 case COND_CS:
303 os << "cs";
304 break;
305 case COND_CC:
306 os << "cc";
307 break;
308 case COND_MI:
309 os << "mi";
310 break;
311 case COND_PL:
312 os << "pl";
313 break;
314 case COND_VS:
315 os << "vs";
316 break;
317 case COND_VC:
318 os << "vc";
319 break;
320 case COND_HI:
321 os << "hi";
322 break;
323 case COND_LS:
324 os << "ls";
325 break;
326 case COND_GE:
327 os << "ge";
328 break;
329 case COND_LT:
330 os << "lt";
331 break;
332 case COND_GT:
333 os << "gt";
334 break;
335 case COND_LE:
336 os << "le";
337 break;
338 case COND_AL:
339 // This one is implicit.
340 break;
341 case COND_NV:
342 os << "nv";
341 case COND_UC:
342 // Unconditional.
343 break;
344 default:
345 panic("Unrecognized condition code %d.\n", condCode);
346 }
347 os << suffix << " ";
348 }
349}
350
351void
352ArmStaticInstBase::printMemSymbol(std::ostream &os,
353 const SymbolTable *symtab,
354 const std::string &prefix,
355 const Addr addr,
356 const std::string &suffix) const
357{
358 Addr symbolAddr;
359 std::string symbol;
360 if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
361 ccprintf(os, "%s%s", prefix, symbol);
362 if (symbolAddr != addr)
363 ccprintf(os, "+%d", addr - symbolAddr);
364 ccprintf(os, suffix);
365 }
366}
367
368void
369ArmStaticInstBase::printShiftOperand(std::ostream &os) const
370{
371 printReg(os, machInst.rm);
372
373 bool immShift = (machInst.opcode4 == 0);
374 bool done = false;
375 unsigned shiftAmt = (machInst.shiftSize);
376 ArmShiftType type = (ArmShiftType)(uint32_t)machInst.shift;
377
378 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
379 shiftAmt = 32;
380
381 switch (type) {
382 case LSL:
383 if (immShift && shiftAmt == 0) {
384 done = true;
385 break;
386 }
387 os << ", LSL";
388 break;
389 case LSR:
390 os << ", LSR";
391 break;
392 case ASR:
393 os << ", ASR";
394 break;
395 case ROR:
396 if (immShift && shiftAmt == 0) {
397 os << ", RRX";
398 done = true;
399 break;
400 }
401 os << ", ROR";
402 break;
403 default:
404 panic("Tried to disassemble unrecognized shift type.\n");
405 }
406 if (!done) {
407 os << " ";
408 if (immShift)
409 os << "#" << shiftAmt;
410 else
411 printReg(os, machInst.rs);
412 }
413}
414
415void
416ArmStaticInstBase::printDataInst(std::ostream &os, bool withImm) const
417{
418 printMnemonic(os, machInst.sField ? "s" : "");
419 //XXX It would be nice if the decoder figured this all out for us.
420 unsigned opcode = machInst.opcode;
421 bool firstOp = true;
422
423 // Destination
424 // Cmp, cmn, teq, and tst don't have one.
425 if (opcode < 8 || opcode > 0xb) {
426 firstOp = false;
427 printReg(os, machInst.rd);
428 }
429
430 // Source 1.
431 // Mov and Movn don't have one of these.
432 if (opcode != 0xd && opcode != 0xf) {
433 if (!firstOp)
434 os << ", ";
435 firstOp = false;
436 printReg(os, machInst.rn);
437 }
438
439 if (!firstOp)
440 os << ", ";
441 if (withImm) {
442 unsigned rotate = machInst.rotate * 2;
443 uint32_t imm = machInst.imm;
444 ccprintf(os, "#%#x", (imm << (32 - rotate)) | (imm >> rotate));
445 } else {
446 printShiftOperand(os);
447 }
448}
449
450std::string
451ArmStaticInstBase::generateDisassembly(Addr pc,
452 const SymbolTable *symtab) const
453{
454 std::stringstream ss;
455 printMnemonic(ss);
456 return ss.str();
457}
458}
343 break;
344 default:
345 panic("Unrecognized condition code %d.\n", condCode);
346 }
347 os << suffix << " ";
348 }
349}
350
351void
352ArmStaticInstBase::printMemSymbol(std::ostream &os,
353 const SymbolTable *symtab,
354 const std::string &prefix,
355 const Addr addr,
356 const std::string &suffix) const
357{
358 Addr symbolAddr;
359 std::string symbol;
360 if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
361 ccprintf(os, "%s%s", prefix, symbol);
362 if (symbolAddr != addr)
363 ccprintf(os, "+%d", addr - symbolAddr);
364 ccprintf(os, suffix);
365 }
366}
367
368void
369ArmStaticInstBase::printShiftOperand(std::ostream &os) const
370{
371 printReg(os, machInst.rm);
372
373 bool immShift = (machInst.opcode4 == 0);
374 bool done = false;
375 unsigned shiftAmt = (machInst.shiftSize);
376 ArmShiftType type = (ArmShiftType)(uint32_t)machInst.shift;
377
378 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
379 shiftAmt = 32;
380
381 switch (type) {
382 case LSL:
383 if (immShift && shiftAmt == 0) {
384 done = true;
385 break;
386 }
387 os << ", LSL";
388 break;
389 case LSR:
390 os << ", LSR";
391 break;
392 case ASR:
393 os << ", ASR";
394 break;
395 case ROR:
396 if (immShift && shiftAmt == 0) {
397 os << ", RRX";
398 done = true;
399 break;
400 }
401 os << ", ROR";
402 break;
403 default:
404 panic("Tried to disassemble unrecognized shift type.\n");
405 }
406 if (!done) {
407 os << " ";
408 if (immShift)
409 os << "#" << shiftAmt;
410 else
411 printReg(os, machInst.rs);
412 }
413}
414
415void
416ArmStaticInstBase::printDataInst(std::ostream &os, bool withImm) const
417{
418 printMnemonic(os, machInst.sField ? "s" : "");
419 //XXX It would be nice if the decoder figured this all out for us.
420 unsigned opcode = machInst.opcode;
421 bool firstOp = true;
422
423 // Destination
424 // Cmp, cmn, teq, and tst don't have one.
425 if (opcode < 8 || opcode > 0xb) {
426 firstOp = false;
427 printReg(os, machInst.rd);
428 }
429
430 // Source 1.
431 // Mov and Movn don't have one of these.
432 if (opcode != 0xd && opcode != 0xf) {
433 if (!firstOp)
434 os << ", ";
435 firstOp = false;
436 printReg(os, machInst.rn);
437 }
438
439 if (!firstOp)
440 os << ", ";
441 if (withImm) {
442 unsigned rotate = machInst.rotate * 2;
443 uint32_t imm = machInst.imm;
444 ccprintf(os, "#%#x", (imm << (32 - rotate)) | (imm >> rotate));
445 } else {
446 printShiftOperand(os);
447 }
448}
449
450std::string
451ArmStaticInstBase::generateDisassembly(Addr pc,
452 const SymbolTable *symtab) const
453{
454 std::stringstream ss;
455 printMnemonic(ss);
456 return ss.str();
457}
458}