mem.hh revision 7291
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
66// The address is a base register plus an immediate.
67class RfeOp : public PredOp
68{
69  public:
70    enum AddrMode {
71        DecrementAfter,
72        DecrementBefore,
73        IncrementAfter,
74        IncrementBefore
75    };
76  protected:
77    IntRegIndex base;
78    AddrMode mode;
79    bool wb;
80
81    RfeOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
82          IntRegIndex _base, AddrMode _mode, bool _wb)
83        : PredOp(mnem, _machInst, __opClass),
84          base(_base), mode(_mode), wb(_wb)
85    {}
86
87    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
88};
89
90class Memory : public PredOp
91{
92  public:
93    enum AddrMode {
94        AddrMd_Offset,
95        AddrMd_PreIndex,
96        AddrMd_PostIndex
97    };
98
99  protected:
100
101    IntRegIndex dest;
102    IntRegIndex base;
103    bool add;
104
105    Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
106           IntRegIndex _dest, IntRegIndex _base, bool _add)
107        : PredOp(mnem, _machInst, __opClass),
108          dest(_dest), base(_base), add(_add)
109    {}
110
111    virtual void
112    printOffset(std::ostream &os) const
113    {}
114
115    virtual void
116    printDest(std::ostream &os) const
117    {
118        printReg(os, dest);
119    }
120
121    void printInst(std::ostream &os, AddrMode addrMode) const;
122};
123
124// The address is a base register plus an immediate.
125class MemoryImm : public Memory
126{
127  protected:
128    int32_t imm;
129
130    MemoryImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
131              IntRegIndex _dest, IntRegIndex _base, bool _add, int32_t _imm)
132        : Memory(mnem, _machInst, __opClass, _dest, _base, _add), imm(_imm)
133    {}
134
135    void
136    printOffset(std::ostream &os) const
137    {
138        int32_t pImm = imm;
139        if (!add)
140            pImm = -pImm;
141        ccprintf(os, "#%d", pImm);
142    }
143};
144
145// The address is a base register plus an immediate.
146class MemoryDImm : public MemoryImm
147{
148  protected:
149    IntRegIndex dest2;
150
151    MemoryDImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
152              IntRegIndex _dest, IntRegIndex _dest2,
153              IntRegIndex _base, bool _add, int32_t _imm)
154        : MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
155          dest2(_dest2)
156    {}
157
158    void
159    printDest(std::ostream &os) const
160    {
161        MemoryImm::printDest(os);
162        os << ", ";
163        printReg(os, dest2);
164    }
165};
166
167// The address is a shifted register plus an immediate
168class MemoryReg : public Memory
169{
170  protected:
171    int32_t shiftAmt;
172    ArmShiftType shiftType;
173    IntRegIndex index;
174
175    MemoryReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
176              IntRegIndex _dest, IntRegIndex _base, bool _add,
177              int32_t _shiftAmt, ArmShiftType _shiftType,
178              IntRegIndex _index)
179        : Memory(mnem, _machInst, __opClass, _dest, _base, _add),
180          shiftAmt(_shiftAmt), shiftType(_shiftType), index(_index)
181    {}
182
183    void
184    printOffset(std::ostream &os) const
185    {
186        if (!add)
187            os << "-";
188        printReg(os, index);
189        if (shiftType != LSL || shiftAmt != 0) {
190            switch (shiftType) {
191              case LSL:
192                ccprintf(os, " LSL #%d", shiftAmt);
193                break;
194              case LSR:
195                if (shiftAmt == 0) {
196                    ccprintf(os, " LSR #%d", 32);
197                } else {
198                    ccprintf(os, " LSR #%d", shiftAmt);
199                }
200                break;
201              case ASR:
202                if (shiftAmt == 0) {
203                    ccprintf(os, " ASR #%d", 32);
204                } else {
205                    ccprintf(os, " ASR #%d", shiftAmt);
206                }
207                break;
208              case ROR:
209                if (shiftAmt == 0) {
210                    ccprintf(os, " RRX");
211                } else {
212                    ccprintf(os, " ROR #%d", shiftAmt);
213                }
214                break;
215            }
216        }
217    }
218};
219
220class MemoryDReg : public MemoryReg
221{
222  protected:
223    IntRegIndex dest2;
224
225    MemoryDReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
226               IntRegIndex _dest, IntRegIndex _dest2,
227               IntRegIndex _base, bool _add,
228               int32_t _shiftAmt, ArmShiftType _shiftType,
229               IntRegIndex _index)
230        : MemoryReg(mnem, _machInst, __opClass, _dest, _base, _add,
231                    _shiftAmt, _shiftType, _index),
232          dest2(_dest2)
233    {}
234
235    void
236    printDest(std::ostream &os) const
237    {
238        MemoryReg::printDest(os);
239        os << ", ";
240        printReg(os, dest2);
241    }
242};
243
244template<class Base>
245class MemoryOffset : public Base
246{
247  protected:
248    MemoryOffset(const char *mnem, ExtMachInst _machInst,
249                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
250                 bool _add, int32_t _imm)
251        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
252    {}
253
254    MemoryOffset(const char *mnem, ExtMachInst _machInst,
255                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
256                 bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
257                 IntRegIndex _index)
258        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
259                _shiftAmt, _shiftType, _index)
260    {}
261
262    MemoryOffset(const char *mnem, ExtMachInst _machInst,
263                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
264                 IntRegIndex _base, bool _add, int32_t _imm)
265        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
266    {}
267
268    MemoryOffset(const char *mnem, ExtMachInst _machInst,
269                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
270                 IntRegIndex _base, bool _add,
271                 int32_t _shiftAmt, ArmShiftType _shiftType,
272                 IntRegIndex _index)
273        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
274                _shiftAmt, _shiftType, _index)
275    {}
276
277    std::string
278    generateDisassembly(Addr pc, const SymbolTable *symtab) const
279    {
280        std::stringstream ss;
281        this->printInst(ss, Memory::AddrMd_Offset);
282        return ss.str();
283    }
284};
285
286template<class Base>
287class MemoryPreIndex : public Base
288{
289  protected:
290    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
291                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
292                   bool _add, int32_t _imm)
293        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
294    {}
295
296    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
297                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
298                   bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
299                   IntRegIndex _index)
300        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
301                _shiftAmt, _shiftType, _index)
302    {}
303
304    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
305                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
306                   IntRegIndex _base, bool _add, int32_t _imm)
307        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
308    {}
309
310    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
311                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
312                   IntRegIndex _base, bool _add,
313                   int32_t _shiftAmt, ArmShiftType _shiftType,
314                   IntRegIndex _index)
315        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
316                _shiftAmt, _shiftType, _index)
317    {}
318
319    std::string
320    generateDisassembly(Addr pc, const SymbolTable *symtab) const
321    {
322        std::stringstream ss;
323        this->printInst(ss, Memory::AddrMd_PreIndex);
324        return ss.str();
325    }
326};
327
328template<class Base>
329class MemoryPostIndex : public Base
330{
331  protected:
332    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
333                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
334                    bool _add, int32_t _imm)
335        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
336    {}
337
338    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
339                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
340                    bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
341                    IntRegIndex _index)
342        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
343                _shiftAmt, _shiftType, _index)
344    {}
345
346    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
347                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
348                    IntRegIndex _base, bool _add, int32_t _imm)
349        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
350    {}
351
352    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
353                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
354                    IntRegIndex _base, bool _add,
355                    int32_t _shiftAmt, ArmShiftType _shiftType,
356                    IntRegIndex _index)
357        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
358                _shiftAmt, _shiftType, _index)
359    {}
360
361    std::string
362    generateDisassembly(Addr pc, const SymbolTable *symtab) const
363    {
364        std::stringstream ss;
365        this->printInst(ss, Memory::AddrMd_PostIndex);
366        return ss.str();
367    }
368};
369}
370
371#endif //__ARCH_ARM_INSTS_MEM_HH__
372