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