Deleted Added
sdiff udiff text old ( 7145:a71ac505d83b ) new ( 7148:1f8d18f5fe5d )
full compact
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
208void
209ArmStaticInstBase::printReg(std::ostream &os, int reg) const
210{
211 if (reg < FP_Base_DepTag) {
212 switch (reg) {
213 case PCReg:
214 ccprintf(os, "pc");
215 break;
216 case StackPointerReg:
217 ccprintf(os, "sp");
218 break;
219 case FramePointerReg:
220 ccprintf(os, "fp");
221 break;
222 case ReturnAddressReg:
223 ccprintf(os, "lr");
224 break;
225 default:
226 ccprintf(os, "r%d", reg);
227 break;
228 }
229 } else if (reg < Ctrl_Base_DepTag) {
230 ccprintf(os, "f%d", reg - FP_Base_DepTag);
231 } else {
232 reg -= Ctrl_Base_DepTag;
233 assert(reg < NUM_MISCREGS);
234 ccprintf(os, "%s", ArmISA::miscRegName[reg]);
235 }
236}
237
238void
239ArmStaticInstBase::printMnemonic(std::ostream &os,
240 const std::string &suffix,
241 bool withPred) const
242{
243 os << " " << mnemonic;
244 if (withPred) {
245 unsigned condCode = machInst.condCode;
246 switch (condCode) {
247 case COND_EQ:
248 os << "eq";
249 break;
250 case COND_NE:
251 os << "ne";
252 break;
253 case COND_CS:
254 os << "cs";
255 break;
256 case COND_CC:
257 os << "cc";
258 break;
259 case COND_MI:
260 os << "mi";
261 break;
262 case COND_PL:
263 os << "pl";
264 break;
265 case COND_VS:
266 os << "vs";
267 break;
268 case COND_VC:
269 os << "vc";
270 break;
271 case COND_HI:
272 os << "hi";
273 break;
274 case COND_LS:
275 os << "ls";
276 break;
277 case COND_GE:
278 os << "ge";
279 break;
280 case COND_LT:
281 os << "lt";
282 break;
283 case COND_GT:
284 os << "gt";
285 break;
286 case COND_LE:
287 os << "le";
288 break;
289 case COND_AL:
290 // This one is implicit.
291 break;
292 case COND_UC:
293 // Unconditional.
294 break;
295 default:
296 panic("Unrecognized condition code %d.\n", condCode);
297 }
298 os << suffix;
299 if (machInst.bigThumb)
300 os << ".w";
301 os << " ";
302 }
303}
304
305void
306ArmStaticInstBase::printMemSymbol(std::ostream &os,
307 const SymbolTable *symtab,
308 const std::string &prefix,
309 const Addr addr,
310 const std::string &suffix) const
311{
312 Addr symbolAddr;
313 std::string symbol;
314 if (symtab && symtab->findNearestSymbol(addr, symbol, symbolAddr)) {
315 ccprintf(os, "%s%s", prefix, symbol);
316 if (symbolAddr != addr)
317 ccprintf(os, "+%d", addr - symbolAddr);
318 ccprintf(os, suffix);
319 }
320}
321
322void
323ArmStaticInstBase::printShiftOperand(std::ostream &os,
324 IntRegIndex rm,
325 bool immShift,
326 uint32_t shiftAmt,
327 IntRegIndex rs,
328 ArmShiftType type) const
329{
330 bool firstOp = false;
331
332 if (rm != INTREG_ZERO) {
333 printReg(os, rm);
334 }
335
336 bool done = false;
337
338 if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
339 shiftAmt = 32;
340
341 switch (type) {
342 case LSL:
343 if (immShift && shiftAmt == 0) {
344 done = true;
345 break;
346 }
347 if (!firstOp)
348 os << ", ";
349 os << "LSL";
350 break;
351 case LSR:
352 if (!firstOp)
353 os << ", ";
354 os << "LSR";
355 break;
356 case ASR:
357 if (!firstOp)
358 os << ", ";
359 os << "ASR";
360 break;
361 case ROR:
362 if (immShift && shiftAmt == 0) {
363 if (!firstOp)
364 os << ", ";
365 os << "RRX";
366 done = true;
367 break;
368 }
369 if (!firstOp)
370 os << ", ";
371 os << "ROR";
372 break;
373 default:
374 panic("Tried to disassemble unrecognized shift type.\n");
375 }
376 if (!done) {
377 if (!firstOp)
378 os << " ";
379 if (immShift)
380 os << "#" << shiftAmt;
381 else
382 printReg(os, rs);
383 }
384}
385
386void
387ArmStaticInstBase::printDataInst(std::ostream &os, bool withImm,
388 bool immShift, bool s, IntRegIndex rd, IntRegIndex rn,
389 IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt,
390 ArmShiftType type, uint32_t imm) const
391{
392 printMnemonic(os, s ? "s" : "");
393 bool firstOp = true;
394
395 // Destination
396 if (rd != INTREG_ZERO) {
397 firstOp = false;
398 printReg(os, rd);
399 }
400
401 // Source 1.
402 if (rn != INTREG_ZERO) {
403 if (!firstOp)
404 os << ", ";
405 firstOp = false;
406 printReg(os, rn);
407 }
408
409 if (!firstOp)
410 os << ", ";
411 if (withImm) {
412 ccprintf(os, "#%d", imm);
413 } else {
414 printShiftOperand(os, rm, immShift, shiftAmt, rs, type);
415 }
416}
417
418std::string
419ArmStaticInstBase::generateDisassembly(Addr pc,
420 const SymbolTable *symtab) const
421{
422 std::stringstream ss;
423 printMnemonic(ss);
424 return ss.str();
425}
426}