sve_macromem.hh revision 14106
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 4814106Sjavier.setoain@arm.comtemplate <typename Element, 4914106Sjavier.setoain@arm.com template <typename> class MicroopLdMemType, 5014106Sjavier.setoain@arm.com template <typename> class MicroopDeIntrlvType> 5114106Sjavier.setoain@arm.comclass SveLdStructSS : public PredMacroOp 5214106Sjavier.setoain@arm.com{ 5314106Sjavier.setoain@arm.com protected: 5414106Sjavier.setoain@arm.com IntRegIndex dest; 5514106Sjavier.setoain@arm.com IntRegIndex gp; 5614106Sjavier.setoain@arm.com IntRegIndex base; 5714106Sjavier.setoain@arm.com IntRegIndex offset; 5814106Sjavier.setoain@arm.com uint8_t numregs; 5914106Sjavier.setoain@arm.com 6014106Sjavier.setoain@arm.com public: 6114106Sjavier.setoain@arm.com SveLdStructSS(const char* mnem, ExtMachInst machInst, OpClass __opClass, 6214106Sjavier.setoain@arm.com IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, 6314106Sjavier.setoain@arm.com IntRegIndex _offset, uint8_t _numregs) 6414106Sjavier.setoain@arm.com : PredMacroOp(mnem, machInst, __opClass), 6514106Sjavier.setoain@arm.com dest(_dest), gp(_gp), base(_base), offset(_offset), numregs(_numregs) 6614106Sjavier.setoain@arm.com { 6714106Sjavier.setoain@arm.com numMicroops = numregs * 2; 6814106Sjavier.setoain@arm.com 6914106Sjavier.setoain@arm.com microOps = new StaticInstPtr[numMicroops]; 7014106Sjavier.setoain@arm.com 7114106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 7214106Sjavier.setoain@arm.com microOps[i] = new MicroopLdMemType<Element>( 7314106Sjavier.setoain@arm.com mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i), 7414106Sjavier.setoain@arm.com _gp, _base, _offset, _numregs, i); 7514106Sjavier.setoain@arm.com } 7614106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 7714106Sjavier.setoain@arm.com microOps[i + numregs] = new MicroopDeIntrlvType<Element>( 7814106Sjavier.setoain@arm.com mnem, machInst, static_cast<IntRegIndex>((_dest + i) % 32), 7914106Sjavier.setoain@arm.com _numregs, i, this); 8014106Sjavier.setoain@arm.com } 8114106Sjavier.setoain@arm.com 8214106Sjavier.setoain@arm.com microOps[0]->setFirstMicroop(); 8314106Sjavier.setoain@arm.com microOps[numMicroops - 1]->setLastMicroop(); 8414106Sjavier.setoain@arm.com 8514106Sjavier.setoain@arm.com for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 8614106Sjavier.setoain@arm.com (*uop)->setDelayedCommit(); 8714106Sjavier.setoain@arm.com } 8814106Sjavier.setoain@arm.com } 8914106Sjavier.setoain@arm.com 9014106Sjavier.setoain@arm.com Fault 9114106Sjavier.setoain@arm.com execute(ExecContext *, Trace::InstRecord *) const 9214106Sjavier.setoain@arm.com { 9314106Sjavier.setoain@arm.com panic("Execute method called when it shouldn't!"); 9414106Sjavier.setoain@arm.com return NoFault; 9514106Sjavier.setoain@arm.com } 9614106Sjavier.setoain@arm.com 9714106Sjavier.setoain@arm.com std::string 9814106Sjavier.setoain@arm.com generateDisassembly(Addr pc, const SymbolTable *symtab) const 9914106Sjavier.setoain@arm.com { 10014106Sjavier.setoain@arm.com std::stringstream ss; 10114106Sjavier.setoain@arm.com printMnemonic(ss, "", false); 10214106Sjavier.setoain@arm.com ccprintf(ss, "{"); 10314106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 10414106Sjavier.setoain@arm.com printVecReg(ss, (dest + i) % 32, true); 10514106Sjavier.setoain@arm.com if (i < numregs - 1) 10614106Sjavier.setoain@arm.com ccprintf(ss, ", "); 10714106Sjavier.setoain@arm.com } 10814106Sjavier.setoain@arm.com ccprintf(ss, "}, "); 10914106Sjavier.setoain@arm.com printVecPredReg(ss, gp); 11014106Sjavier.setoain@arm.com ccprintf(ss, "/z, ["); 11114106Sjavier.setoain@arm.com printIntReg(ss, base); 11214106Sjavier.setoain@arm.com ccprintf(ss, ", "); 11314106Sjavier.setoain@arm.com printIntReg(ss, offset); 11414106Sjavier.setoain@arm.com ccprintf(ss, "]"); 11514106Sjavier.setoain@arm.com return ss.str(); 11614106Sjavier.setoain@arm.com } 11714106Sjavier.setoain@arm.com}; 11814106Sjavier.setoain@arm.com 11914106Sjavier.setoain@arm.comtemplate <typename Element, 12014106Sjavier.setoain@arm.com template <typename> class MicroopStMemType, 12114106Sjavier.setoain@arm.com template <typename> class MicroopIntrlvType> 12214106Sjavier.setoain@arm.comclass SveStStructSS : public PredMacroOp 12314106Sjavier.setoain@arm.com{ 12414106Sjavier.setoain@arm.com protected: 12514106Sjavier.setoain@arm.com IntRegIndex dest; 12614106Sjavier.setoain@arm.com IntRegIndex gp; 12714106Sjavier.setoain@arm.com IntRegIndex base; 12814106Sjavier.setoain@arm.com IntRegIndex offset; 12914106Sjavier.setoain@arm.com uint8_t numregs; 13014106Sjavier.setoain@arm.com 13114106Sjavier.setoain@arm.com public: 13214106Sjavier.setoain@arm.com SveStStructSS(const char* mnem, ExtMachInst machInst, OpClass __opClass, 13314106Sjavier.setoain@arm.com IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, 13414106Sjavier.setoain@arm.com IntRegIndex _offset, uint8_t _numregs) 13514106Sjavier.setoain@arm.com : PredMacroOp(mnem, machInst, __opClass), 13614106Sjavier.setoain@arm.com dest(_dest), gp(_gp), base(_base), offset(_offset), numregs(_numregs) 13714106Sjavier.setoain@arm.com { 13814106Sjavier.setoain@arm.com numMicroops = numregs * 2; 13914106Sjavier.setoain@arm.com 14014106Sjavier.setoain@arm.com microOps = new StaticInstPtr[numMicroops]; 14114106Sjavier.setoain@arm.com 14214106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 14314106Sjavier.setoain@arm.com microOps[i] = new MicroopIntrlvType<Element>( 14414106Sjavier.setoain@arm.com mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i), 14514106Sjavier.setoain@arm.com _dest, _numregs, i, this); 14614106Sjavier.setoain@arm.com } 14714106Sjavier.setoain@arm.com 14814106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 14914106Sjavier.setoain@arm.com microOps[i + numregs] = new MicroopStMemType<Element>( 15014106Sjavier.setoain@arm.com mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i), 15114106Sjavier.setoain@arm.com _gp, _base, _offset, _numregs, i); 15214106Sjavier.setoain@arm.com } 15314106Sjavier.setoain@arm.com 15414106Sjavier.setoain@arm.com microOps[0]->setFirstMicroop(); 15514106Sjavier.setoain@arm.com microOps[numMicroops - 1]->setLastMicroop(); 15614106Sjavier.setoain@arm.com 15714106Sjavier.setoain@arm.com for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 15814106Sjavier.setoain@arm.com (*uop)->setDelayedCommit(); 15914106Sjavier.setoain@arm.com } 16014106Sjavier.setoain@arm.com } 16114106Sjavier.setoain@arm.com 16214106Sjavier.setoain@arm.com Fault 16314106Sjavier.setoain@arm.com execute(ExecContext *, Trace::InstRecord *) const 16414106Sjavier.setoain@arm.com { 16514106Sjavier.setoain@arm.com panic("Execute method called when it shouldn't!"); 16614106Sjavier.setoain@arm.com return NoFault; 16714106Sjavier.setoain@arm.com } 16814106Sjavier.setoain@arm.com 16914106Sjavier.setoain@arm.com std::string 17014106Sjavier.setoain@arm.com generateDisassembly(Addr pc, const SymbolTable *symtab) const 17114106Sjavier.setoain@arm.com { 17214106Sjavier.setoain@arm.com std::stringstream ss; 17314106Sjavier.setoain@arm.com printMnemonic(ss, "", false); 17414106Sjavier.setoain@arm.com ccprintf(ss, "{"); 17514106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 17614106Sjavier.setoain@arm.com printVecReg(ss, (dest + i) % 32, true); 17714106Sjavier.setoain@arm.com if (i < numregs - 1) 17814106Sjavier.setoain@arm.com ccprintf(ss, ", "); 17914106Sjavier.setoain@arm.com } 18014106Sjavier.setoain@arm.com ccprintf(ss, "}, "); 18114106Sjavier.setoain@arm.com printVecPredReg(ss, gp); 18214106Sjavier.setoain@arm.com ccprintf(ss, ", ["); 18314106Sjavier.setoain@arm.com printIntReg(ss, base); 18414106Sjavier.setoain@arm.com ccprintf(ss, ", "); 18514106Sjavier.setoain@arm.com printIntReg(ss, offset); 18614106Sjavier.setoain@arm.com ccprintf(ss, "]"); 18714106Sjavier.setoain@arm.com return ss.str(); 18814106Sjavier.setoain@arm.com } 18914106Sjavier.setoain@arm.com}; 19014106Sjavier.setoain@arm.com 19114106Sjavier.setoain@arm.com 19214106Sjavier.setoain@arm.comtemplate <typename Element, 19314106Sjavier.setoain@arm.com template <typename> class MicroopLdMemType, 19414106Sjavier.setoain@arm.com template <typename> class MicroopDeIntrlvType> 19514106Sjavier.setoain@arm.comclass SveLdStructSI : public PredMacroOp 19614106Sjavier.setoain@arm.com{ 19714106Sjavier.setoain@arm.com protected: 19814106Sjavier.setoain@arm.com IntRegIndex dest; 19914106Sjavier.setoain@arm.com IntRegIndex gp; 20014106Sjavier.setoain@arm.com IntRegIndex base; 20114106Sjavier.setoain@arm.com int64_t imm; 20214106Sjavier.setoain@arm.com uint8_t numregs; 20314106Sjavier.setoain@arm.com 20414106Sjavier.setoain@arm.com public: 20514106Sjavier.setoain@arm.com SveLdStructSI(const char* mnem, ExtMachInst machInst, OpClass __opClass, 20614106Sjavier.setoain@arm.com IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, 20714106Sjavier.setoain@arm.com int64_t _imm, uint8_t _numregs) 20814106Sjavier.setoain@arm.com : PredMacroOp(mnem, machInst, __opClass), 20914106Sjavier.setoain@arm.com dest(_dest), gp(_gp), base(_base), imm(_imm), numregs(_numregs) 21014106Sjavier.setoain@arm.com { 21114106Sjavier.setoain@arm.com numMicroops = numregs * 2; 21214106Sjavier.setoain@arm.com 21314106Sjavier.setoain@arm.com microOps = new StaticInstPtr[numMicroops]; 21414106Sjavier.setoain@arm.com 21514106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 21614106Sjavier.setoain@arm.com microOps[i] = new MicroopLdMemType<Element>( 21714106Sjavier.setoain@arm.com mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i), 21814106Sjavier.setoain@arm.com _gp, _base, _imm, _numregs, i); 21914106Sjavier.setoain@arm.com } 22014106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 22114106Sjavier.setoain@arm.com microOps[i + numregs] = new MicroopDeIntrlvType<Element>( 22214106Sjavier.setoain@arm.com mnem, machInst, static_cast<IntRegIndex>((_dest + i) % 32), 22314106Sjavier.setoain@arm.com _numregs, i, this); 22414106Sjavier.setoain@arm.com } 22514106Sjavier.setoain@arm.com 22614106Sjavier.setoain@arm.com microOps[0]->setFirstMicroop(); 22714106Sjavier.setoain@arm.com microOps[numMicroops - 1]->setLastMicroop(); 22814106Sjavier.setoain@arm.com 22914106Sjavier.setoain@arm.com for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 23014106Sjavier.setoain@arm.com (*uop)->setDelayedCommit(); 23114106Sjavier.setoain@arm.com } 23214106Sjavier.setoain@arm.com } 23314106Sjavier.setoain@arm.com 23414106Sjavier.setoain@arm.com Fault 23514106Sjavier.setoain@arm.com execute(ExecContext *, Trace::InstRecord *) const 23614106Sjavier.setoain@arm.com { 23714106Sjavier.setoain@arm.com panic("Execute method called when it shouldn't!"); 23814106Sjavier.setoain@arm.com return NoFault; 23914106Sjavier.setoain@arm.com } 24014106Sjavier.setoain@arm.com 24114106Sjavier.setoain@arm.com std::string 24214106Sjavier.setoain@arm.com generateDisassembly(Addr pc, const SymbolTable *symtab) const 24314106Sjavier.setoain@arm.com { 24414106Sjavier.setoain@arm.com std::stringstream ss; 24514106Sjavier.setoain@arm.com printMnemonic(ss, "", false); 24614106Sjavier.setoain@arm.com ccprintf(ss, "{"); 24714106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 24814106Sjavier.setoain@arm.com printVecReg(ss, (dest + i) % 32, true); 24914106Sjavier.setoain@arm.com if (i < numregs - 1) 25014106Sjavier.setoain@arm.com ccprintf(ss, ", "); 25114106Sjavier.setoain@arm.com } 25214106Sjavier.setoain@arm.com ccprintf(ss, "}, "); 25314106Sjavier.setoain@arm.com printVecPredReg(ss, gp); 25414106Sjavier.setoain@arm.com ccprintf(ss, "/z, ["); 25514106Sjavier.setoain@arm.com printIntReg(ss, base); 25614106Sjavier.setoain@arm.com if (imm != 0) { 25714106Sjavier.setoain@arm.com ccprintf(ss, ", #%d, MUL VL", imm); 25814106Sjavier.setoain@arm.com } 25914106Sjavier.setoain@arm.com ccprintf(ss, "]"); 26014106Sjavier.setoain@arm.com return ss.str(); 26114106Sjavier.setoain@arm.com } 26214106Sjavier.setoain@arm.com}; 26314106Sjavier.setoain@arm.com 26414106Sjavier.setoain@arm.comtemplate <typename Element, 26514106Sjavier.setoain@arm.com template <typename> class MicroopStMemType, 26614106Sjavier.setoain@arm.com template <typename> class MicroopIntrlvType> 26714106Sjavier.setoain@arm.comclass SveStStructSI : public PredMacroOp 26814106Sjavier.setoain@arm.com{ 26914106Sjavier.setoain@arm.com protected: 27014106Sjavier.setoain@arm.com IntRegIndex dest; 27114106Sjavier.setoain@arm.com IntRegIndex gp; 27214106Sjavier.setoain@arm.com IntRegIndex base; 27314106Sjavier.setoain@arm.com int64_t imm; 27414106Sjavier.setoain@arm.com uint8_t numregs; 27514106Sjavier.setoain@arm.com 27614106Sjavier.setoain@arm.com public: 27714106Sjavier.setoain@arm.com SveStStructSI(const char* mnem, ExtMachInst machInst, OpClass __opClass, 27814106Sjavier.setoain@arm.com IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, 27914106Sjavier.setoain@arm.com int64_t _imm, uint8_t _numregs) 28014106Sjavier.setoain@arm.com : PredMacroOp(mnem, machInst, __opClass), 28114106Sjavier.setoain@arm.com dest(_dest), gp(_gp), base(_base), imm(_imm), numregs(_numregs) 28214106Sjavier.setoain@arm.com { 28314106Sjavier.setoain@arm.com numMicroops = numregs * 2; 28414106Sjavier.setoain@arm.com 28514106Sjavier.setoain@arm.com microOps = new StaticInstPtr[numMicroops]; 28614106Sjavier.setoain@arm.com 28714106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 28814106Sjavier.setoain@arm.com microOps[i] = new MicroopIntrlvType<Element>( 28914106Sjavier.setoain@arm.com mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i), 29014106Sjavier.setoain@arm.com _dest, _numregs, i, this); 29114106Sjavier.setoain@arm.com } 29214106Sjavier.setoain@arm.com 29314106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 29414106Sjavier.setoain@arm.com microOps[i + numregs] = new MicroopStMemType<Element>( 29514106Sjavier.setoain@arm.com mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i), 29614106Sjavier.setoain@arm.com _gp, _base, _imm, _numregs, i); 29714106Sjavier.setoain@arm.com } 29814106Sjavier.setoain@arm.com 29914106Sjavier.setoain@arm.com microOps[0]->setFirstMicroop(); 30014106Sjavier.setoain@arm.com microOps[numMicroops - 1]->setLastMicroop(); 30114106Sjavier.setoain@arm.com 30214106Sjavier.setoain@arm.com for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 30314106Sjavier.setoain@arm.com (*uop)->setDelayedCommit(); 30414106Sjavier.setoain@arm.com } 30514106Sjavier.setoain@arm.com } 30614106Sjavier.setoain@arm.com 30714106Sjavier.setoain@arm.com Fault 30814106Sjavier.setoain@arm.com execute(ExecContext *, Trace::InstRecord *) const 30914106Sjavier.setoain@arm.com { 31014106Sjavier.setoain@arm.com panic("Execute method called when it shouldn't!"); 31114106Sjavier.setoain@arm.com return NoFault; 31214106Sjavier.setoain@arm.com } 31314106Sjavier.setoain@arm.com 31414106Sjavier.setoain@arm.com std::string 31514106Sjavier.setoain@arm.com generateDisassembly(Addr pc, const SymbolTable *symtab) const 31614106Sjavier.setoain@arm.com { 31714106Sjavier.setoain@arm.com std::stringstream ss; 31814106Sjavier.setoain@arm.com printMnemonic(ss, "", false); 31914106Sjavier.setoain@arm.com ccprintf(ss, "{"); 32014106Sjavier.setoain@arm.com for (int i = 0; i < numregs; ++i) { 32114106Sjavier.setoain@arm.com printVecReg(ss, (dest + i) % 32, true); 32214106Sjavier.setoain@arm.com if (i < numregs - 1) 32314106Sjavier.setoain@arm.com ccprintf(ss, ", "); 32414106Sjavier.setoain@arm.com } 32514106Sjavier.setoain@arm.com ccprintf(ss, "}, "); 32614106Sjavier.setoain@arm.com printVecPredReg(ss, gp); 32714106Sjavier.setoain@arm.com ccprintf(ss, ", ["); 32814106Sjavier.setoain@arm.com printIntReg(ss, base); 32914106Sjavier.setoain@arm.com if (imm != 0) { 33014106Sjavier.setoain@arm.com ccprintf(ss, ", #%d, MUL VL", imm); 33114106Sjavier.setoain@arm.com } 33214106Sjavier.setoain@arm.com ccprintf(ss, "]"); 33314106Sjavier.setoain@arm.com return ss.str(); 33414106Sjavier.setoain@arm.com } 33514106Sjavier.setoain@arm.com}; 33614106Sjavier.setoain@arm.com 33714028Sgiacomo.gabrielli@arm.comtemplate <typename RegElemType, typename MemElemType, 33814091Sgabor.dozsa@arm.com template <typename, typename> class MicroopType, 33914091Sgabor.dozsa@arm.com template <typename> class FirstFaultWritebackMicroopType> 34014028Sgiacomo.gabrielli@arm.comclass SveIndexedMemVI : public PredMacroOp 34114028Sgiacomo.gabrielli@arm.com{ 34214028Sgiacomo.gabrielli@arm.com protected: 34314028Sgiacomo.gabrielli@arm.com IntRegIndex dest; 34414028Sgiacomo.gabrielli@arm.com IntRegIndex gp; 34514028Sgiacomo.gabrielli@arm.com IntRegIndex base; 34614028Sgiacomo.gabrielli@arm.com uint64_t imm; 34714028Sgiacomo.gabrielli@arm.com 34814028Sgiacomo.gabrielli@arm.com public: 34914028Sgiacomo.gabrielli@arm.com SveIndexedMemVI(const char *mnem, ExtMachInst machInst, OpClass __opClass, 35014028Sgiacomo.gabrielli@arm.com IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, 35114091Sgabor.dozsa@arm.com uint64_t _imm, bool firstFault) 35214028Sgiacomo.gabrielli@arm.com : PredMacroOp(mnem, machInst, __opClass), 35314028Sgiacomo.gabrielli@arm.com dest(_dest), gp(_gp), base(_base), imm(_imm) 35414028Sgiacomo.gabrielli@arm.com { 35514028Sgiacomo.gabrielli@arm.com bool isLoad = (__opClass == MemReadOp); 35614091Sgabor.dozsa@arm.com assert(!firstFault || isLoad); 35714028Sgiacomo.gabrielli@arm.com 35814028Sgiacomo.gabrielli@arm.com int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType); 35914028Sgiacomo.gabrielli@arm.com 36014028Sgiacomo.gabrielli@arm.com numMicroops = num_elems; 36114028Sgiacomo.gabrielli@arm.com if (isLoad) { 36214091Sgabor.dozsa@arm.com if (firstFault) { 36314091Sgabor.dozsa@arm.com numMicroops += 2; 36414091Sgabor.dozsa@arm.com } else { 36514091Sgabor.dozsa@arm.com numMicroops++; 36614091Sgabor.dozsa@arm.com } 36714028Sgiacomo.gabrielli@arm.com } 36814028Sgiacomo.gabrielli@arm.com 36914028Sgiacomo.gabrielli@arm.com microOps = new StaticInstPtr[numMicroops]; 37014028Sgiacomo.gabrielli@arm.com 37114028Sgiacomo.gabrielli@arm.com StaticInstPtr *uop = microOps; 37214028Sgiacomo.gabrielli@arm.com 37314028Sgiacomo.gabrielli@arm.com if (isLoad) { 37414028Sgiacomo.gabrielli@arm.com // The first microop of a gather load copies the source vector 37514028Sgiacomo.gabrielli@arm.com // register used for address calculation to an auxiliary register, 37614028Sgiacomo.gabrielli@arm.com // with all subsequent microops reading from the latter. This is 37714028Sgiacomo.gabrielli@arm.com // needed to properly handle cases where the source vector 37814028Sgiacomo.gabrielli@arm.com // register is the same as the destination register 37914028Sgiacomo.gabrielli@arm.com *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop( 38014028Sgiacomo.gabrielli@arm.com mnem, machInst, _base, this); 38114028Sgiacomo.gabrielli@arm.com uop++; 38214028Sgiacomo.gabrielli@arm.com } 38314028Sgiacomo.gabrielli@arm.com 38414028Sgiacomo.gabrielli@arm.com for (int i = 0; i < num_elems; i++, uop++) { 38514028Sgiacomo.gabrielli@arm.com *uop = new MicroopType<RegElemType, MemElemType>( 38614028Sgiacomo.gabrielli@arm.com mnem, machInst, __opClass, _dest, _gp, 38714028Sgiacomo.gabrielli@arm.com isLoad ? (IntRegIndex) VECREG_UREG0 : _base, _imm, i, 38814091Sgabor.dozsa@arm.com num_elems, firstFault); 38914028Sgiacomo.gabrielli@arm.com } 39014028Sgiacomo.gabrielli@arm.com 39114091Sgabor.dozsa@arm.com if (firstFault) { 39214091Sgabor.dozsa@arm.com *uop = new FirstFaultWritebackMicroopType<RegElemType>( 39314091Sgabor.dozsa@arm.com mnem, machInst, __opClass, num_elems, this); 39414091Sgabor.dozsa@arm.com } else { 39514091Sgabor.dozsa@arm.com --uop; 39614091Sgabor.dozsa@arm.com } 39714091Sgabor.dozsa@arm.com 39814028Sgiacomo.gabrielli@arm.com (*uop)->setLastMicroop(); 39914028Sgiacomo.gabrielli@arm.com microOps[0]->setFirstMicroop(); 40014028Sgiacomo.gabrielli@arm.com 40114028Sgiacomo.gabrielli@arm.com for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 40214028Sgiacomo.gabrielli@arm.com (*uop)->setDelayedCommit(); 40314028Sgiacomo.gabrielli@arm.com } 40414028Sgiacomo.gabrielli@arm.com } 40514028Sgiacomo.gabrielli@arm.com 40614028Sgiacomo.gabrielli@arm.com Fault 40714028Sgiacomo.gabrielli@arm.com execute(ExecContext *, Trace::InstRecord *) const 40814028Sgiacomo.gabrielli@arm.com { 40914028Sgiacomo.gabrielli@arm.com panic("Execute method called when it shouldn't!"); 41014028Sgiacomo.gabrielli@arm.com return NoFault; 41114028Sgiacomo.gabrielli@arm.com } 41214028Sgiacomo.gabrielli@arm.com 41314028Sgiacomo.gabrielli@arm.com std::string 41414028Sgiacomo.gabrielli@arm.com generateDisassembly(Addr pc, const SymbolTable *symtab) const 41514028Sgiacomo.gabrielli@arm.com { 41614028Sgiacomo.gabrielli@arm.com // TODO: add suffix to transfer and base registers 41714028Sgiacomo.gabrielli@arm.com std::stringstream ss; 41814028Sgiacomo.gabrielli@arm.com printMnemonic(ss, "", false); 41914028Sgiacomo.gabrielli@arm.com ccprintf(ss, "{"); 42014028Sgiacomo.gabrielli@arm.com printVecReg(ss, dest, true); 42114028Sgiacomo.gabrielli@arm.com ccprintf(ss, "}, "); 42214028Sgiacomo.gabrielli@arm.com printVecPredReg(ss, gp); 42314028Sgiacomo.gabrielli@arm.com ccprintf(ss, "/z, ["); 42414028Sgiacomo.gabrielli@arm.com printVecReg(ss, base, true); 42514028Sgiacomo.gabrielli@arm.com if (imm != 0) { 42614028Sgiacomo.gabrielli@arm.com ccprintf(ss, ", #%d", imm * sizeof(MemElemType)); 42714028Sgiacomo.gabrielli@arm.com } 42814028Sgiacomo.gabrielli@arm.com ccprintf(ss, "]"); 42914028Sgiacomo.gabrielli@arm.com return ss.str(); 43014028Sgiacomo.gabrielli@arm.com } 43114028Sgiacomo.gabrielli@arm.com}; 43214028Sgiacomo.gabrielli@arm.com 43314028Sgiacomo.gabrielli@arm.comtemplate <typename RegElemType, typename MemElemType, 43414091Sgabor.dozsa@arm.com template <typename, typename> class MicroopType, 43514091Sgabor.dozsa@arm.com template <typename> class FirstFaultWritebackMicroopType> 43614028Sgiacomo.gabrielli@arm.comclass SveIndexedMemSV : public PredMacroOp 43714028Sgiacomo.gabrielli@arm.com{ 43814028Sgiacomo.gabrielli@arm.com protected: 43914028Sgiacomo.gabrielli@arm.com IntRegIndex dest; 44014028Sgiacomo.gabrielli@arm.com IntRegIndex gp; 44114028Sgiacomo.gabrielli@arm.com IntRegIndex base; 44214028Sgiacomo.gabrielli@arm.com IntRegIndex offset; 44314028Sgiacomo.gabrielli@arm.com 44414028Sgiacomo.gabrielli@arm.com bool offsetIs32; 44514028Sgiacomo.gabrielli@arm.com bool offsetIsSigned; 44614028Sgiacomo.gabrielli@arm.com bool offsetIsScaled; 44714028Sgiacomo.gabrielli@arm.com 44814028Sgiacomo.gabrielli@arm.com public: 44914028Sgiacomo.gabrielli@arm.com SveIndexedMemSV(const char *mnem, ExtMachInst machInst, OpClass __opClass, 45014028Sgiacomo.gabrielli@arm.com IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, 45114028Sgiacomo.gabrielli@arm.com IntRegIndex _offset, bool _offsetIs32, 45214091Sgabor.dozsa@arm.com bool _offsetIsSigned, bool _offsetIsScaled, 45314091Sgabor.dozsa@arm.com bool firstFault) 45414028Sgiacomo.gabrielli@arm.com : PredMacroOp(mnem, machInst, __opClass), 45514028Sgiacomo.gabrielli@arm.com dest(_dest), gp(_gp), base(_base), offset(_offset), 45614028Sgiacomo.gabrielli@arm.com offsetIs32(_offsetIs32), offsetIsSigned(_offsetIsSigned), 45714028Sgiacomo.gabrielli@arm.com offsetIsScaled(_offsetIsScaled) 45814028Sgiacomo.gabrielli@arm.com { 45914028Sgiacomo.gabrielli@arm.com bool isLoad = (__opClass == MemReadOp); 46014091Sgabor.dozsa@arm.com assert(!firstFault || isLoad); 46114028Sgiacomo.gabrielli@arm.com 46214028Sgiacomo.gabrielli@arm.com int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType); 46314028Sgiacomo.gabrielli@arm.com 46414028Sgiacomo.gabrielli@arm.com numMicroops = num_elems; 46514028Sgiacomo.gabrielli@arm.com if (isLoad) { 46614091Sgabor.dozsa@arm.com if (firstFault) { 46714091Sgabor.dozsa@arm.com numMicroops += 2; 46814091Sgabor.dozsa@arm.com } else { 46914091Sgabor.dozsa@arm.com numMicroops++; 47014091Sgabor.dozsa@arm.com } 47114028Sgiacomo.gabrielli@arm.com } 47214028Sgiacomo.gabrielli@arm.com 47314028Sgiacomo.gabrielli@arm.com microOps = new StaticInstPtr[numMicroops]; 47414028Sgiacomo.gabrielli@arm.com 47514028Sgiacomo.gabrielli@arm.com StaticInstPtr *uop = microOps; 47614028Sgiacomo.gabrielli@arm.com 47714028Sgiacomo.gabrielli@arm.com if (isLoad) { 47814028Sgiacomo.gabrielli@arm.com // The first microop of a gather load copies the source vector 47914028Sgiacomo.gabrielli@arm.com // register used for address calculation to an auxiliary register, 48014028Sgiacomo.gabrielli@arm.com // with all subsequent microops reading from the latter. This is 48114028Sgiacomo.gabrielli@arm.com // needed to properly handle cases where the source vector 48214028Sgiacomo.gabrielli@arm.com // register is the same as the destination register 48314028Sgiacomo.gabrielli@arm.com *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop( 48414028Sgiacomo.gabrielli@arm.com mnem, machInst, _offset, this); 48514028Sgiacomo.gabrielli@arm.com uop++; 48614028Sgiacomo.gabrielli@arm.com } 48714028Sgiacomo.gabrielli@arm.com 48814028Sgiacomo.gabrielli@arm.com for (int i = 0; i < num_elems; i++, uop++) { 48914028Sgiacomo.gabrielli@arm.com *uop = new MicroopType<RegElemType, MemElemType>( 49014028Sgiacomo.gabrielli@arm.com mnem, machInst, __opClass, _dest, _gp, _base, 49114028Sgiacomo.gabrielli@arm.com isLoad ? (IntRegIndex) VECREG_UREG0 : _offset, _offsetIs32, 49214091Sgabor.dozsa@arm.com _offsetIsSigned, _offsetIsScaled, i, num_elems, firstFault); 49314028Sgiacomo.gabrielli@arm.com } 49414028Sgiacomo.gabrielli@arm.com 49514091Sgabor.dozsa@arm.com if (firstFault) { 49614091Sgabor.dozsa@arm.com *uop = new FirstFaultWritebackMicroopType<RegElemType>( 49714091Sgabor.dozsa@arm.com mnem, machInst, __opClass, num_elems, this); 49814091Sgabor.dozsa@arm.com } else { 49914091Sgabor.dozsa@arm.com --uop; 50014091Sgabor.dozsa@arm.com } 50114091Sgabor.dozsa@arm.com 50214028Sgiacomo.gabrielli@arm.com (*uop)->setLastMicroop(); 50314028Sgiacomo.gabrielli@arm.com microOps[0]->setFirstMicroop(); 50414028Sgiacomo.gabrielli@arm.com 50514028Sgiacomo.gabrielli@arm.com for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 50614028Sgiacomo.gabrielli@arm.com (*uop)->setDelayedCommit(); 50714028Sgiacomo.gabrielli@arm.com } 50814028Sgiacomo.gabrielli@arm.com } 50914028Sgiacomo.gabrielli@arm.com 51014028Sgiacomo.gabrielli@arm.com Fault 51114028Sgiacomo.gabrielli@arm.com execute(ExecContext *, Trace::InstRecord *) const 51214028Sgiacomo.gabrielli@arm.com { 51314028Sgiacomo.gabrielli@arm.com panic("Execute method called when it shouldn't!"); 51414028Sgiacomo.gabrielli@arm.com return NoFault; 51514028Sgiacomo.gabrielli@arm.com } 51614028Sgiacomo.gabrielli@arm.com 51714028Sgiacomo.gabrielli@arm.com std::string 51814028Sgiacomo.gabrielli@arm.com generateDisassembly(Addr pc, const SymbolTable *symtab) const 51914028Sgiacomo.gabrielli@arm.com { 52014028Sgiacomo.gabrielli@arm.com // TODO: add suffix to transfer and base registers 52114028Sgiacomo.gabrielli@arm.com std::stringstream ss; 52214028Sgiacomo.gabrielli@arm.com printMnemonic(ss, "", false); 52314028Sgiacomo.gabrielli@arm.com ccprintf(ss, "{"); 52414028Sgiacomo.gabrielli@arm.com printVecReg(ss, dest, true); 52514028Sgiacomo.gabrielli@arm.com ccprintf(ss, "}, "); 52614028Sgiacomo.gabrielli@arm.com printVecPredReg(ss, gp); 52714028Sgiacomo.gabrielli@arm.com ccprintf(ss, "/z, ["); 52814028Sgiacomo.gabrielli@arm.com printIntReg(ss, base); 52914028Sgiacomo.gabrielli@arm.com ccprintf(ss, ", "); 53014028Sgiacomo.gabrielli@arm.com printVecReg(ss, offset, true); 53114028Sgiacomo.gabrielli@arm.com ccprintf(ss, "]"); 53214028Sgiacomo.gabrielli@arm.com return ss.str(); 53314028Sgiacomo.gabrielli@arm.com } 53414028Sgiacomo.gabrielli@arm.com}; 53514028Sgiacomo.gabrielli@arm.com 53614028Sgiacomo.gabrielli@arm.com} // namespace ArmISA 53714028Sgiacomo.gabrielli@arm.com 53814028Sgiacomo.gabrielli@arm.com#endif // __ARCH_ARM_SVE_MACROMEM_HH__ 539