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("mttar")) {
54 } else if (!myMnemonic
.compare("mfcr") ||
55 !myMnemonic
.compare("mfxer") ||
56 !myMnemonic
.compare("mflr") ||
57 !myMnemonic
.compare("mfctr") ||
58 !myMnemonic
.compare("mftar")) {
62 // Additional characters depending on isa bits being set
63 if (oeSet
) myMnemonic
= myMnemonic
+ "o";
64 if (rcSet
) myMnemonic
= myMnemonic
+ ".";
65 ccprintf(ss
, "%-10s ", myMnemonic
);
67 // Print the first destination only
68 if (_numDestRegs
> 0 && printDest
) {
69 printReg(ss
, destRegIdx(0));
72 // Print the (possibly) two source registers
73 if (_numSrcRegs
> 0 && printSrcs
) {
74 if (_numDestRegs
> 0 && printDest
) {
77 printReg(ss
, srcRegIdx(0));
78 if (_numSrcRegs
> 1 && printSecondSrc
) {
80 printReg(ss
, srcRegIdx(1));
89 IntImmOp::generateDisassembly(Addr pc
, const Loader::SymbolTable
*symtab
) const
93 ccprintf(ss
, "%-10s ", mnemonic
);
95 // Print the first destination only
96 if (_numDestRegs
> 0) {
97 printReg(ss
, destRegIdx(0));
100 // Print the source register
101 if (_numSrcRegs
> 0) {
102 if (_numDestRegs
> 0) {
105 printReg(ss
, srcRegIdx(0));
108 // Print the immediate value last
109 ss
<< ", " << (int32_t)imm
;
116 IntArithOp::generateDisassembly(
117 Addr pc
, const Loader::SymbolTable
*symtab
) const
119 std::stringstream ss
;
120 bool printSecondSrc
= true;
121 bool printThirdSrc
= false;
123 // Generate the correct mnemonic
124 std::string
myMnemonic(mnemonic
);
127 if (!myMnemonic
.compare("addme") ||
128 !myMnemonic
.compare("addze") ||
129 !myMnemonic
.compare("subfme") ||
130 !myMnemonic
.compare("subfze") ||
131 !myMnemonic
.compare("neg")){
132 printSecondSrc
= false;
133 } else if (!myMnemonic
.compare("maddhd") ||
134 !myMnemonic
.compare("maddhdu") ||
135 !myMnemonic
.compare("maddld")) {
136 printThirdSrc
= true;
139 // Additional characters depending on isa bits being set
140 if (oeSet
) myMnemonic
= myMnemonic
+ "o";
141 if (rcSet
) myMnemonic
= myMnemonic
+ ".";
142 ccprintf(ss
, "%-10s ", myMnemonic
);
144 // Print the first destination only
145 if (_numDestRegs
> 0) {
146 printReg(ss
, destRegIdx(0));
149 // Print the first source register
150 if (_numSrcRegs
> 0) {
151 if (_numDestRegs
> 0) {
154 printReg(ss
, srcRegIdx(0));
156 // Print the second source register
157 if (_numSrcRegs
> 1 && printSecondSrc
) {
159 printReg(ss
, srcRegIdx(1));
161 // Print the third source register
162 if (_numSrcRegs
> 2 && printThirdSrc
) {
164 printReg(ss
, srcRegIdx(2));
174 IntImmArithOp::generateDisassembly(
175 Addr pc
, const Loader::SymbolTable
*symtab
) const
177 std::stringstream ss
;
178 bool negateSimm
= false;
180 // Generate the correct mnemonic
181 std::string
myMnemonic(mnemonic
);
184 if (!myMnemonic
.compare("addi")) {
185 if (_numSrcRegs
== 0) {
187 } else if (simm
< 0) {
191 } else if (!myMnemonic
.compare("addis")) {
192 if (_numSrcRegs
== 0) {
194 } else if (simm
< 0) {
195 myMnemonic
= "subis";
198 } else if (!myMnemonic
.compare("addic") && simm
< 0) {
199 myMnemonic
= "subic";
201 } else if (!myMnemonic
.compare("addic_")) {
203 myMnemonic
= "subic.";
206 myMnemonic
= "addic.";
210 ccprintf(ss
, "%-10s ", myMnemonic
);
212 // Print the first destination only
213 if (_numDestRegs
> 0) {
214 printReg(ss
, destRegIdx(0));
217 // Print the source register
218 if (_numSrcRegs
> 0) {
219 if (_numDestRegs
> 0) {
222 printReg(ss
, srcRegIdx(0));
225 // Print the immediate value
237 IntDispArithOp::generateDisassembly(
238 Addr pc
, const Loader::SymbolTable
*symtab
) const
240 std::stringstream ss
;
241 bool printSrcs
= true;
242 bool printDisp
= true;
243 bool negateDisp
= false;
245 // Generate the correct mnemonic
246 std::string
myMnemonic(mnemonic
);
249 if (!myMnemonic
.compare("addpcis")) {
254 } else if (disp
< 0) {
255 myMnemonic
= "subpcis";
260 ccprintf(ss
, "%-10s ", myMnemonic
);
262 // Print the first destination only
263 if (_numDestRegs
> 0) {
264 printReg(ss
, destRegIdx(0));
267 // Print the source register
268 if (_numSrcRegs
> 0 && printSrcs
) {
269 if (_numDestRegs
> 0) {
272 printReg(ss
, srcRegIdx(0));
275 // Print the displacement
289 IntLogicOp::generateDisassembly(
290 Addr pc
, const Loader::SymbolTable
*symtab
) const
292 std::stringstream ss
;
293 bool printSecondSrc
= true;
295 // Generate the correct mnemonic
296 std::string
myMnemonic(mnemonic
);
299 if (!myMnemonic
.compare("or") && srcRegIdx(0) == srcRegIdx(1)) {
301 printSecondSrc
= false;
302 } else if (!myMnemonic
.compare("extsb") ||
303 !myMnemonic
.compare("extsh") ||
304 !myMnemonic
.compare("extsw") ||
305 !myMnemonic
.compare("cntlzw") ||
306 !myMnemonic
.compare("cntlzd") ||
307 !myMnemonic
.compare("cnttzw") ||
308 !myMnemonic
.compare("cnttzd")) {
309 printSecondSrc
= false;
312 // Additional characters depending on isa bits being set
313 if (rcSet
) myMnemonic
= myMnemonic
+ ".";
314 ccprintf(ss
, "%-10s ", myMnemonic
);
316 // Print the first destination only
317 if (_numDestRegs
> 0) {
318 printReg(ss
, destRegIdx(0));
321 // Print the first source register
322 if (_numSrcRegs
> 0) {
323 if (_numDestRegs
> 0) {
326 printReg(ss
, srcRegIdx(0));
328 // Print the second source register
329 if (printSecondSrc
) {
331 // If the instruction updates the CR, the destination register
332 // Ra is read and thus, it becomes the second source register
333 // due to its higher precedence over Rb. In this case, it must
336 if (_numSrcRegs
> 2) {
338 printReg(ss
, srcRegIdx(2));
341 if (_numSrcRegs
> 1) {
343 printReg(ss
, srcRegIdx(1));
354 IntImmLogicOp::generateDisassembly(
355 Addr pc
, const Loader::SymbolTable
*symtab
) const
357 std::stringstream ss
;
358 bool printRegs
= true;
360 // Generate the correct mnemonic
361 std::string
myMnemonic(mnemonic
);
364 if (!myMnemonic
.compare("ori") &&
365 destRegIdx(0).index() == 0 && srcRegIdx(0).index() == 0) {
368 } else if (!myMnemonic
.compare("xori") &&
369 destRegIdx(0).index() == 0 && srcRegIdx(0).index() == 0) {
372 } else if (!myMnemonic
.compare("andi_")) {
373 myMnemonic
= "andi.";
374 } else if (!myMnemonic
.compare("andis_")) {
375 myMnemonic
= "andis.";
378 ccprintf(ss
, "%-10s ", myMnemonic
);
382 // Print the first destination only
383 if (_numDestRegs
> 0) {
384 printReg(ss
, destRegIdx(0));
387 // Print the source register
388 if (_numSrcRegs
> 0) {
389 if (_numDestRegs
> 0) {
392 printReg(ss
, srcRegIdx(0));
395 // Print the immediate value
404 IntCompOp::generateDisassembly(
405 Addr pc
, const Loader::SymbolTable
*symtab
) const
407 std::stringstream ss
;
408 bool printFieldPrefix
= false;
409 bool printLength
= true;
411 // Generate the correct mnemonic
412 std::string
myMnemonic(mnemonic
);
415 if (!myMnemonic
.compare("cmp")) {
421 printFieldPrefix
= true;
423 } else if (!myMnemonic
.compare("cmpl")) {
425 myMnemonic
= "cmpld";
427 myMnemonic
= "cmplw";
429 printFieldPrefix
= true;
433 ccprintf(ss
, "%-10s ", myMnemonic
);
435 // Print the first destination only
436 if (printFieldPrefix
) {
446 if (!printFieldPrefix
|| field
> 0) {
452 // Print the first source register
453 if (_numSrcRegs
> 0) {
454 if (!printFieldPrefix
|| field
> 0 || printLength
) {
457 printReg(ss
, srcRegIdx(0));
459 // Print the second source register
460 if (_numSrcRegs
> 1) {
462 printReg(ss
, srcRegIdx(1));
471 IntImmCompOp::generateDisassembly(
472 Addr pc
, const Loader::SymbolTable
*symtab
) const
474 std::stringstream ss
;
475 bool printFieldPrefix
= false;
476 bool printLength
= true;
478 // Generate the correct mnemonic
479 std::string
myMnemonic(mnemonic
);
482 if (!myMnemonic
.compare("cmpi")) {
484 myMnemonic
= "cmpdi";
486 myMnemonic
= "cmpwi";
488 printFieldPrefix
= true;
492 ccprintf(ss
, "%-10s ", myMnemonic
);
494 // Print the first destination only
495 if (printFieldPrefix
) {
505 if (!printFieldPrefix
|| field
> 0) {
511 // Print the first source register
512 if (_numSrcRegs
> 0) {
513 if (!printFieldPrefix
|| field
> 0 || printLength
) {
516 printReg(ss
, srcRegIdx(0));
519 // Print the immediate value
527 IntImmCompLogicOp::generateDisassembly(
528 Addr pc
, const Loader::SymbolTable
*symtab
) const
530 std::stringstream ss
;
531 bool printFieldPrefix
= false;
532 bool printLength
= true;
534 // Generate the correct mnemonic
535 std::string
myMnemonic(mnemonic
);
538 if (!myMnemonic
.compare("cmpli")) {
540 myMnemonic
= "cmpldi";
542 myMnemonic
= "cmplwi";
544 printFieldPrefix
= true;
548 ccprintf(ss
, "%-10s ", myMnemonic
);
550 // Print the first destination only
551 if (printFieldPrefix
) {
561 if (!printFieldPrefix
|| field
> 0) {
567 // Print the first source register
568 if (_numSrcRegs
> 0) {
569 if (!printFieldPrefix
|| field
> 0 || printLength
) {
572 printReg(ss
, srcRegIdx(0));
575 // Print the immediate value
583 IntShiftOp::generateDisassembly(
584 Addr pc
, const Loader::SymbolTable
*symtab
) const
586 std::stringstream ss
;
588 ccprintf(ss
, "%-10s ", mnemonic
);
590 // Print the first destination only
591 if (_numDestRegs
> 0) {
592 printReg(ss
, destRegIdx(0));
595 // Print the first source register
596 if (_numSrcRegs
> 0) {
597 if (_numDestRegs
> 0) {
600 printReg(ss
, srcRegIdx(0));
611 IntRotateOp::generateDisassembly(
612 Addr pc
, const Loader::SymbolTable
*symtab
) const
614 std::stringstream ss
;
616 ccprintf(ss
, "%-10s ", mnemonic
);
618 // Print the first destination only
619 if (_numDestRegs
> 0) {
620 printReg(ss
, destRegIdx(0));
623 // Print the first source register
624 if (_numSrcRegs
> 0) {
625 if (_numDestRegs
> 0) {
628 printReg(ss
, srcRegIdx(0));
631 // Print the shift, mask begin and mask end
632 ss
<< ", " << sh
<< ", " << mb
<< ", " << me
;