gem5  v22.1.0.0
pred_inst.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2012-2013, 2017-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  * Copyright (c) 2007-2008 The Florida State University
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #ifndef __ARCH_ARM_INSTS_PREDINST_HH__
42 #define __ARCH_ARM_INSTS_PREDINST_HH__
43 
45 #include "arch/arm/pcstate.hh"
46 #include "base/compiler.hh"
47 #include "base/logging.hh"
48 #include "base/trace.hh"
49 #include "cpu/thread_context.hh"
50 
51 namespace gem5
52 {
53 
54 namespace ArmISA
55 {
56 static inline uint32_t
57 rotate_imm(uint32_t immValue, uint32_t rotateValue)
58 {
59  rotateValue &= 31;
60  return rotateValue == 0 ? immValue :
61  (immValue >> rotateValue) | (immValue << (32 - rotateValue));
62 }
63 
64 static inline uint32_t
65 modified_imm(uint8_t ctrlImm, uint8_t dataImm)
66 {
67  uint32_t bigData = dataImm;
68  uint32_t bigCtrl = ctrlImm;
69  if (bigCtrl < 4) {
70  switch (bigCtrl) {
71  case 0:
72  return bigData;
73  case 1:
74  return bigData | (bigData << 16);
75  case 2:
76  return (bigData << 8) | (bigData << 24);
77  case 3:
78  return (bigData << 0) | (bigData << 8) |
79  (bigData << 16) | (bigData << 24);
80  }
81  }
82  bigCtrl = (bigCtrl << 1) | ((bigData >> 7) & 0x1);
83  bigData |= (1 << 7);
84  return bigData << (32 - bigCtrl);
85 }
86 
87 static inline uint64_t
88 simd_modified_imm(bool op, uint8_t cmode, uint8_t data, bool &immValid,
89  bool isAarch64 = false)
90 {
91  uint64_t bigData = data;
92  immValid = true;
93  switch (cmode) {
94  case 0x0:
95  case 0x1:
96  bigData = (bigData << 0) | (bigData << 32);
97  break;
98  case 0x2:
99  case 0x3:
100  bigData = (bigData << 8) | (bigData << 40);
101  break;
102  case 0x4:
103  case 0x5:
104  bigData = (bigData << 16) | (bigData << 48);
105  break;
106  case 0x6:
107  case 0x7:
108  bigData = (bigData << 24) | (bigData << 56);
109  break;
110  case 0x8:
111  case 0x9:
112  bigData = (bigData << 0) | (bigData << 16) |
113  (bigData << 32) | (bigData << 48);
114  break;
115  case 0xa:
116  case 0xb:
117  bigData = (bigData << 8) | (bigData << 24) |
118  (bigData << 40) | (bigData << 56);
119  break;
120  case 0xc:
121  bigData = (0xffULL << 0) | (bigData << 8) |
122  (0xffULL << 32) | (bigData << 40);
123  break;
124  case 0xd:
125  bigData = (0xffffULL << 0) | (bigData << 16) |
126  (0xffffULL << 32) | (bigData << 48);
127  break;
128  case 0xe:
129  if (op) {
130  bigData = 0;
131  for (int i = 7; i >= 0; i--) {
132  if (bits(data, i)) {
133  bigData |= (0xFFULL << (i * 8));
134  }
135  }
136  } else {
137  bigData = (bigData << 0) | (bigData << 8) |
138  (bigData << 16) | (bigData << 24) |
139  (bigData << 32) | (bigData << 40) |
140  (bigData << 48) | (bigData << 56);
141  }
142  break;
143  case 0xf:
144  {
145  uint64_t bVal = 0;
146  if (!op) {
147  bVal = bits(bigData, 6) ? (0x1F) : (0x20);
148  bigData = (bits(bigData, 5, 0) << 19) |
149  (bVal << 25) | (bits(bigData, 7) << 31);
150  bigData |= (bigData << 32);
151  break;
152  } else if (isAarch64) {
153  bVal = bits(bigData, 6) ? (0x0FF) : (0x100);
154  bigData = (bits(bigData, 5, 0) << 48) |
155  (bVal << 54) | (bits(bigData, 7) << 63);
156  break;
157  }
158  }
159  [[fallthrough]];
160  default:
161  immValid = false;
162  break;
163  }
164  return bigData;
165 }
166 
168 enum class FpDataType { Fp16, Fp32, Fp64 };
169 
170 static inline uint64_t
172 {
173  uint64_t bigData = data;
174  uint64_t repData;
175  switch (dtype) {
176  case FpDataType::Fp16:
177  repData = bits(data, 6) ? 0x3 : 0;
178  bigData = (bits(bigData, 5, 0) << 6) |
179  (repData << 12) | (bits(~bigData, 6) << 14) |
180  (bits(bigData, 7) << 15);
181  break;
182  case FpDataType::Fp32:
183  repData = bits(data, 6) ? 0x1F : 0;
184  bigData = (bits(bigData, 5, 0) << 19) |
185  (repData << 25) | (bits(~bigData, 6) << 30) |
186  (bits(bigData, 7) << 31);
187  break;
188  case FpDataType::Fp64:
189  repData = bits(data, 6) ? 0xFF : 0;
190  bigData = (bits(bigData, 5, 0) << 48) |
191  (repData << 54) | (bits(~bigData, 6) << 62) |
192  (bits(bigData, 7) << 63);
193  break;
194  default:
195  panic("Unrecognized FP data type");
196  }
197  return bigData;
198 }
199 
200 static inline FpDataType
202 {
203  switch (encoding) {
204  case 1: return FpDataType::Fp16;
205  case 2: return FpDataType::Fp32;
206  case 3: return FpDataType::Fp64;
207  default:
208  panic(
209  "Invalid floating point data type in VFP/SIMD or SVE instruction");
210  }
211 }
212 
216 class PredOp : public ArmStaticInst
217 {
218  protected:
219 
221 
223  PredOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
224  ArmStaticInst(mnem, _machInst, __opClass)
225  {
226  if (machInst.aarch64)
227  condCode = COND_UC;
228  else if (machInst.itstateMask)
229  condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
230  else
231  condCode = (ConditionCode)(unsigned)machInst.condCode;
232  }
233 };
234 
238 class PredImmOp : public PredOp
239 {
240  protected:
241 
242  uint32_t imm;
243  uint32_t rotated_imm;
244  uint32_t rotated_carry;
245  uint32_t rotate;
246 
248  PredImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
249  PredOp(mnem, _machInst, __opClass),
251  rotate(machInst.rotate << 1)
252  {
254  if (rotate != 0)
256  }
257 
258  std::string generateDisassembly(
259  Addr pc, const loader::SymbolTable *symtab) const override;
260 };
261 
265 class PredIntOp : public PredOp
266 {
267  protected:
268 
269  uint32_t shift_size;
270  uint32_t shift;
271 
273  PredIntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
274  PredOp(mnem, _machInst, __opClass),
276  {
277  }
278 
279  std::string generateDisassembly(
280  Addr pc, const loader::SymbolTable *symtab) const override;
281 };
282 
283 class DataImmOp : public PredOp
284 {
285  protected:
287  uint32_t imm;
288  // Whether the carry flag should be modified if that's an option for
289  // this instruction.
290  bool rotC;
291 
292  DataImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
293  RegIndex _dest, RegIndex _op1, uint32_t _imm, bool _rotC) :
294  PredOp(mnem, _machInst, __opClass),
295  dest(_dest), op1(_op1), imm(_imm), rotC(_rotC)
296  {}
297 
298  std::string generateDisassembly(
299  Addr pc, const loader::SymbolTable *symtab) const override;
300 };
301 
302 class DataRegOp : public PredOp
303 {
304  protected:
306  int32_t shiftAmt;
307  ArmShiftType shiftType;
308 
309  DataRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
310  RegIndex _dest, RegIndex _op1, RegIndex _op2,
311  int32_t _shiftAmt, ArmShiftType _shiftType) :
312  PredOp(mnem, _machInst, __opClass),
313  dest(_dest), op1(_op1), op2(_op2),
314  shiftAmt(_shiftAmt), shiftType(_shiftType)
315  {}
316 
317  std::string generateDisassembly(
318  Addr pc, const loader::SymbolTable *symtab) const override;
319 };
320 
321 class DataRegRegOp : public PredOp
322 {
323  protected:
325  ArmShiftType shiftType;
326 
327  DataRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
328  RegIndex _dest, RegIndex _op1, RegIndex _op2,
329  RegIndex _shift, ArmShiftType _shiftType) :
330  PredOp(mnem, _machInst, __opClass),
331  dest(_dest), op1(_op1), op2(_op2), shift(_shift),
332  shiftType(_shiftType)
333  {}
334 
335  std::string generateDisassembly(
336  Addr pc, const loader::SymbolTable *symtab) const override;
337 };
338 
342 class PredMacroOp : public PredOp
343 {
344  protected:
345 
346  uint32_t numMicroops;
348 
350  PredMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
351  PredOp(mnem, _machInst, __opClass),
352  numMicroops(0), microOps(nullptr)
353  {
354  // We rely on the subclasses of this object to handle the
355  // initialization of the micro-operations, since they are
356  // all of variable length
357  flags[IsMacroop] = true;
358  }
359 
361  {
362  if (numMicroops)
363  delete [] microOps;
364  }
365 
367  fetchMicroop(MicroPC microPC) const override
368  {
369  assert(microPC < numMicroops);
370  return microOps[microPC];
371  }
372 
373  Fault
374  execute(ExecContext *, trace::InstRecord *) const override
375  {
376  panic("Execute method called when it shouldn't!");
377  }
378 
379  std::string generateDisassembly(
380  Addr pc, const loader::SymbolTable *symtab) const override;
381 };
382 
386 class PredMicroop : public PredOp
387 {
389  PredMicroop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
390  PredOp(mnem, _machInst, __opClass)
391  {
392  flags[IsMicroop] = true;
393  }
394 
395  void
396  advancePC(PCStateBase &pcState) const override
397  {
398  auto &apc = pcState.as<PCState>();
399  if (flags[IsLastMicroop])
400  apc.uEnd();
401  else
402  apc.uAdvance();
403  }
404 
405  void
406  advancePC(ThreadContext *tc) const override
407  {
408  PCState pc = tc->pcState().as<PCState>();
409  if (flags[IsLastMicroop])
410  pc.uEnd();
411  else
412  pc.uAdvance();
413  tc->pcState(pc);
414  }
415 };
416 
417 } // namespace ArmISA
418 } // namespace gem5
419 
420 #endif //__ARCH_ARM_INSTS_PREDINST_HH__
const char data[]
DataImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, RegIndex _dest, RegIndex _op1, uint32_t _imm, bool _rotC)
Definition: pred_inst.hh:292
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition: pred_inst.cc:76
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition: pred_inst.cc:86
DataRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, RegIndex _dest, RegIndex _op1, RegIndex _op2, int32_t _shiftAmt, ArmShiftType _shiftType)
Definition: pred_inst.hh:309
ArmShiftType shiftType
Definition: pred_inst.hh:307
DataRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, RegIndex _dest, RegIndex _op1, RegIndex _op2, RegIndex _shift, ArmShiftType _shiftType)
Definition: pred_inst.hh:327
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition: pred_inst.cc:96
Base class for predicated immediate operations.
Definition: pred_inst.hh:239
PredImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
Constructor.
Definition: pred_inst.hh:248
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition: pred_inst.cc:64
Base class for predicated integer operations.
Definition: pred_inst.hh:266
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition: pred_inst.cc:49
PredIntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
Constructor.
Definition: pred_inst.hh:273
Base class for predicated macro-operations.
Definition: pred_inst.hh:343
StaticInstPtr * microOps
Definition: pred_inst.hh:347
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition: pred_inst.hh:374
PredMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
Constructor.
Definition: pred_inst.hh:350
StaticInstPtr fetchMicroop(MicroPC microPC) const override
Return the microop that goes with a particular micropc.
Definition: pred_inst.hh:367
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition: pred_inst.cc:106
Base class for predicated micro-operations.
Definition: pred_inst.hh:387
void advancePC(ThreadContext *tc) const override
Definition: pred_inst.hh:406
void advancePC(PCStateBase &pcState) const override
Definition: pred_inst.hh:396
PredMicroop(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
Constructor.
Definition: pred_inst.hh:389
Base class for predicated integer operations.
Definition: pred_inst.hh:217
ConditionCode condCode
Definition: pred_inst.hh:220
PredOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
Constructor.
Definition: pred_inst.hh:223
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
Definition: exec_context.hh:72
Target & as()
Definition: pcstate.hh:72
std::bitset< Num_Flags > flags
Flag values for this instruction.
Definition: static_inst.hh:103
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual const PCStateBase & pcState() const =0
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
static uint32_t rotate_imm(uint32_t immValue, uint32_t rotateValue)
Definition: pred_inst.hh:57
static FpDataType decode_fp_data_type(uint8_t encoding)
Definition: pred_inst.hh:201
static uint32_t modified_imm(uint8_t ctrlImm, uint8_t dataImm)
Definition: pred_inst.hh:65
FpDataType
Floating point data types.
Definition: pred_inst.hh:168
Bitfield< 7 > i
Definition: misc_types.hh:67
ConditionCode
Definition: cc.hh:92
@ COND_UC
Definition: cc.hh:108
static uint64_t simd_modified_imm(bool op, uint8_t cmode, uint8_t data, bool &immValid, bool isAarch64=false)
Definition: pred_inst.hh:88
static uint64_t vfp_modified_imm(uint8_t data, FpDataType dtype)
Definition: pred_inst.hh:171
Bitfield< 27, 25 > encoding
Definition: types.hh:90
Bitfield< 11, 7 > shiftSize
Definition: types.hh:116
Bitfield< 4 > pc
Bitfield< 4 > op
Definition: types.hh:83
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
uint16_t RegIndex
Definition: types.hh:176
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
uint16_t MicroPC
Definition: types.hh:149

Generated on Wed Dec 21 2022 10:22:26 for gem5 by doxygen 1.9.1