1 // Copyright 2015, 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_AARCH32_TEST_UTILS_AARCH32_H_ 28 #define VIXL_AARCH32_TEST_UTILS_AARCH32_H_ 29 30 #include "test-runner.h" 31 #include "aarch32/constants-aarch32.h" 32 #include "aarch32/instructions-aarch32.h" 33 #include "aarch32/macro-assembler-aarch32.h" 34 35 namespace vixl { 36 namespace aarch32 { 37 38 // Only check the simulator tests when we can actually run them. 39 // TODO: Improve this. 40 #if defined(__arm__) 41 static const bool kCheckSimulatorTestResults = true; 42 #else 43 static const bool kCheckSimulatorTestResults = false; 44 #endif 45 46 // Helper constants used to check for condition code combinations. These are 47 // not part of instruction definitions as no instruction uses them directly. 48 const uint32_t NoFlag = 0x0; 49 const uint32_t NFlag = 0x80000000; 50 const uint32_t ZFlag = 0x40000000; 51 const uint32_t CFlag = 0x20000000; 52 const uint32_t VFlag = 0x10000000; 53 const uint32_t NZFlag = NFlag | ZFlag; 54 const uint32_t NCFlag = NFlag | CFlag; 55 const uint32_t NVFlag = NFlag | VFlag; 56 const uint32_t ZCFlag = ZFlag | CFlag; 57 const uint32_t ZVFlag = ZFlag | VFlag; 58 const uint32_t CVFlag = CFlag | VFlag; 59 const uint32_t NZCFlag = NFlag | ZFlag | CFlag; 60 const uint32_t NZVFlag = NFlag | ZFlag | VFlag; 61 const uint32_t NCVFlag = NFlag | CFlag | VFlag; 62 const uint32_t ZCVFlag = ZFlag | CFlag | VFlag; 63 const uint32_t NZCVFlag = NFlag | ZFlag | CFlag | VFlag; 64 const uint32_t QFlag = 0x08000000; 65 66 const uint32_t GE0Flag = 0x00010000; 67 const uint32_t GE1Flag = 0x00020000; 68 const uint32_t GE2Flag = 0x00040000; 69 const uint32_t GE3Flag = 0x00080000; 70 const uint32_t GE01Flag = GE0Flag | GE1Flag; 71 const uint32_t GE02Flag = GE0Flag | GE2Flag; 72 const uint32_t GE03Flag = GE0Flag | GE3Flag; 73 const uint32_t GE12Flag = GE1Flag | GE2Flag; 74 const uint32_t GE13Flag = GE1Flag | GE3Flag; 75 const uint32_t GE23Flag = GE2Flag | GE3Flag; 76 const uint32_t GE012Flag = GE0Flag | GE1Flag | GE2Flag; 77 const uint32_t GE013Flag = GE0Flag | GE1Flag | GE3Flag; 78 const uint32_t GE023Flag = GE0Flag | GE2Flag | GE3Flag; 79 const uint32_t GE123Flag = GE1Flag | GE2Flag | GE3Flag; 80 const uint32_t GE0123Flag = GE0Flag | GE1Flag | GE2Flag | GE3Flag; 81 const uint32_t GEFlags = GE0123Flag; 82 83 struct vec128_t { 84 uint64_t l; 85 uint64_t h; 86 }; 87 88 class RegisterDump { 89 public: RegisterDump()90 RegisterDump() : completed_(false) { 91 VIXL_ASSERT(sizeof(dump_.r_[0]) == kRegSizeInBytes); 92 } 93 94 // The Dump method generates code to store a snapshot of the register values. 95 // It needs to be able to use the stack temporarily. 96 // 97 // The dumping code is generated though the given MacroAssembler. No registers 98 // are corrupted in the process apart for the program counter, but the stack 99 // is used briefly. Note the program counter cannot be retrieved from the 100 // register dump anyway. 101 void Dump(MacroAssembler* masm); 102 103 // Register accessors. reg(unsigned code)104 int32_t reg(unsigned code) const { 105 VIXL_ASSERT(IsComplete()); 106 // The collected program counter should not be accessed. 107 VIXL_ASSERT(code != kPcCode); 108 return dump_.r_[code]; 109 } 110 111 // QRegister accessors GetQRegisterBits(unsigned code)112 vec128_t GetQRegisterBits(unsigned code) const { 113 VIXL_ASSERT(IsComplete()); 114 VIXL_ASSERT(code < kNumberOfQRegisters); 115 vec128_t content = {dump_.d_[code * 2], dump_.d_[(code * 2) + 1]}; 116 return content; 117 } 118 119 // DRegister accessors GetDRegisterBits(unsigned code)120 uint64_t GetDRegisterBits(unsigned code) const { 121 VIXL_ASSERT(IsComplete()); 122 VIXL_ASSERT(code < kMaxNumberOfDRegisters); 123 return dump_.d_[code]; 124 } 125 126 // SRegister accessors GetSRegisterBits(unsigned code)127 uint32_t GetSRegisterBits(unsigned code) const { 128 VIXL_ASSERT(IsComplete()); 129 VIXL_ASSERT(code < kNumberOfSRegisters); 130 if ((code % 2) == 0) { 131 return GetDRegisterBits(code / 2) & 0xffffffff; 132 } else { 133 return GetDRegisterBits(code / 2) >> 32; 134 } 135 VIXL_UNREACHABLE(); 136 return 0; 137 } 138 139 // Stack pointer accessors. spreg()140 int32_t spreg() const { return reg(kSPRegNum); } 141 142 // Flags accessors. flags_nzcv()143 uint32_t flags_nzcv() const { 144 VIXL_ASSERT(IsComplete()); 145 return dump_.flags_ & NZCVFlag; 146 } 147 IsComplete()148 bool IsComplete() const { return completed_; } 149 150 private: 151 // Indicate whether the dump operation has been completed. 152 bool completed_; 153 154 // Store all the dumped elements in a simple struct so the implementation can 155 // use offsetof to quickly find the correct field. 156 struct dump_t { 157 // Core registers, except for PC. 158 uint32_t r_[kNumberOfRegisters - 1]; 159 uint64_t d_[kMaxNumberOfDRegisters]; 160 161 // NZCV flags, stored in bits 28 to 31. 162 // bit[31] : Negative 163 // bit[30] : Zero 164 // bit[29] : Carry 165 // bit[28] : oVerflow 166 uint32_t flags_; 167 } dump_; 168 }; 169 170 bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg); 171 bool Equal32(uint32_t expected, const RegisterDump* core, uint32_t result); 172 bool Equal32(uint32_t expected, 173 const RegisterDump* core, 174 const SRegister& sreg); 175 bool Equal64(uint64_t expected, 176 const RegisterDump* core, 177 const DRegister& dreg); 178 bool Equal128(uint64_t expected_h, 179 uint64_t expected_l, 180 const RegisterDump* core, 181 const QRegister& qreg); 182 bool EqualFP32(float expected, const RegisterDump* core, const SRegister& dreg); 183 bool EqualFP64(double expected, 184 const RegisterDump* core, 185 const DRegister& dreg); 186 bool EqualNzcv(uint32_t expected, uint32_t result); 187 188 } // namespace aarch32 189 } // namespace vixl 190 191 #endif // VIXL_AARCH32_TEST_UTILS_AARCH32_H_ 192