mem.hh revision 7312:03016344f54e
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
250    printOffset(std::ostream &os) const
251    {
252        if (!add)
253            os << "-";
254        printReg(os, index);
255        if (shiftType != LSL || shiftAmt != 0) {
256            switch (shiftType) {
257              case LSL:
258                ccprintf(os, " LSL #%d", shiftAmt);
259                break;
260              case LSR:
261                if (shiftAmt == 0) {
262                    ccprintf(os, " LSR #%d", 32);
263                } else {
264                    ccprintf(os, " LSR #%d", shiftAmt);
265                }
266                break;
267              case ASR:
268                if (shiftAmt == 0) {
269                    ccprintf(os, " ASR #%d", 32);
270                } else {
271                    ccprintf(os, " ASR #%d", shiftAmt);
272                }
273                break;
274              case ROR:
275                if (shiftAmt == 0) {
276                    ccprintf(os, " RRX");
277                } else {
278                    ccprintf(os, " ROR #%d", shiftAmt);
279                }
280                break;
281            }
282        }
283    }
284};
285
286class MemoryDReg : public MemoryReg
287{
288  protected:
289    IntRegIndex dest2;
290
291    MemoryDReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
292               IntRegIndex _dest, IntRegIndex _dest2,
293               IntRegIndex _base, bool _add,
294               int32_t _shiftAmt, ArmShiftType _shiftType,
295               IntRegIndex _index)
296        : MemoryReg(mnem, _machInst, __opClass, _dest, _base, _add,
297                    _shiftAmt, _shiftType, _index),
298          dest2(_dest2)
299    {}
300
301    void
302    printDest(std::ostream &os) const
303    {
304        MemoryReg::printDest(os);
305        os << ", ";
306        printReg(os, dest2);
307    }
308};
309
310template<class Base>
311class MemoryOffset : public Base
312{
313  protected:
314    MemoryOffset(const char *mnem, ExtMachInst _machInst,
315                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
316                 bool _add, int32_t _imm)
317        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
318    {}
319
320    MemoryOffset(const char *mnem, ExtMachInst _machInst,
321                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
322                 bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
323                 IntRegIndex _index)
324        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
325                _shiftAmt, _shiftType, _index)
326    {}
327
328    MemoryOffset(const char *mnem, ExtMachInst _machInst,
329                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
330                 IntRegIndex _base, bool _add, int32_t _imm)
331        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
332    {}
333
334    MemoryOffset(const char *mnem, ExtMachInst _machInst,
335                 OpClass __opClass, IntRegIndex _result,
336                 IntRegIndex _dest, IntRegIndex _dest2,
337                 IntRegIndex _base, bool _add, int32_t _imm)
338        : Base(mnem, _machInst, __opClass, _result,
339                _dest, _dest2, _base, _add, _imm)
340    {}
341
342    MemoryOffset(const char *mnem, ExtMachInst _machInst,
343                 OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
344                 IntRegIndex _base, bool _add,
345                 int32_t _shiftAmt, ArmShiftType _shiftType,
346                 IntRegIndex _index)
347        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
348                _shiftAmt, _shiftType, _index)
349    {}
350
351    std::string
352    generateDisassembly(Addr pc, const SymbolTable *symtab) const
353    {
354        std::stringstream ss;
355        this->printInst(ss, Memory::AddrMd_Offset);
356        return ss.str();
357    }
358};
359
360template<class Base>
361class MemoryPreIndex : public Base
362{
363  protected:
364    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
365                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
366                   bool _add, int32_t _imm)
367        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
368    {}
369
370    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
371                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
372                   bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
373                   IntRegIndex _index)
374        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
375                _shiftAmt, _shiftType, _index)
376    {}
377
378    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
379                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
380                   IntRegIndex _base, bool _add, int32_t _imm)
381        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
382    {}
383
384    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
385                   OpClass __opClass, IntRegIndex _result,
386                   IntRegIndex _dest, IntRegIndex _dest2,
387                   IntRegIndex _base, bool _add, int32_t _imm)
388        : Base(mnem, _machInst, __opClass, _result,
389                _dest, _dest2, _base, _add, _imm)
390    {}
391
392    MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
393                   OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
394                   IntRegIndex _base, bool _add,
395                   int32_t _shiftAmt, ArmShiftType _shiftType,
396                   IntRegIndex _index)
397        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
398                _shiftAmt, _shiftType, _index)
399    {}
400
401    std::string
402    generateDisassembly(Addr pc, const SymbolTable *symtab) const
403    {
404        std::stringstream ss;
405        this->printInst(ss, Memory::AddrMd_PreIndex);
406        return ss.str();
407    }
408};
409
410template<class Base>
411class MemoryPostIndex : public Base
412{
413  protected:
414    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
415                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
416                    bool _add, int32_t _imm)
417        : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
418    {}
419
420    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
421                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
422                    bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
423                    IntRegIndex _index)
424        : Base(mnem, _machInst, __opClass, _dest, _base, _add,
425                _shiftAmt, _shiftType, _index)
426    {}
427
428    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
429                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
430                    IntRegIndex _base, bool _add, int32_t _imm)
431        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
432    {}
433
434    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
435                    OpClass __opClass, IntRegIndex _result,
436                    IntRegIndex _dest, IntRegIndex _dest2,
437                    IntRegIndex _base, bool _add, int32_t _imm)
438        : Base(mnem, _machInst, __opClass, _result,
439                _dest, _dest2, _base, _add, _imm)
440    {}
441
442    MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
443                    OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
444                    IntRegIndex _base, bool _add,
445                    int32_t _shiftAmt, ArmShiftType _shiftType,
446                    IntRegIndex _index)
447        : Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
448                _shiftAmt, _shiftType, _index)
449    {}
450
451    std::string
452    generateDisassembly(Addr pc, const SymbolTable *symtab) const
453    {
454        std::stringstream ss;
455        this->printInst(ss, Memory::AddrMd_PostIndex);
456        return ss.str();
457    }
458};
459}
460
461#endif //__ARCH_ARM_INSTS_MEM_HH__
462