sve_macromem.hh revision 14091:090449e74135
1/* 2 * Copyright (c) 2018 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Giacomo Gabrielli 38 */ 39 40#ifndef __ARCH_ARM_SVE_MACROMEM_HH__ 41#define __ARCH_ARM_SVE_MACROMEM_HH__ 42 43#include "arch/arm/generated/decoder.hh" 44#include "arch/arm/insts/pred_inst.hh" 45 46namespace ArmISA { 47 48template <typename RegElemType, typename MemElemType, 49 template <typename, typename> class MicroopType, 50 template <typename> class FirstFaultWritebackMicroopType> 51class SveIndexedMemVI : public PredMacroOp 52{ 53 protected: 54 IntRegIndex dest; 55 IntRegIndex gp; 56 IntRegIndex base; 57 uint64_t imm; 58 59 public: 60 SveIndexedMemVI(const char *mnem, ExtMachInst machInst, OpClass __opClass, 61 IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, 62 uint64_t _imm, bool firstFault) 63 : PredMacroOp(mnem, machInst, __opClass), 64 dest(_dest), gp(_gp), base(_base), imm(_imm) 65 { 66 bool isLoad = (__opClass == MemReadOp); 67 assert(!firstFault || isLoad); 68 69 int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType); 70 71 numMicroops = num_elems; 72 if (isLoad) { 73 if (firstFault) { 74 numMicroops += 2; 75 } else { 76 numMicroops++; 77 } 78 } 79 80 microOps = new StaticInstPtr[numMicroops]; 81 82 StaticInstPtr *uop = microOps; 83 84 if (isLoad) { 85 // The first microop of a gather load copies the source vector 86 // register used for address calculation to an auxiliary register, 87 // with all subsequent microops reading from the latter. This is 88 // needed to properly handle cases where the source vector 89 // register is the same as the destination register 90 *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop( 91 mnem, machInst, _base, this); 92 uop++; 93 } 94 95 for (int i = 0; i < num_elems; i++, uop++) { 96 *uop = new MicroopType<RegElemType, MemElemType>( 97 mnem, machInst, __opClass, _dest, _gp, 98 isLoad ? (IntRegIndex) VECREG_UREG0 : _base, _imm, i, 99 num_elems, firstFault); 100 } 101 102 if (firstFault) { 103 *uop = new FirstFaultWritebackMicroopType<RegElemType>( 104 mnem, machInst, __opClass, num_elems, this); 105 } else { 106 --uop; 107 } 108 109 (*uop)->setLastMicroop(); 110 microOps[0]->setFirstMicroop(); 111 112 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 113 (*uop)->setDelayedCommit(); 114 } 115 } 116 117 Fault 118 execute(ExecContext *, Trace::InstRecord *) const 119 { 120 panic("Execute method called when it shouldn't!"); 121 return NoFault; 122 } 123 124 std::string 125 generateDisassembly(Addr pc, const SymbolTable *symtab) const 126 { 127 // TODO: add suffix to transfer and base registers 128 std::stringstream ss; 129 printMnemonic(ss, "", false); 130 ccprintf(ss, "{"); 131 printVecReg(ss, dest, true); 132 ccprintf(ss, "}, "); 133 printVecPredReg(ss, gp); 134 ccprintf(ss, "/z, ["); 135 printVecReg(ss, base, true); 136 if (imm != 0) { 137 ccprintf(ss, ", #%d", imm * sizeof(MemElemType)); 138 } 139 ccprintf(ss, "]"); 140 return ss.str(); 141 } 142}; 143 144template <typename RegElemType, typename MemElemType, 145 template <typename, typename> class MicroopType, 146 template <typename> class FirstFaultWritebackMicroopType> 147class SveIndexedMemSV : public PredMacroOp 148{ 149 protected: 150 IntRegIndex dest; 151 IntRegIndex gp; 152 IntRegIndex base; 153 IntRegIndex offset; 154 155 bool offsetIs32; 156 bool offsetIsSigned; 157 bool offsetIsScaled; 158 159 public: 160 SveIndexedMemSV(const char *mnem, ExtMachInst machInst, OpClass __opClass, 161 IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, 162 IntRegIndex _offset, bool _offsetIs32, 163 bool _offsetIsSigned, bool _offsetIsScaled, 164 bool firstFault) 165 : PredMacroOp(mnem, machInst, __opClass), 166 dest(_dest), gp(_gp), base(_base), offset(_offset), 167 offsetIs32(_offsetIs32), offsetIsSigned(_offsetIsSigned), 168 offsetIsScaled(_offsetIsScaled) 169 { 170 bool isLoad = (__opClass == MemReadOp); 171 assert(!firstFault || isLoad); 172 173 int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType); 174 175 numMicroops = num_elems; 176 if (isLoad) { 177 if (firstFault) { 178 numMicroops += 2; 179 } else { 180 numMicroops++; 181 } 182 } 183 184 microOps = new StaticInstPtr[numMicroops]; 185 186 StaticInstPtr *uop = microOps; 187 188 if (isLoad) { 189 // The first microop of a gather load copies the source vector 190 // register used for address calculation to an auxiliary register, 191 // with all subsequent microops reading from the latter. This is 192 // needed to properly handle cases where the source vector 193 // register is the same as the destination register 194 *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop( 195 mnem, machInst, _offset, this); 196 uop++; 197 } 198 199 for (int i = 0; i < num_elems; i++, uop++) { 200 *uop = new MicroopType<RegElemType, MemElemType>( 201 mnem, machInst, __opClass, _dest, _gp, _base, 202 isLoad ? (IntRegIndex) VECREG_UREG0 : _offset, _offsetIs32, 203 _offsetIsSigned, _offsetIsScaled, i, num_elems, firstFault); 204 } 205 206 if (firstFault) { 207 *uop = new FirstFaultWritebackMicroopType<RegElemType>( 208 mnem, machInst, __opClass, num_elems, this); 209 } else { 210 --uop; 211 } 212 213 (*uop)->setLastMicroop(); 214 microOps[0]->setFirstMicroop(); 215 216 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) { 217 (*uop)->setDelayedCommit(); 218 } 219 } 220 221 Fault 222 execute(ExecContext *, Trace::InstRecord *) const 223 { 224 panic("Execute method called when it shouldn't!"); 225 return NoFault; 226 } 227 228 std::string 229 generateDisassembly(Addr pc, const SymbolTable *symtab) const 230 { 231 // TODO: add suffix to transfer and base registers 232 std::stringstream ss; 233 printMnemonic(ss, "", false); 234 ccprintf(ss, "{"); 235 printVecReg(ss, dest, true); 236 ccprintf(ss, "}, "); 237 printVecPredReg(ss, gp); 238 ccprintf(ss, "/z, ["); 239 printIntReg(ss, base); 240 ccprintf(ss, ", "); 241 printVecReg(ss, offset, true); 242 ccprintf(ss, "]"); 243 return ss.str(); 244 } 245}; 246 247} // namespace ArmISA 248 249#endif // __ARCH_ARM_SVE_MACROMEM_HH__ 250