mem.hh revision 7205:e3dfcdf19561
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    void printInst(std::ostream &os, AddrMode addrMode) const;
92};
93
94// The address is a base register plus an immediate.
95class MemoryImm : public Memory
96{
97  protected:
98    int32_t imm;
99
100    MemoryImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
101              IntRegIndex _dest, IntRegIndex _base, bool _add, int32_t _imm)
102        : Memory(mnem, _machInst, __opClass, _dest, _base, _add), imm(_imm)
103    {}
104
105    void
106    printOffset(std::ostream &os) const
107    {
108        int32_t pImm = imm;
109        if (!add)
110            pImm = -pImm;
111        ccprintf(os, "#%d", pImm);
112    }
113};
114
115// The address is a shifted register plus an immediate
116class MemoryReg : public Memory
117{
118  protected:
119    int32_t shiftAmt;
120    ArmShiftType shiftType;
121    IntRegIndex index;
122
123    MemoryReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
124              IntRegIndex _dest, IntRegIndex _base, bool _add,
125              int32_t _shiftAmt, ArmShiftType _shiftType,
126              IntRegIndex _index)
127        : Memory(mnem, _machInst, __opClass, _dest, _base, _add),
128          shiftAmt(_shiftAmt), shiftType(_shiftType), index(_index)
129    {}
130
131    void
132    printOffset(std::ostream &os) const
133    {
134        if (!add)
135            os << "-";
136        printReg(os, index);
137        if (shiftType != LSL || shiftAmt != 0) {
138            switch (shiftType) {
139              case LSL:
140                ccprintf(os, " LSL #%d", shiftAmt);
141                break;
142              case LSR:
143                if (shiftAmt == 0) {
144                    ccprintf(os, " LSR #%d", 32);
145                } else {
146                    ccprintf(os, " LSR #%d", shiftAmt);
147                }
148                break;
149              case ASR:
150                if (shiftAmt == 0) {
151                    ccprintf(os, " ASR #%d", 32);
152                } else {
153                    ccprintf(os, " ASR #%d", shiftAmt);
154                }
155                break;
156              case ROR:
157                if (shiftAmt == 0) {
158                    ccprintf(os, " RRX");
159                } else {
160                    ccprintf(os, " ROR #%d", shiftAmt);
161                }
162                break;
163            }
164        }
165    }
166};
167
168template<class Base>
169class MemoryOffset : public Base
170{
171  protected:
172    MemoryOffset(const char *mnem, ExtMachInst _machInst,
173                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
174                 bool _add, int32_t _imm)
175        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
176    {}
177
178    MemoryOffset(const char *mnem, ExtMachInst _machInst,
179                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
180                 bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
181                 IntRegIndex _index)
182        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
183                _shiftAmt, _shiftType, _index)
184    {}
185
186    std::string
187    generateDisassembly(Addr pc, const SymbolTable *symtab) const
188    {
189        std::stringstream ss;
190        this->printInst(ss, Memory::AddrMd_Offset);
191        return ss.str();
192    }
193};
194
195template<class Base>
196class MemoryPreIndex : public Base
197{
198  protected:
199    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
200                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
201                   bool _add, int32_t _imm)
202        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
203    {}
204
205    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
206                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
207                   bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
208                   IntRegIndex _index)
209        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
210                _shiftAmt, _shiftType, _index)
211    {}
212
213    std::string
214    generateDisassembly(Addr pc, const SymbolTable *symtab) const
215    {
216        std::stringstream ss;
217        this->printInst(ss, Memory::AddrMd_PreIndex);
218        return ss.str();
219    }
220};
221
222template<class Base>
223class MemoryPostIndex : public Base
224{
225  protected:
226    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
227                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
228                    bool _add, int32_t _imm)
229        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
230    {}
231
232    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
233                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
234                    bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
235                    IntRegIndex _index)
236        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
237                _shiftAmt, _shiftType, _index)
238    {}
239
240    std::string
241    generateDisassembly(Addr pc, const SymbolTable *symtab) const
242    {
243        std::stringstream ss;
244        this->printInst(ss, Memory::AddrMd_PostIndex);
245        return ss.str();
246    }
247};
248}
249
250#endif //__ARCH_ARM_INSTS_MEM_HH__
251