1 // Copyright 2014, VIXL authors 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 30 #include "aarch64/decoder-aarch64.h" 31 #include "aarch64/macro-assembler-aarch64.h" 32 33 using namespace vixl::aarch64; 34 35 class SwitchAddSubRegisterSources : public DecoderVisitor { 36 public: SwitchAddSubRegisterSources()37 SwitchAddSubRegisterSources() 38 : DecoderVisitor(DecoderVisitor::kNonConstVisitor) {} 39 40 // Our visitor switches the register sources for some add and sub instructions 41 // (not all add and sub instructions). Visitors are listed by the macro 42 // `VISITOR_LIST` in aarch64/decoder-aarch64.h. VisitAddSubShifted(const Instruction * instr)43 virtual void VisitAddSubShifted(const Instruction* instr) VIXL_OVERRIDE { 44 int rn = instr->GetRn(); 45 int rm = instr->GetRm(); 46 // Only non-const visitors are allowed to discard constness of the visited 47 // instruction. 48 Instruction* mutable_instr = MutableInstruction(instr); 49 Instr instr_bits = mutable_instr->GetInstructionBits(); 50 51 // Switch the bitfields for the `rn` and `rm` registers. 52 instr_bits &= ~(Rn_mask | Rm_mask); 53 instr_bits |= (rn << Rm_offset) | (rm << Rn_offset); 54 55 // Rewrite the instruction. 56 mutable_instr->SetInstructionBits(instr_bits); 57 } 58 59 // Define the remaining visitors to do nothing. 60 #define UNUSED_VISITOR_LIST(V) \ 61 V(PCRelAddressing) \ 62 V(AddSubImmediate) \ 63 V(LogicalImmediate) \ 64 V(MoveWideImmediate) \ 65 V(Bitfield) \ 66 V(Extract) \ 67 V(UnconditionalBranch) \ 68 V(UnconditionalBranchToRegister) \ 69 V(CompareBranch) \ 70 V(TestBranch) \ 71 V(ConditionalBranch) \ 72 V(System) \ 73 V(Exception) \ 74 V(LoadStorePairPostIndex) \ 75 V(LoadStorePairOffset) \ 76 V(LoadStorePairPreIndex) \ 77 V(LoadStorePairNonTemporal) \ 78 V(LoadLiteral) \ 79 V(LoadStoreUnscaledOffset) \ 80 V(LoadStorePostIndex) \ 81 V(LoadStorePreIndex) \ 82 V(LoadStoreRegisterOffset) \ 83 V(LoadStoreUnsignedOffset) \ 84 V(LoadStoreExclusive) \ 85 V(LogicalShifted) \ 86 V(AddSubExtended) \ 87 V(AddSubWithCarry) \ 88 V(ConditionalCompareRegister) \ 89 V(ConditionalCompareImmediate) \ 90 V(ConditionalSelect) \ 91 V(DataProcessing1Source) \ 92 V(DataProcessing2Source) \ 93 V(DataProcessing3Source) \ 94 V(FPCompare) \ 95 V(FPConditionalCompare) \ 96 V(FPConditionalSelect) \ 97 V(FPImmediate) \ 98 V(FPDataProcessing1Source) \ 99 V(FPDataProcessing2Source) \ 100 V(FPDataProcessing3Source) \ 101 V(FPIntegerConvert) \ 102 V(FPFixedPointConvert) \ 103 V(Crypto2RegSHA) \ 104 V(Crypto3RegSHA) \ 105 V(CryptoAES) \ 106 V(NEON2RegMisc) \ 107 V(NEON3Different) \ 108 V(NEON3Same) \ 109 V(NEONAcrossLanes) \ 110 V(NEONByIndexedElement) \ 111 V(NEONCopy) \ 112 V(NEONExtract) \ 113 V(NEONLoadStoreMultiStruct) \ 114 V(NEONLoadStoreMultiStructPostIndex) \ 115 V(NEONLoadStoreSingleStruct) \ 116 V(NEONLoadStoreSingleStructPostIndex) \ 117 V(NEONModifiedImmediate) \ 118 V(NEONScalar2RegMisc) \ 119 V(NEONScalar3Diff) \ 120 V(NEONScalar3Same) \ 121 V(NEONScalarByIndexedElement) \ 122 V(NEONScalarCopy) \ 123 V(NEONScalarPairwise) \ 124 V(NEONScalarShiftImmediate) \ 125 V(NEONShiftImmediate) \ 126 V(NEONTable) \ 127 V(NEONPerm) \ 128 V(Unallocated) \ 129 V(Unimplemented) 130 #define DEFINE_UNUSED_VISITOR(Name) \ 131 virtual void Visit##Name(const Instruction* i) VIXL_OVERRIDE { \ 132 USE(i); /* Prevents compiler warnings about unused variables. */ \ 133 } 134 UNUSED_VISITOR_LIST(DEFINE_UNUSED_VISITOR) 135 #undef DEFINE_UNUSED_VISITOR 136 #undef UNUSED_VISITOR_LIST 137 }; 138 139 140 void GenerateNonConstVisitorTestCode(MacroAssembler* masm); 141 142 int64_t RunNonConstVisitorTestGeneratedCode(const Instruction* start_instr); 143 144 void ModifyNonConstVisitorTestGeneratedCode(Instruction* start, 145 Instruction* end); 146 147 148 #endif 149