6320bb6da53680f36d037b1748ee74fc5150d57d
[gem5.git] / src / arch / arm / insts / misc.cc
1 /*
2 * Copyright (c) 2010 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
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.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions are
17 * met: redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer;
19 * redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution;
22 * neither the name of the copyright holders nor the names of its
23 * contributors may be used to endorse or promote products derived from
24 * this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 * Authors: Gabe Black
39 */
40
41 #include "arch/arm/insts/misc.hh"
42 #include "cpu/reg_class.hh"
43
44 std::string
45 MrsOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
46 {
47 std::stringstream ss;
48 printMnemonic(ss);
49 printReg(ss, dest);
50 ss << ", ";
51 bool foundPsr = false;
52 for (unsigned i = 0; i < numSrcRegs(); i++) {
53 RegIndex idx = srcRegIdx(i);
54 RegIndex rel_idx;
55 if (regIdxToClass(idx, &rel_idx) != MiscRegClass) {
56 continue;
57 }
58 if (rel_idx == MISCREG_CPSR) {
59 ss << "cpsr";
60 foundPsr = true;
61 break;
62 }
63 if (rel_idx == MISCREG_SPSR) {
64 ss << "spsr";
65 foundPsr = true;
66 break;
67 }
68 }
69 if (!foundPsr) {
70 ss << "????";
71 }
72 return ss.str();
73 }
74
75 void
76 MsrBase::printMsrBase(std::ostream &os) const
77 {
78 printMnemonic(os);
79 bool apsr = false;
80 bool foundPsr = false;
81 for (unsigned i = 0; i < numDestRegs(); i++) {
82 int idx = destRegIdx(i);
83 if (idx < Misc_Reg_Base) {
84 continue;
85 }
86 idx -= Misc_Reg_Base;
87 if (idx == MISCREG_CPSR) {
88 os << "cpsr_";
89 foundPsr = true;
90 break;
91 }
92 if (idx == MISCREG_SPSR) {
93 if (bits(byteMask, 1, 0)) {
94 os << "spsr_";
95 } else {
96 os << "apsr_";
97 apsr = true;
98 }
99 foundPsr = true;
100 break;
101 }
102 }
103 if (!foundPsr) {
104 os << "????";
105 return;
106 }
107 if (bits(byteMask, 3)) {
108 if (apsr) {
109 os << "nzcvq";
110 } else {
111 os << "f";
112 }
113 }
114 if (bits(byteMask, 2)) {
115 if (apsr) {
116 os << "g";
117 } else {
118 os << "s";
119 }
120 }
121 if (bits(byteMask, 1)) {
122 os << "x";
123 }
124 if (bits(byteMask, 0)) {
125 os << "c";
126 }
127 }
128
129 std::string
130 MsrImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
131 {
132 std::stringstream ss;
133 printMsrBase(ss);
134 ccprintf(ss, ", #%#x", imm);
135 return ss.str();
136 }
137
138 std::string
139 MsrRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
140 {
141 std::stringstream ss;
142 printMsrBase(ss);
143 ss << ", ";
144 printReg(ss, op1);
145 return ss.str();
146 }
147
148 std::string
149 ImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
150 {
151 std::stringstream ss;
152 printMnemonic(ss);
153 ccprintf(ss, "#%d", imm);
154 return ss.str();
155 }
156
157 std::string
158 RegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
159 {
160 std::stringstream ss;
161 printMnemonic(ss);
162 printReg(ss, dest);
163 ccprintf(ss, ", #%d", imm);
164 return ss.str();
165 }
166
167 std::string
168 RegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
169 {
170 std::stringstream ss;
171 printMnemonic(ss);
172 printReg(ss, dest);
173 ss << ", ";
174 printReg(ss, op1);
175 return ss.str();
176 }
177
178 std::string
179 RegRegRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
180 {
181 std::stringstream ss;
182 printMnemonic(ss);
183 printReg(ss, dest);
184 ss << ", ";
185 printReg(ss, op1);
186 ss << ", ";
187 printReg(ss, op2);
188 ccprintf(ss, ", #%d", imm);
189 return ss.str();
190 }
191
192 std::string
193 RegRegRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
194 {
195 std::stringstream ss;
196 printMnemonic(ss);
197 printReg(ss, dest);
198 ss << ", ";
199 printReg(ss, op1);
200 ss << ", ";
201 printReg(ss, op2);
202 ss << ", ";
203 printReg(ss, op3);
204 return ss.str();
205 }
206
207 std::string
208 RegRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
209 {
210 std::stringstream ss;
211 printMnemonic(ss);
212 printReg(ss, dest);
213 ss << ", ";
214 printReg(ss, op1);
215 ss << ", ";
216 printReg(ss, op2);
217 return ss.str();
218 }
219
220 std::string
221 RegRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
222 {
223 std::stringstream ss;
224 printMnemonic(ss);
225 printReg(ss, dest);
226 ss << ", ";
227 printReg(ss, op1);
228 ccprintf(ss, ", #%d", imm);
229 return ss.str();
230 }
231
232 std::string
233 RegRegImmImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
234 {
235 std::stringstream ss;
236 printMnemonic(ss);
237 printReg(ss, dest);
238 ss << ", ";
239 printReg(ss, op1);
240 ccprintf(ss, ", #%d, #%d", imm1, imm2);
241 return ss.str();
242 }
243
244 std::string
245 RegImmRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
246 {
247 std::stringstream ss;
248 printMnemonic(ss);
249 printReg(ss, dest);
250 ccprintf(ss, ", #%d, ", imm);
251 printReg(ss, op1);
252 return ss.str();
253 }
254
255 std::string
256 RegImmRegShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
257 {
258 std::stringstream ss;
259 printMnemonic(ss);
260 printReg(ss, dest);
261 ccprintf(ss, ", #%d, ", imm);
262 printShiftOperand(ss, op1, true, shiftAmt, INTREG_ZERO, shiftType);
263 printReg(ss, op1);
264 return ss.str();
265 }
266
267 std::string
268 UnknownOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
269 {
270 return csprintf("%-10s (inst %#08x)", "unknown", machInst);
271 }