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 30 using namespace vixl; 31 32 class 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 137 void GenerateNonConstVisitorTestCode(MacroAssembler* masm); 138 139 int64_t RunNonConstVisitorTestGeneratedCode(const Instruction* start_instr); 140 141 void ModifyNonConstVisitorTestGeneratedCode(Instruction* start, 142 Instruction* end); 143 144 145 #endif 146