mem.hh revision 7428:eea9a618c882
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
90// The address is a base register plus an immediate.
91class SrsOp : public PredOp
92{
93  public:
94    enum AddrMode {
95        DecrementAfter,
96        DecrementBefore,
97        IncrementAfter,
98        IncrementBefore
99    };
100  protected:
101    uint32_t regMode;
102    AddrMode mode;
103    bool wb;
104
105    SrsOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
106          uint32_t _regMode, AddrMode _mode, bool _wb)
107        : PredOp(mnem, _machInst, __opClass),
108          regMode(_regMode), mode(_mode), wb(_wb)
109    {}
110
111    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
112};
113
114class Memory : public PredOp
115{
116  public:
117    enum AddrMode {
118        AddrMd_Offset,
119        AddrMd_PreIndex,
120        AddrMd_PostIndex
121    };
122
123  protected:
124
125    IntRegIndex dest;
126    IntRegIndex base;
127    bool add;
128
129    Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
130           IntRegIndex _dest, IntRegIndex _base, bool _add)
131        : PredOp(mnem, _machInst, __opClass),
132          dest(_dest), base(_base), add(_add)
133    {}
134
135    virtual void
136    printOffset(std::ostream &os) const
137    {}
138
139    virtual void
140    printDest(std::ostream &os) const
141    {
142        printReg(os, dest);
143    }
144
145    void printInst(std::ostream &os, AddrMode addrMode) const;
146};
147
148// The address is a base register plus an immediate.
149class MemoryImm : public Memory
150{
151  protected:
152    int32_t imm;
153
154    MemoryImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
155              IntRegIndex _dest, IntRegIndex _base, bool _add, int32_t _imm)
156        : Memory(mnem, _machInst, __opClass, _dest, _base, _add), imm(_imm)
157    {}
158
159    void
160    printOffset(std::ostream &os) const
161    {
162        int32_t pImm = imm;
163        if (!add)
164            pImm = -pImm;
165        ccprintf(os, "#%d", pImm);
166    }
167};
168
169class MemoryExImm : public MemoryImm
170{
171  protected:
172    IntRegIndex result;
173
174    MemoryExImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
175                IntRegIndex _result, IntRegIndex _dest, IntRegIndex _base,
176                bool _add, int32_t _imm)
177        : MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
178                    result(_result)
179    {}
180
181    void
182    printDest(std::ostream &os) const
183    {
184        printReg(os, result);
185        os << ", ";
186        MemoryImm::printDest(os);
187    }
188};
189
190// The address is a base register plus an immediate.
191class MemoryDImm : public MemoryImm
192{
193  protected:
194    IntRegIndex dest2;
195
196    MemoryDImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
197              IntRegIndex _dest, IntRegIndex _dest2,
198              IntRegIndex _base, bool _add, int32_t _imm)
199        : MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
200          dest2(_dest2)
201    {}
202
203    void
204    printDest(std::ostream &os) const
205    {
206        MemoryImm::printDest(os);
207        os << ", ";
208        printReg(os, dest2);
209    }
210};
211
212class MemoryExDImm : public MemoryDImm
213{
214  protected:
215    IntRegIndex result;
216
217    MemoryExDImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
218                 IntRegIndex _result, IntRegIndex _dest, IntRegIndex _dest2,
219                 IntRegIndex _base, bool _add, int32_t _imm)
220        : MemoryDImm(mnem, _machInst, __opClass, _dest, _dest2,
221                     _base, _add, _imm), result(_result)
222    {}
223
224    void
225    printDest(std::ostream &os) const
226    {
227        printReg(os, result);
228        os << ", ";
229        MemoryDImm::printDest(os);
230    }
231};
232
233// The address is a shifted register plus an immediate
234class MemoryReg : public Memory
235{
236  protected:
237    int32_t shiftAmt;
238    ArmShiftType shiftType;
239    IntRegIndex index;
240
241    MemoryReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
242              IntRegIndex _dest, IntRegIndex _base, bool _add,
243              int32_t _shiftAmt, ArmShiftType _shiftType,
244              IntRegIndex _index)
245        : Memory(mnem, _machInst, __opClass, _dest, _base, _add),
246          shiftAmt(_shiftAmt), shiftType(_shiftType), index(_index)
247    {}
248
249    void printOffset(std::ostream &os) const;
250};
251
252class MemoryDReg : public MemoryReg
253{
254  protected:
255    IntRegIndex dest2;
256
257    MemoryDReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
258               IntRegIndex _dest, IntRegIndex _dest2,
259               IntRegIndex _base, bool _add,
260               int32_t _shiftAmt, ArmShiftType _shiftType,
261               IntRegIndex _index)
262        : MemoryReg(mnem, _machInst, __opClass, _dest, _base, _add,
263                    _shiftAmt, _shiftType, _index),
264          dest2(_dest2)
265    {}
266
267    void
268    printDest(std::ostream &os) const
269    {
270        MemoryReg::printDest(os);
271        os << ", ";
272        printReg(os, dest2);
273    }
274};
275
276template<class Base>
277class MemoryOffset : public Base
278{
279  protected:
280    MemoryOffset(const char *mnem, ExtMachInst _machInst,
281                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
282                 bool _add, int32_t _imm)
283        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
284    {}
285
286    MemoryOffset(const char *mnem, ExtMachInst _machInst,
287                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
288                 bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
289                 IntRegIndex _index)
290        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
291                _shiftAmt, _shiftType, _index)
292    {}
293
294    MemoryOffset(const char *mnem, ExtMachInst _machInst,
295                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
296                 IntRegIndex _base, bool _add, int32_t _imm)
297        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
298    {}
299
300    MemoryOffset(const char *mnem, ExtMachInst _machInst,
301                 OpClass __opClass, IntRegIndex _result,
302                 IntRegIndex _dest, IntRegIndex _dest2,
303                 IntRegIndex _base, bool _add, int32_t _imm)
304        : Base(mnem, _machInst, __opClass, _result,
305                _dest, _dest2, _base, _add, _imm)
306    {}
307
308    MemoryOffset(const char *mnem, ExtMachInst _machInst,
309                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
310                 IntRegIndex _base, bool _add,
311                 int32_t _shiftAmt, ArmShiftType _shiftType,
312                 IntRegIndex _index)
313        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
314                _shiftAmt, _shiftType, _index)
315    {}
316
317    std::string
318    generateDisassembly(Addr pc, const SymbolTable *symtab) const
319    {
320        std::stringstream ss;
321        this->printInst(ss, Memory::AddrMd_Offset);
322        return ss.str();
323    }
324};
325
326template<class Base>
327class MemoryPreIndex : public Base
328{
329  protected:
330    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
331                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
332                   bool _add, int32_t _imm)
333        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
334    {}
335
336    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
337                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
338                   bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
339                   IntRegIndex _index)
340        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
341                _shiftAmt, _shiftType, _index)
342    {}
343
344    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
345                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
346                   IntRegIndex _base, bool _add, int32_t _imm)
347        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
348    {}
349
350    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
351                   OpClass __opClass, IntRegIndex _result,
352                   IntRegIndex _dest, IntRegIndex _dest2,
353                   IntRegIndex _base, bool _add, int32_t _imm)
354        : Base(mnem, _machInst, __opClass, _result,
355                _dest, _dest2, _base, _add, _imm)
356    {}
357
358    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
359                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
360                   IntRegIndex _base, bool _add,
361                   int32_t _shiftAmt, ArmShiftType _shiftType,
362                   IntRegIndex _index)
363        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
364                _shiftAmt, _shiftType, _index)
365    {}
366
367    std::string
368    generateDisassembly(Addr pc, const SymbolTable *symtab) const
369    {
370        std::stringstream ss;
371        this->printInst(ss, Memory::AddrMd_PreIndex);
372        return ss.str();
373    }
374};
375
376template<class Base>
377class MemoryPostIndex : public Base
378{
379  protected:
380    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
381                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
382                    bool _add, int32_t _imm)
383        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
384    {}
385
386    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
387                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
388                    bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
389                    IntRegIndex _index)
390        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
391                _shiftAmt, _shiftType, _index)
392    {}
393
394    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
395                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
396                    IntRegIndex _base, bool _add, int32_t _imm)
397        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
398    {}
399
400    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
401                    OpClass __opClass, IntRegIndex _result,
402                    IntRegIndex _dest, IntRegIndex _dest2,
403                    IntRegIndex _base, bool _add, int32_t _imm)
404        : Base(mnem, _machInst, __opClass, _result,
405                _dest, _dest2, _base, _add, _imm)
406    {}
407
408    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
409                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
410                    IntRegIndex _base, bool _add,
411                    int32_t _shiftAmt, ArmShiftType _shiftType,
412                    IntRegIndex _index)
413        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
414                _shiftAmt, _shiftType, _index)
415    {}
416
417    std::string
418    generateDisassembly(Addr pc, const SymbolTable *symtab) const
419    {
420        std::stringstream ss;
421        this->printInst(ss, Memory::AddrMd_PostIndex);
422        return ss.str();
423    }
424};
425}
426
427#endif //__ARCH_ARM_INSTS_MEM_HH__
428