mem.hh revision 7279
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__
348