2 * Copyright (c) 2009 The University of Edinburgh
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "arch/power/insts/integer.hh"
31 using namespace PowerISA
;
34 IntOp::generateDisassembly(Addr pc
, const Loader::SymbolTable
*symtab
) const
37 bool printDest
= true;
38 bool printSrcs
= true;
39 bool printSecondSrc
= true;
41 // Generate the correct mnemonic
42 std::string
myMnemonic(mnemonic
);
45 if (!myMnemonic
.compare("or") && srcRegIdx(0) == srcRegIdx(1)) {
47 printSecondSrc
= false;
48 } else if (!myMnemonic
.compare("mtcrf") ||
49 !myMnemonic
.compare("mtxer") ||
50 !myMnemonic
.compare("mtlr") ||
51 !myMnemonic
.compare("mtctr") ||
52 !myMnemonic
.compare("cmpi") ||
53 !myMnemonic
.compare("mttar")) {
55 } else if (!myMnemonic
.compare("mfcr") ||
56 !myMnemonic
.compare("mfxer") ||
57 !myMnemonic
.compare("mflr") ||
58 !myMnemonic
.compare("mfctr") ||
59 !myMnemonic
.compare("mftar")) {
63 // Additional characters depending on isa bits being set
64 if (oeSet
) myMnemonic
= myMnemonic
+ "o";
65 if (rcSet
) myMnemonic
= myMnemonic
+ ".";
66 ccprintf(ss
, "%-10s ", myMnemonic
);
68 // Print the first destination only
69 if (_numDestRegs
> 0 && printDest
) {
70 printReg(ss
, destRegIdx(0));
73 // Print the (possibly) two source registers
74 if (_numSrcRegs
> 0 && printSrcs
) {
75 if (_numDestRegs
> 0 && printDest
) {
78 printReg(ss
, srcRegIdx(0));
79 if (_numSrcRegs
> 1 && printSecondSrc
) {
81 printReg(ss
, srcRegIdx(1));
90 IntImmOp::generateDisassembly(Addr pc
, const Loader::SymbolTable
*symtab
) const
94 ccprintf(ss
, "%-10s ", mnemonic
);
96 // Print the first destination only
97 if (_numDestRegs
> 0) {
98 printReg(ss
, destRegIdx(0));
101 // Print the source register
102 if (_numSrcRegs
> 0) {
103 if (_numDestRegs
> 0) {
106 printReg(ss
, srcRegIdx(0));
109 // Print the immediate value last
110 ss
<< ", " << (int32_t)imm
;
117 IntArithOp::generateDisassembly(
118 Addr pc
, const Loader::SymbolTable
*symtab
) const
120 std::stringstream ss
;
121 bool printSecondSrc
= true;
122 bool printThirdSrc
= false;
124 // Generate the correct mnemonic
125 std::string
myMnemonic(mnemonic
);
128 if (!myMnemonic
.compare("addme") ||
129 !myMnemonic
.compare("addze") ||
130 !myMnemonic
.compare("subfme") ||
131 !myMnemonic
.compare("subfze") ||
132 !myMnemonic
.compare("neg")){
133 printSecondSrc
= false;
134 } else if (!myMnemonic
.compare("maddhd") ||
135 !myMnemonic
.compare("maddhdu") ||
136 !myMnemonic
.compare("maddld")) {
137 printThirdSrc
= true;
140 // Additional characters depending on isa bits being set
141 if (oeSet
) myMnemonic
= myMnemonic
+ "o";
142 if (rcSet
) myMnemonic
= myMnemonic
+ ".";
143 ccprintf(ss
, "%-10s ", myMnemonic
);
145 // Print the first destination only
146 if (_numDestRegs
> 0) {
147 printReg(ss
, destRegIdx(0));
150 // Print the first source register
151 if (_numSrcRegs
> 0) {
152 if (_numDestRegs
> 0) {
155 printReg(ss
, srcRegIdx(0));
157 // Print the second source register
158 if (_numSrcRegs
> 1 && printSecondSrc
) {
160 printReg(ss
, srcRegIdx(1));
162 // Print the third source register
163 if (_numSrcRegs
> 2 && printThirdSrc
) {
165 printReg(ss
, srcRegIdx(2));
175 IntImmArithOp::generateDisassembly(
176 Addr pc
, const Loader::SymbolTable
*symtab
) const
178 std::stringstream ss
;
179 bool negateSimm
= false;
181 // Generate the correct mnemonic
182 std::string
myMnemonic(mnemonic
);
185 if (!myMnemonic
.compare("addi")) {
186 if (_numSrcRegs
== 0) {
188 } else if (simm
< 0) {
192 } else if (!myMnemonic
.compare("addis")) {
193 if (_numSrcRegs
== 0) {
195 } else if (simm
< 0) {
196 myMnemonic
= "subis";
199 } else if (!myMnemonic
.compare("addic") && simm
< 0) {
200 myMnemonic
= "subic";
202 } else if (!myMnemonic
.compare("addic_")) {
204 myMnemonic
= "subic.";
207 myMnemonic
= "addic.";
211 ccprintf(ss
, "%-10s ", myMnemonic
);
213 // Print the first destination only
214 if (_numDestRegs
> 0) {
215 printReg(ss
, destRegIdx(0));
218 // Print the source register
219 if (_numSrcRegs
> 0) {
220 if (_numDestRegs
> 0) {
223 printReg(ss
, srcRegIdx(0));
226 // Print the immediate value
238 IntDispArithOp::generateDisassembly(
239 Addr pc
, const Loader::SymbolTable
*symtab
) const
241 std::stringstream ss
;
242 bool printSrcs
= true;
243 bool printDisp
= true;
244 bool negateDisp
= false;
246 // Generate the correct mnemonic
247 std::string
myMnemonic(mnemonic
);
250 if (!myMnemonic
.compare("addpcis")) {
255 } else if (disp
< 0) {
256 myMnemonic
= "subpcis";
261 ccprintf(ss
, "%-10s ", myMnemonic
);
263 // Print the first destination only
264 if (_numDestRegs
> 0) {
265 printReg(ss
, destRegIdx(0));
268 // Print the source register
269 if (_numSrcRegs
> 0 && printSrcs
) {
270 if (_numDestRegs
> 0) {
273 printReg(ss
, srcRegIdx(0));
276 // Print the displacement
290 IntShiftOp::generateDisassembly(
291 Addr pc
, const Loader::SymbolTable
*symtab
) const
293 std::stringstream ss
;
295 ccprintf(ss
, "%-10s ", mnemonic
);
297 // Print the first destination only
298 if (_numDestRegs
> 0) {
299 printReg(ss
, destRegIdx(0));
302 // Print the first source register
303 if (_numSrcRegs
> 0) {
304 if (_numDestRegs
> 0) {
307 printReg(ss
, srcRegIdx(0));
318 IntRotateOp::generateDisassembly(
319 Addr pc
, const Loader::SymbolTable
*symtab
) const
321 std::stringstream ss
;
323 ccprintf(ss
, "%-10s ", mnemonic
);
325 // Print the first destination only
326 if (_numDestRegs
> 0) {
327 printReg(ss
, destRegIdx(0));
330 // Print the first source register
331 if (_numSrcRegs
> 0) {
332 if (_numDestRegs
> 0) {
335 printReg(ss
, srcRegIdx(0));
338 // Print the shift, mask begin and mask end
339 ss
<< ", " << sh
<< ", " << mb
<< ", " << me
;