mem.hh revision 7646:a444dbee8c07
11689SN/A/*
210330Smitch.hayenga@arm.com * Copyright (c) 2010 ARM Limited
38842Smrinmoy.ghosh@arm.com * All rights reserved
48842Smrinmoy.ghosh@arm.com *
58842Smrinmoy.ghosh@arm.com * The license below extends only to copyright in the software and shall
68842Smrinmoy.ghosh@arm.com * not be construed as granting a license to any other intellectual
78842Smrinmoy.ghosh@arm.com * property including but not limited to intellectual property relating
88842Smrinmoy.ghosh@arm.com * to a hardware implementation of the functionality of the software
98842Smrinmoy.ghosh@arm.com * licensed hereunder.  You may use the software subject to the license
108842Smrinmoy.ghosh@arm.com * terms below provided that you ensure that this notice is replicated
118842Smrinmoy.ghosh@arm.com * unmodified and in its entirety in all distributions of the software,
128842Smrinmoy.ghosh@arm.com * modified or unmodified, in source code or in binary form.
138842Smrinmoy.ghosh@arm.com *
142345SN/A * Copyright (c) 2007-2008 The Florida State University
151689SN/A * All rights reserved.
161689SN/A *
171689SN/A * Redistribution and use in source and binary forms, with or without
181689SN/A * modification, are permitted provided that the following conditions are
191689SN/A * met: redistributions of source code must retain the above copyright
201689SN/A * notice, this list of conditions and the following disclaimer;
211689SN/A * redistributions in binary form must reproduce the above copyright
221689SN/A * notice, this list of conditions and the following disclaimer in the
231689SN/A * documentation and/or other materials provided with the distribution;
241689SN/A * neither the name of the copyright holders nor the names of its
251689SN/A * contributors may be used to endorse or promote products derived from
261689SN/A * this software without specific prior written permission.
271689SN/A *
281689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
291689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
301689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
311689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
321689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
331689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
341689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
351689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
361689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
371689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
381689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665SN/A *
402665SN/A * Authors: Stephen Hines
419480Snilay@cs.wisc.edu */
429480Snilay@cs.wisc.edu#ifndef __ARCH_ARM_MEM_HH__
431689SN/A#define __ARCH_ARM_MEM_HH__
441689SN/A
459480Snilay@cs.wisc.edu#include "arch/arm/insts/pred_inst.hh"
469480Snilay@cs.wisc.edu
471062SN/Anamespace ArmISA
486216SN/A{
496216SN/A
506216SN/Aclass Swap : public PredOp
519480Snilay@cs.wisc.edu{
529480Snilay@cs.wisc.edu  protected:
531062SN/A    IntRegIndex dest;
542345SN/A    IntRegIndex op1;
552345SN/A    IntRegIndex base;
562345SN/A
572345SN/A    Swap(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
582345SN/A         IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _base)
592345SN/A        : PredOp(mnem, _machInst, __opClass),
602345SN/A          dest(_dest), op1(_op1), base(_base)
612345SN/A    {}
622345SN/A
639480Snilay@cs.wisc.edu    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
641062SN/A};
651062SN/A
661062SN/A// The address is a base register plus an immediate.
671062SN/Aclass RfeOp : public PredOp
681062SN/A{
699480Snilay@cs.wisc.edu  public:
701062SN/A    enum AddrMode {
711062SN/A        DecrementAfter,
721062SN/A        DecrementBefore,
732345SN/A        IncrementAfter,
742345SN/A        IncrementBefore
751062SN/A    };
762345SN/A  protected:
771062SN/A    IntRegIndex base;
781062SN/A    AddrMode mode;
799480Snilay@cs.wisc.edu    bool wb;
802345SN/A    static const unsigned numMicroops = 2;
812345SN/A
822345SN/A    StaticInstPtr *uops;
832345SN/A
842345SN/A    RfeOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
852345SN/A          IntRegIndex _base, AddrMode _mode, bool _wb)
862345SN/A        : PredOp(mnem, _machInst, __opClass),
879480Snilay@cs.wisc.edu          base(_base), mode(_mode), wb(_wb), uops(NULL)
888842Smrinmoy.ghosh@arm.com    {}
898842Smrinmoy.ghosh@arm.com
908842Smrinmoy.ghosh@arm.com    virtual
918842Smrinmoy.ghosh@arm.com    ~RfeOp()
928842Smrinmoy.ghosh@arm.com    {
938842Smrinmoy.ghosh@arm.com        delete uops;
948842Smrinmoy.ghosh@arm.com    }
959480Snilay@cs.wisc.edu
961062SN/A    StaticInstPtr
971062SN/A    fetchMicroop(MicroPC microPC)
981062SN/A    {
991062SN/A        assert(uops != NULL && microPC < numMicroops);
1002345SN/A        return uops[microPC];
1012345SN/A    }
1028842Smrinmoy.ghosh@arm.com
1038842Smrinmoy.ghosh@arm.com    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1041062SN/A};
1059480Snilay@cs.wisc.edu
1061062SN/A// The address is a base register plus an immediate.
10710330Smitch.hayenga@arm.comclass SrsOp : public PredOp
10810330Smitch.hayenga@arm.com{
1092345SN/A  public:
1102345SN/A    enum AddrMode {
1112345SN/A        DecrementAfter,
1122345SN/A        DecrementBefore,
1132345SN/A        IncrementAfter,
1142345SN/A        IncrementBefore
1152345SN/A    };
1162345SN/A  protected:
1171684SN/A    uint32_t regMode;
1181062SN/A    AddrMode mode;
1191062SN/A    bool wb;
1202345SN/A    static const unsigned numMicroops = 2;
1212345SN/A
1222345SN/A    StaticInstPtr *uops;
1232345SN/A
1242345SN/A    SrsOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
1251062SN/A          uint32_t _regMode, AddrMode _mode, bool _wb)
1261062SN/A        : PredOp(mnem, _machInst, __opClass),
1272345SN/A          regMode(_regMode), mode(_mode), wb(_wb), uops(NULL)
1282345SN/A    {}
1292345SN/A
1302345SN/A    virtual
1311062SN/A    ~SrsOp()
1321062SN/A    {
1332345SN/A        delete uops;
1342345SN/A    }
1351062SN/A
1362345SN/A    StaticInstPtr
1372345SN/A    fetchMicroop(MicroPC microPC)
1382345SN/A    {
1392345SN/A        assert(uops != NULL && microPC < numMicroops);
1402345SN/A        return uops[microPC];
1412345SN/A    }
1422345SN/A
1432345SN/A    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1442345SN/A};
1452345SN/A
1462345SN/Aclass Memory : public PredOp
1472345SN/A{
1482345SN/A  public:
1492345SN/A    enum AddrMode {
1502345SN/A        AddrMd_Offset,
1512345SN/A        AddrMd_PreIndex,
1522345SN/A        AddrMd_PostIndex
1532345SN/A    };
1542345SN/A
1552345SN/A  protected:
1562345SN/A
1572345SN/A    IntRegIndex dest;
1582345SN/A    IntRegIndex base;
1592345SN/A    bool add;
1602345SN/A    static const unsigned numMicroops = 3;
1612345SN/A
1622345SN/A    StaticInstPtr *uops;
1632345SN/A
1642345SN/A    Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
1652345SN/A           IntRegIndex _dest, IntRegIndex _base, bool _add)
1662345SN/A        : PredOp(mnem, _machInst, __opClass),
1672345SN/A          dest(_dest), base(_base), add(_add), uops(NULL)
1682345SN/A    {}
1698842Smrinmoy.ghosh@arm.com
1702345SN/A    virtual
1712345SN/A    ~Memory()
1722345SN/A    {
1732345SN/A        delete [] uops;
1741062SN/A    }
1758842Smrinmoy.ghosh@arm.com
1768842Smrinmoy.ghosh@arm.com    StaticInstPtr
1771062SN/A    fetchMicroop(MicroPC microPC)
1782292SN/A    {
1791062SN/A        assert(uops != NULL && microPC < numMicroops);
1809360SE.Tomusk@sms.ed.ac.uk        return uops[microPC];
1811684SN/A    }
1821062SN/A
1839360SE.Tomusk@sms.ed.ac.uk    virtual void
1842356SN/A    printOffset(std::ostream &os) const
1852356SN/A    {}
1861062SN/A
1871684SN/A    virtual void
1881062SN/A    printDest(std::ostream &os) const
1891062SN/A    {
1902292SN/A        printReg(os, dest);
1911062SN/A    }
1929360SE.Tomusk@sms.ed.ac.uk
1931684SN/A    void printInst(std::ostream &os, AddrMode addrMode) const;
1941062SN/A};
1959360SE.Tomusk@sms.ed.ac.uk
1961684SN/A// The address is a base register plus an immediate.
1971062SN/Aclass MemoryImm : public Memory
1981062SN/A{
1992292SN/A  protected:
2001062SN/A    int32_t imm;
2019360SE.Tomusk@sms.ed.ac.uk
2021684SN/A    MemoryImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
2031062SN/A              IntRegIndex _dest, IntRegIndex _base, bool _add, int32_t _imm)
2041062SN/A        : Memory(mnem, _machInst, __opClass, _dest, _base, _add), imm(_imm)
2051684SN/A    {}
2061062SN/A
2079360SE.Tomusk@sms.ed.ac.uk    void
2089360SE.Tomusk@sms.ed.ac.uk    printOffset(std::ostream &os) const
2099360SE.Tomusk@sms.ed.ac.uk    {
2101684SN/A        int32_t pImm = imm;
2111062SN/A        if (!add)
2129360SE.Tomusk@sms.ed.ac.uk            pImm = -pImm;
2139360SE.Tomusk@sms.ed.ac.uk        ccprintf(os, "#%d", pImm);
2141684SN/A    }
2151062SN/A};
2169360SE.Tomusk@sms.ed.ac.uk
2179360SE.Tomusk@sms.ed.ac.ukclass MemoryExImm : public MemoryImm
2181062SN/A{
2191062SN/A  protected:
2209360SE.Tomusk@sms.ed.ac.uk    IntRegIndex result;
2219360SE.Tomusk@sms.ed.ac.uk
2229360SE.Tomusk@sms.ed.ac.uk    MemoryExImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
2239360SE.Tomusk@sms.ed.ac.uk                IntRegIndex _result, IntRegIndex _dest, IntRegIndex _base,
2249360SE.Tomusk@sms.ed.ac.uk                bool _add, int32_t _imm)
2259360SE.Tomusk@sms.ed.ac.uk        : MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
2269360SE.Tomusk@sms.ed.ac.uk                    result(_result)
2279360SE.Tomusk@sms.ed.ac.uk    {}
2281062SN/A
2292292SN/A    void
2301062SN/A    printDest(std::ostream &os) const
2319360SE.Tomusk@sms.ed.ac.uk    {
2321684SN/A        printReg(os, result);
2331062SN/A        os << ", ";
2349360SE.Tomusk@sms.ed.ac.uk        MemoryImm::printDest(os);
2351684SN/A    }
2361062SN/A};
2371062SN/A
2381062SN/A// The address is a base register plus an immediate.
2391062SN/Aclass MemoryDImm : public MemoryImm
2401062SN/A{
2411062SN/A  protected:
2429360SE.Tomusk@sms.ed.ac.uk    IntRegIndex dest2;
2431062SN/A
2441062SN/A    MemoryDImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
2459360SE.Tomusk@sms.ed.ac.uk              IntRegIndex _dest, IntRegIndex _dest2,
2469360SE.Tomusk@sms.ed.ac.uk              IntRegIndex _base, bool _add, int32_t _imm)
2479360SE.Tomusk@sms.ed.ac.uk        : MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
2481062SN/A          dest2(_dest2)
2491062SN/A    {}
2509480Snilay@cs.wisc.edu
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