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