pred_inst.hh revision 10537
12SN/A/*
21762SN/A * Copyright (c) 2010, 2012-2013 ARM Limited
35502Snate@binkert.org * All rights reserved
42SN/A *
52SN/A * The license below extends only to copyright in the software and shall
62SN/A * not be construed as granting a license to any other intellectual
72SN/A * property including but not limited to intellectual property relating
82SN/A * to a hardware implementation of the functionality of the software
92SN/A * licensed hereunder.  You may use the software subject to the license
102SN/A * terms below provided that you ensure that this notice is replicated
112SN/A * unmodified and in its entirety in all distributions of the software,
122SN/A * modified or unmodified, in source code or in binary form.
132SN/A *
142SN/A * Copyright (c) 2007-2008 The Florida State University
152SN/A * All rights reserved.
162SN/A *
172SN/A * Redistribution and use in source and binary forms, with or without
182SN/A * modification, are permitted provided that the following conditions are
192SN/A * met: redistributions of source code must retain the above copyright
202SN/A * notice, this list of conditions and the following disclaimer;
212SN/A * redistributions in binary form must reproduce the above copyright
222SN/A * notice, this list of conditions and the following disclaimer in the
232SN/A * documentation and/or other materials provided with the distribution;
242SN/A * neither the name of the copyright holders nor the names of its
252SN/A * contributors may be used to endorse or promote products derived from
262SN/A * this software without specific prior written permission.
272SN/A *
282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
345501Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
395502Snate@binkert.org *
405501Snate@binkert.org * Authors: Stephen Hines
415501Snate@binkert.org */
421717SN/A#ifndef __ARCH_ARM_INSTS_PREDINST_HH__
435501Snate@binkert.org#define __ARCH_ARM_INSTS_PREDINST_HH__
4456SN/A
452SN/A#include "arch/arm/insts/static_inst.hh"
462SN/A#include "base/trace.hh"
472SN/A
482SN/Anamespace ArmISA
492SN/A{
502SN/Astatic inline uint32_t
512SN/Arotate_imm(uint32_t immValue, uint32_t rotateValue)
522SN/A{
532SN/A    rotateValue &= 31;
545605Snate@binkert.org    return rotateValue == 0 ? immValue :
552SN/A        (immValue >> rotateValue) | (immValue << (32 - rotateValue));
564017Sstever@eecs.umich.edu}
574016Sstever@eecs.umich.edu
584017Sstever@eecs.umich.edustatic inline uint32_t
594016Sstever@eecs.umich.edumodified_imm(uint8_t ctrlImm, uint8_t dataImm)
605602Snate@binkert.org{
615602Snate@binkert.org    uint32_t bigData = dataImm;
625502Snate@binkert.org    uint32_t bigCtrl = ctrlImm;
635503Snate@binkert.org    if (bigCtrl < 4) {
645502Snate@binkert.org        switch (bigCtrl) {
655502Snate@binkert.org          case 0:
665502Snate@binkert.org            return bigData;
675502Snate@binkert.org          case 1:
685502Snate@binkert.org            return bigData | (bigData << 16);
695503Snate@binkert.org          case 2:
705502Snate@binkert.org            return (bigData << 8) | (bigData << 24);
715502Snate@binkert.org          case 3:
725502Snate@binkert.org            return (bigData << 0) | (bigData << 8) |
735502Snate@binkert.org                   (bigData << 16) | (bigData << 24);
745503Snate@binkert.org        }
755503Snate@binkert.org    }
765503Snate@binkert.org    bigCtrl = (bigCtrl << 1) | ((bigData >> 7) & 0x1);
775502Snate@binkert.org    bigData |= (1 << 7);
785503Snate@binkert.org    return bigData << (32 - bigCtrl);
795502Snate@binkert.org}
805502Snate@binkert.org
812SN/Astatic inline uint64_t
822SN/Asimd_modified_imm(bool op, uint8_t cmode, uint8_t data, bool &immValid,
832SN/A                  bool isAarch64 = false)
845502Snate@binkert.org{
855502Snate@binkert.org    uint64_t bigData = data;
865602Snate@binkert.org    immValid = true;
875502Snate@binkert.org    switch (cmode) {
885502Snate@binkert.org      case 0x0:
892SN/A      case 0x1:
905502Snate@binkert.org        bigData = (bigData << 0) | (bigData << 32);
915502Snate@binkert.org        break;
925503Snate@binkert.org      case 0x2:
935503Snate@binkert.org      case 0x3:
945503Snate@binkert.org        bigData = (bigData << 8) | (bigData << 40);
955503Snate@binkert.org        break;
965503Snate@binkert.org      case 0x4:
975502Snate@binkert.org      case 0x5:
982SN/A        bigData = (bigData << 16) | (bigData << 48);
995503Snate@binkert.org        break;
1005503Snate@binkert.org      case 0x6:
1015602Snate@binkert.org      case 0x7:
1025502Snate@binkert.org        bigData = (bigData << 24) | (bigData << 56);
1032SN/A        break;
1045602Snate@binkert.org      case 0x8:
1055602Snate@binkert.org      case 0x9:
1065502Snate@binkert.org        bigData = (bigData << 0) | (bigData << 16) |
1075503Snate@binkert.org                  (bigData << 32) | (bigData << 48);
1085503Snate@binkert.org        break;
1095502Snate@binkert.org      case 0xa:
1105503Snate@binkert.org      case 0xb:
1115503Snate@binkert.org        bigData = (bigData << 8) | (bigData << 24) |
1125503Snate@binkert.org                  (bigData << 40) | (bigData << 56);
1135503Snate@binkert.org        break;
1145503Snate@binkert.org      case 0xc:
1155503Snate@binkert.org        bigData = (0xffULL << 0) | (bigData << 8) |
1165503Snate@binkert.org                  (0xffULL << 32) | (bigData << 40);
1175503Snate@binkert.org        break;
1185503Snate@binkert.org      case 0xd:
1195503Snate@binkert.org        bigData = (0xffffULL << 0) | (bigData << 16) |
1205503Snate@binkert.org                  (0xffffULL << 32) | (bigData << 48);
1215503Snate@binkert.org        break;
1225503Snate@binkert.org      case 0xe:
1235503Snate@binkert.org        if (op) {
1245502Snate@binkert.org            bigData = 0;
1255502Snate@binkert.org            for (int i = 7; i >= 0; i--) {
1265503Snate@binkert.org                if (bits(data, i)) {
1275503Snate@binkert.org                    bigData |= (ULL(0xFF) << (i * 8));
1282SN/A                }
1295502Snate@binkert.org            }
1305503Snate@binkert.org        } else {
1315503Snate@binkert.org            bigData = (bigData << 0)  | (bigData << 8)  |
1325503Snate@binkert.org                      (bigData << 16) | (bigData << 24) |
1332SN/A                      (bigData << 32) | (bigData << 40) |
1342SN/A                      (bigData << 48) | (bigData << 56);
1352SN/A        }
1362SN/A        break;
1372SN/A      case 0xf:
1382SN/A        {
1395502Snate@binkert.org            uint64_t bVal = 0;
1402SN/A            if (!op) {
1415502Snate@binkert.org                bVal = bits(bigData, 6) ? (0x1F) : (0x20);
1425502Snate@binkert.org                bigData = (bits(bigData, 5, 0) << 19) |
1435502Snate@binkert.org                          (bVal << 25) | (bits(bigData, 7) << 31);
1445602Snate@binkert.org                bigData |= (bigData << 32);
1452SN/A                break;
1462SN/A            } else if (isAarch64) {
1472SN/A                bVal = bits(bigData, 6) ? (0x0FF) : (0x100);
1485502Snate@binkert.org                bigData = (bits(bigData, 5, 0) << 48) |
1492SN/A                          (bVal << 54) | (bits(bigData, 7) << 63);
1505502Snate@binkert.org                break;
1515502Snate@binkert.org            }
1522SN/A        }
1535502Snate@binkert.org        // Fall through, immediate encoding is invalid.
1542SN/A      default:
1552SN/A        immValid = false;
1565502Snate@binkert.org        break;
1575502Snate@binkert.org    }
1585502Snate@binkert.org    return bigData;
1595503Snate@binkert.org}
1605503Snate@binkert.org
1615502Snate@binkert.orgstatic inline uint64_t
1625602Snate@binkert.orgvfp_modified_imm(uint8_t data, bool wide)
1632SN/A{
1642SN/A    uint64_t bigData = data;
1652667Sstever@eecs.umich.edu    uint64_t repData;
1662SN/A    if (wide) {
1672SN/A        repData = bits(data, 6) ? 0xFF : 0;
1685503Snate@binkert.org        bigData = (bits(bigData, 5, 0) << 48) |
1695503Snate@binkert.org                  (repData << 54) | (bits(~bigData, 6) << 62) |
1702SN/A                  (bits(bigData, 7) << 63);
1715502Snate@binkert.org    } else {
1725503Snate@binkert.org        repData = bits(data, 6) ? 0x1F : 0;
1735503Snate@binkert.org        bigData = (bits(bigData, 5, 0) << 19) |
1745503Snate@binkert.org                  (repData << 25) | (bits(~bigData, 6) << 30) |
1755503Snate@binkert.org                  (bits(bigData, 7) << 31);
1765503Snate@binkert.org    }
1775503Snate@binkert.org    return bigData;
1785503Snate@binkert.org}
1795502Snate@binkert.org
1805502Snate@binkert.org
1815503Snate@binkert.org/**
1825502Snate@binkert.org * Base class for predicated integer operations.
1832SN/A */
1842SN/Aclass PredOp : public ArmStaticInst
1852667Sstever@eecs.umich.edu{
1862SN/A  protected:
1872667Sstever@eecs.umich.edu
1882667Sstever@eecs.umich.edu    ConditionCode condCode;
1892667Sstever@eecs.umich.edu
1902667Sstever@eecs.umich.edu    /// Constructor
1912667Sstever@eecs.umich.edu    PredOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
1922SN/A           ArmStaticInst(mnem, _machInst, __opClass)
1932667Sstever@eecs.umich.edu    {
1942SN/A        if (machInst.aarch64)
195294SN/A            condCode = COND_UC;
1962SN/A        else if (machInst.itstateMask)
1972667Sstever@eecs.umich.edu            condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
1982667Sstever@eecs.umich.edu        else
1992SN/A            condCode = (ConditionCode)(unsigned)machInst.condCode;
2002SN/A    }
201224SN/A};
202224SN/A
203224SN/A/**
204224SN/A * Base class for predicated immediate operations.
205224SN/A */
206224SN/Aclass PredImmOp : public PredOp
207224SN/A{
208224SN/A    protected:
209224SN/A
210237SN/A    uint32_t imm;
211224SN/A    uint32_t rotated_imm;
2125695Snate@binkert.org    uint32_t rotated_carry;
2135695Snate@binkert.org    uint32_t rotate;
214224SN/A
215224SN/A    /// Constructor
216224SN/A    PredImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
217224SN/A              PredOp(mnem, _machInst, __opClass),
218224SN/A              imm(machInst.imm), rotated_imm(0), rotated_carry(0),
219224SN/A              rotate(machInst.rotate << 1)
220224SN/A    {
221224SN/A        rotated_imm = rotate_imm(imm, rotate);
222224SN/A        if (rotate != 0)
223224SN/A            rotated_carry = bits(rotated_imm, 31);
224224SN/A    }
225224SN/A
226224SN/A    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
2275695Snate@binkert.org};
228224SN/A
229224SN/A/**
230224SN/A * Base class for predicated integer operations.
2312SN/A */
232217SN/Aclass PredIntOp : public PredOp
2332SN/A{
234265SN/A    protected:
235237SN/A
236237SN/A    uint32_t shift_size;
2375502Snate@binkert.org    uint32_t shift;
2385502Snate@binkert.org
2395503Snate@binkert.org    /// Constructor
2405502Snate@binkert.org    PredIntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
2415503Snate@binkert.org              PredOp(mnem, _machInst, __opClass),
2425502Snate@binkert.org              shift_size(machInst.shiftSize), shift(machInst.shift)
2435502Snate@binkert.org    {
2445502Snate@binkert.org    }
2455502Snate@binkert.org
2465502Snate@binkert.org    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
2475502Snate@binkert.org};
2485503Snate@binkert.org
2495502Snate@binkert.orgclass DataImmOp : public PredOp
2505502Snate@binkert.org{
2512SN/A  protected:
252237SN/A    IntRegIndex dest, op1;
253265SN/A    uint32_t imm;
254265SN/A    // Whether the carry flag should be modified if that's an option for
2555502Snate@binkert.org    // this instruction.
256265SN/A    bool rotC;
257265SN/A
258265SN/A    DataImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
259265SN/A              IntRegIndex _dest, IntRegIndex _op1, uint32_t _imm, bool _rotC) :
2602SN/A        PredOp(mnem, _machInst, __opClass),
2612SN/A        dest(_dest), op1(_op1), imm(_imm), rotC(_rotC)
262237SN/A    {}
263237SN/A
264237SN/A    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
265265SN/A};
266265SN/A
267265SN/Aclass DataRegOp : public PredOp
268270SN/A{
269265SN/A  protected:
270265SN/A    IntRegIndex dest, op1, op2;
271270SN/A    int32_t shiftAmt;
272265SN/A    ArmShiftType shiftType;
273265SN/A
274395SN/A    DataRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
275237SN/A              IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
276237SN/A              int32_t _shiftAmt, ArmShiftType _shiftType) :
277237SN/A        PredOp(mnem, _machInst, __opClass),
2782SN/A        dest(_dest), op1(_op1), op2(_op2),
2795501Snate@binkert.org        shiftAmt(_shiftAmt), shiftType(_shiftType)
2802SN/A    {}
2812SN/A
2822SN/A    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
2832SN/A};
2842SN/A
2852SN/Aclass DataRegRegOp : public PredOp
2862SN/A{
2872SN/A  protected:
2885502Snate@binkert.org    IntRegIndex dest, op1, op2, shift;
2895502Snate@binkert.org    ArmShiftType shiftType;
2905502Snate@binkert.org
2915503Snate@binkert.org    DataRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
2925503Snate@binkert.org                 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
2935502Snate@binkert.org                 IntRegIndex _shift, ArmShiftType _shiftType) :
2945503Snate@binkert.org        PredOp(mnem, _machInst, __opClass),
2955502Snate@binkert.org        dest(_dest), op1(_op1), op2(_op2), shift(_shift),
2965502Snate@binkert.org        shiftType(_shiftType)
2972SN/A    {}
2982SN/A
2992SN/A    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
3002SN/A};
3012SN/A
3022SN/A/**
3035502Snate@binkert.org * Base class for predicated macro-operations.
3045502Snate@binkert.org */
3055502Snate@binkert.orgclass PredMacroOp : public PredOp
3065502Snate@binkert.org{
3075502Snate@binkert.org    protected:
3085502Snate@binkert.org
3095502Snate@binkert.org    uint32_t numMicroops;
3105502Snate@binkert.org    StaticInstPtr * microOps;
3115502Snate@binkert.org
3125502Snate@binkert.org    /// Constructor
3135503Snate@binkert.org    PredMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
3145503Snate@binkert.org                PredOp(mnem, _machInst, __opClass),
3155502Snate@binkert.org                numMicroops(0), microOps(nullptr)
3165502Snate@binkert.org    {
3175502Snate@binkert.org        // We rely on the subclasses of this object to handle the
3185502Snate@binkert.org        // initialization of the micro-operations, since they are
3195502Snate@binkert.org        // all of variable length
3205502Snate@binkert.org        flags[IsMacroop] = true;
3215502Snate@binkert.org    }
3225502Snate@binkert.org
3235502Snate@binkert.org    ~PredMacroOp()
3245502Snate@binkert.org    {
3255502Snate@binkert.org        if (numMicroops)
3265502Snate@binkert.org            delete [] microOps;
3275502Snate@binkert.org    }
3285502Snate@binkert.org
3295502Snate@binkert.org    StaticInstPtr
3305502Snate@binkert.org    fetchMicroop(MicroPC microPC) const
3315502Snate@binkert.org    {
3325502Snate@binkert.org        assert(microPC < numMicroops);
3335502Snate@binkert.org        return microOps[microPC];
3345502Snate@binkert.org    }
3355502Snate@binkert.org
3365502Snate@binkert.org    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
3375503Snate@binkert.org};
3385502Snate@binkert.org
3395502Snate@binkert.org/**
3405502Snate@binkert.org * Base class for predicated micro-operations.
3415502Snate@binkert.org */
3425502Snate@binkert.orgclass PredMicroop : public PredOp
3435502Snate@binkert.org{
3445502Snate@binkert.org    /// Constructor
3451019SN/A    PredMicroop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
3461019SN/A                PredOp(mnem, _machInst, __opClass)
3471019SN/A    {
3481019SN/A        flags[IsMicroop] = true;
3491019SN/A    }
3501019SN/A
3512SN/A    void
3522SN/A    advancePC(PCState &pcState) const
3535336Shines@cs.fsu.edu    {
3542SN/A        if (flags[IsLastMicroop])
3552SN/A            pcState.uEnd();
3562SN/A        else
3572SN/A            pcState.uAdvance();
3582SN/A    }
3592SN/A};
3602SN/A}
3612SN/A
3622SN/A#endif //__ARCH_ARM_INSTS_PREDINST_HH__
3632SN/A