1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2007-2008 The Florida State University
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Stephen Hines
41 */
42#ifndef __ARCH_ARM_MEM_HH__
43#define __ARCH_ARM_MEM_HH__
44
45#include "arch/arm/insts/pred_inst.hh"
46
47namespace ArmISA
48{
49
50class Swap : public PredOp
51{
52 protected:
53 IntRegIndex dest;
54 IntRegIndex op1;
55 IntRegIndex base;
56
57 Swap(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
58 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _base)
59 : PredOp(mnem, _machInst, __opClass),
60 dest(_dest), op1(_op1), base(_base)
61 {}
62
63 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
64};
65
66class Memory : public PredOp
67{
68 public:
69 enum AddrMode {
70 AddrMd_Offset,
71 AddrMd_PreIndex,
72 AddrMd_PostIndex
73 };
74
75 protected:
76
77 IntRegIndex dest;
78 IntRegIndex base;
79 bool add;
80
81 Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
82 IntRegIndex _dest, IntRegIndex _base, bool _add)
83 : PredOp(mnem, _machInst, __opClass),
84 dest(_dest), base(_base), add(_add)
85 {}
86
87 virtual void
88 printOffset(std::ostream &os) const
89 {}
90
91 virtual void
92 printDest(std::ostream &os) const
93 {
94 printReg(os, dest);
95 }
96
97 void printInst(std::ostream &os, AddrMode addrMode) const;
98};
99
100// The address is a base register plus an immediate.
101class MemoryImm : public Memory
102{
103 protected:
104 int32_t imm;
105
106 MemoryImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
107 IntRegIndex _dest, IntRegIndex _base, bool _add, int32_t _imm)
108 : Memory(mnem, _machInst, __opClass, _dest, _base, _add), imm(_imm)
109 {}
110
111 void
112 printOffset(std::ostream &os) const
113 {
114 int32_t pImm = imm;
115 if (!add)
116 pImm = -pImm;
117 ccprintf(os, "#%d", pImm);
118 }
119};
120
121// The address is a base register plus an immediate.
122class MemoryDImm : public MemoryImm
123{
124 protected:
125 IntRegIndex dest2;
126
127 MemoryDImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
128 IntRegIndex _dest, IntRegIndex _dest2,
129 IntRegIndex _base, bool _add, int32_t _imm)
130 : MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
131 dest2(_dest2)
132 {}
133
134 void
135 printDest(std::ostream &os) const
136 {
137 MemoryImm::printDest(os);
138 os << ", ";
139 printReg(os, dest2);
140 }
141};
142
143// The address is a shifted register plus an immediate
144class MemoryReg : public Memory
145{
146 protected:
147 int32_t shiftAmt;
148 ArmShiftType shiftType;
149 IntRegIndex index;
150
151 MemoryReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
152 IntRegIndex _dest, IntRegIndex _base, bool _add,
153 int32_t _shiftAmt, ArmShiftType _shiftType,
154 IntRegIndex _index)
155 : Memory(mnem, _machInst, __opClass, _dest, _base, _add),
156 shiftAmt(_shiftAmt), shiftType(_shiftType), index(_index)
157 {}
158
159 void
160 printOffset(std::ostream &os) const
161 {
162 if (!add)
163 os << "-";
164 printReg(os, index);
165 if (shiftType != LSL || shiftAmt != 0) {
166 switch (shiftType) {
167 case LSL:
168 ccprintf(os, " LSL #%d", shiftAmt);
169 break;
170 case LSR:
171 if (shiftAmt == 0) {
172 ccprintf(os, " LSR #%d", 32);
173 } else {
174 ccprintf(os, " LSR #%d", shiftAmt);
175 }
176 break;
177 case ASR:
178 if (shiftAmt == 0) {
179 ccprintf(os, " ASR #%d", 32);
180 } else {
181 ccprintf(os, " ASR #%d", shiftAmt);
182 }
183 break;
184 case ROR:
185 if (shiftAmt == 0) {
186 ccprintf(os, " RRX");
187 } else {
188 ccprintf(os, " ROR #%d", shiftAmt);
189 }
190 break;
191 }
192 }
193 }
194};
195
196class MemoryDReg : public MemoryReg
197{
198 protected:
199 IntRegIndex dest2;
200
201 MemoryDReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
202 IntRegIndex _dest, IntRegIndex _dest2,
203 IntRegIndex _base, bool _add,
204 int32_t _shiftAmt, ArmShiftType _shiftType,
205 IntRegIndex _index)
206 : MemoryReg(mnem, _machInst, __opClass, _dest, _base, _add,
207 _shiftAmt, _shiftType, _index),
208 dest2(_dest2)
209 {}
210
211 void
212 printDest(std::ostream &os) const
213 {
214 MemoryReg::printDest(os);
215 os << ", ";
216 printReg(os, dest2);
217 }
218};
219
220template<class Base>
221class MemoryOffset : public Base
222{
223 protected:
224 MemoryOffset(const char *mnem, ExtMachInst _machInst,
225 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
226 bool _add, int32_t _imm)
227 : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
228 {}
229
230 MemoryOffset(const char *mnem, ExtMachInst _machInst,
231 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
232 bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
233 IntRegIndex _index)
234 : Base(mnem, _machInst, __opClass, _dest, _base, _add,
235 _shiftAmt, _shiftType, _index)
236 {}
237
238 MemoryOffset(const char *mnem, ExtMachInst _machInst,
239 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
240 IntRegIndex _base, bool _add, int32_t _imm)
241 : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
242 {}
243
244 MemoryOffset(const char *mnem, ExtMachInst _machInst,
245 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
246 IntRegIndex _base, bool _add,
247 int32_t _shiftAmt, ArmShiftType _shiftType,
248 IntRegIndex _index)
249 : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
250 _shiftAmt, _shiftType, _index)
251 {}
252
253 std::string
254 generateDisassembly(Addr pc, const SymbolTable *symtab) const
255 {
256 std::stringstream ss;
257 this->printInst(ss, Memory::AddrMd_Offset);
258 return ss.str();
259 }
260};
261
262template<class Base>
263class MemoryPreIndex : public Base
264{
265 protected:
266 MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
267 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
268 bool _add, int32_t _imm)
269 : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
270 {}
271
272 MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
273 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
274 bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
275 IntRegIndex _index)
276 : Base(mnem, _machInst, __opClass, _dest, _base, _add,
277 _shiftAmt, _shiftType, _index)
278 {}
279
280 MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
281 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
282 IntRegIndex _base, bool _add, int32_t _imm)
283 : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
284 {}
285
286 MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
287 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
288 IntRegIndex _base, bool _add,
289 int32_t _shiftAmt, ArmShiftType _shiftType,
290 IntRegIndex _index)
291 : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
292 _shiftAmt, _shiftType, _index)
293 {}
294
295 std::string
296 generateDisassembly(Addr pc, const SymbolTable *symtab) const
297 {
298 std::stringstream ss;
299 this->printInst(ss, Memory::AddrMd_PreIndex);
300 return ss.str();
301 }
302};
303
304template<class Base>
305class MemoryPostIndex : public Base
306{
307 protected:
308 MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
309 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
310 bool _add, int32_t _imm)
311 : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
312 {}
313
314 MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
315 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
316 bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
317 IntRegIndex _index)
318 : Base(mnem, _machInst, __opClass, _dest, _base, _add,
319 _shiftAmt, _shiftType, _index)
320 {}
321
322 MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
323 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
324 IntRegIndex _base, bool _add, int32_t _imm)
325 : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
326 {}
327
328 MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
329 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
330 IntRegIndex _base, bool _add,
331 int32_t _shiftAmt, ArmShiftType _shiftType,
332 IntRegIndex _index)
333 : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
334 _shiftAmt, _shiftType, _index)
335 {}
336
337 std::string
338 generateDisassembly(Addr pc, const SymbolTable *symtab) const
339 {
340 std::stringstream ss;
341 this->printInst(ss, Memory::AddrMd_PostIndex);
342 return ss.str();
343 }
344};
345}
346
347#endif //__ARCH_ARM_INSTS_MEM_HH__