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