1/*
2 * Copyright (c) 2009 The University of Edinburgh
3 * All rights reserved.
4 *
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.
15 *
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.
27 *
28 * Authors: Timothy M. Jones
29 */
30
31#include "arch/power/insts/integer.hh"
32
33using namespace std;
34using namespace PowerISA;
35
36string
37IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
38{
39    stringstream ss;
40    bool printDest = true;
41    bool printSrcs = true;
42    bool printSecondSrc = true;
43
44    // Generate the correct mnemonic
45    string myMnemonic(mnemonic);
46
47    // Special cases
48    if (!myMnemonic.compare("or") && _srcRegIdx[0] == _srcRegIdx[1]) {
49        myMnemonic = "mr";
50        printSecondSrc = false;
51    } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) {
52        printDest = false;
53    } else if (!myMnemonic.compare("mflr")) {
54        printSrcs = false;
55    }
56
57    // Additional characters depending on isa bits being set
58    if (oeSet) myMnemonic = myMnemonic + "o";
59    if (rcSet) myMnemonic = myMnemonic + ".";
60    ccprintf(ss, "%-10s ", myMnemonic);
61
62    // Print the first destination only
63    if (_numDestRegs > 0 && printDest) {
64        printReg(ss, _destRegIdx[0]);
65    }
66
67    // Print the (possibly) two source registers
68    if (_numSrcRegs > 0 && printSrcs) {
69        if (_numDestRegs > 0 && printDest) {
70            ss << ", ";
71        }
72        printReg(ss, _srcRegIdx[0]);
73        if (_numSrcRegs > 1 && printSecondSrc) {
74          ss << ", ";
75          printReg(ss, _srcRegIdx[1]);
76        }
77    }
78
79    return ss.str();
80}
81
82
83string
84IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
85{
86    stringstream ss;
87
88    // Generate the correct mnemonic
89    string myMnemonic(mnemonic);
90
91    // Special cases
92    if (!myMnemonic.compare("addi") && _numSrcRegs == 0) {
93        myMnemonic = "li";
94    } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) {
95        myMnemonic = "lis";
96    }
97    ccprintf(ss, "%-10s ", myMnemonic);
98
99    // Print the first destination only
100    if (_numDestRegs > 0) {
101        printReg(ss, _destRegIdx[0]);
102    }
103
104    // Print the source register
105    if (_numSrcRegs > 0) {
106        if (_numDestRegs > 0) {
107            ss << ", ";
108        }
109        printReg(ss, _srcRegIdx[0]);
110    }
111
112    // Print the immediate value last
113    ss << ", " << (int32_t)imm;
114
115    return ss.str();
116}
117
118
119string
120IntShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
121{
122    stringstream ss;
123
124    ccprintf(ss, "%-10s ", mnemonic);
125
126    // Print the first destination only
127    if (_numDestRegs > 0) {
128        printReg(ss, _destRegIdx[0]);
129    }
130
131    // Print the first source register
132    if (_numSrcRegs > 0) {
133        if (_numDestRegs > 0) {
134            ss << ", ";
135        }
136        printReg(ss, _srcRegIdx[0]);
137    }
138
139    // Print the shift
140    ss << ", " << sh;
141
142    return ss.str();
143}
144
145
146string
147IntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
148{
149    stringstream ss;
150
151    ccprintf(ss, "%-10s ", mnemonic);
152
153    // Print the first destination only
154    if (_numDestRegs > 0) {
155        printReg(ss, _destRegIdx[0]);
156    }
157
158    // Print the first source register
159    if (_numSrcRegs > 0) {
160        if (_numDestRegs > 0) {
161            ss << ", ";
162        }
163        printReg(ss, _srcRegIdx[0]);
164    }
165
166    // Print the shift, mask begin and mask end
167    ss << ", " << sh << ", " << mb << ", " << me;
168
169    return ss.str();
170}
171