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