1// Copyright 2014, ARM Limited
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7//   * Redistributions of source code must retain the above copyright notice,
8//     this list of conditions and the following disclaimer.
9//   * Redistributions in binary form must reproduce the above copyright notice,
10//     this list of conditions and the following disclaimer in the documentation
11//     and/or other materials provided with the distribution.
12//   * Neither the name of ARM Limited nor the names of its contributors may be
13//     used to endorse or promote products derived from this software without
14//     specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#ifndef VIXL_EXAMPLES_NON_CONST_VISITOR_H_
28#define VIXL_EXAMPLES_NON_CONST_VISITOR_H_
29
30using namespace vixl;
31
32class SwitchAddSubRegisterSources : public DecoderVisitor {
33 public:
34  SwitchAddSubRegisterSources()
35      : DecoderVisitor(DecoderVisitor::kNonConstVisitor) {}
36
37  // Our visitor switches the register sources for some add and sub instructions
38  // (not all add and sub instructions). Visitors are listed by the macro
39  // `VISITOR_LIST` in a64/decoder-a64.h.
40  virtual void VisitAddSubShifted(const Instruction* instr) {
41    int rn = instr->Rn();
42    int rm = instr->Rm();
43    // Only non-const visitors are allowed to discard constness of the visited
44    // instruction.
45    Instruction* mutable_instr = MutableInstruction(instr);
46    Instr instr_bits = mutable_instr->InstructionBits();
47
48    // Switch the bitfields for the `rn` and `rm` registers.
49    instr_bits &= ~(Rn_mask | Rm_mask);
50    instr_bits |= (rn << Rm_offset) | (rm << Rn_offset);
51
52    // Rewrite the instruction.
53    mutable_instr->SetInstructionBits(instr_bits);
54  }
55
56  // Define the remaining visitors to do nothing.
57#define UNUSED_VISITOR_LIST(V)      \
58  V(PCRelAddressing)                \
59  V(AddSubImmediate)                \
60  V(LogicalImmediate)               \
61  V(MoveWideImmediate)              \
62  V(Bitfield)                       \
63  V(Extract)                        \
64  V(UnconditionalBranch)            \
65  V(UnconditionalBranchToRegister)  \
66  V(CompareBranch)                  \
67  V(TestBranch)                     \
68  V(ConditionalBranch)              \
69  V(System)                         \
70  V(Exception)                      \
71  V(LoadStorePairPostIndex)         \
72  V(LoadStorePairOffset)            \
73  V(LoadStorePairPreIndex)          \
74  V(LoadStorePairNonTemporal)       \
75  V(LoadLiteral)                    \
76  V(LoadStoreUnscaledOffset)        \
77  V(LoadStorePostIndex)             \
78  V(LoadStorePreIndex)              \
79  V(LoadStoreRegisterOffset)        \
80  V(LoadStoreUnsignedOffset)        \
81  V(LoadStoreExclusive)             \
82  V(LogicalShifted)                 \
83  V(AddSubExtended)                 \
84  V(AddSubWithCarry)                \
85  V(ConditionalCompareRegister)     \
86  V(ConditionalCompareImmediate)    \
87  V(ConditionalSelect)              \
88  V(DataProcessing1Source)          \
89  V(DataProcessing2Source)          \
90  V(DataProcessing3Source)          \
91  V(FPCompare)                      \
92  V(FPConditionalCompare)           \
93  V(FPConditionalSelect)            \
94  V(FPImmediate)                    \
95  V(FPDataProcessing1Source)        \
96  V(FPDataProcessing2Source)        \
97  V(FPDataProcessing3Source)        \
98  V(FPIntegerConvert)               \
99  V(FPFixedPointConvert)            \
100  V(Crypto2RegSHA)                  \
101  V(Crypto3RegSHA)                  \
102  V(CryptoAES)                      \
103  V(NEON2RegMisc)                   \
104  V(NEON3Different)                 \
105  V(NEON3Same)                      \
106  V(NEONAcrossLanes)                \
107  V(NEONByIndexedElement)           \
108  V(NEONCopy)                       \
109  V(NEONExtract)                    \
110  V(NEONLoadStoreMultiStruct)       \
111  V(NEONLoadStoreMultiStructPostIndex)  \
112  V(NEONLoadStoreSingleStruct)      \
113  V(NEONLoadStoreSingleStructPostIndex) \
114  V(NEONModifiedImmediate)          \
115  V(NEONScalar2RegMisc)             \
116  V(NEONScalar3Diff)                \
117  V(NEONScalar3Same)                \
118  V(NEONScalarByIndexedElement)     \
119  V(NEONScalarCopy)                 \
120  V(NEONScalarPairwise)             \
121  V(NEONScalarShiftImmediate)       \
122  V(NEONShiftImmediate)             \
123  V(NEONTable)                      \
124  V(NEONPerm)                       \
125  V(Unallocated)                    \
126  V(Unimplemented)
127#define DEFINE_UNUSED_VISITOR(Name)                                  \
128  virtual void Visit##Name(const Instruction* i) {                   \
129    USE(i); /* Prevents compiler warnings about unused variables. */ \
130  }
131  UNUSED_VISITOR_LIST(DEFINE_UNUSED_VISITOR)
132#undef DEFINE_UNUSED_VISITOR
133#undef UNUSED_VISITOR_LIST
134};
135
136
137void GenerateNonConstVisitorTestCode(MacroAssembler* masm);
138
139int64_t RunNonConstVisitorTestGeneratedCode(const Instruction* start_instr);
140
141void ModifyNonConstVisitorTestGeneratedCode(Instruction* start,
142                                            Instruction* end);
143
144
145#endif
146