139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// Copyright 2014, ARM Limited
239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// All rights reserved.
339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//
439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// Redistribution and use in source and binary forms, with or without
539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// modification, are permitted provided that the following conditions are met:
639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//
739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//   * Redistributions of source code must retain the above copyright notice,
839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//     this list of conditions and the following disclaimer.
939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//   * Redistributions in binary form must reproduce the above copyright notice,
1039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//     this list of conditions and the following disclaimer in the documentation
1139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//     and/or other materials provided with the distribution.
1239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//   * Neither the name of ARM Limited nor the names of its contributors may be
1339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//     used to endorse or promote products derived from this software without
1439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//     specific prior written permission.
1539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl//
1639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
1739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
2039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
2739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#ifndef VIXL_EXAMPLES_NON_CONST_VISITOR_H_
2839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#define VIXL_EXAMPLES_NON_CONST_VISITOR_H_
2939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
3039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlusing namespace vixl;
3139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
3239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlclass SwitchAddSubRegisterSources : public DecoderVisitor {
3339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl public:
3439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  SwitchAddSubRegisterSources()
3539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl      : DecoderVisitor(DecoderVisitor::kNonConstVisitor) {}
3639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
3739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  // Our visitor switches the register sources for some add and sub instructions
3839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  // (not all add and sub instructions). Visitors are listed by the macro
3939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  // `VISITOR_LIST` in a64/decoder-a64.h.
4039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  virtual void VisitAddSubShifted(const Instruction* instr) {
4139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    int rn = instr->Rn();
4239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    int rm = instr->Rm();
4339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    // Only non-const visitors are allowed to discard constness of the visited
4439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    // instruction.
4539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    Instruction* mutable_instr = MutableInstruction(instr);
4639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    Instr instr_bits = mutable_instr->InstructionBits();
4739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
4839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    // Switch the bitfields for the `rn` and `rm` registers.
4939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    instr_bits &= ~(Rn_mask | Rm_mask);
5039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    instr_bits |= (rn << Rm_offset) | (rm << Rn_offset);
5139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
5239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    // Rewrite the instruction.
5339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    mutable_instr->SetInstructionBits(instr_bits);
5439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  }
5539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
5639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  // Define the remaining visitors to do nothing.
5739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#define UNUSED_VISITOR_LIST(V)      \
5839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(PCRelAddressing)                \
5939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(AddSubImmediate)                \
6039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LogicalImmediate)               \
6139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(MoveWideImmediate)              \
6239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(Bitfield)                       \
6339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(Extract)                        \
6439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(UnconditionalBranch)            \
6539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(UnconditionalBranchToRegister)  \
6639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(CompareBranch)                  \
6739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(TestBranch)                     \
6839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(ConditionalBranch)              \
6939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(System)                         \
7039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(Exception)                      \
7139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStorePairPostIndex)         \
7239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStorePairOffset)            \
7339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStorePairPreIndex)          \
7439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStorePairNonTemporal)       \
7539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadLiteral)                    \
7639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStoreUnscaledOffset)        \
7739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStorePostIndex)             \
7839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStorePreIndex)              \
7939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStoreRegisterOffset)        \
8039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStoreUnsignedOffset)        \
8139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LoadStoreExclusive)             \
8239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(LogicalShifted)                 \
8339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(AddSubExtended)                 \
8439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(AddSubWithCarry)                \
8539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(ConditionalCompareRegister)     \
8639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(ConditionalCompareImmediate)    \
8739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(ConditionalSelect)              \
8839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(DataProcessing1Source)          \
8939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(DataProcessing2Source)          \
9039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(DataProcessing3Source)          \
9139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(FPCompare)                      \
9239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(FPConditionalCompare)           \
9339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(FPConditionalSelect)            \
9439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(FPImmediate)                    \
9539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(FPDataProcessing1Source)        \
9639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(FPDataProcessing2Source)        \
9739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(FPDataProcessing3Source)        \
9839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(FPIntegerConvert)               \
9939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(FPFixedPointConvert)            \
1000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(Crypto2RegSHA)                  \
1010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(Crypto3RegSHA)                  \
1020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(CryptoAES)                      \
1030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEON2RegMisc)                   \
1040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEON3Different)                 \
1050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEON3Same)                      \
1060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONAcrossLanes)                \
1070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONByIndexedElement)           \
1080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONCopy)                       \
1090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONExtract)                    \
1100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONLoadStoreMultiStruct)       \
1110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONLoadStoreMultiStructPostIndex)  \
1120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONLoadStoreSingleStruct)      \
1130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONLoadStoreSingleStructPostIndex) \
1140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONModifiedImmediate)          \
1150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONScalar2RegMisc)             \
1160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONScalar3Diff)                \
1170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONScalar3Same)                \
1180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONScalarByIndexedElement)     \
1190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONScalarCopy)                 \
1200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONScalarPairwise)             \
1210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONScalarShiftImmediate)       \
1220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONShiftImmediate)             \
1230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONTable)                      \
1240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl  V(NEONPerm)                       \
12539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(Unallocated)                    \
12639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  V(Unimplemented)
12739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#define DEFINE_UNUSED_VISITOR(Name)                                  \
12839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  virtual void Visit##Name(const Instruction* i) {                   \
12939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl    USE(i); /* Prevents compiler warnings about unused variables. */ \
13039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  }
13139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  UNUSED_VISITOR_LIST(DEFINE_UNUSED_VISITOR)
13239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#undef DEFINE_UNUSED_VISITOR
13339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#undef UNUSED_VISITOR_LIST
13439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl};
13539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
13639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
13739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid GenerateNonConstVisitorTestCode(MacroAssembler* masm);
13839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
13939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlint64_t RunNonConstVisitorTestGeneratedCode(const Instruction* start_instr);
14039ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
14139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid ModifyNonConstVisitorTestGeneratedCode(Instruction* start,
14239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl                                            Instruction* end);
14339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
14439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl
14539ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl#endif
146