2 * Copyright (c) 2010-2014 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
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.
15 * Copyright (c) 2007-2008 The Florida State University
16 * All rights reserved.
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.
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.
41 * Authors: Stephen Hines
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"
53 // Shift Rm by an immediate value
55 ArmStaticInst::shift_rm_imm(uint32_t base
, uint32_t shamt
,
56 uint32_t type
, uint32_t cfval
) const
59 ArmShiftType shiftType
;
60 shiftType
= (ArmShiftType
)type
;
73 return (base
>> 31) | -((base
& (1 << 31)) >> 31);
75 return (base
>> shamt
) | -((base
& (1 << 31)) >> shamt
);
78 return (cfval
<< 31) | (base
>> 1); // RRX
80 return (base
<< (32 - shamt
)) | (base
>> shamt
);
82 ccprintf(std::cerr
, "Unhandled shift type\n");
90 ArmStaticInst::shiftReg64(uint64_t base
, uint64_t shiftAmt
,
91 ArmShiftType type
, uint8_t width
) const
93 shiftAmt
= shiftAmt
% width
;
94 ArmShiftType shiftType
;
95 shiftType
= (ArmShiftType
)type
;
100 return base
<< shiftAmt
;
105 return (base
& mask(width
)) >> shiftAmt
;
110 int sign_bit
= bits(base
, intWidth
- 1);
112 base
= sign_bit
? (base
| ~mask(intWidth
- shiftAmt
)) : base
;
113 return base
& mask(intWidth
);
119 return (base
<< (width
- shiftAmt
)) | (base
>> shiftAmt
);
121 ccprintf(std::cerr
, "Unhandled shift type\n");
129 ArmStaticInst::extendReg64(uint64_t base
, ArmExtendType type
,
130 uint64_t shiftAmt
, uint8_t width
) const
132 bool sign_extend
= false;
164 len
= len
<= width
- shiftAmt
? len
: width
- shiftAmt
;
165 uint64_t tmp
= (uint64_t) bits(base
, len
- 1, 0) << shiftAmt
;
167 int sign_bit
= bits(tmp
, len
+ shiftAmt
- 1);
168 tmp
= sign_bit
? (tmp
| ~mask(len
+ shiftAmt
)) : tmp
;
170 return tmp
& mask(width
);
175 ArmStaticInst::shift_rm_rs(uint32_t base
, uint32_t shamt
,
176 uint32_t type
, uint32_t cfval
) const
178 enum ArmShiftType shiftType
;
179 shiftType
= (enum ArmShiftType
) type
;
187 return base
<< shamt
;
192 return base
>> shamt
;
195 return (base
>> 31) | -((base
& (1 << 31)) >> 31);
197 return (base
>> shamt
) | -((base
& (1 << 31)) >> shamt
);
199 shamt
= shamt
& 0x1f;
203 return (base
<< (32 - shamt
)) | (base
>> shamt
);
205 ccprintf(std::cerr
, "Unhandled shift type\n");
213 // Generate C for a shift by immediate
215 ArmStaticInst::shift_carry_imm(uint32_t base
, uint32_t shamt
,
216 uint32_t type
, uint32_t cfval
) const
218 enum ArmShiftType shiftType
;
219 shiftType
= (enum ArmShiftType
) type
;
227 return (base
>> (32 - shamt
)) & 1;
232 return (base
>> (shamt
- 1)) & 1;
237 return (base
>> (shamt
- 1)) & 1;
239 shamt
= shamt
& 0x1f;
241 return (base
& 1); // RRX
243 return (base
>> (shamt
- 1)) & 1;
245 ccprintf(std::cerr
, "Unhandled shift type\n");
253 // Generate C for a shift by Rs
255 ArmStaticInst::shift_carry_rs(uint32_t base
, uint32_t shamt
,
256 uint32_t type
, uint32_t cfval
) const
258 enum ArmShiftType shiftType
;
259 shiftType
= (enum ArmShiftType
) type
;
270 return (base
>> (32 - shamt
)) & 1;
275 return (base
>> (shamt
- 1)) & 1;
279 return (base
>> (shamt
- 1)) & 1;
281 shamt
= shamt
& 0x1f;
284 return (base
>> (shamt
- 1)) & 1;
286 ccprintf(std::cerr
, "Unhandled shift type\n");
295 ArmStaticInst::printReg(std::ostream
&os
, int reg
) const
299 switch (regIdxToClass(reg
, &rel_reg
)) {
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");
309 ccprintf(os
, "%s%d", (intWidth
== 32) ? "w" : "x", reg
);
315 case StackPointerReg
:
318 case FramePointerReg
:
321 case ReturnAddressReg
:
325 ccprintf(os
, "r%d", reg
);
331 ccprintf(os
, "f%d", rel_reg
);
334 assert(rel_reg
< NUM_MISCREGS
);
335 ccprintf(os
, "%s", ArmISA::miscRegName
[rel_reg
]);
338 ccprintf(os
, "cc_%s", ArmISA::ccRegName
[rel_reg
]);
344 ArmStaticInst::printMnemonic(std::ostream
&os
,
345 const std::string
&suffix
,
348 ConditionCode cond64
) const
350 os
<< " " << mnemonic
;
351 if (withPred
&& !aarch64
) {
352 printCondition(os
, machInst
.condCode
);
354 } else if (withCond64
) {
356 printCondition(os
, cond64
);
359 if (machInst
.bigThumb
)
365 ArmStaticInst::printTarget(std::ostream
&os
, Addr target
,
366 const SymbolTable
*symtab
) const
371 if (symtab
&& symtab
->findNearestSymbol(target
, symbol
, symbolAddr
)) {
372 ccprintf(os
, "<%s", symbol
);
373 if (symbolAddr
!= target
)
374 ccprintf(os
, "+%d>", target
- symbolAddr
);
378 ccprintf(os
, "%#x", target
);
383 ArmStaticInst::printCondition(std::ostream
&os
,
385 bool noImplicit
) const
431 // This one is implicit.
441 panic("Unrecognized condition code %d.\n", code
);
446 ArmStaticInst::printMemSymbol(std::ostream
&os
,
447 const SymbolTable
*symtab
,
448 const std::string
&prefix
,
450 const std::string
&suffix
) const
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
);
463 ArmStaticInst::printShiftOperand(std::ostream
&os
,
468 ArmShiftType type
) const
470 bool firstOp
= false;
472 if (rm
!= INTREG_ZERO
) {
478 if ((type
== LSR
|| type
== ASR
) && immShift
&& shiftAmt
== 0)
483 if (immShift
&& shiftAmt
== 0) {
502 if (immShift
&& shiftAmt
== 0) {
514 panic("Tried to disassemble unrecognized shift type.\n");
520 os
<< "#" << shiftAmt
;
527 ArmStaticInst::printExtendOperand(bool firstOperand
, std::ostream
&os
,
528 IntRegIndex rm
, ArmExtendType type
,
529 int64_t shiftAmt
) const
534 if (type
== UXTX
&& shiftAmt
== 0)
537 case UXTB
: ccprintf(os
, ", UXTB");
539 case UXTH
: ccprintf(os
, ", UXTH");
541 case UXTW
: ccprintf(os
, ", UXTW");
543 case UXTX
: ccprintf(os
, ", LSL");
545 case SXTB
: ccprintf(os
, ", SXTB");
547 case SXTH
: ccprintf(os
, ", SXTH");
549 case SXTW
: ccprintf(os
, ", SXTW");
551 case SXTX
: ccprintf(os
, ", SXTW");
554 if (type
== UXTX
|| shiftAmt
)
555 ccprintf(os
, " #%d", shiftAmt
);
559 ArmStaticInst::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
, uint64_t imm
) const
564 printMnemonic(os
, s
? "s" : "");
568 if (rd
!= INTREG_ZERO
) {
574 if (rn
!= INTREG_ZERO
) {
584 ccprintf(os
, "#%ld", imm
);
586 printShiftOperand(os
, rm
, immShift
, shiftAmt
, rs
, type
);
591 ArmStaticInst::generateDisassembly(Addr pc
,
592 const SymbolTable
*symtab
) const
594 std::stringstream ss
;