sve_macromem.hh revision 14091
114028Sgiacomo.gabrielli@arm.com/*
214028Sgiacomo.gabrielli@arm.com * Copyright (c) 2018 ARM Limited
314028Sgiacomo.gabrielli@arm.com * All rights reserved
414028Sgiacomo.gabrielli@arm.com *
514028Sgiacomo.gabrielli@arm.com * The license below extends only to copyright in the software and shall
614028Sgiacomo.gabrielli@arm.com * not be construed as granting a license to any other intellectual
714028Sgiacomo.gabrielli@arm.com * property including but not limited to intellectual property relating
814028Sgiacomo.gabrielli@arm.com * to a hardware implementation of the functionality of the software
914028Sgiacomo.gabrielli@arm.com * licensed hereunder.  You may use the software subject to the license
1014028Sgiacomo.gabrielli@arm.com * terms below provided that you ensure that this notice is replicated
1114028Sgiacomo.gabrielli@arm.com * unmodified and in its entirety in all distributions of the software,
1214028Sgiacomo.gabrielli@arm.com * modified or unmodified, in source code or in binary form.
1314028Sgiacomo.gabrielli@arm.com *
1414028Sgiacomo.gabrielli@arm.com * Redistribution and use in source and binary forms, with or without
1514028Sgiacomo.gabrielli@arm.com * modification, are permitted provided that the following conditions are
1614028Sgiacomo.gabrielli@arm.com * met: redistributions of source code must retain the above copyright
1714028Sgiacomo.gabrielli@arm.com * notice, this list of conditions and the following disclaimer;
1814028Sgiacomo.gabrielli@arm.com * redistributions in binary form must reproduce the above copyright
1914028Sgiacomo.gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the
2014028Sgiacomo.gabrielli@arm.com * documentation and/or other materials provided with the distribution;
2114028Sgiacomo.gabrielli@arm.com * neither the name of the copyright holders nor the names of its
2214028Sgiacomo.gabrielli@arm.com * contributors may be used to endorse or promote products derived from
2314028Sgiacomo.gabrielli@arm.com * this software without specific prior written permission.
2414028Sgiacomo.gabrielli@arm.com *
2514028Sgiacomo.gabrielli@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2614028Sgiacomo.gabrielli@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2714028Sgiacomo.gabrielli@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2814028Sgiacomo.gabrielli@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2914028Sgiacomo.gabrielli@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3014028Sgiacomo.gabrielli@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3114028Sgiacomo.gabrielli@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3214028Sgiacomo.gabrielli@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3314028Sgiacomo.gabrielli@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3414028Sgiacomo.gabrielli@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3514028Sgiacomo.gabrielli@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3614028Sgiacomo.gabrielli@arm.com *
3714028Sgiacomo.gabrielli@arm.com * Authors: Giacomo Gabrielli
3814028Sgiacomo.gabrielli@arm.com */
3914028Sgiacomo.gabrielli@arm.com
4014028Sgiacomo.gabrielli@arm.com#ifndef __ARCH_ARM_SVE_MACROMEM_HH__
4114028Sgiacomo.gabrielli@arm.com#define __ARCH_ARM_SVE_MACROMEM_HH__
4214028Sgiacomo.gabrielli@arm.com
4314028Sgiacomo.gabrielli@arm.com#include "arch/arm/generated/decoder.hh"
4414028Sgiacomo.gabrielli@arm.com#include "arch/arm/insts/pred_inst.hh"
4514028Sgiacomo.gabrielli@arm.com
4614028Sgiacomo.gabrielli@arm.comnamespace ArmISA {
4714028Sgiacomo.gabrielli@arm.com
4814028Sgiacomo.gabrielli@arm.comtemplate <typename RegElemType, typename MemElemType,
4914091Sgabor.dozsa@arm.com          template <typename, typename> class MicroopType,
5014091Sgabor.dozsa@arm.com          template <typename> class FirstFaultWritebackMicroopType>
5114028Sgiacomo.gabrielli@arm.comclass SveIndexedMemVI : public PredMacroOp
5214028Sgiacomo.gabrielli@arm.com{
5314028Sgiacomo.gabrielli@arm.com  protected:
5414028Sgiacomo.gabrielli@arm.com    IntRegIndex dest;
5514028Sgiacomo.gabrielli@arm.com    IntRegIndex gp;
5614028Sgiacomo.gabrielli@arm.com    IntRegIndex base;
5714028Sgiacomo.gabrielli@arm.com    uint64_t imm;
5814028Sgiacomo.gabrielli@arm.com
5914028Sgiacomo.gabrielli@arm.com  public:
6014028Sgiacomo.gabrielli@arm.com    SveIndexedMemVI(const char *mnem, ExtMachInst machInst, OpClass __opClass,
6114028Sgiacomo.gabrielli@arm.com                    IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
6214091Sgabor.dozsa@arm.com                    uint64_t _imm, bool firstFault)
6314028Sgiacomo.gabrielli@arm.com        : PredMacroOp(mnem, machInst, __opClass),
6414028Sgiacomo.gabrielli@arm.com          dest(_dest), gp(_gp), base(_base), imm(_imm)
6514028Sgiacomo.gabrielli@arm.com    {
6614028Sgiacomo.gabrielli@arm.com        bool isLoad = (__opClass == MemReadOp);
6714091Sgabor.dozsa@arm.com        assert(!firstFault || isLoad);
6814028Sgiacomo.gabrielli@arm.com
6914028Sgiacomo.gabrielli@arm.com        int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType);
7014028Sgiacomo.gabrielli@arm.com
7114028Sgiacomo.gabrielli@arm.com        numMicroops = num_elems;
7214028Sgiacomo.gabrielli@arm.com        if (isLoad) {
7314091Sgabor.dozsa@arm.com            if (firstFault) {
7414091Sgabor.dozsa@arm.com                numMicroops += 2;
7514091Sgabor.dozsa@arm.com            } else {
7614091Sgabor.dozsa@arm.com                numMicroops++;
7714091Sgabor.dozsa@arm.com            }
7814028Sgiacomo.gabrielli@arm.com        }
7914028Sgiacomo.gabrielli@arm.com
8014028Sgiacomo.gabrielli@arm.com        microOps = new StaticInstPtr[numMicroops];
8114028Sgiacomo.gabrielli@arm.com
8214028Sgiacomo.gabrielli@arm.com        StaticInstPtr *uop = microOps;
8314028Sgiacomo.gabrielli@arm.com
8414028Sgiacomo.gabrielli@arm.com        if (isLoad) {
8514028Sgiacomo.gabrielli@arm.com            // The first microop of a gather load copies the source vector
8614028Sgiacomo.gabrielli@arm.com            // register used for address calculation to an auxiliary register,
8714028Sgiacomo.gabrielli@arm.com            // with all subsequent microops reading from the latter.  This is
8814028Sgiacomo.gabrielli@arm.com            // needed to properly handle cases where the source vector
8914028Sgiacomo.gabrielli@arm.com            // register is the same as the destination register
9014028Sgiacomo.gabrielli@arm.com            *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop(
9114028Sgiacomo.gabrielli@arm.com                mnem, machInst, _base, this);
9214028Sgiacomo.gabrielli@arm.com            uop++;
9314028Sgiacomo.gabrielli@arm.com        }
9414028Sgiacomo.gabrielli@arm.com
9514028Sgiacomo.gabrielli@arm.com        for (int i = 0; i < num_elems; i++, uop++) {
9614028Sgiacomo.gabrielli@arm.com            *uop = new MicroopType<RegElemType, MemElemType>(
9714028Sgiacomo.gabrielli@arm.com                mnem, machInst, __opClass, _dest, _gp,
9814028Sgiacomo.gabrielli@arm.com                isLoad ? (IntRegIndex) VECREG_UREG0 : _base, _imm, i,
9914091Sgabor.dozsa@arm.com                num_elems, firstFault);
10014028Sgiacomo.gabrielli@arm.com        }
10114028Sgiacomo.gabrielli@arm.com
10214091Sgabor.dozsa@arm.com        if (firstFault) {
10314091Sgabor.dozsa@arm.com            *uop = new FirstFaultWritebackMicroopType<RegElemType>(
10414091Sgabor.dozsa@arm.com                mnem, machInst, __opClass, num_elems, this);
10514091Sgabor.dozsa@arm.com        } else {
10614091Sgabor.dozsa@arm.com            --uop;
10714091Sgabor.dozsa@arm.com        }
10814091Sgabor.dozsa@arm.com
10914028Sgiacomo.gabrielli@arm.com        (*uop)->setLastMicroop();
11014028Sgiacomo.gabrielli@arm.com        microOps[0]->setFirstMicroop();
11114028Sgiacomo.gabrielli@arm.com
11214028Sgiacomo.gabrielli@arm.com        for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
11314028Sgiacomo.gabrielli@arm.com            (*uop)->setDelayedCommit();
11414028Sgiacomo.gabrielli@arm.com        }
11514028Sgiacomo.gabrielli@arm.com    }
11614028Sgiacomo.gabrielli@arm.com
11714028Sgiacomo.gabrielli@arm.com    Fault
11814028Sgiacomo.gabrielli@arm.com    execute(ExecContext *, Trace::InstRecord *) const
11914028Sgiacomo.gabrielli@arm.com    {
12014028Sgiacomo.gabrielli@arm.com        panic("Execute method called when it shouldn't!");
12114028Sgiacomo.gabrielli@arm.com        return NoFault;
12214028Sgiacomo.gabrielli@arm.com    }
12314028Sgiacomo.gabrielli@arm.com
12414028Sgiacomo.gabrielli@arm.com    std::string
12514028Sgiacomo.gabrielli@arm.com    generateDisassembly(Addr pc, const SymbolTable *symtab) const
12614028Sgiacomo.gabrielli@arm.com    {
12714028Sgiacomo.gabrielli@arm.com        // TODO: add suffix to transfer and base registers
12814028Sgiacomo.gabrielli@arm.com        std::stringstream ss;
12914028Sgiacomo.gabrielli@arm.com        printMnemonic(ss, "", false);
13014028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "{");
13114028Sgiacomo.gabrielli@arm.com        printVecReg(ss, dest, true);
13214028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "}, ");
13314028Sgiacomo.gabrielli@arm.com        printVecPredReg(ss, gp);
13414028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "/z, [");
13514028Sgiacomo.gabrielli@arm.com        printVecReg(ss, base, true);
13614028Sgiacomo.gabrielli@arm.com        if (imm != 0) {
13714028Sgiacomo.gabrielli@arm.com            ccprintf(ss, ", #%d", imm * sizeof(MemElemType));
13814028Sgiacomo.gabrielli@arm.com        }
13914028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "]");
14014028Sgiacomo.gabrielli@arm.com        return ss.str();
14114028Sgiacomo.gabrielli@arm.com    }
14214028Sgiacomo.gabrielli@arm.com};
14314028Sgiacomo.gabrielli@arm.com
14414028Sgiacomo.gabrielli@arm.comtemplate <typename RegElemType, typename MemElemType,
14514091Sgabor.dozsa@arm.com          template <typename, typename> class MicroopType,
14614091Sgabor.dozsa@arm.com          template <typename> class FirstFaultWritebackMicroopType>
14714028Sgiacomo.gabrielli@arm.comclass SveIndexedMemSV : public PredMacroOp
14814028Sgiacomo.gabrielli@arm.com{
14914028Sgiacomo.gabrielli@arm.com  protected:
15014028Sgiacomo.gabrielli@arm.com    IntRegIndex dest;
15114028Sgiacomo.gabrielli@arm.com    IntRegIndex gp;
15214028Sgiacomo.gabrielli@arm.com    IntRegIndex base;
15314028Sgiacomo.gabrielli@arm.com    IntRegIndex offset;
15414028Sgiacomo.gabrielli@arm.com
15514028Sgiacomo.gabrielli@arm.com    bool offsetIs32;
15614028Sgiacomo.gabrielli@arm.com    bool offsetIsSigned;
15714028Sgiacomo.gabrielli@arm.com    bool offsetIsScaled;
15814028Sgiacomo.gabrielli@arm.com
15914028Sgiacomo.gabrielli@arm.com  public:
16014028Sgiacomo.gabrielli@arm.com    SveIndexedMemSV(const char *mnem, ExtMachInst machInst, OpClass __opClass,
16114028Sgiacomo.gabrielli@arm.com                    IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
16214028Sgiacomo.gabrielli@arm.com                    IntRegIndex _offset, bool _offsetIs32,
16314091Sgabor.dozsa@arm.com                    bool _offsetIsSigned, bool _offsetIsScaled,
16414091Sgabor.dozsa@arm.com                    bool firstFault)
16514028Sgiacomo.gabrielli@arm.com        : PredMacroOp(mnem, machInst, __opClass),
16614028Sgiacomo.gabrielli@arm.com          dest(_dest), gp(_gp), base(_base), offset(_offset),
16714028Sgiacomo.gabrielli@arm.com          offsetIs32(_offsetIs32), offsetIsSigned(_offsetIsSigned),
16814028Sgiacomo.gabrielli@arm.com          offsetIsScaled(_offsetIsScaled)
16914028Sgiacomo.gabrielli@arm.com    {
17014028Sgiacomo.gabrielli@arm.com        bool isLoad = (__opClass == MemReadOp);
17114091Sgabor.dozsa@arm.com        assert(!firstFault || isLoad);
17214028Sgiacomo.gabrielli@arm.com
17314028Sgiacomo.gabrielli@arm.com        int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType);
17414028Sgiacomo.gabrielli@arm.com
17514028Sgiacomo.gabrielli@arm.com        numMicroops = num_elems;
17614028Sgiacomo.gabrielli@arm.com        if (isLoad) {
17714091Sgabor.dozsa@arm.com            if (firstFault) {
17814091Sgabor.dozsa@arm.com                numMicroops += 2;
17914091Sgabor.dozsa@arm.com            } else {
18014091Sgabor.dozsa@arm.com                numMicroops++;
18114091Sgabor.dozsa@arm.com            }
18214028Sgiacomo.gabrielli@arm.com        }
18314028Sgiacomo.gabrielli@arm.com
18414028Sgiacomo.gabrielli@arm.com        microOps = new StaticInstPtr[numMicroops];
18514028Sgiacomo.gabrielli@arm.com
18614028Sgiacomo.gabrielli@arm.com        StaticInstPtr *uop = microOps;
18714028Sgiacomo.gabrielli@arm.com
18814028Sgiacomo.gabrielli@arm.com        if (isLoad) {
18914028Sgiacomo.gabrielli@arm.com            // The first microop of a gather load copies the source vector
19014028Sgiacomo.gabrielli@arm.com            // register used for address calculation to an auxiliary register,
19114028Sgiacomo.gabrielli@arm.com            // with all subsequent microops reading from the latter.  This is
19214028Sgiacomo.gabrielli@arm.com            // needed to properly handle cases where the source vector
19314028Sgiacomo.gabrielli@arm.com            // register is the same as the destination register
19414028Sgiacomo.gabrielli@arm.com            *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop(
19514028Sgiacomo.gabrielli@arm.com                mnem, machInst, _offset, this);
19614028Sgiacomo.gabrielli@arm.com            uop++;
19714028Sgiacomo.gabrielli@arm.com        }
19814028Sgiacomo.gabrielli@arm.com
19914028Sgiacomo.gabrielli@arm.com        for (int i = 0; i < num_elems; i++, uop++) {
20014028Sgiacomo.gabrielli@arm.com            *uop = new MicroopType<RegElemType, MemElemType>(
20114028Sgiacomo.gabrielli@arm.com                mnem, machInst, __opClass, _dest, _gp, _base,
20214028Sgiacomo.gabrielli@arm.com                isLoad ? (IntRegIndex) VECREG_UREG0 : _offset, _offsetIs32,
20314091Sgabor.dozsa@arm.com                _offsetIsSigned, _offsetIsScaled, i, num_elems, firstFault);
20414028Sgiacomo.gabrielli@arm.com        }
20514028Sgiacomo.gabrielli@arm.com
20614091Sgabor.dozsa@arm.com        if (firstFault) {
20714091Sgabor.dozsa@arm.com            *uop = new FirstFaultWritebackMicroopType<RegElemType>(
20814091Sgabor.dozsa@arm.com                mnem, machInst, __opClass, num_elems, this);
20914091Sgabor.dozsa@arm.com        } else {
21014091Sgabor.dozsa@arm.com            --uop;
21114091Sgabor.dozsa@arm.com        }
21214091Sgabor.dozsa@arm.com
21314028Sgiacomo.gabrielli@arm.com        (*uop)->setLastMicroop();
21414028Sgiacomo.gabrielli@arm.com        microOps[0]->setFirstMicroop();
21514028Sgiacomo.gabrielli@arm.com
21614028Sgiacomo.gabrielli@arm.com        for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
21714028Sgiacomo.gabrielli@arm.com            (*uop)->setDelayedCommit();
21814028Sgiacomo.gabrielli@arm.com        }
21914028Sgiacomo.gabrielli@arm.com    }
22014028Sgiacomo.gabrielli@arm.com
22114028Sgiacomo.gabrielli@arm.com    Fault
22214028Sgiacomo.gabrielli@arm.com    execute(ExecContext *, Trace::InstRecord *) const
22314028Sgiacomo.gabrielli@arm.com    {
22414028Sgiacomo.gabrielli@arm.com        panic("Execute method called when it shouldn't!");
22514028Sgiacomo.gabrielli@arm.com        return NoFault;
22614028Sgiacomo.gabrielli@arm.com    }
22714028Sgiacomo.gabrielli@arm.com
22814028Sgiacomo.gabrielli@arm.com    std::string
22914028Sgiacomo.gabrielli@arm.com    generateDisassembly(Addr pc, const SymbolTable *symtab) const
23014028Sgiacomo.gabrielli@arm.com    {
23114028Sgiacomo.gabrielli@arm.com        // TODO: add suffix to transfer and base registers
23214028Sgiacomo.gabrielli@arm.com        std::stringstream ss;
23314028Sgiacomo.gabrielli@arm.com        printMnemonic(ss, "", false);
23414028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "{");
23514028Sgiacomo.gabrielli@arm.com        printVecReg(ss, dest, true);
23614028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "}, ");
23714028Sgiacomo.gabrielli@arm.com        printVecPredReg(ss, gp);
23814028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "/z, [");
23914028Sgiacomo.gabrielli@arm.com        printIntReg(ss, base);
24014028Sgiacomo.gabrielli@arm.com        ccprintf(ss, ", ");
24114028Sgiacomo.gabrielli@arm.com        printVecReg(ss, offset, true);
24214028Sgiacomo.gabrielli@arm.com        ccprintf(ss, "]");
24314028Sgiacomo.gabrielli@arm.com        return ss.str();
24414028Sgiacomo.gabrielli@arm.com    }
24514028Sgiacomo.gabrielli@arm.com};
24614028Sgiacomo.gabrielli@arm.com
24714028Sgiacomo.gabrielli@arm.com}  // namespace ArmISA
24814028Sgiacomo.gabrielli@arm.com
24914028Sgiacomo.gabrielli@arm.com#endif  // __ARCH_ARM_SVE_MACROMEM_HH__
250