misc.hh revision 13574:bab20b8d882d
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 * 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: Gabe Black
38 */
39
40#ifndef __ARCH_ARM_INSTS_MISC_HH__
41#define __ARCH_ARM_INSTS_MISC_HH__
42
43#include "arch/arm/insts/pred_inst.hh"
44
45class MrsOp : public PredOp
46{
47  protected:
48    IntRegIndex dest;
49
50    MrsOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
51            IntRegIndex _dest) :
52        PredOp(mnem, _machInst, __opClass), dest(_dest)
53    {}
54
55    std::string generateDisassembly(
56            Addr pc, const SymbolTable *symtab) const override;
57};
58
59class MsrBase : public PredOp
60{
61  protected:
62    uint8_t byteMask;
63
64    MsrBase(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
65            uint8_t _byteMask) :
66        PredOp(mnem, _machInst, __opClass), byteMask(_byteMask)
67    {}
68
69    void printMsrBase(std::ostream &os) const;
70};
71
72class MsrImmOp : public MsrBase
73{
74  protected:
75    uint32_t imm;
76
77    MsrImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
78             uint32_t _imm, uint8_t _byteMask) :
79        MsrBase(mnem, _machInst, __opClass, _byteMask), imm(_imm)
80    {}
81
82    std::string generateDisassembly(
83            Addr pc, const SymbolTable *symtab) const override;
84};
85
86class MsrRegOp : public MsrBase
87{
88  protected:
89    IntRegIndex op1;
90
91    MsrRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
92             IntRegIndex _op1, uint8_t _byteMask) :
93        MsrBase(mnem, _machInst, __opClass, _byteMask), op1(_op1)
94    {}
95
96    std::string generateDisassembly(
97            Addr pc, const SymbolTable *symtab) const override;
98};
99
100class MrrcOp : public PredOp
101{
102  protected:
103    MiscRegIndex op1;
104    IntRegIndex dest;
105    IntRegIndex dest2;
106    uint32_t    imm;
107
108    MrrcOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
109           MiscRegIndex _op1, IntRegIndex _dest, IntRegIndex _dest2,
110           uint32_t _imm) :
111        PredOp(mnem, _machInst, __opClass), op1(_op1), dest(_dest),
112        dest2(_dest2), imm(_imm)
113    {}
114
115    std::string generateDisassembly(
116            Addr pc, const SymbolTable *symtab) const override;
117};
118
119class McrrOp : public PredOp
120{
121  protected:
122    IntRegIndex op1;
123    IntRegIndex op2;
124    MiscRegIndex dest;
125    uint32_t    imm;
126
127    McrrOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
128           IntRegIndex _op1, IntRegIndex _op2, MiscRegIndex _dest,
129           uint32_t _imm) :
130        PredOp(mnem, _machInst, __opClass), op1(_op1), op2(_op2),
131        dest(_dest), imm(_imm)
132    {}
133
134    std::string generateDisassembly(
135            Addr pc, const SymbolTable *symtab) const override;
136};
137
138class ImmOp : public PredOp
139{
140  protected:
141    uint64_t imm;
142
143    ImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
144             uint64_t _imm) :
145        PredOp(mnem, _machInst, __opClass), imm(_imm)
146    {}
147
148    std::string generateDisassembly(
149            Addr pc, const SymbolTable *symtab) const override;
150};
151
152class RegImmOp : public PredOp
153{
154  protected:
155    IntRegIndex dest;
156    uint64_t imm;
157
158    RegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
159             IntRegIndex _dest, uint64_t _imm) :
160        PredOp(mnem, _machInst, __opClass), dest(_dest), imm(_imm)
161    {}
162
163    std::string generateDisassembly(
164            Addr pc, const SymbolTable *symtab) const override;
165};
166
167class RegRegOp : public PredOp
168{
169  protected:
170    IntRegIndex dest;
171    IntRegIndex op1;
172
173    RegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
174             IntRegIndex _dest, IntRegIndex _op1) :
175        PredOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1)
176    {}
177
178    std::string generateDisassembly(
179            Addr pc, const SymbolTable *symtab) const override;
180};
181
182class RegImmRegOp : public PredOp
183{
184  protected:
185    IntRegIndex dest;
186    uint64_t imm;
187    IntRegIndex op1;
188
189    RegImmRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
190                IntRegIndex _dest, uint64_t _imm, IntRegIndex _op1) :
191        PredOp(mnem, _machInst, __opClass),
192        dest(_dest), imm(_imm), op1(_op1)
193    {}
194
195    std::string generateDisassembly(
196            Addr pc, const SymbolTable *symtab) const override;
197};
198
199class RegRegRegImmOp : public PredOp
200{
201  protected:
202    IntRegIndex dest;
203    IntRegIndex op1;
204    IntRegIndex op2;
205    uint64_t imm;
206
207    RegRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
208                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
209                   uint64_t _imm) :
210        PredOp(mnem, _machInst, __opClass),
211        dest(_dest), op1(_op1), op2(_op2), imm(_imm)
212    {}
213
214    std::string generateDisassembly(
215            Addr pc, const SymbolTable *symtab) const override;
216};
217
218class RegRegRegRegOp : public PredOp
219{
220  protected:
221    IntRegIndex dest;
222    IntRegIndex op1;
223    IntRegIndex op2;
224    IntRegIndex op3;
225
226    RegRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
227                   IntRegIndex _dest, IntRegIndex _op1,
228                   IntRegIndex _op2, IntRegIndex _op3) :
229        PredOp(mnem, _machInst, __opClass),
230        dest(_dest), op1(_op1), op2(_op2), op3(_op3)
231    {}
232
233    std::string generateDisassembly(
234            Addr pc, const SymbolTable *symtab) const override;
235};
236
237class RegRegRegOp : public PredOp
238{
239  protected:
240    IntRegIndex dest;
241    IntRegIndex op1;
242    IntRegIndex op2;
243
244    RegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
245                IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) :
246        PredOp(mnem, _machInst, __opClass),
247        dest(_dest), op1(_op1), op2(_op2)
248    {}
249
250    std::string generateDisassembly(
251            Addr pc, const SymbolTable *symtab) const override;
252};
253
254class RegRegImmOp : public PredOp
255{
256  protected:
257    IntRegIndex dest;
258    IntRegIndex op1;
259    uint64_t imm;
260
261    RegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
262                IntRegIndex _dest, IntRegIndex _op1,
263                uint64_t _imm) :
264        PredOp(mnem, _machInst, __opClass),
265        dest(_dest), op1(_op1), imm(_imm)
266    {}
267
268    std::string generateDisassembly(
269            Addr pc, const SymbolTable *symtab) const override;
270};
271
272class MiscRegRegImmOp : public PredOp
273{
274  protected:
275    MiscRegIndex dest;
276    IntRegIndex op1;
277    uint64_t imm;
278
279    MiscRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
280                    MiscRegIndex _dest, IntRegIndex _op1,
281                    uint64_t _imm) :
282        PredOp(mnem, _machInst, __opClass),
283        dest(_dest), op1(_op1), imm(_imm)
284    {}
285
286    std::string generateDisassembly(
287            Addr pc, const SymbolTable *symtab) const override;
288};
289
290class RegMiscRegImmOp : public PredOp
291{
292  protected:
293    IntRegIndex dest;
294    MiscRegIndex op1;
295    uint64_t imm;
296
297    RegMiscRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
298                    IntRegIndex _dest, MiscRegIndex _op1,
299                    uint64_t _imm) :
300        PredOp(mnem, _machInst, __opClass),
301        dest(_dest), op1(_op1), imm(_imm)
302    {}
303
304    std::string generateDisassembly(
305            Addr pc, const SymbolTable *symtab) const override;
306};
307
308class RegImmImmOp : public PredOp
309{
310  protected:
311    IntRegIndex dest;
312    uint64_t imm1;
313    uint64_t imm2;
314
315    RegImmImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
316                IntRegIndex _dest, uint64_t _imm1, uint64_t _imm2) :
317        PredOp(mnem, _machInst, __opClass),
318        dest(_dest), imm1(_imm1), imm2(_imm2)
319    {}
320
321    std::string generateDisassembly(
322            Addr pc, const SymbolTable *symtab) const override;
323};
324
325class RegRegImmImmOp : public PredOp
326{
327  protected:
328    IntRegIndex dest;
329    IntRegIndex op1;
330    uint64_t imm1;
331    uint64_t imm2;
332
333    RegRegImmImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
334                   IntRegIndex _dest, IntRegIndex _op1,
335                   uint64_t _imm1, uint64_t _imm2) :
336        PredOp(mnem, _machInst, __opClass),
337        dest(_dest), op1(_op1), imm1(_imm1), imm2(_imm2)
338    {}
339
340    std::string generateDisassembly(
341            Addr pc, const SymbolTable *symtab) const override;
342};
343
344class RegImmRegShiftOp : public PredOp
345{
346  protected:
347    IntRegIndex dest;
348    uint64_t imm;
349    IntRegIndex op1;
350    int32_t shiftAmt;
351    ArmShiftType shiftType;
352
353    RegImmRegShiftOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
354                     IntRegIndex _dest, uint64_t _imm, IntRegIndex _op1,
355                     int32_t _shiftAmt, ArmShiftType _shiftType) :
356        PredOp(mnem, _machInst, __opClass),
357        dest(_dest), imm(_imm), op1(_op1),
358        shiftAmt(_shiftAmt), shiftType(_shiftType)
359    {}
360
361    std::string generateDisassembly(
362            Addr pc, const SymbolTable *symtab) const override;
363};
364
365class UnknownOp : public PredOp
366{
367  protected:
368
369    UnknownOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
370        PredOp(mnem, _machInst, __opClass)
371    {}
372
373    std::string generateDisassembly(
374            Addr pc, const SymbolTable *symtab) const override;
375};
376
377/**
378 * Certain mrc/mcr instructions act as nops or flush the pipe based on what
379 * register the instruction is trying to access. This inst/class exists so that
380 * we can still check for hyp traps, as the normal nop instruction
381 * does not.
382 */
383class McrMrcMiscInst : public ArmStaticInst
384{
385  protected:
386    uint64_t iss;
387    MiscRegIndex miscReg;
388
389  public:
390    McrMrcMiscInst(const char *_mnemonic, ExtMachInst _machInst,
391                   uint64_t _iss, MiscRegIndex _miscReg);
392
393    Fault execute(ExecContext *xc,
394                  Trace::InstRecord *traceData) const override;
395
396    std::string generateDisassembly(
397            Addr pc, const SymbolTable *symtab) const override;
398
399};
400
401/**
402 * This class is also used for IMPLEMENTATION DEFINED registers, whose mcr/mrc
403 * behaviour is trappable even for unimplemented registers.
404 */
405class McrMrcImplDefined : public McrMrcMiscInst
406{
407  public:
408    McrMrcImplDefined(const char *_mnemonic, ExtMachInst _machInst,
409                      uint64_t _iss, MiscRegIndex _miscReg);
410
411    Fault execute(ExecContext *xc,
412                  Trace::InstRecord *traceData) const override;
413
414    std::string generateDisassembly(
415            Addr pc, const SymbolTable *symtab) const override;
416
417};
418
419#endif
420