gem5  v20.0.0.2
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
sve_macromem.hh
Go to the documentation of this file.
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 
38 #ifndef __ARCH_ARM_SVE_MACROMEM_HH__
39 #define __ARCH_ARM_SVE_MACROMEM_HH__
40 
41 #include "arch/arm/generated/decoder.hh"
43 
44 namespace ArmISA {
45 
46 template <typename Element,
47  template <typename> class MicroopLdMemType,
48  template <typename> class MicroopDeIntrlvType>
49 class SveLdStructSS : public PredMacroOp
50 {
51  protected:
56  uint8_t numregs;
57 
58  public:
59  SveLdStructSS(const char* mnem, ExtMachInst machInst, OpClass __opClass,
60  IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
61  IntRegIndex _offset, uint8_t _numregs)
62  : PredMacroOp(mnem, machInst, __opClass),
63  dest(_dest), gp(_gp), base(_base), offset(_offset), numregs(_numregs)
64  {
65  numMicroops = numregs * 2;
66 
68 
69  for (int i = 0; i < numregs; ++i) {
70  microOps[i] = new MicroopLdMemType<Element>(
71  mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
72  _gp, _base, _offset, _numregs, i);
73  }
74  for (int i = 0; i < numregs; ++i) {
75  microOps[i + numregs] = new MicroopDeIntrlvType<Element>(
76  mnem, machInst, static_cast<IntRegIndex>((_dest + i) % 32),
77  _numregs, i, this);
78  }
79 
82 
83  for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
84  (*uop)->setDelayedCommit();
85  }
86  }
87 
88  Fault
90  {
91  panic("Execute method called when it shouldn't!");
92  return NoFault;
93  }
94 
95  std::string
97  {
98  std::stringstream ss;
99  printMnemonic(ss, "", false);
100  ccprintf(ss, "{");
101  for (int i = 0; i < numregs; ++i) {
102  printVecReg(ss, (dest + i) % 32, true);
103  if (i < numregs - 1)
104  ccprintf(ss, ", ");
105  }
106  ccprintf(ss, "}, ");
107  printVecPredReg(ss, gp);
108  ccprintf(ss, "/z, [");
109  printIntReg(ss, base);
110  ccprintf(ss, ", ");
111  printIntReg(ss, offset);
112  ccprintf(ss, "]");
113  return ss.str();
114  }
115 };
116 
117 template <typename Element,
118  template <typename> class MicroopStMemType,
119  template <typename> class MicroopIntrlvType>
121 {
122  protected:
127  uint8_t numregs;
128 
129  public:
130  SveStStructSS(const char* mnem, ExtMachInst machInst, OpClass __opClass,
131  IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
132  IntRegIndex _offset, uint8_t _numregs)
133  : PredMacroOp(mnem, machInst, __opClass),
134  dest(_dest), gp(_gp), base(_base), offset(_offset), numregs(_numregs)
135  {
136  numMicroops = numregs * 2;
137 
139 
140  for (int i = 0; i < numregs; ++i) {
141  microOps[i] = new MicroopIntrlvType<Element>(
142  mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
143  _dest, _numregs, i, this);
144  }
145 
146  for (int i = 0; i < numregs; ++i) {
147  microOps[i + numregs] = new MicroopStMemType<Element>(
148  mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
149  _gp, _base, _offset, _numregs, i);
150  }
151 
154 
155  for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
156  (*uop)->setDelayedCommit();
157  }
158  }
159 
160  Fault
162  {
163  panic("Execute method called when it shouldn't!");
164  return NoFault;
165  }
166 
167  std::string
169  {
170  std::stringstream ss;
171  printMnemonic(ss, "", false);
172  ccprintf(ss, "{");
173  for (int i = 0; i < numregs; ++i) {
174  printVecReg(ss, (dest + i) % 32, true);
175  if (i < numregs - 1)
176  ccprintf(ss, ", ");
177  }
178  ccprintf(ss, "}, ");
179  printVecPredReg(ss, gp);
180  ccprintf(ss, ", [");
181  printIntReg(ss, base);
182  ccprintf(ss, ", ");
183  printIntReg(ss, offset);
184  ccprintf(ss, "]");
185  return ss.str();
186  }
187 };
188 
189 
190 template <typename Element,
191  template <typename> class MicroopLdMemType,
192  template <typename> class MicroopDeIntrlvType>
194 {
195  protected:
199  int64_t imm;
200  uint8_t numregs;
201 
202  public:
203  SveLdStructSI(const char* mnem, ExtMachInst machInst, OpClass __opClass,
204  IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
205  int64_t _imm, uint8_t _numregs)
206  : PredMacroOp(mnem, machInst, __opClass),
207  dest(_dest), gp(_gp), base(_base), imm(_imm), numregs(_numregs)
208  {
209  numMicroops = numregs * 2;
210 
212 
213  for (int i = 0; i < numregs; ++i) {
214  microOps[i] = new MicroopLdMemType<Element>(
215  mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
216  _gp, _base, _imm, _numregs, i);
217  }
218  for (int i = 0; i < numregs; ++i) {
219  microOps[i + numregs] = new MicroopDeIntrlvType<Element>(
220  mnem, machInst, static_cast<IntRegIndex>((_dest + i) % 32),
221  _numregs, i, this);
222  }
223 
226 
227  for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
228  (*uop)->setDelayedCommit();
229  }
230  }
231 
232  Fault
234  {
235  panic("Execute method called when it shouldn't!");
236  return NoFault;
237  }
238 
239  std::string
241  {
242  std::stringstream ss;
243  printMnemonic(ss, "", false);
244  ccprintf(ss, "{");
245  for (int i = 0; i < numregs; ++i) {
246  printVecReg(ss, (dest + i) % 32, true);
247  if (i < numregs - 1)
248  ccprintf(ss, ", ");
249  }
250  ccprintf(ss, "}, ");
251  printVecPredReg(ss, gp);
252  ccprintf(ss, "/z, [");
253  printIntReg(ss, base);
254  if (imm != 0) {
255  ccprintf(ss, ", #%d, MUL VL", imm);
256  }
257  ccprintf(ss, "]");
258  return ss.str();
259  }
260 };
261 
262 template <typename Element,
263  template <typename> class MicroopStMemType,
264  template <typename> class MicroopIntrlvType>
266 {
267  protected:
271  int64_t imm;
272  uint8_t numregs;
273 
274  public:
275  SveStStructSI(const char* mnem, ExtMachInst machInst, OpClass __opClass,
276  IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
277  int64_t _imm, uint8_t _numregs)
278  : PredMacroOp(mnem, machInst, __opClass),
279  dest(_dest), gp(_gp), base(_base), imm(_imm), numregs(_numregs)
280  {
281  numMicroops = numregs * 2;
282 
284 
285  for (int i = 0; i < numregs; ++i) {
286  microOps[i] = new MicroopIntrlvType<Element>(
287  mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
288  _dest, _numregs, i, this);
289  }
290 
291  for (int i = 0; i < numregs; ++i) {
292  microOps[i + numregs] = new MicroopStMemType<Element>(
293  mnem, machInst, static_cast<IntRegIndex>(INTRLVREG0 + i),
294  _gp, _base, _imm, _numregs, i);
295  }
296 
299 
300  for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
301  (*uop)->setDelayedCommit();
302  }
303  }
304 
305  Fault
307  {
308  panic("Execute method called when it shouldn't!");
309  return NoFault;
310  }
311 
312  std::string
314  {
315  std::stringstream ss;
316  printMnemonic(ss, "", false);
317  ccprintf(ss, "{");
318  for (int i = 0; i < numregs; ++i) {
319  printVecReg(ss, (dest + i) % 32, true);
320  if (i < numregs - 1)
321  ccprintf(ss, ", ");
322  }
323  ccprintf(ss, "}, ");
324  printVecPredReg(ss, gp);
325  ccprintf(ss, ", [");
326  printIntReg(ss, base);
327  if (imm != 0) {
328  ccprintf(ss, ", #%d, MUL VL", imm);
329  }
330  ccprintf(ss, "]");
331  return ss.str();
332  }
333 };
334 
335 template <typename RegElemType, typename MemElemType,
336  template <typename, typename> class MicroopType,
337  template <typename> class FirstFaultWritebackMicroopType>
339 {
340  protected:
344  uint64_t imm;
345 
346  public:
347  SveIndexedMemVI(const char *mnem, ExtMachInst machInst, OpClass __opClass,
348  IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
349  uint64_t _imm, bool firstFault)
350  : PredMacroOp(mnem, machInst, __opClass),
351  dest(_dest), gp(_gp), base(_base), imm(_imm)
352  {
353  bool isLoad = (__opClass == MemReadOp);
354  assert(!firstFault || isLoad);
355 
356  int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType);
357 
358  numMicroops = num_elems;
359  if (isLoad) {
360  if (firstFault) {
361  numMicroops += 2;
362  } else {
363  numMicroops++;
364  }
365  }
366 
368 
369  StaticInstPtr *uop = microOps;
370 
371  if (isLoad) {
372  // The first microop of a gather load copies the source vector
373  // register used for address calculation to an auxiliary register,
374  // with all subsequent microops reading from the latter. This is
375  // needed to properly handle cases where the source vector
376  // register is the same as the destination register
377  *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop(
378  mnem, machInst, _base, this);
379  uop++;
380  }
381 
382  for (int i = 0; i < num_elems; i++, uop++) {
383  *uop = new MicroopType<RegElemType, MemElemType>(
384  mnem, machInst, __opClass, _dest, _gp,
385  isLoad ? (IntRegIndex) VECREG_UREG0 : _base, _imm, i,
386  num_elems, firstFault);
387  }
388 
389  if (firstFault) {
390  *uop = new FirstFaultWritebackMicroopType<RegElemType>(
391  mnem, machInst, __opClass, num_elems, this);
392  } else {
393  --uop;
394  }
395 
396  (*uop)->setLastMicroop();
398 
399  for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
400  (*uop)->setDelayedCommit();
401  }
402  }
403 
404  Fault
406  {
407  panic("Execute method called when it shouldn't!");
408  return NoFault;
409  }
410 
411  std::string
413  {
414  // TODO: add suffix to transfer and base registers
415  std::stringstream ss;
416  printMnemonic(ss, "", false);
417  ccprintf(ss, "{");
418  printVecReg(ss, dest, true);
419  ccprintf(ss, "}, ");
420  printVecPredReg(ss, gp);
421  ccprintf(ss, "/z, [");
422  printVecReg(ss, base, true);
423  if (imm != 0) {
424  ccprintf(ss, ", #%d", imm * sizeof(MemElemType));
425  }
426  ccprintf(ss, "]");
427  return ss.str();
428  }
429 };
430 
431 template <typename RegElemType, typename MemElemType,
432  template <typename, typename> class MicroopType,
433  template <typename> class FirstFaultWritebackMicroopType>
435 {
436  protected:
441 
445 
446  public:
447  SveIndexedMemSV(const char *mnem, ExtMachInst machInst, OpClass __opClass,
448  IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base,
449  IntRegIndex _offset, bool _offsetIs32,
450  bool _offsetIsSigned, bool _offsetIsScaled,
451  bool firstFault)
452  : PredMacroOp(mnem, machInst, __opClass),
453  dest(_dest), gp(_gp), base(_base), offset(_offset),
454  offsetIs32(_offsetIs32), offsetIsSigned(_offsetIsSigned),
455  offsetIsScaled(_offsetIsScaled)
456  {
457  bool isLoad = (__opClass == MemReadOp);
458  assert(!firstFault || isLoad);
459 
460  int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType);
461 
462  numMicroops = num_elems;
463  if (isLoad) {
464  if (firstFault) {
465  numMicroops += 2;
466  } else {
467  numMicroops++;
468  }
469  }
470 
472 
473  StaticInstPtr *uop = microOps;
474 
475  if (isLoad) {
476  // The first microop of a gather load copies the source vector
477  // register used for address calculation to an auxiliary register,
478  // with all subsequent microops reading from the latter. This is
479  // needed to properly handle cases where the source vector
480  // register is the same as the destination register
481  *uop = new ArmISAInst::SveGatherLoadCpySrcVecMicroop(
482  mnem, machInst, _offset, this);
483  uop++;
484  }
485 
486  for (int i = 0; i < num_elems; i++, uop++) {
487  *uop = new MicroopType<RegElemType, MemElemType>(
488  mnem, machInst, __opClass, _dest, _gp, _base,
489  isLoad ? (IntRegIndex) VECREG_UREG0 : _offset, _offsetIs32,
490  _offsetIsSigned, _offsetIsScaled, i, num_elems, firstFault);
491  }
492 
493  if (firstFault) {
494  *uop = new FirstFaultWritebackMicroopType<RegElemType>(
495  mnem, machInst, __opClass, num_elems, this);
496  } else {
497  --uop;
498  }
499 
500  (*uop)->setLastMicroop();
502 
503  for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
504  (*uop)->setDelayedCommit();
505  }
506  }
507 
508  Fault
510  {
511  panic("Execute method called when it shouldn't!");
512  return NoFault;
513  }
514 
515  std::string
517  {
518  // TODO: add suffix to transfer and base registers
519  std::stringstream ss;
520  printMnemonic(ss, "", false);
521  ccprintf(ss, "{");
522  printVecReg(ss, dest, true);
523  ccprintf(ss, "}, ");
524  printVecPredReg(ss, gp);
525  ccprintf(ss, "/z, [");
526  printIntReg(ss, base);
527  ccprintf(ss, ", ");
528  printVecReg(ss, offset, true);
529  ccprintf(ss, "]");
530  return ss.str();
531  }
532 };
533 
534 } // namespace ArmISA
535 
536 #endif // __ARCH_ARM_SVE_MACROMEM_HH__
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:163
void ccprintf(cp::Print &print)
Definition: cprintf.hh:127
const int VECREG_UREG0
Definition: registers.hh:126
void printMnemonic(std::ostream &os, const std::string &suffix="", bool withPred=true, bool withCond64=false, ConditionCode cond64=COND_UC) const
Definition: static_inst.cc:372
decltype(nullptr) constexpr NoFault
Definition: types.hh:243
IntRegIndex
Definition: intregs.hh:51
Fault execute(ExecContext *, Trace::InstRecord *) const
Bitfield< 7 > i
Fault execute(ExecContext *, Trace::InstRecord *) const
bool isLoad() const
Definition: static_inst.hh:161
SveLdStructSS(const char *mnem, ExtMachInst machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, IntRegIndex _offset, uint8_t _numregs)
Definition: sve_macromem.hh:59
SveStStructSI(const char *mnem, ExtMachInst machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, int64_t _imm, uint8_t _numregs)
Definition: ccregs.hh:41
Fault execute(ExecContext *, Trace::InstRecord *) const
const int INTRLVREG0
Definition: registers.hh:122
SveStStructSS(const char *mnem, ExtMachInst machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, IntRegIndex _offset, uint8_t _numregs)
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
Internal function to generate disassembly string.
void printVecPredReg(std::ostream &os, RegIndex reg_idx) const
Definition: static_inst.cc:353
const ExtMachInst machInst
The binary machine instruction.
Definition: static_inst.hh:231
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
Definition: exec_context.hh:70
Bitfield< 4 > pc
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
Internal function to generate disassembly string.
void printVecReg(std::ostream &os, RegIndex reg_idx, bool isSveVecReg=false) const
Definition: static_inst.cc:346
void printIntReg(std::ostream &os, RegIndex reg_idx, uint8_t opWidth=0) const
Print a register name for disassembly given the unique dependence tag number (FP or int)...
Definition: static_inst.cc:294
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
Internal function to generate disassembly string.
Definition: sve_macromem.hh:96
uint32_t numMicroops
Definition: pred_inst.hh:340
Bitfield< 21 > ss
void setFirstMicroop()
Definition: static_inst.hh:207
Fault execute(ExecContext *, Trace::InstRecord *) const
void setLastMicroop()
Definition: static_inst.hh:208
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
SveIndexedMemVI(const char *mnem, ExtMachInst machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, uint64_t _imm, bool firstFault)
static const OpClass MemReadOp
Definition: op_class.hh:99
SveLdStructSI(const char *mnem, ExtMachInst machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, int64_t _imm, uint8_t _numregs)
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
Internal function to generate disassembly string.
Fault execute(ExecContext *, Trace::InstRecord *) const
Base class for predicated macro-operations.
Definition: pred_inst.hh:336
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
Internal function to generate disassembly string.
Fault execute(ExecContext *, Trace::InstRecord *) const
Definition: sve_macromem.hh:89
TheISA::ExtMachInst ExtMachInst
Binary extended machine instruction type.
Definition: static_inst.hh:89
StaticInstPtr * microOps
Definition: pred_inst.hh:341
std::shared_ptr< FaultBase > Fault
Definition: types.hh:238
SveIndexedMemSV(const char *mnem, ExtMachInst machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _gp, IntRegIndex _base, IntRegIndex _offset, bool _offsetIs32, bool _offsetIsSigned, bool _offsetIsScaled, bool firstFault)
bool isLastMicroop() const
Definition: static_inst.hh:201
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
Internal function to generate disassembly string.

Generated on Mon Jun 8 2020 15:34:39 for gem5 by doxygen 1.8.13